From 7edbf615b65f7828737fb103ca00db253b543203 Mon Sep 17 00:00:00 2001 From: Vaern Date: Sat, 8 Oct 2022 15:15:41 -0700 Subject: [PATCH] Major refactoring, some fixes aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --- .../com/hbm/world/worldgen/MapGenBunker.java | 11 +- .../worldgen/components/BunkerComponents.java | 225 ++--------------- .../worldgen/components/CivilianFeatures.java | 10 +- .../{Feature.java => Component.java} | 18 +- .../components/MilitaryBaseFeatures.java | 4 +- .../worldgen/components/OfficeFeatures.java | 6 +- .../components/ProceduralComponents.java | 228 ++++++++++++++++++ .../worldgen/components/RuinFeatures.java | 8 +- 8 files changed, 283 insertions(+), 227 deletions(-) rename src/main/java/com/hbm/world/worldgen/components/{Feature.java => Component.java} (98%) create mode 100644 src/main/java/com/hbm/world/worldgen/components/ProceduralComponents.java diff --git a/src/main/java/com/hbm/world/worldgen/MapGenBunker.java b/src/main/java/com/hbm/world/worldgen/MapGenBunker.java index 665d2112e..669bf999d 100644 --- a/src/main/java/com/hbm/world/worldgen/MapGenBunker.java +++ b/src/main/java/com/hbm/world/worldgen/MapGenBunker.java @@ -1,10 +1,12 @@ package com.hbm.world.worldgen; +import java.util.List; import java.util.Random; import com.hbm.config.GeneralConfig; import com.hbm.world.worldgen.components.BunkerComponents; import com.hbm.world.worldgen.components.BunkerComponents.Atrium; +import com.hbm.world.worldgen.components.ProceduralComponents.ProceduralComponent; import net.minecraft.world.World; import net.minecraft.world.gen.structure.MapGenStructure; @@ -41,12 +43,13 @@ public class MapGenBunker extends MapGenStructure { this.components.add(atrium); atrium.buildComponent(atrium, components, rand); - /*List list = atrium.componentsToBuild; + List list = atrium.queuedComponents; while(!list.isEmpty()) { int k = rand.nextInt(list.size()); - Bunker component = (Bunker)list.remove(k); - component.buildComponent(atrium, list, rand); - }*/ + ProceduralComponent component = (ProceduralComponent)list.remove(k); + atrium.lastComponent = component; + component.buildComponent(atrium, this.components, rand); + } if(GeneralConfig.enableDebugMode) { System.out.print("[Debug] StructureStart at " + (chunkX * 16 + 8) + ", idfk lmao, " + (chunkZ * 16 + 8) + "\n[Debug] Components: "); diff --git a/src/main/java/com/hbm/world/worldgen/components/BunkerComponents.java b/src/main/java/com/hbm/world/worldgen/components/BunkerComponents.java index c92cbc363..67cef9a0f 100644 --- a/src/main/java/com/hbm/world/worldgen/components/BunkerComponents.java +++ b/src/main/java/com/hbm/world/worldgen/components/BunkerComponents.java @@ -14,23 +14,20 @@ import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -public class BunkerComponents { +public class BunkerComponents extends ProceduralComponents { - private static final Weight[] weightArray = new Weight[] { - new Weight(1, 50, (list, rand, x, y, z, mode, type) -> { StructureBoundingBox box = Bunker.getComponentToAddBoundingBox(x, y, z, -1, -1, 0, 5, 6, 15, mode); + protected static final Weight[] weightArray = new Weight[] { + new Weight(1, 50, (list, rand, x, y, z, mode, type) -> { StructureBoundingBox box = ProceduralComponent.getComponentToAddBoundingBox(x, y, z, -1, -1, 0, 5, 6, 15, mode); return box.minY > 10 && StructureComponent.findIntersecting(list, box) == null ? new Corridor(type, rand, box, mode) : null; }), - new Weight(2, -1, (list, rand, x, y, z, mode, type) -> { StructureBoundingBox box = Bunker.getComponentToAddBoundingBox(x, y, z, -1, -1, 0, 5, 6, 15, mode); - return box.minY > 10 && StructureComponent.findIntersecting(list, box) == null ? new Corridor(type, rand, box, mode) : null; }), - new Weight(1, -1, (list, rand, x, y, z, mode, type) -> { StructureBoundingBox box = Bunker.getComponentToAddBoundingBox(x, y, z, -1, -1, 0, 5, 6, 5, mode); + new Weight(2, -1, (list, rand, x, y, z, mode, type) -> { StructureBoundingBox box = ProceduralComponent.getComponentToAddBoundingBox(x, y, z, -1, -1, 0, 5, 6, 15, mode); + return box.minY > 10 && StructureComponent.findIntersecting(list, box) == null ? new Corridor(type, rand, box, mode) : null; }), + new Weight(1, -1, (list, rand, x, y, z, mode, type) -> { StructureBoundingBox box = ProceduralComponent.getComponentToAddBoundingBox(x, y, z, -1, -1, 0, 5, 6, 5, mode); return box.minY > 10 && StructureComponent.findIntersecting(list, box) == null ? new Intersection(type, rand, box, mode) : null; }), - new Weight(8, -1, (list, rand, x, y, z, mode, type) -> { StructureBoundingBox box = Bunker.getComponentToAddBoundingBox(x, y, z, -3, -1, 0, 9, 6, 17, mode); + new Weight(8, -1, (list, rand, x, y, z, mode, type) -> { StructureBoundingBox box = ProceduralComponent.getComponentToAddBoundingBox(x, y, z, -3, -1, 0, 9, 6, 17, mode); return box.minY > 10 && StructureComponent.findIntersecting(list, box) == null ? new WideCorridor(type, rand, box, mode) : null; }), }; - private static List componentWeightList; - static int totalWeight; - public static void prepareComponents() { componentWeightList = new ArrayList(); @@ -40,198 +37,21 @@ public class BunkerComponents { } } - private static boolean canAddStructurePieces() { - boolean flag = false; - totalWeight = 0; - Weight weight; - - for(Iterator iterator = componentWeightList.iterator(); iterator.hasNext(); totalWeight += weight.weight) { - weight = (Weight) iterator.next(); - - if(weight.instanceLimit >= 0 && weight.instancesSpawned < weight.instanceLimit) - flag = true; - } - - return flag; - } - - private static Bunker getWeightedComponent(StructureComponent original, List components, Random rand, int minX, int minY, int minZ, int coordMode, int componentType) { - - if(!canAddStructurePieces()) - return null; - - for(int i = 0; i < 5; i++) { - int value = rand.nextInt(totalWeight); - Iterator iterator = componentWeightList.iterator(); - - while(iterator.hasNext()) { - Weight weight = (Weight)iterator.next(); - value -= weight.weight; - - if(value < 0) { - if(!weight.canSpawnStructure(componentType)) - break; - - Bunker component = (Bunker) weight.lambda.findValidPlacement(components, rand, minX, minY, minZ, coordMode, componentType); - - if(component != null) { - weight.instancesSpawned++; - - if(!weight.canSpawnMoreStructures()) - componentWeightList.remove(weight); - - return component; - } - - } - } - } - - return null; - } - - private static StructureComponent getNextValidComponent(StructureComponent original, List components, Random rand, int minX, int minY, int minZ, int coordMode, int componentType) { - - if(components.size() > 50) - return null; - - if(Math.abs(minX - original.getBoundingBox().minX) <= 64 && Math.abs(minZ - original.getBoundingBox().minZ) <= 64) { - - StructureComponent structure = getWeightedComponent(original, components, rand, minX, minY, minZ, coordMode, componentType); - - if(structure != null) { - components.add(structure); //Adds component to structure start list - structure.buildComponent(original, components, rand); //no fucking clue why but doing it how mojang does it didn't work at all - } - - return structure; - } - - return null; - } - - static class Weight { - - public final instantiateStructure lambda; //i refuse to use some 🤓 ass method for getting the class from each PieceWeight - //here, we overengineer shit like real developers - - public final int weight; - public int instancesSpawned; - public int instanceLimit; - - 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) { - return this.instanceLimit < 0 || this.instanceLimit < 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; - } - - } - - /** Returns a new instance of this structureComponent, or null if not able to be placed. */ - @FunctionalInterface - interface instantiateStructure { - StructureComponent findValidPlacement(List components, Random rand, int minX, int minY, int minZ, int coordMode, int componentType); - } - - public abstract static class Bunker extends Feature { - - public Bunker() { } - - public Bunker(int componentType) { - super(componentType); //important to carry over, as it allows for hard limits on the amount of components. increment once for each new component. - } - - /** Gets next component in the direction this component is facing.
'original' refers to the initial starting component (hard distance limits), 'components' refers to the StructureStart list. */ - protected StructureComponent getNextComponentNormal(StructureComponent original, List components, Random rand, int offset, int offsetY) { - switch(this.coordBaseMode) { - case 0: //South - return getNextValidComponent(original, components, rand, this.boundingBox.minX + offset, this.boundingBox.minY + offsetY, this.boundingBox.maxZ + 1, this.coordBaseMode, this.getComponentType() + 1); - case 1: //West - return getNextValidComponent(original, components, rand, this.boundingBox.minX - 1, this.boundingBox.minY + offsetY, this.boundingBox.minZ + offset, this.coordBaseMode, this.getComponentType() + 1); - case 2: //North - return getNextValidComponent(original, components, rand, this.boundingBox.maxX - offset, this.boundingBox.minY + offsetY, this.boundingBox.minZ - 1, this.coordBaseMode, this.getComponentType() + 1); - case 3: //East - return getNextValidComponent(original, components, rand, this.boundingBox.maxX + 1, this.boundingBox.minY + offsetY, this.boundingBox.maxZ - offset, this.coordBaseMode, this.getComponentType() + 1); - 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) relative to this component. */ - protected StructureComponent getNextComponentNX(StructureComponent original, List components, Random rand, int offset, int offsetY) { - switch(this.coordBaseMode) { - case 0: //South - return getNextValidComponent(original, components, rand, this.boundingBox.minX - 1, this.boundingBox.minY + offsetY, this.boundingBox.minZ + offset, 1, this.getComponentType() + 1); - case 1: //West - return getNextValidComponent(original, components, rand, this.boundingBox.maxX - offset, this.boundingBox.minY + offsetY, this.boundingBox.minZ - 1, 2, this.getComponentType() + 1); - case 2: //North - return getNextValidComponent(original, components, rand, this.boundingBox.maxX + 1, this.boundingBox.minY + offsetY, this.boundingBox.maxZ - offset, 3, this.getComponentType() + 1); - case 3: //East - return getNextValidComponent(original, components, rand, this.boundingBox.minX + offset, this.boundingBox.minY + offsetY, this.boundingBox.maxZ + 1, 0, this.getComponentType() + 1); - default: - return null; - } - } - - /** Gets next component, to the East (+X) relative to this component. */ - protected StructureComponent getNextComponentPX(StructureComponent original, List components, Random rand, int offset, int offsetY) { - switch(this.coordBaseMode) { - case 0: //South - return getNextValidComponent(original, components, rand, this.boundingBox.maxX + 1, this.boundingBox.minY + offsetY, this.boundingBox.maxZ - offset, 1, this.getComponentType() + 1); - case 1: //West - return getNextValidComponent(original, components, rand, this.boundingBox.minZ + offset, this.boundingBox.minY + offsetY, this.boundingBox.maxZ + 1, 2, this.getComponentType() + 1); - case 2: //North - return getNextValidComponent(original, components, rand, this.boundingBox.minX - 1, this.boundingBox.minY + offsetY, this.boundingBox.minZ + offset, 3, this.getComponentType() + 1); - case 3: //East - return getNextValidComponent(original, components, rand, this.boundingBox.maxX - offset, this.boundingBox.minY + offsetY, this.boundingBox.minZ - 1, 0, this.getComponentType() + 1); - default: - 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) { - System.out.print(posX + ", " + posY + ", " + posZ + ", CBM: " + coordMode); - switch(coordMode) { //fixed - 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); - } - } - } - - public static class Atrium extends Bunker { + public static class Atrium extends ControlComponent { public Atrium() { } public Atrium(int componentType, Random rand, int posX, int posZ) { //TODO: change basically everything about this component super(componentType); this.coordBaseMode = rand.nextInt(4); - this.boundingBox = new StructureBoundingBox(posX, 64, posZ, posX + 4, 68, posZ + 4); + this.boundingBox = new StructureBoundingBox(posX, 64, posZ, posX + 8, 68, posZ + 8); } @Override - public void buildComponent(StructureComponent original, List components, Random rand) { - getNextComponentNormal(original, components, rand, 1, 1); - getNextComponentNX(original, components, rand, 1, 1); - getNextComponentPX(original, components, rand, 1, 1); + public void buildComponent(ControlComponent original, List components, Random rand) { + getNextComponentNormal(original, components, rand, 3, 1); + getNextComponentNX(original, components, rand, 3, 1); + getNextComponentPX(original, components, rand, 3, 1); } @Override @@ -240,7 +60,7 @@ public class BunkerComponents { } } - public static class Corridor extends Bunker { + public static class Corridor extends ProceduralComponent { boolean expandsNX = false; boolean expandsPX = false; @@ -270,7 +90,7 @@ public class BunkerComponents { } @Override - public void buildComponent(StructureComponent original, List components, Random rand) { + public void buildComponent(ControlComponent original, List components, Random rand) { StructureComponent component = getNextComponentNormal(original, components, rand, 1, 1); extendsPZ = component != null; @@ -375,7 +195,7 @@ public class BunkerComponents { } @Override - public void buildComponent(StructureComponent original, List components, Random rand) { + public void buildComponent(ControlComponent original, List components, Random rand) { StructureComponent component = getNextComponentNormal(original, components, rand, 3, 1); extendsPZ = component != null; @@ -511,7 +331,7 @@ public class BunkerComponents { } } - public static class Turn extends Bunker { + public static class Turn extends ProceduralComponent { public Turn() { } @@ -542,7 +362,7 @@ public class BunkerComponents { } } - public static class Intersection extends Bunker { + public static class Intersection extends ProceduralComponent { boolean opensNX = false; boolean opensPX = false; @@ -558,7 +378,7 @@ public class BunkerComponents { } @Override - public void buildComponent(StructureComponent original, List components, Random rand) { + public void buildComponent(ControlComponent original, List components, Random rand) { if(rand.nextInt(3) != 0) { StructureComponent component = getNextComponentNormal(original, components, rand, 1, 1); opensPZ = component != null; @@ -595,6 +415,7 @@ public class BunkerComponents { //Floor fillWithBlocks(world, box, 1, 0, 0, 3, 0, 3, ModBlocks.deco_titanium); //Ceiling + int pillarMetaWE = getPillarMeta(4); int pillarMetaNS = getPillarMeta(8); fillWithBlocks(world, box, 3, 4, 0, 3, 4, 1, ModBlocks.reinforced_brick); @@ -610,7 +431,7 @@ public class BunkerComponents { if(opensPZ) { fillWithBlocks(world, box, 1, 0, 4, 3, 0, 4, ModBlocks.deco_titanium); //Floor fillWithBlocks(world, box, 1, 4, 3, 1, 4, 4, ModBlocks.reinforced_brick); //Ceiling - fillWithMetadataBlocks(world, box, 2, 4, 3, 2, 4, 4, ModBlocks.concrete_pillar, 8); + fillWithMetadataBlocks(world, box, 2, 4, 3, 2, 4, 4, ModBlocks.concrete_pillar, pillarMetaNS); fillWithBlocks(world, box, 3, 4, 3, 3, 4, 4, ModBlocks.reinforced_brick); fillWithAir(world, box, 1, 1, 4, 3, 3, 4); //Opening } else { @@ -623,7 +444,7 @@ public class BunkerComponents { if(opensNX) { fillWithBlocks(world, box, 0, 0, 1, 0, 0, 3, ModBlocks.deco_titanium); //Floor placeBlockAtCurrentPosition(world, ModBlocks.reinforced_brick, 0, 0, 4, 1, box); //Ceiling - fillWithMetadataBlocks(world, box, 0, 4, 2, 1, 4, 2, ModBlocks.concrete_pillar, 4); + fillWithMetadataBlocks(world, box, 0, 4, 2, 1, 4, 2, ModBlocks.concrete_pillar, pillarMetaWE); placeBlockAtCurrentPosition(world, ModBlocks.reinforced_brick, 0, 0, 4, 3, box); fillWithAir(world, box, 0, 1, 1, 0, 3, 3); //Opening } else { @@ -636,7 +457,7 @@ public class BunkerComponents { if(opensPX) { fillWithBlocks(world, box, 4, 0, 1, 4, 0, 3, ModBlocks.deco_titanium); //Floor placeBlockAtCurrentPosition(world, ModBlocks.reinforced_brick, 0, 4, 4, 1, box); //Ceiling - fillWithMetadataBlocks(world, box, 3, 4, 2, 4, 4, 2, ModBlocks.concrete_pillar, 4); + fillWithMetadataBlocks(world, box, 3, 4, 2, 4, 4, 2, ModBlocks.concrete_pillar, pillarMetaWE); placeBlockAtCurrentPosition(world, ModBlocks.reinforced_brick, 0, 4, 4, 3, box); fillWithAir(world, box, 4, 1, 1, 4, 3, 3); //Opening } else { diff --git a/src/main/java/com/hbm/world/worldgen/components/CivilianFeatures.java b/src/main/java/com/hbm/world/worldgen/components/CivilianFeatures.java index b18789236..4110a1294 100644 --- a/src/main/java/com/hbm/world/worldgen/components/CivilianFeatures.java +++ b/src/main/java/com/hbm/world/worldgen/components/CivilianFeatures.java @@ -22,7 +22,7 @@ import net.minecraft.world.gen.structure.StructureBoundingBox; public class CivilianFeatures { /** Sandstone Ruin 1 */ - public static class NTMHouse1 extends Feature { + public static class NTMHouse1 extends Component { private boolean hasPlacedChest; @@ -120,7 +120,7 @@ public class CivilianFeatures { } - public static class NTMHouse2 extends Feature { + public static class NTMHouse2 extends Component { private static Sandstone RandomSandstone = new Sandstone(); @@ -264,7 +264,7 @@ public class CivilianFeatures { } } - public static class NTMLab1 extends Feature { + public static class NTMLab1 extends Component { private static ConcreteBricks RandomConcreteBricks = new ConcreteBricks(); private static LabTiles RandomLabTiles = new LabTiles(); @@ -391,7 +391,7 @@ public class CivilianFeatures { } } - public static class NTMLab2 extends Feature { + public static class NTMLab2 extends Component { private static SuperConcrete RandomSuperConcrete = new SuperConcrete(); private static ConcreteBricks RandomConcreteBricks = new ConcreteBricks(); @@ -565,7 +565,7 @@ public class CivilianFeatures { } } - public static class NTMWorkshop1 extends Feature { + public static class NTMWorkshop1 extends Component { private static SuperConcrete RandomSuperConcrete = new SuperConcrete(); diff --git a/src/main/java/com/hbm/world/worldgen/components/Feature.java b/src/main/java/com/hbm/world/worldgen/components/Component.java similarity index 98% rename from src/main/java/com/hbm/world/worldgen/components/Feature.java rename to src/main/java/com/hbm/world/worldgen/components/Component.java index 080aaea42..b6eb382c0 100644 --- a/src/main/java/com/hbm/world/worldgen/components/Feature.java +++ b/src/main/java/com/hbm/world/worldgen/components/Component.java @@ -23,7 +23,7 @@ import net.minecraft.world.World; import net.minecraft.world.gen.structure.StructureBoundingBox; import net.minecraft.world.gen.structure.StructureComponent; -abstract public class Feature extends StructureComponent { +abstract public class Component extends StructureComponent { /** The size of the bounding box for this feature in the X axis */ protected int sizeX; /** The size of the bounding box for this feature in the Y axis */ @@ -33,15 +33,15 @@ abstract public class Feature extends StructureComponent { /** Average height (Presumably stands for height position) */ protected int hpos = -1; - protected Feature() { + protected Component() { super(0); } - protected Feature(int componentType) { + protected Component(int componentType) { super(componentType); } - protected Feature(Random rand, int minX, int minY, int minZ, int maxX, int maxY, int maxZ ) { + protected Component(Random rand, int minX, int minY, int minZ, int maxX, int maxY, int maxZ ) { super(0); this.sizeX = maxX; this.sizeY = maxY; @@ -105,6 +105,10 @@ abstract public class Feature extends StructureComponent { return true; } + public int getCoordMode() { + return this.coordBaseMode; + } + /** Metadata for Decoration Methods **/ /** @@ -689,11 +693,11 @@ abstract public class Feature extends StructureComponent { public void selectBlocks(Random rand, int posX, int posY, int posZ, boolean p_75062_5_) { float chance = rand.nextFloat(); - if(chance < 0.2F) { + if(chance < 0.4F) { this.field_151562_a = ModBlocks.brick_concrete; - } else if (chance < 0.55F) { + } else if (chance < 0.7F) { this.field_151562_a = ModBlocks.brick_concrete_mossy; - } else if (chance < 0.75F) { + } else if (chance < 0.9F) { this.field_151562_a = ModBlocks.brick_concrete_cracked; } else { this.field_151562_a = ModBlocks.brick_concrete_broken; diff --git a/src/main/java/com/hbm/world/worldgen/components/MilitaryBaseFeatures.java b/src/main/java/com/hbm/world/worldgen/components/MilitaryBaseFeatures.java index 27571adf5..06acabe2f 100644 --- a/src/main/java/com/hbm/world/worldgen/components/MilitaryBaseFeatures.java +++ b/src/main/java/com/hbm/world/worldgen/components/MilitaryBaseFeatures.java @@ -48,7 +48,7 @@ public class MilitaryBaseFeatures { return chunkPos; } - public static class BasicHelipad extends Feature { + public static class BasicHelipad extends Component { public BasicHelipad() { super(); } @@ -100,7 +100,7 @@ public class MilitaryBaseFeatures { } - public static class RadioShack extends Feature { + public static class RadioShack extends Component { private static LabTiles RandomLabTiles = new LabTiles(); private static ConcreteBricks ConcreteBricks = new ConcreteBricks(); diff --git a/src/main/java/com/hbm/world/worldgen/components/OfficeFeatures.java b/src/main/java/com/hbm/world/worldgen/components/OfficeFeatures.java index fddcd5037..32c5bf866 100644 --- a/src/main/java/com/hbm/world/worldgen/components/OfficeFeatures.java +++ b/src/main/java/com/hbm/world/worldgen/components/OfficeFeatures.java @@ -5,7 +5,7 @@ import java.util.Random; import com.hbm.blocks.ModBlocks; import com.hbm.lib.HbmChestContents; import com.hbm.util.LootGenerator; -import com.hbm.world.worldgen.components.Feature.ConcreteBricks; +import com.hbm.world.worldgen.components.Component.ConcreteBricks; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; @@ -15,7 +15,7 @@ import net.minecraft.world.gen.structure.StructureBoundingBox; //Oh my fucking god TM public class OfficeFeatures { - public static class LargeOffice extends Feature { + public static class LargeOffice extends Component { private static ConcreteBricks ConcreteBricks = new ConcreteBricks(); @@ -216,7 +216,7 @@ public class OfficeFeatures { } //bob i could kiss you - public static class LargeOfficeCorner extends Feature { + public static class LargeOfficeCorner extends Component { private static ConcreteBricks ConcreteBricks = new ConcreteBricks(); diff --git a/src/main/java/com/hbm/world/worldgen/components/ProceduralComponents.java b/src/main/java/com/hbm/world/worldgen/components/ProceduralComponents.java new file mode 100644 index 000000000..57cfd5336 --- /dev/null +++ b/src/main/java/com/hbm/world/worldgen/components/ProceduralComponents.java @@ -0,0 +1,228 @@ +package com.hbm.world.worldgen.components; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +import com.hbm.world.worldgen.components.ProceduralComponents.ControlComponent; + +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraft.world.gen.structure.StructureComponent; + +public abstract class ProceduralComponents { + + protected static List componentWeightList; + static int totalWeight; + + /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * The two methods/fields below *must* be recreated in the subclasses. + * Due to poor language design, Java does not allow the overriding/creation of static abstract methods; + * due to reasonable language design, Java does not allow overriding abstract fields. + * getWeightArray() should contain an array with Weight(s) for your components. + */ + + //protected static final Weight[] weightArray = new Weight[] { }; + + /*public static void prepareComponents() { + componentWeightList = new ArrayList(); + + for(int i = 0; i < weightArray.length; i++) { + weightArray[i].instancesSpawned = 0; + componentWeightList.add(weightArray[i]); + } + }*/ + + protected static boolean canAddStructurePieces() { + boolean flag = false; + 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; + } + + protected static ProceduralComponent getWeightedComponent(ControlComponent original, List components, Random rand, int minX, int minY, int minZ, int coordMode, int componentType) { + + if(!canAddStructurePieces()) + 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 static ProceduralComponent getNextValidComponent(ControlComponent original, List components, Random rand, int minX, int minY, int minZ, int coordMode, int componentType) { + + if(components.size() > 50) //Hard limit on amount of components + return null; + + if(Math.abs(minX - original.getBoundingBox().minX) <= 64 && Math.abs(minZ - original.getBoundingBox().minZ) <= 64) { //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; + } + + /** 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(ControlComponent original, List components, Random rand) { } + + /** Gets next component in the direction this component is facing.
'original' refers to the initial starting component (hard distance limits), 'components' refers to the StructureStart list. */ + protected ProceduralComponent getNextComponentNormal(ControlComponent original, List components, Random rand, int offset, int offsetY) { + switch(this.coordBaseMode) { + case 0: //South + return getNextValidComponent(original, components, rand, this.boundingBox.minX + offset, this.boundingBox.minY + offsetY, this.boundingBox.maxZ + 1, this.coordBaseMode, this.getComponentType()); + case 1: //West + return getNextValidComponent(original, components, rand, this.boundingBox.minX - 1, this.boundingBox.minY + offsetY, this.boundingBox.minZ + offset, this.coordBaseMode, this.getComponentType()); + case 2: //North + return getNextValidComponent(original, components, rand, this.boundingBox.maxX - offset, this.boundingBox.minY + offsetY, this.boundingBox.minZ - 1, this.coordBaseMode, this.getComponentType()); + case 3: //East + return getNextValidComponent(original, components, rand, this.boundingBox.maxX + 1, this.boundingBox.minY + offsetY, this.boundingBox.maxZ - offset, this.coordBaseMode, 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) relative to this component. */ + protected ProceduralComponent getNextComponentNX(ControlComponent original, List components, Random rand, int offset, int offsetY) { + switch(this.coordBaseMode) { + case 0: //South + return getNextValidComponent(original, components, rand, this.boundingBox.minX - 1, this.boundingBox.minY + offsetY, this.boundingBox.minZ + offset, 1, this.getComponentType()); + case 1: //West + return getNextValidComponent(original, components, rand, this.boundingBox.maxX - offset, this.boundingBox.minY + offsetY, this.boundingBox.minZ - 1, 2, this.getComponentType()); + case 2: //North + return getNextValidComponent(original, components, rand, this.boundingBox.maxX + 1, this.boundingBox.minY + offsetY, this.boundingBox.maxZ - offset, 3, this.getComponentType()); + case 3: //East + return 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) relative to this component. */ + protected ProceduralComponent getNextComponentPX(ControlComponent original, List components, Random rand, int offset, int offsetY) { + switch(this.coordBaseMode) { + case 0: //South + return getNextValidComponent(original, components, rand, this.boundingBox.maxX + 1, this.boundingBox.minY + offsetY, this.boundingBox.maxZ - offset, 1, this.getComponentType() + 1); + case 1: //West + return getNextValidComponent(original, components, rand, this.boundingBox.minZ + offset, this.boundingBox.minY + offsetY, this.boundingBox.maxZ + 1, 2, this.getComponentType() + 1); + case 2: //North + return getNextValidComponent(original, components, rand, this.boundingBox.minX - 1, this.boundingBox.minY + offsetY, this.boundingBox.minZ + offset, 3, this.getComponentType() + 1); + case 3: //East + return getNextValidComponent(original, components, rand, this.boundingBox.maxX - offset, this.boundingBox.minY + offsetY, this.boundingBox.minZ - 1, 0, this.getComponentType() + 1); + default: + 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); + } + } + } + + /** 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.
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.instanceLimit < 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; + } + + } + +} diff --git a/src/main/java/com/hbm/world/worldgen/components/RuinFeatures.java b/src/main/java/com/hbm/world/worldgen/components/RuinFeatures.java index 47953d9da..6ba87e6fc 100644 --- a/src/main/java/com/hbm/world/worldgen/components/RuinFeatures.java +++ b/src/main/java/com/hbm/world/worldgen/components/RuinFeatures.java @@ -10,7 +10,7 @@ import net.minecraft.world.gen.structure.StructureBoundingBox; public class RuinFeatures { - public static class NTMRuin1 extends Feature { + public static class NTMRuin1 extends Component { private static ConcreteBricks RandomConcreteBricks = new ConcreteBricks(); @@ -82,7 +82,7 @@ public class RuinFeatures { } } - public static class NTMRuin2 extends Feature { + public static class NTMRuin2 extends Component { private static ConcreteBricks RandomConcreteBricks = new ConcreteBricks(); @@ -145,7 +145,7 @@ public class RuinFeatures { } } - public static class NTMRuin3 extends Feature { + public static class NTMRuin3 extends Component { private static ConcreteBricks RandomConcreteBricks = new ConcreteBricks(); @@ -202,7 +202,7 @@ public class RuinFeatures { } } - public static class NTMRuin4 extends Feature { + public static class NTMRuin4 extends Component { private static ConcreteBricks RandomConcreteBricks = new ConcreteBricks();