mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
Preliminary BunkerComponents
This commit is contained in:
parent
87a87738ba
commit
cd4c976dd7
@ -2,34 +2,15 @@ package com.hbm.items.tool;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.blocks.rail.IRailNTM;
|
||||
import com.hbm.blocks.rail.IRailNTM.RailContext;
|
||||
import com.hbm.explosion.vanillant.ExplosionVNT;
|
||||
import com.hbm.explosion.vanillant.standard.BlockAllocatorBulkie;
|
||||
import com.hbm.explosion.vanillant.standard.BlockMutatorBulkie;
|
||||
import com.hbm.explosion.vanillant.standard.BlockProcessorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.EntityProcessorStandard;
|
||||
import com.hbm.explosion.vanillant.standard.ExplosionEffectStandard;
|
||||
import com.hbm.explosion.vanillant.standard.PlayerProcessorStandard;
|
||||
import com.hbm.lib.Library;
|
||||
import com.hbm.packet.PacketDispatcher;
|
||||
import com.hbm.packet.PlayerInformPacket;
|
||||
import com.hbm.util.ParticleUtil;
|
||||
import com.hbm.util.fauxpointtwelve.BlockPos;
|
||||
import com.hbm.world.feature.OilSpot;
|
||||
import com.hbm.world.gen.component.BunkerComponents;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.MovingObjectPosition;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.structure.StructureBoundingBox;
|
||||
|
||||
public class ItemWandD extends Item {
|
||||
|
||||
@ -43,13 +24,13 @@ public class ItemWandD extends Item {
|
||||
|
||||
if(pos != null) {
|
||||
|
||||
ExplosionVNT vnt = new ExplosionVNT(world, pos.hitVec.xCoord, pos.hitVec.yCoord, pos.hitVec.zCoord, 7);
|
||||
/*ExplosionVNT vnt = new ExplosionVNT(world, pos.hitVec.xCoord, pos.hitVec.yCoord, pos.hitVec.zCoord, 7);
|
||||
vnt.setBlockAllocator(new BlockAllocatorBulkie(60));
|
||||
vnt.setBlockProcessor(new BlockProcessorStandard().withBlockEffect(new BlockMutatorBulkie(ModBlocks.block_slag)).setNoDrop());
|
||||
vnt.setEntityProcessor(new EntityProcessorStandard());
|
||||
vnt.setPlayerProcessor(new PlayerProcessorStandard());
|
||||
vnt.setSFX(new ExplosionEffectStandard());
|
||||
vnt.explode();
|
||||
vnt.explode();*/
|
||||
|
||||
/*TimeAnalyzer.startCount("setBlock");
|
||||
world.setBlock(pos.blockX, pos.blockY, pos.blockZ, Blocks.dirt);
|
||||
@ -71,20 +52,12 @@ public class ItemWandD extends Item {
|
||||
tom.destructionRange = 600;
|
||||
world.spawnEntityInWorld(tom);*/
|
||||
|
||||
/*ItemStack itemStack = new ItemStack(ModItems.book_lore);
|
||||
BookLoreType.setTypeForStack(itemStack, BookLoreType.BOOK_IODINE);
|
||||
|
||||
player.inventory.addItemStackToInventory(itemStack);
|
||||
player.inventoryContainer.detectAndSendChanges();*/
|
||||
|
||||
//use sparingly
|
||||
/*int k = ((pos.blockX >> 4) << 4) + 8;
|
||||
int k = ((pos.blockX >> 4) << 4) + 8;
|
||||
int l = ((pos.blockZ >> 4) << 4) + 8;
|
||||
|
||||
MapGenBunker.Start start = new MapGenBunker.Start(world, world.rand, pos.blockX >> 4, pos.blockZ >> 4);
|
||||
start.generateStructure(world, world.rand, new StructureBoundingBox(k - 124, l - 124, k + 15 + 124, l + 15 + 124));*/
|
||||
//MapGenStronghold.Start startS = new MapGenStronghold.Start(world, world.rand, pos.blockX >> 4, pos.blockZ >> 4);
|
||||
//startS.generateStructure(world, world.rand, new StructureBoundingBox(k - 124, l - 124, k + 15 + 124, l + 15 + 124));
|
||||
BunkerComponents.BunkerStart start = new BunkerComponents.BunkerStart(world, world.rand, pos.blockX >> 4, pos.blockZ >> 4);
|
||||
start.generateStructure(world, world.rand, new StructureBoundingBox(k - 124, l - 124, k + 15 + 124, l + 15 + 124));
|
||||
|
||||
/*EntityNukeTorex torex = new EntityNukeTorex(world);
|
||||
torex.setPositionAndRotation(pos.blockX, pos.blockY + 1, pos.blockZ, 0, 0);
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
package com.hbm.lib;
|
||||
|
||||
import com.hbm.world.worldgen.MapGenNTMFeatures;
|
||||
import com.hbm.world.worldgen.NTMWorldGenerator;
|
||||
import com.hbm.world.worldgen.components.CivilianFeatures;
|
||||
import com.hbm.world.worldgen.components.OfficeFeatures;
|
||||
import com.hbm.world.worldgen.components.RuinFeatures;
|
||||
import com.hbm.world.gen.MapGenNTMFeatures;
|
||||
import com.hbm.world.gen.NTMWorldGenerator;
|
||||
import com.hbm.world.gen.component.BunkerComponents;
|
||||
import com.hbm.world.gen.component.CivilianFeatures;
|
||||
import com.hbm.world.gen.component.OfficeFeatures;
|
||||
import com.hbm.world.gen.component.RuinFeatures;
|
||||
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import net.minecraft.world.gen.structure.MapGenStructureIO;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
public class HbmWorld {
|
||||
|
||||
@ -24,7 +26,10 @@ public class HbmWorld {
|
||||
registerNTMFeatures();
|
||||
|
||||
registerWorldGen(new HbmWorldGen(), 1);
|
||||
registerWorldGen(new NTMWorldGenerator(), 1); //Ideally, move everything over from HbmWorldGen to NTMWorldGenerator
|
||||
|
||||
NTMWorldGenerator worldGenerator = new NTMWorldGenerator();
|
||||
registerWorldGen(worldGenerator, 1); //Ideally, move everything over from HbmWorldGen to NTMWorldGenerator
|
||||
MinecraftForge.EVENT_BUS.register(worldGenerator);
|
||||
//registerWorldGen(new WorldGenTest(), 1);
|
||||
}
|
||||
|
||||
@ -37,5 +42,6 @@ public class HbmWorld {
|
||||
CivilianFeatures.registerComponents();
|
||||
OfficeFeatures.registerComponents();
|
||||
RuinFeatures.registerComponents();
|
||||
BunkerComponents.registerComponents();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.hbm.world.worldgen;
|
||||
package com.hbm.world.gen;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@ -7,9 +7,9 @@ import java.util.Random;
|
||||
|
||||
import com.hbm.config.GeneralConfig;
|
||||
import com.hbm.config.StructureConfig;
|
||||
import com.hbm.world.worldgen.components.CivilianFeatures.*;
|
||||
import com.hbm.world.worldgen.components.OfficeFeatures.*;
|
||||
import com.hbm.world.worldgen.components.RuinFeatures.*;
|
||||
import com.hbm.world.gen.component.CivilianFeatures.*;
|
||||
import com.hbm.world.gen.component.OfficeFeatures.*;
|
||||
import com.hbm.world.gen.component.RuinFeatures.*;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
@ -99,10 +99,8 @@ public class MapGenNTMFeatures extends MapGenStructure {
|
||||
public Start(World world, Random rand, int chunkX, int chunkZ) {
|
||||
super(chunkX, chunkZ);
|
||||
|
||||
BiomeGenBase biome = world.getBiomeGenForCoords(chunkX * 16 + 8, chunkZ * 16 + 8);
|
||||
int posY = world.getHeightValue(chunkX * 16 + 8, chunkZ * 16 + 8);
|
||||
if(posY == 0)
|
||||
posY = world.getTopSolidOrLiquidBlock(chunkX * 16 + 8, chunkZ * 16 + 8);
|
||||
BiomeGenBase biome = world.getBiomeGenForCoords(chunkX * 16 + 8, chunkZ * 16 + 8); //Only gets the biome in the corner of the chunk.
|
||||
final int posY = 64; // Terrain *does not exist* at this stage - at least, for vanilla. Here it has to be called after, but better safe than sorry.
|
||||
|
||||
/*
|
||||
* Probably want to use nextInt() to increase the structures of rarity here. As a fallback, you could have generic stone brick/useless block ruins that will always be chosen if the
|
||||
126
src/main/java/com/hbm/world/gen/NTMWorldGenerator.java
Normal file
126
src/main/java/com/hbm/world/gen/NTMWorldGenerator.java
Normal file
@ -0,0 +1,126 @@
|
||||
package com.hbm.world.gen;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.blocks.generic.BlockNTMFlower.EnumFlowerType;
|
||||
import com.hbm.config.StructureConfig;
|
||||
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import static net.minecraftforge.common.BiomeDictionary.*;
|
||||
import net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate;
|
||||
import net.minecraftforge.event.terraingen.InitMapGenEvent.EventType;
|
||||
import net.minecraftforge.event.terraingen.PopulateChunkEvent;
|
||||
import static net.minecraftforge.event.terraingen.TerrainGen.*;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
|
||||
public class NTMWorldGenerator implements IWorldGenerator {
|
||||
|
||||
private MapGenNTMFeatures scatteredFeatureGenerator = new MapGenNTMFeatures();
|
||||
|
||||
private final Random rand = new Random(); //A central random, used to cleanly generate our stuff without affecting vanilla or modded seeds.
|
||||
|
||||
/** Inits all MapGen upon the loading of a new world. Hopefully clears out structureMaps and structureData when a different world is loaded. */
|
||||
@SubscribeEvent
|
||||
public void onLoad(WorldEvent.Load event) {
|
||||
scatteredFeatureGenerator = (MapGenNTMFeatures) getModdedMapGen(new MapGenNTMFeatures(), EventType.CUSTOM);
|
||||
hasPopulationEvent = false;
|
||||
}
|
||||
|
||||
/** Called upon the initial population of a chunk. Called in the pre-population event first; called again if pre-population didn't occur (flatland) */
|
||||
private void setRandomSeed(World world, int chunkX, int chunkZ) {
|
||||
rand.setSeed(world.getSeed());
|
||||
final long i = rand.nextLong() / 2L * 2L + 1L;
|
||||
final long j = rand.nextLong() / 2L * 2L + 1L;
|
||||
rand.setSeed((long)chunkX * i + (long)chunkZ * j ^ world.getSeed());
|
||||
}
|
||||
|
||||
/*
|
||||
* Pre-population Events / Structure Generation
|
||||
* Used to generate structures without unnecessary intrusion by biome decoration, like trees.
|
||||
*/
|
||||
|
||||
private boolean hasPopulationEvent = false; // Does the given chunkGenerator have a population event? If not (flatlands), default to using generate.
|
||||
|
||||
@SubscribeEvent
|
||||
public void generateStructures(PopulateChunkEvent.Pre event) {
|
||||
setRandomSeed(event.world, event.chunkX, event.chunkZ); //Set random for population down the line.
|
||||
hasPopulationEvent = true;
|
||||
|
||||
if(!StructureConfig.enableStructures) return;
|
||||
|
||||
switch (event.world.provider.dimensionId) {
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
generateOverworldStructures(event.world, event.chunkProvider, event.chunkX, event.chunkZ);
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void generateOverworldStructures(World world, IChunkProvider chunkProvider, int chunkX, int chunkZ) {
|
||||
Block[] ablock = new Block[65536]; //ablock isn't actually used for anything in MapGenStructure
|
||||
|
||||
this.scatteredFeatureGenerator.func_151539_a(chunkProvider, world, chunkX, chunkZ, ablock);
|
||||
this.scatteredFeatureGenerator.generateStructuresInChunk(world, rand, chunkX, chunkZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Post-Vanilla / Modded Generation
|
||||
* Used to generate features that don't care about intrusions (ores, craters, caves, etc.)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void generate(Random rand, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
|
||||
|
||||
switch (world.provider.dimensionId) {
|
||||
case -1:
|
||||
generateNether(world, rand, chunkGenerator, chunkX, chunkZ); break;
|
||||
case 0:
|
||||
generateSurface(world, rand, chunkGenerator, chunkProvider, chunkX, chunkZ); break;
|
||||
case 1:
|
||||
generateEnd(world, rand, chunkGenerator, chunkX, chunkZ); break;
|
||||
}
|
||||
}
|
||||
|
||||
private void generateNether(World world, Random rand, IChunkProvider chunkGenerator, int chunkX, int chunkZ) { }
|
||||
|
||||
/* Overworld Generation */
|
||||
|
||||
private void generateSurface(World world, Random rand, IChunkProvider chunkGenerator, IChunkProvider chunkProvider, int chunkX, int chunkZ) {
|
||||
if(!hasPopulationEvent) { //If we've failed to generate any structures (flatlands)
|
||||
setRandomSeed(world, chunkX, chunkZ); //Reset the random seed to compensate
|
||||
if(StructureConfig.enableStructures) generateOverworldStructures(world, chunkGenerator, chunkX, chunkZ); //Do it through the post-population generation directly
|
||||
}
|
||||
|
||||
final int posX = (chunkX << 4) + 8;
|
||||
final int posZ = (chunkZ << 4) + 8;
|
||||
BiomeGenBase biome = world.getBiomeGenForCoords(posX, posZ);
|
||||
|
||||
/* biome dictionary my beloved <3
|
||||
* no check for tom here because the event handler already checks for decoration events, + this way they won't become permanently extinct.
|
||||
*/
|
||||
|
||||
/* Biome check, followed by chance, followed by event (for compat, both intra- and inter- (in the case of Tom). */
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void generateEnd(World world, Random rand, IChunkProvider chunkGenerator, int chunkX, int chunkZ) { }
|
||||
|
||||
/** Utility method for biome checking multiple types exclusively. Not sure why it wasn't already present. */
|
||||
public static boolean isBiomeOfTypes(BiomeGenBase biome, Type... types) { //If new biomes are implemented, move this to any biome-related utility class.
|
||||
for(Type type : types) {
|
||||
if(!isBiomeOfType(biome, type)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
247
src/main/java/com/hbm/world/gen/ProceduralStructureStart.java
Normal file
247
src/main/java/com/hbm/world/gen/ProceduralStructureStart.java
Normal file
@ -0,0 +1,247 @@
|
||||
package com.hbm.world.gen;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.structure.StructureBoundingBox;
|
||||
import net.minecraft.world.gen.structure.StructureComponent;
|
||||
import net.minecraft.world.gen.structure.StructureStart;
|
||||
|
||||
/** This makes so much more sense! OOP wasn't confusing sometimes, you were just retarded! */
|
||||
public class ProceduralStructureStart extends StructureStart {
|
||||
/** List of queued components to call buildComponent on randomly. Iterated over until hard limits reached. */
|
||||
public List<StructureComponent> queuedComponents = new ArrayList();
|
||||
/** List of the component weights for this particular structure -- weights removed as components are 'used up.' */
|
||||
protected List<Weight> componentWeightList; //Make sure to initialize the array list to the weight array size, since might as well
|
||||
|
||||
public ProceduralStructureStart() { }
|
||||
|
||||
public ProceduralStructureStart(int chunkX, int chunkZ) {
|
||||
super(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
/** 'starter' is just the starting component, so like a village well. meant to be nice and convenient and not needing a super necessarily. */
|
||||
public ProceduralStructureStart buildStart(World world, Random rand, StructureComponent starter, Weight...weights) {
|
||||
prepareWeights(weights);
|
||||
|
||||
components.add(starter);
|
||||
queuedComponents.add(starter);
|
||||
while(!queuedComponents.isEmpty()) {
|
||||
final int i = rand.nextInt(queuedComponents.size());
|
||||
StructureComponent component = queuedComponents.remove(i);
|
||||
if(component instanceof ProceduralComponent)
|
||||
((ProceduralComponent) component).buildComponent(this, rand); //additional components are added to the list; the 'last component' is the caller already.
|
||||
}
|
||||
|
||||
this.updateBoundingBox();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void prepareWeights(Weight...weights) {
|
||||
componentWeightList = new ArrayList(weights.length);
|
||||
|
||||
for(int i = 0; i < weights.length; i++) {
|
||||
weights[i].instancesSpawned = 0;
|
||||
componentWeightList.add(weights[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads from NBT. */
|
||||
@Override
|
||||
public void func_143017_b(NBTTagCompound nbt) {
|
||||
|
||||
}
|
||||
|
||||
/** Writes to NBT. */
|
||||
@Override
|
||||
public void func_143022_a(NBTTagCompound nbt) {
|
||||
|
||||
}
|
||||
|
||||
protected int getTotalWeight() {
|
||||
boolean flag = false;
|
||||
int totalWeight = 0;
|
||||
Weight weight;
|
||||
|
||||
for(Iterator iterator = componentWeightList.iterator(); iterator.hasNext(); totalWeight += weight.weight) { //Iterates over the entire list to find the total weight
|
||||
weight = (Weight) iterator.next();
|
||||
|
||||
if(weight.instanceLimit >= 0 && weight.instancesSpawned < weight.instanceLimit) //can more structure pieces be added, in general?
|
||||
flag = true;
|
||||
}
|
||||
|
||||
return flag ? totalWeight : -1;
|
||||
}
|
||||
|
||||
protected StructureComponent getWeightedComponent(StructureComponent last, Random rand, int minX, int minY, int minZ, int coordMode, int componentType) {
|
||||
int totalWeight = getTotalWeight();
|
||||
|
||||
if(totalWeight < 0)
|
||||
return null;
|
||||
|
||||
for(int i = 0; i < 5; i++) {
|
||||
int value = rand.nextInt(totalWeight); //Pick a random value, based on how many parts there are already
|
||||
Iterator iterator = componentWeightList.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
Weight weight = (Weight)iterator.next();
|
||||
value -= weight.weight; //Iterate over the list until the value is less than 0
|
||||
|
||||
if(value < 0) {
|
||||
if(!weight.canSpawnStructure(componentType, coordMode, last)) //Additional checks based on game state info preventing spawn? start from beginning
|
||||
break;
|
||||
|
||||
StructureComponent component = weight.lambda.findValidPlacement(components, rand, minX, minY, minZ, coordMode, componentType); //Construct the chosen component
|
||||
|
||||
if(component != null) { //If it has been constructed, add it
|
||||
weight.instancesSpawned++;
|
||||
|
||||
if(!weight.canSpawnMoreStructures()) //Structure can no longer be spawned regardless of game state? remove as an option
|
||||
componentWeightList.remove(weight);
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//might remove these, add hard limits so subclasses can create their own implementations
|
||||
protected int sizeLimit = 50;
|
||||
protected int distanceLimit = 64;
|
||||
|
||||
/** Gets the next valid component based on the structure start's members */
|
||||
protected StructureComponent getNextValidComponent(StructureComponent last, Random rand, int minX, int minY, int minZ, int coordMode, int componentType) {
|
||||
|
||||
if(components.size() > sizeLimit) //Hard limit on amount of components
|
||||
return null;
|
||||
|
||||
if(Math.abs(minX - (func_143019_e() * 16 + 8)) <= distanceLimit && Math.abs(minZ - (func_143018_f() * 16 + 8)) <= distanceLimit) { //Hard limit on spread of structure
|
||||
|
||||
StructureComponent structure = getWeightedComponent(last, rand, minX, minY, minZ, coordMode, componentType + 1); //Returns null if all checks fail
|
||||
|
||||
if(structure != null) {
|
||||
this.components.add(structure); //Adds component to structure start list
|
||||
this.queuedComponents.add(structure); //Add it to the list of queued components waiting to be built
|
||||
}
|
||||
|
||||
return structure;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Useful utility method to automatically construct the appropriate structure bounding box; based on the getNextComponents below!<br>
|
||||
* posX, posY, posZ represent the original anchor point of the structurecomponent (minX, minY, minZ).<br>
|
||||
* offsetX, offsetY, offsetZ all add onto that point, meaning that offsets <b>will always move that anchor towards +x, +y, +z (in terms of south).</b><br>
|
||||
* maxX, maxY, maxZ additionally are added to get the maximum x, y, z (obviously) in terms of south. An offset of 1 is subtracted, so these do not start at 0, and
|
||||
* <b>refer to the ACTUAL dimensions of the component.</b><br>
|
||||
* The initial anchor point is kind of arbitrary based on where it is in the door, so what really matters is keeping it consistent.
|
||||
*/
|
||||
public static StructureBoundingBox getComponentToAddBoundingBox(int posX, int posY, int posZ, int offsetX, int offsetY, int offsetZ, int maxX, int maxY, int maxZ, int coordMode) {
|
||||
switch(coordMode) {
|
||||
default:
|
||||
case 0: return new StructureBoundingBox(posX + offsetX, posY + offsetY, posZ + offsetZ, posX + maxX - 1 + offsetX, posY + maxY - 1 + offsetY, posZ + maxZ - 1 + offsetZ); //South
|
||||
case 1: return new StructureBoundingBox(posX - maxZ + 1 - offsetZ, posY + offsetY, posZ + offsetX, posX - offsetZ, posY + maxY - 1 + offsetY, posZ + maxX - 1 + offsetX); //West
|
||||
case 2: return new StructureBoundingBox(posX - maxX + 1 - offsetX, posY + offsetY, posZ - maxZ + 1 - offsetZ, posX - offsetX, posY + maxY - 1 + offsetY, posZ + offsetZ); //North
|
||||
case 3: return new StructureBoundingBox(posX + offsetZ, posY + offsetY, posZ - maxX + 1 - offsetX, posX + maxZ - 1 + offsetZ, posY + maxY - 1 + offsetY, posZ - offsetX); //East
|
||||
}
|
||||
}
|
||||
|
||||
/** no class-based multiple inheritance? */
|
||||
public static interface ProceduralComponent {
|
||||
|
||||
public default void buildComponent(ProceduralStructureStart start, Random rand) { } //no class-based multiple inheritance?
|
||||
|
||||
/** Gets next component in the direction this component is facing.<br>'original' refers to the initial starting component (hard distance limits), 'components' refers to the StructureStart list.<br>
|
||||
* offset and offsetY are added to the <b>anchor point of the new component<br>, referring to the minX and minY respectively (in terms of south).<br>
|
||||
* An offset of 1 is added to the minZ anchor point, relative to south.
|
||||
*/
|
||||
public default StructureComponent getNextComponentNormal(ProceduralStructureStart start, StructureComponent caller, int coordMode, Random rand, int offset, int offsetY) {
|
||||
StructureBoundingBox box = caller.getBoundingBox();
|
||||
switch(coordMode) {
|
||||
case 0: return start.getNextValidComponent(caller, rand, box.minX + offset, box.minY + offsetY, box.maxZ + 1, coordMode, caller.getComponentType()); //South
|
||||
case 1: return start.getNextValidComponent(caller, rand, box.minX - 1, box.minY + offsetY, box.minZ + offset, coordMode, caller.getComponentType()); //West
|
||||
case 2: return start.getNextValidComponent(caller, rand, box.maxX - offset, box.minY + offsetY, box.minZ - 1, coordMode, caller.getComponentType()); //North
|
||||
case 3: return start.getNextValidComponent(caller, rand, box.maxX + 1, box.minY + offsetY, box.maxZ - offset, coordMode, caller.getComponentType()); //East
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets next component in the opposite direction this component is facing. */
|
||||
public default StructureComponent getNextComponentAntiNormal(ProceduralStructureStart start, StructureComponent caller, int coordMode, Random rand, int offset, int offsetY) {
|
||||
StructureBoundingBox box = caller.getBoundingBox();
|
||||
switch(coordMode) {
|
||||
case 0: return start.getNextValidComponent(caller, rand, box.maxX - offset, box.minY + offsetY, box.minZ - 1, 2, caller.getComponentType()); //South
|
||||
case 1: return start.getNextValidComponent(caller, rand, box.maxX + 1, box.minY + offsetY, box.maxZ - offset, 3, caller.getComponentType()); //West
|
||||
case 2: return start.getNextValidComponent(caller, rand, box.minX + offset, box.minY + offsetY, box.maxZ + 1, 0, caller.getComponentType()); //North
|
||||
case 3: return start.getNextValidComponent(caller, rand, box.minX - 1, box.minY + offsetY, box.minZ + offset, 1, caller.getComponentType()); //East
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
//Keep in mind for these methods: a given room would have its *actual entrance* opposite the side it is facing.
|
||||
/** Gets next component, to the West (-X) <i>relative to this component. */
|
||||
public default StructureComponent getNextComponentWest(ProceduralStructureStart start, StructureComponent caller, int coordMode, Random rand, int offset, int offsetY) {
|
||||
StructureBoundingBox box = caller.getBoundingBox();
|
||||
switch(coordMode) {
|
||||
case 0: return start.getNextValidComponent(caller, rand, box.minX - 1, box.minY + offsetY, box.minZ + offset, 1, caller.getComponentType()); //South
|
||||
case 1: return start.getNextValidComponent(caller, rand, box.maxX - offset, box.minY + offsetY, box.minZ - 1, 2, caller.getComponentType()); //West
|
||||
case 2: return start.getNextValidComponent(caller, rand, box.maxX + 1, box.minY + offsetY, box.maxZ - offset, 3, caller.getComponentType()); //North
|
||||
case 3: return start.getNextValidComponent(caller, rand, box.minX + offset, box.minY + offsetY, box.maxZ + 1, 0, caller.getComponentType()); //East
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets next component, to the East (+X) <i>relative to this component. */
|
||||
public default StructureComponent getNextComponentEast(ProceduralStructureStart start, StructureComponent caller, int coordMode, Random rand, int offset, int offsetY) {
|
||||
StructureBoundingBox box = caller.getBoundingBox();
|
||||
switch(coordMode) {
|
||||
case 0: return start.getNextValidComponent(caller, rand, box.maxX + 1, box.minY + offsetY, box.maxZ - offset, 3, caller.getComponentType()); //South
|
||||
case 1: return start.getNextValidComponent(caller, rand, box.minX + offset, box.minY + offsetY, box.maxZ + 1, 0, caller.getComponentType()); //West
|
||||
case 2: return start.getNextValidComponent(caller, rand, box.minX - 1, box.minY + offsetY, box.minZ + offset, 1, caller.getComponentType()); //North
|
||||
case 3: return start.getNextValidComponent(caller, rand, box.maxX - offset, box.minY + offsetY, box.minZ - 1, 2, caller.getComponentType()); //East
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a new instance of this structureComponent, or null if not able to be placed.<br>Based on bounding box checks. Please use a method reference in the component. */
|
||||
@FunctionalInterface
|
||||
protected static interface instantiateStructure {
|
||||
StructureComponent findValidPlacement(List components, Random rand, int minX, int minY, int minZ, int coordMode, int componentType);
|
||||
}
|
||||
|
||||
protected static class Weight {
|
||||
|
||||
public final instantiateStructure lambda; //Read above
|
||||
|
||||
public final int weight; //Weight of this component
|
||||
public int instancesSpawned; //How many components spawned?
|
||||
public int instanceLimit; //Limit on amount of components: -1 for no limit
|
||||
|
||||
public Weight(int weight, int limit, instantiateStructure lambda) {
|
||||
this.weight = weight;
|
||||
this.instanceLimit = limit;
|
||||
this.lambda = lambda;
|
||||
}
|
||||
|
||||
//Checks if another structure can be spawned based on input data
|
||||
public boolean canSpawnStructure(int componentAmount, int coordMode, StructureComponent component) {
|
||||
return this.instanceLimit < 0 || this.instancesSpawned < this.instanceLimit;
|
||||
}
|
||||
|
||||
//Checks if another structure can be spawned at all (used to flag for removal from the list)
|
||||
public boolean canSpawnMoreStructures() {
|
||||
return this.instanceLimit < 0 || this.instancesSpawned < this.instanceLimit;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
547
src/main/java/com/hbm/world/gen/component/BunkerComponents.java
Normal file
547
src/main/java/com/hbm/world/gen/component/BunkerComponents.java
Normal file
@ -0,0 +1,547 @@
|
||||
package com.hbm.world.gen.component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.lib.HbmChestContents;
|
||||
import com.hbm.world.gen.ProceduralStructureStart;
|
||||
import com.hbm.world.gen.ProceduralStructureStart.ProceduralComponent;
|
||||
import com.hbm.world.gen.component.Component.ConcreteBricks;
|
||||
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.structure.MapGenStructureIO;
|
||||
import net.minecraft.world.gen.structure.StructureBoundingBox;
|
||||
import net.minecraft.world.gen.structure.StructureComponent;
|
||||
|
||||
public class BunkerComponents {
|
||||
|
||||
public static class BunkerStart extends ProceduralStructureStart {
|
||||
|
||||
public BunkerStart(World world, Random rand, int chunkX, int chunkZ) {
|
||||
super(chunkX, chunkZ);
|
||||
|
||||
this.sizeLimit = 7 + rand.nextInt(6);
|
||||
this.distanceLimit = 40;
|
||||
|
||||
final int x = chunkX * 16 + 8;
|
||||
final int z = chunkZ * 16 + 8;
|
||||
|
||||
Weight[] weights = new Weight[] {
|
||||
new Weight(6, 3, Corridor::findValidPlacement),
|
||||
new Weight(7, 4, BedroomL::findValidPlacement),
|
||||
new Weight(10, 3, FunJunction::findValidPlacement),
|
||||
new Weight(5, 2, BathroomL::findValidPlacement),
|
||||
};
|
||||
|
||||
StructureComponent starter = new StartingHub(rand, x, z);
|
||||
|
||||
buildStart(world, rand, starter, weights);
|
||||
|
||||
this.markAvailableHeight(world, rand, 20);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void registerComponents() {
|
||||
MapGenStructureIO.func_143031_a(StartingHub.class, "NTMBStartingHub");
|
||||
MapGenStructureIO.func_143031_a(Corridor.class, "NTMBCorridor");
|
||||
MapGenStructureIO.func_143031_a(BedroomL.class, "NTMBBedroomL");
|
||||
MapGenStructureIO.func_143031_a(FunJunction.class, "NTMBFunJunction");
|
||||
MapGenStructureIO.func_143031_a(BathroomL.class, "NTMBBathroomL");
|
||||
//TODO more rooms for more variety
|
||||
}
|
||||
|
||||
//why are we still doing this?
|
||||
private static ConcreteBricks ConcreteBricks = new ConcreteBricks();
|
||||
|
||||
public static class StartingHub extends Component implements ProceduralComponent {
|
||||
|
||||
private boolean[] paths = new boolean[3];
|
||||
|
||||
public StartingHub() { }
|
||||
|
||||
public StartingHub(Random rand, int x, int z) {
|
||||
super(rand, x, 64, z, 7, 5, 7);
|
||||
}
|
||||
|
||||
public StartingHub(int componentType, StructureBoundingBox box, int coordMode) {
|
||||
super(componentType);
|
||||
this.boundingBox = box;
|
||||
this.coordBaseMode = coordMode;
|
||||
}
|
||||
|
||||
/** write to nbt */
|
||||
@Override
|
||||
protected void func_143012_a(NBTTagCompound nbt) {
|
||||
super.func_143012_a(nbt);
|
||||
for(int i = 0; i < paths.length; i++)
|
||||
nbt.setBoolean("p" + i, paths[i]);
|
||||
}
|
||||
|
||||
/** read from nbt */
|
||||
@Override
|
||||
protected void func_143011_b(NBTTagCompound nbt) {
|
||||
super.func_143011_b(nbt);
|
||||
for(int i = 0; i < paths.length; i++)
|
||||
paths[i] = nbt.getBoolean("p" + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildComponent(ProceduralStructureStart start, Random rand) {
|
||||
paths[0] = this.getNextComponentEast(start, this, coordBaseMode, rand, 5, 1) != null;
|
||||
paths[1] = this.getNextComponentAntiNormal(start, this, coordBaseMode, rand, 4, 1) != null;
|
||||
paths[2] = this.getNextComponentWest(start, this, coordBaseMode, rand, 3, 1) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addComponentParts(World world, Random rand, StructureBoundingBox box) {
|
||||
|
||||
fillWithAir(world, box, 1, 1, 1, 6, 3, 6);
|
||||
//floor
|
||||
fillWithMetadataBlocks(world, box, 1, 0, 1, 6, 0, 6, ModBlocks.vinyl_tile, 1);
|
||||
//ceiling
|
||||
fillWithBlocks(world, box, 1, 4, 1, 6, 4, 6, ModBlocks.vinyl_tile);
|
||||
//upper shield
|
||||
fillWithBlocks(world, box, 1, 4, 4, 3, 4, 6, ModBlocks.reinforced_stone);
|
||||
fillWithBlocks(world, box, 0, 5, 0, 7, 5, 7, ModBlocks.reinforced_stone);
|
||||
//walls
|
||||
fillWithRandomizedBlocks(world, box, 0, 0, 0, 0, 4, 7, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 1, 0, 7, 6, 4, 7, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 7, 0, 0, 7, 4, 7, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 1, 0, 0, 6, 4, 0, rand, ConcreteBricks);
|
||||
//meh, fix the area later
|
||||
final int hpos = Component.getAverageHeight(world, boundingBox, box, componentType - boundingBox.minY);
|
||||
//top hatch
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_slab, 1, 0, hpos, 5, box);
|
||||
fillWithMetadataBlocks(world, box, 1, hpos, 4, 1, hpos, 6, ModBlocks.concrete_smooth_stairs, getStairMeta(0));
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_slab, 1, 2, hpos, 3, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, getStairMeta(2), 2, hpos, 4, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.trapdoor, getDecoModelMeta(8) >> 2, 2, hpos, 5, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, getStairMeta(3), 2, hpos, 6, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_slab, 1, 2, hpos, 7, box);
|
||||
fillWithMetadataBlocks(world, box, 3, hpos, 4, 3, hpos, 6, ModBlocks.concrete_smooth_stairs, getStairMeta(1));
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_slab, 1, 4, hpos, 5, box);
|
||||
//tunnel downwards
|
||||
fillWithBlocks(world, box, 1, 6, 4, 1, hpos - 1, 6, ModBlocks.reinforced_stone);
|
||||
fillWithBlocks(world, box, 2, 1, 6, 2, hpos - 1, 6, ModBlocks.reinforced_stone);
|
||||
fillWithBlocks(world, box, 3, 6, 4, 3, hpos - 1, 6, ModBlocks.reinforced_stone);
|
||||
fillWithBlocks(world, box, 2, 6, 4, 2, hpos - 1, 4, ModBlocks.reinforced_stone);
|
||||
fillWithMetadataBlocks(world, box, 2, 1, 5, 2, hpos - 1, 5, ModBlocks.ladder_sturdy, getDecoMeta(2)); //double check meta
|
||||
|
||||
/* DECO */
|
||||
//lamps
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 2, 5, 2, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 5, 5, 2, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 5, 5, 5, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 2, 4, 2, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 5, 4, 2, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 5, 4, 5, box);
|
||||
//machine
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.deco_tungsten, 0, 3, 1, 6, box);
|
||||
generateInvContents(world, box, rand, Blocks.chest, getDecoMeta(2), 4, 1, 6, HbmChestContents.antenna/*TODO change */, 5);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.deco_tungsten, 0, 5, 1, 6, box);
|
||||
fillWithMetadataBlocks(world, box, 3, 2, 6, 5, 2, 6, ModBlocks.concrete_smooth_stairs, getStairMeta(2) | 4);
|
||||
fillWithMetadataBlocks(world, box, 3, 3, 6, 5, 3, 6, ModBlocks.tape_recorder, getDecoMeta(2));
|
||||
//desk
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, getStairMeta(1) | 4, 3, 1, 4, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, getStairMeta(3) | 4, 4, 1, 4, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, getStairMeta(0) | 4, 5, 1, 4, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.deco_computer, getDecoModelMeta(0), 4, 2, 4, box);
|
||||
//clear out entryways based on path
|
||||
if(paths[0]) fillWithAir(world, box, 7, 1, 2, 7, 2, 3);
|
||||
if(paths[1]) fillWithAir(world, box, 3, 1, 0, 4, 2, 0);
|
||||
if(paths[2]) fillWithAir(world, box, 0, 1, 2, 0, 2, 3);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Corridor extends Component implements ProceduralComponent {
|
||||
|
||||
private boolean path;
|
||||
|
||||
public Corridor() { }
|
||||
|
||||
public Corridor(int componentType, StructureBoundingBox box, int coordMode) {
|
||||
super(componentType);
|
||||
this.boundingBox = box;
|
||||
this.coordBaseMode = coordMode;
|
||||
}
|
||||
|
||||
/** write to nbt */
|
||||
@Override
|
||||
protected void func_143012_a(NBTTagCompound nbt) {
|
||||
super.func_143012_a(nbt);
|
||||
nbt.setBoolean("p", path);
|
||||
}
|
||||
|
||||
/** read from nbt */
|
||||
@Override
|
||||
protected void func_143011_b(NBTTagCompound nbt) {
|
||||
super.func_143011_b(nbt);
|
||||
path = nbt.getBoolean("p");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildComponent(ProceduralStructureStart start, Random rand) {
|
||||
path = this.getNextComponentNormal(start, this, coordBaseMode, rand, 3, 1) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addComponentParts(World world, Random rand, StructureBoundingBox box) {
|
||||
|
||||
fillWithAir(world, box, 1, 1, 1, 4, 3, 5);
|
||||
//floor
|
||||
fillWithMetadataBlocks(world, box, 1, 0, 1, 4, 0, 5, ModBlocks.vinyl_tile, 1);
|
||||
//ceiling
|
||||
fillWithBlocks(world, box, 1, 4, 1, 4, 4, 5, ModBlocks.vinyl_tile);
|
||||
//upper shield
|
||||
fillWithBlocks(world, box, 0, 5, 0, 5, 5, 6, ModBlocks.reinforced_stone);
|
||||
//walls
|
||||
fillWithRandomizedBlocks(world, box, 0, 0, 0, 0, 4, 6, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 1, 0, 6, 4, 4, 6, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 5, 0, 0, 5, 4, 6, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 1, 0, 0, 4, 4, 0, rand, ConcreteBricks);
|
||||
|
||||
//TODO different deco types? maybe plants or vending machines?
|
||||
//save it to nbt either way
|
||||
/* DECO */
|
||||
//lamps
|
||||
fillWithBlocks(world, box, 2, 5, 3, 3, 5, 3, ModBlocks.reinforced_lamp_off);
|
||||
fillWithBlocks(world, box, 2, 4, 3, 3, 4, 3, ModBlocks.fan);
|
||||
//table w/ chairs
|
||||
final int stairMetaS = getStairMeta(3);
|
||||
final int stairMetaN = getStairMeta(2);
|
||||
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaS, 1, 1, 2, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaN, 1, 1, 4, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.fence, 0, 1, 1, 3, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.wooden_pressure_plate, 1, 1, 2, 3, box);
|
||||
//desk w/ computer
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaS | 4, 4, 1, 2, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaN, 4, 1, 4, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.deco_computer, getDecoModelMeta(1), 4, 2, 2, box);
|
||||
//doors
|
||||
placeDoor(world, box, ModBlocks.door_bunker, 1, true, rand.nextBoolean(), 2, 1, 0);
|
||||
placeDoor(world, box, ModBlocks.door_bunker, 1, false, rand.nextBoolean(), 3, 1, 0);
|
||||
if(path) fillWithAir(world, box, 2, 1, 6, 3, 2, 6);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static StructureComponent findValidPlacement(List components, Random rand, int x, int y, int z, int coordMode, int type) {
|
||||
StructureBoundingBox box = ProceduralStructureStart.getComponentToAddBoundingBox(x, y, z, -3, -1, 0, 6, 6, 7, coordMode);
|
||||
return box.minY > 10 && StructureComponent.findIntersecting(components, box) == null ? new Corridor(type, box, coordMode) : null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class BedroomL extends Component implements ProceduralComponent {
|
||||
|
||||
private boolean path;
|
||||
|
||||
public BedroomL() { }
|
||||
|
||||
public BedroomL(int componentType, StructureBoundingBox box, int coordMode) {
|
||||
super(componentType);
|
||||
this.boundingBox = box;
|
||||
this.coordBaseMode = coordMode;
|
||||
}
|
||||
|
||||
/** write to nbt */
|
||||
@Override
|
||||
protected void func_143012_a(NBTTagCompound nbt) {
|
||||
super.func_143012_a(nbt);
|
||||
nbt.setBoolean("p", path);
|
||||
}
|
||||
|
||||
/** read from nbt */
|
||||
@Override
|
||||
protected void func_143011_b(NBTTagCompound nbt) {
|
||||
super.func_143011_b(nbt);
|
||||
path = nbt.getBoolean("p");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildComponent(ProceduralStructureStart start, Random rand) {
|
||||
path = this.getNextComponentWest(start, this, coordBaseMode, rand, 9, 1) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addComponentParts(World world, Random rand, StructureBoundingBox box) {
|
||||
|
||||
fillWithAir(world, box, 4, 1, 1, 8, 3, 4);
|
||||
fillWithAir(world, box, 1, 1, 5, 8, 3, 9);
|
||||
//floor
|
||||
fillWithMetadataBlocks(world, box, 4, 0, 1, 8, 0, 4, ModBlocks.vinyl_tile, 1);
|
||||
fillWithMetadataBlocks(world, box, 1, 0, 5, 8, 0, 9, ModBlocks.vinyl_tile, 1);
|
||||
//ceiling
|
||||
fillWithBlocks(world, box, 4, 4, 1, 8, 4, 4, ModBlocks.vinyl_tile);
|
||||
fillWithBlocks(world, box, 1, 4, 5, 8, 4, 9, ModBlocks.vinyl_tile);
|
||||
//upper shield
|
||||
fillWithBlocks(world, box, 3, 5, 0, 9, 5, 3, ModBlocks.reinforced_stone);
|
||||
fillWithBlocks(world, box, 0, 5, 4, 9, 5, 10, ModBlocks.reinforced_stone);
|
||||
//walls
|
||||
fillWithRandomizedBlocks(world, box, 0, 0, 4, 0, 4, 10, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 1, 0, 10, 8, 4, 10, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 9, 0, 0, 9, 4, 10, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 4, 0, 0, 8, 4, 0, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 3, 0, 0, 3, 4, 4, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 1, 0, 4, 2, 4, 4, rand, ConcreteBricks);
|
||||
|
||||
/* DECO */
|
||||
//lamps
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 3, 5, 7, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 6, 5, 7, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 6, 5, 3, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 3, 4, 7, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 6, 4, 7, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 6, 4, 3, box);
|
||||
//Beds w/ table
|
||||
final int stairMetaW = getStairMeta(0);
|
||||
final int stairMetaE = getStairMeta(1);
|
||||
final int stairMetaN = getStairMeta(2);
|
||||
final int stairMetaS = getStairMeta(3);
|
||||
placeBed(world, box, 1, 5, 1, 1);
|
||||
placeBed(world, box, 1, 5, 1, 3);
|
||||
placeBed(world, box, 2, 3, 1, 6);
|
||||
placeBed(world, box, 2, 1, 1, 6);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaE | 4, 4, 1, 2, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaE | 4, 4, 1, 4, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaS | 4, 4, 1, 5, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaS | 4, 2, 1, 5, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.radiorec, getDecoMeta(4), 4, 2, 4, box);
|
||||
//table w/ microwave
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaS | 4, 8, 1, 3, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaN | 4, 8, 1, 4, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.noteblock, 0, 8, 1, 5, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.machine_microwave, getDecoMeta(4), 8, 2, 4, box);
|
||||
//desk w/ computer
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaW | 4, 6, 1, 9, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaN | 4, 5, 1, 9, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaE | 4, 4, 1, 9, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaS, 5, 1, 8, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.deco_computer, getDecoModelMeta(0), 5, 2, 9, box);
|
||||
generateInvContents(world, box, rand, ModBlocks.filing_cabinet, getDecoModelMeta(0), 3, 1, 9, HbmChestContents.antenna/*TODO change */, 5);
|
||||
//lockers
|
||||
generateInvContents(world, box, rand, Blocks.chest, getDecoMeta(4), 8, 1, 7, HbmChestContents.antenna/*TODO change */, 3);
|
||||
generateInvContents(world, box, rand, Blocks.chest, getDecoMeta(4), 8, 2, 7, HbmChestContents.antenna/*TODO change */, 3);
|
||||
fillWithBlocks(world, box, 8, 1, 8, 8, 2, 8, ModBlocks.deco_tungsten);
|
||||
generateInvContents(world, box, rand, Blocks.chest, getDecoMeta(4), 8, 1, 9, HbmChestContents.antenna/*TODO change */, 3);
|
||||
generateInvContents(world, box, rand, Blocks.chest, getDecoMeta(4), 8, 2, 9, HbmChestContents.antenna/*TODO change */, 3);
|
||||
fillWithMetadataBlocks(world, box, 8, 3, 7, 8, 3, 9, Blocks.trapdoor, getDecoModelMeta(2) >> 2);
|
||||
//doors
|
||||
placeDoor(world, box, ModBlocks.door_bunker, 1, true, rand.nextBoolean(), 7, 1, 0);
|
||||
placeDoor(world, box, ModBlocks.door_bunker, 1, false, rand.nextBoolean(), 8, 1, 0);
|
||||
if(path) fillWithAir(world, box, 0, 1, 8, 0, 2, 9);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static StructureComponent findValidPlacement(List components, Random rand, int x, int y, int z, int coordMode, int type) {
|
||||
StructureBoundingBox box = ProceduralStructureStart.getComponentToAddBoundingBox(x, y, z, -8, -1, 0, 10, 6, 11, coordMode);
|
||||
return box.minY > 10 && StructureComponent.findIntersecting(components, box) == null ? new BedroomL(type, box, coordMode) : null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FunJunction extends Component implements ProceduralComponent {
|
||||
|
||||
private boolean[] paths = new boolean[2];
|
||||
|
||||
public FunJunction() { }
|
||||
|
||||
public FunJunction(int componentType, StructureBoundingBox box, int coordMode) {
|
||||
super(componentType);
|
||||
this.boundingBox = box;
|
||||
this.coordBaseMode = coordMode;
|
||||
}
|
||||
|
||||
/** write to nbt */
|
||||
@Override
|
||||
protected void func_143012_a(NBTTagCompound nbt) {
|
||||
super.func_143012_a(nbt);
|
||||
for(int i = 0; i < paths.length; i++)
|
||||
nbt.setBoolean("p" + i, paths[i]);
|
||||
}
|
||||
|
||||
/** read from nbt */
|
||||
@Override
|
||||
protected void func_143011_b(NBTTagCompound nbt) {
|
||||
super.func_143011_b(nbt);
|
||||
for(int i = 0; i < paths.length; i++)
|
||||
paths[i] = nbt.getBoolean("p" + i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildComponent(ProceduralStructureStart start, Random rand) {
|
||||
paths[0] = this.getNextComponentEast(start, this, coordBaseMode, rand, 6, 1) != null;
|
||||
paths[1] = this.getNextComponentNormal(start, this, coordBaseMode, rand, 5, 1) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addComponentParts(World world, Random rand, StructureBoundingBox box) {
|
||||
|
||||
fillWithAir(world, box, 1, 1, 1, 6, 3, 10);
|
||||
//floor
|
||||
fillWithMetadataBlocks(world, box, 1, 0, 1, 6, 0, 10, ModBlocks.vinyl_tile, 1);
|
||||
//ceiling
|
||||
fillWithBlocks(world, box, 1, 4, 1, 6, 4, 10, ModBlocks.vinyl_tile);
|
||||
//upper shield
|
||||
fillWithBlocks(world, box, 0, 5, 0, 7, 5, 11, ModBlocks.reinforced_stone);
|
||||
//walls
|
||||
fillWithRandomizedBlocks(world, box, 0, 0, 0, 0, 4, 11, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 1, 0, 11, 6, 4, 11, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 7, 0, 0, 7, 4, 11, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 1, 0, 0, 6, 4, 0, rand, ConcreteBricks);
|
||||
|
||||
/* DECO */
|
||||
//lamps
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 2, 5, 3, box);
|
||||
fillWithBlocks(world, box, 5, 5, 5, 5, 5, 6, ModBlocks.reinforced_lamp_off);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 2, 5, 8, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 2, 4, 3, box);
|
||||
fillWithBlocks(world, box, 5, 4, 5, 5, 4, 6, ModBlocks.fan);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 2, 4, 8, box);
|
||||
//couches w/ tables
|
||||
final int stairMetaW = getStairMeta(0);
|
||||
final int stairMetaE = getStairMeta(1);
|
||||
final int stairMetaN = getStairMeta(2);
|
||||
final int stairMetaS = getStairMeta(3);
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaE, 1, 1, 1, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaS, 2, 1, 1, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaW, 3, 1, 1, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaS, 1, 1, 4, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaE, 1, 1, 5, box);
|
||||
fillWithMetadataBlocks(world, box, 1, 1, 6, 2, 1, 6, Blocks.oak_stairs, stairMetaN);
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaW, 3, 1, 6, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.fence, 0, 1, 1, 3, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.wooden_pressure_plate, 0, 1, 2, 3, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.fence, 0, 3, 1, 4, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.wooden_pressure_plate, 0, 3, 2, 4, box);
|
||||
//table & chest
|
||||
placeBlockAtCurrentPosition(world, Blocks.fence, 0, 6, 1, 2, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.wooden_pressure_plate, 0, 6, 2, 2, box);
|
||||
generateInvContents(world, box, rand, Blocks.chest, getDecoMeta(4), 6, 1, 3, HbmChestContents.antenna/*TODO change */, 7);
|
||||
//desk w/ computer + bobblehead
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaS | 4, 1, 1, 8, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaE | 4, 1, 1, 9, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_smooth_stairs, stairMetaN | 4, 1, 1, 10, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.oak_stairs, stairMetaS, 2, 1, 8, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.deco_computer, getDecoModelMeta(3), 1, 2, 9, box);
|
||||
if(rand.nextBoolean()) placeRandomBobble(world, box, rand, 1, 2, 8);
|
||||
//jukebox
|
||||
fillWithBlocks(world, box, 6, 1, 8, 6, 2, 8, Blocks.noteblock);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.deco_tungsten, 0, 6, 1, 9, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.tape_recorder, getDecoMeta(4), 6, 2, 9, box);
|
||||
fillWithBlocks(world, box, 6, 3, 8, 6, 3, 9, ModBlocks.concrete_slab);
|
||||
placeBlockAtCurrentPosition(world, Blocks.lever, getDecoMeta(2), 5, 1, 9, box); //double-check meta
|
||||
//doors
|
||||
placeDoor(world, box, ModBlocks.door_bunker, 1, true, rand.nextBoolean(), 4, 1, 0);
|
||||
placeDoor(world, box, ModBlocks.door_bunker, 1, false, rand.nextBoolean(), 5, 1, 0);
|
||||
if(paths[0]) fillWithAir(world, box, 7, 1, 5, 7, 2, 6);
|
||||
if(paths[1]) fillWithAir(world, box, 4, 1, 11, 5, 2, 11);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static StructureComponent findValidPlacement(List components, Random rand, int x, int y, int z, int coordMode, int type) {
|
||||
StructureBoundingBox box = ProceduralStructureStart.getComponentToAddBoundingBox(x, y, z, -5, -1, 0, 8, 6, 12, coordMode);
|
||||
return box.minY > 10 && StructureComponent.findIntersecting(components, box) == null ? new FunJunction(type, box, coordMode) : null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class BathroomL extends Component implements ProceduralComponent {
|
||||
|
||||
private boolean path;
|
||||
|
||||
public BathroomL() { }
|
||||
|
||||
public BathroomL(int componentType, StructureBoundingBox box, int coordMode) {
|
||||
super(componentType);
|
||||
this.boundingBox = box;
|
||||
this.coordBaseMode = coordMode;
|
||||
}
|
||||
|
||||
/** write to nbt */
|
||||
@Override
|
||||
protected void func_143012_a(NBTTagCompound nbt) {
|
||||
super.func_143012_a(nbt);
|
||||
nbt.setBoolean("p", path);
|
||||
}
|
||||
|
||||
/** read from nbt */
|
||||
@Override
|
||||
protected void func_143011_b(NBTTagCompound nbt) {
|
||||
super.func_143011_b(nbt);
|
||||
path = nbt.getBoolean("p");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildComponent(ProceduralStructureStart start, Random rand) {
|
||||
path = this.getNextComponentEast(start, this, coordBaseMode, rand, 3, 1) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addComponentParts(World world, Random rand, StructureBoundingBox box) {
|
||||
|
||||
fillWithAir(world, box, 1, 1, 1, 7, 3, 9);
|
||||
//floor
|
||||
fillWithMetadataBlocks(world, box, 1, 0, 1, 7, 0, 9, ModBlocks.vinyl_tile, 1);
|
||||
//ceiling
|
||||
fillWithBlocks(world, box, 1, 4, 1, 7, 4, 9, ModBlocks.vinyl_tile);
|
||||
//upper shield
|
||||
fillWithBlocks(world, box, 0, 5, 0, 8, 5, 10, ModBlocks.reinforced_stone);
|
||||
//walls
|
||||
fillWithRandomizedBlocks(world, box, 0, 0, 0, 0, 4, 10, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 1, 0, 10, 7, 4, 10, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 8, 0, 0, 8, 4, 10, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 1, 0, 0, 7, 4, 0, rand, ConcreteBricks);
|
||||
|
||||
/* DECO */
|
||||
//lamps
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 2, 5, 3, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 2, 5, 7, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 5, 5, 7, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.reinforced_lamp_off, 0, 5, 5, 3, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 2, 4, 3, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 2, 4, 7, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 5, 4, 7, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, 0, 5, 4, 3, box);
|
||||
//sinks
|
||||
for(int i = 2; i <= 8; i += 2) {
|
||||
placeBlockAtCurrentPosition(world, Blocks.cauldron, rand.nextInt(4), 1, 1, i, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.concrete_slab, 8, 1, 1, i + 1, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.tripwire_hook, getTripwireMeta(3), 1, 2, i, box);
|
||||
}
|
||||
//hand-dryers (industrial-strength)
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.steel_beam, 3, 4, 1, 9, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, getDecoMeta(2), 4, 2, 9, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.stone_button, 2, 3, 2, 9, box); //TODO button meta
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.steel_beam, 3, 6, 1, 9, box);
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.fan, getDecoMeta(2), 6, 2, 9, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.stone_button, 1, 7, 2, 9, box);
|
||||
//stalls w/ toilets
|
||||
for(int i = 1; i <= 5; i += 2) {
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.door_metal, 0, 5, 1, i, box);
|
||||
placeDoor(world, box, ModBlocks.door_metal, 0, false, rand.nextBoolean(), 5, 1, i);
|
||||
fillWithMetadataBlocks(world, box, 5, 1, i + 1, 5, 2, i + 1, ModBlocks.steel_corner, getDecoMeta(2));
|
||||
fillWithMetadataBlocks(world, box, 6, 1, i + 1, 7, 2, i + 1, ModBlocks.steel_wall, getDecoMeta(2));
|
||||
placeBlockAtCurrentPosition(world, ModBlocks.deco_pipe_rim, 0, 7, 1, i, box);
|
||||
placeBlockAtCurrentPosition(world, Blocks.trapdoor, getDecoModelMeta(2) >> 2, 7, 2, i, box);
|
||||
}
|
||||
//doors
|
||||
placeDoor(world, box, ModBlocks.door_bunker, 1, true, rand.nextBoolean(), 2, 1, 0);
|
||||
placeDoor(world, box, ModBlocks.door_bunker, 1, false, rand.nextBoolean(), 3, 1, 0);
|
||||
if(path) fillWithAir(world, box, 8, 1, 7, 8, 2, 8);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static StructureComponent findValidPlacement(List components, Random rand, int x, int y, int z, int coordMode, int type) {
|
||||
StructureBoundingBox box = ProceduralStructureStart.getComponentToAddBoundingBox(x, y, z, -3, -1, 0, 9, 6, 11, coordMode);
|
||||
return box.minY > 10 && StructureComponent.findIntersecting(components, box) == null ? new BathroomL(type, box, coordMode) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package com.hbm.world.worldgen.components;
|
||||
package com.hbm.world.gen.component;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.hbm.world.worldgen.components;
|
||||
package com.hbm.world.gen.component;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@ -108,6 +108,26 @@ abstract public class Component extends StructureComponent {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static int getAverageHeight(World world, StructureBoundingBox area, StructureBoundingBox box, int y) {
|
||||
|
||||
int total = 0;
|
||||
int iterations = 0;
|
||||
|
||||
for(int z = area.minZ; z <= area.maxZ; z++) {
|
||||
for(int x = area.minX; x <= area.maxX; x++) {
|
||||
if(box.isVecInside(x, y, z)) {
|
||||
total += Math.max(world.getTopSolidOrLiquidBlock(x, z), world.provider.getAverageGroundLevel());
|
||||
iterations++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(iterations == 0)
|
||||
return -1;
|
||||
|
||||
return total / iterations;
|
||||
}
|
||||
|
||||
public int getCoordMode() {
|
||||
return this.coordBaseMode;
|
||||
}
|
||||
@ -224,35 +244,41 @@ abstract public class Component extends StructureComponent {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/* For Later:
|
||||
* 0/S: S->S; W->W; N->N; E->E
|
||||
* 1/W: S->W; W->N; N->E; E->S
|
||||
* 2/N: S->N; W->E; N->S; E->W
|
||||
* 3/E: S->E; W->S; N->W; E->N
|
||||
* 0/b00/W, 1/b01/N, 2/b10/E, 3/b11/S
|
||||
*/
|
||||
/**
|
||||
* Places door at specified location with orientation-adjusted meta
|
||||
* 0 = West, 1 = North, 2 = East, 3 = South
|
||||
/*
|
||||
* Assuming door is on opposite side of block from direction: East: 0, South: 1, West: 2, North: 3<br>
|
||||
* Doors cleverly take advantage of the use of two blocks to get around the 16 value limit on metadata, with the top and bottom blocks essentially relying on eachother for everything.<br>
|
||||
* <li>The 4th bit (0b1000 or 8) indicates whether it is the top block: on for yes, off for no.
|
||||
* <li>When the 4th bit is on, the 1st bit indicates whether the door opens to the right or not: on (0b1001) for yes, off (0b1000) for no.
|
||||
* <li>The bits 1 & 2 (0b0011 or 3) indicate the direction the door is facing.
|
||||
* <li>When the 4th bit is off, the 3rd bit (0b0100 or 4) indicates whether the door is open or not: on for yes, off for no. Used for doors' interactions with redstone power.
|
||||
* </li>
|
||||
*/
|
||||
protected void placeDoor(World world, StructureBoundingBox box, Block door, int meta, int featureX, int featureY, int featureZ) {
|
||||
switch(this.coordBaseMode) {
|
||||
default:
|
||||
break;
|
||||
case 1:
|
||||
meta = (meta + 1) % 4; break;
|
||||
case 2:
|
||||
meta = meta ^ 2; break; //Flip second bit
|
||||
case 3:
|
||||
meta = (meta - 1) % 4; break;
|
||||
}
|
||||
|
||||
protected void placeDoor(World world, StructureBoundingBox box, Block door, int dirMeta, boolean opensRight, boolean isOpen, int featureX, int featureY, int featureZ) { //isOpen for randomly opened doors
|
||||
int posX = this.getXWithOffset(featureX, featureZ);
|
||||
int posY = this.getYWithOffset(featureY);
|
||||
int posZ = this.getZWithOffset(featureX, featureZ);
|
||||
|
||||
this.placeBlockAtCurrentPosition(world, door, meta, featureX, featureY, featureZ, box);
|
||||
ItemDoor.placeDoorBlock(world, posX, posY, posZ, meta, door);
|
||||
if(!box.isVecInside(posX, posY, posZ)) return;
|
||||
|
||||
switch(this.coordBaseMode) {
|
||||
default:
|
||||
break;
|
||||
case 1:
|
||||
dirMeta = (dirMeta + 1) % 4; break;
|
||||
case 2:
|
||||
dirMeta ^= 2; break; //Flip second bit
|
||||
case 3:
|
||||
dirMeta = (dirMeta - 1) % 4; break;
|
||||
}
|
||||
|
||||
//hee hoo
|
||||
int metaTop = opensRight ? 0b1001 : 0b1000;
|
||||
int metaBottom = dirMeta | (isOpen ? 0b100 : 0);
|
||||
|
||||
if(world.doesBlockHaveSolidTopSurface(world, posX, posY - 1, posZ)) {
|
||||
world.setBlock(posX, posY, posZ, door, metaBottom, 2);
|
||||
world.setBlock(posX, posY + 1, posZ, door, metaTop, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**N:0 W:1 S:2 E:3 */
|
||||
@ -1,4 +1,4 @@
|
||||
package com.hbm.world.worldgen.components;
|
||||
package com.hbm.world.gen.component;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@ -200,9 +200,9 @@ public class OfficeFeatures {
|
||||
randomlyFillWithBlocks(world, box, rand, 0.25F, 6, 3, 1, sizeX - 1, 3, 6, Blocks.web);
|
||||
randomlyFillWithBlocks(world, box, rand, 0.25F, 10, 3, 7, sizeX - 1, 3, sizeZ - 1, Blocks.web);
|
||||
//Doors
|
||||
placeDoor(world, box, ModBlocks.door_office, 3, 2, 1, 7);
|
||||
placeDoor(world, box, ModBlocks.door_office, 3, 3, 1, 7);
|
||||
placeDoor(world, box, ModBlocks.door_office, 0, 5, 1, 6);
|
||||
placeDoor(world, box, ModBlocks.door_office, 3, false, rand.nextBoolean(), 2, 1, 7);
|
||||
placeDoor(world, box, ModBlocks.door_office, 3, false, rand.nextBoolean(), 3, 1, 7);
|
||||
placeDoor(world, box, ModBlocks.door_office, 0, false, rand.nextBoolean(), 5, 1, 6);
|
||||
|
||||
//Woot
|
||||
if(!this.hasPlacedLoot[0])
|
||||
@ -427,16 +427,16 @@ public class OfficeFeatures {
|
||||
fillWithRandomizedBlocks(world, box, 2, 11, 10, 3, 11, 10, rand, ConcreteBricks);
|
||||
fillWithRandomizedBlocks(world, box, 2, 9, 10, 2, 10, 10, rand, ConcreteBricks);
|
||||
//Doors
|
||||
placeDoor(world, box, Blocks.wooden_door, 3, 1, 1, 14);
|
||||
placeDoor(world, box, Blocks.wooden_door, 3, 2, 1, 14);
|
||||
placeDoor(world, box, Blocks.wooden_door, 0, 0, 1, 12);
|
||||
placeDoor(world, box, Blocks.wooden_door, 0, 0, 1, 13);
|
||||
placeDoor(world, box, ModBlocks.door_office, 0, 6, 1, 3);
|
||||
placeDoor(world, box, ModBlocks.door_office, 0, 5, 5, 3);
|
||||
placeDoor(world, box, ModBlocks.door_office, 2, 4, 5, 11);
|
||||
placeDoor(world, box, ModBlocks.door_office, 0, 10, 9, 3);
|
||||
placeDoor(world, box, ModBlocks.door_office, 1, 3, 9, 10);
|
||||
placeDoor(world, box, ModBlocks.door_metal, 0, 5, 13, 3);
|
||||
placeDoor(world, box, Blocks.wooden_door, 3, false, rand.nextBoolean(), 1, 1, 14);
|
||||
placeDoor(world, box, Blocks.wooden_door, 3, true, rand.nextBoolean(), 2, 1, 14);
|
||||
placeDoor(world, box, Blocks.wooden_door, 0, false, rand.nextBoolean(), 0, 1, 12);
|
||||
placeDoor(world, box, Blocks.wooden_door, 0, true, rand.nextBoolean(), 0, 1, 13);
|
||||
placeDoor(world, box, ModBlocks.door_office, 0, false, rand.nextBoolean(), 6, 1, 3);
|
||||
placeDoor(world, box, ModBlocks.door_office, 0, false, rand.nextBoolean(), 5, 5, 3);
|
||||
placeDoor(world, box, ModBlocks.door_office, 2, false, rand.nextBoolean(), 4, 5, 11);
|
||||
placeDoor(world, box, ModBlocks.door_office, 0, false, rand.nextBoolean(), 10, 9, 3);
|
||||
placeDoor(world, box, ModBlocks.door_office, 1, false, rand.nextBoolean(), 3, 9, 10);
|
||||
placeDoor(world, box, ModBlocks.door_metal, 0, false, rand.nextBoolean(), 5, 13, 3);
|
||||
//Furniture
|
||||
//Floor 1
|
||||
int NorthStairMeta = getStairMeta(2);
|
||||
@ -1,4 +1,4 @@
|
||||
package com.hbm.world.worldgen.components;
|
||||
package com.hbm.world.gen.component;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
package com.hbm.world.worldgen;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.hbm.config.StructureConfig;
|
||||
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraftforge.event.terraingen.InitMapGenEvent.EventType;
|
||||
import net.minecraftforge.event.terraingen.TerrainGen;
|
||||
|
||||
public class NTMWorldGenerator implements IWorldGenerator {
|
||||
|
||||
private MapGenNTMFeatures NTMFeatureGenerator = new MapGenNTMFeatures();
|
||||
|
||||
{
|
||||
NTMFeatureGenerator = (MapGenNTMFeatures) TerrainGen.getModdedMapGen(NTMFeatureGenerator, EventType.CUSTOM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(Random rand, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
|
||||
|
||||
switch (world.provider.dimensionId) {
|
||||
case -1:
|
||||
generateNether(world, rand, chunkGenerator, chunkX, chunkZ); break;
|
||||
case 0:
|
||||
generateSurface(world, rand, chunkGenerator, chunkX, chunkZ); break;
|
||||
case 1:
|
||||
generateEnd(world, rand, chunkGenerator, chunkX, chunkZ); break;
|
||||
}
|
||||
}
|
||||
|
||||
private void generateNether(World world, Random rand, IChunkProvider chunkGenerator, int chunkX, int chunkZ) { }
|
||||
|
||||
private void generateSurface(World world, Random rand, IChunkProvider chunkGenerator, int chunkX, int chunkZ) {
|
||||
Block[] ablock = new Block[65536];
|
||||
|
||||
//WorldConfig.enableStructures
|
||||
/** Spawns structure starts. Utilizes canSpawnStructureAtCoords() + if else checks in Start constructor */
|
||||
if(StructureConfig.enableStructures) {
|
||||
this.NTMFeatureGenerator.func_151539_a(chunkGenerator, world, chunkX, chunkZ, ablock);
|
||||
}
|
||||
|
||||
/** Actually generates structures in a given chunk. */
|
||||
if(StructureConfig.enableStructures) {
|
||||
this.NTMFeatureGenerator.generateStructuresInChunk(world, rand, chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateEnd(World world, Random rand, IChunkProvider chunkGenerator, int chunkX, int chunkZ) { }
|
||||
}
|
||||
@ -1,240 +0,0 @@
|
||||
package com.hbm.world.worldgen.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.world.gen.structure.StructureBoundingBox;
|
||||
|
||||
public abstract class ProceduralComponents {
|
||||
|
||||
protected List componentWeightList;
|
||||
|
||||
protected static Weight[] weightArray = new Weight[] { };
|
||||
|
||||
public void prepareComponents() {
|
||||
componentWeightList = new ArrayList();
|
||||
|
||||
for(int i = 0; i < weightArray.length; i++) {
|
||||
weightArray[i].instancesSpawned = 0;
|
||||
componentWeightList.add(weightArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
protected int getTotalWeight() {
|
||||
boolean flag = false;
|
||||
int totalWeight = 0;
|
||||
Weight weight;
|
||||
|
||||
for(Iterator iterator = componentWeightList.iterator(); iterator.hasNext(); totalWeight += weight.weight) { //Iterates over the entire list to find the total weight
|
||||
weight = (Weight) iterator.next();
|
||||
|
||||
if(weight.instanceLimit >= 0 && weight.instancesSpawned < weight.instanceLimit) //can more structure pieces be added, in general?
|
||||
flag = true;
|
||||
}
|
||||
|
||||
return flag ? totalWeight : -1;
|
||||
}
|
||||
|
||||
protected ProceduralComponent getWeightedComponent(ControlComponent original, List components, Random rand, int minX, int minY, int minZ, int coordMode, int componentType) {
|
||||
int totalWeight = getTotalWeight();
|
||||
|
||||
if(totalWeight < 0)
|
||||
return null;
|
||||
|
||||
for(int i = 0; i < 5; i++) {
|
||||
int value = rand.nextInt(totalWeight); //Pick a random value, based on how many parts there are already
|
||||
Iterator iterator = componentWeightList.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
Weight weight = (Weight)iterator.next();
|
||||
value -= weight.weight; //Iterate over the list until the value is less than 0
|
||||
|
||||
if(value < 0) {
|
||||
if(!weight.canSpawnStructure(componentType, coordMode, original.lastComponent)) //Additional checks based on game state info preventing spawn? start from beginning
|
||||
break;
|
||||
|
||||
ProceduralComponent component = (ProceduralComponent) weight.lambda.findValidPlacement(components, rand, minX, minY, minZ, coordMode, componentType); //Construct the chosen component
|
||||
|
||||
if(component != null) { //If it has been constructed, add it
|
||||
weight.instancesSpawned++;
|
||||
|
||||
if(!weight.canSpawnMoreStructures()) //Structure can no longer be spawned regardless of game state? remove as an option
|
||||
componentWeightList.remove(weight);
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected int sizeLimit = 50;
|
||||
protected int distanceLimit = 64;
|
||||
|
||||
protected ProceduralComponent getNextValidComponent(ControlComponent original, List components, Random rand, int minX, int minY, int minZ, int coordMode, int componentType) {
|
||||
|
||||
if(components.size() > sizeLimit) //Hard limit on amount of components
|
||||
return null;
|
||||
|
||||
if(Math.abs(minX - original.getBoundingBox().minX) <= distanceLimit && Math.abs(minZ - original.getBoundingBox().minZ) <= distanceLimit) { //Hard limit on spread of structure
|
||||
|
||||
ProceduralComponent structure = getWeightedComponent(original, components, rand, minX, minY, minZ, coordMode, componentType + 1); //Returns null if all checks fail
|
||||
|
||||
if(structure != null) {
|
||||
components.add(structure); //Adds component to structure start list
|
||||
original.queuedComponents.add(structure); //Add it to the list of queued components waiting to be built
|
||||
}
|
||||
|
||||
return structure;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static StructureBoundingBox getComponentToAddBoundingBox(int posX, int posY, int posZ, int offsetX, int offsetY, int offsetZ, int maxX, int maxY, int maxZ, int coordMode) {
|
||||
switch(coordMode) {
|
||||
case 0: //South
|
||||
return new StructureBoundingBox(posX + offsetX, posY + offsetY, posZ + offsetZ, posX + maxX - 1 + offsetX, posY + maxY - 1 + offsetY, posZ + maxZ - 1 + offsetZ);
|
||||
case 1: //West
|
||||
return new StructureBoundingBox(posX - maxZ + 1 - offsetZ, posY + offsetY, posZ + offsetX, posX - offsetZ, posY + maxY - 1 + offsetY, posZ + maxX - 1 + offsetX);
|
||||
case 2: //North
|
||||
return new StructureBoundingBox(posX - maxX + 1 - offsetX, posY + offsetY, posZ - maxZ + 1 - offsetZ, posX - offsetX, posY + maxY - 1 + offsetY, posZ + offsetZ);
|
||||
case 3: //East
|
||||
return new StructureBoundingBox(posX + offsetZ, posY + offsetY, posZ - maxX + 1 - offsetX, posX + maxZ - 1 + offsetZ, posY + maxY - 1 + offsetY, posZ - offsetX);
|
||||
default:
|
||||
return new StructureBoundingBox(posX + offsetX, posY + offsetY, posZ + offsetZ, posX + maxX - 1 + offsetX, posY + maxY - 1 + offsetY, posZ + maxZ - 1 + offsetZ);
|
||||
}
|
||||
}
|
||||
|
||||
/** StructureComponent that supports procedural generation */
|
||||
public abstract static class ProceduralComponent extends Component {
|
||||
|
||||
public ProceduralComponent() { }
|
||||
|
||||
public ProceduralComponent(int componentType) {
|
||||
super(componentType); //Important to carry over.
|
||||
}
|
||||
|
||||
public void buildComponent(ProceduralComponents instance, ControlComponent original, List components, Random rand) { }
|
||||
|
||||
/** Gets next component in the direction this component is facing.<br>'original' refers to the initial starting component (hard distance limits), 'components' refers to the StructureStart list. */
|
||||
protected ProceduralComponent getNextComponentNormal(ProceduralComponents instance, ControlComponent original, List components, Random rand, int offset, int offsetY) {
|
||||
switch(this.coordBaseMode) {
|
||||
case 0: //South
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.minX + offset, this.boundingBox.minY + offsetY, this.boundingBox.maxZ + 1, this.coordBaseMode, this.getComponentType());
|
||||
case 1: //West
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.minX - 1, this.boundingBox.minY + offsetY, this.boundingBox.minZ + offset, this.coordBaseMode, this.getComponentType());
|
||||
case 2: //North
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.maxX - offset, this.boundingBox.minY + offsetY, this.boundingBox.minZ - 1, this.coordBaseMode, this.getComponentType());
|
||||
case 3: //East
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.maxX + 1, this.boundingBox.minY + offsetY, this.boundingBox.maxZ - offset, this.coordBaseMode, this.getComponentType());
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets next component in the opposite direction this component is facing. */
|
||||
protected ProceduralComponent getNextComponentAntiNormal(ProceduralComponents instance, ControlComponent original, List components, Random rand, int offset, int offsetY) {
|
||||
switch(this.coordBaseMode) {
|
||||
case 0: //South
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.maxX - offset, this.boundingBox.minY + offsetY, this.boundingBox.minZ - 1, 2, this.getComponentType());
|
||||
case 1: //West
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.maxX + 1, this.boundingBox.minY + offsetY, this.boundingBox.maxZ - offset, 3, this.getComponentType());
|
||||
case 2: //North
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.minX + offset, this.boundingBox.minY + offsetY, this.boundingBox.maxZ + 1, 0, this.getComponentType());
|
||||
case 3: //East
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.minX - 1, this.boundingBox.minY + offsetY, this.boundingBox.minZ + offset, 1, this.getComponentType());
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//Keep in mind for these methods: a given room would have its *actual entrance* opposite the side it is facing.
|
||||
/** Gets next component, to the West (-X) <i>relative to this component. */
|
||||
protected ProceduralComponent getNextComponentNX(ProceduralComponents instance, ControlComponent original, List components, Random rand, int offset, int offsetY) {
|
||||
switch(this.coordBaseMode) {
|
||||
case 0: //South
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.minX - 1, this.boundingBox.minY + offsetY, this.boundingBox.minZ + offset, 1, this.getComponentType());
|
||||
case 1: //West
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.maxX - offset, this.boundingBox.minY + offsetY, this.boundingBox.minZ - 1, 2, this.getComponentType());
|
||||
case 2: //North
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.maxX + 1, this.boundingBox.minY + offsetY, this.boundingBox.maxZ - offset, 3, this.getComponentType());
|
||||
case 3: //East
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.minX + offset, this.boundingBox.minY + offsetY, this.boundingBox.maxZ + 1, 0, this.getComponentType());
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets next component, to the East (+X) <i>relative to this component. */
|
||||
protected ProceduralComponent getNextComponentPX(ProceduralComponents instance, ControlComponent original, List components, Random rand, int offset, int offsetY) {
|
||||
switch(this.coordBaseMode) {
|
||||
case 0: //South
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.maxX + 1, this.boundingBox.minY + offsetY, this.boundingBox.maxZ - offset, 3, this.getComponentType() + 1);
|
||||
case 1: //West
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.minX + offset, this.boundingBox.minY + offsetY, this.boundingBox.maxZ + 1, 0, this.getComponentType() + 1);
|
||||
case 2: //North
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.minX - 1, this.boundingBox.minY + offsetY, this.boundingBox.minZ + offset, 1, this.getComponentType() + 1);
|
||||
case 3: //East
|
||||
return instance.getNextValidComponent(original, components, rand, this.boundingBox.maxX - offset, this.boundingBox.minY + offsetY, this.boundingBox.minZ - 1, 2, this.getComponentType() + 1);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Finds valid placement, using input information. Should be passed as a method reference to its respective Weight. */
|
||||
//Static so no override (cringe!)
|
||||
//public static ProceduralComponent findValidPlacement(List components, Random rand, int minX, int minY, int minZ, int coordMode, int componentType) { return null; }
|
||||
}
|
||||
|
||||
/** ProceduralComponent that can serve as a master "control component" for procedural generation and building of components. */
|
||||
public abstract static class ControlComponent extends ProceduralComponent {
|
||||
|
||||
public List queuedComponents = new ArrayList(); //List of all queued ProceduralComponents waiting to be built. Randomly iterated over until limits like component amt or dist are reached.
|
||||
public ProceduralComponent lastComponent = this; //Last component to be built. Used as input for the random selection's checks for specific components.
|
||||
|
||||
public ControlComponent() { }
|
||||
|
||||
public ControlComponent(int componentType) {
|
||||
super(componentType);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a new instance of this structureComponent, or null if not able to be placed.<br>Based on bounding box checks. */
|
||||
@FunctionalInterface
|
||||
interface instantiateStructure {
|
||||
ProceduralComponent findValidPlacement(List components, Random rand, int minX, int minY, int minZ, int coordMode, int componentType);
|
||||
}
|
||||
|
||||
protected static class Weight {
|
||||
|
||||
public final instantiateStructure lambda; //Read above
|
||||
|
||||
public final int weight; //Weight of this component
|
||||
public int instancesSpawned; //How many components spawned?
|
||||
public int instanceLimit; //Limit on amount of components: -1 for no limit
|
||||
|
||||
public Weight(int weight, int limit, instantiateStructure lambda) {
|
||||
this.weight = weight;
|
||||
this.instanceLimit = limit;
|
||||
this.lambda = lambda;
|
||||
}
|
||||
|
||||
//Checks if another structure can be spawned based on input data
|
||||
public boolean canSpawnStructure(int componentAmount, int coordMode, ProceduralComponent component) {
|
||||
return this.instanceLimit < 0 || this.instancesSpawned < this.instanceLimit;
|
||||
}
|
||||
|
||||
//Checks if another structure can be spawned at all (used to flag for removal from the list)
|
||||
public boolean canSpawnMoreStructures() {
|
||||
return this.instanceLimit < 0 || this.instancesSpawned < this.instanceLimit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user