diff --git a/.gitignore b/.gitignore
index 98f584375..ec3ad6d8a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,5 @@ Thumbs.db
build/
eclipse/
.project
+output/
+.cache
diff --git a/Eclipse Java Standard.xml b/Eclipse Java Standard.xml
index 08413f6a9..f9c4359ce 100644
--- a/Eclipse Java Standard.xml
+++ b/Eclipse Java Standard.xml
@@ -1,291 +1,820 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/atomic/src/main/scala/resonantinduction/atomic/Atomic.java b/atomic/src/main/scala/resonantinduction/atomic/Atomic.java
new file mode 100644
index 000000000..d98c8e12e
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/Atomic.java
@@ -0,0 +1,743 @@
+package resonantinduction.atomic;
+
+import ic2.api.item.Items;
+import ic2.api.recipe.IRecipeInput;
+import ic2.api.recipe.RecipeOutput;
+import ic2.api.recipe.Recipes;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.EnumArmorMaterial;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemBucket;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.EnumMovingObjectType;
+import net.minecraft.world.World;
+import net.minecraftforge.client.event.TextureStitchEvent;
+import net.minecraftforge.common.Configuration;
+import net.minecraftforge.common.EnumHelper;
+import net.minecraftforge.common.ForgeChunkManager;
+import net.minecraftforge.common.ForgeChunkManager.LoadingCallback;
+import net.minecraftforge.common.ForgeChunkManager.Ticket;
+import net.minecraftforge.common.ForgeChunkManager.Type;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.event.Event.Result;
+import net.minecraftforge.event.ForgeSubscribe;
+import net.minecraftforge.event.entity.player.FillBucketEvent;
+import net.minecraftforge.event.world.WorldEvent.Save;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+import net.minecraftforge.fluids.FluidRegistry;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.oredict.OreDictionary;
+import net.minecraftforge.oredict.ShapedOreRecipe;
+import net.minecraftforge.oredict.ShapelessOreRecipe;
+import resonant.api.IElectromagnet;
+import resonant.api.event.PlasmaEvent.SpawnPlasmaEvent;
+import resonant.api.recipe.QuantumAssemblerRecipes;
+import resonant.core.content.debug.BlockCreativeBuilder;
+import resonant.lib.content.ContentRegistry;
+import resonant.lib.flag.FlagRegistry;
+import resonant.lib.modproxy.ProxyHandler;
+import resonant.lib.network.PacketAnnotation;
+import resonant.lib.network.PacketHandler;
+import resonant.lib.prefab.block.BlockRadioactive;
+import resonant.lib.prefab.ore.OreGenBase;
+import resonant.lib.prefab.ore.OreGenReplaceStone;
+import resonant.lib.prefab.ore.OreGenerator;
+import resonant.lib.recipe.UniversalRecipe;
+import resonant.lib.render.RenderUtility;
+import resonant.lib.thermal.EventThermal.EventThermalUpdate;
+import resonant.lib.utility.nbt.NBTUtility;
+import resonantinduction.atomic.base.ItemCell;
+import resonantinduction.atomic.fission.BlockUraniumOre;
+import resonantinduction.atomic.fission.ItemBreederFuel;
+import resonantinduction.atomic.fission.ItemFissileFuel;
+import resonantinduction.atomic.fission.ItemRadioactive;
+import resonantinduction.atomic.fission.ItemUranium;
+import resonantinduction.atomic.fission.reactor.BlockToxicWaste;
+import resonantinduction.atomic.fission.reactor.TileControlRod;
+import resonantinduction.atomic.fission.reactor.TileReactorCell;
+import resonantinduction.atomic.fusion.BlockPlasmaHeater;
+import resonantinduction.atomic.fusion.TileElectromagnet;
+import resonantinduction.atomic.fusion.TilePlasma;
+import resonantinduction.atomic.fusion.TilePlasmaHeater;
+import resonantinduction.atomic.particle.accelerator.BlockAccelerator;
+import resonantinduction.atomic.particle.accelerator.EntityParticle;
+import resonantinduction.atomic.particle.accelerator.ItemDarkMatter;
+import resonantinduction.atomic.particle.accelerator.TileAccelerator;
+import resonantinduction.atomic.particle.fulmination.FulminationHandler;
+import resonantinduction.atomic.particle.fulmination.ItemAntimatter;
+import resonantinduction.atomic.particle.fulmination.TileFulmination;
+import resonantinduction.atomic.particle.quantum.TileQuantumAssembler;
+import resonantinduction.atomic.process.BlockChemicalExtractor;
+import resonantinduction.atomic.process.ItemHazmat;
+import resonantinduction.atomic.process.TileChemicalExtractor;
+import resonantinduction.atomic.process.fission.BlockCentrifuge;
+import resonantinduction.atomic.process.fission.BlockNuclearBoiler;
+import resonantinduction.atomic.process.fission.TileCentrifuge;
+import resonantinduction.atomic.process.fission.TileNuclearBoiler;
+import resonantinduction.atomic.process.sensor.TileSiren;
+import resonantinduction.atomic.process.sensor.TileThermometer;
+import resonantinduction.atomic.process.turbine.BlockElectricTurbine;
+import resonantinduction.atomic.process.turbine.TileElectricTurbine;
+import resonantinduction.atomic.process.turbine.TileFunnel;
+import resonantinduction.atomic.schematic.SchematicAccelerator;
+import resonantinduction.atomic.schematic.SchematicBreedingReactor;
+import resonantinduction.atomic.schematic.SchematicFissionReactor;
+import resonantinduction.atomic.schematic.SchematicFusionReactor;
+import resonantinduction.core.Reference;
+import resonantinduction.core.ResonantInduction;
+import resonantinduction.core.Settings;
+import resonantinduction.core.TabRI;
+import universalelectricity.api.vector.Vector3;
+import universalelectricity.api.vector.VectorWorld;
+import cpw.mods.fml.common.Loader;
+import cpw.mods.fml.common.Mod;
+import cpw.mods.fml.common.Mod.EventHandler;
+import cpw.mods.fml.common.Mod.Instance;
+import cpw.mods.fml.common.ModMetadata;
+import cpw.mods.fml.common.SidedProxy;
+import cpw.mods.fml.common.event.FMLInitializationEvent;
+import cpw.mods.fml.common.event.FMLPostInitializationEvent;
+import cpw.mods.fml.common.event.FMLPreInitializationEvent;
+import cpw.mods.fml.common.network.NetworkMod;
+import cpw.mods.fml.common.network.NetworkRegistry;
+import cpw.mods.fml.common.registry.EntityRegistry;
+import cpw.mods.fml.common.registry.GameRegistry;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@Mod(modid = Atomic.ID, name = Atomic.NAME, version = Reference.VERSION, dependencies = "required-after:ResonantEngine;after:IC2;after:ResonantInduction|Electrical;required-after:" + ResonantInduction.ID)
+@NetworkMod(channels =
+{ Reference.CHANNEL }, clientSideRequired = true, serverSideRequired = false, packetHandler = PacketHandler.class)
+public class Atomic
+{
+ public static final String ID = "ResonantInduction|Atomic";
+ public static final String TEXTURE_DIRECTORY = "textures/";
+ public static final String GUI_TEXTURE_DIRECTORY = TEXTURE_DIRECTORY + "gui/";
+ public static final int ENTITY_ID_PREFIX = 49;
+ public static final int SECOND_IN_TICKS = 20;
+ public static final EnumArmorMaterial hazmatArmorMaterial = EnumHelper.addArmorMaterial("HAZMAT", 0, new int[]
+ { 0, 0, 0, 0 }, 0);
+ public static final String BAN_ANTIMATTER_POWER = FlagRegistry.registerFlag("ban_antimatter_power");
+ public static final String NAME = Reference.NAME + " Atomic";
+ public static final ContentRegistry contentRegistry = new ContentRegistry(Settings.CONFIGURATION, Settings.idManager, ID).setPrefix(Reference.PREFIX).setTab(TabRI.DEFAULT);
+ private static final String[] SUPPORTED_LANGUAGES = new String[]
+ { "en_US", "pl_PL", "de_DE" };
+
+ @Instance(ID)
+ public static Atomic INSTANCE;
+
+ @SidedProxy(clientSide = "resonantinduction.atomic.ClientProxy", serverSide = "resonantinduction.atomic.CommonProxy")
+ public static CommonProxy proxy;
+
+ public ProxyHandler modproxies;
+
+ @Mod.Metadata(ID)
+ public static ModMetadata metadata;
+
+ /** Block and Items */
+ public static Block blockRadioactive;
+ public static Block blockCentrifuge;
+ public static Block blockElectricTurbine;
+ public static Block blockNuclearBoiler;
+ public static Block blockControlRod;
+ public static Block blockThermometer;
+ public static Block blockFusionCore;
+ public static Block blockPlasma;
+ public static Block blockElectromagnet;
+ public static Block blockChemicalExtractor;
+ public static Block blockSiren;
+ public static Block blockSteamFunnel;
+ public static Block blockAccelerator;
+ public static Block blockFulmination;
+ public static Block blockQuantumAssembler;
+ public static Block blockReactorCell;
+
+ /** Cells */
+ public static Item itemCell, itemFissileFuel, itemBreedingRod, itemDarkMatter, itemAntimatter, itemDeuteriumCell, itemTritiumCell, itemWaterCell;
+ public static Item itemBucketToxic;
+
+ /** Uranium Related Items */
+ public static Block blockUraniumOre;
+ public static Item itemYellowCake;
+ public static Item itemUranium;
+ public static Item itemHazmatTop;
+ public static Item itemHazmatBody;
+ public static Item itemHazmatLeggings;
+ public static Item itemHazmatBoots;
+
+ /** Fluids */
+ public static Block blockToxicWaste;
+
+ /** Water, Uranium Hexafluoride, Steam, Deuterium, Toxic waste */
+ public static FluidStack FLUIDSTACK_WATER, FLUIDSTACK_URANIUM_HEXAFLOURIDE, FLUIDSTACK_STEAM, FLUIDSTACK_DEUTERIUM, FLUIDSTACK_TRITIUM, FLUIDSTACK_TOXIC_WASTE;
+ public static Fluid FLUID_URANIUM_HEXAFLOURIDE, FLUID_PLASMA, FLUID_STEAM, FLUID_DEUTERIUM, FLUID_TRITIUM, FLUID_TOXIC_WASTE;
+ public static OreGenBase uraniumOreGeneration;
+
+ /** Is this ItemStack a cell?
+ *
+ * @param itemStack
+ * @return */
+ public static boolean isItemStackEmptyCell(ItemStack itemStack)
+ {
+ return isItemStackOreDictionaryCompatible(itemStack, "cellEmpty");
+ }
+
+ public static boolean isItemStackWaterCell(ItemStack itemStack)
+ {
+ return isItemStackOreDictionaryCompatible(itemStack, "cellWater");
+ }
+
+ public static boolean isItemStackUraniumOre(ItemStack itemStack)
+ {
+ return isItemStackOreDictionaryCompatible(itemStack, "dropUranium", "oreUranium");
+ }
+
+ public static boolean isItemStackDeuteriumCell(ItemStack itemStack)
+ {
+ return isItemStackOreDictionaryCompatible(itemStack, "molecule_1d", "molecule_1h2", "cellDeuterium");
+ }
+
+ public static boolean isItemStackTritiumCell(ItemStack itemStack)
+ {
+ return isItemStackOreDictionaryCompatible(itemStack, "molecule_h3", "cellTritium");
+ }
+
+ /** Compare to Ore Dict
+ *
+ * @param itemStack
+ * @return */
+ public static boolean isItemStackOreDictionaryCompatible(ItemStack itemStack, String... names)
+ {
+ if (itemStack != null && names != null && names.length > 0)
+ {
+ String name = OreDictionary.getOreName(OreDictionary.getOreID(itemStack));
+
+ for (String compareName : names)
+ {
+ if (name.equals(compareName))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public static int getFluidAmount(FluidStack fluid)
+ {
+ if (fluid != null)
+ {
+ return fluid.amount;
+ }
+ return 0;
+ }
+
+ @EventHandler
+ public void preInit(FMLPreInitializationEvent event)
+ {
+ modproxies = new ProxyHandler();
+ INSTANCE = this;
+ MinecraftForge.EVENT_BUS.register(this);
+ NetworkRegistry.instance().registerGuiHandler(this, proxy);
+
+ PacketAnnotation.register(TileElectricTurbine.class);
+ PacketAnnotation.register(TileReactorCell.class);
+ PacketAnnotation.register(TileThermometer.class);
+
+ BlockCreativeBuilder.register(new SchematicAccelerator());
+ BlockCreativeBuilder.register(new SchematicBreedingReactor());
+ BlockCreativeBuilder.register(new SchematicFissionReactor());
+ BlockCreativeBuilder.register(new SchematicFusionReactor());
+
+ Settings.CONFIGURATION.load();
+
+ /** Register Packets */
+ PacketAnnotation.register(TileAccelerator.class);
+ PacketAnnotation.register(TileChemicalExtractor.class);
+ PacketAnnotation.register(TileNuclearBoiler.class);
+ PacketAnnotation.register(TileElectricTurbine.class);
+
+ /** Registers Gases & Fluids */
+ FLUID_URANIUM_HEXAFLOURIDE = new Fluid("uraniumhexafluoride").setGaseous(true);
+ FLUID_STEAM = new Fluid("steam").setGaseous(true);
+ FLUID_DEUTERIUM = new Fluid("deuterium").setGaseous(true);
+ FLUID_TRITIUM = new Fluid("tritium").setGaseous(true);
+ FLUID_TOXIC_WASTE = new Fluid("toxicwaste");
+ FLUID_PLASMA = new Fluid("plasma").setGaseous(true);
+
+ FluidRegistry.registerFluid(FLUID_URANIUM_HEXAFLOURIDE);
+ FluidRegistry.registerFluid(FLUID_STEAM);
+ FluidRegistry.registerFluid(FLUID_TRITIUM);
+ FluidRegistry.registerFluid(FLUID_DEUTERIUM);
+ FluidRegistry.registerFluid(FLUID_TOXIC_WASTE);
+ FluidRegistry.registerFluid(FLUID_PLASMA);
+
+ /** Fluid Stack Reference Initialization */
+ FLUIDSTACK_WATER = new FluidStack(FluidRegistry.WATER, 0);
+ FLUIDSTACK_URANIUM_HEXAFLOURIDE = new FluidStack(FLUID_URANIUM_HEXAFLOURIDE, 0);
+ FLUIDSTACK_STEAM = new FluidStack(FluidRegistry.getFluidID("steam"), 0);
+ FLUIDSTACK_DEUTERIUM = new FluidStack(FluidRegistry.getFluidID("deuterium"), 0);
+ FLUIDSTACK_TRITIUM = new FluidStack(FluidRegistry.getFluidID("tritium"), 0);
+ FLUIDSTACK_TOXIC_WASTE = new FluidStack(FluidRegistry.getFluidID("toxicwaste"), 0);
+
+ /** Block Initiation */
+ blockRadioactive = contentRegistry.createBlock(BlockRadioactive.class).setUnlocalizedName(Reference.PREFIX + "radioactive").setTextureName(Reference.PREFIX + "radioactive").setCreativeTab(TabRI.DEFAULT);
+ blockUraniumOre = contentRegistry.createBlock(BlockUraniumOre.class);
+
+ blockElectricTurbine = contentRegistry.createTile(BlockElectricTurbine.class, TileElectricTurbine.class);
+ blockCentrifuge = contentRegistry.createTile(BlockCentrifuge.class, TileCentrifuge.class);
+ blockReactorCell = contentRegistry.newBlock(TileReactorCell.class);
+ blockNuclearBoiler = contentRegistry.createTile(BlockNuclearBoiler.class, TileNuclearBoiler.class);
+ blockChemicalExtractor = contentRegistry.createTile(BlockChemicalExtractor.class, TileChemicalExtractor.class);
+ blockFusionCore = contentRegistry.createTile(BlockPlasmaHeater.class, TilePlasmaHeater.class);
+ blockControlRod = contentRegistry.newBlock(TileControlRod.class);
+ blockThermometer = contentRegistry.newBlock(TileThermometer.class);
+ blockPlasma = contentRegistry.newBlock(TilePlasma.class);
+ blockElectromagnet = contentRegistry.newBlock(TileElectromagnet.class);
+ blockSiren = contentRegistry.newBlock(TileSiren.class);
+ blockSteamFunnel = contentRegistry.newBlock(TileFunnel.class);
+ blockAccelerator = contentRegistry.createTile(BlockAccelerator.class, TileAccelerator.class);
+ blockFulmination = contentRegistry.newBlock(TileFulmination.class);
+ blockQuantumAssembler = contentRegistry.newBlock(TileQuantumAssembler.class);
+ blockToxicWaste = contentRegistry.createBlock(BlockToxicWaste.class).setCreativeTab(null);
+
+ /** Items */
+ itemHazmatTop = new ItemHazmat(Settings.CONFIGURATION.getItem("HazmatTop", Settings.getNextItemID()).getInt(), hazmatArmorMaterial, proxy.getArmorIndex("hazmat"), 0).setUnlocalizedName(Reference.PREFIX + "hazmatMask");
+ itemHazmatBody = new ItemHazmat(Settings.CONFIGURATION.getItem("HazmatBody", Settings.getNextItemID()).getInt(), hazmatArmorMaterial, proxy.getArmorIndex("hazmat"), 1).setUnlocalizedName(Reference.PREFIX + "hazmatBody");
+ itemHazmatLeggings = new ItemHazmat(Settings.CONFIGURATION.getItem("HazmatBottom", Settings.getNextItemID()).getInt(), hazmatArmorMaterial, proxy.getArmorIndex("hazmat"), 2).setUnlocalizedName(Reference.PREFIX + "hazmatLeggings");
+ itemHazmatBoots = new ItemHazmat(Settings.CONFIGURATION.getItem("HazmatBoots", Settings.getNextItemID()).getInt(), hazmatArmorMaterial, proxy.getArmorIndex("hazmat"), 3).setUnlocalizedName(Reference.PREFIX + "hazmatBoots");
+
+ itemCell = contentRegistry.createItem("cellEmpty", Item.class);
+ itemFissileFuel = contentRegistry.createItem("rodFissileFuel", ItemFissileFuel.class);
+ itemDeuteriumCell = contentRegistry.createItem("cellDeuterium", ItemCell.class);
+ itemTritiumCell = contentRegistry.createItem("cellTritium", ItemCell.class);
+ itemWaterCell = contentRegistry.createItem("cellWater", ItemCell.class);
+ itemDarkMatter = contentRegistry.createItem("darkMatter", ItemDarkMatter.class);
+ itemAntimatter = contentRegistry.createItem("antimatter", ItemAntimatter.class);
+ itemBreedingRod = contentRegistry.createItem("rodBreederFuel", ItemBreederFuel.class);
+
+ itemYellowCake = contentRegistry.createItem("yellowcake", ItemRadioactive.class);
+ itemUranium = contentRegistry.createItem(ItemUranium.class);
+
+ /** Fluid Item Initialization */
+ FLUID_PLASMA.setBlockID(blockPlasma);
+
+ int bucketID = Settings.getNextItemID();
+ itemBucketToxic = (new ItemBucket(Settings.CONFIGURATION.getItem("Toxic Waste Bucket", bucketID).getInt(bucketID), blockToxicWaste.blockID)).setCreativeTab(TabRI.DEFAULT).setUnlocalizedName(Reference.PREFIX + "bucketToxicWaste")
+ .setContainerItem(Item.bucketEmpty).setTextureName(Reference.PREFIX + "bucketToxicWaste");
+
+ FluidContainerRegistry.registerFluidContainer(FluidRegistry.getFluid("toxicwaste"), new ItemStack(itemBucketToxic), new ItemStack(Item.bucketEmpty));
+ FluidContainerRegistry.registerFluidContainer(FluidRegistry.WATER, new ItemStack(itemWaterCell), new ItemStack(itemCell));
+ FluidContainerRegistry.registerFluidContainer(new FluidStack(FluidRegistry.getFluid("deuterium"), 200), new ItemStack(itemDeuteriumCell), new ItemStack(itemCell));
+ FluidContainerRegistry.registerFluidContainer(new FluidStack(FluidRegistry.getFluid("tritium"), 200), new ItemStack(itemTritiumCell), new ItemStack(itemCell));
+
+ if (OreDictionary.getOres("oreUranium").size() > 1 && Settings.CONFIGURATION.get(Configuration.CATEGORY_GENERAL, "Auto Disable Uranium If Exist", false).getBoolean(false))
+ {
+ ResonantInduction.LOGGER.fine("Disabled Uranium Generation. Detected another uranium being generated: " + OreDictionary.getOres("oreUranium").size());
+ }
+ else
+ {
+ uraniumOreGeneration = new OreGenReplaceStone("Uranium Ore", "oreUranium", new ItemStack(blockUraniumOre), 0, 25, 9, 3, "pickaxe", 2);
+ uraniumOreGeneration.enable(Settings.CONFIGURATION);
+ OreGenerator.addOre(uraniumOreGeneration);
+ ResonantInduction.LOGGER.fine("Added Atomic Science uranium to ore generator.");
+ }
+
+ Settings.CONFIGURATION.save();
+
+ MinecraftForge.EVENT_BUS.register(itemAntimatter);
+ MinecraftForge.EVENT_BUS.register(FulminationHandler.INSTANCE);
+
+ /** Cell registry. */
+ if (Settings.allowOreDictionaryCompatibility)
+ {
+ OreDictionary.registerOre("ingotUranium", itemUranium);
+ OreDictionary.registerOre("dustUranium", itemYellowCake);
+ }
+
+ OreDictionary.registerOre("breederUranium", new ItemStack(itemUranium, 1, 1));
+ OreDictionary.registerOre("blockRadioactive", blockRadioactive);
+
+ OreDictionary.registerOre("cellEmpty", itemCell);
+ OreDictionary.registerOre("cellUranium", itemFissileFuel);
+ OreDictionary.registerOre("cellTritium", itemTritiumCell);
+ OreDictionary.registerOre("cellDeuterium", itemDeuteriumCell);
+ OreDictionary.registerOre("cellWater", itemWaterCell);
+ OreDictionary.registerOre("strangeMatter", itemDarkMatter);
+ OreDictionary.registerOre("antimatterMilligram", new ItemStack(itemAntimatter, 1, 0));
+ OreDictionary.registerOre("antimatterGram", new ItemStack(itemAntimatter, 1, 1));
+
+ ForgeChunkManager.setForcedChunkLoadingCallback(this, new LoadingCallback()
+ {
+ @Override
+ public void ticketsLoaded(List tickets, World world)
+ {
+ for (Ticket ticket : tickets)
+ {
+ if (ticket.getType() == Type.ENTITY)
+ {
+ if (ticket.getEntity() != null)
+ {
+ if (ticket.getEntity() instanceof EntityParticle)
+ {
+ ((EntityParticle) ticket.getEntity()).updateTicket = ticket;
+ }
+ }
+ }
+ }
+ }
+ });
+
+ proxy.preInit();
+ Settings.CONFIGURATION.save();
+ TabRI.ITEMSTACK = new ItemStack(blockReactorCell);
+ }
+
+ @EventHandler
+ public void init(FMLInitializationEvent evt)
+ {
+ Settings.setModMetadata(metadata, ID, NAME, ResonantInduction.ID);
+ proxy.init();
+ modproxies.init();
+ }
+
+ @EventHandler
+ public void postInit(FMLPostInitializationEvent event)
+ {
+ /** IC2 Recipes */
+ if (Loader.isModLoaded("IC2") && Settings.allowAlternateRecipes)
+ {
+ OreDictionary.registerOre("cellEmpty", Items.getItem("cell"));
+
+ // Check to make sure we have actually registered the Ore, otherwise tell the user about
+ // it.
+ String cellEmptyName = OreDictionary.getOreName(OreDictionary.getOreID("cellEmpty"));
+ if (cellEmptyName == "Unknown")
+ {
+ ResonantInduction.LOGGER.info("Unable to register cellEmpty in OreDictionary!");
+ }
+
+ // IC2 exchangeable recipes
+ GameRegistry.addRecipe(new ShapelessOreRecipe(itemYellowCake, Items.getItem("reactorUraniumSimple")));
+ GameRegistry.addRecipe(new ShapelessOreRecipe(Items.getItem("cell"), itemCell));
+ GameRegistry.addRecipe(new ShapelessOreRecipe(itemCell, "cellEmpty"));
+ }
+
+ // Antimatter
+ GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(itemAntimatter, 1, 1), new Object[]
+ { itemAntimatter, itemAntimatter, itemAntimatter, itemAntimatter, itemAntimatter, itemAntimatter, itemAntimatter, itemAntimatter }));
+ GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(itemAntimatter, 8, 0), new Object[]
+ { new ItemStack(itemAntimatter, 1, 1) }));
+
+ // Steam Funnel
+ GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockSteamFunnel, 2), new Object[]
+ { " B ", "B B", "B B", 'B', UniversalRecipe.SECONDARY_METAL.get(Settings.allowAlternateRecipes) }));
+ GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockSteamFunnel, 2), new Object[]
+ { " B ", "B B", "B B", 'B', "ingotIron" }));
+
+ // Atomic Assembler
+ GameRegistry.addRecipe(new ShapedOreRecipe(blockQuantumAssembler, new Object[]
+ { "CCC", "SXS", "SSS", 'X', blockCentrifuge, 'C', UniversalRecipe.CIRCUIT_T3.get(Settings.allowAlternateRecipes), 'S', UniversalRecipe.PRIMARY_PLATE.get(Settings.allowAlternateRecipes) }));
+
+ // Fulmination Generator
+ GameRegistry.addRecipe(new ShapedOreRecipe(blockFulmination, new Object[]
+ { "OSO", "SCS", "OSO", 'O', Block.obsidian, 'C', UniversalRecipe.CIRCUIT_T2.get(Settings.allowAlternateRecipes), 'S', UniversalRecipe.PRIMARY_PLATE.get(Settings.allowAlternateRecipes) }));
+
+ // Particle Accelerator
+ GameRegistry.addRecipe(new ShapedOreRecipe(blockAccelerator, new Object[]
+ { "SCS", "CMC", "SCS", 'M', UniversalRecipe.MOTOR.get(Settings.allowAlternateRecipes), 'C', UniversalRecipe.CIRCUIT_T3.get(Settings.allowAlternateRecipes), 'S', UniversalRecipe.PRIMARY_PLATE.get(Settings.allowAlternateRecipes) }));
+
+ // Centrifuge
+ GameRegistry.addRecipe(new ShapedOreRecipe(blockCentrifuge, new Object[]
+ { "BSB", "MCM", "BSB", 'C', UniversalRecipe.CIRCUIT_T2.get(Settings.allowAlternateRecipes), 'S', UniversalRecipe.PRIMARY_PLATE.get(Settings.allowAlternateRecipes), 'B', UniversalRecipe.SECONDARY_METAL.get(Settings.allowAlternateRecipes), 'M',
+ UniversalRecipe.MOTOR.get(Settings.allowAlternateRecipes) }));
+
+ // Nuclear Boiler
+ GameRegistry.addRecipe(new ShapedOreRecipe(blockNuclearBoiler, new Object[]
+ { "S S", "FBF", "SMS", 'F', Block.furnaceIdle, 'S', UniversalRecipe.PRIMARY_PLATE.get(Settings.allowAlternateRecipes), 'B', Item.bucketEmpty, 'M', UniversalRecipe.MOTOR.get(Settings.allowAlternateRecipes) }));
+
+ // Chemical Extractor
+ GameRegistry.addRecipe(new ShapedOreRecipe(blockChemicalExtractor, new Object[]
+ { "BSB", "MCM", "BSB", 'C', UniversalRecipe.CIRCUIT_T3.get(Settings.allowAlternateRecipes), 'S', UniversalRecipe.PRIMARY_PLATE.get(Settings.allowAlternateRecipes), 'B', UniversalRecipe.SECONDARY_METAL.get(Settings.allowAlternateRecipes), 'M',
+ UniversalRecipe.MOTOR.get(Settings.allowAlternateRecipes) }));
+
+ // Siren
+ GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockSiren, 2), new Object[]
+ { "NPN", 'N', Block.music, 'P', UniversalRecipe.SECONDARY_PLATE.get(Settings.allowAlternateRecipes) }));
+
+ // Fission Reactor
+ GameRegistry
+ .addRecipe(new ShapedOreRecipe(blockReactorCell, new Object[]
+ { "SCS", "MEM", "SCS", 'E', "cellEmpty", 'C', UniversalRecipe.CIRCUIT_T2.get(Settings.allowAlternateRecipes), 'S', UniversalRecipe.PRIMARY_PLATE.get(Settings.allowAlternateRecipes), 'M',
+ UniversalRecipe.MOTOR.get(Settings.allowAlternateRecipes) }));
+
+ // Fusion Reactor
+ GameRegistry.addRecipe(new ShapedOreRecipe(blockFusionCore, new Object[]
+ { "CPC", "PFP", "CPC", 'P', UniversalRecipe.PRIMARY_PLATE.get(Settings.allowAlternateRecipes), 'F', blockReactorCell, 'C', UniversalRecipe.CIRCUIT_T3.get(Settings.allowAlternateRecipes) }));
+
+ // Turbine
+ GameRegistry.addRecipe(new ShapedOreRecipe(blockElectricTurbine, new Object[]
+ { " B ", "BMB", " B ", 'B', UniversalRecipe.SECONDARY_PLATE.get(Settings.allowAlternateRecipes), 'M', UniversalRecipe.MOTOR.get(Settings.allowAlternateRecipes) }));
+
+ // Empty Cell
+ GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(itemCell, 16), new Object[]
+ { " T ", "TGT", " T ", 'T', "ingotTin", 'G', Block.glass }));
+
+ // Water Cell
+ GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(itemWaterCell), new Object[]
+ { "cellEmpty", Item.bucketWater }));
+
+ // Thermometer
+ GameRegistry.addRecipe(new ShapedOreRecipe(blockThermometer, new Object[]
+ { "SSS", "GCG", "GSG", 'S', UniversalRecipe.PRIMARY_METAL.get(Settings.allowAlternateRecipes), 'G', Block.glass, 'C', UniversalRecipe.CIRCUIT_T1.get(Settings.allowAlternateRecipes) }));
+
+ // Control Rod
+ GameRegistry.addRecipe(new ShapedOreRecipe(blockControlRod, new Object[]
+ { "I", "I", "I", 'I', Item.ingotIron }));
+
+ // Fuel Rod
+ GameRegistry.addRecipe(new ShapedOreRecipe(itemFissileFuel, new Object[]
+ { "CUC", "CUC", "CUC", 'U', "ingotUranium", 'C', "cellEmpty" }));
+
+ // Breeder Rod
+ GameRegistry.addRecipe(new ShapedOreRecipe(itemBreedingRod, new Object[]
+ { "CUC", "CUC", "CUC", 'U', "breederUranium", 'C', "cellEmpty" }));
+
+ // Electromagnet
+ GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockElectromagnet, 2, 0), new Object[]
+ { "BBB", "BMB", "BBB", 'B', UniversalRecipe.SECONDARY_METAL.get(Settings.allowAlternateRecipes), 'M', UniversalRecipe.MOTOR.get(Settings.allowAlternateRecipes) }));
+
+ // Electromagnet Glass
+ GameRegistry.addRecipe(new ShapelessOreRecipe(new ItemStack(blockElectromagnet, 1, 1), new Object[]
+ { blockElectromagnet, Block.glass }));
+
+ // Hazmat Suit
+ GameRegistry.addRecipe(new ShapedOreRecipe(itemHazmatTop, new Object[]
+ { "SSS", "BAB", "SCS", 'A', Item.helmetLeather, 'C', UniversalRecipe.CIRCUIT_T1.get(Settings.allowAlternateRecipes), 'S', Block.cloth }));
+ GameRegistry.addRecipe(new ShapedOreRecipe(itemHazmatBody, new Object[]
+ { "SSS", "BAB", "SCS", 'A', Item.plateLeather, 'C', UniversalRecipe.CIRCUIT_T1.get(Settings.allowAlternateRecipes), 'S', Block.cloth }));
+ GameRegistry.addRecipe(new ShapedOreRecipe(itemHazmatLeggings, new Object[]
+ { "SSS", "BAB", "SCS", 'A', Item.legsLeather, 'C', UniversalRecipe.CIRCUIT_T1.get(Settings.allowAlternateRecipes), 'S', Block.cloth }));
+ GameRegistry.addRecipe(new ShapedOreRecipe(itemHazmatBoots, new Object[]
+ { "SSS", "BAB", "SCS", 'A', Item.bootsLeather, 'C', UniversalRecipe.CIRCUIT_T1.get(Settings.allowAlternateRecipes), 'S', Block.cloth }));
+
+ EntityRegistry.registerGlobalEntityID(EntityParticle.class, "ASParticle", EntityRegistry.findGlobalUniqueEntityId());
+ EntityRegistry.registerModEntity(EntityParticle.class, "ASParticle", ENTITY_ID_PREFIX, this, 80, 3, true);
+
+ Atomic.proxy.init();
+
+ Settings.CONFIGURATION.load();
+
+ if (Loader.isModLoaded("IC2") && Settings.allowAlternateRecipes)
+ {
+ if (Settings.allowIC2UraniumCompression)
+ {
+ try
+ {
+ if (Recipes.compressor != null)
+ {
+ Map compressorRecipes = Recipes.compressor.getRecipes();
+ Iterator> it = compressorRecipes.entrySet().iterator();
+ int i = 0;
+
+ while (it.hasNext())
+ {
+ Map.Entry entry = it.next();
+
+ for (ItemStack checkStack : entry.getKey().getInputs())
+ {
+ if (isItemStackUraniumOre(checkStack))
+ {
+ i++;
+ it.remove();
+ }
+ }
+ }
+
+ ResonantInduction.LOGGER.fine("Removed " + i + " IC2 uranium compression recipe, use centrifuge instead.");
+ }
+ }
+ catch (Exception e)
+ {
+ ResonantInduction.LOGGER.fine("Failed to remove IC2 compressor recipes.");
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /** Atomic Assembler Recipes */
+ if (Settings.quantumAssemblerGenerateMode > 0)
+ {
+ for (Item item : Item.itemsList)
+ {
+ if (item != null)
+ {
+ if (item.itemID > 256 || Settings.quantumAssemblerGenerateMode == 2)
+ {
+ ItemStack itemStack = new ItemStack(item);
+
+ if (itemStack != null)
+ {
+ QuantumAssemblerRecipes.addRecipe(itemStack);
+ }
+ }
+ }
+ }
+
+ if (Settings.quantumAssemblerGenerateMode == 2)
+ {
+ for (Block block : Block.blocksList)
+ {
+ if (block != null)
+ {
+ ItemStack itemStack = new ItemStack(block);
+ if (itemStack != null)
+ {
+ QuantumAssemblerRecipes.addRecipe(itemStack);
+ }
+ }
+ }
+ }
+
+ for (String oreName : OreDictionary.getOreNames())
+ {
+ if (oreName.startsWith("ingot"))
+ {
+ for (ItemStack itemStack : OreDictionary.getOres(oreName))
+ {
+ if (itemStack != null)
+ {
+ QuantumAssemblerRecipes.addRecipe(itemStack);
+ }
+ }
+ }
+ }
+ }
+
+ Settings.CONFIGURATION.save();
+ }
+
+ @ForgeSubscribe
+ public void thermalEventHandler(EventThermalUpdate evt)
+ {
+ VectorWorld pos = evt.position;
+ Block block = Block.blocksList[pos.getBlockID()];
+
+ if (block == blockElectromagnet)
+ {
+ evt.heatLoss = evt.deltaTemperature * 0.6f;
+ }
+ }
+
+ @ForgeSubscribe
+ public void plasmaEvent(SpawnPlasmaEvent evt)
+ {
+ World world = evt.world;
+ Vector3 position = new Vector3(evt.x, evt.y, evt.z);
+ int blockID = position.getBlockID(world);
+
+ Block block = Block.blocksList[blockID];
+
+ if (block != null)
+ {
+ if (block.blockID == Block.bedrock.blockID || block.blockID == Block.blockIron.blockID)
+ {
+ return;
+ }
+
+ TileEntity tile = position.getTileEntity(world);
+
+ if (tile instanceof TilePlasma)
+ {
+ ((TilePlasma) tile).setTemperature(evt.temperature);
+ return;
+ }
+
+ if (tile instanceof IElectromagnet)
+ {
+ return;
+ }
+ }
+
+ position.setBlock(world, blockPlasma.blockID);
+
+ TileEntity tile = position.getTileEntity(world);
+
+ if (tile instanceof TilePlasma)
+ {
+ ((TilePlasma) tile).setTemperature(evt.temperature);
+ }
+ }
+
+ @ForgeSubscribe
+ @SideOnly(Side.CLIENT)
+ public void preTextureHook(TextureStitchEvent.Pre event)
+ {
+ if (event.map.textureType == 0)
+ {
+ RenderUtility.registerIcon(Reference.PREFIX + "uraniumHexafluoride", event.map);
+ RenderUtility.registerIcon(Reference.PREFIX + "steam", event.map);
+ RenderUtility.registerIcon(Reference.PREFIX + "deuterium", event.map);
+ RenderUtility.registerIcon(Reference.PREFIX + "tritium", event.map);
+ RenderUtility.registerIcon(Reference.PREFIX + "atomic_edge", event.map);
+ RenderUtility.registerIcon(Reference.PREFIX + "funnel_edge", event.map);
+ RenderUtility.registerIcon(Reference.PREFIX + "glass", event.map);
+ }
+ }
+
+ @ForgeSubscribe
+ @SideOnly(Side.CLIENT)
+ public void postTextureHook(TextureStitchEvent.Post event)
+ {
+ FLUID_URANIUM_HEXAFLOURIDE.setIcons(RenderUtility.loadedIconMap.get(Reference.PREFIX + "uraniumHexafluoride"));
+ FLUID_STEAM.setIcons(RenderUtility.loadedIconMap.get(Reference.PREFIX + "steam"));
+ FLUID_DEUTERIUM.setIcons(RenderUtility.loadedIconMap.get(Reference.PREFIX + "deuterium"));
+ FLUID_TRITIUM.setIcons(RenderUtility.loadedIconMap.get(Reference.PREFIX + "tritium"));
+ FLUID_TOXIC_WASTE.setIcons(blockToxicWaste.getIcon(0, 0));
+ FLUID_PLASMA.setIcons(blockPlasma.getIcon(0, 0));
+ }
+
+ @ForgeSubscribe
+ public void worldSave(Save evt)
+ {
+ if (!evt.world.isRemote)
+ {
+ if (FlagRegistry.getModFlag(FlagRegistry.DEFAULT_NAME) != null)
+ {
+ NBTUtility.saveData(FlagRegistry.DEFAULT_NAME, FlagRegistry.getModFlag(FlagRegistry.DEFAULT_NAME).getNBT());
+ }
+ }
+ }
+
+ @ForgeSubscribe
+ public void fillBucketEvent(FillBucketEvent evt)
+ {
+ if (!evt.world.isRemote && evt.target != null && evt.target.typeOfHit == EnumMovingObjectType.TILE)
+ {
+ Vector3 blockPos = new Vector3(evt.target);
+ int blockID = blockPos.getBlockID(evt.world);
+
+ if (blockID == blockToxicWaste.blockID)
+ {
+ blockPos.setBlock(evt.world, 0);
+ evt.result = new ItemStack(itemBucketToxic);
+ evt.setResult(Result.ALLOW);
+ }
+ }
+ }
+
+ /** Recipes */
+ public static enum RecipeType
+ {
+ CHEMICAL_EXTRACTOR;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/ClientProxy.java b/atomic/src/main/scala/resonantinduction/atomic/ClientProxy.java
new file mode 100644
index 000000000..de290b7fd
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/ClientProxy.java
@@ -0,0 +1,107 @@
+package resonantinduction.atomic;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import net.minecraftforge.common.MinecraftForge;
+import resonant.lib.render.block.BlockRenderingHandler;
+import resonantinduction.atomic.fission.reactor.GuiReactorCell;
+import resonantinduction.atomic.fission.reactor.RenderReactorCell;
+import resonantinduction.atomic.fission.reactor.TileReactorCell;
+import resonantinduction.atomic.fusion.RenderPlasmaHeater;
+import resonantinduction.atomic.fusion.TilePlasmaHeater;
+import resonantinduction.atomic.particle.accelerator.EntityParticle;
+import resonantinduction.atomic.particle.accelerator.GuiAccelerator;
+import resonantinduction.atomic.particle.accelerator.RenderParticle;
+import resonantinduction.atomic.particle.accelerator.TileAccelerator;
+import resonantinduction.atomic.particle.quantum.GuiQuantumAssembler;
+import resonantinduction.atomic.particle.quantum.TileQuantumAssembler;
+import resonantinduction.atomic.process.RenderChemicalExtractor;
+import resonantinduction.atomic.process.TileChemicalExtractor;
+import resonantinduction.atomic.process.fission.GuiCentrifuge;
+import resonantinduction.atomic.process.fission.GuiChemicalExtractor;
+import resonantinduction.atomic.process.fission.GuiNuclearBoiler;
+import resonantinduction.atomic.process.fission.RenderCentrifuge;
+import resonantinduction.atomic.process.fission.RenderNuclearBoiler;
+import resonantinduction.atomic.process.fission.TileCentrifuge;
+import resonantinduction.atomic.process.fission.TileNuclearBoiler;
+import resonantinduction.atomic.process.sensor.RenderThermometer;
+import resonantinduction.atomic.process.sensor.TileThermometer;
+import resonantinduction.atomic.process.turbine.RenderElectricTurbine;
+import resonantinduction.atomic.process.turbine.TileElectricTurbine;
+import cpw.mods.fml.client.registry.ClientRegistry;
+import cpw.mods.fml.client.registry.RenderingRegistry;
+
+public class ClientProxy extends CommonProxy
+{
+ @Override
+ public void preInit()
+ {
+ MinecraftForge.EVENT_BUS.register(SoundHandler.INSTANCE);
+ RenderingRegistry.registerBlockHandler(new BlockRenderingHandler());
+ }
+
+ @Override
+ public int getArmorIndex(String armor)
+ {
+ return RenderingRegistry.addNewArmourRendererPrefix(armor);
+ }
+
+ @Override
+ public void init()
+ {
+ super.init();
+ ClientRegistry.bindTileEntitySpecialRenderer(TileCentrifuge.class, new RenderCentrifuge());
+ ClientRegistry.bindTileEntitySpecialRenderer(TilePlasmaHeater.class, new RenderPlasmaHeater());
+ ClientRegistry.bindTileEntitySpecialRenderer(TileNuclearBoiler.class, new RenderNuclearBoiler());
+ ClientRegistry.bindTileEntitySpecialRenderer(TileElectricTurbine.class, new RenderElectricTurbine());
+ ClientRegistry.bindTileEntitySpecialRenderer(TileThermometer.class, new RenderThermometer());
+ ClientRegistry.bindTileEntitySpecialRenderer(TileChemicalExtractor.class, new RenderChemicalExtractor());
+ ClientRegistry.bindTileEntitySpecialRenderer(TileReactorCell.class, new RenderReactorCell());
+
+ RenderingRegistry.registerEntityRenderingHandler(EntityParticle.class, new RenderParticle());
+ }
+
+ @Override
+ public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
+ {
+ TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
+ Block block = Block.blocksList[world.getBlockId(x, y, z)];
+
+ if (tileEntity instanceof TileCentrifuge)
+ {
+ return new GuiCentrifuge(player.inventory, ((TileCentrifuge) tileEntity));
+ }
+ else if (tileEntity instanceof TileChemicalExtractor)
+ {
+ return new GuiChemicalExtractor(player.inventory, ((TileChemicalExtractor) tileEntity));
+ }
+ else if (tileEntity instanceof TileAccelerator)
+ {
+ return new GuiAccelerator(player.inventory, ((TileAccelerator) tileEntity));
+ }
+ else if (tileEntity instanceof TileQuantumAssembler)
+ {
+ return new GuiQuantumAssembler(player.inventory, ((TileQuantumAssembler) tileEntity));
+ }
+ else if (tileEntity instanceof TileNuclearBoiler)
+ {
+ return new GuiNuclearBoiler(player.inventory, ((TileNuclearBoiler) tileEntity));
+ }
+ else if (tileEntity instanceof TileReactorCell)
+ {
+ return new GuiReactorCell(player.inventory, (TileReactorCell) tileEntity);
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean isFancyGraphics()
+ {
+ return Minecraft.getMinecraft().gameSettings.fancyGraphics;
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/CommonProxy.java b/atomic/src/main/scala/resonantinduction/atomic/CommonProxy.java
new file mode 100644
index 000000000..b050b43e5
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/CommonProxy.java
@@ -0,0 +1,70 @@
+package resonantinduction.atomic;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import resonant.lib.prefab.ProxyBase;
+import resonantinduction.atomic.fission.reactor.ContainerReactorCell;
+import resonantinduction.atomic.fission.reactor.TileReactorCell;
+import resonantinduction.atomic.fusion.ContainerNuclearBoiler;
+import resonantinduction.atomic.particle.accelerator.ContainerAccelerator;
+import resonantinduction.atomic.particle.accelerator.TileAccelerator;
+import resonantinduction.atomic.particle.quantum.ContainerQuantumAssembler;
+import resonantinduction.atomic.particle.quantum.TileQuantumAssembler;
+import resonantinduction.atomic.process.ContainerChemicalExtractor;
+import resonantinduction.atomic.process.TileChemicalExtractor;
+import resonantinduction.atomic.process.fission.ContainerCentrifuge;
+import resonantinduction.atomic.process.fission.TileCentrifuge;
+import resonantinduction.atomic.process.fission.TileNuclearBoiler;
+
+public class CommonProxy extends ProxyBase
+{
+ public int getArmorIndex(String armor)
+ {
+ return 0;
+ }
+
+ @Override
+ public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
+ {
+ return null;
+ }
+
+ @Override
+ public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
+ {
+ TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
+
+ if (tileEntity instanceof TileCentrifuge)
+ {
+ return new ContainerCentrifuge(player.inventory, ((TileCentrifuge) tileEntity));
+ }
+ else if (tileEntity instanceof TileChemicalExtractor)
+ {
+ return new ContainerChemicalExtractor(player.inventory, ((TileChemicalExtractor) tileEntity));
+ }
+ else if (tileEntity instanceof TileAccelerator)
+ {
+ return new ContainerAccelerator(player.inventory, ((TileAccelerator) tileEntity));
+ }
+ else if (tileEntity instanceof TileQuantumAssembler)
+ {
+ return new ContainerQuantumAssembler(player.inventory, ((TileQuantumAssembler) tileEntity));
+ }
+ else if (tileEntity instanceof TileNuclearBoiler)
+ {
+ return new ContainerNuclearBoiler(player.inventory, ((TileNuclearBoiler) tileEntity));
+ }
+ else if (tileEntity instanceof TileReactorCell)
+ {
+ return new ContainerReactorCell(player, ((TileReactorCell) tileEntity));
+ }
+
+ return null;
+ }
+
+ public boolean isFancyGraphics()
+ {
+ return false;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/ReactorExplosion.java b/atomic/src/main/scala/resonantinduction/atomic/ReactorExplosion.java
new file mode 100644
index 000000000..2e0b3a9ef
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/ReactorExplosion.java
@@ -0,0 +1,50 @@
+package resonantinduction.atomic;
+
+import java.util.Iterator;
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.entity.Entity;
+import net.minecraft.world.ChunkPosition;
+import net.minecraft.world.Explosion;
+import net.minecraft.world.World;
+
+/** Creates a reactor explosion.
+ *
+ * @author Calclavia */
+public class ReactorExplosion extends Explosion
+{
+ private Random explosionRAND = new Random();
+ private World worldObj;
+
+ public ReactorExplosion(World world, Entity par2Entity, double par3, double par5, double par7, float par9)
+ {
+ super(world, par2Entity, par3, par5, par7, par9);
+ this.worldObj = world;
+ this.isFlaming = true;
+ }
+
+ /** Does the second part of the explosion (sound, particles, drop spawn) */
+ @Override
+ public void doExplosionB(boolean par1)
+ {
+ super.doExplosionB(par1);
+
+ Iterator iterator = this.affectedBlockPositions.iterator();
+
+ while (iterator.hasNext())
+ {
+ ChunkPosition chunkposition = (ChunkPosition) iterator.next();
+ int x = chunkposition.x;
+ int y = chunkposition.y;
+ int z = chunkposition.z;
+ int id = this.worldObj.getBlockId(x, y, z);
+ int i1 = this.worldObj.getBlockId(x, y - 1, z);
+
+ if (id == 0 && Block.opaqueCubeLookup[i1] && this.explosionRAND.nextInt(3) == 0)
+ {
+ this.worldObj.setBlock(x, y, z, Atomic.blockRadioactive.blockID);
+ }
+ }
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/SoundHandler.java b/atomic/src/main/scala/resonantinduction/atomic/SoundHandler.java
new file mode 100644
index 000000000..bce3b5d44
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/SoundHandler.java
@@ -0,0 +1,25 @@
+package resonantinduction.atomic;
+
+import net.minecraftforge.client.event.sound.SoundLoadEvent;
+import net.minecraftforge.event.ForgeSubscribe;
+import resonantinduction.core.Reference;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class SoundHandler
+{
+ public static final SoundHandler INSTANCE = new SoundHandler();
+
+ public static final String[] SOUND_FILES =
+ { "antimatter.ogg", "strangematter.ogg", "alarm.ogg", "accelerator.ogg", "turbine.ogg", "assembler.ogg", "reactorcell.ogg" };
+
+ @ForgeSubscribe
+ public void loadSoundEvents(SoundLoadEvent event)
+ {
+ for (int i = 0; i < SOUND_FILES.length; i++)
+ {
+ event.manager.addSound(Reference.PREFIX + SOUND_FILES[i]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/base/ItASBase.java b/atomic/src/main/scala/resonantinduction/atomic/base/ItASBase.java
new file mode 100644
index 000000000..054bacc87
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/base/ItASBase.java
@@ -0,0 +1,15 @@
+package resonantinduction.atomic.base;
+
+import resonant.lib.prefab.item.ItemBase;
+import resonantinduction.core.Reference;
+import resonantinduction.core.Settings;
+import resonantinduction.core.TabRI;
+
+public class ItASBase extends ItemBase
+{
+ /** Must be called while in mod init phase. */
+ public ItASBase(int itemID, String name)
+ {
+ super(itemID, name, Settings.CONFIGURATION, Reference.PREFIX, TabRI.DEFAULT);
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/base/ItElectricAS.java b/atomic/src/main/scala/resonantinduction/atomic/base/ItElectricAS.java
new file mode 100644
index 000000000..e789214a8
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/base/ItElectricAS.java
@@ -0,0 +1,21 @@
+package resonantinduction.atomic.base;
+
+import resonantinduction.core.Reference;
+import resonantinduction.core.Settings;
+import resonantinduction.core.TabRI;
+import universalelectricity.api.UniversalClass;
+import universalelectricity.api.item.IEnergyItem;
+import universalelectricity.api.item.ItemElectric;
+
+@UniversalClass
+public abstract class ItElectricAS extends ItemElectric implements IEnergyItem
+{
+ public ItElectricAS(int itemID, String name)
+ {
+ super(Settings.CONFIGURATION.getItem(name, itemID).getInt());
+ this.setUnlocalizedName(Reference.PREFIX + name);
+ this.setCreativeTab(TabRI.DEFAULT);
+ this.setTextureName(Reference.PREFIX + name);
+
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/base/ItemCell.java b/atomic/src/main/scala/resonantinduction/atomic/base/ItemCell.java
new file mode 100644
index 000000000..6212a0f4b
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/base/ItemCell.java
@@ -0,0 +1,51 @@
+package resonantinduction.atomic.base;
+
+import java.util.List;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+
+import org.lwjgl.input.Keyboard;
+
+import resonant.lib.render.EnumColor;
+import resonant.lib.utility.LanguageUtility;
+import resonantinduction.atomic.Atomic;
+
+public class ItemCell extends Item
+{
+ public ItemCell(int itemID)
+ {
+ super(itemID);
+ setContainerItem(Atomic.itemCell);
+ }
+
+ @Override
+ public void addInformation(ItemStack itemStack, EntityPlayer par2EntityPlayer, List list, boolean par4)
+ {
+ String tooltip = LanguageUtility.getLocal(getUnlocalizedName(itemStack) + ".tooltip");
+
+ if (tooltip != null && tooltip.length() > 0)
+ {
+ if (!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))
+ {
+ list.add(LanguageUtility.getLocal("tooltip.noShift").replace("%0", EnumColor.AQUA.toString()).replace("%1", EnumColor.GREY.toString()));
+ }
+ else
+ {
+ list.addAll(LanguageUtility.splitStringPerWord(tooltip, 5));
+ }
+ }
+ }
+
+ @Override
+ public String getUnlocalizedName(ItemStack itemstack)
+ {
+ String localized = LanguageUtility.getLocal(getUnlocalizedName() + "." + itemstack.getItemDamage() + ".name");
+ if (localized != null && !localized.isEmpty())
+ {
+ return getUnlocalizedName() + "." + itemstack.getItemDamage();
+ }
+ return getUnlocalizedName();
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/BlockUraniumOre.java b/atomic/src/main/scala/resonantinduction/atomic/fission/BlockUraniumOre.java
new file mode 100644
index 000000000..d33d469db
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/BlockUraniumOre.java
@@ -0,0 +1,56 @@
+package resonantinduction.atomic.fission;
+
+import java.util.Random;
+
+import net.minecraft.block.material.Material;
+import net.minecraft.util.Icon;
+import net.minecraft.world.World;
+import resonant.lib.prefab.block.BlockRadioactive;
+import resonantinduction.core.Reference;
+import resonantinduction.core.Settings;
+import resonantinduction.core.TabRI;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** Uranium ore block */
+public class BlockUraniumOre extends BlockRadioactive
+{
+ public BlockUraniumOre(int id)
+ {
+ super(id, Material.rock);
+ this.setUnlocalizedName(Reference.PREFIX + "oreUranium");
+ this.setStepSound(soundStoneFootstep);
+ this.setCreativeTab(TabRI.DEFAULT);
+ this.setHardness(2f);
+ this.setTextureName(Reference.PREFIX + "oreUranium");
+
+ this.isRandomlyRadioactive = Settings.allowRadioactiveOres;
+ this.canWalkPoison = Settings.allowRadioactiveOres;
+ this.canSpread = false;
+ this.radius = 1f;
+ this.amplifier = 0;
+ this.spawnParticle = false;
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void randomDisplayTick(World world, int x, int y, int z, Random par5Random)
+ {
+ if (Settings.allowRadioactiveOres)
+ {
+ super.randomDisplayTick(world, x, y, z, par5Random);
+ }
+ }
+
+ @Override
+ public Icon getIcon(int side, int metadata)
+ {
+ return this.blockIcon;
+ }
+
+ @Override
+ public int quantityDropped(Random par1Random)
+ {
+ return 1;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/ItemBreederFuel.java b/atomic/src/main/scala/resonantinduction/atomic/fission/ItemBreederFuel.java
new file mode 100644
index 000000000..ac406e9dc
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/ItemBreederFuel.java
@@ -0,0 +1,34 @@
+package resonantinduction.atomic.fission;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import resonant.api.IReactor;
+import resonant.api.IReactorComponent;
+
+/** Breeder rods */
+public class ItemBreederFuel extends ItemRadioactive implements IReactorComponent
+{
+ public ItemBreederFuel(int itemID)
+ {
+ super(itemID);
+ this.setMaxDamage(ItemFissileFuel.DECAY);
+ this.setMaxStackSize(1);
+ this.setNoRepair();
+ }
+
+ @Override
+ public void onReact(ItemStack itemStack, IReactor reactor)
+ {
+ TileEntity tileEntity = (TileEntity) reactor;
+ World worldObj = tileEntity.worldObj;
+
+ // Breeder fuel rods have half the normal energy potential of pure uranium.
+ reactor.heat(ItemFissileFuel.ENERGY_PER_TICK / 2);
+
+ if (reactor.world().getWorldTime() % 20 == 0)
+ {
+ itemStack.setItemDamage(Math.min(itemStack.getItemDamage() + 1, itemStack.getMaxDamage()));
+ }
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/ItemFissileFuel.java b/atomic/src/main/scala/resonantinduction/atomic/fission/ItemFissileFuel.java
new file mode 100644
index 000000000..f165a3769
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/ItemFissileFuel.java
@@ -0,0 +1,99 @@
+package resonantinduction.atomic.fission;
+
+import java.util.List;
+
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.fluids.FluidStack;
+import resonant.api.IReactor;
+import resonant.api.IReactorComponent;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.Settings;
+import universalelectricity.api.vector.Vector3;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** Fissile fuel rod */
+public class ItemFissileFuel extends ItemRadioactive implements IReactorComponent
+{
+ public static final int DECAY = 2500;
+
+ /** Temperature at which the fuel rod will begin to re-enrich itself. */
+ public static final int BREEDING_TEMP = 1200;
+
+ /** The energy in one KG of uranium is: 72PJ, 100TJ in one cell of uranium. */
+ public static final long ENERGY = 100000000000L;
+
+ /** Approximately 20,000,000J per tick. 400 MW. */
+ public static final long ENERGY_PER_TICK = ENERGY / 50000;
+
+ public ItemFissileFuel(int itemID)
+ {
+ super(itemID);
+ this.setMaxStackSize(1);
+ this.setMaxDamage(DECAY);
+ this.setNoRepair();
+ }
+
+ @Override
+ public void onReact(ItemStack itemStack, IReactor reactor)
+ {
+ TileEntity tileEntity = (TileEntity) reactor;
+ World worldObj = tileEntity.worldObj;
+ int reactors = 0;
+
+ for (int i = 0; i < 6; i++)
+ {
+ Vector3 checkPos = new Vector3(tileEntity).translate(ForgeDirection.getOrientation(i));
+ TileEntity tile = checkPos.getTileEntity(worldObj);
+
+ // Check that the other reactors not only exist but also are running.
+ if (tile instanceof IReactor && ((IReactor) tile).getTemperature() > BREEDING_TEMP)
+ {
+ reactors++;
+ }
+ }
+
+ // Only three reactor cells are required to begin the uranium breeding process instead of four.
+ if (reactors >= 3)
+ {
+ // Begin the process of re-enriching the uranium rod but not consistently.
+ if (worldObj.rand.nextInt(1000) <= 100 && reactor.getTemperature() > BREEDING_TEMP)
+ {
+ // Cells can regain a random amount of health per tick.
+ int healAmt = worldObj.rand.nextInt(5);
+ itemStack.setItemDamage(Math.max(itemStack.getItemDamage() - healAmt, 0));
+ // System.out.println("[Atomic Science] [Reactor Cell] Breeding " + String.valueOf(healAmt) + " back into fissle rod. " + String.valueOf(itemStack.getItemDamage()) + " / " + String.valueOf(itemStack.getMaxDamage()));
+ }
+ }
+ else
+ {
+ reactor.heat(ENERGY_PER_TICK);
+
+ if (reactor.world().getWorldTime() % 20 == 0)
+ {
+ itemStack.setItemDamage(Math.min(itemStack.getItemDamage() + 1, itemStack.getMaxDamage()));
+ }
+
+ // Create toxic waste.
+ if (Settings.allowToxicWaste && worldObj.rand.nextFloat() > 0.5)
+ {
+ FluidStack fluid = Atomic.FLUIDSTACK_TOXIC_WASTE.copy();
+ fluid.amount = 1;
+ reactor.fill(ForgeDirection.UNKNOWN, fluid, true);
+ }
+ }
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List)
+ {
+ par3List.add(new ItemStack(par1, 1, 0));
+ par3List.add(new ItemStack(par1, 1, getMaxDamage() - 1));
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/ItemRadioactive.java b/atomic/src/main/scala/resonantinduction/atomic/fission/ItemRadioactive.java
new file mode 100644
index 000000000..9cf21a9e2
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/ItemRadioactive.java
@@ -0,0 +1,28 @@
+package resonantinduction.atomic.fission;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.world.World;
+import resonant.lib.prefab.poison.PoisonRadiation;
+import universalelectricity.api.vector.Vector3;
+
+/** Radioactive Items */
+public class ItemRadioactive extends Item
+{
+ public ItemRadioactive(int itemID)
+ {
+ super(itemID);
+ }
+
+ @Override
+ public void onUpdate(ItemStack par1ItemStack, World par2World, Entity entity, int par4, boolean par5)
+ {
+ if (entity instanceof EntityLivingBase)
+ {
+ PoisonRadiation.INSTANCE.poisonEntity(new Vector3(entity), (EntityLivingBase) entity, 1);
+ }
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/ItemUranium.java b/atomic/src/main/scala/resonantinduction/atomic/fission/ItemUranium.java
new file mode 100644
index 000000000..022820096
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/ItemUranium.java
@@ -0,0 +1,54 @@
+package resonantinduction.atomic.fission;
+
+import java.util.List;
+
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+
+import org.lwjgl.input.Keyboard;
+
+import resonant.lib.render.EnumColor;
+import resonant.lib.utility.LanguageUtility;
+
+/** Uranium */
+public class ItemUranium extends ItemRadioactive
+{
+ public ItemUranium(int itemID)
+ {
+ super(itemID);
+ this.setHasSubtypes(true);
+ this.setMaxDamage(0);
+ }
+
+ @Override
+ public void addInformation(ItemStack itemStack, EntityPlayer par2EntityPlayer, List list, boolean par4)
+ {
+ String tooltip = LanguageUtility.getLocal(getUnlocalizedName(itemStack) + ".tooltip");
+
+ if (tooltip != null && tooltip.length() > 0)
+ {
+ if (!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))
+ {
+ list.add(LanguageUtility.getLocal("tooltip.noShift").replace("%0", EnumColor.AQUA.toString()).replace("%1", EnumColor.GREY.toString()));
+ }
+ else
+ {
+ list.addAll(LanguageUtility.splitStringPerWord(tooltip, 5));
+ }
+ }
+ }
+
+ @Override
+ public String getUnlocalizedName(ItemStack itemStack)
+ {
+ return this.getUnlocalizedName() + "." + itemStack.getItemDamage();
+ }
+
+ @Override
+ public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List list)
+ {
+ list.add(new ItemStack(this, 1, 0));
+ list.add(new ItemStack(this, 1, 1));
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/BlockReactorDrain.java b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/BlockReactorDrain.java
new file mode 100644
index 000000000..67db7d1bc
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/BlockReactorDrain.java
@@ -0,0 +1,72 @@
+package resonantinduction.atomic.fission.reactor;
+
+import net.minecraft.client.renderer.texture.IconRegister;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.Icon;
+import net.minecraft.util.MathHelper;
+import net.minecraft.world.World;
+import resonant.lib.prefab.block.BlockRotatable;
+import universalelectricity.api.UniversalElectricity;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** Reactor tap block */
+public class BlockReactorDrain extends BlockRotatable
+{
+ private Icon frontIcon;
+
+ public BlockReactorDrain(int id)
+ {
+ super(id, UniversalElectricity.machine);
+ }
+
+ @Override
+ public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entityLiving, ItemStack itemStack)
+ {
+ if (MathHelper.abs((float) entityLiving.posX - x) < 2.0F && MathHelper.abs((float) entityLiving.posZ - z) < 2.0F)
+ {
+ double d0 = entityLiving.posY + 1.82D - entityLiving.yOffset;
+
+ if (d0 - y > 2.0D)
+ {
+ world.setBlockMetadataWithNotify(x, y, z, 1, 3);
+ return;
+ }
+
+ if (y - d0 > 0.0D)
+ {
+ world.setBlockMetadataWithNotify(x, y, z, 0, 3);
+ return;
+ }
+ }
+
+ super.onBlockPlacedBy(world, x, y, z, entityLiving, itemStack);
+ }
+
+ @Override
+ public Icon getIcon(int side, int metadata)
+ {
+ if (side == metadata)
+ {
+ return this.frontIcon;
+ }
+ return this.blockIcon;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public void registerIcons(IconRegister iconRegister)
+ {
+ super.registerIcons(iconRegister);
+ this.frontIcon = iconRegister.registerIcon(this.getUnlocalizedName().replace("tile.", "") + "_front");
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(World var1)
+ {
+ return new TileReactorDrain();
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/BlockToxicWaste.java b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/BlockToxicWaste.java
new file mode 100644
index 000000000..a6080c6fa
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/BlockToxicWaste.java
@@ -0,0 +1,51 @@
+package resonantinduction.atomic.fission.reactor;
+
+import java.util.Random;
+
+import net.minecraft.block.material.Material;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.util.DamageSource;
+import net.minecraft.world.World;
+import net.minecraftforge.fluids.BlockFluidClassic;
+import net.minecraftforge.fluids.FluidRegistry;
+import resonant.lib.prefab.poison.PoisonRadiation;
+import universalelectricity.api.vector.Vector3;
+
+public class BlockToxicWaste extends BlockFluidClassic
+{
+ public BlockToxicWaste(int id)
+ {
+ super(id, FluidRegistry.getFluid("toxicwaste"), Material.water);
+ setTickRate(20);
+ }
+
+ @Override
+ public void randomDisplayTick(World par1World, int x, int y, int z, Random par5Random)
+ {
+ super.randomDisplayTick(par1World, x, y, z, par5Random);
+
+ if (par5Random.nextInt(100) == 0)
+ {
+ double d5 = x + par5Random.nextFloat();
+ double d7 = y + this.maxY;
+ double d6 = z + par5Random.nextFloat();
+ par1World.spawnParticle("suspended", d5, d7, d6, 0.0D, 0.0D, 0.0D);
+ }
+
+ if (par5Random.nextInt(200) == 0)
+ {
+ par1World.playSound(x, y, z, "liquid.lava", 0.2F + par5Random.nextFloat() * 0.2F, 0.9F + par5Random.nextFloat() * 0.15F, false);
+ }
+ }
+
+ @Override
+ public void onEntityCollidedWithBlock(World par1World, int x, int y, int z, Entity entity)
+ {
+ if (entity instanceof EntityLivingBase)
+ {
+ entity.attackEntityFrom(DamageSource.wither, 3);
+ PoisonRadiation.INSTANCE.poisonEntity(new Vector3(x, y, z), (EntityLivingBase) entity, 4);
+ }
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/ContainerReactorCell.java b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/ContainerReactorCell.java
new file mode 100644
index 000000000..928fd15cc
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/ContainerReactorCell.java
@@ -0,0 +1,78 @@
+package resonantinduction.atomic.fission.reactor;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import resonant.lib.gui.ContainerBase;
+import resonant.lib.prefab.slot.SlotSpecific;
+import resonantinduction.atomic.fission.ItemBreederFuel;
+import resonantinduction.atomic.fission.ItemFissileFuel;
+
+public class ContainerReactorCell extends ContainerBase
+{
+ public ContainerReactorCell(EntityPlayer player, TileReactorCell tileEntity)
+ {
+ super(tileEntity);
+ this.addSlotToContainer(new SlotSpecific(tileEntity, 0, 79, 17, ItemFissileFuel.class, ItemBreederFuel.class));
+ this.addPlayerInventory(player);
+ }
+
+ /** Called to transfer a stack from one inventory to the other eg. when shift clicking. */
+ @Override
+ public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par1)
+ {
+ ItemStack var2 = null;
+ Slot var3 = (Slot) this.inventorySlots.get(par1);
+
+ if (var3 != null && var3.getHasStack())
+ {
+ ItemStack itemStack = var3.getStack();
+ var2 = itemStack.copy();
+
+ if (par1 >= this.slotCount)
+ {
+ if (this.getSlot(0).isItemValid(itemStack))
+ {
+ if (!this.mergeItemStack(itemStack, 0, 1, false))
+ {
+ return null;
+ }
+ }
+ else if (par1 < 27 + this.slotCount)
+ {
+ if (!this.mergeItemStack(itemStack, 27 + slotCount, 36 + slotCount, false))
+ {
+ return null;
+ }
+ }
+ else if (par1 >= 27 + slotCount && par1 < 36 + slotCount && !this.mergeItemStack(itemStack, 4, 30, false))
+ {
+ return null;
+ }
+ }
+ else if (!this.mergeItemStack(itemStack, slotCount, 36 + slotCount, false))
+ {
+ return null;
+ }
+
+ if (itemStack.stackSize == 0)
+ {
+ var3.putStack((ItemStack) null);
+ }
+ else
+ {
+ var3.onSlotChanged();
+ }
+
+ if (itemStack.stackSize == var2.stackSize)
+ {
+ return null;
+ }
+
+ var3.onPickupFromSlot(par1EntityPlayer, itemStack);
+ }
+
+ return var2;
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/GuiReactorCell.java b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/GuiReactorCell.java
new file mode 100644
index 000000000..add750070
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/GuiReactorCell.java
@@ -0,0 +1,90 @@
+package resonantinduction.atomic.fission.reactor;
+
+import java.util.List;
+
+import net.minecraft.entity.player.InventoryPlayer;
+
+import org.lwjgl.opengl.GL11;
+
+import resonant.lib.gui.GuiContainerBase;
+import resonant.lib.utility.LanguageUtility;
+import universalelectricity.api.energy.UnitDisplay;
+import universalelectricity.api.energy.UnitDisplay.Unit;
+
+public class GuiReactorCell extends GuiContainerBase
+{
+ private TileReactorCell tileEntity;
+
+ public GuiReactorCell(InventoryPlayer inventory, TileReactorCell tileEntity)
+ {
+ super(new ContainerReactorCell(inventory.player, tileEntity));
+ this.tileEntity = tileEntity;
+ }
+
+ /** Draw the foreground layer for the GuiContainer (everything in front of the items) */
+ @Override
+ public void drawGuiContainerForegroundLayer(int x, int y)
+ {
+ fontRenderer.drawString(tileEntity.getInvName(), xSize / 2 - fontRenderer.getStringWidth(tileEntity.getInvName()) / 2, 6, 4210752);
+
+ if (tileEntity.getStackInSlot(0) != null)
+ {
+ // Test field for actual heat inside of reactor cell.
+ fontRenderer.drawString(LanguageUtility.getLocal("tooltip.temperature"), 9, 45, 4210752);
+ fontRenderer.drawString(String.valueOf((int) tileEntity.getTemperature()) + "/" + String.valueOf(TileReactorCell.MELTING_POINT) + " K", 9, 58, 4210752);
+
+ // Text field for total number of ticks remaining.
+ int secondsLeft = (tileEntity.getStackInSlot(0).getMaxDamage() - tileEntity.getStackInSlot(0).getItemDamage());
+ fontRenderer.drawString(LanguageUtility.getLocal("tooltip.remainingTime"), 100, 45, 4210752);
+ fontRenderer.drawString(secondsLeft + " seconds", 100, 58, 4210752);
+ }
+
+ fontRenderer.drawString(LanguageUtility.getLocal("tooltip.remainingTime"), 100, 45, 4210752);
+
+ if (isPointInRegion(80, 40, meterWidth, meterHeight, x, y))
+ {
+ if (tileEntity.tank.getFluid() != null)
+ {
+ drawTooltip(x - guiLeft, y - guiTop + 10, tileEntity.tank.getFluid().getFluid().getLocalizedName(), UnitDisplay.getDisplay(tileEntity.tank.getFluidAmount(), Unit.LITER));
+ }
+ else
+ {
+ drawTooltip(x - guiLeft, y - guiTop + 10, "No Fluid");
+ }
+ }
+
+ List desc = LanguageUtility.splitStringPerWord(LanguageUtility.getLocal("tile.atomicscience:reactorCell.tooltip"), 5);
+
+ for (int i = 0; i < desc.size(); i++)
+ {
+ fontRenderer.drawString(desc.get(i), 9, 85 + i * 9, 4210752);
+ }
+ }
+
+ /** Draw the background layer for the GuiContainer (everything behind the items) */
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float par1, int x, int y)
+ {
+ super.drawGuiContainerBackgroundLayer(par1, x, y);
+ drawSlot(78, 16);
+ drawMeter(80, 36, (float) tileEntity.tank.getFluidAmount() / (float) tileEntity.tank.getCapacity(), tileEntity.tank.getFluid());
+
+ if (tileEntity.getStackInSlot(0) != null)
+ {
+ // Progress bar of temperature inside of reactor.
+ GL11.glPushMatrix();
+ GL11.glTranslatef(32 * 2, 0, 0);
+ GL11.glScalef(0.5f, 1, 1);
+ drawForce(20, 70, (tileEntity.getTemperature()) / (TileReactorCell.MELTING_POINT));
+ GL11.glPopMatrix();
+
+ // Progress bar of remaining burn time on reactor cell.
+ GL11.glPushMatrix();
+ GL11.glTranslatef(68 * 2, 0, 0);
+ GL11.glScalef(0.5f, 1, 1);
+ float ticksLeft = (tileEntity.getStackInSlot(0).getMaxDamage() - tileEntity.getStackInSlot(0).getItemDamage());
+ drawElectricity(70, 70, ticksLeft / tileEntity.getStackInSlot(0).getMaxDamage());
+ GL11.glPopMatrix();
+ }
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/RenderReactorCell.java b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/RenderReactorCell.java
new file mode 100644
index 000000000..2e975f836
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/RenderReactorCell.java
@@ -0,0 +1,101 @@
+package resonantinduction.atomic.fission.reactor;
+
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.model.AdvancedModelLoader;
+import net.minecraftforge.client.model.IModelCustom;
+
+import org.lwjgl.opengl.GL11;
+
+import resonant.lib.render.RenderUtility;
+import resonant.lib.render.block.ModelCube;
+import resonantinduction.core.Reference;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class RenderReactorCell extends TileEntitySpecialRenderer
+{
+ public static final IModelCustom MODEL_TOP = AdvancedModelLoader.loadModel(Reference.MODEL_DIRECTORY + "reactorCellTop.tcn");
+ public static final IModelCustom MODEL_MIDDLE = AdvancedModelLoader.loadModel(Reference.MODEL_DIRECTORY + "reactorCellMiddle.tcn");
+ public static final IModelCustom MODEL_BOTTOM = AdvancedModelLoader.loadModel(Reference.MODEL_DIRECTORY + "reactorCellBottom.tcn");
+
+ public static final ResourceLocation TEXTURE_TOP = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "reactorCellTop.png");
+ public static final ResourceLocation TEXTURE_MIDDLE = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "reactorCellMiddle.png");
+ public static final ResourceLocation TEXTURE_BOTTOM = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "reactorCellBottom.png");
+ public static final ResourceLocation TEXTURE_FISSILE = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "fissileMaterial.png");
+
+ @Override
+ public void renderTileEntityAt(TileEntity t, double x, double y, double z, float f)
+ {
+ TileReactorCell tileEntity = (TileReactorCell) t;
+
+ // Render main body
+ GL11.glPushMatrix();
+ GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5);
+
+ int meta = 2;
+
+ if (tileEntity.worldObj != null)
+ {
+ meta = tileEntity.getBlockMetadata();
+ }
+
+ boolean hasBelow = tileEntity.worldObj != null && t.worldObj.getBlockTileEntity(t.xCoord, t.yCoord - 1, t.zCoord) instanceof TileReactorCell;
+
+ switch (meta)
+ {
+ case 0:
+ bindTexture(TEXTURE_BOTTOM);
+ MODEL_BOTTOM.renderAll();
+ break;
+ case 1:
+ bindTexture(TEXTURE_MIDDLE);
+ GL11.glTranslatef(0, 0.075f, 0);
+ GL11.glScalef(1f, 1.15f, 1f);
+ MODEL_MIDDLE.renderAll();
+ break;
+ case 2:
+ bindTexture(TEXTURE_TOP);
+
+ if (hasBelow)
+ {
+ GL11.glScalef(1f, 1.32f, 1f);
+ }
+ else
+ {
+ GL11.glTranslatef(0, 0.1f, 0);
+ GL11.glScalef(1f, 1.2f, 1f);
+ }
+
+ if (hasBelow)
+ {
+ MODEL_TOP.renderAllExcept("BottomPad", "BaseDepth", "BaseWidth", "Base");
+ }
+ else
+ {
+ MODEL_TOP.renderAll();
+ }
+
+ break;
+ }
+
+ GL11.glPopMatrix();
+
+ // Render the fuel within the reactor
+ if (tileEntity.getStackInSlot(0) != null)
+ {
+ float height = tileEntity.getHeight() * ((float) (tileEntity.getStackInSlot(0).getMaxDamage() - tileEntity.getStackInSlot(0).getItemDamage()) / (float) tileEntity.getStackInSlot(0).getMaxDamage());
+
+ GL11.glPushMatrix();
+ GL11.glTranslatef((float) x + 0.5F, (float) y + 0.5F * height, (float) z + 0.5F);
+ GL11.glScalef(0.4f, 0.9f * height, 0.4f);
+ bindTexture(TEXTURE_FISSILE);
+ RenderUtility.disableLighting();
+ ModelCube.INSTNACE.render();
+ RenderUtility.enableLighting();
+ GL11.glPopMatrix();
+ }
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/TileControlRod.java b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/TileControlRod.java
new file mode 100644
index 000000000..d7ebe620d
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/TileControlRod.java
@@ -0,0 +1,16 @@
+package resonantinduction.atomic.fission.reactor;
+
+import net.minecraft.block.material.Material;
+import resonant.lib.content.module.TileBlock;
+import resonant.lib.prefab.vector.Cuboid;
+
+/** Control rod block */
+public class TileControlRod extends TileBlock
+{
+ public TileControlRod()
+ {
+ super(Material.iron);
+ bounds = new Cuboid(0.3f, 0f, 0.3f, 0.7f, 1f, 0.7f);
+ isOpaqueCube = false;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/TileReactorCell.java b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/TileReactorCell.java
new file mode 100644
index 000000000..7e838aaaa
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/TileReactorCell.java
@@ -0,0 +1,612 @@
+package resonantinduction.atomic.fission.reactor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.minecraft.block.Block;
+import net.minecraft.entity.EntityLiving;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.packet.Packet;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.world.World;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTank;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidHandler;
+import resonant.api.IReactor;
+import resonant.api.IReactorComponent;
+import resonant.api.event.PlasmaEvent.SpawnPlasmaEvent;
+import resonant.lib.content.module.prefab.TileInventory;
+import resonant.lib.multiblock.IMultiBlockStructure;
+import resonant.lib.multiblock.MultiBlockHandler;
+import resonant.lib.network.PacketHandler;
+import resonant.lib.network.Synced;
+import resonant.lib.network.Synced.SyncedInput;
+import resonant.lib.network.Synced.SyncedOutput;
+import resonant.lib.prefab.poison.PoisonRadiation;
+import resonant.lib.thermal.ThermalGrid;
+import resonant.lib.thermal.ThermalPhysics;
+import resonant.lib.utility.inventory.InventoryUtility;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.atomic.ReactorExplosion;
+import resonantinduction.atomic.fusion.TilePlasma;
+import resonantinduction.core.ResonantInduction;
+import universalelectricity.api.UniversalElectricity;
+import universalelectricity.api.vector.Vector3;
+import universalelectricity.api.vector.VectorWorld;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** The primary reactor component cell used to build reactors with.
+ *
+ * @author Calclavia */
+public class TileReactorCell extends TileInventory implements IMultiBlockStructure, IInventory, IReactor, IFluidHandler, ISidedInventory
+{
+ public static final int RADIUS = 2;
+ public static final int MELTING_POINT = 2000;
+
+ private final int specificHeatCapacity = 1000;
+ private final float mass = ThermalPhysics.getMass(1000, 7);
+ public FluidTank tank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 15);
+
+ @Synced
+ public float temperature = 295;
+
+ private float previousTemperature = 295;
+
+ private boolean shouldUpdate = false;
+
+ private long prevInternalEnergy = 0;
+ private long internalEnergy = 0;
+ private int meltdownCounter = 0;
+ private int meltdownCounterMaximum = 1000;
+
+ /** Multiblock Methods. */
+ private MultiBlockHandler multiBlock;
+
+ public TileReactorCell()
+ {
+ super(UniversalElectricity.machine);
+ textureName = "machine";
+ isOpaqueCube = false;
+ normalRender = false;
+ customItemRender = true;
+ }
+
+ @Override
+ protected void onWorldJoin()
+ {
+ updatePositionStatus();
+ }
+
+ @Override
+ protected void onNeighborChanged()
+ {
+ updatePositionStatus();
+ }
+
+ @Override
+ public void initiate()
+ {
+ updatePositionStatus();
+ super.initiate();
+ }
+
+ /** Called when the block is right clicked by the player */
+ @Override
+ protected boolean use(EntityPlayer player, int side, Vector3 hit)
+ {
+ if (!world().isRemote)
+ {
+ TileReactorCell tile = getMultiBlock().get();
+
+ if (!player.isSneaking())
+ {
+ if (tile.getStackInSlot(0) != null)
+ {
+ InventoryUtility.dropItemStack(world(), new Vector3(player), tile.getStackInSlot(0), 0);
+ tile.setInventorySlotContents(0, null);
+ return true;
+ }
+ else if (player.inventory.getCurrentItem() != null)
+ {
+ if (player.inventory.getCurrentItem().getItem() instanceof IReactorComponent)
+ {
+ ItemStack itemStack = player.inventory.getCurrentItem().copy();
+ itemStack.stackSize = 1;
+ tile.setInventorySlotContents(0, itemStack);
+ player.inventory.decrStackSize(player.inventory.currentItem, 1);
+ return true;
+ }
+ }
+ }
+
+ player.openGui(Atomic.INSTANCE, 0, world(), tile.xCoord, tile.yCoord, tile.zCoord);
+ }
+
+ return true;
+ }
+
+ @Override
+ protected void markUpdate()
+ {
+ super.markUpdate();
+ shouldUpdate = true;
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+
+ /** Move fuel rod down into the primary cell block if possible */
+ if (!getMultiBlock().isPrimary())
+ {
+ if (getStackInSlot(0) != null)
+ {
+ if (getMultiBlock().get().getStackInSlot(0) == null)
+ {
+ getMultiBlock().get().setInventorySlotContents(0, getStackInSlot(0));
+ setInventorySlotContents(0, null);
+ }
+ }
+
+ if (tank.getFluidAmount() > 0)
+ {
+ getMultiBlock().get().tank.fill(tank.drain(tank.getCapacity(), true), true);
+ }
+ }
+
+ if (!worldObj.isRemote)
+ {
+ if (getMultiBlock().isPrimary() && tank.getFluid() != null && tank.getFluid().fluidID == Atomic.FLUID_PLASMA.getID())
+ {
+ /** Spawn plasma */
+ FluidStack drain = tank.drain(FluidContainerRegistry.BUCKET_VOLUME, false);
+
+ if (drain != null && drain.amount >= FluidContainerRegistry.BUCKET_VOLUME)
+ {
+ ForgeDirection spawnDir = ForgeDirection.getOrientation(worldObj.rand.nextInt(3) + 2);
+ Vector3 spawnPos = new Vector3(this).translate(spawnDir, 2);
+ spawnPos.translate(0, Math.max(worldObj.rand.nextInt(getHeight()) - 1, 0), 0);
+
+ if (worldObj.isAirBlock(spawnPos.intX(), spawnPos.intY(), spawnPos.intZ()))
+ {
+ MinecraftForge.EVENT_BUS.post(new SpawnPlasmaEvent(worldObj, spawnPos.intX(), spawnPos.intY(), spawnPos.intZ(), TilePlasma.plasmaMaxTemperature));
+ tank.drain(FluidContainerRegistry.BUCKET_VOLUME, true);
+ }
+ }
+ }
+ else
+ {
+ prevInternalEnergy = internalEnergy;
+
+ /** Handle cell rod interactions. */
+ ItemStack fuelRod = getMultiBlock().get().getStackInSlot(0);
+
+ if (fuelRod != null)
+ {
+ if (fuelRod.getItem() instanceof IReactorComponent)
+ {
+ // Activate rods.
+ ((IReactorComponent) fuelRod.getItem()).onReact(fuelRod, this);
+
+ if (!worldObj.isRemote)
+ {
+ if (fuelRod.getItemDamage() >= fuelRod.getMaxDamage())
+ {
+ getMultiBlock().get().setInventorySlotContents(0, null);
+ }
+ }
+
+ // Emit Radiations
+ if (ticks % 20 == 0)
+ {
+ if (worldObj.rand.nextFloat() > 0.65)
+ {
+ List entities = worldObj.getEntitiesWithinAABB(EntityLiving.class,
+ AxisAlignedBB.getBoundingBox(xCoord - RADIUS * 2, yCoord - RADIUS * 2, zCoord - RADIUS * 2, xCoord + RADIUS * 2, yCoord + RADIUS * 2, zCoord + RADIUS * 2));
+
+ for (EntityLiving entity : entities)
+ {
+ PoisonRadiation.INSTANCE.poisonEntity(new Vector3(this), entity);
+ }
+ }
+ }
+ }
+ }
+
+ // Update the temperature from the thermal grid.
+ temperature = ThermalGrid.getTemperature(new VectorWorld(this));
+
+ /** Only a small percentage of the internal energy is used for temperature. */
+ if (internalEnergy - prevInternalEnergy > 0)
+ {
+ float deltaT = ThermalPhysics.getTemperatureForEnergy(mass, specificHeatCapacity, (long) ((internalEnergy - prevInternalEnergy) * 0.15));
+
+ /** Check control rods */
+ int rods = 0;
+
+ for (int i = 2; i < 6; i++)
+ {
+ Vector3 checkAdjacent = new Vector3(this).translate(ForgeDirection.getOrientation(i));
+
+ if (checkAdjacent.getBlockID(worldObj) == Atomic.blockControlRod.blockID)
+ {
+ deltaT /= 1.1;
+ rods++;
+ }
+ }
+
+ // Add heat to surrounding blocks in the thermal grid.
+ ThermalGrid.addTemperature(new VectorWorld(this), deltaT);
+
+ // Sound of lava flowing randomly plays when above temperature to boil water.
+ if (worldObj.rand.nextInt(80) == 0 && this.getTemperature() >= 373)
+ {
+ worldObj.playSoundEffect(this.xCoord + 0.5F, this.yCoord + 0.5F, this.zCoord + 0.5F, "Fluid.lava", 0.5F, 2.1F + (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.85F);
+ }
+
+ // Sounds of lava popping randomly plays when above temperature to boil water.
+ if (worldObj.rand.nextInt(40) == 0 && this.getTemperature() >= 373)
+ {
+ worldObj.playSoundEffect(this.xCoord + 0.5F, this.yCoord + 0.5F, this.zCoord + 0.5F, "Fluid.lavapop", 0.5F, 2.6F + (worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.8F);
+ }
+
+ // Reactor cell plays random idle noises while operating and above temperature to boil water.
+ if (worldObj.getWorldTime() % (Atomic.SECOND_IN_TICKS * 5.0F) == 0 && this.getTemperature() >= 373)
+ {
+ float percentage = Math.min(this.getTemperature() / TileReactorCell.MELTING_POINT, 1.0F);
+ worldObj.playSoundEffect(this.xCoord + 0.5F, this.yCoord + 0.5F, this.zCoord + 0.5F, "atomicscience:reactorcell", percentage, 1.0F);
+ // AtomicScience.LOGGER.info("REACTOR SOUND");
+ }
+
+ if (previousTemperature != temperature && !shouldUpdate)
+ {
+ shouldUpdate = true;
+ previousTemperature = temperature;
+ // System.out.println("[Atomic Science] [Thermal Grid] Temperature: " + String.valueOf(previousTemperature));
+ }
+
+ if (previousTemperature >= MELTING_POINT && meltdownCounter < meltdownCounterMaximum)
+ {
+ shouldUpdate = true;
+ meltdownCounter++;
+ // System.out.println("[Atomic Science] [Reactor Cell] Meltdown Ticker: " + String.valueOf(temperature) + " @ " + String.valueOf(meltdownCounter) + "/" + String.valueOf(meltdownCounterMaximum));
+ }
+
+ if (previousTemperature >= MELTING_POINT && meltdownCounter >= meltdownCounterMaximum)
+ {
+ // System.out.println("[Atomic Science] [Reactor Cell] Meltdown Ticker: REACTOR MELTDOWN!");
+ meltdownCounter = 0;
+ meltDown();
+ return;
+ }
+ else
+ {
+ // Reset meltdown ticker to give the reactor more of a 'goldilocks zone'.
+ meltdownCounter = 0;
+ }
+ }
+
+ internalEnergy = 0;
+
+ if (isOverToxic())
+ {
+ /** Randomly leak toxic waste when it is too toxic */
+ VectorWorld leakPos = new VectorWorld(this).translate(worldObj.rand.nextInt(20) - 10, worldObj.rand.nextInt(20) - 10, worldObj.rand.nextInt(20) - 10);
+
+ int blockID = leakPos.getBlockID();
+
+ if (blockID == Block.grass.blockID)
+ {
+ leakPos.setBlock(worldObj, Atomic.blockRadioactive.blockID);
+ tank.drain(FluidContainerRegistry.BUCKET_VOLUME, true);
+ }
+ else if (blockID == 0 || Block.blocksList[blockID].isBlockReplaceable(worldObj, leakPos.intX(), leakPos.intY(), leakPos.intZ()))
+ {
+ if (tank.getFluid() != null)
+ {
+ leakPos.setBlock(worldObj, tank.getFluid().getFluid().getBlockID());
+ tank.drain(FluidContainerRegistry.BUCKET_VOLUME, true);
+ }
+ }
+ }
+
+ }
+
+ if (ticks % 60 == 0 || shouldUpdate)
+ {
+ shouldUpdate = false;
+ notifyChange();
+ PacketHandler.sendPacketToClients(getDescriptionPacket(), worldObj, new Vector3(this), 50);
+ }
+ }
+ else
+ {
+
+ // Particles of white smoke will rise from above the reactor chamber when above water boiling temperature.
+ if (worldObj.rand.nextInt(5) == 0 && this.getTemperature() >= 373)
+ {
+ worldObj.spawnParticle("cloud", this.xCoord + worldObj.rand.nextInt(2), this.yCoord + 1.0F, this.zCoord + worldObj.rand.nextInt(2), 0, 0.1D, 0);
+ worldObj.spawnParticle("bubble", this.xCoord + worldObj.rand.nextInt(5), this.yCoord, this.zCoord + worldObj.rand.nextInt(5), 0, 0, 0);
+ }
+ }
+ }
+
+ @Override
+ public boolean isOverToxic()
+ {
+ return tank.getFluid() != null && tank.getFluid().fluidID == Atomic.FLUID_TOXIC_WASTE.getID() && tank.getFluid().amount >= tank.getCapacity();
+ }
+
+ /** Multiblock Methods */
+ public void updatePositionStatus()
+ {
+ TileReactorCell mainTile = getLowest();
+ mainTile.getMultiBlock().deconstruct();
+ mainTile.getMultiBlock().construct();
+
+ boolean top = new Vector3(this).add(new Vector3(0, 1, 0)).getTileEntity(worldObj) instanceof TileReactorCell;
+ boolean bottom = new Vector3(this).add(new Vector3(0, -1, 0)).getTileEntity(worldObj) instanceof TileReactorCell;
+
+ if (top && bottom)
+ {
+ worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 1, 3);
+ }
+ else if (top)
+ {
+ worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, 3);
+ }
+ else
+ {
+ worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 2, 3);
+ }
+ }
+
+ @Override
+ public void onMultiBlockChanged()
+ {
+
+ }
+
+ @Override
+ public Vector3[] getMultiBlockVectors()
+ {
+ List vectors = new ArrayList();
+
+ Vector3 checkPosition = new Vector3(this);
+
+ while (true)
+ {
+ TileEntity t = checkPosition.getTileEntity(this.worldObj);
+
+ if (t instanceof TileReactorCell)
+ {
+ vectors.add(checkPosition.clone().subtract(getPosition()));
+ }
+ else
+ {
+ break;
+ }
+
+ checkPosition.y++;
+ }
+
+ return vectors.toArray(new Vector3[0]);
+ }
+
+ public TileReactorCell getLowest()
+ {
+ TileReactorCell lowest = this;
+ Vector3 checkPosition = new Vector3(this);
+
+ while (true)
+ {
+ TileEntity t = checkPosition.getTileEntity(this.worldObj);
+
+ if (t instanceof TileReactorCell)
+ {
+ lowest = (TileReactorCell) t;
+ }
+ else
+ {
+ break;
+ }
+
+ checkPosition.y--;
+ }
+
+ return lowest;
+ }
+
+ @Override
+ public World getWorld()
+ {
+ return worldObj;
+ }
+
+ @Override
+ public Vector3 getPosition()
+ {
+ return new Vector3(this);
+ }
+
+ @Override
+ public MultiBlockHandler getMultiBlock()
+ {
+ if (multiBlock == null)
+ {
+ multiBlock = new MultiBlockHandler(this);
+ }
+
+ return multiBlock;
+ }
+
+ public int getHeight()
+ {
+ int height = 0;
+ Vector3 checkPosition = new Vector3(this);
+ TileEntity tile = this;
+
+ while (tile instanceof TileReactorCell)
+ {
+ checkPosition.y++;
+ height++;
+ tile = checkPosition.getTileEntity(worldObj);
+ }
+
+ return height;
+ }
+
+ @Override
+ public Packet getDescriptionPacket()
+ {
+ return ResonantInduction.PACKET_ANNOTATION.getPacket(this);
+ }
+
+ private void meltDown()
+ {
+ if (!worldObj.isRemote)
+ {
+ // No need to destroy reactor cell since explosion will do that for us.
+ ReactorExplosion reactorExplosion = new ReactorExplosion(worldObj, null, xCoord, yCoord, zCoord, 9f);
+ reactorExplosion.doExplosionA();
+ reactorExplosion.doExplosionB(true);
+ }
+ }
+
+ /** Reads a tile entity from NBT. */
+ @SyncedInput
+ @Override
+ public void readFromNBT(NBTTagCompound nbt)
+ {
+ super.readFromNBT(nbt);
+ temperature = nbt.getFloat("temperature");
+ tank.readFromNBT(nbt);
+ getMultiBlock().load(nbt);
+ }
+
+ /** Writes a tile entity to NBT. */
+ @SyncedOutput
+ @Override
+ public void writeToNBT(NBTTagCompound nbt)
+ {
+ super.writeToNBT(nbt);
+ nbt.setFloat("temperature", temperature);
+ tank.writeToNBT(nbt);
+ getMultiBlock().save(nbt);
+ }
+
+ @Override
+ public int getInventoryStackLimit()
+ {
+ return 1;
+ }
+
+ /** Returns true if automation can insert the given item in the given slot from the given side. Args: Slot, item, side */
+ @Override
+ public boolean canInsertItem(int slot, ItemStack items, int side)
+ {
+ return this.isItemValidForSlot(slot, items);
+ }
+
+ @Override
+ public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer)
+ {
+ return worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this ? false : par1EntityPlayer.getDistanceSq(xCoord + 0.5D, yCoord + 0.5D, zCoord + 0.5D) <= 64.0D;
+ }
+
+ @Override
+ public String getInvName()
+ {
+ return getBlockType().getLocalizedName();
+ }
+
+ @Override
+ public boolean isItemValidForSlot(int slotID, ItemStack itemStack)
+ {
+ if (getMultiBlock().isPrimary() && getMultiBlock().get().getStackInSlot(0) == null)
+ {
+ return itemStack.getItem() instanceof IReactorComponent;
+ }
+
+ return false;
+ }
+
+ /** Fluid Functions. */
+ @Override
+ public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
+ {
+ return getMultiBlock().get().tank.fill(resource, doFill);
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
+ {
+ return tank.drain(maxDrain, doDrain);
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
+ {
+ if (resource == null || !resource.isFluidEqual(tank.getFluid()))
+ {
+ return null;
+ }
+
+ return tank.drain(resource.amount, doDrain);
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid)
+ {
+ return fluid == Atomic.FLUID_PLASMA;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid)
+ {
+ return fluid == Atomic.FLUID_TOXIC_WASTE;
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection from)
+ {
+ return new FluidTankInfo[]
+ { tank.getInfo() };
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public AxisAlignedBB getRenderBoundingBox()
+ {
+ if (getMultiBlock().isPrimary() && getMultiBlock().isConstructed())
+ {
+ return INFINITE_EXTENT_AABB;
+ }
+
+ return super.getRenderBoundingBox();
+ }
+
+ @Override
+ public void heat(long energy)
+ {
+ internalEnergy = Math.max(internalEnergy + energy, 0);
+ }
+
+ @Override
+ public float getTemperature()
+ {
+ return temperature;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/TileReactorDrain.java b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/TileReactorDrain.java
new file mode 100644
index 000000000..be5699db8
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fission/reactor/TileReactorDrain.java
@@ -0,0 +1,182 @@
+package resonantinduction.atomic.fission.reactor;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockFluid;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidBlock;
+import net.minecraftforge.fluids.IFluidHandler;
+import net.minecraftforge.fluids.IFluidTank;
+import resonant.lib.path.IPathCallBack;
+import resonant.lib.path.Pathfinder;
+import resonant.lib.prefab.tile.TileAdvanced;
+import universalelectricity.api.vector.Vector3;
+
+/** Reactor Drain
+ *
+ * @author Calclavia */
+public class TileReactorDrain extends TileAdvanced implements IFluidHandler
+{
+ private final Set tanks = new HashSet();
+ private long lastFindTime = -1;
+
+ public void find()
+ {
+ this.tanks.clear();
+ final World world = this.worldObj;
+ final Vector3 position = new Vector3(this);
+
+ Pathfinder finder = new Pathfinder(new IPathCallBack()
+ {
+ @Override
+ public Set getConnectedNodes(Pathfinder finder, Vector3 currentNode)
+ {
+ Set neighbors = new HashSet();
+
+ for (int i = 0; i < 6; i++)
+ {
+ ForgeDirection direction = ForgeDirection.getOrientation(i);
+ Vector3 position = currentNode.clone().translate(direction);
+ int connectedBlockID = position.getBlockID(world);
+
+ if (connectedBlockID == 0 || Block.blocksList[connectedBlockID] instanceof BlockFluid || Block.blocksList[connectedBlockID] instanceof IFluidBlock || position.getTileEntity(world) instanceof TileReactorCell)
+ {
+ neighbors.add(position);
+ }
+ }
+
+ return neighbors;
+ }
+
+ @Override
+ public boolean onSearch(Pathfinder finder, Vector3 start, Vector3 node)
+ {
+ if (node.getTileEntity(world) instanceof TileReactorCell)
+ {
+ finder.results.add(node);
+ }
+
+ if (node.distance(position) > 6)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }).init(new Vector3(this).translate(ForgeDirection.getOrientation(this.getBlockMetadata()).getOpposite()));
+
+ for (Vector3 node : finder.results)
+ {
+ TileEntity tileEntity = node.getTileEntity(this.worldObj);
+
+ if (tileEntity instanceof TileReactorCell)
+ {
+ this.tanks.add(((TileReactorCell) tileEntity).tank);
+ }
+ }
+
+ this.lastFindTime = this.worldObj.getWorldTime();
+ }
+
+ public IFluidTank getOptimalTank()
+ {
+ if (this.lastFindTime == -1 || this.worldObj.getWorldTime() - this.lastFindTime > 20)
+ {
+ this.find();
+ }
+
+ if (this.tanks.size() > 0)
+ {
+ IFluidTank optimalTank = null;
+
+ for (IFluidTank tank : this.tanks)
+ {
+ if (tank != null)
+ {
+ if (optimalTank == null || (optimalTank != null && getFluidSafe(tank.getFluid()) > getFluidSafe(optimalTank.getFluid())))
+ {
+ optimalTank = tank;
+ }
+ }
+ }
+
+ return optimalTank;
+ }
+
+ return null;
+ }
+
+ public int getFluidSafe(FluidStack stack)
+ {
+ if (stack != null)
+ {
+ return stack.amount;
+ }
+
+ return 0;
+ }
+
+ @Override
+ public boolean canUpdate()
+ {
+ return false;
+ }
+
+ @Override
+ public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
+ {
+ return 0;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
+ {
+ if (this.getOptimalTank() != null)
+ {
+ return this.getOptimalTank().drain(maxDrain, doDrain);
+ }
+
+ return null;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
+ {
+ return null;
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid)
+ {
+ return false;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid)
+ {
+ return true;
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection from)
+ {
+ List tankInfoList = new ArrayList();
+
+ this.getOptimalTank();
+ for (IFluidTank tank : this.tanks)
+ {
+ tankInfoList.add(tank.getInfo());
+ }
+
+ return tankInfoList.toArray(new FluidTankInfo[0]);
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fusion/BlockPlasmaHeater.java b/atomic/src/main/scala/resonantinduction/atomic/fusion/BlockPlasmaHeater.java
new file mode 100644
index 000000000..b7728d324
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fusion/BlockPlasmaHeater.java
@@ -0,0 +1,53 @@
+package resonantinduction.atomic.fusion;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import resonant.lib.prefab.block.BlockTile;
+import resonant.lib.render.block.BlockRenderingHandler;
+import resonant.lib.utility.FluidUtility;
+import universalelectricity.api.UniversalElectricity;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** Fusion reactor */
+public class BlockPlasmaHeater extends BlockTile
+{
+ public BlockPlasmaHeater(int ID)
+ {
+ super(ID, UniversalElectricity.machine);
+
+ }
+
+ @Override
+ public boolean onMachineActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ)
+ {
+ return FluidUtility.playerActivatedFluidItem(world, x, y, z, player, side);
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public int getRenderType()
+ {
+ return BlockRenderingHandler.ID;
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(World var1)
+ {
+ return new TilePlasmaHeater();
+ }
+
+ @Override
+ public boolean renderAsNormalBlock()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isOpaqueCube()
+ {
+ return false;
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fusion/ContainerNuclearBoiler.java b/atomic/src/main/scala/resonantinduction/atomic/fusion/ContainerNuclearBoiler.java
new file mode 100644
index 000000000..07bb9e453
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fusion/ContainerNuclearBoiler.java
@@ -0,0 +1,114 @@
+package resonantinduction.atomic.fusion;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+import resonant.lib.gui.ContainerBase;
+import resonant.lib.prefab.slot.SlotEnergyItem;
+import resonant.lib.prefab.slot.SlotSpecific;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.atomic.process.fission.TileNuclearBoiler;
+
+/** Nuclear boiler container */
+public class ContainerNuclearBoiler extends ContainerBase
+{
+ private static final int slotCount = 4;
+ private TileNuclearBoiler tileEntity;
+
+ public ContainerNuclearBoiler(InventoryPlayer par1InventoryPlayer, TileNuclearBoiler tileEntity)
+ {
+ super(tileEntity);
+ this.tileEntity = tileEntity;
+ // Battery
+ this.addSlotToContainer(new SlotEnergyItem(tileEntity, 0, 56, 26));
+ // Water Input
+ this.addSlotToContainer(new Slot(tileEntity, 1, 25, 50));
+ // Gas Output
+ this.addSlotToContainer(new Slot(tileEntity, 2, 136, 50));
+ // Yellowcake Input
+ this.addSlotToContainer(new SlotSpecific(tileEntity, 3, 81, 26, new ItemStack(Atomic.itemYellowCake), new ItemStack(Atomic.blockUraniumOre)));
+ this.addPlayerInventory(par1InventoryPlayer.player);
+ tileEntity.openChest();
+ }
+
+ @Override
+ public boolean canInteractWith(EntityPlayer par1EntityPlayer)
+ {
+ return this.tileEntity.isUseableByPlayer(par1EntityPlayer);
+ }
+
+ /** Called to transfer a stack from one inventory to the other eg. when shift clicking. */
+ @Override
+ public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int slotID)
+ {
+ ItemStack var2 = null;
+ Slot slot = (Slot) this.inventorySlots.get(slotID);
+
+ if (slot != null && slot.getHasStack())
+ {
+ ItemStack itemStack = slot.getStack();
+ var2 = itemStack.copy();
+
+ if (slotID >= slotCount)
+ {
+ if (this.getSlot(0).isItemValid(itemStack))
+ {
+ if (!this.mergeItemStack(itemStack, 0, 1, false))
+ {
+ return null;
+ }
+ }
+ else if (Atomic.FLUIDSTACK_WATER.isFluidEqual(FluidContainerRegistry.getFluidForFilledItem(itemStack)))
+ {
+ if (!this.mergeItemStack(itemStack, 1, 2, false))
+ {
+ return null;
+ }
+ }
+ else if (this.getSlot(3).isItemValid(itemStack))
+ {
+ if (!this.mergeItemStack(itemStack, 3, 4, false))
+ {
+ return null;
+ }
+ }
+ else if (slotID < 27 + slotCount)
+ {
+ if (!this.mergeItemStack(itemStack, 27 + slotCount, 36 + slotCount, false))
+ {
+ return null;
+ }
+ }
+ else if (slotID >= 27 + slotCount && slotID < 36 + slotCount && !this.mergeItemStack(itemStack, 4, 30, false))
+ {
+ return null;
+ }
+ }
+ else if (!this.mergeItemStack(itemStack, slotCount, 36 + slotCount, false))
+ {
+ return null;
+ }
+
+ if (itemStack.stackSize == 0)
+ {
+ slot.putStack((ItemStack) null);
+ }
+ else
+ {
+ slot.onSlotChanged();
+ }
+
+ if (itemStack.stackSize == var2.stackSize)
+ {
+ return null;
+ }
+
+ slot.onPickupFromSlot(par1EntityPlayer, itemStack);
+ }
+
+ return var2;
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fusion/RenderPlasmaHeater.java b/atomic/src/main/scala/resonantinduction/atomic/fusion/RenderPlasmaHeater.java
new file mode 100644
index 000000000..b41700cdc
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fusion/RenderPlasmaHeater.java
@@ -0,0 +1,45 @@
+package resonantinduction.atomic.fusion;
+
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.model.AdvancedModelLoader;
+import net.minecraftforge.client.model.IModelCustom;
+
+import org.lwjgl.opengl.GL11;
+
+import resonant.lib.render.RenderTaggedTile;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.Reference;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class RenderPlasmaHeater extends RenderTaggedTile
+{
+ public static final IModelCustom MODEL = AdvancedModelLoader.loadModel(Reference.MODEL_DIRECTORY + "fusionReactor.tcn");
+ public static final ResourceLocation TEXTURE = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "fusionReactor.png");
+
+ @Override
+ public void renderTileEntityAt(TileEntity t, double x, double y, double z, float f)
+ {
+ TilePlasmaHeater tileEntity = (TilePlasmaHeater) t;
+
+ if (tileEntity.worldObj != null)
+ {
+ super.renderTileEntityAt(t, x, y, z, f);
+ }
+
+ GL11.glPushMatrix();
+ GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5);
+
+ bindTexture(TEXTURE);
+
+ GL11.glPushMatrix();
+ GL11.glRotated(Math.toDegrees(tileEntity.rotation), 0, 1, 0);
+ MODEL.renderOnly("rrot", "srot");
+ GL11.glPopMatrix();
+
+ MODEL.renderAllExcept("rrot", "srot");
+ GL11.glPopMatrix();
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fusion/TileElectromagnet.java b/atomic/src/main/scala/resonantinduction/atomic/fusion/TileElectromagnet.java
new file mode 100644
index 000000000..48f9f3244
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fusion/TileElectromagnet.java
@@ -0,0 +1,101 @@
+package resonantinduction.atomic.fusion;
+
+import java.util.List;
+
+import net.minecraft.client.renderer.texture.IconRegister;
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Icon;
+import net.minecraft.world.IBlockAccess;
+import resonant.api.IElectromagnet;
+import resonant.lib.content.module.TileBase;
+import resonant.lib.content.module.TileRender;
+import resonant.lib.utility.ConnectedTextureRenderer;
+import resonant.lib.prefab.item.ItemBlockMetadata;
+import resonantinduction.core.Reference;
+import universalelectricity.api.UniversalElectricity;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** Electromagnet block */
+public class TileElectromagnet extends TileBase implements IElectromagnet
+{
+ private static Icon iconTop, iconGlass;
+
+ public TileElectromagnet()
+ {
+ super(UniversalElectricity.machine);
+ blockResistance = 20;
+ isOpaqueCube = false;
+ itemBlock = ItemBlockMetadata.class;
+ }
+
+ @Override
+ public Icon getIcon(int side, int metadata)
+ {
+ if (metadata == 1)
+ {
+ return iconGlass;
+ }
+
+ if (side == 0 || side == 1)
+ {
+ return iconTop;
+ }
+
+ return super.getIcon(side, metadata);
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public void registerIcons(IconRegister iconRegister)
+ {
+ super.registerIcons(iconRegister);
+ iconTop = iconRegister.registerIcon(domain + textureName + "_top");
+ iconGlass = iconRegister.registerIcon(domain + "electromagnetGlass");
+ }
+
+ @Override
+ public int metadataDropped(int meta, int fortune)
+ {
+ return meta;
+ }
+
+ @Override
+ public boolean canUpdate()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean shouldSideBeRendered(IBlockAccess access, int x, int y, int z, int side)
+ {
+ return true; // access.getBlockId(x, y, z) == blockID() && access.getBlockMetadata(x, y, z) == 1 ? false : super.shouldSideBeRendered(access, x, y, z, side);
+ }
+
+ @Override
+ public int getRenderBlockPass()
+ {
+ return 0;
+ }
+
+ @Override
+ public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List)
+ {
+ par3List.add(new ItemStack(par1, 1, 0));
+ par3List.add(new ItemStack(par1, 1, 1));
+ }
+
+ @Override
+ public boolean isRunning()
+ {
+ return true;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ protected TileRender newRenderer()
+ {
+ return new ConnectedTextureRenderer(this, Reference.PREFIX + "atomic_edge");
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fusion/TilePlasma.java b/atomic/src/main/scala/resonantinduction/atomic/fusion/TilePlasma.java
new file mode 100644
index 000000000..cb0bed3d3
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fusion/TilePlasma.java
@@ -0,0 +1,112 @@
+package resonantinduction.atomic.fusion;
+
+import java.util.ArrayList;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.material.Material;
+import net.minecraft.entity.Entity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.DamageSource;
+import net.minecraft.world.IBlockAccess;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.common.MinecraftForge;
+import resonant.api.event.PlasmaEvent.SpawnPlasmaEvent;
+import resonant.lib.config.Config;
+import resonant.lib.content.module.TileBase;
+import resonant.lib.prefab.vector.Cuboid;
+import resonant.lib.thermal.ThermalGrid;
+import universalelectricity.api.vector.Vector3;
+import universalelectricity.api.vector.VectorWorld;
+
+public class TilePlasma extends TileBase
+{
+ @Config
+ public static int plasmaMaxTemperature = 1000000;
+ private float temperature = plasmaMaxTemperature;
+
+ public TilePlasma()
+ {
+ super(Material.lava);
+ textureName = "plasma";
+ isOpaqueCube = false;
+ }
+
+ @Override
+ public int getLightValue(IBlockAccess access)
+ {
+ return 7;
+ }
+
+ @Override
+ public boolean isSolid(IBlockAccess access, int side)
+ {
+ return false;
+ }
+
+ @Override
+ public Iterable getCollisionBoxes()
+ {
+ return new ArrayList();
+ }
+
+ @Override
+ public ArrayList getDrops(int metadata, int fortune)
+ {
+ return new ArrayList();
+ }
+
+ @Override
+ public int getRenderBlockPass()
+ {
+ return 1;
+ }
+
+ @Override
+ public void collide(Entity entity)
+ {
+ entity.attackEntityFrom(DamageSource.inFire, 100);
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+ ThermalGrid.addTemperature(new VectorWorld(this), (temperature - ThermalGrid.getTemperature(new VectorWorld(this))) * 0.1f);
+
+ if (ticks % 20 == 0)
+ {
+ temperature /= 1.5;
+
+ if (temperature <= plasmaMaxTemperature / 10)
+ {
+ worldObj.setBlock(xCoord, yCoord, zCoord, Block.fire.blockID, 0, 3);
+ return;
+ }
+
+ for (int i = 0; i < 6; i++)
+ {
+ // Randomize spread direction.
+ if (worldObj.rand.nextFloat() > 0.4)
+ {
+ continue;
+ }
+
+ Vector3 diDian = new Vector3(this);
+ diDian.translate(ForgeDirection.getOrientation(i));
+
+ TileEntity tileEntity = diDian.getTileEntity(worldObj);
+
+ if (!(tileEntity instanceof TilePlasma))
+ {
+ MinecraftForge.EVENT_BUS.post(new SpawnPlasmaEvent(worldObj, diDian.intX(), diDian.intY(), diDian.intZ(), (int) temperature));
+ }
+ }
+ }
+ }
+
+ public void setTemperature(int newTemperature)
+ {
+ temperature = newTemperature;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/fusion/TilePlasmaHeater.java b/atomic/src/main/scala/resonantinduction/atomic/fusion/TilePlasmaHeater.java
new file mode 100644
index 000000000..ed05ff074
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/fusion/TilePlasmaHeater.java
@@ -0,0 +1,225 @@
+package resonantinduction.atomic.fusion;
+
+import java.util.HashMap;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.packet.Packet;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTank;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidHandler;
+import resonant.api.ITagRender;
+import resonant.lib.config.Config;
+import resonant.lib.network.IPacketReceiver;
+import resonant.lib.network.PacketHandler;
+import resonant.lib.prefab.tile.TileElectrical;
+import resonant.lib.utility.LanguageUtility;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.ResonantInduction;
+import universalelectricity.api.energy.EnergyStorageHandler;
+import universalelectricity.api.energy.UnitDisplay;
+import universalelectricity.api.energy.UnitDisplay.Unit;
+import universalelectricity.api.vector.Vector3;
+
+import com.google.common.io.ByteArrayDataInput;
+
+public class TilePlasmaHeater extends TileElectrical implements IPacketReceiver, ITagRender, IFluidHandler
+{
+ public static final long DIAN = 10000000000L;
+
+ @Config
+ public static final int plasmaHeatAmount = 100;
+
+ public final FluidTank tankInputDeuterium = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 10);
+ public final FluidTank tankInputTritium = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 10);
+ public final FluidTank tankOutput = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 10);
+
+ public float rotation = 0;
+
+ public TilePlasmaHeater()
+ {
+ energy = new EnergyStorageHandler(DIAN, DIAN / 20);
+ }
+
+ @Override
+ public long onReceiveEnergy(ForgeDirection from, long receive, boolean doReceive)
+ {
+ if (tankInputDeuterium.getFluidAmount() > 0 && tankInputTritium.getFluidAmount() > 0)
+ {
+ return super.onReceiveEnergy(from, receive, doReceive);
+ }
+
+ return 0;
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+
+ rotation += energy.getEnergy() / 10000f;
+
+ if (!worldObj.isRemote)
+ {
+ if (energy.checkExtract())
+ {
+ if (tankInputDeuterium.getFluidAmount() >= plasmaHeatAmount && tankInputTritium.getFluidAmount() >= plasmaHeatAmount)
+ {
+ tankInputDeuterium.drain(plasmaHeatAmount, true);
+ tankInputTritium.drain(plasmaHeatAmount, true);
+ tankOutput.fill(new FluidStack(Atomic.FLUID_PLASMA, plasmaHeatAmount), true);
+ energy.extractEnergy();
+ }
+ }
+ }
+
+ if (ticks % 80 == 0)
+ {
+ PacketHandler.sendPacketToClients(getDescriptionPacket(), worldObj, new Vector3(this), 25);
+ }
+ }
+
+ @Override
+ public Packet getDescriptionPacket()
+ {
+ NBTTagCompound nbt = new NBTTagCompound();
+ writeToNBT(nbt);
+ return ResonantInduction.PACKET_TILE.getPacket(this, nbt);
+ }
+
+ @Override
+ public void onReceivePacket(ByteArrayDataInput data, EntityPlayer player, Object... extra)
+ {
+ try
+ {
+ readFromNBT(PacketHandler.readNBTTagCompound(data));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /** Reads a tile entity from NBT. */
+ @Override
+ public void readFromNBT(NBTTagCompound nbt)
+ {
+ super.readFromNBT(nbt);
+ NBTTagCompound deuterium = nbt.getCompoundTag("tankInputDeuterium");
+ tankInputDeuterium.setFluid(FluidStack.loadFluidStackFromNBT(deuterium));
+ NBTTagCompound tritium = nbt.getCompoundTag("tankInputTritium");
+ tankInputTritium.setFluid(FluidStack.loadFluidStackFromNBT(tritium));
+ NBTTagCompound output = nbt.getCompoundTag("tankOutput");
+ tankOutput.setFluid(FluidStack.loadFluidStackFromNBT(output));
+ }
+
+ /** Writes a tile entity to NBT. */
+ @Override
+ public void writeToNBT(NBTTagCompound nbt)
+ {
+ super.writeToNBT(nbt);
+
+ if (tankInputDeuterium.getFluid() != null)
+ {
+ NBTTagCompound compound = new NBTTagCompound();
+ tankInputDeuterium.getFluid().writeToNBT(compound);
+ nbt.setTag("tankInputDeuterium", compound);
+ }
+ if (tankInputTritium.getFluid() != null)
+ {
+ NBTTagCompound compound = new NBTTagCompound();
+ tankInputTritium.getFluid().writeToNBT(compound);
+ nbt.setTag("tankInputTritium", compound);
+ }
+ if (tankOutput.getFluid() != null)
+ {
+ NBTTagCompound compound = new NBTTagCompound();
+ tankOutput.getFluid().writeToNBT(compound);
+ nbt.setTag("tankOutput", compound);
+ }
+ }
+
+ @Override
+ public float addInformation(HashMap map, EntityPlayer player)
+ {
+ if (energy != null)
+ {
+ map.put(LanguageUtility.getLocal("tooltip.energy") + ": " + UnitDisplay.getDisplay(energy.getEnergy(), Unit.JOULES), 0xFFFFFF);
+ }
+
+ if (tankInputDeuterium.getFluidAmount() > 0)
+ {
+ map.put(LanguageUtility.getLocal("fluid.deuterium") + ": " + tankInputDeuterium.getFluidAmount() + " L", 0xFFFFFF);
+ }
+
+ if (tankInputTritium.getFluidAmount() > 0)
+ {
+ map.put(LanguageUtility.getLocal("fluid.tritium") + ": " + tankInputTritium.getFluidAmount() + " L", 0xFFFFFF);
+ }
+
+ if (tankOutput.getFluidAmount() > 0)
+ {
+ map.put(LanguageUtility.getLocal("fluid.plasma") + ": " + tankOutput.getFluidAmount() + " L", 0xFFFFFF);
+ }
+
+ return 1.5f;
+ }
+
+ @Override
+ public long onExtractEnergy(ForgeDirection from, long extract, boolean doExtract)
+ {
+ return 0;
+ }
+
+ @Override
+ public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
+ {
+ if (resource.isFluidEqual(Atomic.FLUIDSTACK_DEUTERIUM))
+ {
+ return tankInputDeuterium.fill(resource, doFill);
+ }
+
+ if (resource.isFluidEqual(Atomic.FLUIDSTACK_TRITIUM))
+ {
+ return tankInputTritium.fill(resource, doFill);
+ }
+
+ return 0;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
+ {
+ return drain(from, resource.amount, doDrain);
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
+ {
+ return tankOutput.drain(maxDrain, doDrain);
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid)
+ {
+ return fluid.getID() == Atomic.FLUID_DEUTERIUM.getID() || fluid.getID() == Atomic.FLUID_TRITIUM.getID();
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid)
+ {
+ return fluid == Atomic.FLUID_PLASMA;
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection from)
+ {
+ return new FluidTankInfo[]
+ { tankInputDeuterium.getInfo(), tankInputTritium.getInfo(), tankOutput.getInfo() };
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/BlockAccelerator.java b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/BlockAccelerator.java
new file mode 100644
index 000000000..0b229d6be
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/BlockAccelerator.java
@@ -0,0 +1,37 @@
+package resonantinduction.atomic.particle.accelerator;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import resonant.lib.prefab.block.BlockRotatable;
+import resonantinduction.atomic.Atomic;
+import universalelectricity.api.UniversalElectricity;
+
+/** Accelerator block */
+public class BlockAccelerator extends BlockRotatable
+{
+ public BlockAccelerator(int id)
+ {
+ super(id, UniversalElectricity.machine);
+
+ }
+
+ @Override
+ public boolean onMachineActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer, int side, float hitX, float hitY, float hitZ)
+ {
+ int metadata = par1World.getBlockMetadata(x, y, z);
+
+ if (!par1World.isRemote)
+ {
+ par5EntityPlayer.openGui(Atomic.INSTANCE, 0, par1World, x, y, z);
+ }
+
+ return true;
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(World var1)
+ {
+ return new TileAccelerator();
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/ContainerAccelerator.java b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/ContainerAccelerator.java
new file mode 100644
index 000000000..fc9a8ed6a
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/ContainerAccelerator.java
@@ -0,0 +1,79 @@
+package resonantinduction.atomic.particle.accelerator;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.inventory.Slot;
+import net.minecraft.inventory.SlotFurnace;
+import net.minecraft.item.ItemStack;
+import resonant.lib.gui.ContainerBase;
+import resonantinduction.atomic.Atomic;
+
+/** Accelerator container */
+public class ContainerAccelerator extends ContainerBase
+{
+ private TileAccelerator tileEntity;
+
+ public ContainerAccelerator(InventoryPlayer par1InventoryPlayer, TileAccelerator tileEntity)
+ {
+ super(tileEntity);
+ this.tileEntity = tileEntity;
+ // Inputs
+ addSlotToContainer(new Slot(tileEntity, 0, 132, 26));
+ addSlotToContainer(new Slot(tileEntity, 1, 132, 51));
+ // Output
+ addSlotToContainer(new SlotFurnace(par1InventoryPlayer.player, tileEntity, 2, 132, 75));
+ addSlotToContainer(new SlotFurnace(par1InventoryPlayer.player, tileEntity, 3, 106, 75));
+ addPlayerInventory(par1InventoryPlayer.player);
+ }
+
+ /** Called to transfer a stack from one inventory to the other eg. when shift clicking. */
+ @Override
+ public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par1)
+ {
+ ItemStack var2 = null;
+ Slot var3 = (Slot) this.inventorySlots.get(par1);
+
+ if (var3 != null && var3.getHasStack())
+ {
+ ItemStack itemStack = var3.getStack();
+ var2 = itemStack.copy();
+
+ if (par1 > 2)
+ {
+ if (itemStack.itemID == Atomic.itemCell.itemID)
+ {
+ if (!this.mergeItemStack(itemStack, 1, 2, false))
+ {
+ return null;
+ }
+ }
+ else if (!this.mergeItemStack(itemStack, 0, 1, false))
+ {
+ return null;
+ }
+ }
+ else if (!this.mergeItemStack(itemStack, 3, 36 + 3, false))
+ {
+ return null;
+ }
+
+ if (itemStack.stackSize == 0)
+ {
+ var3.putStack((ItemStack) null);
+ }
+ else
+ {
+ var3.onSlotChanged();
+ }
+
+ if (itemStack.stackSize == var2.stackSize)
+ {
+ return null;
+ }
+
+ var3.onPickupFromSlot(par1EntityPlayer, itemStack);
+ }
+
+ return var2;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/EntityParticle.java b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/EntityParticle.java
new file mode 100644
index 000000000..0ff4487e9
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/EntityParticle.java
@@ -0,0 +1,326 @@
+package resonantinduction.atomic.particle.accelerator;
+
+import java.util.List;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLiving;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.world.ChunkCoordIntPair;
+import net.minecraft.world.World;
+import net.minecraftforge.common.ForgeChunkManager;
+import net.minecraftforge.common.ForgeChunkManager.Ticket;
+import net.minecraftforge.common.ForgeChunkManager.Type;
+import net.minecraftforge.common.ForgeDirection;
+import resonant.api.IElectromagnet;
+import resonant.lib.prefab.poison.PoisonRadiation;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.Reference;
+import universalelectricity.api.vector.Vector3;
+import universalelectricity.api.vector.VectorHelper;
+
+import com.google.common.io.ByteArrayDataInput;
+import com.google.common.io.ByteArrayDataOutput;
+
+import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
+
+/** The particle entity used to determine the particle acceleration. */
+public class EntityParticle extends Entity implements IEntityAdditionalSpawnData
+{
+ private static final int MOVE_TICK_RATE = 20;
+ public Ticket updateTicket;
+ public boolean didParticleCollide = false;
+ private int lastTurn = 60;
+ private Vector3 movementVector = new Vector3();
+ private ForgeDirection movementDirection = ForgeDirection.NORTH;
+
+ public EntityParticle(World par1World)
+ {
+ super(par1World);
+ this.setSize(0.3f, 0.3f);
+ this.renderDistanceWeight = 4f;
+ this.ignoreFrustumCheck = true;
+ }
+
+ public EntityParticle(World world, Vector3 pos, Vector3 movementVec, ForgeDirection dir)
+ {
+ this(world);
+ this.setPosition(pos.x, pos.y, pos.z);
+ this.movementVector = movementVec;
+ this.movementDirection = dir;
+ }
+
+ public static boolean canRenderAcceleratedParticle(World world, Vector3 pos)
+ {
+ if (pos.getBlockID(world) != 0)
+ {
+ return false;
+ }
+
+ for (int i = 0; i <= 1; i++)
+ {
+ ForgeDirection dir = ForgeDirection.getOrientation(i);
+
+ if (!isElectromagnet(world, pos, dir))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean isElectromagnet(World world, Vector3 position, ForgeDirection dir)
+ {
+ Vector3 checkPos = position.clone().translate(dir);
+ TileEntity tile = checkPos.getTileEntity(world);
+
+ if (tile instanceof IElectromagnet)
+ {
+ return ((IElectromagnet) tile).isRunning();
+
+ }
+ return false;
+ }
+
+ @Override
+ public void writeSpawnData(ByteArrayDataOutput data)
+ {
+ data.writeInt(this.movementVector.intX());
+ data.writeInt(this.movementVector.intY());
+ data.writeInt(this.movementVector.intZ());
+ data.writeInt(this.movementDirection.ordinal());
+ }
+
+ @Override
+ public void readSpawnData(ByteArrayDataInput data)
+ {
+ this.movementVector.x = data.readInt();
+ this.movementVector.y = data.readInt();
+ this.movementVector.z = data.readInt();
+ this.movementDirection = ForgeDirection.getOrientation(data.readInt());
+ }
+
+ @Override
+ protected void entityInit()
+ {
+ this.dataWatcher.addObject(MOVE_TICK_RATE, (byte) 3);
+
+ if (this.updateTicket == null)
+ {
+ this.updateTicket = ForgeChunkManager.requestTicket(Atomic.INSTANCE, this.worldObj, Type.ENTITY);
+ this.updateTicket.getModData();
+ this.updateTicket.bindEntity(this);
+ }
+ }
+
+ @Override
+ public void onUpdate()
+ {
+ /** Play sound fxs. */
+ if (this.ticksExisted % 10 == 0)
+ {
+ this.worldObj.playSoundAtEntity(this, Reference.PREFIX + "accelerator", 1f, (float) (0.6f + (0.4 * (this.getParticleVelocity() / TileAccelerator.clientParticleVelocity))));
+ }
+
+ /** Check if the accelerator tile entity exists. */
+ TileEntity t = this.worldObj.getBlockTileEntity(this.movementVector.intX(), this.movementVector.intY(), this.movementVector.intZ());
+
+ if (!(t instanceof TileAccelerator))
+ {
+ setDead();
+ return;
+ }
+
+ TileAccelerator tileEntity = (TileAccelerator) t;
+
+ if (tileEntity.entityParticle == null)
+ {
+ tileEntity.entityParticle = this;
+ }
+
+ for (int x = -1; x < 1; x++)
+ {
+ for (int z = -1; z < 1; z++)
+ {
+ ForgeChunkManager.forceChunk(this.updateTicket, new ChunkCoordIntPair(((int) this.posX >> 4) + x, ((int) this.posZ >> 4) + z));
+ }
+ }
+
+ try
+ {
+ if (!this.worldObj.isRemote)
+ {
+ this.dataWatcher.updateObject(MOVE_TICK_RATE, (byte) this.movementDirection.ordinal());
+ }
+ else
+ {
+ this.movementDirection = ForgeDirection.getOrientation(this.dataWatcher.getWatchableObjectByte(MOVE_TICK_RATE));
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ double acceleration = 0.0006f;
+
+ if ((!isElectromagnet(worldObj, new Vector3(this), movementDirection.getRotation(ForgeDirection.UP)) || !isElectromagnet(worldObj, new Vector3(this), movementDirection.getRotation(ForgeDirection.DOWN))) && this.lastTurn <= 0)
+ {
+ acceleration = turn();
+ this.motionX = 0;
+ this.motionY = 0;
+ this.motionZ = 0;
+ this.lastTurn = 40;
+ }
+
+ this.lastTurn--;
+
+ /** Checks if the current block condition allows the particle to exist */
+ if (!canRenderAcceleratedParticle(this.worldObj, new Vector3(this)) || this.isCollided)
+ {
+ explode();
+ return;
+ }
+
+ Vector3 dongLi = new Vector3();
+ dongLi.translate(this.movementDirection);
+ dongLi.scale(acceleration);
+ this.motionX = Math.min(dongLi.x + this.motionX, TileAccelerator.clientParticleVelocity);
+ this.motionY = Math.min(dongLi.y + this.motionY, TileAccelerator.clientParticleVelocity);
+ this.motionZ = Math.min(dongLi.z + this.motionZ, TileAccelerator.clientParticleVelocity);
+ this.isAirBorne = true;
+
+ this.lastTickPosX = this.posX;
+ this.lastTickPosY = this.posY;
+ this.lastTickPosZ = this.posZ;
+
+ this.moveEntity(this.motionX, this.motionY, this.motionZ);
+
+ this.setPosition(this.posX, this.posY, this.posZ);
+
+ if (this.lastTickPosX == this.posX && this.lastTickPosY == this.posY && this.lastTickPosZ == this.posZ && this.getParticleVelocity() <= 0 && this.lastTurn <= 0)
+ {
+ this.setDead();
+ }
+
+ this.worldObj.spawnParticle("portal", this.posX, this.posY, this.posZ, 0, 0, 0);
+ this.worldObj.spawnParticle("largesmoke", this.posX, this.posY, this.posZ, 0, 0, 0);
+
+ float radius = 0.5f;
+
+ AxisAlignedBB bounds = AxisAlignedBB.getBoundingBox(this.posX - radius, this.posY - radius, this.posZ - radius, this.posX + radius, this.posY + radius, this.posZ + radius);
+ List entitiesNearby = this.worldObj.getEntitiesWithinAABB(Entity.class, bounds);
+
+ if (entitiesNearby.size() > 1)
+ {
+ this.explode();
+ return;
+ }
+ }
+
+ /** Try to move the particle left or right depending on which side is empty.
+ *
+ * @return The new velocity. */
+ private double turn()
+ {
+ ForgeDirection zuoFangXiang = VectorHelper.getOrientationFromSide(this.movementDirection, ForgeDirection.EAST);
+ Vector3 zuoBian = new Vector3(this).floor();
+ zuoBian.translate(zuoFangXiang);
+
+ ForgeDirection youFangXiang = VectorHelper.getOrientationFromSide(this.movementDirection, ForgeDirection.WEST);
+ Vector3 youBian = new Vector3(this).floor();
+ youBian.translate(youFangXiang);
+
+ if (zuoBian.getBlockID(this.worldObj) == 0)
+ {
+ this.movementDirection = zuoFangXiang;
+ }
+ else if (youBian.getBlockID(this.worldObj) == 0)
+ {
+ this.movementDirection = youFangXiang;
+ }
+ else
+ {
+ setDead();
+ return 0;
+ }
+
+ this.setPosition(Math.floor(this.posX) + 0.5, Math.floor(this.posY) + 0.5, Math.floor(this.posZ) + 0.5);
+
+ return this.getParticleVelocity() - (this.getParticleVelocity() / Math.min(Math.max(70 * this.getParticleVelocity(), 4), 30));
+
+ }
+
+ public void explode()
+ {
+ this.worldObj.playSoundAtEntity(this, Reference.PREFIX + "antimatter", 1.5f, 1f - this.worldObj.rand.nextFloat() * 0.3f);
+
+ if (!this.worldObj.isRemote)
+ {
+ if (this.getParticleVelocity() > TileAccelerator.clientParticleVelocity / 2)
+ {
+ /* Check for nearby particles and if colliding with another one, drop strange matter. */
+ float radius = 1f;
+
+ AxisAlignedBB bounds = AxisAlignedBB.getBoundingBox(this.posX - radius, this.posY - radius, this.posZ - radius, this.posX + radius, this.posY + radius, this.posZ + radius);
+ List entitiesNearby = this.worldObj.getEntitiesWithinAABB(EntityParticle.class, bounds);
+
+ if (entitiesNearby.size() > 0)
+ {
+ didParticleCollide = true;
+ setDead();
+ return;
+ }
+ }
+
+ this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float) this.getParticleVelocity() * 2.5f, true);
+ }
+
+ float radius = 6;
+
+ AxisAlignedBB bounds = AxisAlignedBB.getBoundingBox(this.posX - radius, this.posY - radius, this.posZ - radius, this.posX + radius, this.posY + radius, this.posZ + radius);
+ List livingNearby = this.worldObj.getEntitiesWithinAABB(EntityLiving.class, bounds);
+
+ for (EntityLiving entity : livingNearby)
+ {
+ PoisonRadiation.INSTANCE.poisonEntity(new Vector3(entity), entity);
+ }
+
+ setDead();
+ }
+
+ public double getParticleVelocity()
+ {
+ return Math.abs(this.motionX) + Math.abs(this.motionY) + Math.abs(this.motionZ);
+ }
+
+ @Override
+ public void applyEntityCollision(Entity par1Entity)
+ {
+ this.explode();
+ }
+
+ @Override
+ public void setDead()
+ {
+ ForgeChunkManager.releaseTicket(this.updateTicket);
+ super.setDead();
+ }
+
+ @Override
+ protected void readEntityFromNBT(NBTTagCompound nbt)
+ {
+ this.movementVector = new Vector3(nbt.getCompoundTag("jiqi"));
+ ForgeDirection.getOrientation(nbt.getByte("fangXiang"));
+ }
+
+ @Override
+ protected void writeEntityToNBT(NBTTagCompound nbt)
+ {
+ nbt.setTag("jiqi", this.movementVector.writeToNBT(new NBTTagCompound()));
+ nbt.setByte("fangXiang", (byte) this.movementDirection.ordinal());
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/GuiAccelerator.java b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/GuiAccelerator.java
new file mode 100644
index 000000000..2499bf6a2
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/GuiAccelerator.java
@@ -0,0 +1,69 @@
+package resonantinduction.atomic.particle.accelerator;
+
+import net.minecraft.entity.player.InventoryPlayer;
+import resonant.lib.gui.GuiContainerBase;
+import universalelectricity.api.energy.UnitDisplay;
+import universalelectricity.api.energy.UnitDisplay.Unit;
+import universalelectricity.api.vector.Vector3;
+
+public class GuiAccelerator extends GuiContainerBase
+{
+ private TileAccelerator tileEntity;
+
+ private int containerWidth;
+ private int containerHeight;
+
+ public GuiAccelerator(InventoryPlayer par1InventoryPlayer, TileAccelerator tileEntity)
+ {
+ super(new ContainerAccelerator(par1InventoryPlayer, tileEntity));
+ this.tileEntity = tileEntity;
+ }
+
+ /** Draw the foreground layer for the GuiContainer (everything in front of the items) */
+ @Override
+ public void drawGuiContainerForegroundLayer(int x, int y)
+ {
+ this.fontRenderer.drawString(tileEntity.getInvName(), 40, 10, 4210752);
+
+ String status = "";
+ Vector3 position = new Vector3(this.tileEntity);
+ position.translate(this.tileEntity.getDirection().getOpposite());
+
+ if (!EntityParticle.canRenderAcceleratedParticle(this.tileEntity.worldObj, position))
+ {
+ status = "\u00a74Fail to emit; try rotating.";
+ }
+ else if (this.tileEntity.entityParticle != null && this.tileEntity.velocity > 0)
+ {
+ status = "\u00a76Accelerating";
+ }
+ else
+ {
+ status = "\u00a72Idle";
+ }
+
+ this.fontRenderer.drawString("Velocity: " + Math.round((this.tileEntity.velocity / TileAccelerator.clientParticleVelocity) * 100) + "%", 8, 27, 4210752);
+ this.fontRenderer.drawString("Energy Used:", 8, 38, 4210752);
+ this.fontRenderer.drawString(UnitDisplay.getDisplay(this.tileEntity.totalEnergyConsumed, Unit.JOULES), 8, 49, 4210752);
+ this.fontRenderer.drawString(UnitDisplay.getDisplay(TileAccelerator.energyPerTick * 20, Unit.WATT), 8, 60, 4210752);
+ this.fontRenderer.drawString(UnitDisplay.getDisplay(this.tileEntity.getVoltageInput(null), Unit.VOLTAGE), 8, 70, 4210752);
+ this.fontRenderer.drawString("Antimatter: " + this.tileEntity.antimatter + " mg", 8, 80, 4210752);
+ this.fontRenderer.drawString("Status:", 8, 90, 4210752);
+ this.fontRenderer.drawString(status, 8, 100, 4210752);
+ this.fontRenderer.drawString("Buffer: " + UnitDisplay.getDisplayShort(this.tileEntity.getEnergyHandler().getEnergy(), Unit.JOULES) + "/" + UnitDisplay.getDisplayShort(this.tileEntity.getEnergyHandler().getEnergyCapacity(), Unit.JOULES), 8, 110,
+ 4210752);
+ this.fontRenderer.drawString("Facing: " + this.tileEntity.getDirection().getOpposite(), 100, 123, 4210752);
+ }
+
+ /** Draw the background layer for the GuiContainer (everything behind the items) */
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float par1, int x, int y)
+ {
+ super.drawGuiContainerBackgroundLayer(par1, x, y);
+
+ this.drawSlot(131, 25);
+ this.drawSlot(131, 50);
+ this.drawSlot(131, 74);
+ this.drawSlot(105, 74);
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/ItemDarkMatter.java b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/ItemDarkMatter.java
new file mode 100644
index 000000000..9df2c4c00
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/ItemDarkMatter.java
@@ -0,0 +1,12 @@
+package resonantinduction.atomic.particle.accelerator;
+
+import resonantinduction.atomic.base.ItemCell;
+
+/** Strange matter cell */
+public class ItemDarkMatter extends ItemCell
+{
+ public ItemDarkMatter(int itemID)
+ {
+ super(itemID);
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/RenderParticle.java b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/RenderParticle.java
new file mode 100644
index 000000000..5f054fb51
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/RenderParticle.java
@@ -0,0 +1,95 @@
+package resonantinduction.atomic.particle.accelerator;
+
+import java.util.Random;
+
+import net.minecraft.client.renderer.RenderHelper;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.entity.Render;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.ResourceLocation;
+
+import org.lwjgl.opengl.GL11;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class RenderParticle extends Render
+{
+ @Override
+ public void doRender(Entity entity, double x, double y, double z, float var8, float var9)
+ {
+ Tessellator tessellator = Tessellator.instance;
+
+ /** Enderdragon Light */
+ float par2 = (entity.ticksExisted);
+
+ while (par2 > 200)
+ {
+ par2 -= 100;
+ }
+
+ RenderHelper.disableStandardItemLighting();
+ float var41 = (5 + par2) / 200.0F;
+ float var51 = 0.0F;
+
+ if (var41 > 0.8F)
+ {
+ var51 = (var41 - 0.8F) / 0.2F;
+ }
+
+ Random rand = new Random(432L);
+
+ GL11.glPushMatrix();
+ GL11.glTranslatef((float) x, (float) y, (float) z);
+ GL11.glScalef(0.15f, 0.15f, 0.15f);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glShadeModel(GL11.GL_SMOOTH);
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
+ GL11.glDisable(GL11.GL_ALPHA_TEST);
+ GL11.glEnable(GL11.GL_CULL_FACE);
+ GL11.glDepthMask(false);
+ GL11.glPushMatrix();
+ GL11.glTranslatef(0.0F, -1.0F, -2.0F);
+
+ for (int i1 = 0; i1 < (var41 + var41 * var41) / 2.0F * 60.0F; ++i1)
+ {
+ GL11.glRotatef(rand.nextFloat() * 360.0F, 1.0F, 0.0F, 0.0F);
+ GL11.glRotatef(rand.nextFloat() * 360.0F, 0.0F, 1.0F, 0.0F);
+ GL11.glRotatef(rand.nextFloat() * 360.0F, 0.0F, 0.0F, 1.0F);
+ GL11.glRotatef(rand.nextFloat() * 360.0F, 1.0F, 0.0F, 0.0F);
+ GL11.glRotatef(rand.nextFloat() * 360.0F, 0.0F, 1.0F, 0.0F);
+ GL11.glRotatef(rand.nextFloat() * 360.0F + var41 * 90.0F, 0.0F, 0.0F, 1.0F);
+ tessellator.startDrawing(6);
+ float var81 = rand.nextFloat() * 20.0F + 5.0F + var51 * 10.0F;
+ float var91 = rand.nextFloat() * 2.0F + 1.0F + var51 * 2.0F;
+ tessellator.setColorRGBA_I(16777215, (int) (255.0F * (1.0F - var51)));
+ tessellator.addVertex(0.0D, 0.0D, 0.0D);
+ tessellator.setColorRGBA_I(0, 0);
+ tessellator.addVertex(-0.866D * var91, var81, -0.5F * var91);
+ tessellator.addVertex(0.866D * var91, var81, -0.5F * var91);
+ tessellator.addVertex(0.0D, var81, 1.0F * var91);
+ tessellator.addVertex(-0.866D * var91, var81, -0.5F * var91);
+ tessellator.draw();
+ }
+
+ GL11.glPopMatrix();
+ GL11.glDepthMask(true);
+ GL11.glDisable(GL11.GL_CULL_FACE);
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glShadeModel(GL11.GL_FLAT);
+ GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ GL11.glEnable(GL11.GL_ALPHA_TEST);
+ RenderHelper.enableStandardItemLighting();
+ GL11.glPopMatrix();
+ }
+
+ @Override
+ protected ResourceLocation getEntityTexture(Entity entity)
+ {
+ return null;
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/TileAccelerator.java b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/TileAccelerator.java
new file mode 100644
index 000000000..01d22c781
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/accelerator/TileAccelerator.java
@@ -0,0 +1,358 @@
+package resonantinduction.atomic.particle.accelerator;
+
+import net.minecraft.block.Block;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.packet.Packet;
+import net.minecraftforge.common.ForgeDirection;
+import resonant.api.IElectromagnet;
+import resonant.api.IRotatable;
+import resonant.lib.network.Synced;
+import resonant.lib.prefab.tile.TileElectricalInventory;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.atomic.particle.fulmination.ItemAntimatter;
+import resonantinduction.core.Reference;
+import resonantinduction.core.ResonantInduction;
+import resonantinduction.core.Settings;
+import universalelectricity.api.electricity.IVoltageInput;
+import universalelectricity.api.energy.EnergyStorageHandler;
+import universalelectricity.api.energy.IEnergyInterface;
+import universalelectricity.api.vector.Vector3;
+import cpw.mods.fml.common.network.PacketDispatcher;
+import cpw.mods.fml.common.network.Player;
+
+/** Accelerator TileEntity */
+public class TileAccelerator extends TileElectricalInventory implements IElectromagnet, IRotatable, IInventory, ISidedInventory, IVoltageInput
+{
+ /** Joules required per ticks. */
+ public static final int energyPerTick = 4800000;
+
+ /** User client side to determine the velocity of the particle. */
+ public static final float clientParticleVelocity = 0.9f;
+
+ /** The total amount of energy consumed by this particle. In Joules. */
+ @Synced
+ public float totalEnergyConsumed = 0;
+
+ /** The amount of anti-matter stored within the accelerator. Measured in milligrams. */
+ @Synced
+ public int antimatter;
+ public EntityParticle entityParticle;
+
+ @Synced
+ public float velocity;
+
+ @Synced
+ private long clientEnergy = 0;
+
+ private int lastSpawnTick = 0;
+
+ /** Multiplier that is used to give extra anti-matter based on density (hardness) of a given ore. */
+ private int antiMatterDensityMultiplyer = DENSITY_MULTIPLYER_DEFAULT;
+ private static final int DENSITY_MULTIPLYER_DEFAULT = 1;
+
+ public TileAccelerator()
+ {
+ energy = new EnergyStorageHandler(energyPerTick * 2, energyPerTick / 20);
+ maxSlots = 4;
+ antiMatterDensityMultiplyer = DENSITY_MULTIPLYER_DEFAULT;
+ }
+
+ @Override
+ public boolean canConnect(ForgeDirection direction, Object obj)
+ {
+ return obj instanceof IEnergyInterface;
+ }
+
+ @Override
+ public long onReceiveEnergy(ForgeDirection from, long receive, boolean doReceive)
+ {
+ if (doReceive)
+ {
+ totalEnergyConsumed += receive;
+ }
+
+ if (getStackInSlot(0) != null && (worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord) || worldObj.getBlockPowerInput(xCoord, yCoord, zCoord) > 0))
+ {
+ return super.onReceiveEnergy(from, receive, doReceive);
+ }
+
+ return 0;
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+
+ if (!worldObj.isRemote)
+ {
+ clientEnergy = energy.getEnergy();
+ velocity = 0;
+
+ // Calculate accelerated particle velocity if it is spawned.
+ if (entityParticle != null)
+ {
+ velocity = (float) entityParticle.getParticleVelocity();
+ }
+
+ // Check if item inside of empty cell slot is indeed an empty slot.
+ if (Atomic.isItemStackEmptyCell(getStackInSlot(1)))
+ {
+ // Check if there are any empty cells we can store anti-matter in.
+ if (getStackInSlot(1).stackSize > 0)
+ {
+ // Craft anti-matter item if there is enough anti-matter to actually do so.
+ if (antimatter >= 125)
+ {
+ if (getStackInSlot(2) != null)
+ {
+ // Increase the existing amount of anti-matter if stack already exists.
+ if (getStackInSlot(2).itemID == Atomic.itemAntimatter.itemID)
+ {
+ ItemStack newStack = getStackInSlot(2).copy();
+ if (newStack.stackSize < newStack.getMaxStackSize())
+ {
+ // Remove an empty cell which we will put the anti-matter into.
+ decrStackSize(1, 1);
+
+ // Remove anti-matter from internal reserve and increase stack count.
+ antimatter -= 125;
+ newStack.stackSize++;
+ setInventorySlotContents(2, newStack);
+ }
+ }
+ }
+ else
+ {
+ // Remove some of the internal reserves of anti-matter and use it to craft an individual item.
+ antimatter -= 125;
+ decrStackSize(1, 1);
+ setInventorySlotContents(2, new ItemStack(Atomic.itemAntimatter));
+ }
+ }
+ }
+ }
+
+ // Check if redstone signal is currently being applied.
+ if (worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord))
+ {
+ if (energy.checkExtract())
+ {
+ if (entityParticle == null)
+ {
+ // Creates a accelerated particle if one needs to exist (on world load for example or player login).
+ if (getStackInSlot(0) != null && lastSpawnTick >= 40)
+ {
+ Vector3 spawnAcceleratedParticle = new Vector3(this);
+ spawnAcceleratedParticle.translate(getDirection().getOpposite());
+ spawnAcceleratedParticle.translate(0.5f);
+
+ // Only render the particle if container within the proper environment for it.
+ if (EntityParticle.canRenderAcceleratedParticle(worldObj, spawnAcceleratedParticle))
+ {
+ // Spawn the particle.
+ totalEnergyConsumed = 0;
+ entityParticle = new EntityParticle(worldObj, spawnAcceleratedParticle, new Vector3(this), getDirection().getOpposite());
+ worldObj.spawnEntityInWorld(entityParticle);
+
+ // Grabs input block hardness if available, otherwise defaults are used.
+ CalculateParticleDensity();
+
+ // Decrease particle we want to collide.
+ decrStackSize(0, 1);
+ lastSpawnTick = 0;
+ }
+ }
+ }
+ else
+ {
+ if (entityParticle.isDead)
+ {
+ // On particle collision we roll the dice to see if dark-matter is generated.
+ if (entityParticle.didParticleCollide)
+ {
+ if (worldObj.rand.nextFloat() <= Settings.darkMatterSpawnChance)
+ {
+ incrStackSize(3, new ItemStack(Atomic.itemDarkMatter));
+ }
+ }
+
+ entityParticle = null;
+ }
+ else if (velocity > clientParticleVelocity)
+ {
+ // Play sound of anti-matter being created.
+ worldObj.playSoundEffect(xCoord, yCoord, zCoord, Reference.PREFIX + "antimatter", 2f, 1f - worldObj.rand.nextFloat() * 0.3f);
+
+ // Create anti-matter in the internal reserve.
+ int generatedAntimatter = 5 + worldObj.rand.nextInt(antiMatterDensityMultiplyer);
+ antimatter += generatedAntimatter;
+ // AtomicScience.LOGGER.info("[Particle Accelerator] Generated " + String.valueOf(generatedAntimatter) + " mg of anti-matter.");
+
+ // Reset energy consumption levels and destroy accelerated particle.
+ totalEnergyConsumed = 0;
+ entityParticle.setDead();
+ entityParticle = null;
+ }
+
+ // Plays sound of particle accelerating past the speed based on total velocity at the time of anti-matter creation.
+ if (entityParticle != null)
+ {
+ worldObj.playSoundEffect(xCoord, yCoord, zCoord, Reference.PREFIX + "accelerator", 1.5f, (float) (0.6f + (0.4 * (entityParticle.getParticleVelocity()) / TileAccelerator.clientParticleVelocity)));
+ }
+ }
+
+ energy.extractEnergy();
+ }
+ else
+ {
+ if (entityParticle != null)
+ {
+ entityParticle.setDead();
+ }
+
+ entityParticle = null;
+ }
+ }
+ else
+ {
+ if (entityParticle != null)
+ {
+ entityParticle.setDead();
+ }
+
+ entityParticle = null;
+ }
+
+ if (ticks % 5 == 0)
+ {
+ for (EntityPlayer player : getPlayersUsing())
+ {
+ PacketDispatcher.sendPacketToPlayer(getDescriptionPacket(), (Player) player);
+ }
+ }
+
+ lastSpawnTick++;
+ }
+ }
+
+ private void CalculateParticleDensity()
+ {
+ ItemStack itemToAccelerate = this.getStackInSlot(0);
+ if (itemToAccelerate != null)
+ {
+ // Calculate block density multiplier if ore dictionary block.
+ antiMatterDensityMultiplyer = DENSITY_MULTIPLYER_DEFAULT;
+ try
+ {
+ Block potentialBlock = Block.blocksList[itemToAccelerate.getItem().itemID];
+ if (potentialBlock != null)
+ {
+ // Prevent negative numbers and disallow zero for density multiplier.
+ antiMatterDensityMultiplyer = (int) Math.abs(potentialBlock.blockHardness);
+ if (antiMatterDensityMultiplyer <= 0)
+ {
+ antiMatterDensityMultiplyer = 1;
+ }
+
+ // AtomicScience.LOGGER.info("[Particle Accelerator] " + String.valueOf(potentialBlock.getUnlocalizedName()) + " Hardness: " + String.valueOf(antiMatterDensityMultiplyer));
+ }
+ }
+ catch (Exception err)
+ {
+ antiMatterDensityMultiplyer = DENSITY_MULTIPLYER_DEFAULT;
+ // AtomicScience.LOGGER.info("[Particle Accelerator] Attempted to query Minecraft block-list with value out of index.");
+ }
+ }
+ }
+
+ @Override
+ public Packet getDescriptionPacket()
+ {
+ return ResonantInduction.PACKET_ANNOTATION.getPacket(this);
+ }
+
+ /** Reads a tile entity from NBT. */
+ @Override
+ public void readFromNBT(NBTTagCompound par1NBTTagCompound)
+ {
+ super.readFromNBT(par1NBTTagCompound);
+ totalEnergyConsumed = par1NBTTagCompound.getFloat("totalEnergyConsumed");
+ antimatter = par1NBTTagCompound.getInteger("antimatter");
+ }
+
+ /** Writes a tile entity to NBT. */
+ @Override
+ public void writeToNBT(NBTTagCompound par1NBTTagCompound)
+ {
+ super.writeToNBT(par1NBTTagCompound);
+ par1NBTTagCompound.setFloat("totalEnergyConsumed", totalEnergyConsumed);
+ par1NBTTagCompound.setInteger("antimatter", antimatter);
+ }
+
+ @Override
+ public long getVoltageInput(ForgeDirection dir)
+ {
+ return 1000;
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(int side)
+ {
+ return new int[]
+ { 0, 1, 2, 3 };
+ }
+
+ @Override
+ public boolean canInsertItem(int slotID, ItemStack itemStack, int j)
+ {
+ return isItemValidForSlot(slotID, itemStack) && slotID != 2 && slotID != 3;
+ }
+
+ @Override
+ public boolean canExtractItem(int slotID, ItemStack itemstack, int j)
+ {
+ return slotID == 2 || slotID == 3;
+ }
+
+ @Override
+ public boolean isItemValidForSlot(int i, ItemStack itemStack)
+ {
+ switch (i)
+ {
+ case 0:
+ return true;
+ case 1:
+ return Atomic.isItemStackEmptyCell(itemStack);
+ case 2:
+ return itemStack.getItem() instanceof ItemAntimatter;
+ case 3:
+ return itemStack.getItem() instanceof ItemDarkMatter;
+ }
+
+ return false;
+ }
+
+ @Override
+ public long onExtractEnergy(ForgeDirection from, long extract, boolean doExtract)
+ {
+ return 0;
+ }
+
+ @Override
+ public void onWrongVoltage(ForgeDirection direction, long voltage)
+ {
+
+ }
+
+ @Override
+ public boolean isRunning()
+ {
+ return true;
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/fulmination/FulminationHandler.java b/atomic/src/main/scala/resonantinduction/atomic/particle/fulmination/FulminationHandler.java
new file mode 100644
index 000000000..8c75218a5
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/fulmination/FulminationHandler.java
@@ -0,0 +1,80 @@
+package resonantinduction.atomic.particle.fulmination;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+import net.minecraft.util.Vec3;
+import net.minecraftforge.event.ForgeSubscribe;
+import resonant.api.explosion.ExplosionEvent.DoExplosionEvent;
+import resonantinduction.atomic.Atomic;
+import universalelectricity.api.vector.Vector3;
+
+/** Atomic Science Event Handling. */
+public class FulminationHandler
+{
+ public static final FulminationHandler INSTANCE = new FulminationHandler();
+
+ public static final List list = new ArrayList();
+
+ public void register(TileFulmination tileEntity)
+ {
+ if (!list.contains(tileEntity))
+ {
+ list.add(tileEntity);
+ }
+ }
+
+ public void unregister(TileFulmination tileEntity)
+ {
+ list.remove(tileEntity);
+ }
+
+ @ForgeSubscribe
+ public void BaoZha(DoExplosionEvent evt)
+ {
+ if (evt.iExplosion != null)
+ {
+ if (evt.iExplosion.getRadius() > 0 && evt.iExplosion.getEnergy() > 0)
+ {
+ HashSet avaliableGenerators = new HashSet();
+
+ for (TileFulmination tileEntity : FulminationHandler.list)
+ {
+ if (tileEntity != null)
+ {
+ if (!tileEntity.isInvalid())
+ {
+ Vector3 tileDiDian = new Vector3(tileEntity);
+ tileDiDian.translate(0.5f);
+ double juLi = tileDiDian.distance(new Vector3(evt.x, evt.y, evt.z));
+
+ if (juLi <= evt.iExplosion.getRadius() && juLi > 0)
+ {
+ float miDu = evt.world.getBlockDensity(Vec3.createVectorHelper(evt.x, evt.y, evt.z), Atomic.blockFulmination.getCollisionBoundingBoxFromPool(evt.world, tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord));
+
+ if (miDu < 1)
+ {
+ avaliableGenerators.add(tileEntity);
+ }
+ }
+ }
+ }
+ }
+
+ final float totalEnergy = evt.iExplosion.getEnergy();
+ final float maxEnergyPerGenerator = totalEnergy / avaliableGenerators.size();
+
+ for (TileFulmination tileEntity : avaliableGenerators)
+ {
+ float density = evt.world.getBlockDensity(Vec3.createVectorHelper(evt.x, evt.y, evt.z), Atomic.blockFulmination.getCollisionBoundingBoxFromPool(evt.world, tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord));
+ double juLi = new Vector3(tileEntity).distance(new Vector3(evt.x, evt.y, evt.z));
+
+ long energy = (long) Math.min(maxEnergyPerGenerator, maxEnergyPerGenerator / (juLi / evt.iExplosion.getRadius()));
+ energy = (long) Math.max((1 - density) * energy, 0);
+ tileEntity.getEnergyHandler().receiveEnergy(energy, true);
+ }
+ }
+ }
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/fulmination/ItemAntimatter.java b/atomic/src/main/scala/resonantinduction/atomic/particle/fulmination/ItemAntimatter.java
new file mode 100644
index 000000000..f24afb6bf
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/fulmination/ItemAntimatter.java
@@ -0,0 +1,144 @@
+package resonantinduction.atomic.particle.fulmination;
+
+import java.util.List;
+
+import net.minecraft.client.renderer.texture.IconRegister;
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLiving;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.Icon;
+import net.minecraft.world.Explosion;
+import net.minecraft.world.World;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.event.ForgeSubscribe;
+import net.minecraftforge.event.entity.item.ItemExpireEvent;
+import resonant.api.explosion.ExplosionEvent.DoExplosionEvent;
+import resonant.api.explosion.IExplosion;
+import resonant.lib.flag.FlagRegistry;
+import resonant.lib.prefab.poison.PoisonRadiation;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.atomic.base.ItemCell;
+import resonantinduction.core.Reference;
+import resonantinduction.core.ResonantInduction;
+import resonantinduction.core.Settings;
+import universalelectricity.api.vector.Vector3;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/* Antimatter Cell */
+public class ItemAntimatter extends ItemCell
+{
+ private Icon iconGram;
+
+ public ItemAntimatter(int itemID)
+ {
+ super(itemID);
+ this.setMaxDamage(0);
+ this.setHasSubtypes(true);
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public void registerIcons(IconRegister iconRegister)
+ {
+ this.itemIcon = iconRegister.registerIcon(this.getUnlocalizedName().replace("item.", "") + "_milligram");
+ this.iconGram = iconRegister.registerIcon(this.getUnlocalizedName().replace("item.", "") + "_gram");
+ }
+
+ @Override
+ public Icon getIconFromDamage(int metadata)
+ {
+ if (metadata >= 1)
+ {
+ return this.iconGram;
+ }
+ else
+ {
+ return this.itemIcon;
+ }
+ }
+
+ @Override
+ public void getSubItems(int id, CreativeTabs par2CreativeTabs, List par3List)
+ {
+ par3List.add(new ItemStack(id, 1, 0));
+ par3List.add(new ItemStack(id, 1, 1));
+ }
+
+ @Override
+ public int getEntityLifespan(ItemStack itemStack, World world)
+ {
+ return 160;
+ }
+
+ @ForgeSubscribe
+ public void baoZhaEvent(ItemExpireEvent evt)
+ {
+ if (evt.entityItem != null)
+ {
+ ItemStack itemStack = evt.entityItem.getEntityItem();
+
+ if (itemStack != null)
+ {
+ if (itemStack.itemID == this.itemID)
+ {
+ evt.entityItem.worldObj.playSoundEffect(evt.entityItem.posX, evt.entityItem.posY, evt.entityItem.posZ, Reference.PREFIX + "antimatter", 3f, 1f - evt.entityItem.worldObj.rand.nextFloat() * 0.3f);
+
+ if (!evt.entityItem.worldObj.isRemote)
+ {
+ if (!FlagRegistry.getModFlag(FlagRegistry.DEFAULT_NAME).containsValue(evt.entityItem.worldObj, Atomic.BAN_ANTIMATTER_POWER, "true", new Vector3(evt.entityItem)))
+ {
+ IExplosion explosive = new BzFanWuSu(evt.entity.worldObj, evt.entityItem, evt.entityItem.posX, evt.entityItem.posY, evt.entityItem.posZ, 4, itemStack.getItemDamage());
+ MinecraftForge.EVENT_BUS.post(new DoExplosionEvent(evt.entityItem.worldObj, explosive));
+ evt.entityItem.worldObj.createExplosion(evt.entityItem, evt.entityItem.posX, evt.entityItem.posY, evt.entityItem.posZ, explosive.getRadius(), true);
+ ResonantInduction.LOGGER.fine("Antimatter cell detonated at: " + evt.entityItem.posX + ", " + evt.entityItem.posY + ", " + evt.entityItem.posZ);
+
+ final int radius = 20;
+ AxisAlignedBB bounds = AxisAlignedBB.getBoundingBox(evt.entityItem.posX - radius, evt.entityItem.posY - radius, evt.entityItem.posZ - radius, evt.entityItem.posX + radius, evt.entityItem.posY + radius, evt.entityItem.posZ
+ + radius);
+ List entitiesNearby = evt.entityItem.worldObj.getEntitiesWithinAABB(EntityLiving.class, bounds);
+
+ for (EntityLiving entity : entitiesNearby)
+ {
+ PoisonRadiation.INSTANCE.poisonEntity(new Vector3(entity), entity);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static class BzFanWuSu extends Explosion implements IExplosion
+ {
+ private int tier;
+
+ public BzFanWuSu(World par1World, Entity par2Entity, double x, double y, double z, float size, int tier)
+ {
+ super(par1World, par2Entity, x, y, z, size + 2 * tier);
+ this.tier = tier;
+ }
+
+ @Override
+ public float getRadius()
+ {
+ return this.explosionSize;
+ }
+
+ @Override
+ public long getEnergy()
+ {
+ return (long) ((2000000000000000L + (2000000000000000L * 9 * tier)) * Settings.fulminationOutputMultiplier);
+
+ }
+
+ @Override
+ public void explode()
+ {
+ this.doExplosionA();
+ this.doExplosionB(true);
+ }
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/fulmination/TileFulmination.java b/atomic/src/main/scala/resonantinduction/atomic/particle/fulmination/TileFulmination.java
new file mode 100644
index 000000000..b56d680ba
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/fulmination/TileFulmination.java
@@ -0,0 +1,82 @@
+package resonantinduction.atomic.particle.fulmination;
+
+import java.util.EnumSet;
+
+import net.minecraft.block.material.Material;
+import net.minecraftforge.common.ForgeDirection;
+import resonant.lib.utility.ConnectedTextureRenderer;
+import resonant.lib.content.module.TileRender;
+import resonant.lib.prefab.tile.TileElectrical;
+import resonantinduction.core.Reference;
+import universalelectricity.api.electricity.IVoltageOutput;
+import universalelectricity.api.energy.EnergyStorageHandler;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** Fulmination TileEntity */
+public class TileFulmination extends TileElectrical implements IVoltageOutput
+{
+ private static final long DIAN = 10000000000000L;
+
+ public TileFulmination()
+ {
+ super(Material.iron);
+ energy = new EnergyStorageHandler(DIAN);
+ blockHardness = 10;
+ blockResistance = 25000;
+ }
+
+ @Override
+ public void initiate()
+ {
+ super.initiate();
+ FulminationHandler.INSTANCE.register(this);
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+ produce();
+ // Slowly lose energy.
+ energy.extractEnergy(1, true);
+ }
+
+ @Override
+ public void invalidate()
+ {
+ FulminationHandler.INSTANCE.unregister(this);
+ super.initiate();
+ }
+
+ @Override
+ public long onReceiveEnergy(ForgeDirection from, long receive, boolean doReceive)
+ {
+ return 0;
+ }
+
+ @Override
+ public EnumSet getInputDirections()
+ {
+ return EnumSet.noneOf(ForgeDirection.class);
+ }
+
+ @Override
+ public EnumSet getOutputDirections()
+ {
+ return EnumSet.allOf(ForgeDirection.class);
+ }
+
+ @Override
+ public long getVoltageOutput(ForgeDirection side)
+ {
+ return 10000000000L;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ protected TileRender newRenderer()
+ {
+ return new ConnectedTextureRenderer(this, Reference.PREFIX + "atomic_edge");
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/ContainerQuantumAssembler.java b/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/ContainerQuantumAssembler.java
new file mode 100644
index 000000000..2d17eba21
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/ContainerQuantumAssembler.java
@@ -0,0 +1,111 @@
+package resonantinduction.atomic.particle.quantum;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.inventory.Container;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import resonantinduction.atomic.Atomic;
+
+/* Atomic assembler container */
+public class ContainerQuantumAssembler extends Container
+{
+ private TileQuantumAssembler tileEntity;
+
+ public ContainerQuantumAssembler(InventoryPlayer par1InventoryPlayer, TileQuantumAssembler tileEntity)
+ {
+ this.tileEntity = tileEntity;
+ this.addSlotToContainer(new Slot(tileEntity, 0, 80, 40));
+ this.addSlotToContainer(new Slot(tileEntity, 1, 53, 56));
+ this.addSlotToContainer(new Slot(tileEntity, 2, 107, 56));
+ this.addSlotToContainer(new Slot(tileEntity, 3, 53, 88));
+ this.addSlotToContainer(new Slot(tileEntity, 4, 107, 88));
+ this.addSlotToContainer(new Slot(tileEntity, 5, 80, 103));
+ this.addSlotToContainer(new Slot(tileEntity, 6, 80, 72));
+
+ int var3;
+
+ for (var3 = 0; var3 < 3; ++var3)
+ {
+ for (int var4 = 0; var4 < 9; ++var4)
+ {
+ this.addSlotToContainer(new Slot(par1InventoryPlayer, var4 + var3 * 9 + 9, 8 + var4 * 18, 148 + var3 * 18));
+ }
+ }
+
+ for (var3 = 0; var3 < 9; ++var3)
+ {
+ this.addSlotToContainer(new Slot(par1InventoryPlayer, var3, 8 + var3 * 18, 206));
+ }
+
+ this.tileEntity.getPlayersUsing().add(par1InventoryPlayer.player);
+ tileEntity.openChest();
+ }
+
+ @Override
+ public void onContainerClosed(EntityPlayer entityplayer)
+ {
+ super.onContainerClosed(entityplayer);
+ this.tileEntity.getPlayersUsing().remove(entityplayer);
+ }
+
+ @Override
+ public boolean canInteractWith(EntityPlayer par1EntityPlayer)
+ {
+ return this.tileEntity.isUseableByPlayer(par1EntityPlayer);
+ }
+
+ /** Called to transfer a stack from one inventory to the other eg. when shift clicking. */
+ @Override
+ public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par1)
+ {
+ ItemStack var2 = null;
+ Slot var3 = (Slot) this.inventorySlots.get(par1);
+
+ if (var3 != null && var3.getHasStack())
+ {
+ ItemStack itemStack = var3.getStack();
+ var2 = itemStack.copy();
+
+ if (par1 > 6)
+ {
+ if (itemStack.itemID == Atomic.itemDarkMatter.itemID)
+ {
+ if (!this.mergeItemStack(itemStack, 0, 6, false))
+ {
+ return null;
+ }
+ }
+ else if (!this.getSlot(6).getHasStack())
+ {
+ if (!this.mergeItemStack(itemStack, 6, 7, false))
+ {
+ return null;
+ }
+ }
+ }
+ else if (!this.mergeItemStack(itemStack, 7, 36 + 7, false))
+ {
+ return null;
+ }
+
+ if (itemStack.stackSize == 0)
+ {
+ var3.putStack((ItemStack) null);
+ }
+ else
+ {
+ var3.onSlotChanged();
+ }
+
+ if (itemStack.stackSize == var2.stackSize)
+ {
+ return null;
+ }
+
+ var3.onPickupFromSlot(par1EntityPlayer, itemStack);
+ }
+
+ return var2;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/GuiQuantumAssembler.java b/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/GuiQuantumAssembler.java
new file mode 100644
index 000000000..5de6fede6
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/GuiQuantumAssembler.java
@@ -0,0 +1,66 @@
+package resonantinduction.atomic.particle.quantum;
+
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.util.ResourceLocation;
+
+import org.lwjgl.opengl.GL11;
+
+import resonant.lib.gui.GuiContainerBase;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.Reference;
+import universalelectricity.api.energy.UnitDisplay.Unit;
+
+public class GuiQuantumAssembler extends GuiContainerBase
+{
+ public static final ResourceLocation TEXTURE = new ResourceLocation(Reference.DOMAIN, Atomic.GUI_TEXTURE_DIRECTORY + "gui_atomic_assembler.png");
+
+ private TileQuantumAssembler tileEntity;
+
+ private int containerWidth;
+ private int containerHeight;
+
+ public GuiQuantumAssembler(InventoryPlayer par1InventoryPlayer, TileQuantumAssembler tileEntity)
+ {
+ super(new ContainerQuantumAssembler(par1InventoryPlayer, tileEntity));
+ this.tileEntity = tileEntity;
+ this.ySize = 230;
+ }
+
+ /** Draw the foreground layer for the GuiContainer (everything in front of the items) */
+ @Override
+ public void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
+ {
+ this.fontRenderer.drawString(this.tileEntity.getInvName(), 65 - this.tileEntity.getInvName().length(), 6, 4210752);
+ String displayText = "";
+
+ if (this.tileEntity.time() > 0)
+ {
+ displayText = "Process: " + (int) (100 - ((float) this.tileEntity.time() / (float) this.tileEntity.MAX_TIME()) * 100) + "%";
+ }
+ else if (this.tileEntity.canProcess())
+ {
+ displayText = "Ready";
+ }
+ else
+ {
+ displayText = "Idle";
+ }
+
+ this.fontRenderer.drawString(displayText, 9, this.ySize - 106, 4210752);
+ this.renderUniversalDisplay(100, this.ySize - 94, this.tileEntity.getVoltageInput(null), mouseX, mouseY, Unit.VOLTAGE);
+ this.renderUniversalDisplay(8, this.ySize - 95, tileEntity.MAX_TIME(), mouseX, mouseY, Unit.WATT);
+ }
+
+ /** Draw the background layer for the GuiContainer (everything behind the items) */
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3)
+ {
+ this.mc.renderEngine.bindTexture(TEXTURE);
+ GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
+
+ this.containerWidth = (this.width - this.xSize) / 2;
+ this.containerHeight = (this.height - this.ySize) / 2;
+
+ this.drawTexturedModalRect(this.containerWidth, this.containerHeight, 0, 0, this.xSize, this.ySize);
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/RenderQuantumAssembler.java b/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/RenderQuantumAssembler.java
new file mode 100644
index 000000000..9d7d99344
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/RenderQuantumAssembler.java
@@ -0,0 +1,83 @@
+package resonantinduction.atomic.particle.quantum;
+
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.entity.RenderItem;
+import net.minecraft.client.renderer.entity.RenderManager;
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.model.AdvancedModelLoader;
+import net.minecraftforge.client.model.IModelCustom;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.lwjgl.opengl.GL11;
+
+import resonantinduction.core.Reference;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class RenderQuantumAssembler extends TileEntitySpecialRenderer
+{
+ public static final IModelCustom MODEL = AdvancedModelLoader.loadModel(Reference.MODEL_DIRECTORY + "quantumAssembler.tcn");
+ public static final ResourceLocation TEXTURE = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "quantumAssembler.png");
+
+ private final RenderBlocks renderBlocks = new RenderBlocks();
+
+ public void render(TileQuantumAssembler tileEntity, double x, double y, double z, float f)
+ {
+ GL11.glPushMatrix();
+ GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5);
+
+ final String[] hands = new String[]
+ { "Back Arm Upper", "Back Arm Lower", "Right Arm Upper", "Right Arm Lower", "Front Arm Upper", "Front Arm Lower", "Left Arm Upper", "Left Arm Lower" };
+ final String[] arms = new String[]
+ { "Middle Rotor Focus Lazer", "Middle Rotor Uppper Arm", "Middle Rotor Lower Arm", "Middle Rotor Arm Base", "Middle Rotor" };
+ final String[] largeArms = new String[]
+ { "Bottom Rotor Upper Arm", "Bottom Rotor Lower Arm", "Bottom Rotor Arm Base", "Bottom Rotor", "Bottom Rotor Resonator Arm" };
+
+ bindTexture(TEXTURE);
+
+ GL11.glPushMatrix();
+ GL11.glRotatef(-tileEntity.rotationYaw1(), 0, 1f, 0);
+ MODEL.renderOnly(hands);
+ MODEL.renderOnly("Resonance_Crystal");
+ GL11.glPopMatrix();
+
+ /** Small Laser Arm */
+ GL11.glPushMatrix();
+ GL11.glRotatef(tileEntity.rotationYaw2(), 0, 1f, 0);
+ MODEL.renderOnly(arms);
+
+ GL11.glPopMatrix();
+
+ /** Large Laser Arm */
+ GL11.glPushMatrix();
+ GL11.glRotatef(-tileEntity.rotationYaw3(), 0, 1f, 0);
+ MODEL.renderOnly(largeArms);
+ GL11.glPopMatrix();
+
+ MODEL.renderAllExcept(ArrayUtils.add(ArrayUtils.addAll(ArrayUtils.addAll(hands, arms), largeArms), "Resonance_Crystal"));
+ GL11.glPopMatrix();
+
+ /** Render the item */
+ RenderItem renderItem = ((RenderItem) RenderManager.instance.getEntityClassRenderObject(EntityItem.class));
+
+ GL11.glPushMatrix();
+
+ if (tileEntity.entityItem() != null)
+ {
+ renderItem.doRenderItem(tileEntity.entityItem(), x + 0.5, y + 0.4, z + 0.5, 0, 0);
+ }
+
+ GL11.glPopMatrix();
+
+ }
+
+ @Override
+ public void renderTileEntityAt(TileEntity tileEntity, double var2, double var4, double var6, float var8)
+ {
+ this.render((TileQuantumAssembler) tileEntity, var2, var4, var6, var8);
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/TileQuantumAssembler.scala b/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/TileQuantumAssembler.scala
new file mode 100644
index 000000000..ce11c5ac5
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/particle/quantum/TileQuantumAssembler.scala
@@ -0,0 +1,239 @@
+package resonantinduction.atomic.particle.quantum
+
+import resonantinduction.atomic
+import resonant.api.recipe.QuantumAssemblerRecipes
+import resonant.lib.network.IPacketReceiver
+import com.google.common.io.ByteArrayDataInput
+import cpw.mods.fml.common.network.PacketDispatcher
+import cpw.mods.fml.common.network.Player
+import net.minecraft.entity.item.EntityItem
+import net.minecraft.entity.player.EntityPlayer
+import net.minecraft.item.Item
+import net.minecraft.item.ItemStack
+import net.minecraft.nbt.NBTTagCompound
+import net.minecraft.network.packet.Packet
+import net.minecraftforge.common.ForgeDirection
+import universalelectricity.api.electricity.IVoltageInput
+import universalelectricity.api.energy.EnergyStorageHandler
+import resonant.lib.content.prefab.TraitInventory
+import net.minecraft.block.material.Material
+import universalelectricity.api.vector.Vector3
+import resonant.lib.prefab.tile.TileElectrical
+import resonantinduction.atomic.Atomic
+import resonantinduction.core.ResonantInduction
+import resonantinduction.core.Reference
+
+class TileQuantumAssembler extends TileElectrical(Material.iron) with TraitInventory with IPacketReceiver with IVoltageInput {
+ val ENERGY: Long = 10000000000000L
+ val MAX_TIME: Int = 20 * 120
+ var time: Int = 0
+ /**
+ * Used for rendering.
+ */
+ var rotationYaw1: Float = 0
+ var rotationYaw2: Float = 0
+ var rotationYaw3: Float = 0
+ /**
+ * Used for rendering.
+ */
+ var entityItem: EntityItem = null
+
+ energy = new EnergyStorageHandler(ENERGY)
+ maxSlots = 6 + 1
+ isOpaqueCube = false;
+ normalRender = false;
+ customItemRender = true;
+ textureName = "machine"
+
+ /**
+ * Called when the block is right clicked by the player
+ */
+ override def use(player: EntityPlayer, side: Int, hit: Vector3): Boolean =
+ {
+ if (!world().isRemote) {
+ player.openGui(Atomic.INSTANCE, 0, world, x, y, z)
+ return true
+ }
+
+ return true
+ }
+
+ override def updateEntity {
+ super.updateEntity
+ if (!this.worldObj.isRemote) {
+ if (this.canProcess) {
+ if (energy.checkExtract) {
+ if (this.time == 0) {
+ this.time = this.MAX_TIME
+ }
+ if (this.time > 0) {
+ this.time -= 1
+ if (this.time < 1) {
+ this.process
+ this.time = 0
+ }
+ } else {
+ this.time = 0
+ }
+ this.energy.extractEnergy(ENERGY, true)
+ }
+ } else {
+ this.time = 0
+ }
+ if (this.ticks % 10 == 0) {
+ import scala.collection.JavaConversions._
+ for (player <- this.getPlayersUsing) {
+ PacketDispatcher.sendPacketToPlayer(getDescriptionPacket, player.asInstanceOf[Player])
+ }
+ }
+ } else if (this.time > 0) {
+ if (this.ticks % 600 == 0) {
+ this.worldObj.playSoundEffect(this.xCoord, this.yCoord, this.zCoord, Reference.PREFIX + "assembler", 0.7f, 1f)
+ }
+ this.rotationYaw1 += 3
+ this.rotationYaw2 += 2
+ this.rotationYaw3 += 1
+ var itemStack: ItemStack = this.getStackInSlot(6)
+ if (itemStack != null) {
+ itemStack = itemStack.copy
+ itemStack.stackSize = 1
+ if (this.entityItem == null) {
+ this.entityItem = new EntityItem(this.worldObj, 0, 0, 0, itemStack)
+ } else if (!itemStack.isItemEqual(this.entityItem.getEntityItem)) {
+ this.entityItem = new EntityItem(this.worldObj, 0, 0, 0, itemStack)
+ }
+ this.entityItem.age += 1
+ } else {
+ this.entityItem = null
+ }
+ }
+ }
+
+ override def onReceiveEnergy(from: ForgeDirection, receive: Long, doReceive: Boolean): Long =
+ {
+ if (this.canProcess) {
+ return super.onReceiveEnergy(from, receive, doReceive)
+ }
+ return 0
+ }
+
+ def onReceivePacket(data: ByteArrayDataInput, player: EntityPlayer, extra: AnyRef*) {
+ try {
+ this.time = data.readInt
+ val itemID: Int = data.readInt
+ val itemAmount: Int = data.readInt
+ val itemMeta: Int = data.readInt
+ if (itemID != -1 && itemAmount != -1 && itemMeta != -1) {
+ this.setInventorySlotContents(6, new ItemStack(Item.itemsList(itemID), itemAmount, itemMeta))
+ }
+ } catch {
+ case e: Exception =>
+ {
+ e.printStackTrace
+ }
+ }
+ }
+
+ override def getDescriptionPacket: Packet =
+ {
+ if (this.getStackInSlot(6) != null) {
+ return ResonantInduction.PACKET_TILE.getPacket(this, Int.box(time), Int.box(getStackInSlot(6).itemID), Int.box(getStackInSlot(6).stackSize), Int.box(getStackInSlot(6).getItemDamage))
+ }
+ return ResonantInduction.PACKET_TILE.getPacket(this, Int.box(time), Int.box(-1), Int.box(-1), Int.box(-1))
+ }
+
+ override def openChest {
+ if (!this.worldObj.isRemote) {
+ import scala.collection.JavaConversions._
+ for (player <- this.getPlayersUsing) {
+ PacketDispatcher.sendPacketToPlayer(getDescriptionPacket, player.asInstanceOf[Player])
+ }
+ }
+ }
+
+ def canProcess: Boolean =
+ {
+ if (getStackInSlot(6) != null) {
+ if (QuantumAssemblerRecipes.hasItemStack(getStackInSlot(6))) {
+ {
+ var i: Int = 0
+ while (i < 6) {
+ {
+ if (getStackInSlot(i) == null) {
+ return false
+ }
+ if (getStackInSlot(i).itemID != Atomic.itemDarkMatter.itemID) {
+ return false
+ }
+ }
+ ({
+ i += 1;
+ i - 1
+ })
+ }
+ }
+ return getStackInSlot(6).stackSize < 64
+ }
+ }
+ return false
+ }
+
+ /**
+ * Turn one item from the furnace source stack into the appropriate smelted item in the furnace
+ * result stack
+ */
+ def process {
+ if (this.canProcess) {
+ {
+ var i: Int = 0
+ while (i < 5) {
+ {
+ if (getStackInSlot(i) != null) {
+ decrStackSize(i, 1)
+ }
+ }
+ ({
+ i += 1;
+ i - 1
+ })
+ }
+ }
+ if (getStackInSlot(6) != null) {
+ getStackInSlot(6).stackSize += 1
+ }
+ }
+ }
+
+ /**
+ * Reads a tile entity from NBT.
+ */
+ override def readFromNBT(par1NBTTagCompound: NBTTagCompound) {
+ super.readFromNBT(par1NBTTagCompound)
+ this.time = par1NBTTagCompound.getInteger("smeltingTicks")
+ }
+
+ /**
+ * Writes a tile entity to NBT.
+ */
+ override def writeToNBT(par1NBTTagCompound: NBTTagCompound) {
+ super.writeToNBT(par1NBTTagCompound)
+ par1NBTTagCompound.setInteger("smeltingTicks", this.time)
+ }
+
+ override def isItemValidForSlot(slotID: Int, itemStack: ItemStack): Boolean =
+ {
+ if (slotID == 6) {
+ return true
+ }
+ return itemStack.itemID == Atomic.itemDarkMatter.itemID
+ }
+
+ def getVoltageInput(from: ForgeDirection): Long =
+ {
+ return 1000
+ }
+
+ def onWrongVoltage(direction: ForgeDirection, voltage: Long) {
+ }
+
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/BlockChemicalExtractor.java b/atomic/src/main/scala/resonantinduction/atomic/process/BlockChemicalExtractor.java
new file mode 100644
index 000000000..49bca240f
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/BlockChemicalExtractor.java
@@ -0,0 +1,62 @@
+package resonantinduction.atomic.process;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import resonant.lib.prefab.block.BlockRotatable;
+import resonant.lib.render.block.BlockRenderingHandler;
+import resonantinduction.atomic.Atomic;
+import universalelectricity.api.UniversalElectricity;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** Chemical Extractor
+ *
+ * @author Calclavia */
+public class BlockChemicalExtractor extends BlockRotatable
+{
+ public BlockChemicalExtractor(int ID)
+ {
+ super(ID, UniversalElectricity.machine);
+ }
+
+ /** Called when the block is right clicked by the player */
+ @Override
+ public boolean onMachineActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer, int side, float hitX, float hitY, float hitZ)
+ {
+ int metadata = par1World.getBlockMetadata(x, y, z);
+
+ if (!par1World.isRemote)
+ {
+ par5EntityPlayer.openGui(Atomic.INSTANCE, 0, par1World, x, y, z);
+ return true;
+ }
+
+ return true;
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(World var1)
+ {
+ return new TileChemicalExtractor();
+ }
+
+ @Override
+ public boolean renderAsNormalBlock()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isOpaqueCube()
+ {
+ return false;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public int getRenderType()
+ {
+ return BlockRenderingHandler.ID;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/ContainerChemicalExtractor.java b/atomic/src/main/scala/resonantinduction/atomic/process/ContainerChemicalExtractor.java
new file mode 100644
index 000000000..88858a1c9
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/ContainerChemicalExtractor.java
@@ -0,0 +1,38 @@
+package resonantinduction.atomic.process;
+
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.inventory.Slot;
+import net.minecraft.inventory.SlotFurnace;
+import resonant.lib.gui.ContainerBase;
+import resonant.lib.prefab.slot.SlotEnergyItem;
+
+/** Chemical extractor container */
+public class ContainerChemicalExtractor extends ContainerBase
+{
+ private static final int slotCount = 5;
+ private TileChemicalExtractor tileEntity;
+
+ public ContainerChemicalExtractor(InventoryPlayer par1InventoryPlayer, TileChemicalExtractor tileEntity)
+ {
+ super(tileEntity);
+ this.tileEntity = tileEntity;
+ // Battery
+ addSlotToContainer(new SlotEnergyItem(tileEntity, 0, 80, 50));
+ // Process Input (Cell or Uranium)
+ addSlotToContainer(new Slot(tileEntity, 1, 53, 25));
+ // Process Output
+ addSlotToContainer(new SlotFurnace(par1InventoryPlayer.player, tileEntity, 2, 107, 25));
+
+ // Fluid input fill
+ addSlotToContainer(new Slot(tileEntity, 3, 25, 19));
+ // Fluid input drain
+ addSlotToContainer(new Slot(tileEntity, 4, 25, 50));
+
+ // Fluid output fill
+ addSlotToContainer(new Slot(tileEntity, 5, 135, 19));
+ // Fluid output drain
+ addSlotToContainer(new Slot(tileEntity, 6, 135, 50));
+
+ addPlayerInventory(par1InventoryPlayer.player);
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/ItemHazmat.java b/atomic/src/main/scala/resonantinduction/atomic/process/ItemHazmat.java
new file mode 100644
index 000000000..b2f547ef8
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/ItemHazmat.java
@@ -0,0 +1,54 @@
+package resonantinduction.atomic.process;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.item.EnumArmorMaterial;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemArmor;
+import net.minecraft.item.ItemStack;
+import resonant.api.armor.IAntiPoisonArmor;
+import resonantinduction.core.Reference;
+import resonantinduction.core.TabRI;
+
+/** Hazmat */
+public class ItemHazmat extends ItemArmor implements IAntiPoisonArmor
+{
+ public ItemHazmat(int par1, EnumArmorMaterial par2EnumArmorMaterial, int par3, int par4)
+ {
+ super(par1, par2EnumArmorMaterial, par3, par4);
+ this.setCreativeTab(TabRI.DEFAULT);
+ this.setMaxDamage(200000);
+ }
+
+ @Override
+ public Item setUnlocalizedName(String par1Str)
+ {
+ super.setUnlocalizedName(par1Str);
+ this.setTextureName(par1Str);
+ return this;
+ }
+
+ @Override
+ public String getArmorTexture(ItemStack stack, Entity entity, int slot, int layer)
+ {
+ return Reference.PREFIX + Reference.MODEL_DIRECTORY + "hazmat.png";
+ }
+
+ @Override
+ public boolean isProtectedFromPoison(ItemStack itemStack, EntityLivingBase entityLiving, String type)
+ {
+ return type.equalsIgnoreCase("radiation") || type.equalsIgnoreCase("chemical") || type.equalsIgnoreCase("contagious");
+ }
+
+ @Override
+ public void onProtectFromPoison(ItemStack itemStack, EntityLivingBase entityLiving, String type)
+ {
+ itemStack.damageItem(1, entityLiving);
+ }
+
+ @Override
+ public int getArmorType()
+ {
+ return this.armorType;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/RenderChemicalExtractor.java b/atomic/src/main/scala/resonantinduction/atomic/process/RenderChemicalExtractor.java
new file mode 100644
index 000000000..917938302
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/RenderChemicalExtractor.java
@@ -0,0 +1,47 @@
+package resonantinduction.atomic.process;
+
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.model.AdvancedModelLoader;
+
+import org.lwjgl.opengl.GL11;
+
+import resonant.lib.render.RenderUtility;
+import resonant.lib.render.model.TechneAdvancedModel;
+import resonantinduction.core.Reference;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class RenderChemicalExtractor extends TileEntitySpecialRenderer
+{
+ public static final TechneAdvancedModel MODEL = (TechneAdvancedModel) AdvancedModelLoader.loadModel(Reference.MODEL_DIRECTORY + "chemicalExtractor.tcn");
+ public static final ResourceLocation TEXTURE = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "chemicalExtractor.png");
+
+ public void render(TileChemicalExtractor tileEntity, double x, double y, double z, float f)
+ {
+ GL11.glPushMatrix();
+ GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5);
+
+ if (tileEntity.worldObj != null)
+ {
+ RenderUtility.rotateBlockBasedOnDirection(tileEntity.getDirection());
+ }
+
+ bindTexture(TEXTURE);
+
+ GL11.glPushMatrix();
+ MODEL.renderOnlyAroundPivot(Math.toDegrees(tileEntity.rotation), 0, 0, 1, "MAIN CHAMBER-ROTATES", "MAGNET 1-ROTATES", "MAGNET 2-ROTATES");
+ GL11.glPopMatrix();
+
+ MODEL.renderAllExcept("MAIN CHAMBER-ROTATES", "MAGNET 1-ROTATES", "MAGNET 2-ROTATES");
+ GL11.glPopMatrix();
+ }
+
+ @Override
+ public void renderTileEntityAt(TileEntity tileEntity, double var2, double var4, double var6, float var8)
+ {
+ this.render((TileChemicalExtractor) tileEntity, var2, var4, var6, var8);
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/TileChemicalExtractor.java b/atomic/src/main/scala/resonantinduction/atomic/process/TileChemicalExtractor.java
new file mode 100644
index 000000000..fbbb8be84
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/TileChemicalExtractor.java
@@ -0,0 +1,385 @@
+package resonantinduction.atomic.process;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.packet.Packet;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+import net.minecraftforge.fluids.FluidRegistry;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTank;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidHandler;
+import resonant.api.IRotatable;
+import resonant.lib.network.Synced;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.ResonantInduction;
+import resonantinduction.core.Settings;
+import universalelectricity.api.CompatibilityModule;
+import universalelectricity.api.electricity.IVoltageInput;
+import universalelectricity.api.energy.EnergyStorageHandler;
+import cpw.mods.fml.common.network.PacketDispatcher;
+import cpw.mods.fml.common.network.Player;
+
+/** Chemical extractor TileEntity */
+
+public class TileChemicalExtractor extends TileProcess implements ISidedInventory, IFluidHandler, IRotatable, IVoltageInput
+{
+ public static final int TICK_TIME = 20 * 14;
+ public static final int EXTRACT_SPEED = 100;
+ public static final long ENERGY = 5000;
+ @Synced
+ public final FluidTank inputTank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 10);
+ @Synced
+ public final FluidTank outputTank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 10);
+ // How many ticks has this item been extracting for?
+ @Synced
+ public int time = 0;
+ public float rotation = 0;
+
+ public TileChemicalExtractor()
+ {
+ energy = new EnergyStorageHandler(ENERGY * 2);
+ maxSlots = 7;
+ inputSlot = 1;
+ outputSlot = 2;
+ tankInputFillSlot = 3;
+ tankInputDrainSlot = 4;
+ tankOutputFillSlot = 5;
+ tankOutputDrainSlot = 6;
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+
+ if (time > 0)
+ {
+ rotation += 0.2f;
+ }
+
+ if (!worldObj.isRemote)
+ {
+ if (canUse())
+ {
+ discharge(getStackInSlot(0));
+
+ if (energy.checkExtract(ENERGY))
+ {
+ if (time == 0)
+ {
+ time = TICK_TIME;
+ }
+
+ if (time > 0)
+ {
+ time--;
+
+ if (time < 1)
+ {
+ if (!refineUranium())
+ {
+ if (!extractTritium())
+ {
+ extractDeuterium();
+ }
+ }
+
+ time = 0;
+ }
+ }
+ else
+ {
+ time = 0;
+ }
+ }
+
+ energy.extractEnergy(ENERGY, true);
+ }
+ else
+ {
+ time = 0;
+ }
+
+ if (ticks % 10 == 0)
+ {
+ for (EntityPlayer player : getPlayersUsing())
+ {
+ PacketDispatcher.sendPacketToPlayer(getDescriptionPacket(), (Player) player);
+ }
+ }
+ }
+ }
+
+ @Override
+ public Packet getDescriptionPacket()
+ {
+ return ResonantInduction.PACKET_ANNOTATION.getPacket(this);
+ }
+
+ public boolean canUse()
+ {
+ if (inputTank.getFluid() != null)
+ {
+ if (inputTank.getFluid().amount >= FluidContainerRegistry.BUCKET_VOLUME && Atomic.isItemStackUraniumOre(getStackInSlot(inputSlot)))
+ {
+ if (isItemValidForSlot(outputSlot, new ItemStack(Atomic.itemYellowCake)))
+ {
+ return true;
+ }
+ }
+
+ if (outputTank.getFluidAmount() < outputTank.getCapacity())
+ {
+ if (inputTank.getFluid().getFluid().getID() == Atomic.FLUID_DEUTERIUM.getID() && inputTank.getFluid().amount >= Settings.deutermiumPerTritium * EXTRACT_SPEED)
+ {
+ if (outputTank.getFluid() == null || Atomic.FLUIDSTACK_TRITIUM.equals(outputTank.getFluid()))
+ {
+ return true;
+ }
+ }
+
+ if (inputTank.getFluid().getFluid().getID() == FluidRegistry.WATER.getID() && inputTank.getFluid().amount >= Settings.waterPerDeutermium * EXTRACT_SPEED)
+ {
+ if (outputTank.getFluid() == null || Atomic.FLUIDSTACK_DEUTERIUM.equals(outputTank.getFluid()))
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /** Turn one item from the furnace source stack into the appropriate smelted item in the furnace result stack. */
+ public boolean refineUranium()
+ {
+ if (canUse())
+ {
+ if (Atomic.isItemStackUraniumOre(getStackInSlot(inputSlot)))
+ {
+ inputTank.drain(FluidContainerRegistry.BUCKET_VOLUME, true);
+ incrStackSize(outputSlot, new ItemStack(Atomic.itemYellowCake, 3));
+ decrStackSize(inputSlot, 1);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public boolean extractDeuterium()
+ {
+ if (canUse())
+ {
+ FluidStack drain = inputTank.drain(Settings.waterPerDeutermium * EXTRACT_SPEED, false);
+
+ if (drain != null && drain.amount >= 1 && drain.getFluid().getID() == FluidRegistry.WATER.getID())
+ {
+ if (outputTank.fill(new FluidStack(Atomic.FLUIDSTACK_DEUTERIUM, EXTRACT_SPEED), true) >= EXTRACT_SPEED)
+ {
+ inputTank.drain(Settings.waterPerDeutermium * EXTRACT_SPEED, true);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public boolean extractTritium()
+ {
+ if (canUse())
+ {
+ int waterUsage = Settings.deutermiumPerTritium;
+
+ FluidStack drain = inputTank.drain(Settings.deutermiumPerTritium * EXTRACT_SPEED, false);
+
+ if (drain != null && drain.amount >= 1 && drain.getFluid().getID() == Atomic.FLUID_DEUTERIUM.getID())
+ {
+ if (outputTank.fill(new FluidStack(Atomic.FLUIDSTACK_TRITIUM, EXTRACT_SPEED), true) >= EXTRACT_SPEED)
+ {
+ inputTank.drain(Settings.deutermiumPerTritium * EXTRACT_SPEED, true);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /** Reads a tile entity from NBT. */
+ @Override
+ public void readFromNBT(NBTTagCompound nbt)
+ {
+ super.readFromNBT(nbt);
+
+ time = nbt.getInteger("time");
+ NBTTagCompound water = nbt.getCompoundTag("inputTank");
+ inputTank.setFluid(FluidStack.loadFluidStackFromNBT(water));
+ NBTTagCompound deuterium = nbt.getCompoundTag("outputTank");
+ outputTank.setFluid(FluidStack.loadFluidStackFromNBT(deuterium));
+ }
+
+ /** Writes a tile entity to NBT. */
+ @Override
+ public void writeToNBT(NBTTagCompound nbt)
+ {
+ super.writeToNBT(nbt);
+ nbt.setInteger("time", time);
+
+ if (inputTank.getFluid() != null)
+ {
+ NBTTagCompound compound = new NBTTagCompound();
+ inputTank.getFluid().writeToNBT(compound);
+ nbt.setTag("inputTank", compound);
+ }
+
+ if (outputTank.getFluid() != null)
+ {
+ NBTTagCompound compound = new NBTTagCompound();
+ outputTank.getFluid().writeToNBT(compound);
+ nbt.setTag("outputTank", compound);
+ }
+ }
+
+ /** Tank Methods */
+ @Override
+ public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
+ {
+ if (resource != null && canFill(from, resource.getFluid()))
+ {
+ return inputTank.fill(resource, doFill);
+ }
+
+ return 0;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
+ {
+ return drain(from, resource.amount, doDrain);
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
+ {
+ return outputTank.drain(maxDrain, doDrain);
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid)
+ {
+ return FluidRegistry.WATER.getID() == fluid.getID() || Atomic.FLUID_DEUTERIUM.getID() == fluid.getID();
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid)
+ {
+ return outputTank.getFluid() != null && outputTank.getFluid().getFluid().getID() == fluid.getID();
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection from)
+ {
+ return new FluidTankInfo[]
+ { this.inputTank.getInfo(), this.outputTank.getInfo() };
+ }
+
+ @Override
+ public boolean isItemValidForSlot(int slotID, ItemStack itemStack)
+ {
+ // Water input for machine.
+ if (slotID == 0)
+ {
+ return CompatibilityModule.isHandler(itemStack.getItem());
+ }
+
+ if (slotID == 1)
+ {
+ return Atomic.isItemStackWaterCell(itemStack);
+ }
+
+ // Empty cell to be filled with deuterium or tritium.
+ if (slotID == 2)
+ {
+ return Atomic.isItemStackDeuteriumCell(itemStack) || Atomic.isItemStackTritiumCell(itemStack);
+ }
+
+ // Uranium to be extracted into yellowcake.
+ if (slotID == 3)
+ {
+ return Atomic.isItemStackEmptyCell(itemStack) || Atomic.isItemStackUraniumOre(itemStack) || Atomic.isItemStackDeuteriumCell(itemStack);
+ }
+
+ return false;
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(int side)
+ {
+ return new int[]
+ { 1, 2, 3 };
+ }
+
+ @Override
+ public boolean canInsertItem(int slotID, ItemStack itemStack, int side)
+ {
+ return this.isItemValidForSlot(slotID, itemStack);
+ }
+
+ @Override
+ public boolean canExtractItem(int slotID, ItemStack itemstack, int side)
+ {
+ return slotID == 2;
+ }
+
+ @Override
+ public long onExtractEnergy(ForgeDirection from, long extract, boolean doExtract)
+ {
+ return 0;
+ }
+
+ @Override
+ public long onReceiveEnergy(ForgeDirection from, long receive, boolean doReceive)
+ {
+ if (this.canUse())
+ {
+ return super.onReceiveEnergy(from, receive, doReceive);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ @Override
+ public long getVoltageInput(ForgeDirection from)
+ {
+ return 1000;
+ }
+
+ @Override
+ public void onWrongVoltage(ForgeDirection direction, long voltage)
+ {
+
+ }
+
+ @Override
+ public FluidTank getInputTank()
+ {
+ return inputTank;
+ }
+
+ @Override
+ public FluidTank getOutputTank()
+ {
+ return outputTank;
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/TileProcess.java b/atomic/src/main/scala/resonantinduction/atomic/process/TileProcess.java
new file mode 100644
index 000000000..a244ba797
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/TileProcess.java
@@ -0,0 +1,102 @@
+package resonantinduction.atomic.process;
+
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTank;
+import resonant.api.recipe.MachineRecipes;
+import resonant.api.recipe.RecipeResource;
+import resonant.lib.prefab.tile.TileElectricalInventory;
+
+/** General class for all machines that do traditional recipe processing
+ *
+ * @author Calclavia */
+public abstract class TileProcess extends TileElectricalInventory
+{
+ protected int inputSlot;
+ protected int outputSlot;
+
+ protected int tankInputFillSlot;
+ protected int tankInputDrainSlot;
+ protected int tankOutputFillSlot;
+ protected int tankOutputDrainSlot;
+
+ protected String machineName;
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+
+ if (getInputTank() != null)
+ {
+ fillOrDrainTank(tankInputFillSlot, tankInputDrainSlot, getInputTank());
+ }
+ if (getOutputTank() != null)
+ {
+ fillOrDrainTank(tankOutputFillSlot, tankOutputDrainSlot, getOutputTank());
+ }
+ }
+
+ /** Takes an fluid container item and try to fill the tank, dropping the remains in the output slot. */
+ public void fillOrDrainTank(int containerInput, int containerOutput, FluidTank tank)
+ {
+ ItemStack inputStack = getStackInSlot(containerInput);
+ ItemStack outputStack = getStackInSlot(containerOutput);
+
+ if (FluidContainerRegistry.isFilledContainer(inputStack))
+ {
+ FluidStack fluidStack = FluidContainerRegistry.getFluidForFilledItem(inputStack);
+ ItemStack result = inputStack.getItem().getContainerItemStack(inputStack);
+
+ if (result != null && tank.fill(fluidStack, false) >= fluidStack.amount && (outputStack == null || result.isItemEqual(outputStack)))
+ {
+ tank.fill(fluidStack, true);
+ decrStackSize(containerInput, 1);
+ incrStackSize(containerOutput, result);
+ }
+ }
+ else if (FluidContainerRegistry.isEmptyContainer(inputStack))
+ {
+ FluidStack avaliable = tank.getFluid();
+
+ if (avaliable != null)
+ {
+ ItemStack result = FluidContainerRegistry.fillFluidContainer(avaliable, inputStack);
+ FluidStack filled = FluidContainerRegistry.getFluidForFilledItem(result);
+
+ if (result != null && filled != null && (outputStack == null || result.isItemEqual(outputStack)))
+ {
+ decrStackSize(containerInput, 1);
+ incrStackSize(containerOutput, result);
+ tank.drain(filled.amount, true);
+ }
+ }
+ }
+ }
+
+ /** Gets the current result of the input set up.
+ *
+ * @return */
+ public RecipeResource[] getResults()
+ {
+ ItemStack inputStack = getStackInSlot(inputSlot);
+ RecipeResource[] mixedResult = MachineRecipes.INSTANCE.getOutput(machineName, inputStack, getInputTank().getFluid());
+
+ if (mixedResult.length > 0)
+ {
+ return mixedResult;
+ }
+
+ return MachineRecipes.INSTANCE.getOutput(machineName, inputStack);
+ }
+
+ public boolean hasResult()
+ {
+ return getResults().length > 0;
+ }
+
+ public abstract FluidTank getInputTank();
+
+ public abstract FluidTank getOutputTank();
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/fission/BlockCentrifuge.java b/atomic/src/main/scala/resonantinduction/atomic/process/fission/BlockCentrifuge.java
new file mode 100644
index 000000000..6a04f2637
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/fission/BlockCentrifuge.java
@@ -0,0 +1,61 @@
+package resonantinduction.atomic.process.fission;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import resonant.lib.prefab.block.BlockRotatable;
+import resonant.lib.render.block.BlockRenderingHandler;
+import resonantinduction.atomic.Atomic;
+import universalelectricity.api.UniversalElectricity;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** Centrifuge block */
+public class BlockCentrifuge extends BlockRotatable
+{
+ public BlockCentrifuge(int ID)
+ {
+ super(ID, UniversalElectricity.machine);
+
+ }
+
+ /** Called when the block is right clicked by the player */
+ @Override
+ public boolean onMachineActivated(World world, int x, int y, int z, EntityPlayer par5EntityPlayer, int side, float hitX, float hitY, float hitZ)
+ {
+ int metadata = world.getBlockMetadata(x, y, z);
+
+ if (!world.isRemote)
+ {
+ par5EntityPlayer.openGui(Atomic.INSTANCE, 0, world, x, y, z);
+ return true;
+ }
+
+ return true;
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(World var1)
+ {
+ return new TileCentrifuge();
+ }
+
+ @Override
+ public boolean renderAsNormalBlock()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isOpaqueCube()
+ {
+ return false;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public int getRenderType()
+ {
+ return BlockRenderingHandler.ID;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/fission/BlockNuclearBoiler.java b/atomic/src/main/scala/resonantinduction/atomic/process/fission/BlockNuclearBoiler.java
new file mode 100644
index 000000000..b8db81dc2
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/fission/BlockNuclearBoiler.java
@@ -0,0 +1,60 @@
+package resonantinduction.atomic.process.fission;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import resonant.lib.prefab.block.BlockRotatable;
+import resonant.lib.render.block.BlockRenderingHandler;
+import resonantinduction.atomic.Atomic;
+import universalelectricity.api.UniversalElectricity;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** Nuclear boiler block */
+public class BlockNuclearBoiler extends BlockRotatable
+{
+ public BlockNuclearBoiler(int ID)
+ {
+ super(ID, UniversalElectricity.machine);
+ }
+
+ /** Called when the block is right clicked by the player */
+ @Override
+ public boolean onMachineActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer, int side, float hitX, float hitY, float hitZ)
+ {
+ int metadata = par1World.getBlockMetadata(x, y, z);
+
+ if (!par1World.isRemote)
+ {
+ par5EntityPlayer.openGui(Atomic.INSTANCE, 0, par1World, x, y, z);
+ return true;
+ }
+
+ return true;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public int getRenderType()
+ {
+ return BlockRenderingHandler.ID;
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(World var1)
+ {
+ return new TileNuclearBoiler();
+ }
+
+ @Override
+ public boolean renderAsNormalBlock()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isOpaqueCube()
+ {
+ return false;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/fission/ContainerCentrifuge.java b/atomic/src/main/scala/resonantinduction/atomic/process/fission/ContainerCentrifuge.java
new file mode 100644
index 000000000..62e5526f3
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/fission/ContainerCentrifuge.java
@@ -0,0 +1,119 @@
+package resonantinduction.atomic.process.fission;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.inventory.Slot;
+import net.minecraft.inventory.SlotFurnace;
+import net.minecraft.item.ItemStack;
+import resonant.lib.gui.ContainerBase;
+import resonant.lib.prefab.slot.SlotEnergyItem;
+import resonantinduction.atomic.Atomic;
+
+/** Centrifuge container */
+public class ContainerCentrifuge extends ContainerBase
+{
+ private static final int slotCount = 4;
+ private TileCentrifuge tileEntity;
+
+ public ContainerCentrifuge(InventoryPlayer par1InventoryPlayer, TileCentrifuge tileEntity)
+ {
+ super(tileEntity);
+ this.tileEntity = tileEntity;
+ // Electric Item
+ this.addSlotToContainer(new SlotEnergyItem(tileEntity, 0, 131, 26));
+ // Uranium Gas Tank
+ this.addSlotToContainer(new Slot(tileEntity, 1, 25, 50));
+ // Output Uranium 235
+ this.addSlotToContainer(new SlotFurnace(par1InventoryPlayer.player, tileEntity, 2, 81, 26));
+ // Output Uranium 238
+ this.addSlotToContainer(new SlotFurnace(par1InventoryPlayer.player, tileEntity, 3, 101, 26));
+ this.addPlayerInventory(par1InventoryPlayer.player);
+ tileEntity.openChest();
+ }
+
+ @Override
+ public void onContainerClosed(EntityPlayer entityplayer)
+ {
+ super.onContainerClosed(entityplayer);
+ this.tileEntity.getPlayersUsing().remove(entityplayer);
+ }
+
+ @Override
+ public boolean canInteractWith(EntityPlayer par1EntityPlayer)
+ {
+ return this.tileEntity.isUseableByPlayer(par1EntityPlayer);
+ }
+
+ /** Called to transfer a stack from one inventory to the other eg. when shift clicking. */
+ @Override
+ public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par1)
+ {
+ ItemStack var2 = null;
+ Slot var3 = (Slot) this.inventorySlots.get(par1);
+
+ if (var3 != null && var3.getHasStack())
+ {
+ ItemStack itemStack = var3.getStack();
+ var2 = itemStack.copy();
+
+ if (par1 >= slotCount)
+ {
+ if (this.getSlot(0).isItemValid(itemStack))
+ {
+ if (!this.mergeItemStack(itemStack, 0, 1, false))
+ {
+ return null;
+ }
+ }
+ else if (Atomic.isItemStackUraniumOre(itemStack))
+ {
+ if (!this.mergeItemStack(itemStack, 1, 2, false))
+ {
+ return null;
+ }
+ }
+ else if (Atomic.isItemStackEmptyCell(itemStack))
+ {
+ if (!this.mergeItemStack(itemStack, 3, 4, false))
+ {
+ return null;
+ }
+ }
+ else if (par1 < 27 + slotCount)
+ {
+ if (!this.mergeItemStack(itemStack, 27 + slotCount, 36 + slotCount, false))
+ {
+ return null;
+ }
+ }
+ else if (par1 >= 27 + slotCount && par1 < 36 + slotCount && !this.mergeItemStack(itemStack, 4, 30, false))
+ {
+ return null;
+ }
+ }
+ else if (!this.mergeItemStack(itemStack, slotCount, 36 + slotCount, false))
+ {
+ return null;
+ }
+
+ if (itemStack.stackSize == 0)
+ {
+ var3.putStack((ItemStack) null);
+ }
+ else
+ {
+ var3.onSlotChanged();
+ }
+
+ if (itemStack.stackSize == var2.stackSize)
+ {
+ return null;
+ }
+
+ var3.onPickupFromSlot(par1EntityPlayer, itemStack);
+ }
+
+ return var2;
+ }
+
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/fission/GuiCentrifuge.java b/atomic/src/main/scala/resonantinduction/atomic/process/fission/GuiCentrifuge.java
new file mode 100644
index 000000000..7542f5528
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/fission/GuiCentrifuge.java
@@ -0,0 +1,72 @@
+package resonantinduction.atomic.process.fission;
+
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.util.StatCollector;
+import resonant.lib.gui.GuiContainerBase;
+import universalelectricity.api.energy.UnitDisplay.Unit;
+
+public class GuiCentrifuge extends GuiContainerBase
+{
+ private TileCentrifuge tileEntity;
+
+ public GuiCentrifuge(InventoryPlayer par1InventoryPlayer, TileCentrifuge tileEntity)
+ {
+ super(new ContainerCentrifuge(par1InventoryPlayer, tileEntity));
+ this.tileEntity = tileEntity;
+ }
+
+ /** Draw the foreground layer for the GuiContainer (everything in front of the items) */
+ @Override
+ public void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
+ {
+ this.fontRenderer.drawString(tileEntity.getInvName(), 60, 6, 4210752);
+
+ String displayText = "";
+
+ if (this.tileEntity.timer > 0)
+ {
+ displayText = "Processing";
+ }
+ else if (this.tileEntity.nengYong())
+ {
+ displayText = "Ready";
+ }
+ else
+ {
+ displayText = "Idle";
+ }
+
+ this.fontRenderer.drawString("Status: " + displayText, 70, 50, 4210752);
+
+ this.renderUniversalDisplay(8, 112, TileNuclearBoiler.DIAN * 20, mouseX, mouseY, Unit.WATT);
+ this.renderUniversalDisplay(100, 112, this.tileEntity.getVoltageInput(null), mouseX, mouseY, Unit.VOLTAGE);
+
+ this.fontRenderer.drawString("The centrifuge spins", 8, 75, 4210752);
+ this.fontRenderer.drawString("uranium hexafluoride gas into", 8, 85, 4210752);
+ this.fontRenderer.drawString("enriched uranium for fission.", 8, 95, 4210752);
+
+ this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752);
+
+ if (this.isPointInRegion(8, 18, this.meterWidth, this.meterHeight, mouseX, mouseY) && this.tileEntity.gasTank.getFluid() != null)
+ {
+ this.drawTooltip(mouseX - this.guiLeft, mouseY - this.guiTop + 10, this.tileEntity.gasTank.getFluid().getFluid().getLocalizedName(), this.tileEntity.gasTank.getFluid().amount + " L");
+ }
+ }
+
+ /** Draw the background layer for the GuiContainer (everything behind the items) */
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float par1, int x, int y)
+ {
+ super.drawGuiContainerBackgroundLayer(par1, x, y);
+
+ this.drawSlot(80, 25);
+ this.drawSlot(100, 25);
+ this.drawSlot(130, 25, SlotType.BATTERY);
+
+ this.drawBar(40, 26, (float) this.tileEntity.timer / (float) TileCentrifuge.SHI_JIAN);
+
+ // Uranium Gas
+ this.drawMeter(8, 18, (float) this.tileEntity.gasTank.getFluidAmount() / (float) this.tileEntity.gasTank.getCapacity(), this.tileEntity.gasTank.getFluid());
+ this.drawSlot(24, 49, SlotType.GAS);
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/fission/GuiChemicalExtractor.java b/atomic/src/main/scala/resonantinduction/atomic/process/fission/GuiChemicalExtractor.java
new file mode 100644
index 000000000..bf1ae2243
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/fission/GuiChemicalExtractor.java
@@ -0,0 +1,82 @@
+package resonantinduction.atomic.process.fission;
+
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.util.StatCollector;
+import resonant.lib.gui.GuiContainerBase;
+import resonantinduction.atomic.process.ContainerChemicalExtractor;
+import resonantinduction.atomic.process.TileChemicalExtractor;
+import universalelectricity.api.energy.UnitDisplay.Unit;
+
+public class GuiChemicalExtractor extends GuiContainerBase
+{
+ private TileChemicalExtractor tileEntity;
+
+ public GuiChemicalExtractor(InventoryPlayer par1InventoryPlayer, TileChemicalExtractor tileEntity)
+ {
+ super(new ContainerChemicalExtractor(par1InventoryPlayer, tileEntity));
+ this.tileEntity = tileEntity;
+ }
+
+ /** Draw the foreground layer for the GuiContainer (everything in front of the items) */
+ @Override
+ public void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
+ {
+ this.fontRenderer.drawString(tileEntity.getInvName(), 45, 6, 4210752);
+
+ this.renderUniversalDisplay(8, 112, TileChemicalExtractor.ENERGY * 20, mouseX, mouseY, Unit.WATT);
+ this.renderUniversalDisplay(100, 112, this.tileEntity.getVoltageInput(null), mouseX, mouseY, Unit.VOLTAGE);
+
+ this.fontRenderer.drawString("The extractor can extract", 8, 75, 4210752);
+ this.fontRenderer.drawString("uranium, deuterium and tritium.", 8, 85, 4210752);
+ this.fontRenderer.drawString("Place them in the input slot.", 8, 95, 4210752);
+
+ this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752);
+
+ if (this.isPointInRegion(8, 18, this.meterWidth, this.meterHeight, mouseX, mouseY) && this.tileEntity.inputTank.getFluid() != null)
+ {
+ if (this.tileEntity.inputTank.getFluid() != null)
+ {
+ this.drawTooltip(mouseX - this.guiLeft, mouseY - this.guiTop + 10, this.tileEntity.inputTank.getFluid().getFluid().getLocalizedName(), this.tileEntity.inputTank.getFluid().amount + " L");
+ }
+ }
+ if (this.isPointInRegion(154, 18, this.meterWidth, this.meterHeight, mouseX, mouseY) && this.tileEntity.outputTank.getFluid() != null)
+ {
+ if (this.tileEntity.outputTank.getFluid() != null)
+ {
+ this.drawTooltip(mouseX - this.guiLeft, mouseY - this.guiTop + 10, this.tileEntity.outputTank.getFluid().getFluid().getLocalizedName(), this.tileEntity.outputTank.getFluid().amount + " L");
+ }
+ }
+ if (this.isPointInRegion(134, 49, 18, 18, mouseX, mouseY))
+ {
+ if (this.tileEntity.getStackInSlot(4) == null)
+ {
+ // this.drawTooltip(x - this.guiLeft, y - this.guiTop + 10, "Place empty cells.");
+ }
+ }
+ if (this.isPointInRegion(52, 24, 18, 18, mouseX, mouseY))
+ {
+ if (this.tileEntity.outputTank.getFluidAmount() > 0 && this.tileEntity.getStackInSlot(3) == null)
+ {
+ this.drawTooltip(mouseX - this.guiLeft, mouseY - this.guiTop + 10, "Input slot");
+ }
+ }
+ }
+
+ /** Draw the background layer for the GuiContainer (everything behind the items) */
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float par1, int x, int y)
+ {
+ super.drawGuiContainerBackgroundLayer(par1, x, y);
+
+ drawSlot(79, 49, SlotType.BATTERY);
+ drawSlot(52, 24);
+ drawSlot(106, 24);
+ drawBar(75, 24, (float) tileEntity.time / (float) TileChemicalExtractor.TICK_TIME);
+ drawMeter(8, 18, (float) tileEntity.inputTank.getFluidAmount() / (float) tileEntity.inputTank.getCapacity(), tileEntity.inputTank.getFluid());
+ drawSlot(24, 18, SlotType.LIQUID);
+ drawSlot(24, 49, SlotType.LIQUID);
+ drawMeter(154, 18, (float) tileEntity.outputTank.getFluidAmount() / (float) tileEntity.outputTank.getCapacity(), tileEntity.outputTank.getFluid());
+ drawSlot(134, 18, SlotType.LIQUID);
+ drawSlot(134, 49, SlotType.LIQUID);
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/fission/GuiNuclearBoiler.java b/atomic/src/main/scala/resonantinduction/atomic/process/fission/GuiNuclearBoiler.java
new file mode 100644
index 000000000..883116392
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/fission/GuiNuclearBoiler.java
@@ -0,0 +1,64 @@
+package resonantinduction.atomic.process.fission;
+
+import net.minecraft.entity.player.InventoryPlayer;
+import net.minecraft.util.StatCollector;
+import resonant.lib.gui.GuiContainerBase;
+import resonantinduction.atomic.fusion.ContainerNuclearBoiler;
+import universalelectricity.api.energy.UnitDisplay.Unit;
+
+public class GuiNuclearBoiler extends GuiContainerBase
+{
+ private TileNuclearBoiler tileEntity;
+
+ public GuiNuclearBoiler(InventoryPlayer par1InventoryPlayer, TileNuclearBoiler tileEntity)
+ {
+ super(new ContainerNuclearBoiler(par1InventoryPlayer, tileEntity));
+ this.tileEntity = tileEntity;
+ }
+
+ /** Draw the foreground layer for the GuiContainer (everything in front of the items) */
+ @Override
+ public void drawGuiContainerForegroundLayer(int mouseX, int mouseY)
+ {
+ this.fontRenderer.drawString(tileEntity.getInvName(), 52, 6, 4210752);
+
+ this.renderUniversalDisplay(8, 112, TileNuclearBoiler.DIAN * 20, mouseX, mouseY, Unit.WATT);
+ this.renderUniversalDisplay(110, 112, this.tileEntity.getVoltageInput(null), mouseX, mouseY, Unit.VOLTAGE);
+
+ this.fontRenderer.drawString("The nuclear boiler can boil", 8, 75, 4210752);
+ this.fontRenderer.drawString("yellow cake into uranium", 8, 85, 4210752);
+ this.fontRenderer.drawString("hexafluoride gas to be refined.", 8, 95, 4210752);
+
+ this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752);
+
+ if (this.isPointInRegion(8, 18, this.meterWidth, this.meterHeight, mouseX, mouseY) && this.tileEntity.waterTank.getFluid() != null)
+ {
+ this.drawTooltip(mouseX - this.guiLeft, mouseY - this.guiTop + 10, this.tileEntity.waterTank.getFluid().getFluid().getLocalizedName(), this.tileEntity.waterTank.getFluid().amount + " L");
+
+ }
+ else if (this.isPointInRegion(155, 18, this.meterWidth, this.meterHeight, mouseX, mouseY) && this.tileEntity.gasTank.getFluid() != null)
+ {
+ this.drawTooltip(mouseX - this.guiLeft, mouseY - this.guiTop + 10, this.tileEntity.gasTank.getFluid().getFluid().getLocalizedName(), this.tileEntity.gasTank.getFluid().amount + " L");
+ }
+ }
+
+ /** Draw the background layer for the GuiContainer (everything behind the items) */
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float par1, int x, int y)
+ {
+ super.drawGuiContainerBackgroundLayer(par1, x, y);
+
+ this.drawSlot(55, 25, SlotType.BATTERY);
+ this.drawSlot(80, 25);
+
+ this.drawBar(110, 26, (float) this.tileEntity.timer / (float) this.tileEntity.SHI_JIAN);
+
+ // Water
+ this.drawMeter(8, 18, (float) this.tileEntity.waterTank.getFluidAmount() / (float) this.tileEntity.waterTank.getCapacity(), this.tileEntity.waterTank.getFluid());
+ this.drawSlot(24, 49, SlotType.LIQUID);
+
+ // Uranium Gas
+ this.drawMeter(155, 18, (float) this.tileEntity.gasTank.getFluidAmount() / (float) this.tileEntity.gasTank.getCapacity(), this.tileEntity.gasTank.getFluid());
+ this.drawSlot(135, 49, SlotType.GAS);
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/fission/RenderCentrifuge.java b/atomic/src/main/scala/resonantinduction/atomic/process/fission/RenderCentrifuge.java
new file mode 100644
index 000000000..0d20cd4f5
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/fission/RenderCentrifuge.java
@@ -0,0 +1,48 @@
+package resonantinduction.atomic.process.fission;
+
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.model.AdvancedModelLoader;
+import net.minecraftforge.client.model.IModelCustom;
+
+import org.lwjgl.opengl.GL11;
+
+import resonant.lib.render.RenderUtility;
+import resonantinduction.core.Reference;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class RenderCentrifuge extends TileEntitySpecialRenderer
+{
+ public static final IModelCustom MODEL = AdvancedModelLoader.loadModel(Reference.MODEL_DIRECTORY + "centrifuge.tcn");
+ public static final ResourceLocation TEXTURE = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "centrifuge.png");
+
+ public void render(TileCentrifuge tileEntity, double x, double y, double z, float f)
+ {
+ GL11.glPushMatrix();
+ GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5);
+
+ if (tileEntity.worldObj != null)
+ {
+ RenderUtility.rotateBlockBasedOnDirection(tileEntity.getDirection());
+ }
+
+ bindTexture(TEXTURE);
+
+ GL11.glPushMatrix();
+ GL11.glRotated(Math.toDegrees(tileEntity.rotation), 0, 1, 0);
+ MODEL.renderOnly("C", "JROT", "KROT", "LROT", "MROT");
+ GL11.glPopMatrix();
+
+ MODEL.renderAllExcept("C", "JROT", "KROT", "LROT", "MROT");
+ GL11.glPopMatrix();
+ }
+
+ @Override
+ public void renderTileEntityAt(TileEntity tileEntity, double var2, double var4, double var6, float var8)
+ {
+ this.render((TileCentrifuge) tileEntity, var2, var4, var6, var8);
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/fission/RenderNuclearBoiler.java b/atomic/src/main/scala/resonantinduction/atomic/process/fission/RenderNuclearBoiler.java
new file mode 100644
index 000000000..0b22abb37
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/fission/RenderNuclearBoiler.java
@@ -0,0 +1,46 @@
+package resonantinduction.atomic.process.fission;
+
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.model.AdvancedModelLoader;
+
+import org.lwjgl.opengl.GL11;
+
+import resonant.lib.render.RenderUtility;
+import resonant.lib.render.model.TechneAdvancedModel;
+import resonantinduction.core.Reference;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class RenderNuclearBoiler extends TileEntitySpecialRenderer
+{
+ public static final TechneAdvancedModel MODEL = (TechneAdvancedModel) AdvancedModelLoader.loadModel(Reference.MODEL_DIRECTORY + "nuclearBoiler.tcn");
+ public static final ResourceLocation TEXTURE = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "nuclearBoiler.png");
+
+ public void renderAModelAt(TileNuclearBoiler tileEntity, double x, double y, double z, float f)
+ {
+ GL11.glPushMatrix();
+ GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5);
+ GL11.glRotatef(90, 0, 1, 0);
+
+ if (tileEntity.worldObj != null)
+ {
+ RenderUtility.rotateBlockBasedOnDirection(tileEntity.getDirection());
+ }
+
+ bindTexture(TEXTURE);
+
+ MODEL.renderOnlyAroundPivot(Math.toDegrees(tileEntity.rotation), 0, 1, 0, "FUEL BAR SUPPORT 1 ROTATES", "FUEL BAR 1 ROTATES");
+ MODEL.renderOnlyAroundPivot(-Math.toDegrees(tileEntity.rotation), 0, 1, 0, "FUEL BAR SUPPORT 2 ROTATES", "FUEL BAR 2 ROTATES");
+ MODEL.renderAllExcept("FUEL BAR SUPPORT 1 ROTATES", "FUEL BAR SUPPORT 2 ROTATES", "FUEL BAR 1 ROTATES", "FUEL BAR 2 ROTATES");
+ GL11.glPopMatrix();
+ }
+
+ @Override
+ public void renderTileEntityAt(TileEntity tileEntity, double var2, double var4, double var6, float var8)
+ {
+ this.renderAModelAt((TileNuclearBoiler) tileEntity, var2, var4, var6, var8);
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/fission/TileCentrifuge.java b/atomic/src/main/scala/resonantinduction/atomic/process/fission/TileCentrifuge.java
new file mode 100644
index 000000000..291052a26
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/fission/TileCentrifuge.java
@@ -0,0 +1,345 @@
+package resonantinduction.atomic.process.fission;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.packet.Packet;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTank;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidHandler;
+import resonant.api.IRotatable;
+import resonant.lib.network.IPacketReceiver;
+import resonant.lib.prefab.tile.TileElectricalInventory;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.ResonantInduction;
+import resonantinduction.core.Settings;
+import universalelectricity.api.CompatibilityModule;
+import universalelectricity.api.electricity.IVoltageInput;
+import universalelectricity.api.energy.EnergyStorageHandler;
+import universalelectricity.api.vector.Vector3;
+import universalelectricity.api.vector.VectorHelper;
+
+import com.google.common.io.ByteArrayDataInput;
+
+import cpw.mods.fml.common.network.PacketDispatcher;
+import cpw.mods.fml.common.network.Player;
+
+/** Centrifuge TileEntity */
+public class TileCentrifuge extends TileElectricalInventory implements ISidedInventory, IPacketReceiver, IFluidHandler, IRotatable, IVoltageInput
+{
+ public static final int SHI_JIAN = 20 * 60;
+
+ public static final long DIAN = 500000;
+ public final FluidTank gasTank = new FluidTank(Atomic.FLUIDSTACK_URANIUM_HEXAFLOURIDE.copy(), FluidContainerRegistry.BUCKET_VOLUME * 5);
+ public int timer = 0;
+ public float rotation = 0;
+
+ public TileCentrifuge()
+ {
+ energy = new EnergyStorageHandler(DIAN * 2);
+ maxSlots = 4;
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+
+ if (timer > 0)
+ {
+ rotation += 0.45f;
+ }
+
+ if (!this.worldObj.isRemote)
+ {
+ /** Look for nearby tanks that contains uranium gas and try to extract it. */
+ if (this.ticks % 20 == 0)
+ {
+ for (int i = 0; i < 6; i++)
+ {
+ ForgeDirection direction = ForgeDirection.getOrientation(i);
+ TileEntity tileEntity = VectorHelper.getTileEntityFromSide(this.worldObj, new Vector3(this), direction);
+
+ if (tileEntity instanceof IFluidHandler && tileEntity.getClass() != this.getClass())
+ {
+ IFluidHandler fluidHandler = ((IFluidHandler) tileEntity);
+
+ if (fluidHandler != null)
+ {
+ FluidStack requestFluid = Atomic.FLUIDSTACK_URANIUM_HEXAFLOURIDE.copy();
+ requestFluid.amount = this.gasTank.getCapacity() - Atomic.getFluidAmount(this.gasTank.getFluid());
+ FluidStack receiveFluid = fluidHandler.drain(direction.getOpposite(), requestFluid, true);
+
+ if (receiveFluid != null)
+ {
+ if (receiveFluid.amount > 0)
+ {
+ if (this.gasTank.fill(receiveFluid, false) > 0)
+ {
+ this.gasTank.fill(receiveFluid, true);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (this.nengYong())
+ {
+ this.discharge(getStackInSlot(0));
+
+ if (this.energy.extractEnergy(TileCentrifuge.DIAN, false) >= DIAN)
+ {
+ if (this.timer == 0)
+ {
+ this.timer = TileCentrifuge.SHI_JIAN;
+ }
+
+ if (this.timer > 0)
+ {
+ this.timer--;
+
+ if (this.timer < 1)
+ {
+ this.yong();
+ this.timer = 0;
+ }
+ }
+ else
+ {
+ this.timer = 0;
+ }
+
+ this.energy.extractEnergy(DIAN, true);
+ }
+ }
+ else
+ {
+ this.timer = 0;
+ }
+
+ if (this.ticks % 10 == 0)
+ {
+ for (EntityPlayer player : this.getPlayersUsing())
+ {
+ PacketDispatcher.sendPacketToPlayer(getDescriptionPacket(), (Player) player);
+ }
+ }
+ }
+ }
+
+ @Override
+ public long onReceiveEnergy(ForgeDirection from, long receive, boolean doReceive)
+ {
+ if (this.nengYong())
+ {
+ return super.onReceiveEnergy(from, receive, doReceive);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ @Override
+ public void onReceivePacket(ByteArrayDataInput data, EntityPlayer player, Object... extra)
+ {
+ try
+ {
+ this.timer = data.readInt();
+ this.gasTank.setFluid(new FluidStack(Atomic.FLUIDSTACK_URANIUM_HEXAFLOURIDE.fluidID, data.readInt()));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public Packet getDescriptionPacket()
+ {
+ return ResonantInduction.PACKET_TILE.getPacket(this, this.timer, Atomic.getFluidAmount(this.gasTank.getFluid()));
+ }
+
+ @Override
+ public void openChest()
+ {
+ if (!this.worldObj.isRemote)
+ {
+ for (EntityPlayer player : this.getPlayersUsing())
+ {
+ PacketDispatcher.sendPacketToPlayer(getDescriptionPacket(), (Player) player);
+ }
+ }
+ }
+
+ @Override
+ public void closeChest()
+ {
+ }
+
+ /** @return If the machine can be used. */
+ public boolean nengYong()
+ {
+ if (this.gasTank.getFluid() != null)
+ {
+ if (this.gasTank.getFluid().amount >= Settings.uraniumHexaflourideRatio)
+ {
+ return isItemValidForSlot(2, new ItemStack(Atomic.itemUranium)) && isItemValidForSlot(3, new ItemStack(Atomic.itemUranium, 1, 1));
+ }
+ }
+
+ return false;
+ }
+
+ /** Turn one item from the furnace source stack into the appropriate smelted item in the furnace result stack */
+ public void yong()
+ {
+ if (this.nengYong())
+ {
+ this.gasTank.drain(Settings.uraniumHexaflourideRatio, true);
+
+ if (this.worldObj.rand.nextFloat() > 0.6)
+ {
+ this.incrStackSize(2, new ItemStack(Atomic.itemUranium));
+ }
+ else
+ {
+ this.incrStackSize(3, new ItemStack(Atomic.itemUranium, 1, 1));
+ }
+ }
+ }
+
+ /** Reads a tile entity from NBT. */
+ @Override
+ public void readFromNBT(NBTTagCompound nbt)
+ {
+ super.readFromNBT(nbt);
+ this.timer = nbt.getInteger("smeltingTicks");
+
+ NBTTagCompound compound = nbt.getCompoundTag("gas");
+ this.gasTank.setFluid(FluidStack.loadFluidStackFromNBT(compound));
+ }
+
+ /** Writes a tile entity to NBT. */
+ @Override
+ public void writeToNBT(NBTTagCompound nbt)
+ {
+ super.writeToNBT(nbt);
+ nbt.setInteger("smeltingTicks", this.timer);
+
+ if (this.gasTank.getFluid() != null)
+ {
+ NBTTagCompound compound = new NBTTagCompound();
+ this.gasTank.getFluid().writeToNBT(compound);
+ nbt.setTag("gas", compound);
+ }
+ }
+
+ /** Tank Methods */
+ @Override
+ public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
+ {
+ if (Atomic.FLUIDSTACK_URANIUM_HEXAFLOURIDE.isFluidEqual(resource))
+ {
+ return this.gasTank.fill(resource, doFill);
+ }
+
+ return 0;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
+ {
+ return null;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
+ {
+ return null;
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid)
+ {
+ return Atomic.FLUIDSTACK_URANIUM_HEXAFLOURIDE.fluidID == fluid.getID();
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid)
+ {
+ return false;
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection from)
+ {
+ return new FluidTankInfo[]
+ { this.gasTank.getInfo() };
+ }
+
+ /** Inventory */
+ @Override
+ public int[] getAccessibleSlotsFromSide(int side)
+ {
+ return side == 1 ? new int[]
+ { 0, 1 } : new int[]
+ { 2, 3 };
+ }
+
+ @Override
+ public boolean canInsertItem(int slotID, ItemStack itemStack, int side)
+ {
+ return slotID == 1 && this.isItemValidForSlot(slotID, itemStack);
+ }
+
+ @Override
+ public boolean canExtractItem(int slotID, ItemStack itemstack, int j)
+ {
+ return slotID == 2 || slotID == 3;
+ }
+
+ @Override
+ public boolean isItemValidForSlot(int i, ItemStack itemStack)
+ {
+ switch (i)
+ {
+ case 0:
+ return CompatibilityModule.isHandler(itemStack.getItem());
+ case 1:
+ return true;
+ case 2:
+ return itemStack.itemID == Atomic.itemUranium.itemID;
+ case 3:
+ return itemStack.itemID == Atomic.itemUranium.itemID;
+ }
+
+ return false;
+ }
+
+ @Override
+ public long onExtractEnergy(ForgeDirection from, long extract, boolean doExtract)
+ {
+ return 0;
+ }
+
+ @Override
+ public long getVoltageInput(ForgeDirection from)
+ {
+ return 1000;
+ }
+
+ @Override
+ public void onWrongVoltage(ForgeDirection direction, long voltage)
+ {
+
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/fission/TileNuclearBoiler.java b/atomic/src/main/scala/resonantinduction/atomic/process/fission/TileNuclearBoiler.java
new file mode 100644
index 000000000..8061cef67
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/fission/TileNuclearBoiler.java
@@ -0,0 +1,348 @@
+package resonantinduction.atomic.process.fission;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.ISidedInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.packet.Packet;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTank;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidHandler;
+import resonant.api.IRotatable;
+import resonant.lib.network.IPacketReceiver;
+import resonant.lib.network.Synced;
+import resonant.lib.prefab.tile.TileElectricalInventory;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.ResonantInduction;
+import resonantinduction.core.Settings;
+import universalelectricity.api.electricity.IVoltageInput;
+import universalelectricity.api.energy.EnergyStorageHandler;
+
+import com.google.common.io.ByteArrayDataInput;
+
+import cpw.mods.fml.common.network.PacketDispatcher;
+import cpw.mods.fml.common.network.Player;
+
+/** Nuclear boiler TileEntity */
+
+public class TileNuclearBoiler extends TileElectricalInventory implements ISidedInventory, IPacketReceiver, IFluidHandler, IRotatable, IVoltageInput
+{
+ public final static long DIAN = 50000;
+ public final int SHI_JIAN = 20 * 15;
+ @Synced
+ public final FluidTank waterTank = new FluidTank(Atomic.FLUIDSTACK_WATER.copy(), FluidContainerRegistry.BUCKET_VOLUME * 5);
+ @Synced
+ public final FluidTank gasTank = new FluidTank(Atomic.FLUIDSTACK_URANIUM_HEXAFLOURIDE.copy(), FluidContainerRegistry.BUCKET_VOLUME * 5);
+ // How many ticks has this item been extracting for?
+ @Synced
+ public int timer = 0;
+ public float rotation = 0;
+
+ public TileNuclearBoiler()
+ {
+ energy = new EnergyStorageHandler(DIAN * 2);
+ maxSlots = 4;
+ }
+
+ @Override
+ public long onReceiveEnergy(ForgeDirection from, long receive, boolean doReceive)
+ {
+ if (this.nengYong())
+ {
+ return super.onReceiveEnergy(from, receive, doReceive);
+ }
+
+ return 0;
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+
+ if (timer > 0)
+ {
+ rotation += 0.1f;
+ }
+
+ if (!this.worldObj.isRemote)
+ {
+ // Put water as liquid
+ if (getStackInSlot(1) != null)
+ {
+ if (FluidContainerRegistry.isFilledContainer(getStackInSlot(1)))
+ {
+ FluidStack liquid = FluidContainerRegistry.getFluidForFilledItem(getStackInSlot(1));
+
+ if (liquid.isFluidEqual(Atomic.FLUIDSTACK_WATER))
+ {
+ if (this.fill(ForgeDirection.UNKNOWN, liquid, false) > 0)
+ {
+ ItemStack resultingContainer = getStackInSlot(1).getItem().getContainerItemStack(getStackInSlot(1));
+
+ if (resultingContainer == null && getStackInSlot(1).stackSize > 1)
+ {
+ getStackInSlot(1).stackSize--;
+ }
+ else
+ {
+ setInventorySlotContents(1, resultingContainer);
+ }
+
+ this.waterTank.fill(liquid, true);
+ }
+ }
+ }
+ }
+
+ if (this.nengYong())
+ {
+ this.discharge(getStackInSlot(0));
+
+ if (this.energy.extractEnergy(DIAN, false) >= TileNuclearBoiler.DIAN)
+ {
+ if (this.timer == 0)
+ {
+ this.timer = SHI_JIAN;
+ }
+
+ if (this.timer > 0)
+ {
+ this.timer--;
+
+ if (this.timer < 1)
+ {
+ this.yong();
+ this.timer = 0;
+ }
+ }
+ else
+ {
+ this.timer = 0;
+ }
+
+ this.energy.extractEnergy(DIAN, true);
+ }
+ }
+ else
+ {
+ this.timer = 0;
+ }
+
+ if (this.ticks % 10 == 0)
+ {
+ this.sendDescPack();
+ }
+ }
+ }
+
+ @Override
+ public void onReceivePacket(ByteArrayDataInput data, EntityPlayer player, Object... extra)
+ {
+ try
+ {
+ this.timer = data.readInt();
+ this.waterTank.setFluid(new FluidStack(Atomic.FLUIDSTACK_WATER.fluidID, data.readInt()));
+ this.gasTank.setFluid(new FluidStack(Atomic.FLUIDSTACK_URANIUM_HEXAFLOURIDE.fluidID, data.readInt()));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public Packet getDescriptionPacket()
+ {
+ return ResonantInduction.PACKET_TILE.getPacket(this, this.timer, Atomic.getFluidAmount(this.waterTank.getFluid()), Atomic.getFluidAmount(this.gasTank.getFluid()));
+ }
+
+ public void sendDescPack()
+ {
+ if (!this.worldObj.isRemote)
+ {
+ for (EntityPlayer player : this.getPlayersUsing())
+ {
+ PacketDispatcher.sendPacketToPlayer(getDescriptionPacket(), (Player) player);
+ }
+ }
+ }
+
+ // Check all conditions and see if we can start smelting
+ public boolean nengYong()
+ {
+ if (this.waterTank.getFluid() != null)
+ {
+ if (this.waterTank.getFluid().amount >= FluidContainerRegistry.BUCKET_VOLUME)
+ {
+ if (getStackInSlot(3) != null)
+ {
+ if (Atomic.itemYellowCake.itemID == getStackInSlot(3).itemID || Atomic.isItemStackUraniumOre(getStackInSlot(3)))
+ {
+ if (Atomic.getFluidAmount(this.gasTank.getFluid()) < this.gasTank.getCapacity())
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /** Turn one item from the furnace source stack into the appropriate smelted item in the furnace result stack. */
+ public void yong()
+ {
+ if (this.nengYong())
+ {
+ this.waterTank.drain(FluidContainerRegistry.BUCKET_VOLUME, true);
+ FluidStack liquid = Atomic.FLUIDSTACK_URANIUM_HEXAFLOURIDE.copy();
+ liquid.amount = Settings.uraniumHexaflourideRatio * 2;
+ this.gasTank.fill(liquid, true);
+ this.decrStackSize(3, 1);
+ }
+ }
+
+ /** Reads a tile entity from NBT. */
+ @Override
+ public void readFromNBT(NBTTagCompound nbt)
+ {
+ super.readFromNBT(nbt);
+ this.timer = nbt.getInteger("shiJian");
+
+ NBTTagCompound waterCompound = nbt.getCompoundTag("water");
+ this.waterTank.setFluid(FluidStack.loadFluidStackFromNBT(waterCompound));
+
+ NBTTagCompound gasCompound = nbt.getCompoundTag("gas");
+ this.gasTank.setFluid(FluidStack.loadFluidStackFromNBT(gasCompound));
+ }
+
+ /** Writes a tile entity to NBT. */
+ @Override
+ public void writeToNBT(NBTTagCompound nbt)
+ {
+ super.writeToNBT(nbt);
+ nbt.setInteger("shiJian", this.timer);
+
+ if (this.waterTank.getFluid() != null)
+ {
+ NBTTagCompound compound = new NBTTagCompound();
+ this.waterTank.getFluid().writeToNBT(compound);
+ nbt.setTag("water", compound);
+ }
+
+ if (this.gasTank.getFluid() != null)
+ {
+ NBTTagCompound compound = new NBTTagCompound();
+ this.gasTank.getFluid().writeToNBT(compound);
+ nbt.setTag("gas", compound);
+ }
+ }
+
+ /** Tank Methods */
+ @Override
+ public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
+ {
+ if (Atomic.FLUIDSTACK_WATER.isFluidEqual(resource))
+ {
+ return this.waterTank.fill(resource, doFill);
+ }
+
+ return 0;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
+ {
+ if (Atomic.FLUIDSTACK_URANIUM_HEXAFLOURIDE.isFluidEqual(resource))
+ {
+ return this.gasTank.drain(resource.amount, doDrain);
+ }
+
+ return null;
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
+ {
+ return this.gasTank.drain(maxDrain, doDrain);
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid)
+ {
+ return Atomic.FLUIDSTACK_WATER.fluidID == fluid.getID();
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid)
+ {
+ return Atomic.FLUIDSTACK_URANIUM_HEXAFLOURIDE.fluidID == fluid.getID();
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection from)
+ {
+ return new FluidTankInfo[]
+ { this.waterTank.getInfo(), this.gasTank.getInfo() };
+ }
+
+ /** Inventory */
+ @Override
+ public boolean isItemValidForSlot(int slotID, ItemStack itemStack)
+ {
+ if (slotID == 1)
+ {
+ return Atomic.isItemStackWaterCell(itemStack);
+ }
+ else if (slotID == 3)
+ {
+ return itemStack.itemID == Atomic.itemYellowCake.itemID;
+ }
+
+ return false;
+ }
+
+ @Override
+ public int[] getAccessibleSlotsFromSide(int side)
+ {
+ return side == 0 ? new int[]
+ { 2 } : new int[]
+ { 1, 3 };
+ }
+
+ @Override
+ public boolean canInsertItem(int slotID, ItemStack itemStack, int side)
+ {
+ return this.isItemValidForSlot(slotID, itemStack);
+ }
+
+ @Override
+ public boolean canExtractItem(int slotID, ItemStack itemstack, int j)
+ {
+ return slotID == 2;
+ }
+
+ @Override
+ public long onExtractEnergy(ForgeDirection from, long extract, boolean doExtract)
+ {
+ return 0;
+ }
+
+ @Override
+ public long getVoltageInput(ForgeDirection from)
+ {
+ return 1000;
+ }
+
+ @Override
+ public void onWrongVoltage(ForgeDirection direction, long voltage)
+ {
+
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/sensor/ItemBlockThermometer.java b/atomic/src/main/scala/resonantinduction/atomic/process/sensor/ItemBlockThermometer.java
new file mode 100644
index 000000000..c492f2f04
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/sensor/ItemBlockThermometer.java
@@ -0,0 +1,96 @@
+package resonantinduction.atomic.process.sensor;
+
+import java.util.List;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.world.World;
+import resonant.lib.prefab.item.ItemBlockSaved;
+import resonant.lib.utility.LanguageUtility;
+import resonant.lib.utility.nbt.NBTUtility;
+import universalelectricity.api.vector.Vector3;
+
+/** Handheld thermometer */
+public class ItemBlockThermometer extends ItemBlockSaved
+{
+ public static final int ENERGY_CONSUMPTION = 1000;
+
+ public ItemBlockThermometer(int id)
+ {
+ super(id);
+ }
+
+ @Override
+ public void addInformation(ItemStack itemStack, EntityPlayer player, List par3List, boolean par4)
+ {
+ super.addInformation(itemStack, player, par3List, par4);
+ Vector3 coord = getSavedCoord(itemStack);
+
+ if (coord != null)
+ {
+ par3List.add("\uaa74" + LanguageUtility.getLocal("tooltip.trackingTemperature"));
+ par3List.add("X: " + coord.intX() + ", Y: " + coord.intY() + ", Z: " + coord.intZ());
+ // TODO: Add client side temperature.
+ }
+ else
+ {
+ par3List.add("\u00a74" + LanguageUtility.getLocal("tooltip.notTrackingTemperature"));
+ }
+ }
+
+ public void setSavedCoords(ItemStack itemStack, Vector3 position)
+ {
+ NBTTagCompound nbt = NBTUtility.getNBTTagCompound(itemStack);
+
+ if (position != null)
+ {
+ nbt.setCompoundTag("trackCoordinate", position.writeToNBT(new NBTTagCompound()));
+ }
+ else
+ {
+ nbt.removeTag("trackCoordinate");
+ }
+ }
+
+ public Vector3 getSavedCoord(ItemStack itemStack)
+ {
+ NBTTagCompound nbt = NBTUtility.getNBTTagCompound(itemStack);
+
+ if (nbt.hasKey("trackCoordinate"))
+ {
+ return new Vector3(nbt.getCompoundTag("trackCoordinate"));
+ }
+
+ return null;
+ }
+
+ @Override
+ public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player)
+ {
+ setSavedCoords(itemStack, null);
+
+ if (!world.isRemote)
+ {
+ player.addChatMessage("Cleared tracking coordinate.");
+ }
+ return itemStack;
+ }
+
+ @Override
+ public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int par7, float par8, float par9, float par10)
+ {
+ if (player.isSneaking())
+ {
+ if (!world.isRemote)
+ {
+ setSavedCoords(itemStack, new Vector3(x, y, z));
+ player.addChatMessage("Tracking coordinate: " + x + ", " + y + ", " + z);
+ }
+
+ return true;
+ }
+
+ return super.onItemUse(itemStack, player, world, x, y, z, par7, par8, par9, par10);
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/sensor/RenderThermometer.java b/atomic/src/main/scala/resonantinduction/atomic/process/sensor/RenderThermometer.java
new file mode 100644
index 000000000..ac75814a5
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/sensor/RenderThermometer.java
@@ -0,0 +1,37 @@
+package resonantinduction.atomic.process.sensor;
+
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.tileentity.TileEntity;
+
+import org.lwjgl.opengl.GL11;
+
+import resonant.lib.render.RenderUtility;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class RenderThermometer extends TileEntitySpecialRenderer
+{
+ @Override
+ public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float var8)
+ {
+ TileThermometer tile = (TileThermometer) tileEntity;
+
+ GL11.glPushMatrix();
+ RenderUtility.enableLightmap();
+
+ for (int side = 2; side < 6; side++)
+ {
+ RenderUtility.renderText((tile.isOverThreshold() ? "\u00a74" : "") + Math.round(tile.detectedTemperature) + " K", side, 0.8f, x, y + 0.1, z);
+ RenderUtility.renderText((tile.isOverThreshold() ? "\u00a74" : "\u00a71") + "Threshold: " + (tile.getThershold()) + " K", side, 1, x, y - 0.1, z);
+
+ if (tile.trackCoordinate != null)
+ {
+ RenderUtility.renderText(tile.trackCoordinate.intX() + ", " + tile.trackCoordinate.intY() + ", " + tile.trackCoordinate.intZ(), side, 0.5f, x, y - 0.3, z);
+ }
+ }
+
+ GL11.glPopMatrix();
+
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/sensor/TileSiren.java b/atomic/src/main/scala/resonantinduction/atomic/process/sensor/TileSiren.java
new file mode 100644
index 000000000..a80211d5c
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/sensor/TileSiren.java
@@ -0,0 +1,79 @@
+package resonantinduction.atomic.process.sensor;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraftforge.common.ForgeDirection;
+import resonant.lib.content.module.TileBlock;
+import resonantinduction.core.Reference;
+import universalelectricity.api.UniversalElectricity;
+import universalelectricity.api.vector.Vector3;
+
+/** Siren block */
+public class TileSiren extends TileBlock
+{
+ public TileSiren()
+ {
+ super(UniversalElectricity.machine);
+ }
+
+ @Override
+ public void onWorldJoin()
+ {
+ scheduelTick(1);
+ }
+
+ @Override
+ public void onNeighborChanged()
+ {
+ scheduelTick(1);
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ if (worldObj == null)
+ {
+ return;
+ }
+
+ int metadata = worldObj.getBlockMetadata(x(), y(), z());
+
+ if (worldObj.getBlockPowerInput(x(), y(), z()) > 0)
+ {
+ float volume = 0.5f;
+
+ for (int i = 0; i < 6; i++)
+ {
+ Vector3 check = position().translate(ForgeDirection.getOrientation(i));
+ int blockID = check.getBlockID(worldObj);
+
+ if (blockID == blockID())
+ {
+ volume *= 1.5f;
+ }
+ }
+
+ worldObj.playSoundEffect(x(), y(), z(), Reference.PREFIX + "alarm", volume, 1f - 0.18f * (metadata / 15f));
+ scheduelTick(30);
+ }
+ }
+
+ @Override
+ protected boolean configure(EntityPlayer player, int side, Vector3 hit)
+ {
+ int metadata = world().getBlockMetadata(x(), y(), z());
+
+ if (player.isSneaking())
+ {
+ metadata -= 1;
+ }
+ else
+ {
+ metadata += 1;
+ }
+
+ metadata = Math.max(metadata % 16, 0);
+
+ world().setBlockMetadataWithNotify(x(), y(), z(), metadata, 2);
+ return true;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/sensor/TileThermometer.java b/atomic/src/main/scala/resonantinduction/atomic/process/sensor/TileThermometer.java
new file mode 100644
index 000000000..d74cfe322
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/sensor/TileThermometer.java
@@ -0,0 +1,351 @@
+package resonantinduction.atomic.process.sensor;
+
+import java.util.ArrayList;
+
+import li.cil.oc.api.network.Arguments;
+import li.cil.oc.api.network.Callback;
+import li.cil.oc.api.network.Context;
+import li.cil.oc.api.network.SimpleComponent;
+import net.minecraft.block.material.Material;
+import net.minecraft.client.renderer.texture.IconRegister;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.packet.Packet;
+import net.minecraft.util.Icon;
+import net.minecraft.world.IBlockAccess;
+import resonant.lib.content.module.TileBase;
+import resonant.lib.network.PacketHandler;
+import resonant.lib.network.Synced;
+import resonant.lib.prefab.item.ItemBlockSaved;
+import resonant.lib.thermal.ThermalGrid;
+import resonant.lib.utility.inventory.InventoryUtility;
+import resonantinduction.core.Reference;
+import resonantinduction.core.ResonantInduction;
+import universalelectricity.api.vector.Vector3;
+import universalelectricity.api.vector.VectorWorld;
+import cpw.mods.fml.common.Optional;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import dan200.computercraft.api.lua.ILuaContext;
+import dan200.computercraft.api.peripheral.IComputerAccess;
+import dan200.computercraft.api.peripheral.IPeripheral;
+
+/** Thermometer TileEntity */
+@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")
+public class TileThermometer extends TileBase implements IPeripheral, SimpleComponent
+{
+ public static final int MAX_THRESHOLD = 5000;
+ private static Icon iconSide;
+
+ @Synced
+ public float detectedTemperature = 295;
+
+ @Synced
+ public float previousDetectedTemperature = 295;
+
+ @Synced
+ public Vector3 trackCoordinate;
+
+ @Synced
+ private int threshold = 1000;
+
+ @Synced
+ private boolean isProvidingPower = false;
+
+ public TileThermometer()
+ {
+ super(Material.piston);
+ canProvidePower = true;
+ normalRender = false;
+ forceStandardRender = true;
+ itemBlock = ItemBlockThermometer.class;
+ }
+
+ @Override
+ public Icon getIcon(int side, int meta)
+ {
+ return side == 1 || side == 0 ? super.getIcon(side, meta) : iconSide;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public void registerIcons(IconRegister iconRegister)
+ {
+ super.registerIcons(iconRegister);
+ iconSide = iconRegister.registerIcon(Reference.PREFIX + "machine");
+ }
+
+ @Override
+ protected boolean use(EntityPlayer player, int side, Vector3 hit)
+ {
+ if (player.isSneaking())
+ {
+ setThreshold(getThershold() + 100);
+ }
+ else
+ {
+ setThreshold(getThershold() - 100);
+ }
+
+ return true;
+ }
+
+ @Override
+ protected boolean configure(EntityPlayer player, int side, Vector3 hit)
+ {
+ if (player.isSneaking())
+ {
+ setThreshold(getThershold() - 10);
+ }
+ else
+ {
+ setThreshold(getThershold() + 10);
+ }
+ return true;
+ }
+
+ @Override
+ public int getStrongRedstonePower(IBlockAccess access, int side)
+ {
+ return isProvidingPower ? 15 : 0;
+ }
+
+ @Override
+ public ArrayList getDrops(int metadata, int fortune)
+ {
+ return new ArrayList();
+ }
+
+ @Override
+ public void onRemove(int par5, int par6)
+ {
+ ItemStack stack = ItemBlockSaved.getItemStackWithNBT(getBlockType(), world(), x(), y(), z());
+ InventoryUtility.dropItemStack(world(), center(), stack);
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+
+ // Server only operation.
+ if (!worldObj.isRemote)
+ {
+ // Every ten ticks.
+ if (ticks % 10 == 0)
+ {
+ // Grab temperature from target or from ourselves.
+ if (trackCoordinate != null)
+ {
+ detectedTemperature = ThermalGrid.getTemperature(new VectorWorld(world(), trackCoordinate));
+ }
+ else
+ {
+ detectedTemperature = ThermalGrid.getTemperature(new VectorWorld(this));
+ }
+
+ // Send update packet if temperature is different or over temperature threshold.
+ if (detectedTemperature != previousDetectedTemperature || isProvidingPower != this.isOverThreshold())
+ {
+ previousDetectedTemperature = detectedTemperature;
+ isProvidingPower = isOverThreshold();
+ notifyChange();
+ PacketHandler.sendPacketToClients(getDescriptionPacket(), this.worldObj, new Vector3(this), 25);
+ }
+ }
+ }
+ }
+
+ @Override
+ public Packet getDescriptionPacket()
+ {
+ return ResonantInduction.PACKET_ANNOTATION.getPacket(this);
+ }
+
+ public void setTrack(Vector3 track)
+ {
+ trackCoordinate = track;
+ }
+
+ /** Reads a tile entity from NBT. */
+ @Override
+ public void readFromNBT(NBTTagCompound nbt)
+ {
+ super.readFromNBT(nbt);
+ threshold = nbt.getInteger("threshold");
+
+ if (nbt.hasKey("trackCoordinate"))
+ {
+ trackCoordinate = new Vector3(nbt.getCompoundTag("trackCoordinate"));
+ }
+ else
+ {
+ trackCoordinate = null;
+ }
+ }
+
+ /** Writes a tile entity to NBT. */
+ @Override
+ public void writeToNBT(NBTTagCompound nbt)
+ {
+ super.writeToNBT(nbt);
+ nbt.setInteger("threshold", threshold);
+
+ if (trackCoordinate != null)
+ {
+ nbt.setCompoundTag("trackCoordinate", this.trackCoordinate.writeToNBT(new NBTTagCompound()));
+ }
+ }
+
+ public int getThershold()
+ {
+ return threshold;
+ }
+
+ public void setThreshold(int newThreshold)
+ {
+ threshold = newThreshold % MAX_THRESHOLD;
+
+ if (threshold <= 0)
+ {
+ threshold = MAX_THRESHOLD;
+ }
+
+ markUpdate();
+ }
+
+ public boolean isOverThreshold()
+ {
+ return detectedTemperature >= getThershold();
+ }
+
+ /** ComputerCraft */
+ @Override
+ public String getType()
+ {
+ return "AS Thermometer";
+ }
+
+ @Override
+ public String[] getMethodNames()
+ {
+ return new String[]
+ { "getTemperature", "getWarningTemperature", "setWarningTemperature", "isAboveWarningTemperature" };
+ }
+
+ @Override
+ public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws Exception
+ {
+ final int getTemperature = 0;
+ final int getWarningTemperature = 1;
+ final int setWarningTemperature = 2;
+ final int isAboveWarningTemperature = 3;
+
+ switch (method)
+ {
+ case getTemperature:
+ return new Object[]
+ { this.detectedTemperature };
+ case getWarningTemperature:
+ return new Object[]
+ { this.getThershold() };
+ case isAboveWarningTemperature:
+ return new Object[]
+ { this.isOverThreshold() };
+ case setWarningTemperature:
+ {
+ if (arguments.length <= 0)
+ {
+ throw new IllegalArgumentException("Not enough Arguments. Must provide one argument");
+ }
+ if (arguments.length >= 2)
+ {
+ throw new IllegalArgumentException("Too many Arguments. Must provide one argument");
+ }
+ if (!(arguments[0] instanceof Number))
+ {
+ throw new IllegalArgumentException("Invalid Argument. Must provide a number");
+ }
+ synchronized (this)
+ {
+ this.setThreshold((Integer) arguments[0]);
+ }
+ return new Object[]
+ { this.threshold == (Integer) arguments[0] };
+ }
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public void attach(IComputerAccess computer)
+ {
+ }
+
+ @Override
+ public void detach(IComputerAccess computer)
+ {
+ }
+
+ @Override
+ public boolean equals(IPeripheral other)
+ {
+ return equals(this);
+ }
+
+ @Override
+ public String getComponentName()
+ {
+ return "AS_Thermometer";
+ }
+
+ @Callback
+ @Optional.Method(modid = "OpenComputers")
+ public Object[] getTemperature(Context context, Arguments args)
+ {
+ return new Object[]
+ { this.detectedTemperature };
+ }
+
+ @Callback
+ @Optional.Method(modid = "OpenComputers")
+ public Object[] getWarningTemperature(Context context, Arguments args)
+ {
+ return new Object[]
+ { this.getThershold() };
+ }
+
+ @Callback
+ @Optional.Method(modid = "OpenComputers")
+ public Object[] isAboveWarningTemperature(Context context, Arguments args)
+ {
+ return new Object[]
+ { this.isOverThreshold() };
+ }
+
+ @Callback
+ @Optional.Method(modid = "OpenComputers")
+ public Object[] setWarningTemperature(Context context, Arguments args)
+ {
+ if (args.count() <= 0)
+ {
+ throw new IllegalArgumentException("Not enough Arguments. Must provide one argument");
+ }
+ if (args.count() >= 2)
+ {
+ throw new IllegalArgumentException("Too many Arguments. Must provide one argument");
+ }
+ if (!(args.isInteger(0)))
+ {
+ throw new IllegalArgumentException("Invalid Argument. Must provide an Integer");
+ }
+ synchronized (this)
+ {
+ this.setThreshold(args.checkInteger(0));
+ }
+ return new Object[]
+ { this.threshold == args.checkInteger(0) };
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/turbine/BlockElectricTurbine.java b/atomic/src/main/scala/resonantinduction/atomic/process/turbine/BlockElectricTurbine.java
new file mode 100644
index 000000000..55de84303
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/turbine/BlockElectricTurbine.java
@@ -0,0 +1,33 @@
+package resonantinduction.atomic.process.turbine;
+
+import net.minecraft.block.material.Material;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import resonant.lib.prefab.turbine.BlockTurbine;
+import resonant.lib.render.block.BlockRenderingHandler;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.Reference;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+public class BlockElectricTurbine extends BlockTurbine
+{
+ public BlockElectricTurbine(int id)
+ {
+ super(id, Material.iron);
+ setTextureName(Reference.PREFIX + "machine");
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public int getRenderType()
+ {
+ return BlockRenderingHandler.ID;
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(World var1)
+ {
+ return new TileElectricTurbine();
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/turbine/RenderElectricTurbine.java b/atomic/src/main/scala/resonantinduction/atomic/process/turbine/RenderElectricTurbine.java
new file mode 100644
index 000000000..9f92181d0
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/turbine/RenderElectricTurbine.java
@@ -0,0 +1,109 @@
+package resonantinduction.atomic.process.turbine;
+
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.model.AdvancedModelLoader;
+import net.minecraftforge.client.model.IModelCustom;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.lwjgl.opengl.GL11;
+
+import resonant.lib.prefab.turbine.TileTurbine;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.Reference;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+public class RenderElectricTurbine extends TileEntitySpecialRenderer
+{
+ public static final IModelCustom MODEL_SMALL = AdvancedModelLoader.loadModel(Reference.MODEL_DIRECTORY + "turbineSmall.tcn");
+ public static final IModelCustom MODEL_LARGE = AdvancedModelLoader.loadModel(Reference.MODEL_DIRECTORY + "turbineLarge.tcn");
+ public static final ResourceLocation SMALL_TEXTURE = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "turbineSmall.png");
+ public static final ResourceLocation LARGE_TEXTURE = new ResourceLocation(Reference.DOMAIN, Reference.MODEL_PATH + "turbineLarge.png");
+
+ @Override
+ public void renderTileEntityAt(TileEntity t, double x, double y, double z, float f)
+ {
+ TileTurbine tile = (TileTurbine) t;
+
+ if (tile.getMultiBlock().isPrimary())
+ {
+ // Texture file
+ GL11.glPushMatrix();
+ GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5);
+
+ if (tile.getMultiBlock().isConstructed())
+ {
+ bindTexture(LARGE_TEXTURE);
+
+ final String[] blades = new String[]
+ { "Blade1", "Blade2", "Blade3", "Blade4", "Blade5", "Blade6" };
+ final String[] mediumBlades = new String[]
+ { "MediumBlade1", "MediumBlade2", "MediumBlade3", "MediumBlade4", "MediumBlade5", "MediumBlade6" };
+ final String[] largeBlades = new String[]
+ { "LargeBlade1", "LargeBlade2", "LargeBlade3", "LargeBlade4", "LargeBlade5", "LargeBlade6" };
+
+ GL11.glPushMatrix();
+ GL11.glRotated(Math.toDegrees(tile.rotation), 0, 1, 0);
+ MODEL_LARGE.renderOnly(blades);
+ MODEL_LARGE.renderOnly(largeBlades);
+ GL11.glPopMatrix();
+
+ GL11.glPushMatrix();
+ GL11.glRotated(-Math.toDegrees(tile.rotation), 0, 1, 0);
+ MODEL_LARGE.renderOnly(mediumBlades);
+ GL11.glPopMatrix();
+
+ MODEL_LARGE.renderAllExcept(ArrayUtils.addAll(ArrayUtils.addAll(blades, mediumBlades), largeBlades));
+ }
+ else
+ {
+ GL11.glScalef(1f, 1.1f, 1f);
+ bindTexture(SMALL_TEXTURE);
+
+ final String[] bladesA = new String[3];
+ for (int i = 0; i < bladesA.length; i++)
+ {
+ bladesA[i] = "BLADE A" + (i + 1) + " SPINS";
+ }
+
+ final String[] sheildsA = new String[6];
+ for (int i = 0; i < sheildsA.length; i++)
+ {
+ sheildsA[i] = "SHIELD A" + (i + 1) + " SPINS";
+ }
+
+ final String[] bladesB = new String[3];
+ for (int i = 0; i < bladesB.length; i++)
+ {
+ bladesB[i] = "BLADE B" + (i + 1) + " SPINS";
+ }
+
+ final String[] sheildsB = new String[6];
+ for (int i = 0; i < sheildsB.length; i++)
+ {
+ sheildsB[i] = "SHIELD B" + (i + 1) + " SPINS";
+ }
+
+ final String[] renderA = ArrayUtils.addAll(bladesA, sheildsA);
+ final String[] renderB = ArrayUtils.addAll(bladesB, sheildsB);
+
+ GL11.glPushMatrix();
+ GL11.glRotated(Math.toDegrees(tile.rotation), 0, 1, 0);
+ MODEL_SMALL.renderOnly(renderA);
+ GL11.glPopMatrix();
+
+ GL11.glPushMatrix();
+ GL11.glRotated(-Math.toDegrees(tile.rotation), 0, 1, 0);
+ MODEL_SMALL.renderOnly(renderB);
+ GL11.glPopMatrix();
+
+ MODEL_SMALL.renderAllExcept(ArrayUtils.addAll(renderA, renderB));
+ }
+
+ GL11.glPopMatrix();
+ }
+ }
+}
\ No newline at end of file
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/turbine/TileElectricTurbine.java b/atomic/src/main/scala/resonantinduction/atomic/process/turbine/TileElectricTurbine.java
new file mode 100644
index 000000000..665d60333
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/turbine/TileElectricTurbine.java
@@ -0,0 +1,56 @@
+package resonantinduction.atomic.process.turbine;
+
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import resonant.api.IBoilHandler;
+import resonant.lib.prefab.turbine.TileTurbine;
+import resonantinduction.atomic.Atomic;
+import resonantinduction.core.Settings;
+
+public class TileElectricTurbine extends TileTurbine implements IBoilHandler
+{
+ public TileElectricTurbine()
+ {
+ super();
+ maxPower = 5000000;
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ if (getMultiBlock().isConstructed())
+ {
+ torque = defaultTorque * 500 * getArea();
+ }
+ else
+ {
+ torque = defaultTorque * 500;
+ }
+
+ super.updateEntity();
+ }
+
+ @Override
+ public void onProduce()
+ {
+ energy.receiveEnergy((long) (power * Settings.turbineOutputMultiplier), true);
+ produce();
+ }
+
+ @Override
+ public void playSound()
+ {
+ if (this.worldObj.getWorldTime() % (Atomic.SECOND_IN_TICKS * 1.3F) == 0)
+ {
+ double maxVelocity = (getMaxPower() / torque) * 4;
+ float percentage = angularVelocity * 4 / (float) maxVelocity;
+ this.worldObj.playSoundEffect(this.xCoord, this.yCoord, this.zCoord, "atomicscience:turbine", percentage, 1.0F);
+ }
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid)
+ {
+ return from == ForgeDirection.DOWN && super.canFill(from, fluid);
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/process/turbine/TileFunnel.java b/atomic/src/main/scala/resonantinduction/atomic/process/turbine/TileFunnel.java
new file mode 100644
index 000000000..5e8e4c405
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/process/turbine/TileFunnel.java
@@ -0,0 +1,149 @@
+package resonantinduction.atomic.process.turbine;
+
+import net.minecraft.block.material.Material;
+import net.minecraft.client.renderer.texture.IconRegister;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.Icon;
+import net.minecraftforge.common.ForgeDirection;
+import net.minecraftforge.fluids.Fluid;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidTank;
+import net.minecraftforge.fluids.FluidTankInfo;
+import net.minecraftforge.fluids.IFluidHandler;
+import resonant.api.IBoilHandler;
+import resonant.lib.content.module.TileBase;
+import resonant.lib.content.module.TileRender;
+import resonant.lib.utility.ConnectedTextureRenderer;
+import resonantinduction.core.Reference;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+
+/** Funnel for gas. */
+public class TileFunnel extends TileBase implements IBoilHandler
+{
+ private static Icon iconTop;
+ private final FluidTank tank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME * 16);
+
+ public TileFunnel()
+ {
+ super(Material.iron);
+
+ }
+
+ @Override
+ public Icon getIcon(int side, int meta)
+ {
+ return side == 1 || side == 0 ? iconTop : super.getIcon(side, meta);
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public void registerIcons(IconRegister iconRegister)
+ {
+ super.registerIcons(iconRegister);
+ iconTop = iconRegister.registerIcon(domain + name + "_top");
+ }
+
+ @Override
+ public void updateEntity()
+ {
+ super.updateEntity();
+
+ if (tank.getFluidAmount() > 0)
+ {
+ TileEntity tileEntity = this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord + 1, this.zCoord);
+
+ if (tileEntity instanceof IFluidHandler)
+ {
+ IFluidHandler handler = (IFluidHandler) tileEntity;
+
+ if (handler.canFill(ForgeDirection.DOWN, tank.getFluid().getFluid()))
+ {
+ FluidStack drainedStack = tank.drain(tank.getCapacity(), false);
+
+ if (drainedStack != null)
+ {
+ tank.drain(handler.fill(ForgeDirection.DOWN, drainedStack, true), true);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound tag)
+ {
+ super.readFromNBT(tag);
+ tank.writeToNBT(tag);
+ }
+
+ @Override
+ public void writeToNBT(NBTTagCompound tag)
+ {
+ super.writeToNBT(tag);
+ tank.readFromNBT(tag);
+ }
+
+ /** Tank Methods */
+
+ /* IFluidHandler */
+ @Override
+ public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
+ {
+ return tank.fill(resource, doFill);
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
+ {
+ return this.tank.drain(maxDrain, doDrain);
+ }
+
+ @Override
+ public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
+ {
+ if (resource == null || !resource.isFluidEqual(tank.getFluid()))
+ {
+ return null;
+ }
+ return tank.drain(resource.amount, doDrain);
+ }
+
+ @Override
+ public boolean canFill(ForgeDirection from, Fluid fluid)
+ {
+ if (fluid.isGaseous() && from == ForgeDirection.DOWN)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean canDrain(ForgeDirection from, Fluid fluid)
+ {
+ if (fluid.isGaseous() && from == ForgeDirection.UP)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public FluidTankInfo[] getTankInfo(ForgeDirection from)
+ {
+ return new FluidTankInfo[]
+ { tank.getInfo() };
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ protected TileRender newRenderer()
+ {
+ return new ConnectedTextureRenderer(this, Reference.PREFIX + "funnel_edge");
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicAccelerator.java b/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicAccelerator.java
new file mode 100644
index 000000000..0bbacb5f5
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicAccelerator.java
@@ -0,0 +1,81 @@
+package resonantinduction.atomic.schematic;
+
+import java.util.HashMap;
+
+import net.minecraftforge.common.ForgeDirection;
+import resonant.lib.schematic.Schematic;
+import resonant.lib.type.Pair;
+import resonantinduction.atomic.Atomic;
+import universalelectricity.api.vector.Vector3;
+
+public class SchematicAccelerator extends Schematic
+{
+ @Override
+ public String getName()
+ {
+ return "schematic.accelerator.name";
+ }
+
+ @Override
+ public HashMap> getStructure(ForgeDirection dir, int size)
+ {
+ HashMap> returnMap = new HashMap>();
+
+ int r = size;
+
+ for (int x = -r; x < r; x++)
+ {
+ for (int z = -r; z < r; z++)
+ {
+ for (int y = -1; y <= 1; y++)
+ {
+ if (x == -r || x == r - 1 || z == -r || z == r - 1)
+ {
+ returnMap.put(new Vector3(x, y, z), new Pair(Atomic.blockElectromagnet.blockID, 0));
+ }
+ }
+ }
+ }
+
+ r = size - 2;
+
+ for (int x = -r; x < r; x++)
+ {
+ for (int z = -r; z < r; z++)
+ {
+ for (int y = -1; y <= 1; y++)
+ {
+ if (x == -r || x == r - 1 || z == -r || z == r - 1)
+ {
+ returnMap.put(new Vector3(x, y, z), new Pair(Atomic.blockElectromagnet.blockID, 0));
+ }
+ }
+ }
+ }
+
+ r = size - 1;
+
+ for (int x = -r; x < r; x++)
+ {
+ for (int z = -r; z < r; z++)
+ {
+ for (int y = -1; y <= 1; y++)
+ {
+ if (x == -r || x == r - 1 || z == -r || z == r - 1)
+ {
+ if (y == -1 || y == 1)
+ {
+ returnMap.put(new Vector3(x, y, z), new Pair(Atomic.blockElectromagnet.blockID, 1));
+ }
+ else if (y == 0)
+ {
+ returnMap.put(new Vector3(x, y, z), new Pair(0, 0));
+ }
+ }
+ }
+ }
+ }
+
+ return returnMap;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicBreedingReactor.java b/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicBreedingReactor.java
new file mode 100644
index 000000000..ce0c82dc9
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicBreedingReactor.java
@@ -0,0 +1,67 @@
+package resonantinduction.atomic.schematic;
+
+import java.util.HashMap;
+
+import net.minecraft.block.Block;
+import net.minecraftforge.common.ForgeDirection;
+import resonant.lib.schematic.Schematic;
+import resonant.lib.type.Pair;
+import resonantinduction.atomic.Atomic;
+import universalelectricity.api.vector.Vector3;
+
+public class SchematicBreedingReactor extends Schematic
+{
+ @Override
+ public String getName()
+ {
+ return "schematic.breedingReactor.name";
+ }
+
+ @Override
+ public HashMap> getStructure(ForgeDirection dir, int size)
+ {
+ HashMap> returnMap = new HashMap>();
+
+ int r = Math.max(size, 2);
+
+ for (int x = -r; x <= r; x++)
+ {
+ for (int z = -r; z <= r; z++)
+ {
+ returnMap.put(new Vector3(x, 0, z), new Pair(Block.waterStill.blockID, 0));
+ }
+ }
+
+ r--;
+
+ for (int x = -r; x <= r; x++)
+ {
+ for (int z = -r; z <= r; z++)
+ {
+ Vector3 targetPosition = new Vector3(x, 1, z);
+
+ if (new Vector3(x, 0, z).getMagnitude() <= 2)
+ {
+ if (!((x == -r || x == r) && (z == -r || z == r)))
+ {
+ returnMap.put(new Vector3(x, 0, z), new Pair(Atomic.blockReactorCell.blockID, 0));
+ returnMap.put(new Vector3(x, -1, z), new Pair(Atomic.blockThermometer.blockID, 0));
+ returnMap.put(new Vector3(x, -3, z), new Pair(Atomic.blockSiren.blockID, 0));
+ returnMap.put(new Vector3(x, -2, z), new Pair(Block.redstoneWire.blockID, 0));
+
+ }
+ else
+ {
+ returnMap.put(new Vector3(x, -1, z), new Pair(Atomic.blockControlRod.blockID, 0));
+ returnMap.put(new Vector3(x, -2, z), new Pair(Block.pistonStickyBase.blockID, 1));
+ }
+ }
+ }
+ }
+
+ returnMap.put(new Vector3(0, -2, 0), new Pair(Block.stone.blockID, 0));
+ returnMap.put(new Vector3(0, -3, 0), new Pair(Block.stone.blockID, 0));
+ returnMap.put(new Vector3(), new Pair(Atomic.blockReactorCell.blockID, 0));
+ return returnMap;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicFissionReactor.java b/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicFissionReactor.java
new file mode 100644
index 000000000..c6176c556
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicFissionReactor.java
@@ -0,0 +1,121 @@
+package resonantinduction.atomic.schematic;
+
+import java.util.HashMap;
+
+import net.minecraft.block.Block;
+import net.minecraftforge.common.ForgeDirection;
+import resonant.lib.schematic.Schematic;
+import resonant.lib.type.Pair;
+import resonantinduction.atomic.Atomic;
+import universalelectricity.api.vector.Vector3;
+
+public class SchematicFissionReactor extends Schematic
+{
+ @Override
+ public String getName()
+ {
+ return "schematic.fissionReactor.name";
+ }
+
+ @Override
+ public HashMap> getStructure(ForgeDirection dir, int size)
+ {
+ HashMap> returnMap = new HashMap>();
+
+ if (size <= 1)
+ {
+ int r = 2;
+
+ for (int x = -r; x <= r; x++)
+ {
+ for (int z = -r; z <= r; z++)
+ {
+ Vector3 targetPosition = new Vector3(x, 0, z);
+ returnMap.put(targetPosition, new Pair(Block.waterStill.blockID, 0));
+ }
+ }
+
+ r -= 1;
+
+ /** Create turbines and control rods */
+ for (int x = -r; x <= r; x++)
+ {
+ for (int z = -r; z <= r; z++)
+ {
+ Vector3 targetPosition = new Vector3(x, 1, z);
+ returnMap.put(targetPosition, new Pair(Atomic.blockElectricTurbine.blockID, 0));
+
+ if (!((x == -r || x == r) && (z == -r || z == r)) && new Vector3(x, 0, z).getMagnitude() <= 1)
+ {
+ returnMap.put(new Vector3(x, -1, z), new Pair(Atomic.blockControlRod.blockID, 0));
+ returnMap.put(new Vector3(x, -2, z), new Pair(Block.pistonStickyBase.blockID, 1));
+ }
+ }
+ }
+
+ returnMap.put(new Vector3(0, -1, 0), new Pair(Atomic.blockThermometer.blockID, 0));
+ // TODO: IF Siren is a Tile, don't do this. Redstone can't hold it.
+ returnMap.put(new Vector3(0, -3, 0), new Pair(Atomic.blockSiren.blockID, 0));
+ returnMap.put(new Vector3(0, -2, 0), new Pair(Block.redstoneWire.blockID, 0));
+ returnMap.put(new Vector3(), new Pair(Atomic.blockReactorCell.blockID, 0));
+ }
+ else
+ {
+ int r = 2;
+
+ for (int y = 0; y < size; y++)
+ {
+ for (int x = -r; x <= r; x++)
+ {
+ for (int z = -r; z <= r; z++)
+ {
+ Vector3 targetPosition = new Vector3(x, y, z);
+ Vector3 leveledPosition = new Vector3(0, y, 0);
+
+ if (y < size - 1)
+ {
+ if (targetPosition.distance(leveledPosition) == 2)
+ {
+ returnMap.put(targetPosition, new Pair(Atomic.blockControlRod.blockID, 0));
+
+ /** Place piston base to push control rods in. */
+ int rotationMetadata = 0;
+ Vector3 offset = new Vector3(x, 0, z).normalize();
+
+ for (ForgeDirection checkDir : ForgeDirection.VALID_DIRECTIONS)
+ {
+ if (offset.x == checkDir.offsetX && offset.y == checkDir.offsetY && offset.z == checkDir.offsetZ)
+ {
+ rotationMetadata = checkDir.getOpposite().ordinal();
+ break;
+ }
+ }
+
+ returnMap.put(targetPosition.clone().translate(offset), new Pair(Block.pistonStickyBase.blockID, rotationMetadata));
+ }
+ else if (x == -r || x == r || z == -r || z == r)
+ {
+ returnMap.put(targetPosition, new Pair(Block.glass.blockID, 0));
+
+ }
+ else if (x == 0 && z == 0)
+ {
+ returnMap.put(targetPosition, new Pair(Atomic.blockReactorCell.blockID, 0));
+ }
+ else
+ {
+ returnMap.put(targetPosition, new Pair(Block.waterMoving.blockID, 0));
+ }
+ }
+ else if (targetPosition.distance(leveledPosition) < 2)
+ {
+ returnMap.put(targetPosition, new Pair(Atomic.blockElectricTurbine.blockID, 0));
+ }
+ }
+ }
+ }
+ }
+
+ return returnMap;
+ }
+}
diff --git a/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicFusionReactor.java b/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicFusionReactor.java
new file mode 100644
index 000000000..d08859244
--- /dev/null
+++ b/atomic/src/main/scala/resonantinduction/atomic/schematic/SchematicFusionReactor.java
@@ -0,0 +1,74 @@
+package resonantinduction.atomic.schematic;
+
+import java.util.HashMap;
+
+import net.minecraftforge.common.ForgeDirection;
+import resonant.lib.schematic.Schematic;
+import resonant.lib.type.Pair;
+import resonantinduction.atomic.Atomic;
+import universalelectricity.api.vector.Vector3;
+
+public class SchematicFusionReactor extends Schematic
+{
+ @Override
+ public String getName()
+ {
+ return "schematic.fusionReactor.name";
+ }
+
+ @Override
+ public HashMap> getStructure(ForgeDirection dir, int size)
+ {
+ HashMap> returnMap = new HashMap>();
+
+ /** Fusion Torus */
+ int radius = size + 2;
+
+ for (int x = -radius; x <= radius; x++)
+ {
+ for (int z = -radius; z <= radius; z++)
+ {
+ for (int y = 0; y <= size; y++)
+ {
+ Vector3 position = new Vector3(x, y, z);
+ double magnitude = Math.sqrt(x * x + z * z);
+
+ if (!returnMap.containsKey(position))
+ {
+ returnMap.put(position, new Pair(0, 0));
+ }
+
+ if (magnitude <= radius)
+ {
+ if (y == 0 || y == size)
+ {
+ if (magnitude >= 1)
+ {
+ double yDeviation = (y == 0 ? size / 3 : -size / 3) + (y == 0 ? -1 : 1) * Math.sin(magnitude / radius * Math.PI) * size / 2d;
+ Vector3 newPos = position.clone().translate(0, yDeviation, 0);
+ returnMap.put(newPos.round(), new Pair(Atomic.blockElectromagnet.blockID, 1));
+ }
+ }
+ else if (magnitude > radius - 1)
+ {
+ returnMap.put(position, new Pair(Atomic.blockElectromagnet.blockID, 0));
+ }
+ }
+ }
+ }
+ }
+ /** Fusion Core */
+ for (int y = 0; y < size; y++)
+ {
+ returnMap.put(new Vector3(0, y, 0), new Pair(Atomic.blockReactorCell.blockID, 0));
+ returnMap.put(new Vector3(1, y, 0), new Pair(Atomic.blockElectromagnet.blockID, 0));
+ returnMap.put(new Vector3(0, y, 1), new Pair(Atomic.blockElectromagnet.blockID, 0));
+ returnMap.put(new Vector3(0, y, -1), new Pair(Atomic.blockElectromagnet.blockID, 0));
+ returnMap.put(new Vector3(-1, y, 0), new Pair(Atomic.blockElectromagnet.blockID, 0));
+ }
+
+ returnMap.put(new Vector3(0, 0, 0), new Pair(Atomic.blockReactorCell.blockID, 0));
+
+ return returnMap;
+ }
+}
diff --git a/electrical/src/main/scala/resonantinduction/electrical/Electrical.java b/electrical/src/main/scala/resonantinduction/electrical/Electrical.java
index ff995f052..0db38b9fd 100644
--- a/electrical/src/main/scala/resonantinduction/electrical/Electrical.java
+++ b/electrical/src/main/scala/resonantinduction/electrical/Electrical.java
@@ -108,7 +108,7 @@ public class Electrical
@EventHandler
public void preInit(FMLPreInitializationEvent evt)
{
- modproxies = new ProxyHandler();
+ modproxies = new ProxyHandler();
NetworkRegistry.instance().registerGuiHandler(this, proxy);
Settings.CONFIGURATION.load();
diff --git a/models/atomic/centrifuge.tcn b/models/atomic/centrifuge.tcn
new file mode 100644
index 000000000..5b76c1396
Binary files /dev/null and b/models/atomic/centrifuge.tcn differ
diff --git a/models/atomic/chemicalExtractor.tcn b/models/atomic/chemicalExtractor.tcn
new file mode 100644
index 000000000..5cf33db23
Binary files /dev/null and b/models/atomic/chemicalExtractor.tcn differ
diff --git a/models/atomic/fusionReactor.tcn b/models/atomic/fusionReactor.tcn
new file mode 100644
index 000000000..b143cfeb6
Binary files /dev/null and b/models/atomic/fusionReactor.tcn differ
diff --git a/models/atomic/nuclearBoiler.tcn b/models/atomic/nuclearBoiler.tcn
new file mode 100644
index 000000000..c6c1c044b
Binary files /dev/null and b/models/atomic/nuclearBoiler.tcn differ
diff --git a/models/atomic/quantumAssembler.tcn b/models/atomic/quantumAssembler.tcn
new file mode 100644
index 000000000..75a211895
Binary files /dev/null and b/models/atomic/quantumAssembler.tcn differ
diff --git a/models/atomic/reactorCellBottom.tcn b/models/atomic/reactorCellBottom.tcn
new file mode 100644
index 000000000..0725691f2
Binary files /dev/null and b/models/atomic/reactorCellBottom.tcn differ
diff --git a/models/atomic/reactorCellMiddle.tcn b/models/atomic/reactorCellMiddle.tcn
new file mode 100644
index 000000000..6307e280e
Binary files /dev/null and b/models/atomic/reactorCellMiddle.tcn differ
diff --git a/models/atomic/reactorCellTop.tcn b/models/atomic/reactorCellTop.tcn
new file mode 100644
index 000000000..1ee418950
Binary files /dev/null and b/models/atomic/reactorCellTop.tcn differ
diff --git a/models/atomic/turbineLarge.tcn b/models/atomic/turbineLarge.tcn
new file mode 100644
index 000000000..7dc28e054
Binary files /dev/null and b/models/atomic/turbineLarge.tcn differ
diff --git a/models/atomic/turbineSmall.tcn b/models/atomic/turbineSmall.tcn
new file mode 100644
index 000000000..c0dc9b48e
Binary files /dev/null and b/models/atomic/turbineSmall.tcn differ
diff --git a/settings.gradle b/settings.gradle
index d8243eba7..0b8d5f7ac 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1,2 @@
rootProject.name = 'core'
-include 'archaic', 'mechanical', 'electrical'
\ No newline at end of file
+include 'archaic', 'mechanical', 'electrical', 'atomic'
\ No newline at end of file
diff --git a/src/main/resources/assets/resonantinduction/languages/de_DE.properties b/src/main/resources/assets/resonantinduction/languages/de_DE.properties
new file mode 100644
index 000000000..b4c9ecb51
--- /dev/null
+++ b/src/main/resources/assets/resonantinduction/languages/de_DE.properties
@@ -0,0 +1,305 @@
+# German @author Vexatos
+# If a localization includes %v it is some data that is calculated. Such as attributes on a cable.
+# The %v may be followed by a number if there are multiple pieces of calculated data, but it will be explained in a comment.
+# A % followed by a number is used for colors. The exact usage will be outlined in the comment above the localization.
+
+itemGroup.resonantinduction=Resonant Induction
+itemGroup.resonantinduction.core=Resonant Induction Core
+meta.resonantinduction.description=Resonant Induction ist eine Minecraft-Mod, die sich auf die Manipulation von Elektrizit\u00E4t und kabelloser Technologie spezialisiert. Wolltest du schon immer flammende elektrische Schocks durch deine Basis fliegen sehen? Dann bist du hier richtig!
+meta.resonantinduction.credits=Dank an Archadia f\u00FCr die tollen assets!
+
+fluid.mixture=Mixtur
+toolmode.link.name=Verbinden
+
+### Schematics
+schematic.windTurbine.name=Windturbine
+schematic.waterTurbine.name=Wasserturbine
+
+### Core
+misc.resonantinduction.ingot=Barren
+item.resonantinduction\:ingot.name=%vbarren
+item.resonantinduction\:oreDust.name=%vstaub
+item.resonantinduction\:oreDust.tooltip=Shift-rechtsklicke auf einen Kessel zum Raffinieren.
+item.resonantinduction\:oreRefinedDust.name=Gereinigter %vstaub
+item.resonantinduction\:oreRubble.name=%vschutt
+item.resonantinduction\:bucketMixture.name=Eimer mit %v
+item.resonantinduction\:bucketMolten.name=Eimer mit %v
+
+### Archaic Module
+## machineMaterials
+tile.resonantinduction\:gutter.name=Rinne
+tile.resonantinduction\:gutter.tooltip=Ein primitiver Weg, Fl\u00FCssigkeiten zu transportieren.
+tile.resonantinduction\:machineMaterial.0.name=Industrieziegel
+tile.resonantinduction\:machineMaterial.1.name=Industrieziegel
+tile.resonantinduction\:machineMaterial.2.name=Gemei\u00DFelter Industrieziegel
+tile.resonantinduction\:machineMaterial.3.name=Industriepflasterstein
+tile.resonantinduction\:machineMaterial.4.name=Br\u00FCchiger Industriestein
+tile.resonantinduction\:machineMaterial.5.name=Industriestein
+tile.resonantinduction\:machineMaterial.6.name=Industriesteinstufe
+tile.resonantinduction\:machineMaterial.7.name=Moosiger Industriestein
+tile.resonantinduction\:machineMaterial.8.name=Dunkler Stahl
+tile.resonantinduction\:machineMaterial.9.name=Get\u00F6nter Stahl
+tile.resonantinduction\:machineMaterial.10.name=Stahl
+
+## Items
+item.resonantinduction\:imprint.name=Pr\u00E4gung
+item.resonantinduction\:hammer.name=Hammer
+item.resonantinduction\:handCrank.name=Handkurbel
+
+## Machines
+tile.resonantinduction\:castingMold.name=Gussform
+tile.resonantinduction\:castingMold.tooltip=Gie\u00DFe fl\u00FCssiges Metall in die Form, um einen Barren zu gie\u00Dfen.
+tile.resonantinduction\:millstone.name=M\u00FChlstein
+tile.resonantinduction\:millstone.tooltip=Gib etwas Schutt hinein und nutze eine Handkurbel, um den Schutt zu Staub zu mahlen.
+tile.resonantinduction\:imprinter.name=Pr\u00E4ger
+tile.resonantinduction\:firebox.0.name=Feuerb\u00FCchse
+tile.resonantinduction\:firebox.1.name=Elektrische Feuerb\u00FCchse
+tile.resonantinduction\:hotPlate.name=Heizplatte
+
+tile.resonantinduction\:engineeringTable.name=Konstruktionstisch
+engineerTable.config.inventory.true=Konstruktionstisch ist nun mit nahen Inventaren verbunden.
+engineerTable.config.inventory.false=Konstruktionstisch ist nun mit nahen Inventaren getrennt.
+
+## Transport
+tile.resonantinduction\:turntable.name=Drehscheibe
+tile.resonantinduction\:crate.0.name=Holzkiste
+tile.resonantinduction\:crate.1.name=Eisenkiste
+tile.resonantinduction\:crate.2.name=Stahlkiste
+
+crate.orefilter.true= OreDictionary-Unterst\u00FCtzung aktiviert
+crate.orefilter.false= OreDictionary-Unterst\u00FCtzung deaktiviert
+crate.tooltip.amount= Menge:
+
+tile.resonantinduction\:crate.0.tooltip=Rechtsklicke, um Items hinzuzuf\u00Fcgen, linksklicke, um Items zu entfernen, Strg-klicke, um Item-Filtermodus zu setzen
+tile.resonantinduction\:crate.1.tooltip=Rechtsklicke, um Items hinzuzuf\u00Fcgen, linksklicke, um Items zu entfernen, Strg-klicke, um Item-Filtermodus zu setzen
+tile.resonantinduction\:crate.2.tooltip=Rechtsklicke, um Items hinzuzuf\u00Fcgen, linksklicke, um Items zu entfernen, Strg-klicke, um Item-Filtermodus zu setzen
+
+### Mechanical Module
+## Energy
+item.resonantinduction\:gear.0.name=Holzzahnrad
+item.resonantinduction\:gear.1.name=Steinzahnrad
+item.resonantinduction\:gear.2.name=Metallzahnrad
+item.resonantinduction\:gear.10.name=K\u00FCrbiszahnrad
+item.resonantinduction\:gearShaft.0.name=Holzzahnradschaft
+item.resonantinduction\:gearShaft.1.name=Steinzahnradschaft
+item.resonantinduction\:gearShaft.2.name=Metallzahnradschaft
+tile.resonantinduction\:windTurbine.0.name=H\u00F6lzerne Windturbine
+tile.resonantinduction\:windTurbine.0.tooltip=Die h\u00F6lzerne Windturbine ist leicht, fragil und dreht sich schnell.
+tile.resonantinduction\:windTurbine.1.name=Steinerne Windturbine
+tile.resonantinduction\:windTurbine.1.tooltip=Die steinerne Windturbine ist schwer, kr\u00E4ftig und strapazierf\u00E4hig.
+tile.resonantinduction\:windTurbine.2.name=Metall-Windturbine
+tile.resonantinduction\:windTurbine.2.tooltip=Die Metall-Windturbine ist kr\u00E4ftig und agil.
+tile.resonantinduction\:waterTurbine.0.name=H\u00F6lzerne Wasserturbine
+tile.resonantinduction\:waterTurbine.0.tooltip=Die h\u00F6lzerne Wasserturbine ist leicht und bewegt sich schnell
+tile.resonantinduction\:waterTurbine.1.name=Steinerne Wasserturbine
+tile.resonantinduction\:waterTurbine.1.tooltip=Die steinerne Wasserturbine ist schwer,kr\u00E4ftig und strapazierf\u00E4hig.
+tile.resonantinduction\:waterTurbine.2.name=Metall-Wasserturbine
+tile.resonantinduction\:waterTurbine.2.tooltip=Die Metall-Wasserturbine ist kr\u00E4ftig und agil.
+
+## Transport
+item.resonantinduction\:pipe.ceramic.name=Keramikrohr
+item.resonantinduction\:pipe.bronze.name=Bronzerohr
+item.resonantinduction\:pipe.plastic.name=Plastikrohr
+item.resonantinduction\:pipe.iron.name=Eisenrohr
+item.resonantinduction\:pipe.steel.name=Stahlrohr
+item.resonantinduction\:pipe.fiberglass.name=Glasfaserrohr
+tile.resonantinduction\:pump.name=Pumpe
+tile.resonantinduction\:grate.name=Gitter
+tile.resonantinduction\:conveyorBelt.name=Flie\u00DFband
+tile.resonantinduction\:tank.name=Tank
+tile.resonantinduction\:tank.tooltip=Shift-rechtsklicke, um mit enthaltener Fl\u00FCssigkeit aufzunehmen.
+tile.resonantinduction\:detector.name=Detektor
+tile.resonantinduction\:detector.tooltip=Sendet ein Redstone-Signal, wenn er ein Item entdeckt. Konfiguriere, um den Pr\u00E4gungsfilter zu invertieren.
+tile.resonantinduction\:manipulator.name=Manipulator
+tile.resonantinduction\:rejector.name=Rejektor
+tile.resonantinduction\:sorter.name=Sortierer
+tile.resonantinduction\:breaker.name=Blockzerst\u00F6rer
+tile.resonantinduction\:placer.name=Blockplatzierer
+
+## Machines and Processing
+tile.resonantinduction\:mixer.name=Mixer
+tile.resonantinduction\:mixer.tooltip=Der Mixer mischt Staub mit Wasser, um den Erzstaub zu reinigen. Der Mixer ben\u00F6tigt eine hohe Geschwindigkeit, um Staub zu reinigen.
+tile.resonantinduction\:mechanicalPiston.name=Mechanischer Kolben
+tile.resonantinduction\:grindingWheel.name=Mahlwerkrad
+tile.resonantinduction\:grindingWheel.tooltip=Das Mahlwerkrad mahlt Erze zu Schutt und Staub. Gr\u00F6\u00DFeres Drehmoment erm\u00F6glicht schnelleres Mahlen.
+tile.resonantinduction\:filter.name=Filter
+resonantinduction.machine.grinder=Mahlwerk
+resonantinduction.machine.crusher=Zersto\u00DFer
+resonantinduction.machine.mixer=Mixer
+resonantinduction.machine.sawmill=S\u00E4gewerk
+resonantinduction.machine.smelter=Schmelzer
+
+### Electrical Module
+## Blocks
+tile.resonantinduction\:tesla.name=Teslaspule
+tile.resonantinduction\:tesla.tooltip=\u00DCbertr\u00E4gt Strom drahtlos. Verbinde mit dem Konfigurator f\u00FCr Teleportation zwischen Dimensionen.
+item.resonantinduction\:levitator.name=Elektromagnetischer Levitator
+tile.resonantinduction\:battery.name=Batterie
+tile.resonantinduction\:armbot.name=Roboterarm
+tile.resonantinduction\:encoder.name=Kodierer
+item.resonantinduction\:charger.name=Ladeplatte
+item.resonantinduction\:insulation.name=Isolierung
+
+## Generators
+tile.resonantinduction\:solarPanel.name=Solarmodul
+tile.resonantinduction\:motor.name=Elektromotor
+tile.resonantinduction\:thermopile.name=Thermos\u00E4ule
+tile.resonantinduction\:thermopile.tooltip=Generiert eine Spannung proportional zu lokaler Temperaturdifferenz.
+
+#Transport
+item.resonantinduction\:disk.name=Programmplatte
+
+## Energy
+item.resonantinduction\:wire.copper.name=Kupferkabel
+item.resonantinduction\:wire.tin.name=Zinnkabel
+item.resonantinduction\:wire.iron.name=Eisenkabel
+item.resonantinduction\:wire.aluminum.name=Aluminiumkabel
+item.resonantinduction\:wire.silver.name=Silberkabel
+item.resonantinduction\:wire.superconductor.name=Supraleitkabel
+item.resonantinduction\:transformer.name=Transformator
+item.resonantinduction\:multimeter.name=Multimeter
+item.resonantinduction\:multimeter.tooltip=Multimeter ist eine Platte, die Energie- und Fl\u00FCssigkeitsinformationen eines Blocks anzeigt.
+
+### Quantum Tier
+tile.resonantinduction\:quantumGate.name=Quantentor
+item.resonantinduction\:quantumGlyph.0.name=Nullum-Glyphe
+item.resonantinduction\:quantumGlyph.1.name=Monogon-Glyphe
+item.resonantinduction\:quantumGlyph.2.name=Digon-Glyphe
+item.resonantinduction\:quantumGlyph.3.name=Trigon-Glyphe
+item.resonantinduction\:quantumGlyph.4.name=Tetragon-Glyphe
+
+## Tool-tips
+tooltip.mixture=Mixtur
+tooltip.molten=Geschmolzenem
+
+tooltip.pipe.rate=Flie\u00DFrate: %v
+tooltip.pipe.pressure=Max-Druck: %v
+
+tooltip.wire.resistance=Widerstand: %v
+tooltip.wire.current=Stromst\u00E4rke: %v
+tooltip.wire.damage=Schaden: %v
+tooltip.wire.helpText=Die Energietransferrate kann erh\u00F6ht sowie der Energieverlust reduziert werden, wenn eine h\u00F6here Spannung verwendet wird.
+# %0 is the color for the charge level, %1 is grey to reset it back to normal (optional), %v0 is the current charge, %v1 is the max charge
+tooltip.battery.energy=Energie: %0%v0 / %v1
+tooltip.noInformation=Keine Information
+tooltip.tier=Stufe
+tooltip.empty=Leer
+tooltip.noOutput=Kein Resultat
+tooltip.noImprint=Keine Pr\u00E4gung
+
+tooltip.graph.energy=Energie
+tooltip.graph.power=Energie
+tooltip.graph.capacity=Kapazit\u00E4t
+tooltip.graph.voltage=Spannung
+tooltip.graph.torque=Drehmoment
+tooltip.graph.speed=Winkelgeschw.
+tooltip.graph.fluid=Fl\u00FCssigkeit
+tooltip.graph.temperature=Temperatur
+tooltip.graph.pressure=Druck
+
+## GUI Strings that can't be any other localization
+gui.resonantinduction.multimeter.toggle=Wechseln
+gui.resonantinduction.multimeter.toggleDetection=Erkennung wechseln
+gui.resonantinduction.multimeter.toggleGraph=Graphen wechseln
+gui.resonantinduction.multimeter.averageEnergy=Energiedurchschnitt:
+gui.resonantinduction.multimeter.energy=Energie:
+gui.resonantinduction.multimeter.redstone=Versende Redstone, wenn...
+gui.resonantinduction.multimeter.logic=Logik:
+
+gui.resonantinduction.multimeter.none=Nie
+gui.resonantinduction.multimeter.lessThan=Unter
+gui.resonantinduction.multimeter.lessThanOrEqual=Unter oder Gleich Wie
+gui.resonantinduction.multimeter.equal=Gleich Wie
+gui.resonantinduction.multimeter.greaterThanOrEqual=\u00DCber oder Gleich Wie
+gui.resonantinduction.multimeter.greaterThan=\u00DCber
+
+## Messages to players
+message.multimeter.onUse=Energie: %v J
+message.tesla.toggleAttack=\u00C4ndere Energieangriff auf: %v
+# %v0 is the tile that's linking to the other (usually %v0 is a tesla), the others are coordinates in the standard [x, y, z]
+message.tesla.pair=%v0 mit [%v1, %v2, %v3] verbunden
+message.tesla.mode=Tesla-Empfangsmodus ist nun %v
+
+### Atomic Module
+## Translated by Vexatos
+itemGroup.atomicscience=Atomic Science
+potion.radiation=Strahlung
+death.attack.radiation=%1$s starb durch Verstrahlung.
+
+## Schematic
+schematic.accelerator.name=Teilchenbeschleuniger
+schematic.breedingReactor.name=Brutreaktor
+schematic.fissionReactor.name=Kernreaktor
+schematic.fusionReactor.name=Fusionsreaktor
+
+## Fluids
+fluid.uraniumhexafluoride=Uranhexafluorid
+fluid.deuterium=Deuterium
+fluid.tritium=Tritium
+fluid.plasma=Plasma
+fluid.steam=Dampf
+fluid.toxicwaste=Giftm\u00FCll
+fluid.tile.water=Wasser
+
+item.resonantinduction\:hazmatMask.name=Chemikalienschutzmaske
+item.resonantinduction\:hazmatBody.name=Chemikalienschutzjacke
+item.resonantinduction\:hazmatLeggings.name=Chemikalienschutzhose
+item.resonantinduction\:hazmatBoots.name=Chemikalienschutzstiefel
+item.resonantinduction\:bucketToxicWaste.name=Giftm\u00FClleimer
+
+## Cells
+item.resonantinduction\:cellEmpty.name=Leere Zelle
+item.resonantinduction\:cellWater.name=Wasserzelle
+item.resonantinduction\:cellDeuterium.name=Deuteriumzelle
+item.resonantinduction\:cellTritium.name=Tritiumzelle
+item.resonantinduction\:darkMatter.name=Dunkle Materie
+item.resonantinduction\:antimatter.0.name=Antimaterie
+item.resonantinduction\:antimatter.0.tooltip=1 Gramm
+item.resonantinduction\:antimatter.1.name=Antimaterie
+item.resonantinduction\:antimatter.1.tooltip=125 Milligramm
+
+## Uranium Related Items
+tile.resonantinduction\:uraniumOre.name=Uranerz
+item.resonantinduction\:yellowcake.name=Yellowcake
+item.resonantinduction\:uranium.0.name=Uran-235
+item.resonantinduction\:uranium.0.tooltip=Angereichertes Uran
+item.resonantinduction\:uranium.1.name=Uran-238
+item.resonantinduction\:uranium.1.tooltip=Bruturan
+item.resonantinduction\:rodFissileFuel.name=Kernbrennstab
+item.resonantinduction\:rodFissileFuel.tooltip=Die prim\u00E4re Brennstoffquelle f\u00FCr Kernreaktoren.
+item.resonantinduction\:rodBreederFuel.name=Brutbrennstab
+item.resonantinduction\:rodBreederFuel.tooltip=Ein Brennstoff, um zerfallene Kernbrennst\u00E4be wieder anzureichern.
+item.resonantinduction\:uraniumHexafluoride.name=Uranhexafluorid
+item.resonantinduction\:steam.name=Dampf
+
+## Blocks
+tile.resonantinduction\:reactorDrain.name=Reaktorabfluss
+tile.resonantinduction\:reactorDrain.tooltip=Extrahiert Fl\u00FCssigkeiten aus dem Reaktor, zum Beispiel Giftm\u00FCll.
+tile.resonantinduction\:nuclearBoiler.name=Nuklearheizkessel
+tile.resonantinduction\:centrifuge.name=Zentrifuge
+tile.resonantinduction\:reactorCell.name=Reaktorzelle
+tile.resonantinduction\:reactorCell.tooltip=Reaktorzellen werden als prim\u00E4re Komponente f\u00Fcr alle Reaktorarten verwendet. Brennst\u00E4be oder Plasma kann in eine Zelle injeziert werden.
+tile.resonantinduction\:plasmaHeater.name=Plasmaerhitzer
+tile.resonantinduction\:reactorExpansion.name=Reaktorerweiterung
+tile.resonantinduction\:electricTurbine.name=Elektrische Turbine
+tile.resonantinduction\:radioactive.name=Radioaktives Material
+tile.resonantinduction\:thermometer.name=Thermometer
+tile.resonantinduction\:thermometer.tooltip=Das Thermometer liest die Temperatur an der aktuellen Position. Shift-rechtsklicke, um die Messung auf bestimmte Koordinaten zu beschr\u00E4nken.
+tile.resonantinduction\:electromagnet.name=Elektromagnet
+tile.resonantinduction\:chemicalExtractor.name=Chemischer Extraktor
+tile.resonantinduction\:siren.name=Sirene
+tile.resonantinduction\:electromagnetGlass.name=Electromagnetisches Glas
+tile.resonantinduction\:controlRod.name=Steuerstab
+tile.resonantinduction\:plasma.name=Plasma
+tile.resonantinduction\:funnel.name=Dampftrichter
+tile.resonantinduction\:accelerator.name=Teilchenbeschleuniger
+tile.resonantinduction\:fulmination.name=Fulminationsgenerator
+tile.resonantinduction\:quantumAssembler.name=Quantenassembler
+tile.resonantinduction\:toxicWaste.name=Giftm\u00FCll
+
+## Tooltips
+tooltip.energy=Energie
+tooltip.temperature=Temperatur
+tooltip.remainingTime=Verbleibende Zeit
+tooltip.trackingTemperature=Messe Temperatur bei:
+tooltip.notTrackingTemperature=Misst momentan keine Temperatur.
\ No newline at end of file
diff --git a/src/main/resources/assets/resonantinduction/languages/en_US.properties b/src/main/resources/assets/resonantinduction/languages/en_US.properties
new file mode 100644
index 000000000..5a83e0614
--- /dev/null
+++ b/src/main/resources/assets/resonantinduction/languages/en_US.properties
@@ -0,0 +1,331 @@
+# English @author Calclavia, Alex_hawks
+# If a localization includes %v it is some data that is calculated. Such as attributes on a cable.
+# The %v may be followed by a number if there are multiple pieces of calculated data, but it will be explained in a comment.
+# A % followed by a number is used for colors. The exact usage will be outlined in the comment above the localization.
+
+itemGroup.resonantinduction=Resonant Induction
+itemGroup.resonantinduction.core=Resonant Induction Core
+meta.resonantinduction.description=Resonant Induction is a Minecraft mod focusing on the manipulation of electricity and wireless technology. Ever wanted blazing electrical shocks flying off your evil lairs? You've came to the right place!
+meta.resonantinduction.credits=Visit website for credits.
+
+fluid.mixture=Mixture
+toolmode.link.name=Linking
+
+### Schematics
+schematic.windTurbine.name=Wind Turbine
+schematic.waterTurbine.name=Water Turbine
+
+### Core
+misc.resonantinduction.ingot=Ingot
+item.resonantinduction\:ingot.name=%v Ingot
+item.resonantinduction\:oreDust.name=%v Dust
+item.resonantinduction\:oreDust.tooltip=Shift-right click on a cauldron to refine.
+item.resonantinduction\:oreRefinedDust.name=%v Refined Dust
+item.resonantinduction\:oreRubble.name=%v Rubble
+item.resonantinduction\:bucketMixture.name=%v Bucket
+item.resonantinduction\:bucketMolten.name=%v Bucket
+
+### Archaic Module
+## machineMaterials
+tile.resonantinduction\:gutter.name=Gutter
+tile.resonantinduction\:gutter.tooltip=A primitive way of transfering liquid.
+tile.resonantinduction\:machineMaterial.0.name=Industrial Brick
+tile.resonantinduction\:machineMaterial.1.name=Industrial Brick
+tile.resonantinduction\:machineMaterial.2.name=Industrial Chiseled Brick
+tile.resonantinduction\:machineMaterial.3.name=Industrial Cobblestone
+tile.resonantinduction\:machineMaterial.4.name=Industrial Cracked Stone
+tile.resonantinduction\:machineMaterial.5.name=Industrial Stone
+tile.resonantinduction\:machineMaterial.6.name=Industrial Stone Slab
+tile.resonantinduction\:machineMaterial.7.name=Industrial Mossy Stone
+tile.resonantinduction\:machineMaterial.8.name=Dark Steel
+tile.resonantinduction\:machineMaterial.9.name=Tinted Steel
+tile.resonantinduction\:machineMaterial.10.name=Steel
+
+## Items
+item.resonantinduction\:imprint.name=Imprint
+item.resonantinduction\:hammer.name=Hammer
+item.resonantinduction\:handCrank.name=Hand Crank
+
+## Machines
+tile.resonantinduction\:castingMold.name=Casting Mold
+tile.resonantinduction\:castingMold.tooltip=Pour molten metal into the cast to form an ingot.
+tile.resonantinduction\:millstone.name=Millstone
+tile.resonantinduction\:millstone.tooltip=Put some rubble in the millstone and use a hand crank to grind rubble into dust.
+tile.resonantinduction\:imprinter.name=Imprinter
+tile.resonantinduction\:firebox.0.name=Firebox
+tile.resonantinduction\:firebox.1.name=Electric Firebox
+tile.resonantinduction\:hotPlate.name=Hot Plate
+
+tile.resonantinduction\:engineeringTable.name=Engineering Table
+engineerTable.config.inventory.true=Engineering table is now connected to nearby inventories.
+engineerTable.config.inventory.false=Engineering table is now disconnected from nearby inventories.
+
+## Transport
+tile.resonantinduction\:turntable.name=Turntable
+tile.resonantinduction\:crate.0.name=Wooden Crate
+tile.resonantinduction\:crate.1.name=Iron Crate
+tile.resonantinduction\:crate.2.name=Steel Crate
+
+info.waila.crate.stack=Item:
+info.waila.crate.stored=Stored:
+info.waila.crate.empty=Empty
+
+crate.orefilter.true= Same OreName stacking enabled
+crate.orefilter.false= Same OreName stacking disabled
+crate.tooltip.amount= Amount:
+
+tile.resonantinduction\:crate.0.tooltip=Right click to add items Left click to remove items Ctrl Click sets itemstack filter
+tile.resonantinduction\:crate.1.tooltip=Right click to add items Left click to remove items Ctrl Click sets itemstack filter
+tile.resonantinduction\:crate.2.tooltip=Right click to add items Left click to remove items Ctrl Click sets itemstack filter
+
+tile.resonantinduction\:tank.name=Tank
+tile.resonantinduction\:tank.tooltip=Shift right click to pick up with fluid contained within.
+info.waila.tank.fluid=Fluid:
+info.waila.tank.vol=Volume:
+info.waila.tank.empty=Empty
+
+### Mechanical Module
+## Energy
+item.resonantinduction\:gear.0.name=Wooden Gear
+item.resonantinduction\:gear.1.name=Stone Gear
+item.resonantinduction\:gear.2.name=Metal Gear
+item.resonantinduction\:gear.10.name=Pumpkin Gear
+item.resonantinduction\:gearShaft.0.name=Wooden Gear Shaft
+item.resonantinduction\:gearShaft.1.name=Stone Gear Shaft
+item.resonantinduction\:gearShaft.2.name=Metal Gear Shaft
+tile.resonantinduction\:windTurbine.0.name=Wooden Wind Turbine
+tile.resonantinduction\:windTurbine.0.tooltip=The wooden wind turbine is light, fragile and spins fast.
+tile.resonantinduction\:windTurbine.1.name=Stone Wind Turbine
+tile.resonantinduction\:windTurbine.1.tooltip=The stone turbine is heavy, strong and durable.
+tile.resonantinduction\:windTurbine.2.name=Metal Wind Turbine
+tile.resonantinduction\:windTurbine.2.tooltip=The metal wind turbine is strong and agile.
+tile.resonantinduction\:waterTurbine.0.name=Wooden Water Turbine
+tile.resonantinduction\:waterTurbine.0.tooltip=The wooden water turbine is light and moves fast.
+tile.resonantinduction\:waterTurbine.1.name=Stone Water Turbine
+tile.resonantinduction\:waterTurbine.1.tooltip=The stone water turbine is heavy, strong and durable.
+tile.resonantinduction\:waterTurbine.2.name=Metal Water Turbine
+tile.resonantinduction\:waterTurbine.2.tooltip=The metal water turbine is strong and agile.
+
+## Transport
+item.resonantinduction\:pipe.ceramic.name=Ceramic Pipe
+item.resonantinduction\:pipe.bronze.name=Bronze Pipe
+item.resonantinduction\:pipe.plastic.name=Plastic Pipe
+item.resonantinduction\:pipe.iron.name=Iron Pipe
+item.resonantinduction\:pipe.steel.name=Steel Pipe
+item.resonantinduction\:pipe.fiberglass.name=Fiberglass Pipe
+tile.resonantinduction\:pump.name=Pump
+tile.resonantinduction\:grate.name=Grate
+tile.resonantinduction\:conveyorBelt.name=Conveyor Belt
+
+tile.resonantinduction\:detector.name=Detector
+tile.resonantinduction\:detector.tooltip=Outputs a Redstone signal upon item detection. Configure to invert imprint filter.
+tile.resonantinduction\:manipulator.name=Manipulator
+tile.resonantinduction\:rejector.name=Rejector
+tile.resonantinduction\:sorter.name=Sorter
+tile.resonantinduction\:breaker.name=Breaker
+tile.resonantinduction\:placer.name=Placer
+
+## Machines and Processing
+tile.resonantinduction\:mixer.name=Mixer
+tile.resonantinduction\:mixer.tooltip=The mixer mixes dusts with water to wash and refine the ore dust. Mixer prefers more angular velocity (spin) to process dusts.
+tile.resonantinduction\:mechanicalPiston.name=Mechanical Piston
+tile.resonantinduction\:grindingWheel.name=Grinding Wheel
+tile.resonantinduction\:grindingWheel.tooltip=The grinding wheel grinds ores into rubble and dust. Larger torque allows faster grinding.
+tile.resonantinduction\:filter.name=Filter
+resonantinduction.machine.grinder=Grinder
+resonantinduction.machine.crusher=Crusher
+resonantinduction.machine.mixer=Mixer
+resonantinduction.machine.sawmill=Saw-mill
+resonantinduction.machine.smelter=Smelter
+
+### Electrical Module
+## Blocks
+tile.resonantinduction\:tesla.name=Tesla Coil
+tile.resonantinduction\:tesla.tooltip=Transfer electricity wirelessly. Link with a configurator for cross dimension teleportation.
+item.resonantinduction\:levitator.name=Electromagnetic Levitator
+tile.resonantinduction\:battery.name=Battery
+tile.resonantinduction\:armbot.name=Armbot
+tile.resonantinduction\:encoder.name=Encoder
+item.resonantinduction\:charger.name=Charging Plate
+item.resonantinduction\:insulation.name=Insulation
+
+tool.mode.set=Mode set to:
+laser.toolmode.remove=Remove
+laser.toolmode.smelt=Smelt
+laser.toolmode.damage=Damage
+
+## Generators
+tile.resonantinduction\:solarPanel.name=Solar Panel
+tile.resonantinduction\:motor.name=Electric Motor
+tile.resonantinduction\:thermopile.name=Thermopile
+tile.resonantinduction\:thermopile.tooltip=Generates a voltage proportional to local temperature difference.
+
+#Transport
+item.resonantinduction\:disk.name=Program Disk
+
+## Energy
+item.resonantinduction\:wire.copper.name=Copper Wire
+item.resonantinduction\:wire.tin.name=Tin Wire
+item.resonantinduction\:wire.iron.name=Iron Wire
+item.resonantinduction\:wire.aluminum.name=Aluminum Wire
+item.resonantinduction\:wire.silver.name=Silver Wire
+item.resonantinduction\:wire.superconductor.name=Superconductor Wire
+item.resonantinduction\:transformer.name=Transformer
+item.resonantinduction\:multimeter.name=Multimeter
+item.resonantinduction\:multimeter.tooltip=Multimeter is a panel that display the energy and fluid information of a block.
+
+### Quantum Tier
+tile.resonantinduction\:quantumGate.name=Quantum Gate
+item.resonantinduction\:quantumGlyph.0.name=Nought Glyph
+item.resonantinduction\:quantumGlyph.1.name=Monogon Glyph
+item.resonantinduction\:quantumGlyph.2.name=Digon Glyph
+item.resonantinduction\:quantumGlyph.3.name=Trigon Glyph
+item.resonantinduction\:quantumGlyph.4.name=Tetragon Glyph
+
+## Tool-tips
+tooltip.mixture=Mixture
+tooltip.molten=Molten
+
+tooltip.pipe.rate=Flow Rate: %v
+tooltip.pipe.pressure=Max Pressure: %v
+
+tooltip.wire.resistance=Resistance: %v
+tooltip.wire.current=Current: %v
+tooltip.wire.damage=Damage: %v
+tooltip.wire.helpText=Higher voltages will increase transfer rate and decrease energy loss. Shift right click to place a framed wire.
+# %0 is the color for the charge level, %1 is grey to reset it back to normal (optional), %v0 is the current charge, %v1 is the max charge
+tooltip.battery.energy=Energy: %0%v0 / %v1
+tooltip.noInformation=No Information
+tooltip.tier=Tier
+tooltip.empty=Empty
+tooltip.noOutput=No Output
+tooltip.noImprint=No Imprint
+
+tooltip.graph.energy=Energy
+tooltip.graph.power=Power
+tooltip.graph.capacity=Capacity
+tooltip.graph.voltage=Voltage
+tooltip.graph.torque=Torque
+tooltip.graph.speed=Speed
+tooltip.graph.fluid=Fluid
+tooltip.graph.temperature=Temperature
+tooltip.graph.pressure=Pressure
+
+## GUI Strings that can't be any other localization
+gui.resonantinduction.multimeter.toggle=Toggle
+gui.resonantinduction.multimeter.toggleDetection=Toggle Detection
+gui.resonantinduction.multimeter.toggleGraph=Toggle Graph
+gui.resonantinduction.multimeter.capacity=Capacity:
+gui.resonantinduction.multimeter.energy=Energy:
+gui.resonantinduction.multimeter.redstone=Output Redstone If...
+gui.resonantinduction.multimeter.logic=Logic:
+
+gui.resonantinduction.multimeter.none=None
+gui.resonantinduction.multimeter.lessThan=Less Than
+gui.resonantinduction.multimeter.lessThanOrEqual=Less Than or Equal
+gui.resonantinduction.multimeter.equal=Equal
+gui.resonantinduction.multimeter.greaterThanOrEqual=Greater Than or Equal
+gui.resonantinduction.multimeter.greaterThan=Greater Than
+
+## Messages to players
+message.multimeter.onUse=Energy: %v J
+message.tesla.toggleAttack=Toggled entity attack to: %v
+# %v0 is the tile that's linking to the other (usually %v0 is a tesla), the others are coordinates in the standard [x, y, z]
+message.tesla.pair=Linked %v0 with [%v1, %v2, %v3]
+message.tesla.mode=Tesla receive mode is now %v
+
+### Atomic Module
+potion.radiation=Radiation
+death.attack.radiation=%1$s died from radiation.
+
+## Schematic
+schematic.accelerator.name=Particle Accelerator
+schematic.breedingReactor.name=Breeding Reactor
+schematic.fissionReactor.name=Fission Reactor
+schematic.fusionReactor.name=Fusion Reactor
+
+## Fluids
+fluid.uraniumhexafluoride=Uranium Hexafluoride
+fluid.deuterium=Deuterium
+fluid.tritium=Tritium
+fluid.plasma=Plasma
+fluid.steam=Steam
+fluid.toxicwaste=Toxic Waste
+fluid.tile.water=Water
+
+item.resonantinduction\:hazmatMask.name=Hazmat Mask
+item.resonantinduction\:hazmatBody.name=Hazmat Body
+item.resonantinduction\:hazmatLeggings.name=Hazmat Leggings
+item.resonantinduction\:hazmatBoots.name=Hazmat Boots
+item.resonantinduction\:bucketToxicWaste.name=Toxic Waste Bucket
+
+## Cells
+item.resonantinduction\:cellEmpty.name=Empty Cell
+item.resonantinduction\:cellWater.name=Water Cell
+item.resonantinduction\:cellDeuterium.name=Deuterium Cell
+item.resonantinduction\:cellTritium.name=Tritium Cell
+item.resonantinduction\:darkMatter.name=Dark Matter
+item.resonantinduction\:antimatter.0.name=Antimatter
+item.resonantinduction\:antimatter.0.tooltip=1 Gram
+item.resonantinduction\:antimatter.1.name=Antimatter
+item.resonantinduction\:antimatter.1.tooltip=125 Milligrams
+
+## Uranium Related Items
+item.resonantinduction\:yellowcake.name=Yellowcake
+item.resonantinduction\:uranium.0.name=Uranium-235
+item.resonantinduction\:uranium.0.tooltip=Enriched Uranium
+item.resonantinduction\:uranium.1.name=Uranium-238
+item.resonantinduction\:uranium.1.tooltip=Breeding Uranium
+item.resonantinduction\:rodFissileFuel.name=Fissile Fuel Rod
+item.resonantinduction\:rodFissileFuel.tooltip=The primary fuel source for fission reactors.
+item.resonantinduction\:rodBreederFuel.name=Breeder Fuel Rod
+item.resonantinduction\:rodBreederFuel.tooltip=The fuel source for re-breeding decayed fissile fuels.
+item.resonantinduction\:uraniumHexafluoride.name=Uranium Hexafluoride
+item.resonantinduction\:steam.name=Steam
+
+## Blocks
+tile.resonantinduction\:uraniumOre.name=Uranium Ore
+tile.resonantinduction\:uraniumOre.tooltip=A precious and useful ore used for fission reactions.
+tile.resonantinduction\:reactorDrain.name=Reactor Drain
+tile.resonantinduction\:reactorDrain.tooltip=Extracts fluids out of the reactor, such as toxic waste.
+tile.resonantinduction\:nuclearBoiler.name=Nuclear Boiler
+tile.resonantinduction\:nuclearBoiler.tooltip=Boils yellowcake into uranium hexaflouride gas.
+tile.resonantinduction\:centrifuge.name=Centrifuge
+tile.resonantinduction\:centrifuge.tooltip=Refines Uranium Hexafluoride gas into usable uranium.
+tile.resonantinduction\:reactorCell.name=Reactor Cell
+tile.resonantinduction\:reactorCell.tooltip=The primary components for all types of reactors. Fuel rods or plasma may be injected into the cell.
+tile.resonantinduction\:plasmaHeater.name=Plasma Heater
+tile.resonantinduction\:plasmaHeater.tooltip=A plasma heater is used to heat deuterium and tritium to plasma state for fusion power. Plasma must be moved into the reactor cell.
+tile.resonantinduction\:electricTurbine.name=Electric Turbine
+tile.resonantinduction\:electricTurbine.tooltip=Transform the kinetic energy from moving steam into electrical energy.
+tile.resonantinduction\:radioactive.name=Radioactive Waste
+tile.resonantinduction\:radioactive.tooltip=Generates harmful radiation and spreads around the world, mutating organisms.
+tile.resonantinduction\:thermometer.name=Thermometer
+tile.resonantinduction\:thermometer.tooltip=Reads the temperature at the current coordinate. Shift-right click to lock the reading to a specific coordinate.
+tile.resonantinduction\:electromagnet.name=Electromagnet
+tile.resonantinduction\:electromagnet.tooltip=Creates an electromagnetic field preventing plasma and particles from getting near.
+tile.resonantinduction\:chemicalExtractor.name=Chemical Extractor
+tile.resonantinduction\:chemicalExtractor.tooltip=Extracts uranium ores to yellowcake, water to deuterium and deuterium to tritium.
+tile.resonantinduction\:siren.name=Siren
+tile.resonantinduction\:siren.tooltip=Creates an alarm with customizable pitch and volume with a Redstone signal.
+tile.resonantinduction\:controlRod.name=Control Rod
+tile.resonantinduction\:controlRod.tooltip=Suppresses fission reaction in adjacent reactor cells.
+tile.resonantinduction\:plasma.name=Plasma
+tile.resonantinduction\:plasma.tooltip=Generates extreme heat for boiling water.
+tile.resonantinduction\:funnel.name=Gas Funnel
+tile.resonantinduction\:funnel.tooltip=Captures gas to allow it to be transported with piping.
+tile.resonantinduction\:accelerator.name=Particle Accelerator
+tile.resonantinduction\:accelerator.tooltip=Accelerates particles and creates antimatter and dark matter.
+tile.resonantinduction\:fulmination.name=Fulmination Generator
+tile.resonantinduction\:fulmination.tooltip=Transforms the kinetic energy from explosions into electrical energy.
+tile.resonantinduction\:quantumAssembler.name=Quantum Assembler
+tile.resonantinduction\:quantumAssembler.tooltip=Reassembles Dark Matter atoms into usable materials.
+tile.resonantinduction\:toxicWaste.name=Toxic Waste
+tile.resonantinduction\:toxicWaste.tooltip=Toxic, nuclear waste that pollutes the world.
+
+## Tooltips
+tooltip.energy=Energy
+tooltip.temperature=Temperature
+tooltip.remainingTime=Remaining Time
+tooltip.trackingTemperature=Tracking temperature at:
+tooltip.notTrackingTemperature=Not tracking temperature.
\ No newline at end of file
diff --git a/src/main/resources/assets/resonantinduction/languages/pl_PL.properties b/src/main/resources/assets/resonantinduction/languages/pl_PL.properties
new file mode 100644
index 000000000..f1a533722
--- /dev/null
+++ b/src/main/resources/assets/resonantinduction/languages/pl_PL.properties
@@ -0,0 +1,51 @@
+# spolszczenie wykonane przez unekpl
+itemGroup.atomicscience=Atomic Science
+potion.radiation=Napromieniowanie
+death.attack.radiation=%1$s umar\u0142 z napromieniowania.
+
+item.resonantinduction\:hazmatMask.name=Maska hazmat
+item.resonantinduction\:hazmatBody.name=Napier\u015Bnik hazmat
+item.resonantinduction\:hazmatLeggings.name=Nogawice hazmat
+item.resonantinduction\:hazmatBoots.name=Buty hazmat
+item.resonantinduction\:thermometer.name=Termometr kieszonkowy
+item.resonantinduction\:bucketToxicWaste.name=Wiadro z odpadami toksycznymi
+
+## Cells
+item.resonantinduction\:cellEmpty.name=Pusta kom\u00F3rka
+item.resonantinduction\:cellWater.name=Kom\u00F3rka a wod\u0105
+item.resonantinduction\:cellDeuterium.name=Kom\u00F3rka z deuterem
+item.resonantinduction\:strangeMatter.name=Materia dziwna
+item.resonantinduction\:antimatter.name=Antymateria
+
+## Uranium Related Items
+tile.resonantinduction\:oreUranium.name=Ruda uranu
+item.resonantinduction\:yellowcake.name=Yellowcake
+item.resonantinduction\:uranium.0.name=Uran-235
+item.resonantinduction\:uranium.1.name=Uran-238
+item.resonantinduction\:rodFissileFuel.name=Rozszczepialny pr\u0119t paliwa
+item.resonantinduction\:rodBreederFuel.name=Powielaj\u0105cy pr\u0119t paliwa
+item.resonantinduction\:uraniumHexafluoride.name=Heksafluorek uranu
+item.resonantinduction\:steam.name=Para wodna
+
+## Blocks
+tile.resonantinduction\:reactorTap.name=Odp\u0142yw reaktora
+tile.resonantinduction\:nuclearBoiler.name=Bojler wodny wrz\u0105cy
+tile.resonantinduction\:centrifuge.name=Centryfuga
+tile.resonantinduction\:fissionReactor.name=Reaktor rozszczepieniowy
+tile.resonantinduction\:fusionReactor.name=Reaktor fuzyjny
+tile.resonantinduction\:reactorExpansion.name=Rozszerzenie reaktora
+tile.resonantinduction\:turbine.name=Turbina reaktora
+tile.resonantinduction\:radioactive.name=Materia\u0142 radioaktywny
+tile.resonantinduction\:thermometer.name=Termometr
+tile.resonantinduction\:electromagnet.name=Elektromagnes
+tile.resonantinduction\:chemicalExtractor.name=Ekstraktor chemiczny
+tile.resonantinduction\:siren.name=Syrena alarmowa
+tile.resonantinduction\:electromagnetGlass.name=Elektromagnetyczne szk\u0142o
+tile.resonantinduction\:controlRod.name=Pr\u0119t kontrolny
+tile.resonantinduction\:plasma.name=Plazma
+tile.resonantinduction\:funnel.name=Lejek do pary wodnej
+tile.resonantinduction\:accelerator.name=Przyspieszacz cz\u0105steczek
+tile.resonantinduction\:instantBuilder.name=Reaktor w pude\u0142ku
+tile.resonantinduction\:fulmination.name=Generator fulminacyjny
+tile.resonantinduction\:atomicAssembler.name=Wytwarzacz atomowy
+tile.resonantinduction\:toxicWaste.name=Odpad toksyczny
\ No newline at end of file
diff --git a/src/main/resources/assets/resonantinduction/models/centrifuge.png b/src/main/resources/assets/resonantinduction/models/centrifuge.png
new file mode 100644
index 000000000..f85a1e685
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/centrifuge.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/centrifuge.tcn b/src/main/resources/assets/resonantinduction/models/centrifuge.tcn
new file mode 100644
index 000000000..5b76c1396
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/centrifuge.tcn differ
diff --git a/src/main/resources/assets/resonantinduction/models/chemicalExtractor.png b/src/main/resources/assets/resonantinduction/models/chemicalExtractor.png
new file mode 100644
index 000000000..c52aef6a4
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/chemicalExtractor.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/chemicalExtractor.tcn b/src/main/resources/assets/resonantinduction/models/chemicalExtractor.tcn
new file mode 100644
index 000000000..5cf33db23
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/chemicalExtractor.tcn differ
diff --git a/src/main/resources/assets/resonantinduction/models/fissileMaterial.png b/src/main/resources/assets/resonantinduction/models/fissileMaterial.png
new file mode 100644
index 000000000..99f581b1f
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/fissileMaterial.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/fusionReactor.png b/src/main/resources/assets/resonantinduction/models/fusionReactor.png
new file mode 100644
index 000000000..4c567f90b
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/fusionReactor.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/fusionReactor.tcn b/src/main/resources/assets/resonantinduction/models/fusionReactor.tcn
new file mode 100644
index 000000000..b143cfeb6
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/fusionReactor.tcn differ
diff --git a/src/main/resources/assets/resonantinduction/models/hazmat.png b/src/main/resources/assets/resonantinduction/models/hazmat.png
new file mode 100644
index 000000000..3c78481a2
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/hazmat.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/nuclearBoiler.png b/src/main/resources/assets/resonantinduction/models/nuclearBoiler.png
new file mode 100644
index 000000000..3d51592a9
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/nuclearBoiler.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/nuclearBoiler.tcn b/src/main/resources/assets/resonantinduction/models/nuclearBoiler.tcn
new file mode 100644
index 000000000..c6c1c044b
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/nuclearBoiler.tcn differ
diff --git a/src/main/resources/assets/resonantinduction/models/quantumAssembler.png b/src/main/resources/assets/resonantinduction/models/quantumAssembler.png
new file mode 100644
index 000000000..82c6c503b
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/quantumAssembler.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/quantumAssembler.tcn b/src/main/resources/assets/resonantinduction/models/quantumAssembler.tcn
new file mode 100644
index 000000000..75a211895
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/quantumAssembler.tcn differ
diff --git a/src/main/resources/assets/resonantinduction/models/reactorCellBottom.png b/src/main/resources/assets/resonantinduction/models/reactorCellBottom.png
new file mode 100644
index 000000000..ad08dd56f
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/reactorCellBottom.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/reactorCellBottom.tcn b/src/main/resources/assets/resonantinduction/models/reactorCellBottom.tcn
new file mode 100644
index 000000000..0725691f2
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/reactorCellBottom.tcn differ
diff --git a/src/main/resources/assets/resonantinduction/models/reactorCellMiddle.png b/src/main/resources/assets/resonantinduction/models/reactorCellMiddle.png
new file mode 100644
index 000000000..3da092927
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/reactorCellMiddle.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/reactorCellMiddle.tcn b/src/main/resources/assets/resonantinduction/models/reactorCellMiddle.tcn
new file mode 100644
index 000000000..6307e280e
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/reactorCellMiddle.tcn differ
diff --git a/src/main/resources/assets/resonantinduction/models/reactorCellTop.png b/src/main/resources/assets/resonantinduction/models/reactorCellTop.png
new file mode 100644
index 000000000..77b4dcdc1
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/reactorCellTop.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/reactorCellTop.tcn b/src/main/resources/assets/resonantinduction/models/reactorCellTop.tcn
new file mode 100644
index 000000000..1ee418950
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/reactorCellTop.tcn differ
diff --git a/src/main/resources/assets/resonantinduction/models/turbineLarge.png b/src/main/resources/assets/resonantinduction/models/turbineLarge.png
new file mode 100644
index 000000000..8b6f872fd
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/turbineLarge.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/turbineLarge.tcn b/src/main/resources/assets/resonantinduction/models/turbineLarge.tcn
new file mode 100644
index 000000000..7dc28e054
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/turbineLarge.tcn differ
diff --git a/src/main/resources/assets/resonantinduction/models/turbineSmall.png b/src/main/resources/assets/resonantinduction/models/turbineSmall.png
new file mode 100644
index 000000000..9c2ddb2e9
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/turbineSmall.png differ
diff --git a/src/main/resources/assets/resonantinduction/models/turbineSmall.tcn b/src/main/resources/assets/resonantinduction/models/turbineSmall.tcn
new file mode 100644
index 000000000..c0dc9b48e
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/models/turbineSmall.tcn differ
diff --git a/src/main/resources/assets/resonantinduction/sound/accelerator.ogg b/src/main/resources/assets/resonantinduction/sound/accelerator.ogg
new file mode 100644
index 000000000..7ceecc61c
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/sound/accelerator.ogg differ
diff --git a/src/main/resources/assets/resonantinduction/sound/alarm.ogg b/src/main/resources/assets/resonantinduction/sound/alarm.ogg
new file mode 100644
index 000000000..765542951
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/sound/alarm.ogg differ
diff --git a/src/main/resources/assets/resonantinduction/sound/antimatter.ogg b/src/main/resources/assets/resonantinduction/sound/antimatter.ogg
new file mode 100644
index 000000000..160d84b14
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/sound/antimatter.ogg differ
diff --git a/src/main/resources/assets/resonantinduction/sound/assembler.ogg b/src/main/resources/assets/resonantinduction/sound/assembler.ogg
new file mode 100644
index 000000000..ab3f228c4
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/sound/assembler.ogg differ
diff --git a/src/main/resources/assets/resonantinduction/sound/powerup.ogg b/src/main/resources/assets/resonantinduction/sound/powerup.ogg
new file mode 100644
index 000000000..053a20807
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/sound/powerup.ogg differ
diff --git a/src/main/resources/assets/resonantinduction/sound/reactorcell.ogg b/src/main/resources/assets/resonantinduction/sound/reactorcell.ogg
new file mode 100644
index 000000000..d71ea1c78
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/sound/reactorcell.ogg differ
diff --git a/src/main/resources/assets/resonantinduction/sound/strangematter.ogg b/src/main/resources/assets/resonantinduction/sound/strangematter.ogg
new file mode 100644
index 000000000..807670729
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/sound/strangematter.ogg differ
diff --git a/src/main/resources/assets/resonantinduction/sound/turbine.ogg b/src/main/resources/assets/resonantinduction/sound/turbine.ogg
new file mode 100644
index 000000000..afcfac0b2
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/sound/turbine.ogg differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/accelerator.png b/src/main/resources/assets/resonantinduction/textures/blocks/accelerator.png
new file mode 100644
index 000000000..638a938b4
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/accelerator.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/atomic_edge.png b/src/main/resources/assets/resonantinduction/textures/blocks/atomic_edge.png
new file mode 100644
index 000000000..fac11806b
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/atomic_edge.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/controlRod.png b/src/main/resources/assets/resonantinduction/textures/blocks/controlRod.png
new file mode 100644
index 000000000..bb530947a
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/controlRod.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/deuterium.png b/src/main/resources/assets/resonantinduction/textures/blocks/deuterium.png
new file mode 100644
index 000000000..6975d755c
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/deuterium.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/electromagnet.png b/src/main/resources/assets/resonantinduction/textures/blocks/electromagnet.png
new file mode 100644
index 000000000..1b24ef647
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/electromagnet.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/electromagnetGlass.png b/src/main/resources/assets/resonantinduction/textures/blocks/electromagnetGlass.png
new file mode 100644
index 000000000..e6f8dd172
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/electromagnetGlass.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/electromagnet_top.png b/src/main/resources/assets/resonantinduction/textures/blocks/electromagnet_top.png
new file mode 100644
index 000000000..9cbb22cd3
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/electromagnet_top.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/fulmination.png b/src/main/resources/assets/resonantinduction/textures/blocks/fulmination.png
new file mode 100644
index 000000000..01fd55c7e
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/fulmination.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/funnel.png b/src/main/resources/assets/resonantinduction/textures/blocks/funnel.png
new file mode 100644
index 000000000..482645198
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/funnel.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/funnel_edge.png b/src/main/resources/assets/resonantinduction/textures/blocks/funnel_edge.png
new file mode 100644
index 000000000..dc02bcba8
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/funnel_edge.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/funnel_top.png b/src/main/resources/assets/resonantinduction/textures/blocks/funnel_top.png
new file mode 100644
index 000000000..5954b535c
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/funnel_top.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/machine.png b/src/main/resources/assets/resonantinduction/textures/blocks/machine.png
new file mode 100644
index 000000000..68e2ab09b
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/machine.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/oreUranium.png b/src/main/resources/assets/resonantinduction/textures/blocks/oreUranium.png
new file mode 100644
index 000000000..89a964d0a
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/oreUranium.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/plasma.png b/src/main/resources/assets/resonantinduction/textures/blocks/plasma.png
new file mode 100644
index 000000000..d0c9a78eb
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/plasma.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/radioactive.png b/src/main/resources/assets/resonantinduction/textures/blocks/radioactive.png
new file mode 100644
index 000000000..235fb43a2
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/radioactive.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/radioactive_bottom.png b/src/main/resources/assets/resonantinduction/textures/blocks/radioactive_bottom.png
new file mode 100644
index 000000000..484b9579a
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/radioactive_bottom.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/radioactive_top.png b/src/main/resources/assets/resonantinduction/textures/blocks/radioactive_top.png
new file mode 100644
index 000000000..6a7730df1
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/radioactive_top.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/reactorDrain.png b/src/main/resources/assets/resonantinduction/textures/blocks/reactorDrain.png
new file mode 100644
index 000000000..c6ebf7521
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/reactorDrain.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/reactorDrain_front.png b/src/main/resources/assets/resonantinduction/textures/blocks/reactorDrain_front.png
new file mode 100644
index 000000000..d9c81eb11
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/reactorDrain_front.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/siren.png b/src/main/resources/assets/resonantinduction/textures/blocks/siren.png
new file mode 100644
index 000000000..c4efbee3e
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/siren.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/steam.png b/src/main/resources/assets/resonantinduction/textures/blocks/steam.png
new file mode 100644
index 000000000..91a7854bf
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/steam.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/thermometer.png b/src/main/resources/assets/resonantinduction/textures/blocks/thermometer.png
new file mode 100644
index 000000000..099ab535b
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/thermometer.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/toxicWaste.png b/src/main/resources/assets/resonantinduction/textures/blocks/toxicWaste.png
new file mode 100644
index 000000000..e421f10c3
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/toxicWaste.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/toxicWaste.png.mcmeta b/src/main/resources/assets/resonantinduction/textures/blocks/toxicWaste.png.mcmeta
new file mode 100644
index 000000000..a7ffb0ae5
--- /dev/null
+++ b/src/main/resources/assets/resonantinduction/textures/blocks/toxicWaste.png.mcmeta
@@ -0,0 +1,6 @@
+{
+ "animation":
+ {
+ "frametime": 3
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/tritium.png b/src/main/resources/assets/resonantinduction/textures/blocks/tritium.png
new file mode 100644
index 000000000..62ec327f2
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/tritium.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/blocks/uraniumHexafluoride.png b/src/main/resources/assets/resonantinduction/textures/blocks/uraniumHexafluoride.png
new file mode 100644
index 000000000..99f581b1f
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/blocks/uraniumHexafluoride.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/gui/gui_accelerator.png b/src/main/resources/assets/resonantinduction/textures/gui/gui_accelerator.png
new file mode 100644
index 000000000..0589384f0
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/gui/gui_accelerator.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/gui/gui_atomic_assembler.png b/src/main/resources/assets/resonantinduction/textures/gui/gui_atomic_assembler.png
new file mode 100644
index 000000000..041896b91
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/gui/gui_atomic_assembler.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/antimatter_gram.png b/src/main/resources/assets/resonantinduction/textures/items/antimatter_gram.png
new file mode 100644
index 000000000..2c65bb0d2
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/antimatter_gram.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/antimatter_gram.png.mcmeta b/src/main/resources/assets/resonantinduction/textures/items/antimatter_gram.png.mcmeta
new file mode 100644
index 000000000..1ca3a06b6
--- /dev/null
+++ b/src/main/resources/assets/resonantinduction/textures/items/antimatter_gram.png.mcmeta
@@ -0,0 +1,6 @@
+{
+ "animation":
+ {
+ "frametime": 1
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/resonantinduction/textures/items/antimatter_milligram.png b/src/main/resources/assets/resonantinduction/textures/items/antimatter_milligram.png
new file mode 100644
index 000000000..4faf19e95
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/antimatter_milligram.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/antimatter_milligram.png.mcmeta b/src/main/resources/assets/resonantinduction/textures/items/antimatter_milligram.png.mcmeta
new file mode 100644
index 000000000..1ca3a06b6
--- /dev/null
+++ b/src/main/resources/assets/resonantinduction/textures/items/antimatter_milligram.png.mcmeta
@@ -0,0 +1,6 @@
+{
+ "animation":
+ {
+ "frametime": 1
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/resonantinduction/textures/items/bucketToxicWaste.png b/src/main/resources/assets/resonantinduction/textures/items/bucketToxicWaste.png
new file mode 100644
index 000000000..c83e6454e
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/bucketToxicWaste.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/cellCorrosive.png b/src/main/resources/assets/resonantinduction/textures/items/cellCorrosive.png
new file mode 100644
index 000000000..3d48f5ce1
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/cellCorrosive.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/cellDeuterium.png b/src/main/resources/assets/resonantinduction/textures/items/cellDeuterium.png
new file mode 100644
index 000000000..069edaa80
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/cellDeuterium.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/cellEmpty.png b/src/main/resources/assets/resonantinduction/textures/items/cellEmpty.png
new file mode 100644
index 000000000..d4bae6b86
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/cellEmpty.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/cellTritium.png b/src/main/resources/assets/resonantinduction/textures/items/cellTritium.png
new file mode 100644
index 000000000..fc18b27a2
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/cellTritium.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/cellWater.png b/src/main/resources/assets/resonantinduction/textures/items/cellWater.png
new file mode 100644
index 000000000..5c096f783
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/cellWater.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/darkMatter.png b/src/main/resources/assets/resonantinduction/textures/items/darkMatter.png
new file mode 100644
index 000000000..48220906a
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/darkMatter.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/darkMatter.png.mcmeta b/src/main/resources/assets/resonantinduction/textures/items/darkMatter.png.mcmeta
new file mode 100644
index 000000000..1ca3a06b6
--- /dev/null
+++ b/src/main/resources/assets/resonantinduction/textures/items/darkMatter.png.mcmeta
@@ -0,0 +1,6 @@
+{
+ "animation":
+ {
+ "frametime": 1
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/resonantinduction/textures/items/hazmatBody.png b/src/main/resources/assets/resonantinduction/textures/items/hazmatBody.png
new file mode 100644
index 000000000..9c0b89ea3
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/hazmatBody.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/hazmatBoots.png b/src/main/resources/assets/resonantinduction/textures/items/hazmatBoots.png
new file mode 100644
index 000000000..67d1a84e8
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/hazmatBoots.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/hazmatLeggings.png b/src/main/resources/assets/resonantinduction/textures/items/hazmatLeggings.png
new file mode 100644
index 000000000..2e0a621f3
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/hazmatLeggings.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/hazmatMask.png b/src/main/resources/assets/resonantinduction/textures/items/hazmatMask.png
new file mode 100644
index 000000000..db043f811
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/hazmatMask.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/rodBreederFuel.png b/src/main/resources/assets/resonantinduction/textures/items/rodBreederFuel.png
new file mode 100644
index 000000000..6d52370f8
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/rodBreederFuel.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/rodFissileFuel.png b/src/main/resources/assets/resonantinduction/textures/items/rodFissileFuel.png
new file mode 100644
index 000000000..d4226f167
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/rodFissileFuel.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/thermometer.png b/src/main/resources/assets/resonantinduction/textures/items/thermometer.png
new file mode 100644
index 000000000..7563cc5fa
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/thermometer.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/uranium.png b/src/main/resources/assets/resonantinduction/textures/items/uranium.png
new file mode 100644
index 000000000..7caf547d9
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/uranium.png differ
diff --git a/src/main/resources/assets/resonantinduction/textures/items/yellowcake.png b/src/main/resources/assets/resonantinduction/textures/items/yellowcake.png
new file mode 100644
index 000000000..a58d88e9f
Binary files /dev/null and b/src/main/resources/assets/resonantinduction/textures/items/yellowcake.png differ
diff --git a/src/main/scala/resonantinduction/core/Settings.java b/src/main/scala/resonantinduction/core/Settings.java
index f4b72f837..99004e837 100644
--- a/src/main/scala/resonantinduction/core/Settings.java
+++ b/src/main/scala/resonantinduction/core/Settings.java
@@ -3,10 +3,13 @@ package resonantinduction.core;
import java.io.File;
import java.util.Arrays;
+import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.common.Configuration;
+import resonant.api.recipe.QuantumAssemblerRecipes;
import resonant.lib.config.Config;
import resonant.lib.content.IDManager;
+import resonant.lib.prefab.poison.PotionRadiation;
import resonant.lib.utility.LanguageUtility;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Loader;
@@ -16,16 +19,38 @@ import cpw.mods.fml.common.ModMetadata;
public class Settings
{
public static final Configuration CONFIGURATION = new Configuration(new File(Loader.instance().getConfigDir(), Reference.NAME + ".cfg"));
- public static final String DOMAIN = "resonantinduction";
+ public static final String DOMAIN = "resonantinduction";
+
/** IDs suggested by Jyzarc and Horfius */
public static final IDManager idManager;
static
{
CONFIGURATION.load();
+
idManager = new IDManager(CONFIGURATION.get(Configuration.CATEGORY_GENERAL, "BlockIDPrefix", 1200).getInt(1200), CONFIGURATION.get(Configuration.CATEGORY_GENERAL, "ItemIDPrefix", 20150).getInt(20150));
+
CONFIGURATION.save();
}
+
+ /** Config Options */
+ public static void load()
+ {
+ for (int recipeID : quantumAssemblerRecipes)
+ {
+ try
+ {
+ QuantumAssemblerRecipes.addRecipe(new ItemStack(recipeID, 1, 0));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ // Calling this once to prevent the static class from not initiating.
+ PotionRadiation.INSTANCE.getId();
+ }
public static int getNextBlockID()
{
@@ -51,27 +76,81 @@ public class Settings
@Config(key = "Engineering Table Autocraft")
public static boolean ALLOW_ENGINEERING_AUTOCRAFT = true;
+
@Config(key = "Tesla Sound FXs")
public static boolean SOUND_FXS = true;
+
@Config(key = "Shiny silver Wires")
public static boolean SHINY_SILVER = true;
+
@Config(key = "Max EM Contractor Path")
public static int MAX_LEVITATOR_DISTANCE = 200;
+
@Config(category = Configuration.CATEGORY_GENERAL, key = "Levitator Max Reach")
public static int LEVITATOR_MAX_REACH = 40;
+
@Config(category = Configuration.CATEGORY_GENERAL, key = "Levitator Push Delay")
public static int LEVITATOR_PUSH_DELAY = 5;
+
@Config(category = Configuration.CATEGORY_GENERAL, key = "Levitator Max Speed")
public static double LEVITATOR_MAX_SPEED = .2;
+
@Config(category = Configuration.CATEGORY_GENERAL, key = "Levitator Acceleration")
public static double LEVITATOR_ACCELERATION = .02;
@Config(category = "Power", key = "Wind_tubine_Ratio")
public static int WIND_POWER_RATIO = 1;
+
@Config(category = "Power", key = "Water_tubine_Ratio")
public static int WATER_POWER_RATIO = 1;
+
@Config(category = "Power", key = "Solor_Panel")
public static int SOLAR_ENERGY = 50;
+
+ @Config
+ public static double fulminationOutputMultiplier = 1;
+
+ @Config
+ public static double turbineOutputMultiplier = 1;
+
+ @Config
+ public static double fissionBoilVolumeMultiplier = 1;
+
+ @Config
+ public static boolean allowTurbineStacking = true;
+
+ @Config
+ public static boolean allowToxicWaste = true;
+
+ @Config
+ public static boolean allowRadioactiveOres = true;
+
+ @Config
+ public static boolean allowOreDictionaryCompatibility = true;
+
+ @Config
+ public static boolean allowAlternateRecipes = true;
+
+ @Config
+ public static boolean allowIC2UraniumCompression = true;
+
+ @Config(comment = "0 = Do not generate, 1 = Generate items only, 2 = Generate all")
+ public static int quantumAssemblerGenerateMode = 1;
+
+ @Config
+ public static int uraniumHexaflourideRatio = 200;
+
+ @Config
+ public static int waterPerDeutermium = 4;
+
+ @Config
+ public static int deutermiumPerTritium = 4;
+
+ @Config(comment = "Put a list of block/item IDs to be used by the Quantum Assembler. Separate by commas, no space.")
+ public static int[] quantumAssemblerRecipes = new int[0];
+
+ @Config
+ public static double darkMatterSpawnChance = 0.2;
public static void setModMetadata(ModMetadata metadata, String id, String name)
{
@@ -86,7 +165,7 @@ public class Settings
metadata.url = "http://calclavia.com/resonant-induction";
metadata.logoFile = "ri_logo.png";
metadata.version = Reference.VERSION + "." + Reference.BUILD_VERSION;
- metadata.authorList = Arrays.asList(new String[] { "Calclavia", "DarkCow" });
+ metadata.authorList = Arrays.asList(new String[] { "Calclavia", "DarkCow", "Maxwolf Goodliffe" });
metadata.credits = LanguageUtility.getLocal("meta.resonantinduction.credits");
metadata.parent = parent;
metadata.autogenerated = false;