diff options
author | NotAPenguin <michiel.vandeginste@gmail.com> | 2024-09-02 23:17:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-02 23:17:17 +0200 |
commit | 1b820de08a05070909a267e17f033fcf58ac8710 (patch) | |
tree | 02831a025986a06b20f87e5bcc69d1e0c639a342 /src/main/java/galacticgreg | |
parent | afd3fd92b6a6ab9ab0d0dc3214e6bc8ff7a86c9b (diff) | |
download | GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.gz GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.tar.bz2 GT5-Unofficial-1b820de08a05070909a267e17f033fcf58ac8710.zip |
The Great Renaming (#3014)
* move kekztech to a single root dir
* move detrav to a single root dir
* move gtnh-lanthanides to a single root dir
* move tectech and delete some gross reflection in gt++
* remove more reflection inside gt5u
* delete more reflection in gt++
* fix imports
* move bartworks and bwcrossmod
* fix proxies
* move galactigreg and ggfab
* move gtneioreplugin
* try to fix gt++ bee loader
* apply the rename rules to BW
* apply rename rules to bwcrossmod
* apply rename rules to detrav scanner mod
* apply rename rules to galacticgreg
* apply rename rules to ggfab
* apply rename rules to goodgenerator
* apply rename rules to gtnh-lanthanides
* apply rename rules to gt++
* apply rename rules to kekztech
* apply rename rules to kubatech
* apply rename rules to tectech
* apply rename rules to gt
apply the rename rules to gt
* fix tt import
* fix mui hopefully
* fix coremod except intergalactic
* rename assline recipe class
* fix a class name i stumbled on
* rename StructureUtility to GTStructureUtility to prevent conflict with structurelib
* temporary rename of GTTooltipDataCache to old name
* fix gt client/server proxy names
Diffstat (limited to 'src/main/java/galacticgreg')
37 files changed, 4900 insertions, 0 deletions
diff --git a/src/main/java/galacticgreg/GalacticGreg.java b/src/main/java/galacticgreg/GalacticGreg.java new file mode 100644 index 0000000000..03cb4d1569 --- /dev/null +++ b/src/main/java/galacticgreg/GalacticGreg.java @@ -0,0 +1,113 @@ +package galacticgreg; + +import static gregtech.api.enums.Mods.AppliedEnergistics2; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.Mod.EventHandler; +import cpw.mods.fml.common.event.FMLPostInitializationEvent; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.event.FMLServerStartingEvent; +import galacticgreg.auxiliary.GalacticGregConfig; +import galacticgreg.auxiliary.LogHelper; +import galacticgreg.auxiliary.ProfilingStorage; +import galacticgreg.command.AEStorageCommand; +import galacticgreg.command.ProfilingCommand; +import galacticgreg.registry.GalacticGregRegistry; +import galacticgreg.schematics.SpaceSchematicHandler; +import gregtech.GT_Version; +import gregtech.api.world.GTWorldgen; + +@Mod( + modid = GalacticGreg.MODID, + name = GalacticGreg.MODNAME, + version = GalacticGreg.VERSION, + dependencies = "after:GalacticraftCore; required-after:gregtech@5.09.32.30;", + acceptableRemoteVersions = "*") +public class GalacticGreg { + + public static final List<GTWorldgen> smallOreWorldgenList = new ArrayList<>(); + public static final List<GTWorldgen> oreVeinWorldgenList = new ArrayList<>(); + + public static final String NICE_MODID = "GalacticGreg"; + public static final String MODID = "galacticgreg"; + public static final String MODNAME = "Galactic Greg"; + + public static final String VERSION = GT_Version.VERSION; + + public static final LogHelper Logger = new LogHelper(NICE_MODID); + public static ProfilingStorage Profiler = new ProfilingStorage(); + public static SpaceSchematicHandler SchematicHandler; + + public static Random GalacticRandom = null; + + public static GalacticGregConfig GalacticConfig = null; + + /** + * Preload phase. Read config values and set various features.. n stuff... + * + * @param aEvent + */ + @EventHandler + public void onPreLoad(FMLPreInitializationEvent aEvent) { + GalacticConfig = new GalacticGregConfig(aEvent.getModConfigurationDirectory(), NICE_MODID, NICE_MODID); + if (!GalacticConfig.LoadConfig()) GalacticGreg.Logger + .warn("Something went wrong while reading GalacticGregs config file. Things will be wonky.."); + + GalacticRandom = new Random(System.currentTimeMillis()); + + if (GalacticConfig.SchematicsEnabled) + SchematicHandler = new SpaceSchematicHandler(aEvent.getModConfigurationDirectory()); + + Logger.trace("Leaving PRELOAD"); + } + + public static final ArrayList<Runnable> ADDITIONALVEINREGISTER = new ArrayList<>(); + + /** + * Postload phase. Mods can add their custom definition to our api in their own PreLoad or Init-phase Once + * GalacticGregRegistry.InitRegistry() is called, no changes are accepted. (Well you can with reflection, but on a + * "normal" way it's not possible) + * + * @param aEvent + */ + @EventHandler + public void onPostLoad(FMLPostInitializationEvent aEvent) { + Logger.trace("Entering POSTLOAD"); + + if (!GalacticGregRegistry.InitRegistry()) throw new RuntimeException( + "GalacticGreg registry has been finalized from a 3rd-party mod, this is forbidden!"); + + for (Runnable r : ADDITIONALVEINREGISTER) { + try { + r.run(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + GalacticConfig.serverPostInit(); + + Logger.trace("Leaving POSTLOAD"); + } + + /** + * If oregen profiling is enabled, then register the command + * + * @param pEvent + */ + @EventHandler + public void serverLoad(FMLServerStartingEvent pEvent) { + Logger.trace("Entering SERVERLOAD"); + + if (GalacticConfig.ProfileOreGen) pEvent.registerServerCommand(new ProfilingCommand()); + + if (AppliedEnergistics2.isModLoaded() && GalacticConfig.EnableAEExportCommand + && GalacticConfig.SchematicsEnabled) pEvent.registerServerCommand(new AEStorageCommand()); + + Logger.trace("Leaving SERVERLOAD"); + } +} diff --git a/src/main/java/galacticgreg/SpaceDimRegisterer.java b/src/main/java/galacticgreg/SpaceDimRegisterer.java new file mode 100644 index 0000000000..611477f7df --- /dev/null +++ b/src/main/java/galacticgreg/SpaceDimRegisterer.java @@ -0,0 +1,140 @@ +package galacticgreg; + +import net.minecraft.init.Blocks; + +import galacticgreg.api.AsteroidBlockComb; +import galacticgreg.api.Enums; +import galacticgreg.api.GTOreTypes; +import galacticgreg.api.ModContainer; +import galacticgreg.api.SpecialBlockComb; +import galacticgreg.api.enums.DimensionDef; +import galacticgreg.api.enums.ModContainers; +import galacticgreg.registry.GalacticGregRegistry; + +/** + * In this class, you'll find everything you need in order to tell GGreg what to do and where. Everything is done in + * here. If you're trying to use anything else, you're probably doing something wrong (Or I forgot to add it. In that + * case, find me on github and create an issue please) + */ +public class SpaceDimRegisterer { + + public static void register() { + GalacticGregRegistry.registerModContainer(setupVanilla()); + GalacticGregRegistry.registerModContainer(setupGalactiCraftCore()); + GalacticGregRegistry.registerModContainer(setupGalactiCraftPlanets()); + GalacticGregRegistry.registerModContainer(setupGalaxySpace()); + GalacticGregRegistry.registerModContainer(setupAmunRa()); + } + + /** + * Vanilla MC (End Asteroids) + */ + private static ModContainer setupVanilla() { + + // If you happen to have an asteroid dim, just skip the blocklist, and setDimensionType() to + // DimensionType.Asteroid + // also don't forget to add at least one asteroid type, or nothing will generate! + DimensionDef.EndAsteroids.modDimensionDef.addAsteroidMaterial(new AsteroidBlockComb(GTOreTypes.Netherrack)); + DimensionDef.EndAsteroids.modDimensionDef.addAsteroidMaterial(new AsteroidBlockComb(GTOreTypes.RedGranite)); + DimensionDef.EndAsteroids.modDimensionDef.addAsteroidMaterial(new AsteroidBlockComb(GTOreTypes.BlackGranite)); + DimensionDef.EndAsteroids.modDimensionDef.addAsteroidMaterial(new AsteroidBlockComb(GTOreTypes.EndStone)); + + // These Blocks will randomly be generated + DimensionDef.EndAsteroids.modDimensionDef.addSpecialAsteroidBlock(new SpecialBlockComb(Blocks.glowstone)); + DimensionDef.EndAsteroids.modDimensionDef + .addSpecialAsteroidBlock(new SpecialBlockComb(Blocks.lava, Enums.AllowedBlockPosition.AsteroidCore)); + + ModContainers.Vanilla.modContainer.addDimensionDef(DimensionDef.EndAsteroids.modDimensionDef); + + return ModContainers.Vanilla.modContainer; + } + + /** + * Mod GalactiCraft + */ + private static ModContainer setupGalactiCraftCore() { + ModContainers.GalactiCraftCore.modContainer.addDimensionDef(DimensionDef.Moon.modDimensionDef); + return ModContainers.GalactiCraftCore.modContainer; + } + + /** + * As GalactiCraftPlanets is an optional mod, don't hardlink it here + */ + private static ModContainer setupGalactiCraftPlanets() { + // Overwrite ore blocks on mars with red granite ones. This will default to regular stone if not set + DimensionDef.Mars.modDimensionDef.setStoneType(GTOreTypes.RedGranite); + ModContainers.GalacticraftMars.modContainer.addDimensionDef(DimensionDef.Mars.modDimensionDef); + + DimensionDef.Asteroids.modDimensionDef.addAsteroidMaterial(new AsteroidBlockComb(GTOreTypes.BlackGranite)); + DimensionDef.Asteroids.modDimensionDef.addAsteroidMaterial(new AsteroidBlockComb(GTOreTypes.RedGranite)); + DimensionDef.Asteroids.modDimensionDef.addAsteroidMaterial(new AsteroidBlockComb(GTOreTypes.Netherrack)); + ModContainers.GalacticraftMars.modContainer.addDimensionDef(DimensionDef.Asteroids.modDimensionDef); + + return ModContainers.GalacticraftMars.modContainer; + } + + /** + * Mod GalaxySpace by BlesseNtumble + */ + private static ModContainer setupGalaxySpace() { + // First, we create a mod-container that will be populated with dimensions later. + // The Name must match your ID, as it is checked if this mod is loaded, in order + // to enable/disable the parsing/registering of dimensions + // See enum ModContainers + + // Now lets first define a block here for our dimension. You can add the ID, but you don't have to. + // It will automatically add the mods name that is defined in the modcontainer. + // See enum DimensionBlockMetaDefinitionList + + // Now define the available dimensions, and their chunkprovider. + // Same as above, to not have any dependency in your code, you can just give it a string. + // But it's better to use the actual ChunkProvider class. The Name is used for the GalacticGreg config file. + // The resulting config setting will be: <ModID>_<Name you give here as arg0>_false = false + // make sure to never change this name once you've generated your config files, as it will overwrite everything! + + // 30.11.2016 GSpace v1.1.3 Stable + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Pluto.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Triton.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Proteus.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Oberon.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Titan.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Callisto.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Ganymede.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Ceres.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Deimos.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Enceladus.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Io.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Europa.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Phobos.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Venus.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Mercury.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.MakeMake.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Haumea.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.CentauriAlpha.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.VegaB.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.BarnardC.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.BarnardE.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.BarnardF.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.TcetiE.modDimensionDef); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.Miranda.modDimensionDef); + DimensionDef.KuiperBelt.modDimensionDef.setDimensionType(Enums.DimensionType.Asteroid); + DimensionDef.KuiperBelt.modDimensionDef.addAsteroidMaterial(new AsteroidBlockComb(GTOreTypes.RedGranite)); + DimensionDef.KuiperBelt.modDimensionDef.addAsteroidMaterial(new AsteroidBlockComb(GTOreTypes.BlackGranite)); + ModContainers.GalaxySpace.modContainer.addDimensionDef(DimensionDef.KuiperBelt.modDimensionDef); + return ModContainers.GalaxySpace.modContainer; + } + + /** + * Mod Amun-Ra + */ + private static ModContainer setupAmunRa() { + ModContainers.AmunRa.modContainer.addDimensionDef(DimensionDef.Neper.modDimensionDef); + ModContainers.AmunRa.modContainer.addDimensionDef(DimensionDef.Maahes.modDimensionDef); + ModContainers.AmunRa.modContainer.addDimensionDef(DimensionDef.Anubis.modDimensionDef); + ModContainers.AmunRa.modContainer.addDimensionDef(DimensionDef.Horus.modDimensionDef); + ModContainers.AmunRa.modContainer.addDimensionDef(DimensionDef.Seth.modDimensionDef); + DimensionDef.MehenBelt.modDimensionDef.addAsteroidMaterial(GTOreTypes.BlackGranite); + ModContainers.AmunRa.modContainer.addDimensionDef(DimensionDef.MehenBelt.modDimensionDef); + return ModContainers.AmunRa.modContainer; + } +} diff --git a/src/main/java/galacticgreg/TileEntitySpaceOres.java b/src/main/java/galacticgreg/TileEntitySpaceOres.java new file mode 100644 index 0000000000..00ad3ba51f --- /dev/null +++ b/src/main/java/galacticgreg/TileEntitySpaceOres.java @@ -0,0 +1,144 @@ +package galacticgreg; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import galacticgreg.api.Enums; +import galacticgreg.api.ModDimensionDef; +import gregtech.api.GregTechAPI; +import gregtech.api.util.GTLog; +import gregtech.common.blocks.BlockOresAbstract; +import gregtech.common.blocks.TileEntityOres; + +public class TileEntitySpaceOres { + + // Renamed function to prevent function shadowing with base GT-code + public static boolean setOuterSpaceOreBlock(ModDimensionDef pDimensionDef, World pWorld, int pX, int pY, int pZ, + int pMetaData) { + return setOuterSpaceOreBlock(pDimensionDef, pWorld, pX, pY, pZ, pMetaData, false, -1); + } + + public static boolean setOuterSpaceOreBlock(ModDimensionDef pDimensionDef, World pWorld, int pX, int pY, int pZ, + int pMetaData, boolean pAir) { + return setOuterSpaceOreBlock(pDimensionDef, pWorld, pX, pY, pZ, pMetaData, pAir, -1); + } + + /** + * Check if the block at given position may be replaced by an ore + * + * @param pWorld the world in question + * @param pX X-Cord + * @param pY Y-Cord + * @param pZ Z-Cord + * @return + */ + private static Enums.ReplaceState CheckForReplaceableBlock(World pWorld, int pX, int pY, int pZ, + ModDimensionDef pDimDef) { + try { + Enums.ReplaceState tFlag = Enums.ReplaceState.Unknown; + + Block targetBlock = pWorld.getBlock(pX, pY, pZ); + int targetBlockMeta = pWorld.getBlockMetadata(pX, pY, pZ); + + if (targetBlock == Blocks.air) tFlag = Enums.ReplaceState.Airblock; + else tFlag = pDimDef.getReplaceStateForBlock(targetBlock, targetBlockMeta); + + return tFlag; + } catch (Exception e) { + e.printStackTrace(GTLog.err); + GalacticGreg.Logger.error("Error while processing CheckForReplaceableBlock(), defaulting to UNKNOWN"); + return Enums.ReplaceState.Unknown; + } + } + + /** + * Actually set the OreBlock + * + * @param pWorld the world in question + * @param pX + * @param pY + * @param pZ + * @param pMetaData GT-Ore metadata + * @param pAir + * @return + */ + public static boolean setOuterSpaceOreBlock(ModDimensionDef pDimensionDef, World pWorld, int pX, int pY, int pZ, + int pMetaData, boolean pAir, int pCustomGTOreOffset) { + if (!pAir) pY = Math.min(pWorld.getActualHeight(), Math.max(pY, 1)); + + if (pDimensionDef == null) { + GalacticGreg.Logger + .warn("Unknown DimensionID: %d. Will not set anything here", pWorld.provider.dimensionId); + return false; + } + try { + Block tBlock = pWorld.getBlock(pX, pY, pZ); + // If the meta is non-zero, and the target block is either non-air or the air-override is active + if ((pMetaData > 0) && ((tBlock != Blocks.air) || pAir)) { + // make sure we're either going with normal ore-metas, or small ores. + // Probably should do another check for <= 1700 + if (pMetaData < 1000 || pMetaData >= 16000) { + Enums.ReplaceState tRS = CheckForReplaceableBlock(pWorld, pX, pY, pZ, pDimensionDef); + + // Unable to lookup replacement state. Means: The block is unknown, and shall not be replaced + if (tRS == Enums.ReplaceState.Unknown) { + GalacticGreg.Logger.trace("Not placing ore Meta %d, as target block is unknown", pMetaData); + return false; + } else if (tRS == Enums.ReplaceState.Airblock && !pAir) { + GalacticGreg.Logger.trace("Not placing ore Meta %d in midair, as AIR is FALSE", pMetaData); + return false; + } + if (tRS == Enums.ReplaceState.CannotReplace) { + // wrong metaData ID for target block + GalacticGreg.Logger.trace("Not placing ore Meta %d, as the state is CANNOTREPLACE", pMetaData); + return false; + } + + if (pCustomGTOreOffset == -1) pMetaData += pDimensionDef.getStoneType() + .getOffset(); + else pMetaData += pCustomGTOreOffset; + // This fix seems like cargo cult coding...The Abstract class just returns 0 for the harvest level. + // But it aligns with the GT5U method, so yay? + pWorld.setBlock( + pX, + pY, + pZ, + GregTechAPI.sBlockOres1, + TileEntityOres.getHarvestData( + (short) pMetaData, + ((BlockOresAbstract) GregTechAPI.sBlockOres1) + .getBaseBlockHarvestLevel(pMetaData % 16000 / 1000)), + 0); + TileEntity tTileEntity = pWorld.getTileEntity(pX, pY, pZ); + if ((tTileEntity instanceof TileEntityOres)) { + ((TileEntityOres) tTileEntity).mMetaData = ((short) pMetaData); + ((TileEntityOres) tTileEntity).mNatural = true; + } else { + // This is somehow triggered randomly, and most times the target block is air, which should + // never happen as we check for air... + // That's why I put this behind a debug config option. If you ever find the reason for it, + // please tell me what caused this + if (GalacticGreg.GalacticConfig.ReportOreGenFailures) GalacticGreg.Logger.warn( + "Something went wrong while placing GT OreTileEntity. Meta: %d X [%d] Y [%d] Z [%d]", + pMetaData, + pX, + pY, + pZ); + } + + return true; + } else GalacticGreg.Logger.warn( + "Not replacing block at pos %d %d %d due unexpected metaData for OreBlock: %d", + pX, + pY, + pZ, + pMetaData); + } + } catch (Exception e) { + if (GalacticGreg.GalacticConfig.ReportOreGenFailures) e.printStackTrace(); + } + return false; + } +} 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()); + } +} diff --git a/src/main/java/galacticgreg/WorldgenGaGT.java b/src/main/java/galacticgreg/WorldgenGaGT.java new file mode 100644 index 0000000000..5814660fe7 --- /dev/null +++ b/src/main/java/galacticgreg/WorldgenGaGT.java @@ -0,0 +1,28 @@ +package galacticgreg; + +import gregtech.api.enums.OreMixes; +import gregtech.api.enums.SmallOres; + +public class WorldgenGaGT implements Runnable { + + @Override + public void run() { + new WorldGeneratorSpace(); + + /* + * This part here enables every GT Small Ore for Space Dims. + */ + for (SmallOres ore : SmallOres.values()) { + ore.addGaGregSmallOre(); + } + + /* + * This part here enables every GT Ore for Space Dims. + */ + + for (OreMixes mix : OreMixes.values()) { + mix.addGaGregOreLayer(); + } + } + +} diff --git a/src/main/java/galacticgreg/WorldgenOreLayerSpace.java b/src/main/java/galacticgreg/WorldgenOreLayerSpace.java new file mode 100644 index 0000000000..c28eb7a392 --- /dev/null +++ b/src/main/java/galacticgreg/WorldgenOreLayerSpace.java @@ -0,0 +1,320 @@ +package galacticgreg; + +import static gregtech.api.enums.GTValues.oreveinPlacerOres; +import static gregtech.api.enums.GTValues.oreveinPlacerOresMultiplier; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.chunk.IChunkProvider; + +import galacticgreg.api.ModContainer; +import galacticgreg.api.ModDimensionDef; +import galacticgreg.auxiliary.GTOreGroup; +import galacticgreg.registry.GalacticGregRegistry; +import gregtech.api.util.GTLog; +import gregtech.api.world.GTWorldgen; +import gregtech.common.OreMixBuilder; + +public class WorldgenOreLayerSpace extends GTWorldgen { + + public static int sWeight = 0; + public final short mMinY; + public final short mMaxY; + public final short mWeight; + public final short mDensity; + public final short mSize; + public final short mPrimaryMeta; + public final short mSecondaryMeta; + public final short mBetweenMeta; + public final short mSporadicMeta; + + private long mProfilingStart; + private long mProfilingEnd; + private Map<String, Boolean> allowedDims; + + public WorldgenOreLayerSpace(OreMixBuilder mix) { + super(mix.oreMixName, GalacticGreg.oreVeinWorldgenList, mix.enabledByDefault); + + mMinY = (short) mix.minY; + mMaxY = (short) Math.max(this.mMinY + 5, mix.maxY); + mWeight = (short) mix.weight; + mDensity = (short) mix.density; + mSize = (short) Math.max(1, mix.size); + mPrimaryMeta = (short) mix.primary.mMetaItemSubID; + mSecondaryMeta = (short) mix.secondary.mMetaItemSubID; + mBetweenMeta = (short) mix.between.mMetaItemSubID; + mSporadicMeta = (short) mix.sporadic.mMetaItemSubID; + + allowedDims = new HashMap<>(); + + for (ModContainer mc : GalacticGregRegistry.getModContainers()) { + if (!mc.getEnabled()) continue; + + for (ModDimensionDef mdd : mc.getDimensionList()) { + String tDimIdentifier = mdd.getDimIdentifier(); + if (allowedDims.containsKey(tDimIdentifier)) GalacticGreg.Logger.error( + "Found 2 Dimensions with the same Identifier: %s Dimension will not generate Ores", + tDimIdentifier); + else { + boolean tFlag = mix.dimsEnabled.getOrDefault(mdd.getDimensionName(), false); + allowedDims.put(tDimIdentifier, tFlag); + } + } + } + + GalacticGreg.Logger.trace("Initialized new OreLayer: %s", mix.oreMixName); + if (mEnabled) sWeight += this.mWeight; + } + + /** + * Check if *this* orelayer is enabled for pDimensionDef + * + * @param pDimensionDef the ChunkProvider in question + * @return + */ + public boolean isEnabledForDim(ModDimensionDef pDimensionDef) { + return allowedDims.getOrDefault(pDimensionDef.getDimIdentifier(), false); + } + + private static Map<String, List<String>> _mBufferedVeinList = new HashMap<>(); + + /** + * Get a List of all Veins which are enabled for given Dim. Query is buffered + * + * @param pDimensionDef + * @return null if nothing is found or error + */ + private static List<String> getOreMixIDsForDim(ModDimensionDef pDimensionDef) { + List<String> tReturn; + + if (_mBufferedVeinList.containsKey(pDimensionDef.getDimIdentifier())) + tReturn = _mBufferedVeinList.get(pDimensionDef.getDimIdentifier()); + else { + tReturn = new ArrayList<>(); + for (GTWorldgen tWorldGen : GalacticGreg.oreVeinWorldgenList) if (tWorldGen instanceof WorldgenOreLayerSpace + && ((WorldgenOreLayerSpace) tWorldGen).isEnabledForDim(pDimensionDef)) + tReturn.add(tWorldGen.mWorldGenName); + + _mBufferedVeinList.put(pDimensionDef.getDimIdentifier(), tReturn); + } + + return tReturn; + } + + /** + * Select a random ore-vein from the list + * + * @param pDimensionDef + * @param pRandom + * @return + */ + public static GTOreGroup getRandomOreGroup(ModDimensionDef pDimensionDef, Random pRandom, boolean pIgnoreWeight) { + short primaryMeta = 0; + short secondaryMeta = 0; + short betweenMeta = 0; + short sporadicMeta = 0; + + if (pIgnoreWeight) { + List<String> tEnabledVeins = getOreMixIDsForDim(pDimensionDef); + int tRnd = pRandom.nextInt(tEnabledVeins.size()); + String tVeinName = tEnabledVeins.get(tRnd); + + GTWorldgen tGen = null; + for (GTWorldgen tWorldGen : GalacticGreg.oreVeinWorldgenList) if (tWorldGen instanceof WorldgenOreLayerSpace + && ((WorldgenOreLayerSpace) tWorldGen).mWorldGenName.equals(tVeinName)) tGen = tWorldGen; + + if (tGen != null) { + // GT_Worldgen_GT_Ore_Layer_Space tGen = GalacticGreg.oreVeinWorldgenList.get(tRndMix); + GalacticGreg.Logger.trace("Using Oremix %s for asteroid", tGen.mWorldGenName); + primaryMeta = ((WorldgenOreLayerSpace) tGen).mPrimaryMeta; + secondaryMeta = ((WorldgenOreLayerSpace) tGen).mSecondaryMeta; + betweenMeta = ((WorldgenOreLayerSpace) tGen).mBetweenMeta; + sporadicMeta = ((WorldgenOreLayerSpace) tGen).mSporadicMeta; + } + } else { + if ((WorldgenOreLayerSpace.sWeight > 0) && (GalacticGreg.oreVeinWorldgenList.size() > 0)) { + GalacticGreg.Logger.trace("About to select oremix"); + 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)) continue; + + tRandomWeight -= ((WorldgenOreLayerSpace) tWorldGen).mWeight; + if (tRandomWeight <= 0) { + try { + if (((WorldgenOreLayerSpace) tWorldGen).isEnabledForDim(pDimensionDef)) { + GalacticGreg.Logger.trace("Using Oremix %s for asteroid", tWorldGen.mWorldGenName); + primaryMeta = ((WorldgenOreLayerSpace) tWorldGen).mPrimaryMeta; + secondaryMeta = ((WorldgenOreLayerSpace) tWorldGen).mSecondaryMeta; + betweenMeta = ((WorldgenOreLayerSpace) tWorldGen).mBetweenMeta; + sporadicMeta = ((WorldgenOreLayerSpace) tWorldGen).mSporadicMeta; + + temp = false; + break; + } + } catch (Throwable e) { + e.printStackTrace(GTLog.err); + } + } + } + } + } + } + if (primaryMeta != 0 || secondaryMeta != 0 || betweenMeta != 0 || sporadicMeta != 0) + return new GTOreGroup(primaryMeta, secondaryMeta, betweenMeta, sporadicMeta); + else return null; + } + + @Override + public boolean executeWorldgen(World pWorld, Random pRandom, String pBiome, int pDimensionType, int pChunkX, + int pChunkZ, IChunkProvider pChunkGenerator, IChunkProvider pChunkProvider) { + GalacticGreg.Logger.trace("Entering executeWorldgen for [%s]", mWorldGenName); + ModDimensionDef tMDD = GalacticGregRegistry.getDimensionTypeByChunkGenerator(pChunkGenerator); + if (tMDD == null) { + GalacticGreg.Logger + .trace("Can't find dimension definition for ChunkProvider %s, skipping", pChunkGenerator.toString()); + return false; + } + + if (!isEnabledForDim(tMDD)) { + GalacticGreg.Logger + .trace("OreGen for %s is disallowed in dimension %s, skipping", mWorldGenName, tMDD.getDimensionName()); + return false; + } + + if (GalacticGreg.GalacticConfig.ProfileOreGen) mProfilingStart = System.currentTimeMillis(); + // --------------------------- + int tMinY = this.mMinY + pRandom.nextInt(this.mMaxY - this.mMinY - 7); + + int cX = pChunkX - pRandom.nextInt(this.mSize); + int eX = pChunkX + 16 + pRandom.nextInt(this.mSize); + int cZ = pChunkZ - pRandom.nextInt(this.mSize); + int eZ = pChunkZ + 16 + pRandom.nextInt(this.mSize); + for (int tX = cX; tX <= eX; tX++) { + for (int tZ = cZ; tZ <= eZ; tZ++) { + if (this.mSecondaryMeta > 0) { + for (int i = tMinY - 1; i < tMinY + 3; i++) { + int placeX = Math.max( + 1, + Math.max(MathHelper.abs_int(cX - tX), MathHelper.abs_int(eX - tX)) + / getDensityFromPos(tX, tZ, pChunkX, pChunkZ)); + int placeZ = Math.max( + 1, + Math.max(MathHelper.abs_int(cZ - tZ), MathHelper.abs_int(eZ - tZ)) + / getDensityFromPos(tX, tZ, pChunkX, pChunkZ)); + if ((pRandom.nextInt(placeZ) == 0) || (pRandom.nextInt(placeX) == 0)) { + TileEntitySpaceOres.setOuterSpaceOreBlock(tMDD, pWorld, tX, i, tZ, this.mSecondaryMeta); + } + } + } + if (this.mBetweenMeta > 0) { + for (int i = tMinY + 2; i < tMinY + 6; i++) { + int placeX = Math.max( + 1, + Math.max(MathHelper.abs_int(cX - tX), MathHelper.abs_int(eX - tX)) + / getDensityFromPos(tX, tZ, pChunkX, pChunkZ)); + int placeZ = Math.max( + 1, + Math.max(MathHelper.abs_int(cZ - tZ), MathHelper.abs_int(eZ - tZ)) + / getDensityFromPos(tX, tZ, pChunkX, pChunkZ)); + if (((pRandom.nextInt(placeZ) == 0) || (pRandom.nextInt(placeX) == 0)) + && (pRandom.nextInt(2) == 0)) { + TileEntitySpaceOres.setOuterSpaceOreBlock(tMDD, pWorld, tX, i, tZ, this.mBetweenMeta); + } + } + + } + if (this.mPrimaryMeta > 0) { + for (int i = tMinY + 4; i < tMinY + 8; i++) { + int placeX = Math.max( + 1, + Math.max(MathHelper.abs_int(cX - tX), MathHelper.abs_int(eX - tX)) + / getDensityFromPos(tX, tZ, pChunkX, pChunkZ)); + int placeZ = Math.max( + 1, + Math.max(MathHelper.abs_int(cZ - tZ), MathHelper.abs_int(eZ - tZ)) + / getDensityFromPos(tX, tZ, pChunkX, pChunkZ)); + if ((pRandom.nextInt(placeZ) == 0) || (pRandom.nextInt(placeX) == 0)) { + TileEntitySpaceOres.setOuterSpaceOreBlock(tMDD, pWorld, tX, i, tZ, this.mPrimaryMeta); + } + } + } + if (this.mSporadicMeta > 0) { + for (int i = tMinY - 1; i < tMinY + 8; i++) { + int placeX = Math.max( + 1, + Math.max(MathHelper.abs_int(cX - tX), MathHelper.abs_int(eX - tX)) + / getDensityFromPos(tX, tZ, pChunkX, pChunkZ)); + int placeZ = Math.max( + 1, + Math.max(MathHelper.abs_int(cZ - tZ), MathHelper.abs_int(eZ - tZ)) + / getDensityFromPos(tX, tZ, pChunkX, pChunkZ)); + if (((pRandom.nextInt(placeX) == 0) || (pRandom.nextInt(placeZ) == 0)) + && (pRandom.nextInt(7) == 0)) { + TileEntitySpaceOres.setOuterSpaceOreBlock(tMDD, pWorld, tX, i, tZ, this.mSporadicMeta); + } + } + } + } + } + + if (oreveinPlacerOres) { + int nSmallOres = (cX - eX) * (cZ - eZ) * this.mDensity / 10 * oreveinPlacerOresMultiplier; + for (int nSmallOresCount = 0; nSmallOresCount < nSmallOres; nSmallOresCount++) { + int tX = pRandom.nextInt(16) + pChunkX + 2; + int tZ = pRandom.nextInt(16) + pChunkZ + 2; + int tY = pRandom.nextInt(160) + 10; // Y height can vary from 10 to 170 for small ores. + if (this.mPrimaryMeta > 0) + TileEntitySpaceOres.setOuterSpaceOreBlock(tMDD, pWorld, tX, tY, tZ, this.mPrimaryMeta + 16000); + tX = pRandom.nextInt(16) + pChunkX + 2; + tZ = pRandom.nextInt(16) + pChunkZ + 2; + tY = pRandom.nextInt(160) + 10; // Y height can vary from 10 to 170 for small ores. + if (this.mSecondaryMeta > 0) + TileEntitySpaceOres.setOuterSpaceOreBlock(tMDD, pWorld, tX, tY, tZ, this.mSecondaryMeta + 16000); + tX = pRandom.nextInt(16) + pChunkX + 2; + tZ = pRandom.nextInt(16) + pChunkZ + 2; + tY = pRandom.nextInt(160) + 10; // Y height can vary from 10 to 170 for small ores. + if (this.mBetweenMeta > 0) + TileEntitySpaceOres.setOuterSpaceOreBlock(tMDD, pWorld, tX, tY, tZ, this.mBetweenMeta + 16000); + tX = pRandom.nextInt(16) + pChunkX + 2; + tZ = pRandom.nextInt(16) + pChunkZ + 2; + tY = pRandom.nextInt(190) + 10; // Y height can vary from 10 to 200 for small ores. + if (this.mSporadicMeta > 0) + TileEntitySpaceOres.setOuterSpaceOreBlock(tMDD, pWorld, tX, tY, tZ, this.mSporadicMeta + 16000); + } + } + + // --------------------------- + if (GalacticGreg.GalacticConfig.ProfileOreGen) { + try { + mProfilingEnd = System.currentTimeMillis(); + long tTotalTime = mProfilingEnd - mProfilingStart; + GalacticGreg.Profiler.AddTimeToList(tMDD, tTotalTime); + GalacticGreg.Logger.debug( + "Done with OreLayer-Worldgen in DimensionType %s. Generation took %d ms", + tMDD.getDimensionName(), + tTotalTime); + } catch (Exception ignored) {} // Silently ignore errors + } + + GalacticGreg.Logger.trace("Leaving executeWorldgen"); + return true; + } + + public int getDensityFromPos(int aX, int aZ, int aSeedX, int aSeedZ) { + if (aX < 0) aX -= 16; + if (aZ < 0) aZ -= 16; + return Math.max( + 1, + this.mDensity + / ((int) Math.sqrt(2 + Math.pow(aX / 16 - aSeedX / 16, 2) + Math.pow(aZ / 16 - aSeedZ / 16, 2)))); + } +} diff --git a/src/main/java/galacticgreg/WorldgenOreSmallSpace.java b/src/main/java/galacticgreg/WorldgenOreSmallSpace.java new file mode 100644 index 0000000000..18dd338ec3 --- /dev/null +++ b/src/main/java/galacticgreg/WorldgenOreSmallSpace.java @@ -0,0 +1,116 @@ +package galacticgreg; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import net.minecraft.world.World; +import net.minecraft.world.chunk.IChunkProvider; + +import galacticgreg.api.ModContainer; +import galacticgreg.api.ModDimensionDef; +import galacticgreg.registry.GalacticGregRegistry; +import gregtech.api.world.GTWorldgen; +import gregtech.common.SmallOreBuilder; + +public class WorldgenOreSmallSpace extends GTWorldgen { + + public final short mMinY; + public final short mMaxY; + public final short mAmount; + public final short mMeta; + + private long mProfilingStart; + private long mProfilingEnd; + private Map<String, Boolean> allowedDims; + + public WorldgenOreSmallSpace(SmallOreBuilder ore) { + super(ore.smallOreName, GalacticGreg.smallOreWorldgenList, ore.enabledByDefault); + + mMinY = (short) ore.minY; + mMaxY = (short) Math.max(this.mMinY + 1, ore.maxY); + mAmount = (short) Math.max(1, ore.amount); + mMeta = (short) ore.ore.mMetaItemSubID; + + allowedDims = new HashMap<>(); + for (ModContainer mc : GalacticGregRegistry.getModContainers()) { + if (!mc.getEnabled()) continue; + + for (ModDimensionDef mdd : mc.getDimensionList()) { + String tDimIdentifier = mdd.getDimIdentifier(); + if (allowedDims.containsKey(tDimIdentifier)) GalacticGreg.Logger.error( + "Found 2 Dimensions with the same Identifier: %s Dimension will not generate Ores", + tDimIdentifier); + else { + boolean tFlag = ore.dimsEnabled.getOrDefault(mdd.getDimensionName(), false); + allowedDims.put(tDimIdentifier, tFlag); + } + } + } + + GalacticGreg.Logger.trace("Initialized new OreLayer: %s", ore.smallOreName); + } + + /** + * Check if *this* orelayer is enabled for pDimensionDef + * + * @param pDimensionDef the ChunkProvider in question + * @return + */ + public boolean isEnabledForDim(ModDimensionDef pDimensionDef) { + return allowedDims.getOrDefault(pDimensionDef.getDimIdentifier(), false); + } + + @Override + public boolean executeWorldgen(World pWorld, Random pRandom, String pBiome, int pDimensionType, int pChunkX, + int pChunkZ, IChunkProvider pChunkGenerator, IChunkProvider pChunkProvider) { + GalacticGreg.Logger.trace("Entering executeWorldgen for [%s]", mWorldGenName); + ModDimensionDef tMDD = GalacticGregRegistry.getDimensionTypeByChunkGenerator(pChunkGenerator); + if (tMDD == null) { + GalacticGreg.Logger + .trace("Can't find dimension definition for ChunkProvider %s, skipping", pChunkGenerator.toString()); + return false; + } + + if (!isEnabledForDim(tMDD)) { + GalacticGreg.Logger + .trace("OreGen for %s is disallowed in dimension %s, skipping", mWorldGenName, tMDD.getDimensionName()); + return false; + } + + if (GalacticGreg.GalacticConfig.ProfileOreGen) mProfilingStart = System.currentTimeMillis(); + // --------------------------- + + if (this.mMeta > 0) { + int i = 0; + for (int j = Math.max(1, this.mAmount / 2 + pRandom.nextInt(this.mAmount) / 2); i < j; i++) { + TileEntitySpaceOres.setOuterSpaceOreBlock( + tMDD, + pWorld, + pChunkX + pRandom.nextInt(16), + this.mMinY + pRandom.nextInt(Math.max(1, this.mMaxY - this.mMinY)), + pChunkZ + pRandom.nextInt(16), + this.mMeta + 16000); + } + } + // --------------------------- + if (GalacticGreg.GalacticConfig.ProfileOreGen) { + try { + mProfilingEnd = System.currentTimeMillis(); + long tTotalTime = mProfilingEnd - mProfilingStart; + GalacticGreg.Profiler.AddTimeToList(tMDD, tTotalTime); + GalacticGreg.Logger.debug( + "Done with SmallOre-Worldgen in DimensionType %s. Generation took %d ms", + tMDD.getDimensionName(), + tTotalTime); + } catch (Exception ignored) {} // Silently ignore errors + } + + GalacticGreg.Logger.trace("Leaving executeWorldgen"); + return true; + } + + public boolean isAllowedForHeight(int pTargetHeight) { + return (pTargetHeight >= mMinY && pTargetHeight <= mMaxY); + } +} diff --git a/src/main/java/galacticgreg/api/AsteroidBlockComb.java b/src/main/java/galacticgreg/api/AsteroidBlockComb.java new file mode 100644 index 0000000000..208d8faed3 --- /dev/null +++ b/src/main/java/galacticgreg/api/AsteroidBlockComb.java @@ -0,0 +1,77 @@ +package galacticgreg.api; + +import net.minecraft.block.Block; + +/** + * Class for a bit more advanced combinations for Asteroids, which supports Custom Blocks as base material and Values + * required to generate Gregtech ores + */ +public class AsteroidBlockComb extends BlockMetaComb { + + private final GTOreTypes _mGTOreMaterial; + + /** + * Create an advanced definition which uses the GregTech-OreType values for ores, and your own definition of Block + * for the asteroid material + * + * @param pOreType The GregTech oreType + * @param pBlock Your block + */ + public AsteroidBlockComb(GTOreTypes pOreType, Block pBlock) { + super(pBlock, 0); + _mGTOreMaterial = pOreType; + } + + /** + * Create an advanced definition which uses the GregTech-OreType values for ores, and your own definition of Block + * for the asteroid material + * + * @param pOreType The GregTech oreType + * @param pBlock Your block + * @param pMeta The metavalue for your block (If required) + */ + public AsteroidBlockComb(GTOreTypes pOreType, Block pBlock, int pMeta) { + super(pBlock, pMeta); + _mGTOreMaterial = pOreType; + } + + /** + * Create a simple definition which uses the GregTech-OreType values for both asteroidStone and ores + * + * @param pOreType The GregTech oreType + */ + public AsteroidBlockComb(GTOreTypes pOreType) { + super(pOreType.getBlock(), pOreType.getMeta()); + _mGTOreMaterial = pOreType; + } + + /** + * Internal function + * + * @return The GT Material for the oregen + */ + public GTOreTypes getOreMaterial() { + return _mGTOreMaterial; + } + + @Override + public boolean equals(Object other) { + if (other == null) return false; + if (other == this) return true; + if (!(other instanceof AsteroidBlockComb)) return false; + AsteroidBlockComb otherObj = (AsteroidBlockComb) other; + + boolean tFlag = true; + String otherName = Block.blockRegistry.getNameForObject(otherObj.getBlock()); + String thisName = Block.blockRegistry.getNameForObject(this.getBlock()); + if (otherName != null && thisName != null) { + if (!otherName.equals(thisName)) tFlag = false; + + if (!(otherObj.getMeta() == this.getMeta())) tFlag = false; + + if (!(otherObj.getOreMaterial() == this.getOreMaterial())) tFlag = false; + } else tFlag = false; + + return tFlag; + } +} diff --git a/src/main/java/galacticgreg/api/BlockMetaComb.java b/src/main/java/galacticgreg/api/BlockMetaComb.java new file mode 100644 index 0000000000..f4dc416c6b --- /dev/null +++ b/src/main/java/galacticgreg/api/BlockMetaComb.java @@ -0,0 +1,50 @@ +package galacticgreg.api; + +import net.minecraft.block.Block; + +/** + * Class used for Simple Block - Meta constructs + */ +public class BlockMetaComb { + + private int mMeta; + private Block mBlock; + + /** + * Creates a simple instance for a block that has no meta value + * + * @param pBlock The Block in question. 0 is used as meta + */ + public BlockMetaComb(Block pBlock) { + this(pBlock, 0); + } + + /** + * Creates a simple instance for a block with a meta value + * + * @param pBlock The Block in question + * @param pMeta The MetaValue in question ([block]:[meta]) + */ + public BlockMetaComb(Block pBlock, int pMeta) { + mMeta = pMeta; + mBlock = pBlock; + } + + /** + * Internal function + * + * @return The metadata for this block + */ + public int getMeta() { + return mMeta; + } + + /** + * Internal function + * + * @return The block + */ + public Block getBlock() { + return mBlock; + } +} diff --git a/src/main/java/galacticgreg/api/Enums.java b/src/main/java/galacticgreg/api/Enums.java new file mode 100644 index 0000000000..f60c5602dd --- /dev/null +++ b/src/main/java/galacticgreg/api/Enums.java @@ -0,0 +1,51 @@ +package galacticgreg.api; + +public class Enums { + + public enum SpaceObjectType { + OreAsteroid, + NonOreSchematic + } + + public enum TargetBlockPosition { + Invalid, + AsteroidInnerCore, + AsteroidCore, + AsteroidShell, + StructureBlock + } + + public enum AllowedBlockPosition { + AsteroidInnerCore, + AsteroidCore, + AsteroidShell, + AsteroidCoreAndShell + } + + public enum AirReplaceRule { + NeverReplaceAir, + AllowReplaceAir, + OnlyReplaceAir + } + + public enum ReplaceState { + Unknown, + Airblock, + CanReplace, + CannotReplace + } + + public enum DimensionType { + /** + * The Dimension is a void dimension and asteroids shall be generated. They will randomly spawn bewteen 0 and + * 250 Additional config values will be generated in worldconfig + */ + Asteroid, + + /** + * The Dimension is a planet, and only ores shall be generated in the ground + */ + Planet, + } + +} diff --git a/src/main/java/galacticgreg/api/GTOreTypes.java b/src/main/java/galacticgreg/api/GTOreTypes.java new file mode 100644 index 0000000000..fdc4ea61ff --- /dev/null +++ b/src/main/java/galacticgreg/api/GTOreTypes.java @@ -0,0 +1,66 @@ +package galacticgreg.api; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; + +import gregtech.api.GregTechAPI; + +/** + * Representation of the various GregTech ores, with their counterpart in VanillaBlocks, and the OreOffset that is + * required to generate the proper ores + */ +public enum GTOreTypes { + + /** + * The Definition for Gregtech's RedGranite + **/ + RedGranite(4000, GregTechAPI.sBlockGranites, 8, 3), + /** + * The Definition for Gregtech's BlackGranite + */ + BlackGranite(3000, GregTechAPI.sBlockGranites, 0, 3), + /** + * The Definition for EndStone + */ + EndStone(2000, Blocks.end_stone, 0, 0), + /** + * The Definition for Netherrack + */ + Netherrack(1000, Blocks.netherrack, 0, 0), // Unsure about blockupdate value! + /** + * The Definition for SmallOres (And BlockType Stone) + */ + SmallOres(16000, Blocks.stone, 0, 0), // Unsure about blockupdate value! + /** + * The Definition for Ores (And BlockType Stone) + */ + NormalOres(0, Blocks.stone, 0, 0); // Unsure about blockupdate value! + + private int _mOffset; + private Block _mStoneBlock; + private int _mBlockMeta; + private int _mUpdateMode; + + GTOreTypes(int pOffset, Block pBlock, int pMeta, int pUpdateMode) { + _mOffset = pOffset; + _mStoneBlock = pBlock; + _mBlockMeta = pMeta; + _mUpdateMode = pUpdateMode; + } + + public Block getBlock() { + return _mStoneBlock; + } + + public int getMeta() { + return _mBlockMeta; + } + + public int getOffset() { + return _mOffset; + } + + public int getUpdateMode() { + return _mUpdateMode; + } +} diff --git a/src/main/java/galacticgreg/api/ISpaceObjectGenerator.java b/src/main/java/galacticgreg/api/ISpaceObjectGenerator.java new file mode 100644 index 0000000000..3cf16c8791 --- /dev/null +++ b/src/main/java/galacticgreg/api/ISpaceObjectGenerator.java @@ -0,0 +1,58 @@ +package galacticgreg.api; + +import java.util.List; + +import net.minecraft.util.Vec3; + +import galacticgreg.api.Enums.SpaceObjectType; + +public interface ISpaceObjectGenerator { + + Vec3 getCenterPoint(); + + /** + * Set the center-point of the object to generate, by providing X, Y and Z directly + * + * @param pX + * @param pY + * @param pZ + */ + void setCenterPoint(int pX, int pY, int pZ); + + /** + * Set the center-point of the object to generate, by providing a Vec3 instance + * + * @param pCenter + */ + void setCenterPoint(Vec3 pCenter); + + List<StructureInformation> getStructure(); + + /** + * Calculate the structure Called after randomize() + */ + void calculate(); + + /** + * Randomize the structure. Called before calculate() + * + * @param pSizeMin The minimum size for the structure. It is up to you how you handle this value. it's what the user + * sets in his config file + * @param pSizeMax The maximum size for the structure. It is up to you how you handle this value. it's what the user + * sets in his config file + */ + void randomize(int pSizeMin, int pSizeMax); + + /** + * Define the type of the generator. OreAsteroid will be used to spawn ores at given coordinates, where + * NonOreSchematic will use the Blocks provided in the structural information to generate your structure + * + * @return + */ + SpaceObjectType getType(); + + /** + * This function is called every time the generator shall be reset in order to generate a blank, new structure + */ + void reset(); +} diff --git a/src/main/java/galacticgreg/api/ModContainer.java b/src/main/java/galacticgreg/api/ModContainer.java new file mode 100644 index 0000000000..37721cd38c --- /dev/null +++ b/src/main/java/galacticgreg/api/ModContainer.java @@ -0,0 +1,85 @@ +package galacticgreg.api; + +import java.util.ArrayList; +import java.util.List; + +/** + * Defines a Mod where this Generator shall be active. Note: This will only work (obviously) for Dimensions where + * either: - Gregtech has a hook in the OreGen or - For mods which are addons to GalactiCraft + * + */ +public class ModContainer { + + private String _mModName; + private List<ModDimensionDef> _mDimensionLookup; + private boolean _mEnabled = false; + + /** + * Internal function + * + * @return The state if the Registry could find the mod or not + */ + public boolean getEnabled() { + return _mEnabled; + } + + /** + * Internal function + * + * Never set this to true. This is an internal marker which is set by the registry if the mod could be found or not + * + * @param pEnabled + */ + public void setEnabled(boolean pEnabled) { + _mEnabled = pEnabled; + } + + /** + * Define a new Mod where GT OreGen shall be enabled + * + * @param pModName The modID. Make sure to use the proper mod-id, or it won't load correctly + */ + public ModContainer(String pModName) { + _mModName = pModName; + _mDimensionLookup = new ArrayList<>(); + } + + /** + * Internal function + * + * @return The mods name + */ + public String getModName() { + return _mModName; + } + + /** + * Internal function + * + * @return The list of attached dimensions for this mod + */ + public List<ModDimensionDef> getDimensionList() { + return _mDimensionLookup; + } + + /** + * Adds a new dimension to this modcontainer. Make sure you've added all blocks there first + * + * @param pDimDef The dimension definition to be added + * @return true if it could be added, false if not + */ + public boolean addDimensionDef(ModDimensionDef pDimDef) { + for (ModDimensionDef mdd : _mDimensionLookup) { + if (mdd.getChunkProviderName() + .equals(pDimDef.getChunkProviderName())) { + // Cannot add DimensionDefinition; The Given chunk-provider name is already taken! + return false; + } + } + + // Set the parent modName of this dimension. This will finalize it + pDimDef.setParentModName(_mModName); + _mDimensionLookup.add(pDimDef); + return true; + } +} diff --git a/src/main/java/galacticgreg/api/ModDBMDef.java b/src/main/java/galacticgreg/api/ModDBMDef.java new file mode 100644 index 0000000000..11d6bc630e --- /dev/null +++ b/src/main/java/galacticgreg/api/ModDBMDef.java @@ -0,0 +1,159 @@ +package galacticgreg.api; + +import net.minecraft.block.Block; + +/** + * Mod "Dimension Block Meta Definition" Defines the Block-Meta combination for Blocks that can be replaced by the + * oregen. + * + */ +public class ModDBMDef { + + private String _targetBlockName; + private int _targetMeta; + private boolean _canAlwaysReplace; + + public String getBlockName() { + return _targetBlockName; + } + + public int getMeta() { + return _targetMeta; + } + + public boolean getCanAlwaysReplace() { + return _canAlwaysReplace; + } + + /** + * Internal function + * + * Check if the given Block is equal to the block in this instance + * + * @param pBlock the Block in question + * @return + */ + public Enums.ReplaceState blockEquals(Block pBlock) { + if (pBlock == null) return Enums.ReplaceState.Unknown; + + if (Block.blockRegistry.getNameForObject(pBlock) + .equals(_targetBlockName)) return Enums.ReplaceState.CanReplace; + else return Enums.ReplaceState.CannotReplace; + } + + /** + * Internal function + * + * Check if the given Block is equal to the block in this instance and matches the metadata + * + * @param pBlock the block in question + * @param pMeta the metadata in question + * @return + */ + public Enums.ReplaceState blockEquals(Block pBlock, int pMeta) { + Enums.ReplaceState tFlag = Enums.ReplaceState.Unknown; + if (blockEquals(pBlock) == Enums.ReplaceState.CanReplace) { + if (pMeta == _targetMeta || _canAlwaysReplace) tFlag = Enums.ReplaceState.CanReplace; + else tFlag = Enums.ReplaceState.CannotReplace; + } + + return tFlag; + } + + @Override + public boolean equals(Object other) { + if (other == null) return false; + if (other == this) return true; + if (!(other instanceof ModDBMDef)) return false; + ModDBMDef otherModDBMDef = (ModDBMDef) other; + return (otherModDBMDef._targetBlockName.equals(_targetBlockName) && otherModDBMDef._targetMeta == _targetMeta); + } + + /** + * Create a new "Block that can be replaced by ores" definition. Meta defaults to 0 here + * + * @param pTargetBlockName The unlocalizedName of the block + */ + public ModDBMDef(String pTargetBlockName) { + this(pTargetBlockName, 0, false); + } + + /** + * Create a new "Block that can be replaced by ores" definition + * + * @param pTargetBlockName The unlocalizedName of the block + * @param pMetaData The blocks metadata + */ + public ModDBMDef(String pTargetBlockName, int pMetaData) { + this(pTargetBlockName, pMetaData, false); + } + + /** + * Create a new "Block that can be replaced by ores" definition + * + * @param pTargetBlock The instance of the block that can be replaced + * @param pMetaData The blocks metadata + */ + public ModDBMDef(Block pTargetBlock, int pMetaData) { + this(Block.blockRegistry.getNameForObject(pTargetBlock), pMetaData, false); + } + + /** + * Create a new "Block that can be replaced by ores" definition. Meta defaults to 0 here + * + * @param pTargetBlock The instance of the block that can be replaced + */ + public ModDBMDef(Block pTargetBlock) { + this(Block.blockRegistry.getNameForObject(pTargetBlock), 0, false); + } + + /** + * Create a new "Block that can be replaced by ores" definition + * + * @param pTargetBlock + * @param pCanAlwaysReplace set to true if this block can always be replaced, regardless of it's metavalue. Like: + * [block]:* + */ + public ModDBMDef(Block pTargetBlock, boolean pCanAlwaysReplace) { + this(Block.blockRegistry.getNameForObject(pTargetBlock), -1, pCanAlwaysReplace); + } + + /** + * Create a new "Block that can be replaced by ores" definition + * + * @param pTargetBlockName The unlocalizedName of the block + * @param pCanAlwaysReplace set to true if this block can always be replaced, regardless of it's metavalue. Like: + * [block]:* + */ + public ModDBMDef(String pTargetBlockName, boolean pCanAlwaysReplace) { + this(pTargetBlockName, -1, false); + } + + /** + * Create a new "Block that can be replaced by ores" definition + * + * @param pTargetBlockName The unlocalizedName of the block + * @param pMetaData The blocks metadata + * @param pCanAlwaysReplace set to true if this block can always be replaced, regardless of it's metavalue. Like: + * [block]:* + */ + public ModDBMDef(String pTargetBlockName, int pMetaData, boolean pCanAlwaysReplace) { + _targetBlockName = pTargetBlockName; + _targetMeta = pMetaData; + _canAlwaysReplace = pCanAlwaysReplace; + } + + /** + * Internal function Never run this function. It is used to update the blocks name when GalacticGreg is initializing + * its internal structures + * + * @param pParentModName The modname to be attached to the block-name + */ + public void updateBlockName(String pParentModName) { + // Do we already have a FQBN? then do nothing + if (_targetBlockName.contains(":")) { + return; + } + _targetBlockName = String.format("%s:%s", pParentModName, _targetBlockName); + } +} diff --git a/src/main/java/galacticgreg/api/ModDimensionDef.java b/src/main/java/galacticgreg/api/ModDimensionDef.java new file mode 100644 index 0000000000..b456aa031e --- /dev/null +++ b/src/main/java/galacticgreg/api/ModDimensionDef.java @@ -0,0 +1,461 @@ +package galacticgreg.api; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.world.chunk.IChunkProvider; + +// import galacticgreg.GalacticGreg; + +/** + * Class to define a Dimension. Supposed to be added to a ModContainer + */ +public class ModDimensionDef { + + private static final String STR_NOTDEFINED = "iiznotdefined"; + private String _mDimensionName; + private String _mInternalDimIdentifier; + private String _mChunkProvider; + private Enums.AirReplaceRule _mDimAirSetting; + private ArrayList<ModDBMDef> _mReplaceableBlocks; + private Enums.DimensionType _mDimensionType; + + private List<ISpaceObjectGenerator> _mSpaceObjectsGenerators; + private List<ISpaceObjectGenerator> _mSpaceStructureGenerators; + + // Special Planets config settings + private int _mGroundOreMaxY = 64; + private int _mFloatingAsteroidsMinY = 128; + // ------ + + // Override for stonetype + private GTOreTypes _mStoneType; + + // Asteroid stuff + private List<AsteroidBlockComb> _mValidAsteroidMaterials; + private List<SpecialBlockComb> _mSpecialBlocksForAsteroids; + + private Random _mRandom = new Random(System.currentTimeMillis()); + + /** + * Internal function + * + * @return A list of possible asteroid-mixes that shall be generated + */ + public List<AsteroidBlockComb> getValidAsteroidMaterials() { + return _mValidAsteroidMaterials; + } + + // ================================================= + /** + * Internal function The only purpose of this functions is to get a default config value for this dim, that can be + * altered by the mod author which adds the dimension definition to his mod, but also provide the + * modpack-author/serveradmin to change these values aswell + */ + public int getPreConfiguratedGroundOreMaxY() { + return _mGroundOreMaxY; + } + + /** + * Internal function The only purpose of this functions is to get a default config value for this dim, that can be + * altered by the mod author which adds the dimension definition to his mod, but also provide the + * modpack-author/serveradmin to change these values aswell + */ + public int getPreConfiguratedFloatingAsteroidMinY() { + return _mFloatingAsteroidsMinY; + } + + /** + * Register new generator for objects in space. You can register as many as you want. If you don't register + * anything, no structures will generate and the default Asteroid-Generator will be used + * + * @param pSpaceObjectGenerator An instance of your own object generator + */ + public void registerSpaceObjectGenerator(ISpaceObjectGenerator pSpaceObjectGenerator) { + Enums.SpaceObjectType tType = pSpaceObjectGenerator.getType(); + switch (tType) { + case NonOreSchematic: + _mSpaceStructureGenerators.add(pSpaceObjectGenerator); + break; + case OreAsteroid: + _mSpaceObjectsGenerators.add(pSpaceObjectGenerator); + break; + default: + // GalacticGreg.Logger.error("registerSpaceObjectGenerator() found unhandled generator type %s. Please + // report asap, the author was lazy!", tType.toString()); + break; + + } + } + + /** + * Internal function Return a random generator for space objects + */ + public ISpaceObjectGenerator getRandomSOGenerator(Enums.SpaceObjectType pTargetType) { + ISpaceObjectGenerator tGen = null; + List<ISpaceObjectGenerator> tLst = null; + try { + switch (pTargetType) { + case NonOreSchematic: + tLst = _mSpaceStructureGenerators; + break; + case OreAsteroid: + tLst = _mSpaceObjectsGenerators; + break; + default: + break; + } + + if (tLst != null) { + if (tLst.size() == 1) tGen = tLst.get(0); + else if (tLst.size() > 1) tGen = tLst.get(_mRandom.nextInt(tLst.size())); + } + } catch (Exception e) { + e.printStackTrace(); + } + return tGen; + } + + /** + * Define the default values for the floating asteroids and the oregen here. As both generators run in the same + * dimension, and you probably don't want to have asteroids stuck in the ground, both generators are separated from + * each other. Basically, you can go with the default values. If you want to change them, make sure that pOregenMaxY + * is lower than pAsteroidMinY + * + * @param pOregenMaxY The maximum Y-height where ores will be allowed to spawn. Default: 64 + * @param pAsteroidMinY The minimum Y-height that has to be reached before asteroids will spawn. Default: 128 + * @throws IllegalArgumentException if the limits are invalid + * + */ + public void setAsteroidAndPlanetLimits(int pOregenMaxY, int pAsteroidMinY) { + if (pOregenMaxY >= pAsteroidMinY) + throw new IllegalArgumentException("pOregenMaxY must be LOWER than pAsteroidMinY!"); + + _mFloatingAsteroidsMinY = pAsteroidMinY; + _mGroundOreMaxY = pOregenMaxY; + } + // ================================================= + + /** + * Internal function + * + * @return A list of all special blocks that shall be used to generate the asteroids. + */ + public List<SpecialBlockComb> getSpecialBlocksForAsteroids() { + return _mSpecialBlocksForAsteroids; + } + + public List<ISpaceObjectGenerator> getSpaceObjectGenerators() { + return _mSpaceObjectsGenerators; + } + + /** + * Internal function + * + * @return The type for this dimension + */ + public Enums.DimensionType getDimensionType() { + return _mDimensionType; + } + + /** + * Set whether this DimensionDefinition defines an void-dimension that shall spawn asteroids instead of ores in + * stone + * + * @param pType The dimensiontype to be used + */ + public void setDimensionType(Enums.DimensionType pType) { + _mDimensionType = pType; + } + + /** + * Internal function + * + * @return The configuration for AirBlocks + */ + public Enums.AirReplaceRule getAirSetting() { + return _mDimAirSetting; + } + + /** + * Define how the oregen shall handle air-blocks. These settings should be pretty self-explandatory, but anyways: + * NeverReplaceAir: No matter what, if there is an Air-Block found, it will not replace it. AllowReplaceAir: This + * will generate Ores in Stones (defined by addBlockDefinition()) and air if found OnlyReplaceAir : This will not + * generate Ores in solid blocks, but only in air + * + * Note that "OnlyReplaceAir" is a special setting if you have a dimension that is not defined as "Asteroids" but + * you still need/want to generate ores in midair. + * + * @param pSetting + */ + public void setAirSetting(Enums.AirReplaceRule pSetting) { + _mDimAirSetting = pSetting; + } + + /** + * Internal function + * + * @return The dimension identifier that is used internally to identify the dimension + */ + public String getDimIdentifier() { + return _mInternalDimIdentifier; + } + + /** + * Set a manual override for ores that shall be generated. This setting is ignored if getIsAsteroidDimension() + * returns true + * + * For example, on GalactiCraft Mars, this value is set to GTOreTypes.RedGranite, because it matches the color + * better. If you don't set anything here, it will generate regular stone-ores. + * + * @param pStoneType + */ + public void setStoneType(GTOreTypes pStoneType) { + _mStoneType = pStoneType; + } + + /** + * Internal function + * + * @return The stone override for gregtech ores + */ + public GTOreTypes getStoneType() { + return _mStoneType; + } + + /** + * Internal function + * + * @return The attached chunk-provider for this dimension + */ + public String getChunkProviderName() { + return _mChunkProvider; + } + + /** + * Adds a new blockdefinition to this dimension. This block will then later be replaced by ores. You can add as many + * blocks as you want. Just don't add Blocks.Air, as there is another setting for allowing Air-Replacement + * + * @param pBlockDef + * @return + */ + public boolean addBlockDefinition(ModDBMDef pBlockDef) { + if (_mReplaceableBlocks.contains(pBlockDef)) { + return false; + } else { + _mReplaceableBlocks.add(pBlockDef); + return true; + } + } + + /** + * Internal function + * + * @return The DimensionName in a Human-readable format + */ + public String getDimensionName() { + return _mDimensionName; + } + + /** + * Internal function + * + * @return A list of all defined Blocks that can be replaced while generating ores + */ + public ArrayList<ModDBMDef> getReplaceableBlocks() { + return _mReplaceableBlocks; + } + + /** + * Define a new dimension + * + * @param pDimensionName The human-readable. Spaces will be removed + * @param pChunkProvider The chunkprovider class that shall be observed for the oregen + */ + public ModDimensionDef(String pDimensionName, Class<? extends IChunkProvider> pChunkProvider, + Enums.DimensionType pDimType) { + this( + pDimensionName, + pChunkProvider.toString() + .substring(6), + pDimType, + null); + } + + /** + * Define a new dimension + * + * @param pDimensionName The human-readable. Spaces will be removed + * @param pChunkProvider The chunkprovider class that shall be observed for the oregen + * @param pBlockDefinitions The list of predefined blocks to be replaced by ores + */ + public ModDimensionDef(String pDimensionName, Class<? extends IChunkProvider> pChunkProvider, + Enums.DimensionType pDimType, List<ModDBMDef> pBlockDefinitions) { + this( + pDimensionName, + pChunkProvider.toString() + .substring(6), + pDimType, + pBlockDefinitions); + } + + /** + * Define a new dimension + * + * @param pDimensionName The human-readable DimensionName. Spaces will be removed + * @param pChunkProviderName The human-readable, full-qualified classname for the chunkprovider + */ + public ModDimensionDef(String pDimensionName, String pChunkProviderName, Enums.DimensionType pDimType) { + this(pDimensionName, pChunkProviderName, pDimType, null); + } + + /** + * Define a new dimension + * + * @param pDimensionName The human-readable DimensionName. Spaces will be removed + * @param pChunkProviderName The human-readable, full-qualified classname for the chunkprovider + * @param pBlockDefinitions The list of predefined blocks to be replaced by ores + */ + public ModDimensionDef(String pDimensionName, String pChunkProviderName, Enums.DimensionType pDimType, + List<ModDBMDef> pBlockDefinitions) { + _mInternalDimIdentifier = STR_NOTDEFINED; + _mDimensionName = pDimensionName; + _mChunkProvider = pChunkProviderName; + _mDimensionType = pDimType; + + _mReplaceableBlocks = new ArrayList<>(); + if (pBlockDefinitions != null) _mReplaceableBlocks.addAll(pBlockDefinitions); + + _mValidAsteroidMaterials = new ArrayList<>(); + _mSpecialBlocksForAsteroids = new ArrayList<>(); + _mSpaceObjectsGenerators = new ArrayList<>(); + _mSpaceStructureGenerators = new ArrayList<>(); + } + + /** + * Internal function + * + * Do not call this function by yourself. Ever. It will cause explosions, water to blood, death of firstborn,... + * Seriously, don't do it. + */ + protected void setParentModName(String pModName) { + if (_mInternalDimIdentifier.equals(STR_NOTDEFINED)) { + _mInternalDimIdentifier = String.format("%s_%s", pModName, _mDimensionName); + } + + // Else Don't update, we're already set + + } + + /** + * Internal function + * + * Check if pBlock can be replaced by an ore + * + * @param pBlock + * @param pMeta + * @return + */ + public Enums.ReplaceState getReplaceStateForBlock(Block pBlock, int pMeta) { + Enums.ReplaceState tFlag = Enums.ReplaceState.Unknown; + + for (ModDBMDef pDef : _mReplaceableBlocks) { + Enums.ReplaceState tResult = pDef.blockEquals(pBlock, pMeta); + if (tResult == Enums.ReplaceState.Unknown) continue; + + if (tResult == Enums.ReplaceState.CanReplace) { + // GalacticGreg.Logger.trace("Targetblock found and metadata match. Replacement allowed"); + tFlag = Enums.ReplaceState.CanReplace; + } else if (tResult == Enums.ReplaceState.CannotReplace) { + // GalacticGreg.Logger.trace("Targetblock found but metadata mismatch. Replacement denied"); + tFlag = Enums.ReplaceState.CannotReplace; + } + break; + } + + return tFlag; + } + + /** + * Internal function + * + * Randomly select one material out of all defined materials + * + * @return + */ + public AsteroidBlockComb getRandomAsteroidMaterial() { + if (_mValidAsteroidMaterials.size() == 0) return null; + + if (_mValidAsteroidMaterials.size() == 1) return _mValidAsteroidMaterials.get(0); + else { + return _mValidAsteroidMaterials.get(_mRandom.nextInt(_mValidAsteroidMaterials.size())); + } + } + + /** + * Internal function + * + * Randomly select one special block to be placed in the asteroids + * + * @return + */ + public SpecialBlockComb getRandomSpecialAsteroidBlock() { + if (_mSpecialBlocksForAsteroids.size() == 0) return null; + + if (_mSpecialBlocksForAsteroids.size() == 1) return _mSpecialBlocksForAsteroids.get(0); + else { + return _mSpecialBlocksForAsteroids.get(_mRandom.nextInt(_mSpecialBlocksForAsteroids.size())); + } + } + + /** + * Define the material the asteroid shall be made of. Limited to GT-Based Ores and their stones + * + * @param pMaterial + */ + public void addAsteroidMaterial(GTOreTypes pMaterial) { + addAsteroidMaterial(new AsteroidBlockComb(pMaterial)); + } + + /** + * Define the material the asteroid shall be made of, more advanced option to specify your own blocks + * + * @param pBlockComb + */ + public void addAsteroidMaterial(AsteroidBlockComb pBlockComb) { + if (!_mValidAsteroidMaterials.contains(pBlockComb)) { + _mValidAsteroidMaterials.add(pBlockComb); + } + } + + /** + * Adds a new material for asteroid generation. These will spawn randomly in asteroids if enabled. You can basically + * add every block you can imagine. Be warned though, if you use Liquids (Water / Lava / ..), it can affect + * performance if the liquid is flowing down to the void. So make sure you define "AsteroidCore" as position + * + * @param pBlock Block-Meta Combination that shall be used + */ + public void addSpecialAsteroidBlock(SpecialBlockComb pBlock) { + if (!_mSpecialBlocksForAsteroids.contains(pBlock)) { + _mSpecialBlocksForAsteroids.add(pBlock); + } + } + + /** + * Internal function Called when GalacticGreg will finalize all its internal structures. You should never call this + * yourself + */ + public void finalizeReplaceableBlocks(String pParentModName) { + for (ModDBMDef rpb : _mReplaceableBlocks) { + try { + rpb.updateBlockName(pParentModName); + if (_mStoneType == null) _mStoneType = GTOreTypes.NormalOres; + } catch (Exception e) { + // GalacticGreg.Logger.error("Unable to finalize replaceable block with modname for block %s. Dimension + // %s will probably have problems generating ores", rpb.getBlockName(), _mDimensionName); + } + } + } +} diff --git a/src/main/java/galacticgreg/api/SpecialBlockComb.java b/src/main/java/galacticgreg/api/SpecialBlockComb.java new file mode 100644 index 0000000000..2cf812169a --- /dev/null +++ b/src/main/java/galacticgreg/api/SpecialBlockComb.java @@ -0,0 +1,69 @@ +package galacticgreg.api; + +import net.minecraft.block.Block; + +public class SpecialBlockComb extends BlockMetaComb { + + private Enums.AllowedBlockPosition _mBlockPosition; + + /** + * Creates a simple instance for a block that has a meta value and a block position it is allowed to spawn + * + * @param pBlock The Block in question + * @param pMeta The meta value of the block + * @param pBlockPosition The position this block is allowed to generate + */ + public SpecialBlockComb(Block pBlock, int pMeta, Enums.AllowedBlockPosition pBlockPosition) { + super(pBlock, pMeta); + _mBlockPosition = pBlockPosition; + } + + /** + * Creates a simple instance for a block that has no meta value but a position it is allowed to spawn + * + * @param pBlock The Block in question. 0 is used as meta + * @param pBlockPosition The position this block is allowed to generate + */ + public SpecialBlockComb(Block pBlock, Enums.AllowedBlockPosition pBlockPosition) { + super(pBlock, 0); + _mBlockPosition = pBlockPosition; + } + + /** + * Creates a simple instance for a block that has no meta value and is allowed to spawn everywhere + * + * @param pBlock The Block in question. 0 is used as meta, and "CoreAndShell" is used as position + */ + public SpecialBlockComb(Block pBlock) { + super(pBlock, 0); + _mBlockPosition = Enums.AllowedBlockPosition.AsteroidCoreAndShell; + } + + /** + * Internal function + * + * @return The position the block is supposed to spawn at + */ + public Enums.AllowedBlockPosition getBlockPosition() { + return _mBlockPosition; + } + + @Override + public boolean equals(Object other) { + if (other == null) return false; + if (other == this) return true; + if (!(other instanceof SpecialBlockComb)) return false; + SpecialBlockComb otherObj = (SpecialBlockComb) other; + + boolean tFlag = true; + String otherName = Block.blockRegistry.getNameForObject(otherObj.getBlock()); + String thisName = Block.blockRegistry.getNameForObject(this.getBlock()); + if (!otherName.equals(thisName)) tFlag = false; + + if (!(otherObj.getMeta() == this.getMeta())) tFlag = false; + + if (!(otherObj.getBlockPosition() == this.getBlockPosition())) tFlag = false; + + return tFlag; + } +} diff --git a/src/main/java/galacticgreg/api/StructureInformation.java b/src/main/java/galacticgreg/api/StructureInformation.java new file mode 100644 index 0000000000..4c33f88c20 --- /dev/null +++ b/src/main/java/galacticgreg/api/StructureInformation.java @@ -0,0 +1,59 @@ +package galacticgreg.api; + +import net.minecraft.util.Vec3; + +import galacticgreg.api.Enums.TargetBlockPosition; + +/** + * Structural information container. Holds X/Y/Z and block/meta information + */ +public class StructureInformation { + + private Vec3 _mCoordinates; + private TargetBlockPosition _mBlockPosition; + private BlockMetaComb _mBlockMetaComb; + + public TargetBlockPosition getBlockPosition() { + return _mBlockPosition; + } + + public int getX() { + return (int) Math.round(_mCoordinates.xCoord); + } + + public int getY() { + return (int) Math.round(_mCoordinates.yCoord); + } + + public int getZ() { + return (int) Math.round(_mCoordinates.zCoord); + } + + public BlockMetaComb getBlock() { + return _mBlockMetaComb; + } + + /** + * Init StructureInfo only with Coords and block position + * + * @param pCoordinates The coords in question + * @param pPosition The position-enum value + */ + public StructureInformation(Vec3 pCoordinates, TargetBlockPosition pPosition) { + this(pCoordinates, pPosition, null); + } + + /** + * Init StructureInfo with Coords, block position and a populated block/meta info + * + * @param pCoordinates The coords in question + * @param pPosition The position-enum value + * @param pTargetBlock The target block in question + */ + public StructureInformation(Vec3 pCoordinates, TargetBlockPosition pPosition, BlockMetaComb pTargetBlock) { + _mCoordinates = pCoordinates; + _mBlockPosition = pPosition; + _mBlockMetaComb = pTargetBlock; + } + +} diff --git a/src/main/java/galacticgreg/api/enums/DimensionBlockMetaDefinitionList.java b/src/main/java/galacticgreg/api/enums/DimensionBlockMetaDefinitionList.java new file mode 100644 index 0000000000..a9cf4a4e79 --- /dev/null +++ b/src/main/java/galacticgreg/api/enums/DimensionBlockMetaDefinitionList.java @@ -0,0 +1,57 @@ +package galacticgreg.api.enums; + +import java.util.Arrays; +import java.util.List; + +import net.minecraft.init.Blocks; + +import galacticgreg.api.ModDBMDef; + +public enum DimensionBlockMetaDefinitionList { + + Moon(new ModDBMDef("tile.moonBlock", 4)), + Mars(new ModDBMDef("tile.mars", 9)), + Phobos(new ModDBMDef("phobosblocks", 2)), + Deimos(new ModDBMDef("deimosblocks", 1)), + Ceres(new ModDBMDef("ceresblocks", 1)), + Io(new ModDBMDef("ioblocks", 2)), + Ganymede(new ModDBMDef("ganymedeblocks", 1)), + Callisto(new ModDBMDef("callistoblocks", 1)), + Venus(new ModDBMDef("venusblocks", 1)), + Mercury(new ModDBMDef("mercuryblocks", 2)), + Enceladus(new ModDBMDef("enceladusblocks", 1)), + Titan(new ModDBMDef("titanblocks", 2)), + Oberon(new ModDBMDef("oberonblocks", 2)), + Proteus(new ModDBMDef("proteusblocks", 2)), + Triton(new ModDBMDef("tritonblocks", 2)), + Pluto(new ModDBMDef("plutoblocks", 5)), + MakeMake(new ModDBMDef("makemakegrunt", 1)), + Haumea(new ModDBMDef("haumeablocks")), + CentauriAlpha(new ModDBMDef("acentauribbsubgrunt")), + VegaB(new ModDBMDef("vegabsubgrunt")), + BarnardaC(new ModDBMDef("barnardaCdirt"), new ModDBMDef(Blocks.stone)), + BarnardaE(new ModDBMDef("barnardaEsubgrunt")), + BarnardaF(new ModDBMDef("barnardaFsubgrunt")), + TcetiE(new ModDBMDef("tcetieblocks", 2)), + Miranda(new ModDBMDef("mirandablocks", 2)), + Europa( + // Europa top layer turned off bc ores are too easy to spot + new ModDBMDef("europagrunt", 1), // Europa Ice Layer ~55-65 without top layer + new ModDBMDef(Blocks.water), new ModDBMDef(Blocks.flowing_water), new ModDBMDef(Blocks.ice), // Generates + // directly over + // bedrock + new ModDBMDef(Blocks.packed_ice), // Generates directly over bedrock + new ModDBMDef("europaunderwatergeyser") // Generates directly over bedrock + ), + Neper(new ModDBMDef(Blocks.stone), new ModDBMDef("tile.baseBlockRock", 10)), + Maahes(new ModDBMDef("tile.baseBlockRock", 1)), + Anubis(new ModDBMDef("tile.baseBlockRock", 1)), + Horus(new ModDBMDef(Blocks.obsidian)), + Seth(new ModDBMDef(Blocks.hardened_clay)); + + public final List<ModDBMDef> DBMDefList; + + private DimensionBlockMetaDefinitionList(ModDBMDef... DBMDefArray) { + DBMDefList = Arrays.asList(DBMDefArray); + } +} diff --git a/src/main/java/galacticgreg/api/enums/DimensionDef.java b/src/main/java/galacticgreg/api/enums/DimensionDef.java new file mode 100644 index 0000000000..96626ee7f3 --- /dev/null +++ b/src/main/java/galacticgreg/api/enums/DimensionDef.java @@ -0,0 +1,228 @@ +package galacticgreg.api.enums; + +import net.minecraft.world.gen.ChunkProviderEnd; + +import galacticgreg.api.Enums; +import galacticgreg.api.ModDimensionDef; + +public enum DimensionDef { + + EndAsteroids(new ModDimensionDef(DimNames.ENDASTEROIDS, ChunkProviderEnd.class, Enums.DimensionType.Asteroid)), + Moon(new ModDimensionDef( + DimNames.MOON, + "micdoodle8.mods.galacticraft.core.world.gen.ChunkProviderMoon", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Moon.DBMDefList)), + Mars(new ModDimensionDef( + DimNames.MARS, + "micdoodle8.mods.galacticraft.planets.mars.world.gen.ChunkProviderMars", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Mars.DBMDefList)), + Asteroids(new ModDimensionDef( + DimNames.ASTEROIDS, + "micdoodle8.mods.galacticraft.planets.asteroids.world.gen.ChunkProviderAsteroids", + Enums.DimensionType.Asteroid)), + Pluto(new ModDimensionDef( + DimNames.PLUTO, + "galaxyspace.SolarSystem.planets.pluto.dimension.ChunkProviderPluto", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Pluto.DBMDefList)), + Triton(new ModDimensionDef( + DimNames.TRITON, + "galaxyspace.SolarSystem.moons.triton.dimension.ChunkProviderTriton", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Triton.DBMDefList)), + Proteus(new ModDimensionDef( + DimNames.PROTEUS, + "galaxyspace.SolarSystem.moons.proteus.dimension.ChunkProviderProteus", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Proteus.DBMDefList)), + Oberon(new ModDimensionDef( + DimNames.OBERON, + "galaxyspace.SolarSystem.moons.oberon.dimension.ChunkProviderOberon", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Oberon.DBMDefList)), + Titan(new ModDimensionDef( + DimNames.TITAN, + "galaxyspace.SolarSystem.moons.titan.dimension.ChunkProviderTitan", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Titan.DBMDefList)), + Callisto(new ModDimensionDef( + DimNames.CALLISTO, + "galaxyspace.SolarSystem.moons.callisto.dimension.ChunkProviderCallisto", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Callisto.DBMDefList)), + Ganymede(new ModDimensionDef( + DimNames.GANYMEDE, + "galaxyspace.SolarSystem.moons.ganymede.dimension.ChunkProviderGanymede", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Ganymede.DBMDefList)), + Ceres(new ModDimensionDef( + DimNames.CERES, + "galaxyspace.SolarSystem.planets.ceres.dimension.ChunkProviderCeres", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Ceres.DBMDefList)), + Deimos(new ModDimensionDef( + DimNames.DEIMOS, + "galaxyspace.SolarSystem.moons.deimos.dimension.ChunkProviderDeimos", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Deimos.DBMDefList)), + Enceladus(new ModDimensionDef( + DimNames.ENCELADUS, + "galaxyspace.SolarSystem.moons.enceladus.dimension.ChunkProviderEnceladus", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Enceladus.DBMDefList)), + Io(new ModDimensionDef( + DimNames.IO, + "galaxyspace.SolarSystem.moons.io.dimension.ChunkProviderIo", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Io.DBMDefList)), + Europa(new ModDimensionDef( + DimNames.EUROPA, + "galaxyspace.SolarSystem.moons.europa.dimension.ChunkProviderEuropa", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Europa.DBMDefList)), + Phobos(new ModDimensionDef( + DimNames.PHOBOS, + "galaxyspace.SolarSystem.moons.phobos.dimension.ChunkProviderPhobos", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Phobos.DBMDefList)), + Venus(new ModDimensionDef( + DimNames.VENUS, + "galaxyspace.SolarSystem.planets.venus.dimension.ChunkProviderVenus", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Venus.DBMDefList)), + Mercury(new ModDimensionDef( + DimNames.MERCURY, + "galaxyspace.SolarSystem.planets.mercury.dimension.ChunkProviderMercury", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Mercury.DBMDefList)), + MakeMake(new ModDimensionDef( + DimNames.MAKEMAKE, + "galaxyspace.SolarSystem.planets.makemake.dimension.ChunkProviderMakemake", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.MakeMake.DBMDefList)), + Haumea(new ModDimensionDef( + DimNames.HAUMEA, + "galaxyspace.SolarSystem.planets.haumea.dimension.ChunkProviderHaumea", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Haumea.DBMDefList)), + CentauriAlpha(new ModDimensionDef( + DimNames.CENTAURIA, + "galaxyspace.ACentauriSystem.planets.aCentauriBb.dimension.ChunkProviderACentauri", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.CentauriAlpha.DBMDefList)), + VegaB(new ModDimensionDef( + DimNames.VEGAB, + "galaxyspace.VegaSystem.planets.vegaB.dimension.ChunkProviderVegaB", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.VegaB.DBMDefList)), + BarnardC(new ModDimensionDef( + DimNames.BARNARDC, + "galaxyspace.BarnardsSystem.planets.barnardaC.dimension.ChunkProviderBarnardaC", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.BarnardaC.DBMDefList)), + BarnardE(new ModDimensionDef( + DimNames.BARNARDE, + "galaxyspace.BarnardsSystem.planets.barnardaE.dimension.ChunkProviderBarnardaE", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.BarnardaE.DBMDefList)), + BarnardF(new ModDimensionDef( + DimNames.BARNARDF, + "galaxyspace.BarnardsSystem.planets.barnardaF.dimension.ChunkProviderBarnardaF", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.BarnardaF.DBMDefList)), + TcetiE(new ModDimensionDef( + DimNames.TCETIE, + "galaxyspace.TCetiSystem.planets.tcetiE.dimension.ChunkProviderTCetiE", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.TcetiE.DBMDefList)), + Miranda(new ModDimensionDef( + DimNames.MIRANDA, + "galaxyspace.SolarSystem.moons.miranda.dimension.ChunkProviderMiranda", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Miranda.DBMDefList)), + KuiperBelt(new ModDimensionDef( + DimNames.KUIPERBELT, + "galaxyspace.SolarSystem.planets.kuiperbelt.dimension.ChunkProviderKuiper", + Enums.DimensionType.Asteroid)), + + Neper(new ModDimensionDef( + DimNames.NEPER, + "de.katzenpapst.amunra.world.neper.NeperChunkProvider", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Neper.DBMDefList)), + Maahes(new ModDimensionDef( + DimNames.MAAHES, + "de.katzenpapst.amunra.world.maahes.MaahesChunkProvider", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Maahes.DBMDefList)), + Anubis(new ModDimensionDef( + DimNames.ANUBIS, + "de.katzenpapst.amunra.world.anubis.AnubisChunkProvider", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Anubis.DBMDefList)), + Horus(new ModDimensionDef( + DimNames.HORUS, + "de.katzenpapst.amunra.world.horus.HorusChunkProvider", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Horus.DBMDefList)), + Seth(new ModDimensionDef( + DimNames.SETH, + "de.katzenpapst.amunra.world.seth.SethChunkProvider", + Enums.DimensionType.Planet, + DimensionBlockMetaDefinitionList.Seth.DBMDefList)), + MehenBelt(new ModDimensionDef( + DimNames.MEHENBELT, + "de.katzenpapst.amunra.world.mehen.MehenChunkProvider", + Enums.DimensionType.Asteroid)); + + public static class DimNames { + + public static final String ENDASTEROIDS = "EndAsteroids"; + public static final String MOON = "Moon"; + public static final String MARS = "Mars"; + public static final String ASTEROIDS = "Asteroids"; + public static final String PLUTO = "Pluto"; + public static final String TRITON = "Triton"; + public static final String PROTEUS = "Proteus"; + public static final String OBERON = "Oberon"; + public static final String TITAN = "Titan"; + public static final String ROSS128B = "Ross128b"; + public static final String ROSS128BA = "Ross128ba"; + public static final String CALLISTO = "Callisto"; + public static final String GANYMEDE = "Ganymede"; + public static final String CERES = "Ceres"; + public static final String DEIMOS = "Deimos"; + public static final String ENCELADUS = "Enceladus"; + public static final String IO = "Io"; + public static final String EUROPA = "Europa"; + public static final String PHOBOS = "Phobos"; + public static final String VENUS = "Venus"; + public static final String MERCURY = "Mercury"; + public static final String MAKEMAKE = "MakeMake"; + public static final String HAUMEA = "Haumea"; + public static final String CENTAURIA = "CentauriA"; + public static final String VEGAB = "VegaB"; + public static final String BARNARDC = "BarnardC"; + public static final String BARNARDE = "BarnardE"; + public static final String BARNARDF = "BarnardF"; + public static final String TCETIE = "TcetiE"; + public static final String MIRANDA = "Miranda"; + public static final String KUIPERBELT = "Kuiperbelt"; + public static final String NEPER = "Neper"; + public static final String MAAHES = "Maahes"; + public static final String ANUBIS = "Anubis"; + public static final String HORUS = "Horus"; + public static final String SETH = "Seth"; + public static final String MEHENBELT = "MehenBelt"; + public static final String DEEPDARK = "Underdark"; + + } + + public final ModDimensionDef modDimensionDef; + + private DimensionDef(ModDimensionDef modDimDef) { + this.modDimensionDef = modDimDef; + } +} diff --git a/src/main/java/galacticgreg/api/enums/ModContainers.java b/src/main/java/galacticgreg/api/enums/ModContainers.java new file mode 100644 index 0000000000..7352e5a75c --- /dev/null +++ b/src/main/java/galacticgreg/api/enums/ModContainers.java @@ -0,0 +1,19 @@ +package galacticgreg.api.enums; + +import galacticgreg.api.ModContainer; +import gregtech.api.enums.Mods; + +public enum ModContainers { + + GalactiCraftCore(new ModContainer(Mods.GalacticraftCore.ID)), + GalacticraftMars(new ModContainer(Mods.GalacticraftMars.ID)), + GalaxySpace(new ModContainer(Mods.GalaxySpace.ID)), + AmunRa(new ModContainer("GalacticraftAmunRa")), + Vanilla(new ModContainer("Vanilla")); + + public final ModContainer modContainer; + + private ModContainers(ModContainer modContainer) { + this.modContainer = modContainer; + } +} diff --git a/src/main/java/galacticgreg/api/enums/properties/AsteroidPropertyBuilder.java b/src/main/java/galacticgreg/api/enums/properties/AsteroidPropertyBuilder.java new file mode 100644 index 0000000000..bf5fecc78a --- /dev/null +++ b/src/main/java/galacticgreg/api/enums/properties/AsteroidPropertyBuilder.java @@ -0,0 +1,105 @@ +package galacticgreg.api.enums.properties; + +public class AsteroidPropertyBuilder { + + public int probability; + public int sizeMin, sizeMax; + public int specialBlockChance; + public OreSpawnPropertyBuilder oreSpawn; + public LootPropertyBuilder loot; + + public static class OreSpawnPropertyBuilder { + + public int baseOreChance; + public boolean obeyHeighLimits; + public boolean oresOnlyInsideAsteroids; + public int primaryToRareOreOffset; + public int smallOreChance; + + public OreSpawnPropertyBuilder baseOreChance(int baseOreChance) { + this.baseOreChance = baseOreChance; + return this; + } + + public OreSpawnPropertyBuilder doesObeyingHeightLimits(boolean obeyHeighLimits) { + this.obeyHeighLimits = obeyHeighLimits; + return this; + } + + public OreSpawnPropertyBuilder AreOresOnlyInsideAsteroids(boolean oresOnlyInsideAsteroids) { + this.oresOnlyInsideAsteroids = oresOnlyInsideAsteroids; + return this; + } + + public OreSpawnPropertyBuilder primaryToRareOreOffset(int primaryToRareOreOffset) { + this.primaryToRareOreOffset = primaryToRareOreOffset; + return this; + } + + public OreSpawnPropertyBuilder smallOreChance(int smallOreChance) { + this.smallOreChance = smallOreChance; + return this; + } + + } + + public static class LootPropertyBuilder { + + public int lootChestChance; + public int lootChestItemCount; + public int lootChestTable; + public boolean randomizeLootItemCount; + + public LootPropertyBuilder lootChestChance(int lootChestChance) { + this.lootChestChance = lootChestChance; + return this; + } + + public LootPropertyBuilder lootChestItemCount(int lootChestItemCount) { + this.lootChestItemCount = lootChestItemCount; + return this; + } + + public LootPropertyBuilder lootChestTable(int lootChestTable) { + this.lootChestTable = lootChestTable; + return this; + } + + public LootPropertyBuilder isLootItemCountRandomized(boolean randomizeLootItemCount) { + this.randomizeLootItemCount = randomizeLootItemCount; + return this; + } + + } + + public AsteroidPropertyBuilder() { + oreSpawn = new OreSpawnPropertyBuilder(); + loot = new LootPropertyBuilder(); + } + + public AsteroidPropertyBuilder probability(int probability) { + this.probability = probability; + return this; + } + + public AsteroidPropertyBuilder sizeRange(int sizeMin, int sizeMax) { + this.sizeMin = sizeMin; + this.sizeMax = sizeMax; + return this; + } + + public AsteroidPropertyBuilder specialBlockChance(int specialBlockChance) { + this.specialBlockChance = specialBlockChance; + return this; + } + + public AsteroidPropertyBuilder oreSpawn(OreSpawnPropertyBuilder oreSpawnPropertyBuilder) { + this.oreSpawn = oreSpawnPropertyBuilder; + return this; + } + + public AsteroidPropertyBuilder loot(LootPropertyBuilder lootPropertyBuilder) { + this.loot = lootPropertyBuilder; + return this; + } +} diff --git a/src/main/java/galacticgreg/api/enums/properties/Asteroids.java b/src/main/java/galacticgreg/api/enums/properties/Asteroids.java new file mode 100644 index 0000000000..2916031aaf --- /dev/null +++ b/src/main/java/galacticgreg/api/enums/properties/Asteroids.java @@ -0,0 +1,78 @@ +package galacticgreg.api.enums.properties; + +import galacticgreg.api.enums.DimensionDef; +import galacticgreg.api.enums.ModContainers; + +public enum Asteroids { + + // spotless : off + EndAsteroids(ModContainers.Vanilla, DimensionDef.EndAsteroids, new AsteroidPropertyBuilder().probability(200) + .sizeRange(5, 15) + .specialBlockChance(5) + .oreSpawn( + new AsteroidPropertyBuilder.OreSpawnPropertyBuilder().baseOreChance(5) + .doesObeyingHeightLimits(false) + .AreOresOnlyInsideAsteroids(false) + .primaryToRareOreOffset(5) + .smallOreChance(10)) + .loot( + new AsteroidPropertyBuilder.LootPropertyBuilder().lootChestChance(1) + .lootChestItemCount(10) + .lootChestTable(3) + .isLootItemCountRandomized(true))), + KuiperBelt(ModContainers.GalaxySpace, DimensionDef.KuiperBelt, new AsteroidPropertyBuilder().probability(200) + .sizeRange(5, 15) + .specialBlockChance(5) + .oreSpawn( + new AsteroidPropertyBuilder.OreSpawnPropertyBuilder().baseOreChance(5) + .doesObeyingHeightLimits(false) + .AreOresOnlyInsideAsteroids(false) + .primaryToRareOreOffset(5) + .smallOreChance(10)) + .loot( + new AsteroidPropertyBuilder.LootPropertyBuilder().lootChestChance(1) + .lootChestItemCount(10) + .lootChestTable(3) + .isLootItemCountRandomized(true))), + MehenBelt(ModContainers.AmunRa, DimensionDef.MehenBelt, new AsteroidPropertyBuilder().probability(200) + .sizeRange(5, 15) + .specialBlockChance(5) + .oreSpawn( + new AsteroidPropertyBuilder.OreSpawnPropertyBuilder().baseOreChance(5) + .doesObeyingHeightLimits(false) + .AreOresOnlyInsideAsteroids(false) + .primaryToRareOreOffset(5) + .smallOreChance(10)) + .loot( + new AsteroidPropertyBuilder.LootPropertyBuilder().lootChestChance(1) + .lootChestItemCount(10) + .lootChestTable(3) + .isLootItemCountRandomized(true))), + Asteroids(ModContainers.GalacticraftMars, DimensionDef.Asteroids, new AsteroidPropertyBuilder().probability(200) + .sizeRange(5, 15) + .specialBlockChance(5) + .oreSpawn( + new AsteroidPropertyBuilder.OreSpawnPropertyBuilder().baseOreChance(5) + .doesObeyingHeightLimits(false) + .AreOresOnlyInsideAsteroids(false) + .primaryToRareOreOffset(5) + .smallOreChance(10)) + .loot( + new AsteroidPropertyBuilder.LootPropertyBuilder().lootChestChance(1) + .lootChestItemCount(10) + .lootChestTable(3) + .isLootItemCountRandomized(true))),; + + // spotless : on + + public ModContainers modContainers; + public DimensionDef dimensionDef; + public AsteroidPropertyBuilder asteroidPropertyBuilder; + + private Asteroids(ModContainers modContainers, DimensionDef dimensionDef, + AsteroidPropertyBuilder asteroidPropertyBuilder) { + this.modContainers = modContainers; + this.dimensionDef = dimensionDef; + this.asteroidPropertyBuilder = asteroidPropertyBuilder; + } +} diff --git a/src/main/java/galacticgreg/auxiliary/ConfigManager.java b/src/main/java/galacticgreg/auxiliary/ConfigManager.java new file mode 100644 index 0000000000..b460757609 --- /dev/null +++ b/src/main/java/galacticgreg/auxiliary/ConfigManager.java @@ -0,0 +1,79 @@ +package galacticgreg.auxiliary; + +import java.io.File; + +import net.minecraftforge.common.config.Configuration; + +import galacticgreg.GalacticGreg; + +/** + * config class to read/setup config files and folders + * + * @author Namikon + */ +public abstract class ConfigManager { + + private File _mainconfigDir = null; + private File _blocksconfigDir = null; + private String _mModCollection = ""; + private String _mModID = ""; + + protected Configuration _mainConfig = null; + + protected File _mConfigBaseDirectory; + public boolean DoDebugMessages = false; + + protected abstract void PreInit(); + + protected abstract void Init(); + + protected abstract void PostInit(); + + public ConfigManager(File pConfigBaseDirectory, String pModCollectionDirectory, String pModID) { + _mModCollection = pModCollectionDirectory; + _mModID = pModID; + _mConfigBaseDirectory = pConfigBaseDirectory; + } + + /** + * Load/init the config file + * + * @return true/false if the load/init was successful or not + */ + public boolean LoadConfig() { + try { + InitConfigDirs(); + if (_mainConfig == null) return false; + + PreInit(); + _mainConfig.load(); + Init(); + _mainConfig.save(); + PostInit(); + + return true; + } catch (Exception e) { + GalacticGreg.Logger.error("Unable to init config file"); + e.printStackTrace(); + return false; + } + } + + /** + * Search for required config-directory / file and create them if they can't be found + */ + private void InitConfigDirs() { + GalacticGreg.Logger.debug("Checking/creating config folders"); + + _mainconfigDir = new File(String.format("%s%s%s", _mConfigBaseDirectory, File.separator, _mModCollection)); + + if (!_mainconfigDir.exists()) { + GalacticGreg.Logger.info("Config folder not found. Creating..."); + _mainconfigDir.mkdir(); + } + + File tRealConfigFile = new File(String.format("%s%s%s%s", _mainconfigDir, File.separator, _mModID, ".cfg")); + + _mainConfig = new Configuration(tRealConfigFile); + } +} diff --git a/src/main/java/galacticgreg/auxiliary/GTOreGroup.java b/src/main/java/galacticgreg/auxiliary/GTOreGroup.java new file mode 100644 index 0000000000..bf5fb39c07 --- /dev/null +++ b/src/main/java/galacticgreg/auxiliary/GTOreGroup.java @@ -0,0 +1,19 @@ +package galacticgreg.auxiliary; + +/** + * Just a simple container to wrap 4 GT Ore-Meta ids into one var + */ +public class GTOreGroup { + + public short PrimaryMeta; + public short SecondaryMeta; + public short SporadicBetweenMeta; + public short SporadicAroundMeta; + + public GTOreGroup(short pPrimaryMeta, short pSecondaryMeta, short pSporadicBetweenMeta, short pSporadicAroundMeta) { + PrimaryMeta = pPrimaryMeta; + SecondaryMeta = pSecondaryMeta; + SporadicBetweenMeta = pSporadicBetweenMeta; + SporadicAroundMeta = pSporadicAroundMeta; + } +} diff --git a/src/main/java/galacticgreg/auxiliary/GalacticGregConfig.java b/src/main/java/galacticgreg/auxiliary/GalacticGregConfig.java new file mode 100644 index 0000000000..39980925a1 --- /dev/null +++ b/src/main/java/galacticgreg/auxiliary/GalacticGregConfig.java @@ -0,0 +1,141 @@ +package galacticgreg.auxiliary; + +import java.io.File; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; + +import cpw.mods.fml.common.registry.GameRegistry; +import galacticgreg.GalacticGreg; +import galacticgreg.api.BlockMetaComb; + +public class GalacticGregConfig extends ConfigManager { + + public GalacticGregConfig(File pConfigBaseDirectory, String pModCollectionDirectory, String pModID) { + super(pConfigBaseDirectory, pModCollectionDirectory, pModID); + + } + + public boolean ProfileOreGen; + public boolean ReportOreGenFailures; + public boolean PrintDebugMessagesToFMLLog; + public boolean PrintTraceMessagesToFMLLog; + + public boolean LootChestsEnabled; + public boolean EnableAEExportCommand; + public boolean SchematicsEnabled; + public String LootChestItemOverride; + public boolean QuietMode; + + public BlockMetaComb CustomLootChest; + + @Override + protected void PreInit() { + ProfileOreGen = false; + ReportOreGenFailures = false; + PrintDebugMessagesToFMLLog = false; + PrintTraceMessagesToFMLLog = false; + + LootChestsEnabled = true; + + // Default false, as it is WiP + EnableAEExportCommand = false; + SchematicsEnabled = false; + + LootChestItemOverride = ""; + QuietMode = false; + } + + @Override + protected void Init() { + ProfileOreGen = _mainConfig.getBoolean( + "ProfileOreGen", + "Debug", + ProfileOreGen, + "Enable to profile oregen and register the ingame command ggregprofiler"); + ReportOreGenFailures = _mainConfig.getBoolean( + "ReportOreGenFailures", + "Debug", + ReportOreGenFailures, + "Report if a ore tileentity could not be placed"); + PrintDebugMessagesToFMLLog = _mainConfig.getBoolean( + "PrintDebugMessagesToFMLLog", + "Debug", + PrintDebugMessagesToFMLLog, + "Enable debug output, not recommended for servers"); + PrintTraceMessagesToFMLLog = _mainConfig.getBoolean( + "PrintTraceMessagesToFMLLog", + "Debug", + PrintTraceMessagesToFMLLog, + "Enable trace output. Warning: This will produce gazillions of log entries"); + QuietMode = _mainConfig.getBoolean( + "QuietMode", + "Debug", + QuietMode, + "In quiet-mode only errors, warnings and fatals will be printed to the logfile/console"); + + LootChestsEnabled = _mainConfig.getBoolean( + "LootChestsEnabled", + "Extras", + LootChestsEnabled, + "Enables/disables the dungeon-chest generator system for asteroids. New config values will be generated if set to true"); + EnableAEExportCommand = _mainConfig.getBoolean( + "EnableAEExportCommand", + "Extras", + EnableAEExportCommand, + "If set to true, you can export any structure stored on a AE2 spatial storage disk. (Can't be spawned yet, WiP). Requires SchematicsEnabled to be true"); + SchematicsEnabled = _mainConfig.getBoolean( + "SchematicsEnabled", + "Extras", + SchematicsEnabled, + "Enable the experimental Schematics-handler to spawn exported schematics in dimensions. This is WiP, use at own risk"); + LootChestItemOverride = _mainConfig.getString( + "CustomLootChest", + "Extras", + LootChestItemOverride, + "Define the chest you wish to use as LootChest. use the <ModID>:<Name>:<meta> format or leave empty for the default Minecraft Chest"); + + GalacticGreg.Logger.setDebugOutput(PrintDebugMessagesToFMLLog); + GalacticGreg.Logger.setTraceOutput(PrintTraceMessagesToFMLLog); + GalacticGreg.Logger.setQuietMode(QuietMode); + } + + @Override + protected void PostInit() { + + } + + public boolean serverPostInit() { + CustomLootChest = new BlockMetaComb(Blocks.chest); + try { + if (LootChestItemOverride != "") { + String[] args = LootChestItemOverride.split(":"); + String tMod; + String tName; + int tMeta; + + if (args.length >= 2) { + tMod = args[0]; + tName = args[1]; + if (args.length == 3) tMeta = Integer.parseInt(args[2]); + else tMeta = 0; + + Block tBlock = GameRegistry.findBlock(tMod, tName); + if (tBlock != null) { + GalacticGreg.Logger + .debug("Found valid ChestOverride: %s. LootChest replaced", LootChestItemOverride); + CustomLootChest = new BlockMetaComb(tBlock, tMeta); + } + } + } + + return true; + } catch (Exception e) { + GalacticGreg.Logger.error( + "Unable to find custom chest override %s. Make sure item exists. Defaulting to Minecraft:chest", + LootChestItemOverride); + e.printStackTrace(); + return false; + } + } +} diff --git a/src/main/java/galacticgreg/auxiliary/LogHelper.java b/src/main/java/galacticgreg/auxiliary/LogHelper.java new file mode 100644 index 0000000000..d4a3bb5dfc --- /dev/null +++ b/src/main/java/galacticgreg/auxiliary/LogHelper.java @@ -0,0 +1,267 @@ +package galacticgreg.auxiliary; + +import java.util.ArrayList; + +import org.apache.logging.log4j.Level; + +import cpw.mods.fml.common.FMLLog; + +/** + * Generic LogHelper to print stuff to the console + * + * @author Namikon + */ +public final class LogHelper { + + private ArrayList<String> _mReportedCategories = new ArrayList<>(); + private boolean doDebugLogs = false; + private boolean doTraceLogs = false; + private boolean quietMode = false; + private String _mModID = ""; + + private final static String STR_NOCAT = "ihaznocathegory"; + private final static String STR_TOKEN_ONETIMEMESSAGE = " OTM"; + + public LogHelper(String pModID) { + _mModID = pModID; + } + + /** + * If true, only error/fatal/warn messages will be printed + * + * @param pEnabled + */ + public void setQuietMode(boolean pEnabled) { + quietMode = pEnabled; + } + + /** + * Enable/Disable debug logs + * + * @param pEnabled + */ + public void setDebugOutput(boolean pEnabled) { + doDebugLogs = pEnabled; + } + + /** + * Enable/Disable trace logs + * + * @param pEnabled + */ + public void setTraceOutput(boolean pEnabled) { + doTraceLogs = pEnabled; + } + + /** + * Resets all One-Time categories, so they will be displayed again + */ + public void ResetCategories() { + _mReportedCategories = new ArrayList<>(); + } + + /** + * Print a log-message with built-in String.format(x) support. This message will only appear once. usefull for + * error/warnings within loops + * + * @param pCategory The category for this message. Used to identify the function, use an easy to memorize name. Will + * never be displayed + * @param pLogLevel The logLevel for this message + * @param pMessage The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void log(String pCategory, Level pLogLevel, String pMessage, Object... args) { + if (pLogLevel == Level.DEBUG && !doDebugLogs) return; + + if (pLogLevel == Level.TRACE && !doTraceLogs) return; + + if (pLogLevel != Level.ERROR && pLogLevel != Level.FATAL && pLogLevel != Level.WARN) if (quietMode) return; + + String tt = ""; + if (!pCategory.equals(STR_NOCAT)) { + tt = STR_TOKEN_ONETIMEMESSAGE; + if (_mReportedCategories.contains(pCategory)) return; + else { + _mReportedCategories.add(pCategory); + } + } + + FMLLog.log(_mModID.toUpperCase() + tt, pLogLevel, pMessage, args); + } + + /** + * Prints a one-time message with Category ALL + * + * @param pCategory The category for this message. Used to identify the function, use an easy to memorize name. Will + * never be displayed + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void ot_all(String pCategory, String object, Object... args) { + log(pCategory, Level.ALL, object, args); + } + + /** + * Prints a one-time message with Category DEBUG + * + * @param pCategory The category for this message. Used to identify the function, use an easy to memorize name. Will + * never be displayed + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void ot_debug(String pCategory, String object, Object... args) { + log(pCategory, Level.DEBUG, object, args); + } + + /** + * Prints a one-time message with Category ERROR + * + * @param pCategory The category for this message. Used to identify the function, use an easy to memorize name. Will + * never be displayed + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void ot_error(String pCategory, String object, Object... args) { + log(pCategory, Level.ERROR, object, args); + } + + /** + * Prints a one-time message with Category FATAL + * + * @param pCategory The category for this message. Used to identify the function, use an easy to memorize name. Will + * never be displayed + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void ot_fatal(String pCategory, String object, Object... args) { + log(pCategory, Level.FATAL, object, args); + } + + /** + * Prints a one-time message with Category INFO + * + * @param pCategory The category for this message. Used to identify the function, use an easy to memorize name. Will + * never be displayed + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void ot_info(String pCategory, String object, Object... args) { + log(pCategory, Level.INFO, object, args); + } + + /** + * Prints a one-time message with Category OFF + * + * @param pCategory The category for this message. Used to identify the function, use an easy to memorize name. Will + * never be displayed + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void ot_off(String pCategory, String object, Object... args) { + log(pCategory, Level.OFF, object, args); + } + + /** + * Prints a one-time message with Category TRACE + * + * @param pCategory The category for this message. Used to identify the function, use an easy to memorize name. Will + * never be displayed + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void ot_trace(String pCategory, String object, Object... args) { + log(pCategory, Level.TRACE, object, args); + } + + /** + * Prints a one-time message with Category WARN + * + * @param pCategory The category for this message. Used to identify the function, use an easy to memorize name. Will + * never be displayed + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void ot_warn(String pCategory, String object, Object... args) { + log(pCategory, Level.WARN, object, args); + } + + /** + * Prints a message with Category ALL + * + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void all(String object, Object... args) { + log(STR_NOCAT, Level.ALL, object, args); + } + + /** + * Prints a message with Category DEBUG + * + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void debug(String object, Object... args) { + log(STR_NOCAT, Level.DEBUG, object, args); + } + + /** + * Prints a message with Category ERROR + * + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void error(String object, Object... args) { + log(STR_NOCAT, Level.ERROR, object, args); + } + + /** + * Prints a message with Category FATAL + * + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void fatal(String object, Object... args) { + log(STR_NOCAT, Level.FATAL, object, args); + } + + /** + * Prints a message with Category INFO + * + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void info(String object, Object... args) { + log(STR_NOCAT, Level.INFO, object, args); + } + + /** + * Prints a message with Category OFF + * + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void off(String object, Object... args) { + log(STR_NOCAT, Level.OFF, object, args); + } + + /** + * Prints a message with Category TRACE + * + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void trace(String object, Object... args) { + log(STR_NOCAT, Level.TRACE, object, args); + } + + /** + * Prints a message with Category WARN + * + * @param object The log message + * @param args Optional args, if you've used format-specifier in pMessage + */ + public void warn(String object, Object... args) { + log(STR_NOCAT, Level.WARN, object, args); + } +} diff --git a/src/main/java/galacticgreg/auxiliary/PlayerChatHelper.java b/src/main/java/galacticgreg/auxiliary/PlayerChatHelper.java new file mode 100644 index 0000000000..faf73713a9 --- /dev/null +++ b/src/main/java/galacticgreg/auxiliary/PlayerChatHelper.java @@ -0,0 +1,106 @@ +package galacticgreg.auxiliary; + +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; + +/** + * Method to easily send chat-messages to EntityPlayer + * + * @author Namikon + * + */ +public class PlayerChatHelper { + + /** + * Meant for notifications that are being send to an admin/op Color will be GREEN + * + * @param pPlayer + * @param pMessage + */ + public static void SendInfo(ICommandSender pCommandSender, String pMessage) { + pCommandSender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + pMessage)); + } + + /** + * Meant for notifications that are being send to an admin/op Color will be RED + * + * @param pPlayer + * @param pMessage + */ + public static void SendError(ICommandSender pCommandSender, String pMessage) { + pCommandSender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + pMessage)); + } + + /** + * Meant for notifications that are being send to an admin/op Color will be YELLOW + * + * @param pPlayer + * @param pMessage + */ + public static void SendWarn(ICommandSender pCommandSender, String pMessage) { + pCommandSender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + pMessage)); + } + + /** + * Meant for notifications that are being send to an admin/op Color will be GREEN + * + * @param pPlayer + * @param pMessage + */ + public static void SendInfo(EntityPlayer pPlayer, String pMessage) { + pPlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + pMessage)); + } + + /** + * Meant for notifications that are being send to an admin/op Color will be RED + * + * @param pPlayer + * @param pMessage + */ + public static void SendError(EntityPlayer pPlayer, String pMessage) { + pPlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + pMessage)); + } + + /** + * Meant for notifications that are being send to an admin/op Color will be YELLOW + * + * @param pPlayer + * @param pMessage + */ + public static void SendWarn(EntityPlayer pPlayer, String pMessage) { + pPlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + pMessage)); + } + + /** + * Meant for ingame notifications that are being send to a player, not an admin/op Color will be DARK_GREEN + * + * @param pPlayer + * @param pMessage + */ + public static void SendNotifyPositive(EntityPlayer pPlayer, String pMessage) { + pPlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.DARK_GREEN + pMessage)); + } + + /** + * Meant for ingame notifications that are being send to a player, not an admin/op Color will be AQUA + * + * @param pPlayer + * @param pMessage + */ + public static void SendNotifyNormal(EntityPlayer pPlayer, String pMessage) { + pPlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.AQUA + pMessage)); + } + + /** + * Meant for ingame notifications that are being send to a player, not an admin/op Color will be DARK_PURPLE + * + * @param pPlayer + * @param pMessage + */ + public static void SendNotifyWarning(EntityPlayer pPlayer, String pMessage) { + pPlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.DARK_PURPLE + pMessage)); + } + +} diff --git a/src/main/java/galacticgreg/auxiliary/ProfilingStorage.java b/src/main/java/galacticgreg/auxiliary/ProfilingStorage.java new file mode 100644 index 0000000000..b429b7f76a --- /dev/null +++ b/src/main/java/galacticgreg/auxiliary/ProfilingStorage.java @@ -0,0 +1,74 @@ +package galacticgreg.auxiliary; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import galacticgreg.api.ModDimensionDef; + +/** + * A simple FIFO-storage for Long-values Will keep 50 values for each dimension in memory Doesn't need to be changed + * when adding new planets/mods + */ +public class ProfilingStorage { + + private Map<String, List<Long>> mProfilingMap; + + public ProfilingStorage() { + mProfilingMap = new HashMap<>(); + } + + /** + * Add a new time to the list of pDimension. Will be ignored it tTotalTime == 0 + * + * @param pDimension + * @param pTotalTime + */ + public void AddTimeToList(ModDimensionDef pDimension, long pTotalTime) { + try { + if (pTotalTime == 0) return; + + if (!mProfilingMap.containsKey(pDimension.getDimIdentifier())) + mProfilingMap.put(pDimension.getDimIdentifier(), new LinkedList<>()); + + LinkedList<Long> ll = (LinkedList<Long>) mProfilingMap.get(pDimension.getDimIdentifier()); + + ll.addLast(pTotalTime); + + while (ll.size() > 50) ll.removeFirst(); + } catch (Exception e) { + // Just do nothing. profiling is for debug purposes only anyways... + } + } + + /** + * Return the average time required to execute the oregen in Dimension pDimension + * + * @param pDimension The DimensionType in question + * @return + */ + public long GetAverageTime(ModDimensionDef pDimension) { + try { + if (!mProfilingMap.containsKey(pDimension.getDimIdentifier())) return -1; + + int tTotalVal = 0; + long tAverage = 0; + long tReturnVal = 0; + + LinkedList<Long> ll = (LinkedList<Long>) mProfilingMap.get(pDimension.getDimIdentifier()); + + if (ll != null) { + for (Long aLong : ll) { + tAverage += aLong; + tTotalVal++; + } + + tReturnVal = (long) ((float) (tAverage / tTotalVal)); + } + return tReturnVal; + } catch (Exception e) { + return -1; + } + } +} diff --git a/src/main/java/galacticgreg/command/AEStorageCommand.java b/src/main/java/galacticgreg/command/AEStorageCommand.java new file mode 100644 index 0000000000..7aff0ff107 --- /dev/null +++ b/src/main/java/galacticgreg/command/AEStorageCommand.java @@ -0,0 +1,180 @@ +package galacticgreg.command; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import appeng.api.util.WorldCoord; +import appeng.items.storage.ItemSpatialStorageCell; +import galacticgreg.GalacticGreg; +import galacticgreg.auxiliary.PlayerChatHelper; +import galacticgreg.schematics.SpaceSchematic; +import galacticgreg.schematics.SpaceSchematicFactory; + +/** + * This command allows to export any structure that has been stored inside a spatial storage cell to a xml file that can + * later be enabled for spawning in dimensions. + */ +public class AEStorageCommand implements ICommand { + + private List<String> aliases; + + public AEStorageCommand() { + this.aliases = new ArrayList<>(); + this.aliases.add("exportae"); + } + + @Override + public String getCommandName() { + return "exportae"; + } + + @Override + public String getCommandUsage(ICommandSender pCommandSender) { + return "exportae <structure name>"; + } + + @Override + public List<String> getCommandAliases() { + return this.aliases; + } + + @Override + public void processCommand(ICommandSender pCommandSender, String[] pArgs) { + try { + if (pCommandSender instanceof EntityPlayer) { + if (pArgs.length < 1) return; + + String tName = pArgs[0]; + + EntityPlayer tEP = (EntityPlayer) pCommandSender; + // Check if item in hand is a spatial storage cell + ItemStack tIS = tEP.inventory.getCurrentItem(); + if (tIS.getItem() instanceof ItemSpatialStorageCell) { + ItemSpatialStorageCell tCell = (ItemSpatialStorageCell) tIS.getItem(); + World tSpatialWorld = tCell.getWorld(tIS); + WorldCoord storedSize = tCell.getStoredSize(tIS); + + // Check if SSC is filled + if (storedSize.x == 0 || storedSize.y == 0 || storedSize.z == 0) { + PlayerChatHelper.SendError(pCommandSender, "Error: This spatial storage is empty"); + return; + } + + // Export structure + GalacticGreg.Logger.info( + "Creating Structure from Spatial AE drive. Dimensions: X [%d] Y [%d] Z [%d]", + storedSize.x, + storedSize.y, + storedSize.z); + SpaceSchematic tSchematic = SpaceSchematicFactory.createSchematic(tName); + boolean tTEWarningSend = false; + + // Loop all 3 dimensions + for (int lX = 1; lX <= storedSize.x; lX++) { + for (int lY = 65; lY < 65 + storedSize.y; lY++) { + for (int lZ = 1; lZ <= storedSize.z; lZ++) { + + // Get the block + Block b = tSpatialWorld.getBlock(lX, lY, lZ); + // Get the meta + int bm = tSpatialWorld.getBlockMetadata(lX, lY, lZ); + + // Search for the blocks name + String tBlockName = Block.blockRegistry.getNameForObject(b); + + // Check if block is a tileentity + TileEntity bTE = tSpatialWorld.getTileEntity(lX, lY, lZ); + + String tMsg = String.format("[X-%d][Y-%d][Z-%d] ", lX, lY, lZ); + String nbtComp = ""; + // If block could be found... + if (b != null) { + tMsg += tBlockName; + // If block is a TileEntity + if (bTE != null) { + // Print a warning on the console + tMsg += " TE"; + GalacticGreg.Logger.warn( + "Warning: Found TileEntity at X[%d] Y[%d] Z[%d]. NBT States are not exported!", + lX, + lY, + lZ); + if (!tTEWarningSend) { + // Send a warning ingame, once per export command + tTEWarningSend = true; + PlayerChatHelper + .SendWarn(pCommandSender, "TileEntity states are not exported!"); + } + + } + + // If the block is not air, add it to the structure + if (b != Blocks.air) tSchematic + .addStructureInfo(SpaceSchematicFactory.createStructureInfo(lX, lY, lZ, b, bm)); + } + } + } + } + + // Save structure to disk + if (!GalacticGreg.SchematicHandler.SaveSpaceStructure(tSchematic)) { + // Something went wrong... + PlayerChatHelper.SendError(pCommandSender, "Something went wrong. Structure not saved"); + } else { + // All good, xml exported. Notify player that he needs to edit the file + PlayerChatHelper.SendInfo( + pCommandSender, + "Structure has been exported to " + tSchematic.getName() + + ".xml. It contains " + + tSchematic.coordInfo() + .size() + + " Blocks"); + PlayerChatHelper + .SendInfo(pCommandSender, "You have to edit the file before a reload will accept it!"); + } + } else PlayerChatHelper + .SendError(pCommandSender, "Error: Item in your hand is not a spatial storage drive!"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public boolean canCommandSenderUseCommand(ICommandSender pCommandSender) { + // Command is only enabled for actual players and only if they are OP-ed + if (pCommandSender instanceof EntityPlayerMP) { + EntityPlayerMP tEP = (EntityPlayerMP) pCommandSender; + return MinecraftServer.getServer() + .getConfigurationManager() + .func_152596_g(tEP.getGameProfile()); + } else return false; + } + + @Override + public int compareTo(Object o) { + return 0; + } + + @SuppressWarnings("rawtypes") + @Override + public List addTabCompletionOptions(ICommandSender p_71516_1_, String[] p_71516_2_) { + return null; + } + + @Override + public boolean isUsernameIndex(String[] p_82358_1_, int p_82358_2_) { + return false; + } +} diff --git a/src/main/java/galacticgreg/command/ProfilingCommand.java b/src/main/java/galacticgreg/command/ProfilingCommand.java new file mode 100644 index 0000000000..91805265dc --- /dev/null +++ b/src/main/java/galacticgreg/command/ProfilingCommand.java @@ -0,0 +1,99 @@ +package galacticgreg.command; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ChatComponentText; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.relauncher.Side; +import galacticgreg.GalacticGreg; +import galacticgreg.api.ModContainer; +import galacticgreg.api.ModDimensionDef; +import galacticgreg.registry.GalacticGregRegistry; + +/** + * Ingame command to get the average oregen time(s) for the active dimensions Doesn't need to be changed when adding new + * planets/mods + * + */ +public class ProfilingCommand implements ICommand { + + private List<String> aliases; + + public ProfilingCommand() { + this.aliases = new ArrayList<>(); + this.aliases.add("ggregprofiler"); + } + + @Override + public String getCommandName() { + return "ggregprofiler"; + } + + @Override + public String getCommandUsage(ICommandSender pCommandSender) { + return "ggregprofiler"; + } + + @Override + public List<String> getCommandAliases() { + return this.aliases; + } + + @Override + public void processCommand(ICommandSender pCommandSender, String[] pArgs) { + pCommandSender.addChatMessage(new ChatComponentText("Average OreGen times:")); + + for (ModContainer mc : GalacticGregRegistry.getModContainers()) { + String tModName = mc.getModName(); + for (ModDimensionDef mdd : mc.getDimensionList()) { + long tTime = GalacticGreg.Profiler.GetAverageTime(mdd); + String tInfo; + if (tTime == -1) tInfo = "N/A"; + else tInfo = String.format("%d ms", tTime); + pCommandSender.addChatMessage( + new ChatComponentText( + String.format("%s (%s): %s", mdd.getDimIdentifier(), mdd.getDimensionName(), tInfo))); + } + } + } + + @Override + public boolean canCommandSenderUseCommand(ICommandSender pCommandSender) { + if (FMLCommonHandler.instance() + .getEffectiveSide() == Side.SERVER + && !FMLCommonHandler.instance() + .getMinecraftServerInstance() + .isDedicatedServer()) + return true; + + if (pCommandSender instanceof EntityPlayerMP) { + EntityPlayerMP tEP = (EntityPlayerMP) pCommandSender; + return MinecraftServer.getServer() + .getConfigurationManager() + .func_152596_g(tEP.getGameProfile()); + } + return false; + } + + @Override + public int compareTo(Object o) { + return 0; + } + + @SuppressWarnings("rawtypes") + @Override + public List addTabCompletionOptions(ICommandSender p_71516_1_, String[] p_71516_2_) { + return null; + } + + @Override + public boolean isUsernameIndex(String[] p_82358_1_, int p_82358_2_) { + return false; + } +} diff --git a/src/main/java/galacticgreg/dynconfig/DynamicDimensionConfig.java b/src/main/java/galacticgreg/dynconfig/DynamicDimensionConfig.java new file mode 100644 index 0000000000..87dad97f35 --- /dev/null +++ b/src/main/java/galacticgreg/dynconfig/DynamicDimensionConfig.java @@ -0,0 +1,160 @@ +package galacticgreg.dynconfig; + +import java.util.HashMap; +import java.util.Map; + +import net.minecraftforge.common.ChestGenHooks; + +import galacticgreg.GalacticGreg; +import galacticgreg.api.Enums.DimensionType; +import galacticgreg.api.ModContainer; +import galacticgreg.api.ModDimensionDef; +import galacticgreg.api.enums.properties.Asteroids; +import galacticgreg.registry.GalacticGregRegistry; + +public class DynamicDimensionConfig { + + public static class AsteroidConfig { + + public int MinSize; + public int MaxSize; + public int Probability; + public int OreChance; + public int OrePrimaryOffset; + public int SpecialBlockChance; + public int SmallOreChance; + public boolean ObeyHeightLimits; + public boolean HiddenOres; + public int LootChestChance; + public int LootChestTable; + public int NumLootItems; + public boolean RandomizeNumLootItems; + } + + private static Map<String, AsteroidConfig> _mDynamicAsteroidMap = new HashMap<>(); + + public static AsteroidConfig getAsteroidConfig(ModDimensionDef pDimDef) { + return _mDynamicAsteroidMap.getOrDefault(pDimDef.getDimIdentifier(), null); + } + + public static boolean InitDynamicConfig() { + try { + for (ModContainer mc : GalacticGregRegistry.getModContainers()) { + if (!mc.getEnabled()) continue; + + for (ModDimensionDef mdd : mc.getDimensionList()) { + DimensionType dt = mdd.getDimensionType(); + if (dt != DimensionType.Asteroid) { + continue; + } + String tDimIdentifier = mdd.getDimIdentifier(); + if (_mDynamicAsteroidMap.containsKey(tDimIdentifier)) { + GalacticGreg.Logger.warn( + "Found 2 Dimensions with the same Identifier! This should never happen, and you should report this to me. Identifier in question: %s", + tDimIdentifier); + continue; + } + + Asteroids AsteroidProperties = null; + for (Asteroids asteroidsConfig : Asteroids.values()) { + if (!asteroidsConfig.modContainers.modContainer.getModName() + .equals(mc.getModName())) { + continue; + } + if (!asteroidsConfig.dimensionDef.modDimensionDef.getDimensionName() + .equals(mdd.getDimensionName())) { + continue; + } + AsteroidProperties = asteroidsConfig; + break; + } + if (AsteroidProperties == null) { + GalacticGreg.Logger.error( + "Something went wrong! no properties are existing for Asteroid dim: " + + mdd.getDimensionName() + + " from mod container " + + mc.getModName()); + continue; + } + + AsteroidConfig aConf = new AsteroidConfig(); + + aConf.MinSize = AsteroidProperties.asteroidPropertyBuilder.sizeMin; + aConf.MaxSize = AsteroidProperties.asteroidPropertyBuilder.sizeMax; + aConf.Probability = AsteroidProperties.asteroidPropertyBuilder.probability; + aConf.SpecialBlockChance = AsteroidProperties.asteroidPropertyBuilder.specialBlockChance; + + aConf.OreChance = AsteroidProperties.asteroidPropertyBuilder.oreSpawn.baseOreChance; + aConf.OrePrimaryOffset = AsteroidProperties.asteroidPropertyBuilder.oreSpawn.primaryToRareOreOffset; + aConf.SmallOreChance = AsteroidProperties.asteroidPropertyBuilder.oreSpawn.smallOreChance; + aConf.ObeyHeightLimits = AsteroidProperties.asteroidPropertyBuilder.oreSpawn.obeyHeighLimits; + aConf.HiddenOres = AsteroidProperties.asteroidPropertyBuilder.oreSpawn.oresOnlyInsideAsteroids; + + if (GalacticGreg.GalacticConfig.LootChestsEnabled) { + aConf.LootChestChance = AsteroidProperties.asteroidPropertyBuilder.loot.lootChestChance; + aConf.LootChestTable = AsteroidProperties.asteroidPropertyBuilder.loot.lootChestTable; + aConf.NumLootItems = AsteroidProperties.asteroidPropertyBuilder.loot.lootChestItemCount; + aConf.RandomizeNumLootItems = AsteroidProperties.asteroidPropertyBuilder.loot.randomizeLootItemCount; + } else { + aConf.LootChestChance = 0; + aConf.LootChestTable = 1; + aConf.NumLootItems = 0; + aConf.RandomizeNumLootItems = false; + } + + if (aConf.MaxSize > 50) GalacticGreg.Logger.warn( + "Asteroid-MaxSize for dimID [%s] is larger than 50. This might cause memory-problems, as the maximum asteroid size will be larger than 50*50*50 blocks", + tDimIdentifier); + _mDynamicAsteroidMap.put(tDimIdentifier, aConf); + + } + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * Convert numbers to actual loot-table entries + * + * @param pACfg + * @return + */ + public static String getLootChestTable(AsteroidConfig pACfg) { + String tLootTable = ChestGenHooks.MINESHAFT_CORRIDOR; + + switch (pACfg.LootChestTable) { + case 2: + tLootTable = ChestGenHooks.PYRAMID_DESERT_CHEST; + break; + case 3: + tLootTable = ChestGenHooks.PYRAMID_JUNGLE_CHEST; + break; + case 4: + tLootTable = ChestGenHooks.PYRAMID_JUNGLE_DISPENSER; + break; + case 5: + tLootTable = ChestGenHooks.STRONGHOLD_CORRIDOR; + break; + case 6: + tLootTable = ChestGenHooks.STRONGHOLD_LIBRARY; + break; + case 7: + tLootTable = ChestGenHooks.STRONGHOLD_CROSSING; + break; + case 8: + tLootTable = ChestGenHooks.VILLAGE_BLACKSMITH; + break; + case 9: + tLootTable = ChestGenHooks.BONUS_CHEST; + break; + case 10: + tLootTable = ChestGenHooks.DUNGEON_CHEST; + break; + } + + return tLootTable; + } +} diff --git a/src/main/java/galacticgreg/generators/GenEllipsoid.java b/src/main/java/galacticgreg/generators/GenEllipsoid.java new file mode 100644 index 0000000000..432260a696 --- /dev/null +++ b/src/main/java/galacticgreg/generators/GenEllipsoid.java @@ -0,0 +1,126 @@ +package galacticgreg.generators; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import net.minecraft.util.MathHelper; +import net.minecraft.util.Vec3; + +import galacticgreg.api.Enums.SpaceObjectType; +import galacticgreg.api.Enums.TargetBlockPosition; +import galacticgreg.api.ISpaceObjectGenerator; +import galacticgreg.api.StructureInformation; + +/** + * Simple ellipsoid-generator. Based on the formular created by Chrysator. Thanks for the help! + * + * Generates a simple ellipsoid with dynamic rotation, random size-values, random noise for the surface, etc. Can + * probably be tweaked even more, but works for now... + */ +public class GenEllipsoid implements ISpaceObjectGenerator { + + private Vec3 _mEllipsoidCenter; + private Random _mRandom; + private List<StructureInformation> _mStructure; + + private double _mCoreDensity = 0.7D; + private double _mSineFactor = 0.05D; + private float _mRandomInfluence; + private float _mRandomAngleX; + private float _mRandomAngleY; + private float _mRandomAngleZ; + + private int _mSizeA; + private int _mSizeB; + private int _mSizeC; + + public GenEllipsoid() { + reset(); + } + + @Override + public SpaceObjectType getType() { + return SpaceObjectType.OreAsteroid; + } + + @Override + public void randomize(int pSizeMin, int pSizeMax) { + _mRandom = new Random(System.currentTimeMillis()); + _mRandomAngleX = (float) (_mRandom.nextFloat() * Math.PI); + _mRandomAngleY = (float) (_mRandom.nextFloat() * Math.PI); + _mRandomAngleZ = (float) (_mRandom.nextFloat() * Math.PI); + + _mRandomInfluence = _mRandom.nextFloat(); + + _mSizeA = pSizeMin + _mRandom.nextInt(pSizeMax - pSizeMin) + 10; + _mSizeB = pSizeMin + _mRandom.nextInt(pSizeMax - pSizeMin) + 10; + _mSizeC = pSizeMin + _mRandom.nextInt(pSizeMax - pSizeMin) + 10; + } + + @Override + public void setCenterPoint(int pX, int pY, int pZ) { + _mEllipsoidCenter = Vec3.createVectorHelper(pX, pY, pZ); + } + + @Override + public void setCenterPoint(Vec3 pCenter) { + _mEllipsoidCenter = pCenter; + } + + @Override + public Vec3 getCenterPoint() { + return _mEllipsoidCenter; + } + + @Override + public List<StructureInformation> getStructure() { + return _mStructure; + } + + @Override + public void calculate() { + int Xmin = (int) (_mEllipsoidCenter.xCoord - _mSizeA); + int Xmax = (int) (_mEllipsoidCenter.xCoord + _mSizeA); + int Ymin = (int) (_mEllipsoidCenter.yCoord - _mSizeB); + int Ymax = (int) (_mEllipsoidCenter.yCoord + _mSizeB); + int Zmin = (int) (_mEllipsoidCenter.zCoord - _mSizeC); + int Zmax = (int) (_mEllipsoidCenter.zCoord + _mSizeC); + + for (int iX = Xmin; iX <= Xmax; iX++) { + for (int iY = Ymin; iY <= Ymax; iY++) { + for (int iZ = Zmin; iZ <= Zmax; iZ++) { + double tmpX = Math.pow(_mEllipsoidCenter.xCoord - iX, 2) / Math.pow(_mSizeA, 2); + double tmpY = Math.pow(_mEllipsoidCenter.yCoord - iY, 2) / Math.pow(_mSizeB, 2); + double tmpZ = Math.pow(_mEllipsoidCenter.zCoord - iZ, 2) / Math.pow(_mSizeC, 2); + double val = (tmpX + tmpY + tmpZ); + + Vec3 tPoint = Vec3.createVectorHelper(iX, iY, iZ); + tPoint.rotateAroundX(_mRandomAngleX); + tPoint.rotateAroundY(_mRandomAngleY); + tPoint.rotateAroundZ(_mRandomAngleZ); + + TargetBlockPosition tbp = TargetBlockPosition.Invalid; + + if (val <= 0.01D) tbp = TargetBlockPosition.AsteroidInnerCore; + + else if (val > 0.01D && val < _mCoreDensity) tbp = TargetBlockPosition.AsteroidCore; + + else if (val >= _mCoreDensity && val <= (1.0D + - (_mSineFactor * MathHelper.sin((iZ + iX + iY - _mRandom.nextFloat() * _mRandomInfluence))))) + tbp = TargetBlockPosition.AsteroidShell; + + if (tbp != TargetBlockPosition.Invalid) + _mStructure.add(new StructureInformation(Vec3.createVectorHelper(iX, iY, iZ), tbp)); + + } + } + } + } + + @Override + public void reset() { + _mStructure = new ArrayList<>(); + _mEllipsoidCenter = Vec3.createVectorHelper(0, 0, 0); + } +} diff --git a/src/main/java/galacticgreg/registry/GalacticGregRegistry.java b/src/main/java/galacticgreg/registry/GalacticGregRegistry.java new file mode 100644 index 0000000000..9dc5d0fa04 --- /dev/null +++ b/src/main/java/galacticgreg/registry/GalacticGregRegistry.java @@ -0,0 +1,183 @@ +package galacticgreg.registry; + +import static galacticgreg.api.enums.ModContainers.Vanilla; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.world.chunk.IChunkProvider; + +import cpw.mods.fml.common.Loader; +import galacticgreg.GalacticGreg; +import galacticgreg.api.Enums.DimensionType; +import galacticgreg.api.ModContainer; +import galacticgreg.api.ModDimensionDef; +import galacticgreg.dynconfig.DynamicDimensionConfig; +import galacticgreg.generators.GenEllipsoid; + +/** + * GalacticGregs registry + * + */ +public class GalacticGregRegistry { + + private static final Map<String, ModContainer> _mModContainers = new HashMap<>(); + public static final String DIM_UNKNOWN = "GGREG_DIMENSION_UNKNOWN"; + private static boolean _mInitializationDone = false; + + /** + * Register new ModContainer in the registry. Call this after you've populated it with Dimensions and Blocks Must be + * called from your own PreInit or Init event + * + * @param pModContainer + * @return + */ + public static boolean registerModContainer(ModContainer pModContainer) { + if (_mInitializationDone) { + GalacticGreg.Logger.warn("Initialization is already done, you can't add more ModContainers!"); + return false; + } + + if (_mModContainers.containsKey(pModContainer.getModName())) { + GalacticGreg.Logger + .warn("There is already a mod registered with that name: [%s]", pModContainer.getModName()); + return false; + } else { + GalacticGreg.Logger.info( + "Registered new mod to generate ores: [%s] Dimensions provided: [%d]", + pModContainer.getModName(), + pModContainer.getDimensionList() + .size()); + _mModContainers.put(pModContainer.getModName(), pModContainer); + return true; + } + } + + /** + * Lookup the registered dimensions and try to find the DimensionDefinition that has the ChunkProvider that we have + * here + * + * @param pChunkProvider + * @return + */ + public static ModDimensionDef getDimensionTypeByChunkGenerator(IChunkProvider pChunkProvider) { + try { + if (!_mInitializationDone) return null; + + String tFQCPN = pChunkProvider.toString() + .split("@")[0]; + ModDimensionDef tReturnMDD = null; + + for (ModContainer mc : _mModContainers.values()) { + for (ModDimensionDef mdd : mc.getDimensionList()) { + if (mdd.getChunkProviderName() + .equals(tFQCPN)) { + tReturnMDD = mdd; + break; + } + } + } + + return tReturnMDD; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * Get all registered modcontainers. Can only be done after the initialization process is done + * + * @return + */ + public static Collection<ModContainer> getModContainers() { + if (!_mInitializationDone) return null; + + return _mModContainers.values(); + } + + /** + * Initializes the Registry. Never do this in your code, GalacticGreg will crash if you do so + */ + public static boolean InitRegistry() { + if (_mInitializationDone) // never run init twice! + return false; + + InitModContainers(); + + DynamicDimensionConfig.InitDynamicConfig(); + return true; + } + + /** + * Parse modcontainers and search for loaded mods. Enable found mods for generation + */ + private static void InitModContainers() { + for (ModContainer mc : _mModContainers.values()) { + // todo: rename Vanilla mod container name from "Vanilla" to "minecraft" + if (!Loader.isModLoaded(mc.getModName()) && !mc.getModName() + .equals(Vanilla.modContainer.getModName())) { + GalacticGreg.Logger.warn( + "Ignoring ModRegistration for OreGen: [%s], because mod is not loaded. Did you misspell the name?", + mc.getModName()); + mc.setEnabled(false); + } else { + GalacticGreg.Logger.info("Mod [%s] is now enabled for OreGen by GalacticGreg", mc.getModName()); + mc.setEnabled(true); + for (ModDimensionDef md : mc.getDimensionList()) { + GalacticGreg.Logger.info( + "ModID: [%s] DimName: [%s] ValidBlocks: [%d] Identifier: [%s] Generators: [%d]", + mc.getModName(), + md.getDimensionName(), + md.getReplaceableBlocks() + .size(), + md.getDimIdentifier(), + md.getSpaceObjectGenerators() + .size()); + + // Register default generator if dimension is asteroid and no generator was added + if (md.getDimensionType() == DimensionType.Asteroid) { + if (md.getSpaceObjectGenerators() + .size() == 0) { + GalacticGreg.Logger.debug("No generators found, adding build-in ellipsoid generator"); + md.registerSpaceObjectGenerator(new GenEllipsoid()); + } + GalacticGreg.Logger.info( + "Asteroid-Enabled dimension. Registered Generators: [%d]", + md.getSpaceObjectGenerators() + .size()); + } + + md.finalizeReplaceableBlocks(mc.getModName()); + } + } + } + _mInitializationDone = true; + } + + /** + * Returns ModContainer for given DimensionDefinition + * + * @param pDimensionDefinition + * @return + */ + public static ModContainer getModContainerForDimension(ModDimensionDef pDimensionDefinition) { + if (!_mInitializationDone) return null; + + try { + for (ModContainer mc : _mModContainers.values()) { + for (ModDimensionDef md : mc.getDimensionList()) { + if (pDimensionDefinition.getDimIdentifier() + .equals(md.getDimIdentifier())) { + return mc; + } + } + } + return null; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/galacticgreg/schematics/SpaceSchematic.java b/src/main/java/galacticgreg/schematics/SpaceSchematic.java new file mode 100644 index 0000000000..976b699e85 --- /dev/null +++ b/src/main/java/galacticgreg/schematics/SpaceSchematic.java @@ -0,0 +1,100 @@ +package galacticgreg.schematics; + +import java.util.ArrayList; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; + +import net.minecraft.block.Block; +import net.minecraft.util.Vec3; + +import galacticgreg.api.StructureInformation; + +/** + * Class for XML Structure files. You only should edit/use this file/class if you want to add/fix stuff with + * GalacticGreg itself, and never if you're a mod developer and want to add support for GGreg to your mod. However, feel + * free to copy this code to your own mod to implement structures. If you have questions, find me on github and ask + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "SpaceSchematic") +public class SpaceSchematic { + + @XmlAttribute(name = "enabled") + protected boolean _mStructureEnabled; + @XmlAttribute(name = "centerX") + protected int _mCenterX; + @XmlAttribute(name = "centerY") + protected int _mCenterY; + @XmlAttribute(name = "centerZ") + protected int _mCenterZ; + + @XmlElement(name = "StructureName") + protected String _mStructureName; + + @XmlElement(name = "Rarity") + protected int _mRarity; + + @XmlElementWrapper(name = "Coords") + @XmlElement(name = "block") + protected ArrayList<BaseStructureInfo> mStructureInfoList; + + public boolean isEnabled() { + return _mStructureEnabled; + } + + public Vec3 getStructureCenter() { + return Vec3.createVectorHelper(_mCenterX, _mCenterY, _mCenterZ); + } + + public int getRarity() { + return _mRarity; + } + + public String getName() { + return _mStructureName; + } + + public ArrayList<BaseStructureInfo> coordInfo() { + if (mStructureInfoList == null) mStructureInfoList = new ArrayList<>(); + + return mStructureInfoList; + } + + public void addStructureInfo(StructureInformation pStrucInfo) { + if (mStructureInfoList == null) mStructureInfoList = new ArrayList<>(); + mStructureInfoList.add(new BaseStructureInfo(pStrucInfo)); + } + + public static class BaseStructureInfo { + + @XmlAttribute(name = "X") + protected int posX; + @XmlAttribute(name = "Y") + protected int posY; + @XmlAttribute(name = "Z") + protected int posZ; + @XmlAttribute(name = "Block") + protected String blockName; + @XmlAttribute(name = "Meta") + protected int blockMeta; + + public BaseStructureInfo(StructureInformation pSI) { + posX = pSI.getX(); + posY = pSI.getY(); + posZ = pSI.getZ(); + blockName = Block.blockRegistry.getNameForObject( + pSI.getBlock() + .getBlock()); + blockMeta = pSI.getBlock() + .getMeta(); + } + + public Vec3 getVec3Pos() { + return Vec3.createVectorHelper(posX, posY, posZ); + } + } +} diff --git a/src/main/java/galacticgreg/schematics/SpaceSchematicFactory.java b/src/main/java/galacticgreg/schematics/SpaceSchematicFactory.java new file mode 100644 index 0000000000..584ea80319 --- /dev/null +++ b/src/main/java/galacticgreg/schematics/SpaceSchematicFactory.java @@ -0,0 +1,33 @@ +package galacticgreg.schematics; + +import net.minecraft.block.Block; +import net.minecraft.util.Vec3; + +import galacticgreg.api.Enums.AllowedBlockPosition; +import galacticgreg.api.Enums.TargetBlockPosition; +import galacticgreg.api.SpecialBlockComb; +import galacticgreg.api.StructureInformation; + +/** + * Class for XML Structure files. You only should edit/use this file/class if you want to add/fix stuff with + * GalacticGreg itself, and never if you're a mod developer and want to add support for GGreg to your mod. However, feel + * free to copy this code to your own mod to implement structures. If you have questions, find me on github and ask + */ +public class SpaceSchematicFactory { + + public static SpaceSchematic createSchematic(String pName) { + SpaceSchematic tSchem = new SpaceSchematic(); + tSchem._mStructureName = pName; + tSchem._mRarity = 100; + tSchem._mStructureEnabled = false; + + return tSchem; + } + + public static StructureInformation createStructureInfo(int pX, int pY, int pZ, Block pBlock, int pMeta) { + return new StructureInformation( + Vec3.createVectorHelper(pX, pY, pZ), + TargetBlockPosition.Invalid, + new SpecialBlockComb(pBlock, pMeta, AllowedBlockPosition.AsteroidCoreAndShell)); + } +} diff --git a/src/main/java/galacticgreg/schematics/SpaceSchematicHandler.java b/src/main/java/galacticgreg/schematics/SpaceSchematicHandler.java new file mode 100644 index 0000000000..9282ebca06 --- /dev/null +++ b/src/main/java/galacticgreg/schematics/SpaceSchematicHandler.java @@ -0,0 +1,182 @@ +package galacticgreg.schematics; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; + +import org.apache.commons.io.FileUtils; + +import galacticgreg.GalacticGreg; + +/** + * Class for XML Structure files. You only should edit/use this file/class if you want to add/fix stuff with + * GalacticGreg itself, and never if you're a mod developer and want to add support for GGreg to your mod. However, feel + * free to copy this code to your own mod to implement structures. If you have questions, find me on github and ask + */ +public class SpaceSchematicHandler { + + File _mConfigFolderName; + File _mSchematicsFolderName; + private List<SpaceSchematic> _mSpaceSchematics; + + @SuppressWarnings("ResultOfMethodCallIgnored") + public SpaceSchematicHandler(File pConfigFolder) { + _mConfigFolderName = new File(String.format("%s/%s", pConfigFolder.toString(), GalacticGreg.NICE_MODID)); + _mSchematicsFolderName = new File(String.format("%s/schematics", _mConfigFolderName)); + + _mSpaceSchematics = new ArrayList<>(); + + if (!_mSchematicsFolderName.exists()) _mSchematicsFolderName.mkdirs(); + } + + /** + * Get a random schematic to be placed. + * + * @return A schematic that can be spawned in space + */ + public SpaceSchematic getRandomSpaceSchematic() { + int tRandomChance = GalacticGreg.GalacticRandom.nextInt(100); + List<Integer> tRandomIDs = new ArrayList<>(); + SpaceSchematic tChoosenSchematic = null; + + if (_mSpaceSchematics == null) return null; + + if (_mSpaceSchematics.size() == 0) return null; + + if (_mSpaceSchematics.size() == 1) { + tChoosenSchematic = _mSpaceSchematics.get(0); + if (tChoosenSchematic.getRarity() < tRandomChance) tChoosenSchematic = null; + } else { + for (int i = 0; i < _mSpaceSchematics.size(); i++) { + if (_mSpaceSchematics.get(i) + .getRarity() >= tRandomChance) tRandomIDs.add(i); + } + } + + if (tRandomIDs.size() > 0) { + int tRnd = GalacticGreg.GalacticRandom.nextInt(tRandomIDs.size()); + tChoosenSchematic = _mSpaceSchematics.get(tRandomIDs.get(tRnd)); + } + + return tChoosenSchematic; + } + + /** + * Try to reload the schematics. Will not change the list of currently loaded schematics if any errors are detected, + * except if you force it to do so + * + * @return + */ + public boolean reloadSchematics(boolean pForceReload) { + try { + Collection<File> structureFiles = FileUtils + .listFiles(_mSchematicsFolderName, new String[] { "xml" }, false); + List<SpaceSchematic> tNewSpaceSchematics = new ArrayList<>(); + int tErrorsFound = 0; + + if (structureFiles.isEmpty()) return true; + + for (File tSchematic : structureFiles) { + try { + SpaceSchematic tSchematicObj = LoadSpaceSchematic(tSchematic); + if (tSchematicObj != null) tNewSpaceSchematics.add(tSchematicObj); + else { + GalacticGreg.Logger.warn("Could not load Schematic %s. Please check the syntax", tSchematic); + tErrorsFound++; + } + } catch (Exception e) { + GalacticGreg.Logger.error("Error while loading Schematic %s", tSchematic); + e.printStackTrace(); + } + + } + + GalacticGreg.Logger.info("Successfully loaded %d Schematics", tNewSpaceSchematics.size()); + boolean tDoReplace = true; + + if (tErrorsFound > 0) { + GalacticGreg.Logger.warn("Found %d errors while loading, not all schematics will be available"); + if (pForceReload) + GalacticGreg.Logger.info("Reload was forced, replacing currently active list with new one"); + else { + GalacticGreg.Logger.warn("Nothing was replaced. Fix any errors and reload again"); + tDoReplace = false; + } + } + + if (tDoReplace) _mSpaceSchematics = tNewSpaceSchematics; + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * Saves the schematic to disk. The schematics name will be used as filename + * + * @param pSchematic + * @return + */ + public boolean SaveSpaceStructure(SpaceSchematic pSchematic) { + try { + if (pSchematic.getName() + .length() < 1) return false; + + JAXBContext tJaxbCtx = JAXBContext.newInstance(SpaceSchematic.class); + Marshaller jaxMarsh = tJaxbCtx.createMarshaller(); + jaxMarsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + jaxMarsh.marshal( + pSchematic, + new FileOutputStream(String.format("%s/%s.xml", _mSchematicsFolderName, pSchematic.getName()), false)); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * Load a schematic from disk by the schematic-name itself, without .xml or path + * + * @param pSchematicName + * @return + */ + public SpaceSchematic LoadSpaceSchematic(String pSchematicName) { + return LoadSpaceSchematic(new File(String.format("%s/%s.xml", _mSchematicsFolderName, pSchematicName))); + } + + /** + * Load a schematic file from disk by providing the actual file-object + * + * @param pName + * @return + */ + public SpaceSchematic LoadSpaceSchematic(File pName) { + SpaceSchematic tSchematic = null; + + try { + JAXBContext tJaxbCtx = JAXBContext.newInstance(SpaceSchematic.class); + if (!pName.exists()) { + GalacticGreg.Logger.error("SchematicFile %s could not be found", pName); + return null; + } + + Unmarshaller jaxUnmarsh = tJaxbCtx.createUnmarshaller(); + tSchematic = (SpaceSchematic) jaxUnmarsh.unmarshal(pName); + + } catch (Exception e) { + e.printStackTrace(); + } + + return tSchematic; + } +} diff --git a/src/main/java/galacticgreg/schematics/SpaceSchematicWrapper.java b/src/main/java/galacticgreg/schematics/SpaceSchematicWrapper.java new file mode 100644 index 0000000000..4addc5107d --- /dev/null +++ b/src/main/java/galacticgreg/schematics/SpaceSchematicWrapper.java @@ -0,0 +1,104 @@ +package galacticgreg.schematics; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.util.Vec3; + +import cpw.mods.fml.common.registry.GameRegistry; +import galacticgreg.GalacticGreg; +import galacticgreg.api.BlockMetaComb; +import galacticgreg.api.Enums.SpaceObjectType; +import galacticgreg.api.Enums.TargetBlockPosition; +import galacticgreg.api.ISpaceObjectGenerator; +import galacticgreg.api.StructureInformation; +import galacticgreg.schematics.SpaceSchematic.BaseStructureInfo; + +/** + * Class for XML Structure files. You only should edit/use this file/class if you want to add/fix stuff with + * GalacticGreg itself, and never if you're a mod developer and want to add support for GGreg to your mod. However, feel + * free to copy this code to your own mod to implement structures. If you have questions, find me on github and ask + */ +public class SpaceSchematicWrapper implements ISpaceObjectGenerator { + + private SpaceSchematic _mSchematic; + private Vec3 _mCenter = Vec3.createVectorHelper(0, 0, 0); + private List<StructureInformation> _mFinalizedStructure; + + public SpaceSchematicWrapper(SpaceSchematic pSchematic) { + _mSchematic = pSchematic; + } + + public boolean isCalculated() { + return _mFinalizedStructure != null && _mFinalizedStructure.size() > 0; + } + + /** + * Recalculate the Structures position, center it around _mCenter + */ + private void RecalculatePosition() { + _mFinalizedStructure = new ArrayList<>(); + + for (BaseStructureInfo bsi : _mSchematic.coordInfo()) { + try { + String tModID = bsi.blockName.split(":")[0]; + String tBlockName = bsi.blockName.split(":")[1]; + + Block tBlock = GameRegistry.findBlock(tModID, tBlockName); + if (tBlock != null) { + BlockMetaComb bmc = new BlockMetaComb(tBlock, bsi.blockMeta); + Vec3 tCenteredPos = _mCenter.addVector(bsi.posX, bsi.posY, bsi.posZ); + StructureInformation tnewSI = new StructureInformation( + tCenteredPos, + TargetBlockPosition.StructureBlock, + bmc); + _mFinalizedStructure.add(tnewSI); + } else GalacticGreg.Logger + .warn("Block %s:%s could not be found. Schematic will be incomplete!", tModID, tBlockName); + } catch (Exception e) { + e.printStackTrace(); + GalacticGreg.Logger.error("Error while recalculating blocks position"); + } + } + } + + @Override + public Vec3 getCenterPoint() { + return _mCenter; + } + + @Override + public void setCenterPoint(int pX, int pY, int pZ) { + _mCenter = Vec3.createVectorHelper(pX, pY, pZ); + } + + @Override + public void setCenterPoint(Vec3 pCenter) { + _mCenter = pCenter; + } + + @Override + public List<StructureInformation> getStructure() { + return _mFinalizedStructure; + } + + @Override + public void calculate() { + RecalculatePosition(); + } + + @Override + public void randomize(int pSizeMin, int pSizeMax) {} + + @Override + public SpaceObjectType getType() { + return SpaceObjectType.NonOreSchematic; + } + + @Override + public void reset() { + + } + +} |