aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/galacticgreg/WorldGeneratorSpace.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/galacticgreg/WorldGeneratorSpace.java')
-rw-r--r--src/main/java/galacticgreg/WorldGeneratorSpace.java564
1 files changed, 564 insertions, 0 deletions
diff --git a/src/main/java/galacticgreg/WorldGeneratorSpace.java b/src/main/java/galacticgreg/WorldGeneratorSpace.java
new file mode 100644
index 0000000000..336900326c
--- /dev/null
+++ b/src/main/java/galacticgreg/WorldGeneratorSpace.java
@@ -0,0 +1,564 @@
+package galacticgreg;
+
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.util.Vec3;
+import net.minecraft.util.WeightedRandomChestContent;
+import net.minecraft.world.World;
+import net.minecraft.world.biome.BiomeGenBase;
+import net.minecraft.world.chunk.Chunk;
+import net.minecraft.world.chunk.IChunkProvider;
+import net.minecraftforge.common.ChestGenHooks;
+
+import cpw.mods.fml.common.IWorldGenerator;
+import cpw.mods.fml.common.eventhandler.EventBus;
+import cpw.mods.fml.common.registry.GameRegistry;
+import galacticgreg.api.AsteroidBlockComb;
+import galacticgreg.api.BlockMetaComb;
+import galacticgreg.api.Enums;
+import galacticgreg.api.GTOreTypes;
+import galacticgreg.api.ISpaceObjectGenerator;
+import galacticgreg.api.ModDimensionDef;
+import galacticgreg.api.SpecialBlockComb;
+import galacticgreg.api.StructureInformation;
+import galacticgreg.auxiliary.GTOreGroup;
+import galacticgreg.dynconfig.DynamicDimensionConfig;
+import galacticgreg.registry.GalacticGregRegistry;
+import gregtech.api.util.GTLog;
+import gregtech.api.world.GTWorldgen;
+import gregtech.common.GTWorldgenerator;
+
+public class WorldGeneratorSpace implements IWorldGenerator {
+
+ public static boolean sAsteroids = true;
+ private final EventBus eventBus = new EventBus();
+ private World worldObj;
+
+ private int chunkX;
+ private int chunkZ;
+ private int mSize = 100;
+
+ private long mProfilingStart;
+ private long mProfilingEnd;
+
+ public WorldGeneratorSpace() {
+ GameRegistry.registerWorldGenerator(this, Integer.MAX_VALUE);
+ }
+
+ public void generate(Random pRandom, int pX, int pZ, World pWorld, IChunkProvider pChunkGenerator,
+ IChunkProvider pChunkProvider) {
+ pX *= 16;
+ pZ *= 16;
+
+ String tBiome = pWorld.getBiomeGenForCoords(pX + 8, pZ + 8).biomeName;
+ pRandom = new Random(pRandom.nextInt());
+ if (tBiome == null) {
+ tBiome = BiomeGenBase.plains.biomeName;
+ }
+ GalacticGreg.Logger
+ .trace("Triggered generate: [ChunkGenerator %s] [Biome %s]", pChunkGenerator.toString(), tBiome);
+
+ ModDimensionDef tDimDef = GalacticGregRegistry.getDimensionTypeByChunkGenerator(pChunkGenerator);
+
+ if (tDimDef == null) {
+ GalacticGreg.Logger.trace(
+ "Ignoring ChunkGenerator type %s as there is no definition for it in the registry",
+ pChunkGenerator.toString());
+ return;
+ } else {
+ GalacticGreg.Logger.trace("Selected DimDef: [%s]", tDimDef.getDimIdentifier());
+ }
+
+ /*
+ * In some later addons maybe, not for now. Ignoring Biome-based worldgen String tBiome =
+ * pWorld.getBiomeGenForCoords(pX + 8, pZ + 8).biomeName; pRandom = new Random(pRandom.nextInt()); if (tBiome ==
+ * null) { tBiome = BiomeGenBase.plains.biomeName; }
+ */
+
+ if (tDimDef.getDimensionType() != Enums.DimensionType.Planet) {
+ if (tDimDef.getRandomAsteroidMaterial() == null) GalacticGreg.Logger.error(
+ "Dimension [%s] is set to Asteroids, but no asteroid material is specified! Nothing will generate",
+ tDimDef.getDimensionName());
+ else Generate_Asteroids(tDimDef, pRandom, pWorld, pX, pZ);
+ } else if (tDimDef.getDimensionType() != Enums.DimensionType.Asteroid) {
+ Generate_OreVeins(tDimDef, pRandom, pWorld, pX, pZ, "", pChunkGenerator, pChunkProvider);
+ }
+
+ Chunk tChunk = pWorld.getChunkFromBlockCoords(pX, pZ);
+ if (tChunk != null) {
+ tChunk.isModified = true;
+ }
+ }
+
+ private void Generate_Asteroids(ModDimensionDef pDimensionDef, Random pRandom, World pWorld, int pX, int pZ) {
+ GalacticGreg.Logger.trace("Running asteroid-gen in Dim %s", pDimensionDef.getDimIdentifier());
+
+ DynamicDimensionConfig.AsteroidConfig tAConf = DynamicDimensionConfig.getAsteroidConfig(pDimensionDef);
+ if (tAConf == null) {
+ GalacticGreg.Logger.error(
+ "Dimension %s is set to asteroid, but no config object can be found. Skipping!",
+ pDimensionDef.getDimIdentifier());
+ return;
+ } else {
+ GalacticGreg.Logger.trace("Asteroid probability: %d", tAConf.Probability);
+ }
+
+ if ((tAConf.Probability <= 1) || (pRandom.nextInt(tAConf.Probability) == 0)) {
+ GalacticGreg.Logger.trace("Generating asteroid NOW");
+ // ---------------------------
+ if (GalacticGreg.GalacticConfig.ProfileOreGen) mProfilingStart = System.currentTimeMillis();
+ // -----------------------------
+
+ // Get Random position
+ int tX = pX + pRandom.nextInt(16);
+ int tY = 50 + pRandom.nextInt(200 - 50);
+ int tZ = pZ + pRandom.nextInt(16);
+
+ // Check if position is free
+ if ((pWorld.getBlock(tX, tY, tZ)
+ .isAir(pWorld, tX, tY, tZ))) {
+
+ int tCustomAsteroidOffset = -1;
+ int tGraniteMeta = 0;
+
+ // Select Random OreGroup and Asteroid Material
+ GTOreGroup tOreGroup = WorldgenOreLayerSpace.getRandomOreGroup(pDimensionDef, pRandom, true);
+ AsteroidBlockComb tABComb = pDimensionDef.getRandomAsteroidMaterial();
+ if (tABComb == null) return;
+
+ // Fill Vars for random Asteroid
+ Block tFinalAsteroidBlock = tABComb.getBlock();
+ int tFinalAsteroidBlockMeta = tABComb.getMeta();
+ int tFinalOreOffset = tABComb.getOreMaterial()
+ .getOffset();
+ int tFinalUpdateMode = tABComb.getOreMaterial()
+ .getUpdateMode();
+ GalacticGreg.Logger.debug(
+ "Asteroid will be build with: Block: [%s] OreType: [%s]",
+ Block.blockRegistry.getNameForObject(tABComb.getBlock()),
+ tABComb.getOreMaterial()
+ .toString());
+
+ // get random Ore-asteroid generator from the list of registered generators
+ ISpaceObjectGenerator aGen = pDimensionDef.getRandomSOGenerator(Enums.SpaceObjectType.OreAsteroid);
+ if (aGen == null) {
+ GalacticGreg.Logger.ot_error(
+ "GalacticGreg.Generate_Asteroids.NoSOGenFound",
+ "No SpaceObjectGenerator has been registered for type ORE_ASTEROID in Dimension %s. Nothing will generate",
+ pDimensionDef.getDimensionName());
+ return;
+ }
+
+ aGen.reset();
+ aGen.setCenterPoint(tX, tY, tZ);
+ aGen.randomize(tAConf.MinSize, tAConf.MaxSize); // Initialize random values and set size
+ aGen.calculate(); // Calculate structure
+
+ // Random loot-chest somewhere in the asteroid
+ Vec3 tChestPosition = Vec3.createVectorHelper(0, 0, 0);
+ boolean tDoLootChest = false;
+ int tNumLootItems = 0;
+ if (tAConf.LootChestChance > 0) {
+ GalacticGreg.Logger.trace("Random loot chest enabled, flipping the coin");
+ int tChance = pRandom.nextInt(100); // Loot chest is 1 in 100 (Was: 1:1000 which actually never
+ // happend)
+ if (tAConf.LootChestChance >= tChance) {
+ GalacticGreg.Logger.debug("We got a match. Preparing to generate the loot chest");
+ // Get amount of items for the loot chests, randomize it (1-num) if enabled
+ if (tAConf.RandomizeNumLootItems) tNumLootItems = pRandom.nextInt(tAConf.NumLootItems - 1) + 1;
+ else tNumLootItems = tAConf.NumLootItems;
+
+ GalacticGreg.Logger
+ .debug(String.format("Loot chest random item count will be: %d", tNumLootItems));
+
+ // try to find any block that is not on the asteroids outer-shell
+ GalacticGreg.Logger.trace("Starting lookup for valid asteroid-block for the chest");
+ for (int x = 0; x < 64; x++) // 64 enough? Should be
+ {
+ int tRndBlock = pRandom.nextInt(
+ aGen.getStructure()
+ .size());
+ StructureInformation tChestSI = aGen.getStructure()
+ .get(tRndBlock);
+ if (tChestSI.getBlockPosition() != Enums.TargetBlockPosition.AsteroidShell) {
+ GalacticGreg.Logger.debug(
+ String.format(
+ "Chest position found [x:%d y:%d z:%d]",
+ tChestSI.getX(),
+ tChestSI.getY(),
+ tChestSI.getZ()));
+ // Found valid position "Somewhere" in the asteroid, set position...
+ tChestPosition = Vec3
+ .createVectorHelper(tChestSI.getX(), tChestSI.getY(), tChestSI.getZ());
+ // .. and set CreateFlag to true
+ tDoLootChest = true;
+ break;
+ }
+ }
+ }
+ }
+
+ // Now build the structure
+ GalacticGreg.Logger.trace("Now generating Space-Structure");
+ for (StructureInformation si : aGen.getStructure()) {
+ // Only replace airblocks
+ if (pWorld.isAirBlock(si.getX(), si.getY(), si.getZ())) {
+ // === Loot-chest generator >>
+ if (tDoLootChest) // If gen-lootchest enabled...
+ {
+ // Check if current x/y/z is the location where the chest shall be created
+ if ((int) tChestPosition.xCoord == si.getX() && (int) tChestPosition.yCoord == si.getY()
+ && (int) tChestPosition.zCoord == si.getZ()) {
+ GalacticGreg.Logger.trace("Now generating LootChest and contents");
+ // Get items for the configured loot-table
+ WeightedRandomChestContent[] tRandomLoot = ChestGenHooks
+ .getItems(DynamicDimensionConfig.getLootChestTable(tAConf), pRandom);
+
+ // Get chest-block to spawn
+ BlockMetaComb tTargetChestType = GalacticGreg.GalacticConfig.CustomLootChest;
+
+ // Place down the chest
+ if (tTargetChestType.getMeta() > 0) pWorld.setBlock(
+ si.getX(),
+ si.getY(),
+ si.getZ(),
+ tTargetChestType.getBlock(),
+ tTargetChestType.getMeta(),
+ 2);
+ else pWorld.setBlock(si.getX(), si.getY(), si.getZ(), tTargetChestType.getBlock());
+
+ // Retrieve the TEs IInventory that should've been created
+ IInventory entityChestInventory = (IInventory) pWorld
+ .getTileEntity(si.getX(), si.getY(), si.getZ());
+ // If it's not null...
+ if (entityChestInventory != null) {
+ // and if we're on the server...
+ if (!pWorld.isRemote) {
+ // Fill the chest with stuffz!
+ WeightedRandomChestContent.generateChestContents(
+ pRandom,
+ tRandomLoot,
+ entityChestInventory,
+ tNumLootItems);
+ GalacticGreg.Logger.trace("Loot chest successfully generated");
+ }
+ } else {
+ // Something made a boo..
+ GalacticGreg.Logger.warn(
+ "Could not create lootchest at X[%d] Y[%d] Z[%d]. getTileEntity() returned null",
+ si.getX(),
+ si.getY(),
+ si.getZ());
+ }
+ // Make sure we never compare coordinates again (for this asteroid/Structure)
+ tDoLootChest = false;
+ // Do some debug logging
+ GalacticGreg.Logger
+ .debug("Generated LootChest at X[%d] Y[%d] Z[%d]", si.getX(), si.getY(), si.getZ());
+ // And skip the rest of this function
+ continue;
+ }
+ }
+ // << Loot-chest generator ===
+
+ // === Ore generator >>
+ boolean tPlacedOreBlock = false;
+ // If a valid oregroup has been selected (more than 0 ore-veins are enabled for this dim)
+ if (tOreGroup != null) {
+ // GalacticGreg.Logger.trace("tOreGoup is populated, continuing");
+ // Choose a number between 0 and 100
+ int ranOre = pRandom.nextInt(100);
+ int tFinalOreMeta = 0;
+
+ // If choosen number is below the configured orechance, do random between and sporadic
+ if (ranOre < tAConf.OreChance) {
+ if (pRandom.nextBoolean()) {
+ // Only take as final value if meta is not zero
+ if (tOreGroup.SporadicBetweenMeta > 0)
+ tFinalOreMeta = tOreGroup.SporadicBetweenMeta;
+ } else {
+ // Only take as final value if meta is not zero
+ if (tOreGroup.SporadicAroundMeta > 0) tFinalOreMeta = tOreGroup.SporadicAroundMeta;
+ }
+ }
+ // If choosen number is below the configured orechance, do random primary and secondary
+ // We use an offset here, so this part is always higher than the first check.
+ else if (ranOre < tAConf.OreChance + tAConf.OrePrimaryOffset) {
+ if (pRandom.nextBoolean()) {
+ // Only take as final value if meta is not zero
+ if (tOreGroup.PrimaryMeta > 0) tFinalOreMeta = tOreGroup.PrimaryMeta;
+ } else {
+ // Only take as final value if meta is not zero
+ if (tOreGroup.SecondaryMeta > 0) tFinalOreMeta = tOreGroup.SecondaryMeta;
+ }
+ }
+
+ // if the final oreMeta has been found...
+ // GalacticGreg.Logger.info("tFinalOreMeta is %d", tFinalOreMeta);
+ if (tFinalOreMeta > 0) {
+ // make sure we obey the configured "HiddenOres" setting (No ores on the shell)
+ if (tAConf.HiddenOres
+ && (si.getBlockPosition() == Enums.TargetBlockPosition.AsteroidShell)) {
+ // Ore would be placed around the shell, which is disabled (hiddenores)
+ GalacticGreg.Logger.trace(
+ "Skipping ore-placement event (HiddenOres=true; TargetBlockPosition=AsteroidShell)");
+ } else {
+ // try to place the ore block. The result is stored in tPlacedOreBlock
+ tPlacedOreBlock = TileEntitySpaceOres.setOuterSpaceOreBlock(
+ pDimensionDef,
+ pWorld,
+ si.getX(),
+ si.getY(),
+ si.getZ(),
+ tOreGroup.SecondaryMeta,
+ true,
+ tFinalOreOffset);
+ }
+ }
+ }
+ // << Ore generator ===
+
+ // === Additional special blocks >>
+ // If no ore-block has been placed yet...
+ if (!tPlacedOreBlock) {
+ // try to spawn special blocks
+ boolean tFlag = doGenerateSpecialBlocks(
+ pDimensionDef,
+ pRandom,
+ pWorld,
+ tAConf,
+ si.getX(),
+ si.getY(),
+ si.getZ(),
+ si.getBlockPosition());
+
+ // No special block placed? Try smallores
+ if (tFlag) tFlag = doGenerateSmallOreBlock(
+ pDimensionDef,
+ pRandom,
+ pWorld,
+ tAConf,
+ si.getX(),
+ si.getY(),
+ si.getZ(),
+ tFinalOreOffset);
+
+ // no smallores either? do normal block
+ if (tFlag) pWorld.setBlock(
+ si.getX(),
+ si.getY(),
+ si.getZ(),
+ tFinalAsteroidBlock,
+ tFinalAsteroidBlockMeta,
+ tFinalUpdateMode);
+
+ }
+ // << Additional special blocks ===
+ }
+ }
+ }
+ // ---------------------------
+ // OreGen profiler stuff
+ if (GalacticGreg.GalacticConfig.ProfileOreGen) {
+ try {
+ mProfilingEnd = System.currentTimeMillis();
+ long tTotalTime = mProfilingEnd - mProfilingStart;
+ GalacticGreg.Profiler.AddTimeToList(pDimensionDef, tTotalTime);
+ GalacticGreg.Logger.debug(
+ "Done with Asteroid-Worldgen in DimensionType %s. Generation took %d ms",
+ pDimensionDef.getDimensionName(),
+ tTotalTime);
+ } catch (Exception ignored) {} // Silently ignore errors
+ }
+ // ---------------------------
+ }
+ GalacticGreg.Logger.trace("Leaving asteroid-gen for Dim %s", pDimensionDef.getDimIdentifier());
+ }
+
+ /**
+ * Generate Special Blocks in asteroids if enabled
+ *
+ * @param pDimensionDef
+ * @param pRandom
+ * @param pWorld
+ * @param tAConf
+ * @param eX
+ * @param eY
+ * @param eZ
+ * @return
+ */
+ private boolean doGenerateSpecialBlocks(ModDimensionDef pDimensionDef, Random pRandom, World pWorld,
+ DynamicDimensionConfig.AsteroidConfig tAConf, int eX, int eY, int eZ,
+ Enums.TargetBlockPosition pBlockPosition) {
+
+ boolean tFlag = true;
+ // Handler to generate special BlockTypes randomly if activated
+ if (tAConf.SpecialBlockChance > 0) {
+ if (pRandom.nextInt(100) < tAConf.SpecialBlockChance) {
+ SpecialBlockComb bmc = pDimensionDef.getRandomSpecialAsteroidBlock();
+ if (bmc != null) {
+ boolean tIsAllowed = false;
+
+ switch (bmc.getBlockPosition()) {
+ case AsteroidCore:
+ if (pBlockPosition == Enums.TargetBlockPosition.AsteroidCore) tIsAllowed = true;
+ break;
+ case AsteroidCoreAndShell:
+ if (pBlockPosition == Enums.TargetBlockPosition.AsteroidCore
+ || pBlockPosition == Enums.TargetBlockPosition.AsteroidShell) tIsAllowed = true;
+ break;
+ case AsteroidShell:
+ if (pBlockPosition == Enums.TargetBlockPosition.AsteroidShell) tIsAllowed = true;
+ break;
+ case AsteroidInnerCore:
+ if (pBlockPosition == Enums.TargetBlockPosition.AsteroidInnerCore) tIsAllowed = true;
+ break;
+ default:
+ break;
+ }
+
+ if (tIsAllowed) {
+ pWorld.setBlock(eX, eY, eZ, bmc.getBlock(), bmc.getMeta(), 2);
+ tFlag = false;
+ }
+ }
+ }
+ }
+ return tFlag;
+ }
+
+ /**
+ * Pick a random small-ore block from the list of enabled small ores for this dim
+ *
+ * @param pDimDef
+ * @param pRandom
+ * @return
+ */
+ private boolean doGenerateSmallOreBlock(ModDimensionDef pDimDef, Random pRandom, World pWorld,
+ DynamicDimensionConfig.AsteroidConfig pAConf, int pX, int pY, int pZ, int pTargetBlockOffset) {
+ boolean tFlag = true;
+ // If smallores are enabled...
+ if (pAConf.SmallOreChance > 0) {
+ // ... and we hit the random-chance ...
+ if (pRandom.nextInt(100) < pAConf.SmallOreChance) {
+ // Do small ores.
+ int tRandomWeight;
+ boolean continueSearch = true;
+ int tFoundOreMeta = -1;
+ // First find a small ore...
+ for (int i = 0; (i < 256) && (continueSearch); i++) {
+ tRandomWeight = pRandom.nextInt(WorldgenOreLayerSpace.sWeight);
+ for (GTWorldgen tWorldGen : GalacticGreg.smallOreWorldgenList) {
+
+ if (!(tWorldGen instanceof WorldgenOreSmallSpace)) {
+ continue;
+ }
+ // That is enabled for *this* dim...
+ if (!((WorldgenOreSmallSpace) tWorldGen).isEnabledForDim(pDimDef)) continue;
+
+ // And in the correct y-level, of ObeyLimits is true...
+ if (pAConf.ObeyHeightLimits && !((WorldgenOreSmallSpace) tWorldGen).isAllowedForHeight(pY))
+ continue;
+
+ // Care about weight
+ tRandomWeight -= ((WorldgenOreSmallSpace) tWorldGen).mAmount;
+ if (tRandomWeight <= 0) {
+ // And return found ore meta
+ tFoundOreMeta = ((WorldgenOreSmallSpace) tWorldGen).mMeta;
+ continueSearch = false;
+ }
+ }
+ }
+ if (tFoundOreMeta > -1) {
+ // Make the oreID a small ore with correct type
+ int tCustomOffset = (GTOreTypes.SmallOres.getOffset() + pTargetBlockOffset);
+
+ // Set the smallOre block
+ TileEntitySpaceOres
+ .setOuterSpaceOreBlock(pDimDef, pWorld, pX, pY, pZ, tFoundOreMeta, true, tCustomOffset);
+ tFlag = false;
+ }
+ }
+ }
+ return tFlag;
+ }
+
+ /**
+ * Untested! But should work... Comments are todo
+ *
+ * @param pDimensionDef
+ * @param pRandom
+ * @param pWorld
+ * @param pX
+ * @param pZ
+ * @param pBiome
+ * @param pChunkGenerator
+ * @param pChunkProvider
+ */
+ private void Generate_OreVeins(ModDimensionDef pDimensionDef, Random pRandom, World pWorld, int pX, int pZ,
+ String pBiome, IChunkProvider pChunkGenerator, IChunkProvider pChunkProvider) {
+ GalacticGreg.Logger.trace("Running orevein-gen in Dim %s", pDimensionDef.getDimIdentifier());
+
+ if (GTWorldgenerator.isOreChunk(pX / 16, pZ / 16)) {
+ if ((WorldgenOreLayerSpace.sWeight > 0) && (GalacticGreg.oreVeinWorldgenList.size() > 0)) {
+
+ boolean temp = true;
+ int tRandomWeight;
+ for (int i = 0; (i < 256) && (temp); i++) {
+ tRandomWeight = pRandom.nextInt(WorldgenOreLayerSpace.sWeight);
+ for (GTWorldgen tWorldGen : GalacticGreg.oreVeinWorldgenList) {
+ if (tWorldGen instanceof WorldgenOreLayerSpace)
+ tRandomWeight -= ((WorldgenOreLayerSpace) tWorldGen).mWeight;
+
+ if (tRandomWeight <= 0) {
+ try {
+ if (tWorldGen.executeWorldgen(
+ pWorld,
+ pRandom,
+ pBiome,
+ Integer.MIN_VALUE,
+ pX,
+ pZ,
+ pChunkGenerator,
+ pChunkProvider)) {
+ temp = false;
+ }
+ } catch (Throwable e) {
+ e.printStackTrace(GTLog.err);
+ }
+ break;
+ }
+ }
+ }
+ }
+ // Generate Small Ores
+
+ int i = 0;
+ for (int tX = pX - 16; i < 3; tX += 16) {
+ int j = 0;
+ for (int tZ = pZ - 16; j < 3; tZ += 16) {
+ for (GTWorldgen tWorldGen : GalacticGreg.smallOreWorldgenList) {
+ try {
+ tWorldGen.executeWorldgen(
+ pWorld,
+ pRandom,
+ "",
+ Integer.MIN_VALUE,
+ tX,
+ tZ,
+ pChunkGenerator,
+ pChunkProvider);
+ } catch (Throwable e) {
+ e.printStackTrace(GTLog.err);
+ }
+ }
+ j++;
+ }
+ i++;
+ }
+ }
+ GalacticGreg.Logger.trace("Leaving orevein-gen for Dim %s", pDimensionDef.getDimIdentifier());
+ }
+}