package micdoodle8.mods.galacticraft.core.world.gen.dungeon; import micdoodle8.mods.galacticraft.api.world.IGalacticraftWorldProvider; import micdoodle8.mods.galacticraft.core.util.GCCoreUtil; import net.minecraft.util.MathHelper; import net.minecraft.world.World; import net.minecraft.world.gen.structure.MapGenStructure; import net.minecraft.world.gen.structure.MapGenStructureIO; import net.minecraft.world.gen.structure.StructureComponent; import net.minecraft.world.gen.structure.StructureStart; import java.util.List; import java.util.Random; public class MapGenDungeon extends MapGenStructure { private static boolean initialized; private DungeonConfiguration configuration; static { try { MapGenDungeon.initiateStructures(); } catch (Throwable e) { } } public MapGenDungeon(DungeonConfiguration configuration) { this.configuration = configuration; } public static void initiateStructures() throws Throwable { if (!MapGenDungeon.initialized) { MapGenStructureIO.registerStructure(MapGenDungeon.Start.class, "MoonDungeon"); MapGenStructureIO.registerStructureComponent(DungeonStart.class, "MoonDungeonStart"); MapGenStructureIO.registerStructureComponent(Corridor.class, "MoonDungeonCorridor"); MapGenStructureIO.registerStructureComponent(RoomEmpty.class, "MoonDungeonEmptyRoom"); MapGenStructureIO.registerStructureComponent(RoomBoss.class, "MoonDungeonBossRoom"); MapGenStructureIO.registerStructureComponent(RoomTreasure.class, "MoonDungeonTreasureRoom"); MapGenStructureIO.registerStructureComponent(RoomSpawner.class, "MoonDungeonSpawnerRoom"); MapGenStructureIO.registerStructureComponent(RoomChest.class, "MoonDungeonChestRoom"); } MapGenDungeon.initialized = true; } @Override public String getStructureName() { return "GC_Dungeon"; } @Override protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ) { long dungeonPos = getDungeonPosForCoords(this.worldObj, chunkX, chunkZ, ((IGalacticraftWorldProvider) this.worldObj.provider).getDungeonSpacing()); int i = (int) (dungeonPos >> 32); int j = (int) dungeonPos; //Java automatically gives the 32 least significant bits return i == chunkX && j == chunkZ; } public static long getDungeonPosForCoords(World world, int chunkX, int chunkZ, int spacing) { final int numChunks = spacing / 16; if (chunkX < 0) { chunkX -= numChunks - 1; } if (chunkZ < 0) { chunkZ -= numChunks - 1; } int k = chunkX / numChunks; int l = chunkZ / numChunks; Random random = world.setRandomSeed(k, l, 10387340 + world.provider.getDimensionId()); k = k * numChunks + random.nextInt(numChunks); l = l * numChunks + random.nextInt(numChunks); return (((long) k) << 32) + l; } /** * This returns an angle between 0 and 360 degrees. 0 degrees means due North from the current (x, z) position * Only provides meaningful results in worlds with dungeon generation using this class! */ public static float directionToNearestDungeon(World world, double xpos, double zpos) { int spacing = ((IGalacticraftWorldProvider) world.provider).getDungeonSpacing(); int x = MathHelper.floor_double(xpos); int z = MathHelper.floor_double(zpos); int quadrantX = x % spacing; int quadrantZ = z % spacing; int searchOffsetX = quadrantX / (spacing / 2); //0 or 1 int searchOffsetZ = quadrantZ / (spacing / 2); //0 or 1 double nearestX = 0; double nearestZ = 0; double nearestDistance = Double.MAX_VALUE; for (int cx = searchOffsetX - 1; cx < searchOffsetX + 1; cx++) { for (int cz = searchOffsetZ - 1; cz < searchOffsetZ + 1; cz++) { long dungeonPos = getDungeonPosForCoords(world, (x + cx * spacing) / 16, (z + cz * spacing) / 16, spacing); int i = 2 + (((int) (dungeonPos >> 32)) << 4); int j = 2 + (((int) dungeonPos) << 4); //Java automatically gives the 32 least significant bits double oX = i - xpos; double oZ = j - zpos; double distanceSq = oX * oX + oZ * oZ; if (distanceSq < nearestDistance) { nearestDistance = distanceSq; nearestX = oX; nearestZ = oZ; } } } return GCCoreUtil.getAngleForRelativePosition(nearestX, nearestZ); } @Override protected StructureStart getStructureStart(int chunkX, int chunkZ) { return new MapGenDungeon.Start(this.worldObj, this.rand, chunkX, chunkZ, this.configuration); } public static class Start extends StructureStart { private DungeonConfiguration configuration; public Start() { } public Start(World worldIn, Random rand, int chunkX, int chunkZ, DungeonConfiguration configuration) { super(chunkX, chunkZ); this.configuration = configuration; DungeonStart startPiece = new DungeonStart(worldIn, configuration, rand, (chunkX << 4) + 2, (chunkZ << 4) + 2); startPiece.buildComponent(startPiece, this.components, rand); List<StructureComponent> list = startPiece.attachedComponents; while (!list.isEmpty()) { int i = rand.nextInt(list.size()); StructureComponent structurecomponent = list.remove(i); structurecomponent.buildComponent(startPiece, this.components, rand); } this.updateBoundingBox(); } } }