From ecfe9a43b9f09c3a37368f8ab4ae24605c1a1c97 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Fri, 6 Dec 2013 07:26:48 -0500 Subject: [PATCH 01/40] Fixes! --- common/mekanism/common/EnergyNetwork.java | 5 +++++ common/mekanism/common/block/BlockMachine.java | 7 ++++++- common/mekanism/common/item/ItemBlockMachine.java | 10 ---------- .../common/tileentity/TileEntityUniversalCable.java | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/common/mekanism/common/EnergyNetwork.java b/common/mekanism/common/EnergyNetwork.java index ebea35bde..dbd7534c1 100644 --- a/common/mekanism/common/EnergyNetwork.java +++ b/common/mekanism/common/EnergyNetwork.java @@ -85,6 +85,11 @@ public class EnergyNetwork extends DynamicNetwork for(TileEntity acceptor : getAcceptors()) { + if(acceptorDirections.get(acceptor) == null) + { + continue; + } + ForgeDirection side = acceptorDirections.get(acceptor).getOpposite(); if(!ignored.contains(acceptor)) diff --git a/common/mekanism/common/block/BlockMachine.java b/common/mekanism/common/block/BlockMachine.java index 6beb53cc7..78de5fe78 100644 --- a/common/mekanism/common/block/BlockMachine.java +++ b/common/mekanism/common/block/BlockMachine.java @@ -156,6 +156,11 @@ public class BlockMachine extends BlockContainer implements ISpecialBounds int height = Math.round(entityliving.rotationPitch); int change = 3; + if(tileEntity == null) + { + return; + } + if(tileEntity.canSetFacing(0) && tileEntity.canSetFacing(1)) { if(height >= 65) @@ -782,7 +787,7 @@ public class BlockMachine extends BlockContainer implements ISpecialBounds { TileEntityBasicBlock tileEntity = (TileEntityBasicBlock)world.getBlockTileEntity(x, y, z); ItemStack itemStack = new ItemStack(blockID, 1, world.getBlockMetadata(x, y, z)); - + if(((IUpgradeManagement)itemStack.getItem()).supportsUpgrades(itemStack)) { IUpgradeManagement upgrade = (IUpgradeManagement)itemStack.getItem(); diff --git a/common/mekanism/common/item/ItemBlockMachine.java b/common/mekanism/common/item/ItemBlockMachine.java index a283d51fc..8ae1c1dab 100644 --- a/common/mekanism/common/item/ItemBlockMachine.java +++ b/common/mekanism/common/item/ItemBlockMachine.java @@ -1022,14 +1022,6 @@ public class ItemBlockMachine extends ItemBlock implements IEnergizedItem, IItem GasStack stored = GasStack.readFromNBT(itemstack.stackTagCompound.getCompoundTag("stored")); - if(stored == null) - { - itemstack.setItemDamage(100); - } - else { - itemstack.setItemDamage((int)Math.max(1, (Math.abs((((float)stored.amount/getMaxGas(itemstack))*100)-100)))); - } - return stored; } @@ -1055,14 +1047,12 @@ public class ItemBlockMachine extends ItemBlock implements IEnergizedItem, IItem if(stack == null || stack.amount == 0) { - itemstack.setItemDamage(100); itemstack.stackTagCompound.removeTag("stored"); } else { int amount = Math.max(0, Math.min(stack.amount, getMaxGas(itemstack))); GasStack gasStack = new GasStack(stack.getGas(), amount); - itemstack.setItemDamage((int)Math.max(1, (Math.abs((((float)amount/getMaxGas(itemstack))*100)-100)))); itemstack.stackTagCompound.setCompoundTag("stored", gasStack.write(new NBTTagCompound())); } } diff --git a/common/mekanism/common/tileentity/TileEntityUniversalCable.java b/common/mekanism/common/tileentity/TileEntityUniversalCable.java index 88451373e..6cc95b760 100644 --- a/common/mekanism/common/tileentity/TileEntityUniversalCable.java +++ b/common/mekanism/common/tileentity/TileEntityUniversalCable.java @@ -168,7 +168,7 @@ public class TileEntityUniversalCable extends TileEntityTransmitter Date: Fri, 6 Dec 2013 15:26:44 -0500 Subject: [PATCH 02/40] Work on gas masks/scuba gear stuff --- .../client/ClientConnectionHandler.java | 1 + .../client/ClientPlayerTickHandler.java | 70 +++++- .../client/render/ModelCustomArmor.java | 38 ++- .../mekanism/client/sound/GasMaskSound.java | 55 +++++ .../mekanism/client/sound/JetpackSound.java | 34 +-- common/mekanism/client/sound/PlayerSound.java | 45 ++++ common/mekanism/client/sound/Sound.java | 6 + .../mekanism/client/sound/SoundHandler.java | 4 - common/mekanism/common/Mekanism.java | 9 + common/mekanism/common/item/ItemGasMask.java | 43 ++++ .../mekanism/common/item/ItemScubaTank.java | 228 ++++++++++++++++++ .../common/network/PacketScubaTankData.java | 98 ++++++++ resources/assets/mekanism/lang/en_US.lang | 2 + .../assets/mekanism/sound/etc/GasMask.ogg | Bin 0 -> 120015 bytes 14 files changed, 583 insertions(+), 50 deletions(-) create mode 100644 common/mekanism/client/sound/GasMaskSound.java create mode 100644 common/mekanism/client/sound/PlayerSound.java create mode 100644 common/mekanism/common/item/ItemGasMask.java create mode 100644 common/mekanism/common/item/ItemScubaTank.java create mode 100644 common/mekanism/common/network/PacketScubaTankData.java create mode 100644 resources/assets/mekanism/sound/etc/GasMask.ogg diff --git a/common/mekanism/client/ClientConnectionHandler.java b/common/mekanism/client/ClientConnectionHandler.java index 7c6200541..88bf7f878 100644 --- a/common/mekanism/client/ClientConnectionHandler.java +++ b/common/mekanism/client/ClientConnectionHandler.java @@ -68,6 +68,7 @@ public class ClientConnectionHandler implements IConnectionHandler ClientTickHandler.tickingSet.clear(); Mekanism.jetpackOn.clear(); + Mekanism.gasmaskOn.clear(); Mekanism.proxy.unloadSoundHandler(); } diff --git a/common/mekanism/client/ClientPlayerTickHandler.java b/common/mekanism/client/ClientPlayerTickHandler.java index 49cb3632a..ef9d752bf 100644 --- a/common/mekanism/client/ClientPlayerTickHandler.java +++ b/common/mekanism/client/ClientPlayerTickHandler.java @@ -3,18 +3,23 @@ package mekanism.client; import java.util.EnumSet; import mekanism.api.EnumColor; +import mekanism.client.sound.GasMaskSound; +import mekanism.client.sound.JetpackSound; import mekanism.common.Mekanism; import mekanism.common.PacketHandler; import mekanism.common.PacketHandler.Transmission; import mekanism.common.item.ItemConfigurator; import mekanism.common.item.ItemElectricBow; +import mekanism.common.item.ItemGasMask; import mekanism.common.item.ItemJetpack; import mekanism.common.item.ItemJetpack.JetpackMode; +import mekanism.common.item.ItemScubaTank; import mekanism.common.item.ItemWalkieTalkie; import mekanism.common.network.PacketConfiguratorState; import mekanism.common.network.PacketElectricBowState; import mekanism.common.network.PacketJetpackData; import mekanism.common.network.PacketJetpackData.PacketType; +import mekanism.common.network.PacketScubaTankData; import mekanism.common.network.PacketWalkieTalkieState; import mekanism.common.util.StackUtils; import net.minecraft.client.Minecraft; @@ -139,7 +144,31 @@ public class ClientPlayerTickHandler implements ITickHandler for(EntityPlayer entry : Mekanism.jetpackOn) { - Mekanism.proxy.registerSound(entry); + if(MekanismClient.audioHandler.getFrom(entry) == null) + { + new JetpackSound(MekanismClient.audioHandler.getIdentifier(), entry); + } + } + + if(Mekanism.gasmaskOn.contains(entityPlayer) != isGasMaskOn(entityPlayer)) + { + if(isGasMaskOn(entityPlayer)) + { + Mekanism.gasmaskOn.add(entityPlayer); + } + else { + Mekanism.gasmaskOn.remove(entityPlayer); + } + + PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(PacketType.UPDATE, entityPlayer, isGasMaskOn(entityPlayer))); + } + + for(EntityPlayer entry : Mekanism.gasmaskOn) + { + if(MekanismClient.audioHandler.getFrom(entry) == null) + { + new GasMaskSound(MekanismClient.audioHandler.getIdentifier(), entry); + } } if(entityPlayer.getCurrentItemOrArmor(3) != null && entityPlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) @@ -149,7 +178,7 @@ public class ClientPlayerTickHandler implements ITickHandler } if(isJetpackOn(entityPlayer)) - { + { ItemJetpack jetpack = (ItemJetpack)entityPlayer.getCurrentItemOrArmor(3).getItem(); if(jetpack.getMode(entityPlayer.getCurrentItemOrArmor(3)) == JetpackMode.NORMAL) @@ -186,14 +215,17 @@ public class ClientPlayerTickHandler implements ITickHandler jetpack.useGas(entityPlayer.getCurrentItemOrArmor(3)); } + + if(isGasMaskOn(entityPlayer)) + { + ItemScubaTank tank = (ItemScubaTank)entityPlayer.getCurrentItemOrArmor(3).getItem(); + + tank.useGas(entityPlayer.getCurrentItemOrArmor(3)); + entityPlayer.setAir(300); + } } } - private boolean cacheJetpackOn(EntityPlayer player) - { - return Mekanism.jetpackOn.contains(player); - } - public static boolean isJetpackOn(EntityPlayer player) { ItemStack stack = player.inventory.armorInventory[2]; @@ -221,6 +253,30 @@ public class ClientPlayerTickHandler implements ITickHandler return false; } + public static boolean isGasMaskOn(EntityPlayer player) + { + ItemStack tank = player.inventory.armorInventory[2]; + ItemStack mask = player.inventory.armorInventory[3]; + + if(tank != null && mask != null) + { + if(tank.getItem() instanceof ItemScubaTank && mask.getItem() instanceof ItemGasMask) + { + ItemScubaTank scubaTank = (ItemScubaTank)tank.getItem(); + + if(scubaTank.getGas(tank) != null) + { + if(scubaTank.getFlowing(tank)) + { + return true; + } + } + } + } + + return false; + } + @Override public EnumSet ticks() { diff --git a/common/mekanism/client/render/ModelCustomArmor.java b/common/mekanism/client/render/ModelCustomArmor.java index 1b614ad83..253a9acce 100644 --- a/common/mekanism/client/render/ModelCustomArmor.java +++ b/common/mekanism/client/render/ModelCustomArmor.java @@ -46,11 +46,6 @@ public class ModelCustomArmor extends ModelBiped bipedBody.isHidden = false; bipedBody.showModel = true; } - else if(modelType.armorSlot == 2) - { - bipedRightLeg.showModel = true; - bipedLeftLeg.showModel = true; - } setRotationAngles(f, f1, f2, f3, f4, size, entity); } @@ -109,9 +104,20 @@ public class ModelCustomArmor extends ModelBiped mc.renderEngine.bindTexture(modelType.resource); - if(ModelCustomArmor.this.modelType == ArmorModel.JETPACK && biped.bipedBody == partRender) + if(useModel(biped.modelType, partRender, biped)) { - ArmorModel.jetpackModel.render(0.0625F); + if(biped.modelType == ArmorModel.JETPACK) + { + ArmorModel.jetpackModel.render(0.0625F); + } + else if(biped.modelType == ArmorModel.SCUBATANK) + { + + } + else if(biped.modelType == ArmorModel.GASMASK) + { + + } } GL11.glPopMatrix(); @@ -125,10 +131,26 @@ public class ModelCustomArmor extends ModelBiped init(entity, par2, par3, par4, par5, par6, par7); super.render(entity, par2, par3, par4, par5, par6, par7); } + + public static boolean useModel(ArmorModel type, ModelRenderer partRender, ModelCustomArmor biped) + { + if(type.armorSlot == 0) + { + return partRender == biped.bipedHead; + } + else if(type.armorSlot == 1) + { + return partRender == biped.bipedBody; + } + + return false; + } public static enum ArmorModel { - JETPACK(1, MekanismUtils.getResource(ResourceType.RENDER, "Jetpack.png")); + JETPACK(1, MekanismUtils.getResource(ResourceType.RENDER, "Jetpack.png")), + SCUBATANK(1, MekanismUtils.getResource(ResourceType.RENDER, "ScubaTank.png")), + GASMASK(0, MekanismUtils.getResource(ResourceType.RENDER, "GasMask.png")); public int armorSlot; public ResourceLocation resource; diff --git a/common/mekanism/client/sound/GasMaskSound.java b/common/mekanism/client/sound/GasMaskSound.java new file mode 100644 index 000000000..92bbc9944 --- /dev/null +++ b/common/mekanism/client/sound/GasMaskSound.java @@ -0,0 +1,55 @@ +package mekanism.client.sound; + +import mekanism.client.ClientPlayerTickHandler; +import mekanism.common.item.ItemGasMask; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; + +public class GasMaskSound extends PlayerSound +{ + public GasMaskSound(String id, EntityPlayer entity) + { + super(id, "GasMask.ogg", entity); + } + + @Override + public boolean update(World world) + { + if(player.isDead) + { + return false; + } + else if(!world.loadedEntityList.contains(player)) + { + return false; + } + else if(!hasGasMask(player)) + { + return false; + } + else { + if(ClientPlayerTickHandler.isGasMaskOn(player) != isPlaying) + { + if(ClientPlayerTickHandler.isGasMaskOn(player)) + { + play(); + } + else { + stopLoop(); + } + } + } + + if(isPlaying) + { + ticksSincePlay++; + } + + return true; + } + + private boolean hasGasMask(EntityPlayer player) + { + return player.inventory.armorInventory[3] != null && player.inventory.armorInventory[3].getItem() instanceof ItemGasMask; + } +} diff --git a/common/mekanism/client/sound/JetpackSound.java b/common/mekanism/client/sound/JetpackSound.java index dd49774d2..d4dadf9d2 100644 --- a/common/mekanism/client/sound/JetpackSound.java +++ b/common/mekanism/client/sound/JetpackSound.java @@ -2,43 +2,15 @@ package mekanism.client.sound; import mekanism.client.ClientPlayerTickHandler; import mekanism.common.item.ItemJetpack; -import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; import universalelectricity.core.vector.Vector3; -public class JetpackSound extends Sound +public class JetpackSound extends PlayerSound { - /** The TileEntity this sound is associated with. */ - public EntityPlayer player; - - public int ticksSincePlay = 0; - - public JetpackSound(String id, String sound, EntityPlayer entity) + public JetpackSound(String id, EntityPlayer entity) { - super(id, sound, entity, new Vector3(entity)); - - player = entity; - } - - @Override - public float getMultiplier() - { - return Math.min(1, ((float)ticksSincePlay/20F))*0.3F; - } - - @Override - public Vector3 getLocation() - { - return new Vector3(player); - } - - @Override - public void play() - { - super.play(); - - ticksSincePlay = 0; + super(id, "Jetpack.ogg", entity); } @Override diff --git a/common/mekanism/client/sound/PlayerSound.java b/common/mekanism/client/sound/PlayerSound.java new file mode 100644 index 000000000..371cb53ad --- /dev/null +++ b/common/mekanism/client/sound/PlayerSound.java @@ -0,0 +1,45 @@ +package mekanism.client.sound; + +import mekanism.client.ClientPlayerTickHandler; +import mekanism.common.item.ItemJetpack; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; +import universalelectricity.core.vector.Vector3; + +public abstract class PlayerSound extends Sound +{ + /** The TileEntity this sound is associated with. */ + public EntityPlayer player; + + public int ticksSincePlay = 0; + + public PlayerSound(String id, String sound, EntityPlayer entity) + { + super(id, sound, entity, new Vector3(entity)); + + player = entity; + } + + @Override + public float getMultiplier() + { + return Math.min(1, ((float)ticksSincePlay/20F))*0.3F; + } + + @Override + public Vector3 getLocation() + { + return new Vector3(player); + } + + @Override + public void play() + { + super.play(); + + ticksSincePlay = 0; + } + + @Override + public abstract boolean update(World world); +} diff --git a/common/mekanism/client/sound/Sound.java b/common/mekanism/client/sound/Sound.java index a22dff342..f973a00a3 100644 --- a/common/mekanism/client/sound/Sound.java +++ b/common/mekanism/client/sound/Sound.java @@ -3,6 +3,7 @@ package mekanism.client.sound; import java.net.URL; import mekanism.client.MekanismClient; +import mekanism.common.Mekanism; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; @@ -29,6 +30,11 @@ public abstract class Sound */ public Sound(String id, String sound, Object obj, Vector3 loc) { + if(MekanismClient.audioHandler.getFrom(obj) != null) + { + return; + } + synchronized(MekanismClient.audioHandler.sounds) { soundPath = sound; diff --git a/common/mekanism/client/sound/SoundHandler.java b/common/mekanism/client/sound/SoundHandler.java index 5305c6204..da39e87f5 100644 --- a/common/mekanism/client/sound/SoundHandler.java +++ b/common/mekanism/client/sound/SoundHandler.java @@ -248,10 +248,6 @@ public class SoundHandler { new TileSound(getIdentifier(), ((IHasSound)obj).getSoundPath(), (TileEntity)obj); } - else if(obj instanceof EntityPlayer) - { - new JetpackSound(getIdentifier(), "Jetpack.ogg", (EntityPlayer)obj); - } } } } diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index 60dd70695..63a3e91de 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -52,6 +52,7 @@ import mekanism.common.item.ItemDirtyDust; import mekanism.common.item.ItemDust; import mekanism.common.item.ItemElectricBow; import mekanism.common.item.ItemEnergized; +import mekanism.common.item.ItemGasMask; import mekanism.common.item.ItemIngot; import mekanism.common.item.ItemJetpack; import mekanism.common.item.ItemMachineUpgrade; @@ -60,6 +61,7 @@ import mekanism.common.item.ItemNetworkReader; import mekanism.common.item.ItemPortableTeleporter; import mekanism.common.item.ItemProxy; import mekanism.common.item.ItemRobit; +import mekanism.common.item.ItemScubaTank; import mekanism.common.item.ItemWalkieTalkie; import mekanism.common.network.PacketConfigurationUpdate; import mekanism.common.network.PacketConfiguratorState; @@ -78,6 +80,7 @@ import mekanism.common.network.PacketPortalFX; import mekanism.common.network.PacketRedstoneControl; import mekanism.common.network.PacketRemoveUpgrade; import mekanism.common.network.PacketRobit; +import mekanism.common.network.PacketScubaTankData; import mekanism.common.network.PacketSimpleGui; import mekanism.common.network.PacketStatusUpdate; import mekanism.common.network.PacketTileEntity; @@ -182,6 +185,7 @@ public class Mekanism public static KeySync keyMap = new KeySync(); public static Set jetpackOn = new HashSet(); + public static Set gasmaskOn = new HashSet(); public static Set ic2Registered = new HashSet(); @@ -215,6 +219,8 @@ public class Mekanism public static Item WalkieTalkie; public static Item ItemProxy; public static ItemJetpack Jetpack; + public static ItemScubaTank ScubaTank; + public static ItemGasMask GasMask; //Blocks public static Block BasicBlock; @@ -1107,6 +1113,8 @@ public class Mekanism dynamicInventories.clear(); ic2Registered.clear(); jetpackOn.clear(); + gasmaskOn.clear(); + TransporterManager.flowingStacks.clear(); } @@ -1206,6 +1214,7 @@ public class Mekanism PacketHandler.registerPacket(PacketDigitalMinerGui.class); PacketHandler.registerPacket(PacketJetpackData.class); PacketHandler.registerPacket(PacketKey.class); + PacketHandler.registerPacket(PacketScubaTankData.class); //Donators donators.add("mrgreaper"); diff --git a/common/mekanism/common/item/ItemGasMask.java b/common/mekanism/common/item/ItemGasMask.java new file mode 100644 index 000000000..fa5e22e5c --- /dev/null +++ b/common/mekanism/common/item/ItemGasMask.java @@ -0,0 +1,43 @@ +package mekanism.common.item; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import mekanism.client.render.ModelCustomArmor; +import mekanism.client.render.ModelCustomArmor.ArmorModel; +import mekanism.common.Mekanism; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.EnumHelper; + +public class ItemGasMask extends ItemArmor +{ + public ItemGasMask(int id) + { + super(id, EnumHelper.addArmorMaterial("GASMASK", 0, new int[] {0, 0, 0, 0}, 0), 0, 0); + setCreativeTab(Mekanism.tabMekanism); + } + + @Override + public boolean isValidArmor(ItemStack stack, int armorType, Entity entity) + { + return armorType == 0; + } + + @Override + public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type) + { + return "mekanism:render/NullArmor.png"; + } + + @Override + @SideOnly(Side.CLIENT) + public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) + { + ModelCustomArmor model = ModelCustomArmor.INSTANCE; + model.modelType = ArmorModel.GASMASK; + return model; + } +} diff --git a/common/mekanism/common/item/ItemScubaTank.java b/common/mekanism/common/item/ItemScubaTank.java new file mode 100644 index 000000000..70f0c2117 --- /dev/null +++ b/common/mekanism/common/item/ItemScubaTank.java @@ -0,0 +1,228 @@ +package mekanism.common.item; + +import java.util.List; + +import mekanism.api.EnumColor; +import mekanism.api.gas.Gas; +import mekanism.api.gas.GasRegistry; +import mekanism.api.gas.GasStack; +import mekanism.api.gas.IGasItem; +import mekanism.client.render.ModelCustomArmor; +import mekanism.client.render.ModelCustomArmor.ArmorModel; +import mekanism.common.Mekanism; +import mekanism.common.item.ItemJetpack.JetpackMode; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.common.EnumHelper; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public class ItemScubaTank extends ItemArmor implements IGasItem +{ + public int MAX_GAS = 24000; + public int TRANSFER_RATE = 16; + + public ItemScubaTank(int id) + { + super(id, EnumHelper.addArmorMaterial("SCUBATANK", 0, new int[] {0, 0, 0, 0}, 0), 0, 1); + setCreativeTab(Mekanism.tabMekanism); + setMaxDamage(100); + setNoRepair(); + } + + @Override + public void addInformation(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) + { + GasStack gasStack = getGas(itemstack); + + if(gasStack == null) + { + list.add("No gas stored."); + } + else { + list.add("Stored " + gasStack.getGas().getLocalizedName() + ": " + gasStack.amount); + } + + list.add(EnumColor.GREY + "Flowing: " + (getFlowing(itemstack) ? EnumColor.DARK_GREEN : EnumColor.DARK_RED) + getFlowing(itemstack)); + } + + @Override + public boolean isValidArmor(ItemStack stack, int armorType, Entity entity) + { + return armorType == 1; + } + + @Override + public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type) + { + return "mekanism:render/NullArmor.png"; + } + + @Override + @SideOnly(Side.CLIENT) + public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) + { + ModelCustomArmor model = ModelCustomArmor.INSTANCE; + model.modelType = ArmorModel.SCUBATANK; + return model; + } + + public void useGas(ItemStack stack) + { + setGas(new GasStack(getGas(stack).getGas(), getGas(stack).amount-1), stack); + } + + @Override + public int getMaxGas(Object... data) + { + if(data[0] instanceof ItemStack) + { + return MAX_GAS; + } + + return 0; + } + + @Override + public int getRate(ItemStack itemstack) + { + return TRANSFER_RATE; + } + + @Override + public int addGas(ItemStack itemstack, GasStack stack) + { + if(getGas(itemstack) != null && getGas(itemstack).getGas() != stack.getGas()) + { + return 0; + } + + if(stack.getGas() != GasRegistry.getGas("oxygen")) + { + return 0; + } + + int toUse = Math.min(getMaxGas(itemstack)-getStored(itemstack), Math.min(getRate(itemstack), stack.amount)); + setGas(new GasStack(stack.getGas(), getStored(itemstack)+toUse), itemstack); + + return toUse; + } + + @Override + public GasStack removeGas(ItemStack itemstack, int amount) + { + if(getGas(itemstack) == null) + { + return null; + } + + Gas type = getGas(itemstack).getGas(); + + int gasToUse = Math.min(getStored(itemstack), Math.min(getRate(itemstack), amount)); + setGas(new GasStack(type, getStored(itemstack)-gasToUse), itemstack); + + return new GasStack(type, gasToUse); + } + + public int getStored(ItemStack itemstack) + { + return getGas(itemstack) != null ? getGas(itemstack).amount : 0; + } + + public void toggleFlowing(ItemStack stack) + { + setFlowing(stack, !getFlowing(stack)); + } + + public boolean getFlowing(ItemStack stack) + { + if(stack.stackTagCompound == null) + { + return false; + } + + return stack.stackTagCompound.getBoolean("flowing"); + } + + public void setFlowing(ItemStack stack, boolean flowing) + { + if(stack.stackTagCompound == null) + { + stack.setTagCompound(new NBTTagCompound()); + } + + stack.stackTagCompound.setBoolean("flowing", flowing); + } + + @Override + public boolean canReceiveGas(ItemStack itemstack, Gas type) + { + return type == GasRegistry.getGas("oxygen"); + } + + @Override + public boolean canProvideGas(ItemStack itemstack, Gas type) + { + return getGas(itemstack) != null && (type == null || getGas(itemstack).getGas() == type); + } + + @Override + public GasStack getGas(Object... data) + { + if(data[0] instanceof ItemStack) + { + ItemStack itemstack = (ItemStack)data[0]; + + if(itemstack.stackTagCompound == null) + { + return null; + } + + GasStack stored = GasStack.readFromNBT(itemstack.stackTagCompound.getCompoundTag("stored")); + + if(stored == null) + { + itemstack.setItemDamage(100); + } + else { + itemstack.setItemDamage((int)Math.max(1, (Math.abs((((float)stored.amount/getMaxGas(itemstack))*100)-100)))); + } + + return stored; + } + + return null; + } + + @Override + public void setGas(GasStack stack, Object... data) + { + if(data[0] instanceof ItemStack) + { + ItemStack itemstack = (ItemStack)data[0]; + + if(itemstack.stackTagCompound == null) + { + itemstack.setTagCompound(new NBTTagCompound()); + } + + if(stack == null || stack.amount == 0) + { + itemstack.setItemDamage(100); + itemstack.stackTagCompound.removeTag("stored"); + } + else { + int amount = Math.max(0, Math.min(stack.amount, getMaxGas(itemstack))); + GasStack gasStack = new GasStack(stack.getGas(), amount); + + itemstack.setItemDamage((int)Math.max(1, (Math.abs((((float)amount/getMaxGas(itemstack))*100)-100)))); + itemstack.stackTagCompound.setCompoundTag("stored", gasStack.write(new NBTTagCompound())); + } + } + } +} diff --git a/common/mekanism/common/network/PacketScubaTankData.java b/common/mekanism/common/network/PacketScubaTankData.java new file mode 100644 index 000000000..84f2abc93 --- /dev/null +++ b/common/mekanism/common/network/PacketScubaTankData.java @@ -0,0 +1,98 @@ +package mekanism.common.network; + +import java.io.DataOutputStream; + +import mekanism.common.Mekanism; +import mekanism.common.PacketHandler; +import mekanism.common.PacketHandler.Transmission; +import mekanism.common.item.ItemScubaTank; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +import com.google.common.io.ByteArrayDataInput; + +public class PacketScubaTankData implements IMekanismPacket +{ + public PacketType packetType; + + public EntityPlayer updatePlayer; + public boolean value; + + @Override + public String getName() + { + return "ScubaTankData"; + } + + @Override + public IMekanismPacket setParams(Object... data) + { + packetType = (PacketType)data[0]; + + if(packetType == PacketType.UPDATE) + { + updatePlayer = (EntityPlayer)data[1]; + value = (Boolean)data[2]; + } + + return this; + } + + @Override + public void read(ByteArrayDataInput dataStream, EntityPlayer player, World world) throws Exception + { + packetType = PacketType.values()[dataStream.readInt()]; + + if(packetType == PacketType.UPDATE) + { + String username = dataStream.readUTF(); + boolean value = dataStream.readBoolean(); + + EntityPlayer p = world.getPlayerEntityByName(username); + + if(p != null) + { + if(value) + { + Mekanism.gasmaskOn.add(p); + } + else { + Mekanism.gasmaskOn.remove(p); + } + + if(!world.isRemote) + { + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketScubaTankData().setParams(PacketType.UPDATE, p, value), world.provider.dimensionId); + } + } + } + else if(packetType == PacketType.MODE) + { + ItemStack stack = player.getCurrentItemOrArmor(3); + + if(stack != null && stack.getItem() instanceof ItemScubaTank) + { + ((ItemScubaTank)stack.getItem()).toggleFlowing(stack); + } + } + } + + @Override + public void write(DataOutputStream dataStream) throws Exception + { + dataStream.writeInt(packetType.ordinal()); + + if(packetType == PacketType.UPDATE) + { + dataStream.writeUTF(updatePlayer.username); + dataStream.writeBoolean(value); + } + } + + public static enum PacketType + { + UPDATE, + MODE; + } +} diff --git a/resources/assets/mekanism/lang/en_US.lang b/resources/assets/mekanism/lang/en_US.lang index 12bda8d94..750ca13e9 100644 --- a/resources/assets/mekanism/lang/en_US.lang +++ b/resources/assets/mekanism/lang/en_US.lang @@ -23,6 +23,8 @@ item.Configurator.name=Configurator item.NetworkReader.name=Network Reader item.WalkieTalkie.name=Walkie-Talkie item.Jetpack.name=Jetpack +item.ScubaTank.name=Scuba Tank +item.GasMask.name=Gas Mask //Gas Tank tile.GasTank.GasTank.name=Gas Tank diff --git a/resources/assets/mekanism/sound/etc/GasMask.ogg b/resources/assets/mekanism/sound/etc/GasMask.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b0af86d2f5e2d389b182f2a23205c6e132732329 GIT binary patch literal 120015 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

)+kJQuvqFn{LYvi`Grg-6S4!*BGL+Q>_cg> zIo<>S06zB|Mg)LS0KDxSa|6N#)B)fggJ_pON`Kq-KEHQ$6{|>n9;-iC?4F~`ydAU1 zgS`QAP9aCO)DTV%?IwCQeu-N&=NMQSGWrBdKg4+Gu)+V*e&7XydN+Q#30zjd##`wnNyd*h0c z-ZhdOJo4OiU+rM{dfrVmK@3uOgD=EG4A6pen>A78o z(~g^vVs8=k&<0vP^!?h4a6l_BMWfb0#TBa2+9s`KP3SgBl<`@L7NQ-WpR@zNnxI>hr7RQQU?G7F6YlyBdx0N zbdQ_yx$&<7G9Fq3 z>!0J@L)^uTj(#cUO|OpiydIxa`UC4Xv-dCAVL1o@9EP;6zk;VlqvgAhc-zL9ENj~v zDFGe_9YzEYQh@;XU)LPQ1>mY!K?1&mZJBJ9t5Td^vlWNWirhx8#_?V3+t5doCtXI4 zaj~_ux>E#rPATM;6pA#K5b=FJJI!f+fUdExZ)@BCx$IBEIPCX+A66WR?Ks{62^xqA z13Woh1q=Ydde#B8ac3EyXk-OP?yXKA5I z9f-Yf;Rywo7*sOSxYl*yRkl>GcWV4`cJUxmlX`gf{qczjJ-8qa;ijYri$Dg`ZVGLi z$fm=9Z^EZ=QP>wpq|`jD)qRpu$S~8kwIfLNTufh9l_!oPUCl3iII4Z)$@DLMemS#` zTl09MxGj|PO>HyBdi(MR&HjF%&-7xaS=*W5i*{3Vb%iHzPZ?$Cmjh4IfzvFOi&IyngW^^9+2^_S#+gY0lom_9js~C ze`WXj-+mnz|Jvcu><-;AyZe_zAJ6P~En;TFEyYga=gASh{Ly~&{gv}? zbo+X0J~SXllTNUR*LCad<$P@3@o`z>b=!IxM=_4{?L$p$paL96dr4px0Dk7&2p7%PhX^Ra9zveY^~PE}^hH<=9E*tSxplydSy z8l<2A07_Q6N~VuyJ-)wpb@8N#ec6s4+O@+~@5AMIxW(vDAn&0ceRUS=Dh=;fSA{F~ z$Y9OISe^$(%gg0rAqAZwNSvAoIS}|5G};&IJ~H^QOH2D5UCoPRQWS{!0u` zW(@6xjUT%DQBfB{%rPvLFHC-lp{8-aXpt;kLuz5vfn1qdiuFOs_^X9>s&vY{lKC}X zq|77H?=P3fud8#@T@>vZ&Q+>GV|Tt9w4EDPS-uYnbz=6jS&_|Y=Q7)?>+tRPEsAQ~ zR=SFErEXf?Ng=d3$wj6dRb929roOgkUvyako`p(kk6emBtL{ZqVLjI^j!ue{-iDc0 zF$G;iSgE^*bkwq|6t3WP+#=pkoeIf<)3?w1@^Ha zMq(QBK4!gR=g0Lh>*{y}a84f>W=P9d?Tc1vGA5+s>{Wu3kec7ukOcD|uTgn;Ji?a z=^#Y7esj-ZWC-8@@E`X3`e#QO=Ze!mCJ*KN`0S!zVbc=@5^>d zap(5yU6-Ok|E9YuubZk5f$ZtYDN51uhcl|xWySqJgW5qW-b*QvQ74_}-DYOI|DjI^ zv#G3Rao_Ll=$^P8+~&8BE}Nksp5SnSmw3GKwR$lwS?7*z>uZx9i!D-Gn*Eh$$uYZS zux#0qmb@>R3G@#O@qG|lVe$um)80|BX7AVCy1c=R+-6O>Hj&XckE-CnRjn|NC#we94BC{JRyWi z@dg~9U!(W-_*DCC=u(LG_*mFm88C|6(s4Aj&)~#K+*}n&^Iokc66$E0UI)#?zFf<1 zy#8~E$Dv_1G=IGHw)yu#JB3Ao8q(igBj0u^)#E}sNvpSNy|>_1bq~^;0^se6HKHvy7Sj#x)7wJp z_ak>}P&UWT?1%uU!(!S~Ytp^>H`wL~vvZuhriWXzcVxquH|)#T2;F|Oa_ySG{YEz{a(`o$xyBvPrT zMg#DXYC4zkQS|l7n?9*kKE7Up`TZ_bX8Psd-X|0bb!0f2r_a@B z19s2vZ9n<^Rqs}z8e}{F!FaVaDJeP-(d(L?cn`6#>?QXK*!�))Y(Oa$CE$)r+xu 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 bXW?hyrm)Fgb3S79nWb|U$a7lccoJ&@gTbC3 literal 0 HcmV?d00001 From 84ab705170c7f37f66cfa9c134720a87893af1f9 Mon Sep 17 00:00:00 2001 From: "Aidan C. Brady" Date: Fri, 6 Dec 2013 16:44:08 -0500 Subject: [PATCH 03/40] Start work on new description system, UNSTABLE BUILD --- .../client/ClientPlayerTickHandler.java | 186 ++++++++++-------- .../common/CommonPlayerTickHandler.java | 34 ++++ .../common/item/ItemBlockMachine.java | 9 +- common/mekanism/common/item/ItemJetpack.java | 9 +- .../mekanism/common/item/ItemScubaTank.java | 22 +++ 5 files changed, 165 insertions(+), 95 deletions(-) diff --git a/common/mekanism/client/ClientPlayerTickHandler.java b/common/mekanism/client/ClientPlayerTickHandler.java index ef9d752bf..7a63bcc63 100644 --- a/common/mekanism/client/ClientPlayerTickHandler.java +++ b/common/mekanism/client/ClientPlayerTickHandler.java @@ -52,86 +52,89 @@ public class ClientPlayerTickHandler implements ITickHandler ItemStack stack = entityPlayer.getCurrentEquippedItem(); - if(entityPlayer.isSneaking() && StackUtils.getItem(entityPlayer.getCurrentEquippedItem()) instanceof ItemConfigurator) + if(mc.currentScreen == null) { - ItemConfigurator item = (ItemConfigurator)entityPlayer.getCurrentEquippedItem().getItem(); - - if(MekanismKeyHandler.modeSwitchKey.pressed) - { - if(!lastTickUpdate) - { - item.setState(stack, (byte)(item.getState(stack) < 3 ? item.getState(stack)+1 : 0)); - PacketHandler.sendPacket(Transmission.SERVER, new PacketConfiguratorState().setParams(item.getState(stack))); - entityPlayer.sendChatToPlayer(ChatMessageComponent.createFromText(EnumColor.DARK_BLUE + "[Mekanism] " + EnumColor.GREY + "Configure State: " + item.getColor(item.getState(stack)) + item.getStateDisplay(item.getState(stack)))); - lastTickUpdate = true; - } - } - else { - lastTickUpdate = false; - } - } - else if(entityPlayer.isSneaking() && StackUtils.getItem(entityPlayer.getCurrentEquippedItem()) instanceof ItemElectricBow) - { - ItemElectricBow item = (ItemElectricBow)entityPlayer.getCurrentEquippedItem().getItem(); - - if(MekanismKeyHandler.modeSwitchKey.pressed) + if(entityPlayer.isSneaking() && StackUtils.getItem(entityPlayer.getCurrentEquippedItem()) instanceof ItemConfigurator) { - if(!lastTickUpdate) + ItemConfigurator item = (ItemConfigurator)entityPlayer.getCurrentEquippedItem().getItem(); + + if(MekanismKeyHandler.modeSwitchKey.pressed) + { + if(!lastTickUpdate) + { + item.setState(stack, (byte)(item.getState(stack) < 3 ? item.getState(stack)+1 : 0)); + PacketHandler.sendPacket(Transmission.SERVER, new PacketConfiguratorState().setParams(item.getState(stack))); + entityPlayer.sendChatToPlayer(ChatMessageComponent.createFromText(EnumColor.DARK_BLUE + "[Mekanism] " + EnumColor.GREY + "Configure State: " + item.getColor(item.getState(stack)) + item.getStateDisplay(item.getState(stack)))); + lastTickUpdate = true; + } + } + else { + lastTickUpdate = false; + } + } + else if(entityPlayer.isSneaking() && StackUtils.getItem(entityPlayer.getCurrentEquippedItem()) instanceof ItemElectricBow) + { + ItemElectricBow item = (ItemElectricBow)entityPlayer.getCurrentEquippedItem().getItem(); + + if(MekanismKeyHandler.modeSwitchKey.pressed) { - item.setFireState(stack, !item.getFireState(stack)); - PacketHandler.sendPacket(Transmission.SERVER, new PacketElectricBowState().setParams(item.getFireState(stack))); - entityPlayer.sendChatToPlayer(ChatMessageComponent.createFromText(EnumColor.DARK_BLUE + "[Mekanism] " + EnumColor.GREY + "Fire Mode: " + (item.getFireState(stack) ? (EnumColor.DARK_GREEN + "ON") : (EnumColor.DARK_RED + "OFF")))); - lastTickUpdate = true; + if(!lastTickUpdate) + { + item.setFireState(stack, !item.getFireState(stack)); + PacketHandler.sendPacket(Transmission.SERVER, new PacketElectricBowState().setParams(item.getFireState(stack))); + entityPlayer.sendChatToPlayer(ChatMessageComponent.createFromText(EnumColor.DARK_BLUE + "[Mekanism] " + EnumColor.GREY + "Fire Mode: " + (item.getFireState(stack) ? (EnumColor.DARK_GREEN + "ON") : (EnumColor.DARK_RED + "OFF")))); + lastTickUpdate = true; + } + } + else { + lastTickUpdate = false; + } + } + else if(entityPlayer.isSneaking() && StackUtils.getItem(entityPlayer.getCurrentEquippedItem()) instanceof ItemWalkieTalkie) + { + ItemWalkieTalkie item = (ItemWalkieTalkie)entityPlayer.getCurrentEquippedItem().getItem(); + + if(MekanismKeyHandler.modeSwitchKey.pressed && item.getOn(stack)) + { + if(!lastTickUpdate) + { + int newChan = item.getChannel(stack) < 9 ? item.getChannel(stack)+1 : 1; + item.setChannel(stack, newChan); + PacketHandler.sendPacket(Transmission.SERVER, new PacketWalkieTalkieState().setParams(newChan)); + Minecraft.getMinecraft().sndManager.playSoundFX("mekanism:etc.Ding", 1.0F, 1.0F); + lastTickUpdate = true; + } + } + else { + lastTickUpdate = false; + } + } + else if(entityPlayer.getCurrentItemOrArmor(3) != null && entityPlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) + { + ItemStack jetpack = entityPlayer.getCurrentItemOrArmor(3); + + if(MekanismKeyHandler.modeSwitchKey.pressed) + { + if(!lastTickUpdate) + { + ((ItemJetpack)jetpack.getItem()).incrementMode(jetpack); + PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.MODE)); + Minecraft.getMinecraft().sndManager.playSoundFX("mekanism:etc.Hydraulic", 1.0F, 1.0F); + lastTickUpdate = true; + } + } + else { + lastTickUpdate = false; } } else { lastTickUpdate = false; } } - else if(entityPlayer.isSneaking() && StackUtils.getItem(entityPlayer.getCurrentEquippedItem()) instanceof ItemWalkieTalkie) - { - ItemWalkieTalkie item = (ItemWalkieTalkie)entityPlayer.getCurrentEquippedItem().getItem(); - - if(MekanismKeyHandler.modeSwitchKey.pressed && item.getOn(stack)) - { - if(!lastTickUpdate) - { - int newChan = item.getChannel(stack) < 9 ? item.getChannel(stack)+1 : 1; - item.setChannel(stack, newChan); - PacketHandler.sendPacket(Transmission.SERVER, new PacketWalkieTalkieState().setParams(newChan)); - Minecraft.getMinecraft().sndManager.playSoundFX("mekanism:etc.Ding", 1.0F, 1.0F); - lastTickUpdate = true; - } - } - else { - lastTickUpdate = false; - } - } - else if(entityPlayer.getCurrentItemOrArmor(3) != null && entityPlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) - { - ItemStack jetpack = entityPlayer.getCurrentItemOrArmor(3); - - if(MekanismKeyHandler.modeSwitchKey.pressed) - { - if(!lastTickUpdate) - { - ((ItemJetpack)jetpack.getItem()).incrementMode(jetpack); - PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.MODE)); - Minecraft.getMinecraft().sndManager.playSoundFX("mekanism:etc.Hydraulic", 1.0F, 1.0F); - lastTickUpdate = true; - } - } - else { - lastTickUpdate = false; - } - } - else { - lastTickUpdate = false; - } if(Mekanism.jetpackOn.contains(entityPlayer) != isJetpackOn(entityPlayer)) { - if(isJetpackOn(entityPlayer)) + if(isJetpackOn(entityPlayer) && mc.currentScreen == null) { Mekanism.jetpackOn.add(entityPlayer); } @@ -139,7 +142,26 @@ public class ClientPlayerTickHandler implements ITickHandler Mekanism.jetpackOn.remove(entityPlayer); } - PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.UPDATE, entityPlayer, isJetpackOn(entityPlayer))); + if(!isGasMaskOn(entityPlayer) || mc.currentScreen == null) + { + PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.UPDATE, entityPlayer, isJetpackOn(entityPlayer))); + } + } + + if(Mekanism.gasmaskOn.contains(entityPlayer) != isGasMaskOn(entityPlayer)) + { + if(isGasMaskOn(entityPlayer) && mc.currentScreen == null) + { + Mekanism.gasmaskOn.add(entityPlayer); + } + else { + Mekanism.gasmaskOn.remove(entityPlayer); + } + + if(!isGasMaskOn(entityPlayer) || mc.currentScreen == null) + { + PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(PacketType.UPDATE, entityPlayer, isGasMaskOn(entityPlayer))); + } } for(EntityPlayer entry : Mekanism.jetpackOn) @@ -150,19 +172,6 @@ public class ClientPlayerTickHandler implements ITickHandler } } - if(Mekanism.gasmaskOn.contains(entityPlayer) != isGasMaskOn(entityPlayer)) - { - if(isGasMaskOn(entityPlayer)) - { - Mekanism.gasmaskOn.add(entityPlayer); - } - else { - Mekanism.gasmaskOn.remove(entityPlayer); - } - - PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(PacketType.UPDATE, entityPlayer, isGasMaskOn(entityPlayer))); - } - for(EntityPlayer entry : Mekanism.gasmaskOn) { if(MekanismClient.audioHandler.getFrom(entry) == null) @@ -171,24 +180,27 @@ public class ClientPlayerTickHandler implements ITickHandler } } - if(entityPlayer.getCurrentItemOrArmor(3) != null && entityPlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) + if(mc.currentScreen == null) { - MekanismClient.updateKey(entityPlayer, Keyboard.KEY_SPACE); - MekanismClient.updateKey(entityPlayer, Keyboard.KEY_LSHIFT); + if(entityPlayer.getCurrentItemOrArmor(3) != null && entityPlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) + { + MekanismClient.updateKey(entityPlayer, Keyboard.KEY_SPACE); + MekanismClient.updateKey(entityPlayer, Keyboard.KEY_LSHIFT); + } } if(isJetpackOn(entityPlayer)) { ItemJetpack jetpack = (ItemJetpack)entityPlayer.getCurrentItemOrArmor(3).getItem(); - if(jetpack.getMode(entityPlayer.getCurrentItemOrArmor(3)) == JetpackMode.NORMAL) + if(jetpack.getMode(entityPlayer.getCurrentItemOrArmor(3)) == JetpackMode.NORMAL && mc.currentScreen == null) { entityPlayer.motionY = Math.min(mc.thePlayer.motionY + 0.15D, 0.5D); entityPlayer.fallDistance = 0.0F; } else if(jetpack.getMode(entityPlayer.getCurrentItemOrArmor(3)) == JetpackMode.HOVER) { - if((!Keyboard.isKeyDown(Keyboard.KEY_SPACE) && !Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) || (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))) + if(((!Keyboard.isKeyDown(Keyboard.KEY_SPACE) && !Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) || (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))) || mc.currentScreen != null) { if(entityPlayer.motionY > 0) { diff --git a/common/mekanism/common/CommonPlayerTickHandler.java b/common/mekanism/common/CommonPlayerTickHandler.java index 8d3af298f..2f6aec45c 100644 --- a/common/mekanism/common/CommonPlayerTickHandler.java +++ b/common/mekanism/common/CommonPlayerTickHandler.java @@ -5,8 +5,10 @@ import java.util.EnumSet; import org.lwjgl.input.Keyboard; import mekanism.common.PacketHandler.Transmission; +import mekanism.common.item.ItemGasMask; import mekanism.common.item.ItemJetpack; import mekanism.common.item.ItemPortableTeleporter; +import mekanism.common.item.ItemScubaTank; import mekanism.common.item.ItemJetpack.JetpackMode; import mekanism.common.network.PacketStatusUpdate; import mekanism.common.util.MekanismUtils; @@ -123,6 +125,14 @@ public class CommonPlayerTickHandler implements ITickHandler jetpack.useGas(player.getCurrentItemOrArmor(3)); } + + if(isGasMaskOn(player)) + { + ItemScubaTank tank = (ItemScubaTank)player.getCurrentItemOrArmor(3).getItem(); + + tank.useGas(player.getCurrentItemOrArmor(3)); + player.setAir(300); + } } } @@ -152,6 +162,30 @@ public class CommonPlayerTickHandler implements ITickHandler return false; } + + public static boolean isGasMaskOn(EntityPlayer player) + { + ItemStack tank = player.inventory.armorInventory[2]; + ItemStack mask = player.inventory.armorInventory[3]; + + if(tank != null && mask != null) + { + if(tank.getItem() instanceof ItemScubaTank && mask.getItem() instanceof ItemGasMask) + { + ItemScubaTank scubaTank = (ItemScubaTank)tank.getItem(); + + if(scubaTank.getGas(tank) != null) + { + if(scubaTank.getFlowing(tank)) + { + return true; + } + } + } + } + + return false; + } @Override public EnumSet ticks() diff --git a/common/mekanism/common/item/ItemBlockMachine.java b/common/mekanism/common/item/ItemBlockMachine.java index 8ae1c1dab..9a52bba32 100644 --- a/common/mekanism/common/item/ItemBlockMachine.java +++ b/common/mekanism/common/item/ItemBlockMachine.java @@ -120,9 +120,11 @@ public class ItemBlockMachine extends ItemBlock implements IEnergizedItem, IItem if(!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) { - list.add("Hold " + EnumColor.AQUA + "shift" + EnumColor.GREY + " for more details."); + list.add("Hold " + EnumColor.INDIGO + "shift" + EnumColor.GREY + " for a description."); + list.add("Hold " + EnumColor.AQUA + "shift-M" + EnumColor.GREY + " for more details."); } - else { + else if(Keyboard.isKeyDown(Keyboard.KEY_M)) + { if(type == MachineType.BASIC_FACTORY || type == MachineType.ADVANCED_FACTORY || type == MachineType.ELITE_FACTORY) { list.add(EnumColor.INDIGO + "Recipe Type: " + EnumColor.GREY + RecipeType.values()[getRecipeType(itemstack)].getName()); @@ -166,6 +168,9 @@ public class ItemBlockMachine extends ItemBlock implements IEnergizedItem, IItem list.add(EnumColor.AQUA + "Inventory: " + EnumColor.GREY + (getInventory(itemstack) != null && getInventory(itemstack).tagCount() != 0)); } } + else { + + } } @Override diff --git a/common/mekanism/common/item/ItemJetpack.java b/common/mekanism/common/item/ItemJetpack.java index 071373c7d..091c6389e 100644 --- a/common/mekanism/common/item/ItemJetpack.java +++ b/common/mekanism/common/item/ItemJetpack.java @@ -243,12 +243,9 @@ public class ItemJetpack extends ItemArmor implements IGasItem empty.setItemDamage(100); list.add(empty); - for(Gas type : GasRegistry.getRegisteredGasses()) - { - ItemStack filled = new ItemStack(this); - setGas(new GasStack(type, ((IGasItem)filled.getItem()).getMaxGas(filled)), filled); - list.add(filled); - } + ItemStack filled = new ItemStack(this); + setGas(new GasStack(GasRegistry.getGas("hydrogen"), ((IGasItem)filled.getItem()).getMaxGas(filled)), filled); + list.add(filled); } public static enum JetpackMode diff --git a/common/mekanism/common/item/ItemScubaTank.java b/common/mekanism/common/item/ItemScubaTank.java index 70f0c2117..34d172b10 100644 --- a/common/mekanism/common/item/ItemScubaTank.java +++ b/common/mekanism/common/item/ItemScubaTank.java @@ -12,6 +12,7 @@ import mekanism.client.render.ModelCustomArmor.ArmorModel; import mekanism.common.Mekanism; import mekanism.common.item.ItemJetpack.JetpackMode; import net.minecraft.client.model.ModelBiped; +import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; @@ -225,4 +226,25 @@ public class ItemScubaTank extends ItemArmor implements IGasItem } } } + + public ItemStack getEmptyItem() + { + ItemStack empty = new ItemStack(this); + setGas(null, empty); + empty.setItemDamage(100); + return empty; + } + + @Override + public void getSubItems(int i, CreativeTabs tabs, List list) + { + ItemStack empty = new ItemStack(this); + setGas(null, empty); + empty.setItemDamage(100); + list.add(empty); + + ItemStack filled = new ItemStack(this); + setGas(new GasStack(GasRegistry.getGas("oxygen"), ((IGasItem)filled.getItem()).getMaxGas(filled)), filled); + list.add(filled); + } } From 916859c21d4cc8e6fe39b68f4f7c5037cdc2ca6c Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Fri, 6 Dec 2013 20:03:25 -0500 Subject: [PATCH 04/40] Added description text to machines --- common/mekanism/common/block/BlockMachine.java | 5 +++++ .../mekanism/common/item/ItemBlockMachine.java | 8 ++++---- common/mekanism/common/util/MekanismUtils.java | 14 +++++++++++++- resources/assets/mekanism/lang/en_US.lang | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/common/mekanism/common/block/BlockMachine.java b/common/mekanism/common/block/BlockMachine.java index 78de5fe78..5b5f2148a 100644 --- a/common/mekanism/common/block/BlockMachine.java +++ b/common/mekanism/common/block/BlockMachine.java @@ -1074,6 +1074,11 @@ public class BlockMachine extends BlockContainer implements ISpecialBounds } } + public String getDescription() + { + return MekanismUtils.localize("tooltip." + name); + } + public ItemStack getStack() { return new ItemStack(typeId, 1, meta); diff --git a/common/mekanism/common/item/ItemBlockMachine.java b/common/mekanism/common/item/ItemBlockMachine.java index 9a52bba32..ac5283bbb 100644 --- a/common/mekanism/common/item/ItemBlockMachine.java +++ b/common/mekanism/common/item/ItemBlockMachine.java @@ -120,10 +120,10 @@ public class ItemBlockMachine extends ItemBlock implements IEnergizedItem, IItem if(!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) { - list.add("Hold " + EnumColor.INDIGO + "shift" + EnumColor.GREY + " for a description."); - list.add("Hold " + EnumColor.AQUA + "shift-M" + EnumColor.GREY + " for more details."); + list.add("Hold " + EnumColor.AQUA + EnumColor.INDIGO + "shift" + EnumColor.GREY + " for more details."); + list.add("Hold " + EnumColor.AQUA + "shift" + EnumColor.GREY + " and " + EnumColor.AQUA + "M" + EnumColor.GREY + " for a description."); } - else if(Keyboard.isKeyDown(Keyboard.KEY_M)) + else if(!Keyboard.isKeyDown(Keyboard.KEY_M)) { if(type == MachineType.BASIC_FACTORY || type == MachineType.ADVANCED_FACTORY || type == MachineType.ELITE_FACTORY) { @@ -169,7 +169,7 @@ public class ItemBlockMachine extends ItemBlock implements IEnergizedItem, IItem } } else { - + list.addAll(MekanismUtils.getSplitText(type.getDescription())); } } diff --git a/common/mekanism/common/util/MekanismUtils.java b/common/mekanism/common/util/MekanismUtils.java index 9bfd1fc39..757b0df40 100644 --- a/common/mekanism/common/util/MekanismUtils.java +++ b/common/mekanism/common/util/MekanismUtils.java @@ -8,17 +8,19 @@ import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import mekanism.api.EnumColor; import mekanism.api.Object3D; import mekanism.common.DynamicTankCache; import mekanism.common.IActiveState; -import mekanism.common.IInvConfiguration; import mekanism.common.IFactory; import mekanism.common.IFactory.RecipeType; +import mekanism.common.IInvConfiguration; import mekanism.common.IModule; import mekanism.common.IRedstoneControl; import mekanism.common.IRedstoneControl.RedstoneControl; @@ -1126,6 +1128,16 @@ public final class MekanismUtils return "[" + obj.xCoord + ", " + obj.yCoord + ", " + obj.zCoord + "]"; } + public static List getSplitText(String s) + { + ArrayList ret = new ArrayList(); + + String[] split = s.split("!n"); + ret.addAll(Arrays.asList(split)); + + return ret; + } + public static enum ResourceType { GUI("gui"), diff --git a/resources/assets/mekanism/lang/en_US.lang b/resources/assets/mekanism/lang/en_US.lang index 750ca13e9..8b97e99d0 100644 --- a/resources/assets/mekanism/lang/en_US.lang +++ b/resources/assets/mekanism/lang/en_US.lang @@ -249,6 +249,24 @@ tooltip.jetpack.regular=Regular tooltip.jetpack.hover=Hover tooltip.jetpack.disabled=Disabled +tooltip.EnrichmentChamber=A simple machine used to enrich ores into !ntwo of their dust counterparts, as well as !nperform many other operations. +tooltip.OsmiumCompressor=A fairly advanced machine used to compress !nosmium into various dusts in order to create !ntheir ingot counterparts. +tooltip.Combiner=A machine used to combine dusts and cobblestone to !nform their ore counterparts. +tooltip.Crusher=A machine used to crush ingots into their dust counterparts, !nas well as perform many other operations. +tooltip.DigitalMiner=A highly-advanced, filter-based, auto-miner that can !nmine whatever block you tell it to within !na 32 block (max) radius. +tooltip.BasicFactory=The lowest tier of the line of Factories, which can !nbe used to process multiple machine operations !nat once. +tooltip.AdvancedFactory=The middle tier of the line of Factories, which can !nbe used to process multiple machine !noperations at once. +tooltip.EliteFactory=The highest tier of the line of Factories, which can !nbe used to process multiple machine !noperations at once. +tooltip.MetallurgicInfuser=A machine used to infuse various materials !ninto (generally) metals to create metal alloys !nand other compounds. +tooltip.PurificationChamber=An advanced machine capable of processing !nores into three clumps, serving as the initial !nstage of 300% ore processing. +tooltip.EnergizedSmelter=A simple machine that serves as a Mekanism-based !nfurnace that runs off of energy. +tooltip.Teleporter=A machine capable of teleporting players to various !nlocations defined by another teleported. +tooltip.ElectricPump=An advanced pump capable of pumping out an entire !nlava lake. +tooltip.ElectricChest=A portable, 54-slot chest that uses energy to lock !nitself from others by means of password protection. +tooltip.Chargepad=A universal chargepad that can charge any energized item !nfrom any mod. +tooltip.LogisticalSorter=A filter-based, advanced sorting machine that !ncan auto-eject specified items out of and into !nadjacent inventories and Logistical Transporters. +tooltip.RotaryCondensentrator=A machine capable of converting gasses into !ntheir fluid form and vice versa. + //Redstone control control.disabled=Disabled control.high=High From 5e50e920a6f6bebde6d8c067524f88c5c7c1ace4 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sat, 7 Dec 2013 00:55:35 -0500 Subject: [PATCH 05/40] Add potion resistance to gas mask --- .../client/ClientPlayerTickHandler.java | 1 + .../common/CommonPlayerTickHandler.java | 1 + .../mekanism/common/block/BlockMachine.java | 16 +++++----- common/mekanism/common/item/ItemGasMask.java | 29 +++++++++++++++++-- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/common/mekanism/client/ClientPlayerTickHandler.java b/common/mekanism/client/ClientPlayerTickHandler.java index 7a63bcc63..96ac3b7a2 100644 --- a/common/mekanism/client/ClientPlayerTickHandler.java +++ b/common/mekanism/client/ClientPlayerTickHandler.java @@ -234,6 +234,7 @@ public class ClientPlayerTickHandler implements ITickHandler tank.useGas(entityPlayer.getCurrentItemOrArmor(3)); entityPlayer.setAir(300); + entityPlayer.clearActivePotions(); } } } diff --git a/common/mekanism/common/CommonPlayerTickHandler.java b/common/mekanism/common/CommonPlayerTickHandler.java index 2f6aec45c..9e372b4cf 100644 --- a/common/mekanism/common/CommonPlayerTickHandler.java +++ b/common/mekanism/common/CommonPlayerTickHandler.java @@ -132,6 +132,7 @@ public class CommonPlayerTickHandler implements ITickHandler tank.useGas(player.getCurrentItemOrArmor(3)); player.setAir(300); + player.clearActivePotions(); } } } diff --git a/common/mekanism/common/block/BlockMachine.java b/common/mekanism/common/block/BlockMachine.java index 5b5f2148a..2ffbe2260 100644 --- a/common/mekanism/common/block/BlockMachine.java +++ b/common/mekanism/common/block/BlockMachine.java @@ -247,23 +247,23 @@ public class BlockMachine extends BlockContainer implements ISpecialBounds if(side == 4) { - world.spawnParticle("smoke", (double)(xRandom - iRandom), (double)yRandom, (double)(zRandom + jRandom), 0.0D, 0.0D, 0.0D); - world.spawnParticle("reddust", (double)(xRandom - iRandom), (double)yRandom, (double)(zRandom + jRandom), 0.0D, 0.0D, 0.0D); + world.spawnParticle("smoke", (xRandom - iRandom), yRandom, (zRandom + jRandom), 0.0D, 0.0D, 0.0D); + world.spawnParticle("reddust", (xRandom - iRandom), yRandom, (zRandom + jRandom), 0.0D, 0.0D, 0.0D); } else if(side == 5) { - world.spawnParticle("smoke", (double)(xRandom + iRandom), (double)yRandom, (double)(zRandom + jRandom), 0.0D, 0.0D, 0.0D); - world.spawnParticle("reddust", (double)(xRandom + iRandom), (double)yRandom, (double)(zRandom + jRandom), 0.0D, 0.0D, 0.0D); + world.spawnParticle("smoke", (xRandom + iRandom), yRandom, (zRandom + jRandom), 0.0D, 0.0D, 0.0D); + world.spawnParticle("reddust", (xRandom + iRandom), yRandom, (zRandom + jRandom), 0.0D, 0.0D, 0.0D); } else if(side == 2) { - world.spawnParticle("smoke", (double)(xRandom + jRandom), (double)yRandom, (double)(zRandom - iRandom), 0.0D, 0.0D, 0.0D); - world.spawnParticle("reddust", (double)(xRandom + jRandom), (double)yRandom, (double)(zRandom - iRandom), 0.0D, 0.0D, 0.0D); + world.spawnParticle("smoke", (xRandom + jRandom), yRandom, (zRandom - iRandom), 0.0D, 0.0D, 0.0D); + world.spawnParticle("reddust", (xRandom + jRandom), yRandom, (zRandom - iRandom), 0.0D, 0.0D, 0.0D); } else if(side == 3) { - world.spawnParticle("smoke", (double)(xRandom + jRandom), (double)yRandom, (double)(zRandom + iRandom), 0.0D, 0.0D, 0.0D); - world.spawnParticle("reddust", (double)(xRandom + jRandom), (double)yRandom, (double)(zRandom + iRandom), 0.0D, 0.0D, 0.0D); + world.spawnParticle("smoke", (xRandom + jRandom), yRandom, (zRandom + iRandom), 0.0D, 0.0D, 0.0D); + world.spawnParticle("reddust", (xRandom + jRandom), yRandom, (zRandom + iRandom), 0.0D, 0.0D, 0.0D); } } } diff --git a/common/mekanism/common/item/ItemGasMask.java b/common/mekanism/common/item/ItemGasMask.java index fa5e22e5c..1860d51a4 100644 --- a/common/mekanism/common/item/ItemGasMask.java +++ b/common/mekanism/common/item/ItemGasMask.java @@ -1,7 +1,5 @@ package mekanism.common.item; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import mekanism.client.render.ModelCustomArmor; import mekanism.client.render.ModelCustomArmor.ArmorModel; import mekanism.common.Mekanism; @@ -11,6 +9,11 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; import net.minecraftforge.common.EnumHelper; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.ForgeSubscribe; +import net.minecraftforge.event.entity.living.LivingAttackEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; public class ItemGasMask extends ItemArmor { @@ -18,6 +21,7 @@ public class ItemGasMask extends ItemArmor { super(id, EnumHelper.addArmorMaterial("GASMASK", 0, new int[] {0, 0, 0, 0}, 0), 0, 0); setCreativeTab(Mekanism.tabMekanism); + MinecraftForge.EVENT_BUS.register(this); } @Override @@ -40,4 +44,25 @@ public class ItemGasMask extends ItemArmor model.modelType = ArmorModel.GASMASK; return model; } + + @ForgeSubscribe + public void onEntityAttacked(LivingAttackEvent event) + { + EntityLivingBase base = event.entityLiving; + + if(base.getCurrentItemOrArmor(4) != null && base.getCurrentItemOrArmor(4).getItem() instanceof ItemGasMask) + { + ItemGasMask mask = (ItemGasMask)base.getCurrentItemOrArmor(4).getItem(); + + if(base.getCurrentItemOrArmor(3) != null && base.getCurrentItemOrArmor(3).getItem() instanceof ItemScubaTank) + { + ItemScubaTank tank = (ItemScubaTank)base.getCurrentItemOrArmor(3).getItem(); + + if(tank.getFlowing(base.getCurrentItemOrArmor(3)) && tank.getGas(base.getCurrentItemOrArmor(3)) != null) + { + event.setCanceled(true); + } + } + } + } } From c2737ff0640c52ca934aaaa1b35187d6aa6a146d Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sat, 7 Dec 2013 17:06:11 -0500 Subject: [PATCH 06/40] Work on things, may be unstable --- .../mekanism/client/ClientPlayerTracker.java | 26 ++++ common/mekanism/client/ClientProxy.java | 5 + .../tileentity/RenderConfigurableMachine.java | 7 +- .../RenderLogisticalTransporter.java | 8 +- .../tileentity/RenderMechanicalPipe.java | 2 +- .../tileentity/RenderPressurizedTube.java | 2 +- .../render/tileentity/RenderTeleporter.java | 127 +++++++++++++++ .../mekanism/client/sound/GasMaskSound.java | 4 + .../mekanism/client/sound/JetpackSound.java | 4 + common/mekanism/client/sound/PlayerSound.java | 6 - .../mekanism/common/CommonPlayerTracker.java | 5 +- common/mekanism/common/CommonProxy.java | 1 + common/mekanism/common/Mekanism.java | 1 - .../mekanism/common/block/BlockMachine.java | 18 +-- .../network/PacketPortableTeleport.java | 8 + .../tileentity/TileEntityTeleporter.java | 147 +++++++++++++++--- 16 files changed, 311 insertions(+), 60 deletions(-) create mode 100644 common/mekanism/client/ClientPlayerTracker.java create mode 100644 common/mekanism/client/render/tileentity/RenderTeleporter.java diff --git a/common/mekanism/client/ClientPlayerTracker.java b/common/mekanism/client/ClientPlayerTracker.java new file mode 100644 index 000000000..1124c9ad3 --- /dev/null +++ b/common/mekanism/client/ClientPlayerTracker.java @@ -0,0 +1,26 @@ +package mekanism.client; + +import mekanism.common.Mekanism; +import net.minecraft.entity.player.EntityPlayer; +import cpw.mods.fml.common.IPlayerTracker; + +public class ClientPlayerTracker implements IPlayerTracker +{ + @Override + public void onPlayerLogin(EntityPlayer player) {} + + @Override + public void onPlayerLogout(EntityPlayer player) + { + Mekanism.jetpackOn.remove(player); + } + + @Override + public void onPlayerChangedDimension(EntityPlayer player) + { + Mekanism.jetpackOn.remove(player); + } + + @Override + public void onPlayerRespawn(EntityPlayer player) {} +} diff --git a/common/mekanism/client/ClientProxy.java b/common/mekanism/client/ClientProxy.java index c974ff98e..cf64434b3 100644 --- a/common/mekanism/client/ClientProxy.java +++ b/common/mekanism/client/ClientProxy.java @@ -54,6 +54,7 @@ import mekanism.client.render.tileentity.RenderMetallurgicInfuser; import mekanism.client.render.tileentity.RenderObsidianTNT; import mekanism.client.render.tileentity.RenderPressurizedTube; import mekanism.client.render.tileentity.RenderRotaryCondensentrator; +import mekanism.client.render.tileentity.RenderTeleporter; import mekanism.client.render.tileentity.RenderUniversalCable; import mekanism.client.sound.Sound; import mekanism.client.sound.SoundHandler; @@ -109,6 +110,7 @@ import cpw.mods.fml.client.registry.ClientRegistry; import cpw.mods.fml.client.registry.KeyBindingRegistry; import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.common.registry.TickRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -255,6 +257,7 @@ public class ClientProxy extends CommonProxy ClientRegistry.registerTileEntity(TileEntityBin.class, "Bin", new RenderBin()); ClientRegistry.registerTileEntity(TileEntityDigitalMiner.class, "DigitalMiner", new RenderDigitalMiner()); ClientRegistry.registerTileEntity(TileEntityRotaryCondensentrator.class, "RotaryCondensentrator", new RenderRotaryCondensentrator()); + ClientRegistry.registerTileEntity(TileEntityTeleporter.class, "MekanismTeleporter", new RenderTeleporter()); } @Override @@ -381,6 +384,8 @@ public class ClientProxy extends CommonProxy NetworkRegistry.instance().registerConnectionHandler(new ClientConnectionHandler()); KeyBindingRegistry.registerKeyBinding(new MekanismKeyHandler()); + + GameRegistry.registerPlayerTracker(new ClientPlayerTracker()); } @Override diff --git a/common/mekanism/client/render/tileentity/RenderConfigurableMachine.java b/common/mekanism/client/render/tileentity/RenderConfigurableMachine.java index c5fe163e2..c4c5428fc 100644 --- a/common/mekanism/client/render/tileentity/RenderConfigurableMachine.java +++ b/common/mekanism/client/render/tileentity/RenderConfigurableMachine.java @@ -106,7 +106,7 @@ public class RenderConfigurableMachine extends TileEntitySpecialRenderer toReturn.baseBlock = Block.stone; toReturn.setTexture(MekanismRenderer.getColorIcon(color)); - DisplayInteger display = new DisplayInteger(); + DisplayInteger display = DisplayInteger.createAndStart(); if(cachedOverlays.containsKey(side)) { @@ -118,9 +118,6 @@ public class RenderConfigurableMachine extends TileEntitySpecialRenderer cachedOverlays.put(side, map); } - display.display = GLAllocation.generateDisplayLists(1); - GL11.glNewList(display.display, 4864); - switch(side) { case DOWN: @@ -196,7 +193,7 @@ public class RenderConfigurableMachine extends TileEntitySpecialRenderer } MekanismRenderer.renderObject(toReturn); - GL11.glEndList(); + display.endList(); return display; } diff --git a/common/mekanism/client/render/tileentity/RenderLogisticalTransporter.java b/common/mekanism/client/render/tileentity/RenderLogisticalTransporter.java index e623c4a7a..8c7fa7b9f 100644 --- a/common/mekanism/client/render/tileentity/RenderLogisticalTransporter.java +++ b/common/mekanism/client/render/tileentity/RenderLogisticalTransporter.java @@ -18,7 +18,6 @@ import mekanism.common.util.MekanismUtils.ResourceType; import mekanism.common.util.TransporterUtils; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GLAllocation; import net.minecraft.client.renderer.entity.RenderItem; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; @@ -215,7 +214,7 @@ public class RenderLogisticalTransporter extends TileEntitySpecialRenderer toReturn.baseBlock = Block.stone; toReturn.setTexture(icon); - DisplayInteger display = new DisplayInteger(); + DisplayInteger display = DisplayInteger.createAndStart(); if(cachedOverlays.containsKey(side)) { @@ -227,9 +226,6 @@ public class RenderLogisticalTransporter extends TileEntitySpecialRenderer cachedOverlays.put(side, map); } - display.display = GLAllocation.generateDisplayLists(1); - GL11.glNewList(display.display, 4864); - switch(side) { case DOWN: @@ -305,7 +301,7 @@ public class RenderLogisticalTransporter extends TileEntitySpecialRenderer } MekanismRenderer.renderObject(toReturn); - GL11.glEndList(); + display.endList(); return display; } diff --git a/common/mekanism/client/render/tileentity/RenderMechanicalPipe.java b/common/mekanism/client/render/tileentity/RenderMechanicalPipe.java index 5cf195f8e..7115d658f 100644 --- a/common/mekanism/client/render/tileentity/RenderMechanicalPipe.java +++ b/common/mekanism/client/render/tileentity/RenderMechanicalPipe.java @@ -249,7 +249,7 @@ public class RenderMechanicalPipe extends TileEntitySpecialRenderer } MekanismRenderer.renderObject(toReturn); - DisplayInteger.endList(); + displays[i].endList(); } GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); diff --git a/common/mekanism/client/render/tileentity/RenderPressurizedTube.java b/common/mekanism/client/render/tileentity/RenderPressurizedTube.java index 1d06910b4..214cb75f5 100644 --- a/common/mekanism/client/render/tileentity/RenderPressurizedTube.java +++ b/common/mekanism/client/render/tileentity/RenderPressurizedTube.java @@ -300,7 +300,7 @@ public class RenderPressurizedTube extends TileEntitySpecialRenderer } MekanismRenderer.renderObject(toReturn); - DisplayInteger.endList(); + display.endList(); return display; } diff --git a/common/mekanism/client/render/tileentity/RenderTeleporter.java b/common/mekanism/client/render/tileentity/RenderTeleporter.java new file mode 100644 index 000000000..5ebb493a4 --- /dev/null +++ b/common/mekanism/client/render/tileentity/RenderTeleporter.java @@ -0,0 +1,127 @@ +package mekanism.client.render.tileentity; + +import java.util.HashMap; + +import mekanism.api.EnumColor; +import mekanism.api.Object3D; +import mekanism.api.gas.GasRegistry; +import mekanism.client.render.MekanismRenderer; +import mekanism.client.render.MekanismRenderer.DisplayInteger; +import mekanism.client.render.MekanismRenderer.Model3D; +import mekanism.common.Mekanism; +import mekanism.common.tileentity.TileEntityTeleporter; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.ForgeDirection; + +import org.lwjgl.opengl.GL11; + +public class RenderTeleporter extends TileEntitySpecialRenderer +{ + private HashMap cachedOverlays = new HashMap(); + + @Override + public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float partialTick) + { + renderAModelAt((TileEntityTeleporter)tileEntity, x, y, z, partialTick); + } + + public void renderAModelAt(TileEntityTeleporter tileEntity, double x, double y, double z, float partialTick) + { + if(tileEntity.shouldRender) + { + push(); + + GL11.glColor4f(EnumColor.PURPLE.getColor(0), EnumColor.PURPLE.getColor(1), EnumColor.PURPLE.getColor(2), 0.75F); + + bindTexture(MekanismRenderer.getBlocksTexture()); + GL11.glTranslatef((float)x, (float)y, (float)z); + + Object3D obj = Object3D.get(tileEntity).getFromSide(ForgeDirection.WEST); + int type = 0; + + if(obj.getBlockId(tileEntity.worldObj) == Mekanism.basicBlockID && obj.getMetadata(tileEntity.worldObj) == 7) + { + type = 1; + } + + int display = getOverlayDisplay(type).display; + GL11.glCallList(display); + + pop(); + } + } + + private void pop() + { + GL11.glPopAttrib(); + MekanismRenderer.glowOff(); + MekanismRenderer.blendOff(); + GL11.glPopMatrix(); + } + + private void push() + { + GL11.glPushMatrix(); + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_LIGHTING); + MekanismRenderer.glowOn(); + MekanismRenderer.blendOn(); + } + + private DisplayInteger getOverlayDisplay(Integer type) + { + if(cachedOverlays.containsKey(type)) + { + return cachedOverlays.get(type); + } + + Model3D toReturn = new Model3D(); + toReturn.baseBlock = Block.stone; + toReturn.setTexture(GasRegistry.getGas("oxygen").getIcon()); + + DisplayInteger display = DisplayInteger.createAndStart(); + + if(cachedOverlays.containsKey(type)) + { + cachedOverlays.get(type); + } + else { + cachedOverlays.put(type, display); + } + + switch(type) + { + case 0: + { + toReturn.minY = 1; + toReturn.maxY = 3; + + toReturn.minX = 0.46; + toReturn.minZ = 0; + toReturn.maxX = 0.54; + toReturn.maxZ = 1; + break; + } + case 1: + { + toReturn.minY = 1; + toReturn.maxY = 3; + + toReturn.minX = 0; + toReturn.minZ = 0.46; + toReturn.maxX = 1; + toReturn.maxZ = 0.54; + break; + } + } + + MekanismRenderer.renderObject(toReturn); + display.endList(); + + return display; + } +} diff --git a/common/mekanism/client/sound/GasMaskSound.java b/common/mekanism/client/sound/GasMaskSound.java index 92bbc9944..fad189952 100644 --- a/common/mekanism/client/sound/GasMaskSound.java +++ b/common/mekanism/client/sound/GasMaskSound.java @@ -19,6 +19,10 @@ public class GasMaskSound extends PlayerSound { return false; } + else if(player.worldObj != world) + { + return false; + } else if(!world.loadedEntityList.contains(player)) { return false; diff --git a/common/mekanism/client/sound/JetpackSound.java b/common/mekanism/client/sound/JetpackSound.java index d4dadf9d2..1aa7454e6 100644 --- a/common/mekanism/client/sound/JetpackSound.java +++ b/common/mekanism/client/sound/JetpackSound.java @@ -20,6 +20,10 @@ public class JetpackSound extends PlayerSound { return false; } + else if(player.worldObj != world) + { + return false; + } else if(!world.loadedEntityList.contains(player)) { return false; diff --git a/common/mekanism/client/sound/PlayerSound.java b/common/mekanism/client/sound/PlayerSound.java index 371cb53ad..99dd0b0e8 100644 --- a/common/mekanism/client/sound/PlayerSound.java +++ b/common/mekanism/client/sound/PlayerSound.java @@ -1,9 +1,6 @@ package mekanism.client.sound; -import mekanism.client.ClientPlayerTickHandler; -import mekanism.common.item.ItemJetpack; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.world.World; import universalelectricity.core.vector.Vector3; public abstract class PlayerSound extends Sound @@ -39,7 +36,4 @@ public abstract class PlayerSound extends Sound ticksSincePlay = 0; } - - @Override - public abstract boolean update(World world); } diff --git a/common/mekanism/common/CommonPlayerTracker.java b/common/mekanism/common/CommonPlayerTracker.java index 675251a5d..376c64994 100644 --- a/common/mekanism/common/CommonPlayerTracker.java +++ b/common/mekanism/common/CommonPlayerTracker.java @@ -14,7 +14,10 @@ public class CommonPlayerTracker implements IPlayerTracker } @Override - public void onPlayerChangedDimension(EntityPlayer player) {} + public void onPlayerChangedDimension(EntityPlayer player) + { + Mekanism.jetpackOn.remove(player); + } @Override public void onPlayerRespawn(EntityPlayer player) {} diff --git a/common/mekanism/common/CommonProxy.java b/common/mekanism/common/CommonProxy.java index 250c91c22..3755adfa5 100644 --- a/common/mekanism/common/CommonProxy.java +++ b/common/mekanism/common/CommonProxy.java @@ -100,6 +100,7 @@ public class CommonProxy GameRegistry.registerTileEntity(TileEntityDigitalMiner.class, "DigitalMiner"); GameRegistry.registerTileEntity(TileEntityObsidianTNT.class, "ObsidianTNT"); GameRegistry.registerTileEntity(TileEntityRotaryCondensentrator.class, "RotaryCondensentrator"); + GameRegistry.registerTileEntity(TileEntityTeleporter.class, "Teleporter"); } /** diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index 63a3e91de..6aee6e931 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -1084,7 +1084,6 @@ public class Mekanism //Tile entities GameRegistry.registerTileEntity(TileEntityBoundingBlock.class, "BoundingBlock"); GameRegistry.registerTileEntity(TileEntityAdvancedBoundingBlock.class, "AdvancedBoundingBlock"); - GameRegistry.registerTileEntity(TileEntityTeleporter.class, "MekanismTeleporter"); //Load tile entities that have special renderers. proxy.registerSpecialTileEntities(); diff --git a/common/mekanism/common/block/BlockMachine.java b/common/mekanism/common/block/BlockMachine.java index 2ffbe2260..33ba6f840 100644 --- a/common/mekanism/common/block/BlockMachine.java +++ b/common/mekanism/common/block/BlockMachine.java @@ -627,23 +627,7 @@ public class BlockMachine extends BlockContainer implements ISpecialBounds if(tileEntity != null) { - if(metadata == MachineType.TELEPORTER.meta) - { - if(entityplayer.isSneaking()) - { - entityplayer.openGui(Mekanism.instance, 13, world, x, y, z); - return true; - } - - TileEntityTeleporter teleporter = (TileEntityTeleporter)tileEntity; - - if(teleporter.canTeleport() == 1) - { - teleporter.teleport(); - return true; - } - } - else if(metadata == MachineType.ELECTRIC_CHEST.meta) + if(metadata == MachineType.ELECTRIC_CHEST.meta) { TileEntityElectricChest electricChest = (TileEntityElectricChest)tileEntity; diff --git a/common/mekanism/common/network/PacketPortableTeleport.java b/common/mekanism/common/network/PacketPortableTeleport.java index 90adea549..7babc2612 100644 --- a/common/mekanism/common/network/PacketPortableTeleport.java +++ b/common/mekanism/common/network/PacketPortableTeleport.java @@ -7,6 +7,7 @@ import mekanism.common.PacketHandler; import mekanism.common.Teleporter; import mekanism.common.PacketHandler.Transmission; import mekanism.common.item.ItemPortableTeleporter; +import mekanism.common.tileentity.TileEntityTeleporter; import mekanism.common.util.MekanismUtils; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -15,6 +16,8 @@ import net.minecraft.world.World; import com.google.common.io.ByteArrayDataInput; +import cpw.mods.fml.common.FMLCommonHandler; + public class PacketPortableTeleport implements IMekanismPacket { @Override @@ -49,6 +52,11 @@ public class PacketPortableTeleport implements IMekanismPacket ((EntityPlayerMP)player).travelToDimension(coords.dimensionId); } + World teleWorld = FMLCommonHandler.instance().getMinecraftServerInstance().worldServerForDimension(coords.dimensionId); + TileEntityTeleporter teleporter = (TileEntityTeleporter)coords.getTileEntity(teleWorld); + + teleporter.didTeleport.add(player); + teleporter.teleDelay = 5; ((EntityPlayerMP)player).playerNetServerHandler.setPlayerLocation(coords.xCoord+0.5, coords.yCoord+1, coords.zCoord+0.5, player.rotationYaw, player.rotationPitch); world.playSoundAtEntity(player, "mob.endermen.portal", 1.0F, 1.0F); diff --git a/common/mekanism/common/tileentity/TileEntityTeleporter.java b/common/mekanism/common/tileentity/TileEntityTeleporter.java index 6b9ebef0c..2898cfedc 100644 --- a/common/mekanism/common/tileentity/TileEntityTeleporter.java +++ b/common/mekanism/common/tileentity/TileEntityTeleporter.java @@ -1,7 +1,9 @@ package mekanism.common.tileentity; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import mekanism.api.EnumColor; import mekanism.api.Object3D; @@ -11,18 +13,22 @@ import mekanism.common.PacketHandler.Transmission; import mekanism.common.Teleporter; import mekanism.common.block.BlockMachine.MachineType; import mekanism.common.network.PacketPortalFX; +import mekanism.common.network.PacketTileEntity; import mekanism.common.util.ChargeUtils; import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; +import net.minecraft.network.packet.Packet34EntityTeleport; import net.minecraft.util.AxisAlignedBB; -import net.minecraftforge.common.ForgeDirection; +import net.minecraft.world.World; import com.google.common.io.ByteArrayDataInput; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.network.PacketDispatcher; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import dan200.computer.api.IComputerAccess; import dan200.computer.api.ILuaContext; import dan200.computer.api.IPeripheral; @@ -32,6 +38,16 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe /** This teleporter's frequency. */ public Teleporter.Code code; + public AxisAlignedBB teleportBounds = null; + + public Set didTeleport = new HashSet(); + + public int teleDelay = 0; + + public boolean shouldRender; + + public boolean prevShouldRender; + /** This teleporter's current status. */ public String status = (EnumColor.DARK_RED + "Not ready."); @@ -47,8 +63,13 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe { super.onUpdate(); - if(!worldObj.isRemote) + if(teleportBounds == null) { + resetBounds(); + } + + if(!worldObj.isRemote) + { if(Mekanism.teleporters.containsKey(code)) { if(!Mekanism.teleporters.get(code).contains(Object3D.get(this)) && hasFrame()) @@ -88,11 +109,47 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe status = EnumColor.DARK_GREEN + "Idle."; break; } + + if(canTeleport() == 1 && teleDelay == 0) + { + teleport(); + } + + if(teleDelay == 0 && didTeleport.size() > 0) + { + cleanTeleportCache(); + } + + byte b = canTeleport(); + shouldRender = b == 1 || b > 4; + + if(shouldRender != prevShouldRender) + { + PacketHandler.sendPacket(Transmission.CLIENTS_RANGE, new PacketTileEntity().setParams(Object3D.get(this), getNetworkedData(new ArrayList())), Object3D.get(this), 40D); + } + + prevShouldRender = shouldRender; + + teleDelay = Math.max(0, teleDelay-1); } ChargeUtils.discharge(0, this); } + public void cleanTeleportCache() + { + List list = worldObj.getEntitiesWithinAABB(Entity.class, teleportBounds); + Set teleportCopy = (Set)((HashSet)didTeleport).clone(); + + for(Entity entity : teleportCopy) + { + if(!list.contains(entity)) + { + didTeleport.remove(entity); + } + } + } + @Override public int[] getAccessibleSlotsFromSide(int side) { @@ -110,6 +167,11 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe return true; } + public void resetBounds() + { + teleportBounds = AxisAlignedBB.getBoundingBox(xCoord, yCoord, zCoord, xCoord+1, yCoord+3, zCoord+1); + } + /** * 1: yes * 2: no frame @@ -138,7 +200,7 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe if(Mekanism.teleporters.get(code).size() == 2) { - List entitiesInPortal = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(xCoord-1, yCoord, zCoord-1, xCoord+1, yCoord+3, zCoord+1)); + List entitiesInPortal = getToTeleport(); Object3D closestCoords = null; @@ -153,7 +215,7 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe int electricityNeeded = 0; - for(EntityPlayer entity : entitiesInPortal) + for(Entity entity : entitiesInPortal) { electricityNeeded += calculateEnergyCost(entity, closestCoords); } @@ -178,7 +240,7 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe { if(worldObj.isRemote) return; - List entitiesInPortal = worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox(xCoord-1, yCoord, zCoord-1, xCoord+1, yCoord+3, zCoord+1)); + List entitiesInPortal = getToTeleport(); Object3D closestCoords = null; @@ -191,26 +253,58 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe } } - for(EntityPlayer entity : entitiesInPortal) - { - setEnergy(getEnergy() - calculateEnergyCost(entity, closestCoords)); + for(Entity entity : entitiesInPortal) + { + World teleWorld = FMLCommonHandler.instance().getMinecraftServerInstance().worldServerForDimension(closestCoords.dimensionId); + TileEntityTeleporter teleporter = (TileEntityTeleporter)closestCoords.getTileEntity(teleWorld); - worldObj.playSoundAtEntity((EntityPlayerMP)entity, "mob.endermen.portal", 1.0F, 1.0F); - - if(entity.worldObj.provider.dimensionId != closestCoords.dimensionId) + if(teleporter != null) { - entity.travelToDimension(closestCoords.dimensionId); - } - - ((EntityPlayerMP)entity).playerNetServerHandler.setPlayerLocation(closestCoords.xCoord+0.5, closestCoords.yCoord+1, closestCoords.zCoord+0.5, entity.rotationYaw, entity.rotationPitch); - - for(Object3D coords : Mekanism.teleporters.get(code)) - { - PacketHandler.sendPacket(Transmission.CLIENTS_RANGE, new PacketPortalFX().setParams(coords), coords, 40D); + teleporter.didTeleport.add(entity); + teleporter.teleDelay = 5; + + if(entity.worldObj.provider.dimensionId != closestCoords.dimensionId) + { + entity.travelToDimension(closestCoords.dimensionId); + } + + if(entity instanceof EntityPlayerMP) + { + ((EntityPlayerMP)entity).playerNetServerHandler.setPlayerLocation(closestCoords.xCoord+0.5, closestCoords.yCoord+1, closestCoords.zCoord+0.5, entity.rotationYaw, entity.rotationPitch); + } + else { + entity.setLocationAndAngles(closestCoords.xCoord+0.5, closestCoords.yCoord+1, closestCoords.zCoord+0.5, entity.rotationYaw, entity.rotationPitch); + PacketDispatcher.sendPacketToAllPlayers(new Packet34EntityTeleport(entity)); + } + + for(Object3D coords : Mekanism.teleporters.get(code)) + { + PacketHandler.sendPacket(Transmission.CLIENTS_RANGE, new PacketPortalFX().setParams(coords), coords, 40D); + } + + setEnergy(getEnergy() - calculateEnergyCost(entity, closestCoords)); + + worldObj.playSoundAtEntity(entity, "mob.endermen.portal", 1.0F, 1.0F); } } } + public List getToTeleport() + { + List entities = worldObj.getEntitiesWithinAABB(Entity.class, teleportBounds); + List ret = new ArrayList(); + + for(Entity entity : entities) + { + if(!didTeleport.contains(entity)) + { + ret.add(entity); + } + } + + return ret; + } + @Override public void invalidate() { @@ -333,6 +427,7 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe code.digitTwo = dataStream.readInt(); code.digitThree = dataStream.readInt(); code.digitFour = dataStream.readInt(); + shouldRender = dataStream.readBoolean(); } @Override @@ -345,6 +440,7 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe data.add(code.digitTwo); data.add(code.digitThree); data.add(code.digitFour); + data.add(shouldRender); return data; } @@ -420,10 +516,17 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe { return true; } - + @Override public void attach(IComputerAccess computer) {} @Override public void detach(IComputerAccess computer) {} + + @Override + @SideOnly(Side.CLIENT) + public AxisAlignedBB getRenderBoundingBox() + { + return INFINITE_EXTENT_AABB; + } } From 5d742ce200d85c4a5f9c97c27c21f2e560d078f6 Mon Sep 17 00:00:00 2001 From: "Aidan C. Brady" Date: Sat, 7 Dec 2013 23:02:25 -0500 Subject: [PATCH 07/40] Teleporters are actually worth it now. --- .../tileentity/TileEntityTeleporter.java | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/common/mekanism/common/tileentity/TileEntityTeleporter.java b/common/mekanism/common/tileentity/TileEntityTeleporter.java index 2898cfedc..b17449f5d 100644 --- a/common/mekanism/common/tileentity/TileEntityTeleporter.java +++ b/common/mekanism/common/tileentity/TileEntityTeleporter.java @@ -16,17 +16,18 @@ import mekanism.common.network.PacketPortalFX; import mekanism.common.network.PacketTileEntity; import mekanism.common.util.ChargeUtils; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.packet.Packet34EntityTeleport; +import net.minecraft.server.MinecraftServer; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; import com.google.common.io.ByteArrayDataInput; import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.network.PacketDispatcher; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import dan200.computer.api.IComputerAccess; @@ -263,18 +264,17 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe teleporter.didTeleport.add(entity); teleporter.teleDelay = 5; - if(entity.worldObj.provider.dimensionId != closestCoords.dimensionId) - { - entity.travelToDimension(closestCoords.dimensionId); - } - if(entity instanceof EntityPlayerMP) { + if(entity.worldObj.provider.dimensionId != closestCoords.dimensionId) + { + entity.travelToDimension(closestCoords.dimensionId); + } + ((EntityPlayerMP)entity).playerNetServerHandler.setPlayerLocation(closestCoords.xCoord+0.5, closestCoords.yCoord+1, closestCoords.zCoord+0.5, entity.rotationYaw, entity.rotationPitch); } else { - entity.setLocationAndAngles(closestCoords.xCoord+0.5, closestCoords.yCoord+1, closestCoords.zCoord+0.5, entity.rotationYaw, entity.rotationPitch); - PacketDispatcher.sendPacketToAllPlayers(new Packet34EntityTeleport(entity)); + teleportEntityTo(entity, closestCoords, teleporter); } for(Object3D coords : Mekanism.teleporters.get(code)) @@ -289,6 +289,35 @@ public class TileEntityTeleporter extends TileEntityElectricBlock implements IPe } } + public void teleportEntityTo(Entity entity, Object3D coord, TileEntityTeleporter teleporter) + { + MinecraftServer server = MinecraftServer.getServer(); + WorldServer world = server.worldServerForDimension(coord.dimensionId); + + if(entity.worldObj.provider.dimensionId != coord.dimensionId) + { + entity.worldObj.removeEntity(entity); + entity.isDead = false; + + world.spawnEntityInWorld(entity); + entity.setLocationAndAngles(coord.xCoord+0.5, coord.yCoord+1, coord.zCoord+0.5, entity.rotationYaw, entity.rotationPitch); + world.updateEntityWithOptionalForce(entity, false); + entity.setWorld(world); + world.resetUpdateEntityTick(); + + Entity e = EntityList.createEntityByName(EntityList.getEntityString(entity), world); + + if(e != null) + { + e.copyDataFrom(entity, true); + world.spawnEntityInWorld(e); + teleporter.didTeleport.add(e); + } + + entity.isDead = true; + } + } + public List getToTeleport() { List entities = worldObj.getEntitiesWithinAABB(Entity.class, teleportBounds); From 314f4b308291d7dec9d35e67ebd4da7e0189762e Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sat, 7 Dec 2013 23:28:13 -0500 Subject: [PATCH 08/40] A few rendering fixes, fixed VoiceServer hanging --- .../client/ClientConnectionHandler.java | 4 +-- .../render/tileentity/RenderDynamicTank.java | 27 ++++++++----------- .../client/render/RenderBioGenerator.java | 2 +- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/common/mekanism/client/ClientConnectionHandler.java b/common/mekanism/client/ClientConnectionHandler.java index 88bf7f878..36eb12f1c 100644 --- a/common/mekanism/client/ClientConnectionHandler.java +++ b/common/mekanism/client/ClientConnectionHandler.java @@ -36,7 +36,7 @@ public class ClientConnectionHandler implements IConnectionHandler { try { voiceClient = new VoiceClient(server, Mekanism.VOICE_PORT); - voiceClient.run(); + voiceClient.start(); } catch(Exception e) {} } } @@ -49,7 +49,7 @@ public class ClientConnectionHandler implements IConnectionHandler { try { voiceClient = new VoiceClient(InetAddress.getLocalHost().getHostAddress(), Mekanism.VOICE_PORT); - voiceClient.run(); + voiceClient.start(); } catch(Exception e) {} } } diff --git a/common/mekanism/client/render/tileentity/RenderDynamicTank.java b/common/mekanism/client/render/tileentity/RenderDynamicTank.java index fb020e04f..40162766a 100644 --- a/common/mekanism/client/render/tileentity/RenderDynamicTank.java +++ b/common/mekanism/client/render/tileentity/RenderDynamicTank.java @@ -27,7 +27,7 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) public class RenderDynamicTank extends TileEntitySpecialRenderer { - private static Map> cachedCenterFluids = new HashMap>(); + private static Map> cachedCenterFluids = new HashMap>(); private static Map> cachedValveFluids = new HashMap>(); @Override @@ -57,15 +57,15 @@ public class RenderDynamicTank extends TileEntitySpecialRenderer MekanismRenderer.glowOn(tileEntity.structure.fluidStored.getFluid().getLuminosity()); - int[] displayList = getListAndRender(data, tileEntity.structure.fluidStored.getFluid(), tileEntity.worldObj); + DisplayInteger[] displayList = getListAndRender(data, tileEntity.structure.fluidStored.getFluid(), tileEntity.worldObj); if(tileEntity.structure.fluidStored.getFluid().isGaseous()) { GL11.glColor4f(1F, 1F, 1F, Math.min(1, ((float)tileEntity.structure.fluidStored.amount / (float)tileEntity.clientCapacity)+0.3F)); - GL11.glCallList(displayList[getStages(data.height)-1]); + displayList[getStages(data.height)-1].render(); } else { - GL11.glCallList(displayList[(int)(((float)tileEntity.structure.fluidStored.amount/(float)tileEntity.clientCapacity)*((float)getStages(data.height)-1))]); + displayList[(int)(((float)tileEntity.structure.fluidStored.amount/(float)tileEntity.clientCapacity)*((float)getStages(data.height)-1))].render(); } MekanismRenderer.glowOff(); @@ -82,8 +82,7 @@ public class RenderDynamicTank extends TileEntitySpecialRenderer MekanismRenderer.glowOn(tileEntity.structure.fluidStored.getFluid().getLuminosity()); - int display = getValveDisplay(ValveRenderData.get(data, valveData), tileEntity.structure.fluidStored.getFluid(), tileEntity.worldObj).display; - GL11.glCallList(display); + getValveDisplay(ValveRenderData.get(data, valveData), tileEntity.structure.fluidStored.getFluid(), tileEntity.worldObj).render(); MekanismRenderer.glowOff(); @@ -110,7 +109,7 @@ public class RenderDynamicTank extends TileEntitySpecialRenderer GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); } - private int[] getListAndRender(RenderData data, Fluid fluid, World world) + private DisplayInteger[] getListAndRender(RenderData data, Fluid fluid, World world) { if(cachedCenterFluids.containsKey(data) && cachedCenterFluids.get(data).containsKey(fluid)) { @@ -122,14 +121,14 @@ public class RenderDynamicTank extends TileEntitySpecialRenderer toReturn.setTexture(fluid.getIcon()); final int stages = getStages(data.height); - int[] displays = new int[stages]; + DisplayInteger[] displays = new DisplayInteger[stages]; if(cachedCenterFluids.containsKey(data)) { cachedCenterFluids.get(data).put(fluid, displays); } else { - HashMap map = new HashMap(); + HashMap map = new HashMap(); map.put(fluid, displays); cachedCenterFluids.put(data, map); } @@ -138,8 +137,7 @@ public class RenderDynamicTank extends TileEntitySpecialRenderer for(int i = 0; i < stages; i++) { - displays[i] = GLAllocation.generateDisplayLists(1); - GL11.glNewList(displays[i], 4864); + displays[i] = DisplayInteger.createAndStart(); toReturn.minX = 0 + .01; toReturn.minY = 0 + .01; @@ -169,7 +167,7 @@ public class RenderDynamicTank extends TileEntitySpecialRenderer toReturn.baseBlock = Block.waterStill; toReturn.setTexture(fluid.getFlowingIcon()); - DisplayInteger display = new DisplayInteger(); + DisplayInteger display = DisplayInteger.createAndStart(); if(cachedValveFluids.containsKey(data)) { @@ -183,9 +181,6 @@ public class RenderDynamicTank extends TileEntitySpecialRenderer MekanismRenderer.colorFluid(fluid); - display.display = GLAllocation.generateDisplayLists(1); - GL11.glNewList(display.display, 4864); - switch(data.side) { case DOWN: @@ -261,7 +256,7 @@ public class RenderDynamicTank extends TileEntitySpecialRenderer } MekanismRenderer.renderObject(toReturn); - GL11.glEndList(); + display.endList(); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); diff --git a/common/mekanism/generators/client/render/RenderBioGenerator.java b/common/mekanism/generators/client/render/RenderBioGenerator.java index 9982bbf37..5ef8a4aa4 100644 --- a/common/mekanism/generators/client/render/RenderBioGenerator.java +++ b/common/mekanism/generators/client/render/RenderBioGenerator.java @@ -137,7 +137,7 @@ public class RenderBioGenerator extends TileEntitySpecialRenderer } MekanismRenderer.renderObject(model3D); - DisplayInteger.endList(); + displays[i].endList(); } energyDisplays.put(side, displays); From 62bc5c267a13111cfb574279206478864ba5d215 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sat, 7 Dec 2013 23:51:07 -0500 Subject: [PATCH 09/40] Fixed weird jetpack particles --- .../client/render/RenderTickHandler.java | 34 +++++++++++++++---- .../mekanism/client/sound/GasMaskSound.java | 10 +----- .../mekanism/client/sound/JetpackSound.java | 10 +----- common/mekanism/client/sound/PlayerSound.java | 20 +++++++++++ 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/common/mekanism/client/render/RenderTickHandler.java b/common/mekanism/client/render/RenderTickHandler.java index f23d28d2e..9a06f33f4 100644 --- a/common/mekanism/client/render/RenderTickHandler.java +++ b/common/mekanism/client/render/RenderTickHandler.java @@ -9,6 +9,9 @@ import mekanism.common.item.ItemJetpack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.particle.EntityFlameFX; +import net.minecraft.client.particle.EntitySmokeFX; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.MathHelper; @@ -25,6 +28,7 @@ import cpw.mods.fml.relauncher.SideOnly; public class RenderTickHandler implements ITickHandler { public Random rand = new Random(); + public Minecraft mc = Minecraft.getMinecraft(); @Override public void tickStart(EnumSet type, Object... tickData) {} @@ -33,7 +37,6 @@ public class RenderTickHandler implements ITickHandler public void tickEnd(EnumSet type, Object... tickData) { float partialTick = (Float)tickData[0]; - Minecraft mc = FMLClientHandler.instance().getClient(); if(mc.thePlayer != null && mc.theWorld != null) { @@ -125,19 +128,36 @@ public class RenderTickHandler implements ITickHandler mRight.translate(rRight); Vector3 v = new Vector3(p).translate(vLeft); - world.spawnParticle("flame", v.x, v.y, v.z, mLeft.x, mLeft.y, mLeft.z); - world.spawnParticle("smoke", v.x, v.y, v.z, mLeft.x, mLeft.y, mLeft.z); + spawnAndSetParticle("flame", world, v.x, v.y, v.z, mLeft.x, mLeft.y, mLeft.z); + spawnAndSetParticle("smoke", world, v.x, v.y, v.z, mLeft.x, mLeft.y, mLeft.z); v = new Vector3(p).translate(vRight); - world.spawnParticle("flame", v.x, v.y, v.z, mRight.x, mRight.y, mRight.z); - world.spawnParticle("smoke", v.x, v.y, v.z, mRight.x, mRight.y, mRight.z); + spawnAndSetParticle("flame", world, v.x, v.y, v.z, mRight.x, mRight.y, mRight.z); + spawnAndSetParticle("smoke", world, v.x, v.y, v.z, mRight.x, mRight.y, mRight.z); v = new Vector3(p).translate(vCenter); - world.spawnParticle("flame", v.x, v.y, v.z, mCenter.x, mCenter.y, mCenter.z); - world.spawnParticle("smoke", v.x, v.y, v.z, mCenter.x, mCenter.y, mCenter.z); + spawnAndSetParticle("flame", world, v.x, v.y, v.z, mCenter.x, mCenter.y, mCenter.z); + spawnAndSetParticle("smoke", world, v.x, v.y, v.z, mCenter.x, mCenter.y, mCenter.z); } } } + + public void spawnAndSetParticle(String s, World world, double x, double y, double z, double velX, double velY, double velZ) + { + EntityFX fx = null; + + if(s.equals("flame")) + { + fx = new EntityFlameFX(world, x, y, z, velX, velY, velZ); + } + else if(s.equals("smoke")) + { + fx = new EntitySmokeFX(world, x, y, z, velX, velY, velZ); + } + + mc.effectRenderer.addEffect(fx); + fx.onUpdate(); + } @Override public EnumSet ticks() diff --git a/common/mekanism/client/sound/GasMaskSound.java b/common/mekanism/client/sound/GasMaskSound.java index fad189952..a06df019c 100644 --- a/common/mekanism/client/sound/GasMaskSound.java +++ b/common/mekanism/client/sound/GasMaskSound.java @@ -15,15 +15,7 @@ public class GasMaskSound extends PlayerSound @Override public boolean update(World world) { - if(player.isDead) - { - return false; - } - else if(player.worldObj != world) - { - return false; - } - else if(!world.loadedEntityList.contains(player)) + if(!super.update(world)) { return false; } diff --git a/common/mekanism/client/sound/JetpackSound.java b/common/mekanism/client/sound/JetpackSound.java index 1aa7454e6..5dd369874 100644 --- a/common/mekanism/client/sound/JetpackSound.java +++ b/common/mekanism/client/sound/JetpackSound.java @@ -16,15 +16,7 @@ public class JetpackSound extends PlayerSound @Override public boolean update(World world) { - if(player.isDead) - { - return false; - } - else if(player.worldObj != world) - { - return false; - } - else if(!world.loadedEntityList.contains(player)) + if(!super.update(world)) { return false; } diff --git a/common/mekanism/client/sound/PlayerSound.java b/common/mekanism/client/sound/PlayerSound.java index 99dd0b0e8..ce8dd40e2 100644 --- a/common/mekanism/client/sound/PlayerSound.java +++ b/common/mekanism/client/sound/PlayerSound.java @@ -1,6 +1,7 @@ package mekanism.client.sound; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; import universalelectricity.core.vector.Vector3; public abstract class PlayerSound extends Sound @@ -23,6 +24,25 @@ public abstract class PlayerSound extends Sound return Math.min(1, ((float)ticksSincePlay/20F))*0.3F; } + @Override + public boolean update(World world) + { + if(player.isDead) + { + return false; + } + else if(player.worldObj != world) + { + return false; + } + else if(!world.loadedEntityList.contains(player)) + { + return false; + } + + return true; + } + @Override public Vector3 getLocation() { From 97bf92375a8eed8f6b529eab8baa28e4900e4091 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sun, 8 Dec 2013 00:43:20 -0500 Subject: [PATCH 10/40] Add class enumerator for future class stuff --- .../common/classloading/ClassEnumerator.java | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 common/mekanism/common/classloading/ClassEnumerator.java diff --git a/common/mekanism/common/classloading/ClassEnumerator.java b/common/mekanism/common/classloading/ClassEnumerator.java new file mode 100644 index 000000000..6cc2143be --- /dev/null +++ b/common/mekanism/common/classloading/ClassEnumerator.java @@ -0,0 +1,115 @@ +package mekanism.common.classloading; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +public class ClassEnumerator +{ + private static Class loadClass(String className) + { + try { + return Class.forName(className); + } catch(ClassNotFoundException e) { + throw new RuntimeException("Unexpected ClassNotFoundException loading class '" + className + "'"); + } + } + + private static void processDir(File directory, String pkgname, ArrayList> classes) + { + String[] files = directory.list(); + + for(int i = 0; i < files.length; i++) + { + String fileName = files[i]; + String className = null; + + if(fileName.endsWith(".class")) + { + className = pkgname + '.' + fileName.substring(0, fileName.length() - 6); + } + + if(className != null) + { + classes.add(loadClass(className)); + } + + File subdir = new File(directory, fileName); + + if(subdir.isDirectory()) + { + processDir(subdir, pkgname + '.' + fileName, classes); + } + } + } + + private static void processJar(URL resource, String pkgname, ArrayList> classes) + { + String relPath = pkgname.replace('.', '/'); + String resPath = resource.getPath(); + String jarPath = resPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", ""); + + JarFile jarFile; + + try { + jarFile = new JarFile(jarPath); + } catch(IOException e) { + throw new RuntimeException("Unexpected IOException reading JAR File '" + jarPath + "'", e); + } + + Enumeration entries = jarFile.entries(); + + while(entries.hasMoreElements()) + { + JarEntry entry = entries.nextElement(); + String entryName = entry.getName(); + String className = null; + + if(entryName.endsWith(".class") && entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) + { + className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); + } + + if(className != null) + { + classes.add(loadClass(className)); + } + } + } + + public static ArrayList> getClassesForPackage(Package pkg) + { + ArrayList> classes = new ArrayList>(); + + try { + String pkgname = pkg.getName(); + String relPath = pkgname.replace('.', '/'); + + URL resource = ClassLoader.getSystemClassLoader().getResource(relPath); + + if(resource == null) + { + throw new RuntimeException("Unexpected problem: No resource for " + relPath); + } + + resource.getPath(); + + if(resource.toString().startsWith("jar:")) + { + processJar(resource, pkgname, classes); + } + else { + processDir(new File(resource.getPath()), pkgname, classes); + } + } catch(Exception e) { + System.err.println("[Mekanism] Error while loading classes in package " + pkg); + e.printStackTrace(); + } + + return classes; + } +} \ No newline at end of file From eb8e02a39a49c130c36d135794774a2fccbd98f1 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sun, 8 Dec 2013 12:39:26 -0500 Subject: [PATCH 11/40] Fix a few bugs! --- common/mekanism/common/CommonProxy.java | 2 +- common/mekanism/common/EnergyNetwork.java | 6 +-- .../common/item/ItemBlockGenerator.java | 1 - .../TileEntityElectrolyticSeparator.java | 46 +++++++++++-------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/common/mekanism/common/CommonProxy.java b/common/mekanism/common/CommonProxy.java index 3755adfa5..98e2ff217 100644 --- a/common/mekanism/common/CommonProxy.java +++ b/common/mekanism/common/CommonProxy.java @@ -100,7 +100,7 @@ public class CommonProxy GameRegistry.registerTileEntity(TileEntityDigitalMiner.class, "DigitalMiner"); GameRegistry.registerTileEntity(TileEntityObsidianTNT.class, "ObsidianTNT"); GameRegistry.registerTileEntity(TileEntityRotaryCondensentrator.class, "RotaryCondensentrator"); - GameRegistry.registerTileEntity(TileEntityTeleporter.class, "Teleporter"); + GameRegistry.registerTileEntity(TileEntityTeleporter.class, "MekanismTeleporter"); } /** diff --git a/common/mekanism/common/EnergyNetwork.java b/common/mekanism/common/EnergyNetwork.java index dbd7534c1..114df41d6 100644 --- a/common/mekanism/common/EnergyNetwork.java +++ b/common/mekanism/common/EnergyNetwork.java @@ -269,11 +269,7 @@ public class EnergyNetwork extends DynamicNetwork if(handler.canInterface(side.getOpposite())) { - if(handler.receiveEnergy(side.getOpposite(), 1, true) > 0) - { - toReturn.add(acceptor); - } - else if(handler.getMaxEnergyStored(side.getOpposite()) - handler.getEnergyStored(side.getOpposite()) > 0) + if(handler.getMaxEnergyStored(side.getOpposite()) - handler.getEnergyStored(side.getOpposite()) > 0) { toReturn.add(acceptor); } diff --git a/common/mekanism/generators/common/item/ItemBlockGenerator.java b/common/mekanism/generators/common/item/ItemBlockGenerator.java index c08528a0e..08753d0e5 100644 --- a/common/mekanism/generators/common/item/ItemBlockGenerator.java +++ b/common/mekanism/generators/common/item/ItemBlockGenerator.java @@ -84,7 +84,6 @@ public class ItemBlockGenerator extends ItemBlock implements IEnergizedItem, IIt } else { list.add(EnumColor.BRIGHT_GREEN + "Stored Energy: " + EnumColor.GREY + MekanismUtils.getEnergyDisplay(getEnergy(itemstack))); - list.add(EnumColor.BRIGHT_GREEN + "Voltage: " + EnumColor.GREY + (getVoltage(itemstack)*Mekanism.FROM_UE) + "v"); if(hasTank(itemstack)) { diff --git a/common/mekanism/generators/common/tileentity/TileEntityElectrolyticSeparator.java b/common/mekanism/generators/common/tileentity/TileEntityElectrolyticSeparator.java index ca7d37ea8..eba94dafe 100644 --- a/common/mekanism/generators/common/tileentity/TileEntityElectrolyticSeparator.java +++ b/common/mekanism/generators/common/tileentity/TileEntityElectrolyticSeparator.java @@ -151,10 +151,7 @@ public class TileEntityElectrolyticSeparator extends TileEntityElectricBlock imp if(worldObj.rand.nextInt(3) == 2) { - ArrayList data = new ArrayList(); - data.add(2); - - PacketHandler.sendPacket(Transmission.CLIENTS_RANGE, new PacketTileEntity().setParams(Object3D.get(this), data), Object3D.get(this), 40D); + PacketHandler.sendPacket(Transmission.CLIENTS_RANGE, new PacketTileEntity().setParams(Object3D.get(this), getParticlePacket(new ArrayList())), Object3D.get(this), 40D); } } } @@ -320,30 +317,35 @@ public class TileEntityElectrolyticSeparator extends TileEntityElectricBlock imp { dumpType = GasRegistry.getGas(dataStream.readInt()); } - else if(type == 2) - { - spawnParticle(); - } return; } super.handlePacketData(dataStream); - int amount = dataStream.readInt(); + int type = dataStream.readInt(); - if(amount != 0) + if(type == 0) { - waterTank.setFluid(new FluidStack(FluidRegistry.WATER, amount)); + int amount = dataStream.readInt(); + + if(amount != 0) + { + waterTank.setFluid(new FluidStack(FluidRegistry.WATER, amount)); + } + else { + waterTank.setFluid(null); + } + + oxygenStored = dataStream.readInt(); + hydrogenStored = dataStream.readInt(); + outputType = GasRegistry.getGas(dataStream.readInt()); + dumpType = GasRegistry.getGas(dataStream.readInt()); } - else { - waterTank.setFluid(null); + else if(type == 1) + { + spawnParticle(); } - - oxygenStored = dataStream.readInt(); - hydrogenStored = dataStream.readInt(); - outputType = GasRegistry.getGas(dataStream.readInt()); - dumpType = GasRegistry.getGas(dataStream.readInt()); } @Override @@ -351,6 +353,7 @@ public class TileEntityElectrolyticSeparator extends TileEntityElectricBlock imp { super.getNetworkedData(data); + data.add(0); if(waterTank.getFluid() != null) { data.add(waterTank.getFluid().amount); @@ -367,6 +370,13 @@ public class TileEntityElectrolyticSeparator extends TileEntityElectricBlock imp return data; } + public ArrayList getParticlePacket(ArrayList data) + { + super.getNetworkedData(data); + data.add(1); + return data; + } + @Override public void readFromNBT(NBTTagCompound nbtTags) { From 8289af18fd4ced8e75d237c06c16951faf2ff4b1 Mon Sep 17 00:00:00 2001 From: "Aidan C. Brady" Date: Sun, 8 Dec 2013 12:49:48 -0500 Subject: [PATCH 12/40] Add configurable sound volume for all Mekanism sounds --- common/mekanism/client/ClientProxy.java | 1 + common/mekanism/client/MekanismClient.java | 1 + common/mekanism/client/sound/Sound.java | 1 + 3 files changed, 3 insertions(+) diff --git a/common/mekanism/client/ClientProxy.java b/common/mekanism/client/ClientProxy.java index cf64434b3..62309c9ac 100644 --- a/common/mekanism/client/ClientProxy.java +++ b/common/mekanism/client/ClientProxy.java @@ -135,6 +135,7 @@ public class ClientProxy extends CommonProxy Mekanism.configuration.load(); MekanismClient.enableSounds = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "EnableSounds", true).getBoolean(true); MekanismClient.fancyUniversalCableRender = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "FancyUniversalCableRender", true).getBoolean(true); + MekanismClient.baseSoundVolume = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "baseSoundVolume", 1).getDouble(1); Mekanism.configuration.save(); } diff --git a/common/mekanism/client/MekanismClient.java b/common/mekanism/client/MekanismClient.java index dd14f94c7..8673bdbee 100644 --- a/common/mekanism/client/MekanismClient.java +++ b/common/mekanism/client/MekanismClient.java @@ -21,6 +21,7 @@ public class MekanismClient extends Mekanism //General Configuration public static boolean enableSounds = true; public static boolean fancyUniversalCableRender = true; + public static double baseSoundVolume = 1; public static long ticksPassed = 0; diff --git a/common/mekanism/client/sound/Sound.java b/common/mekanism/client/sound/Sound.java index f973a00a3..a806f0364 100644 --- a/common/mekanism/client/sound/Sound.java +++ b/common/mekanism/client/sound/Sound.java @@ -146,6 +146,7 @@ public abstract class Sound double distance = entityplayer.getDistance(getLocation().x, getLocation().y, getLocation().z); volume = (float)Math.min(Math.max(masterVolume-((distance*.08F)*masterVolume), 0)*multiplier, 1); + volume *= Math.max(0, Math.min(1, MekanismClient.baseSoundVolume)); if(SoundHandler.getSoundSystem() != null) { From ce629e218c3a609e2d6a452c355b3b17e5ff8e1a Mon Sep 17 00:00:00 2001 From: "Aidan C. Brady" Date: Sun, 8 Dec 2013 16:10:52 -0500 Subject: [PATCH 13/40] Fix IC2 charging --- common/mekanism/client/sound/Sound.java | 1 - common/mekanism/common/util/ChargeUtils.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/common/mekanism/client/sound/Sound.java b/common/mekanism/client/sound/Sound.java index a806f0364..a45a95641 100644 --- a/common/mekanism/client/sound/Sound.java +++ b/common/mekanism/client/sound/Sound.java @@ -3,7 +3,6 @@ package mekanism.client.sound; import java.net.URL; import mekanism.client.MekanismClient; -import mekanism.common.Mekanism; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; diff --git a/common/mekanism/common/util/ChargeUtils.java b/common/mekanism/common/util/ChargeUtils.java index 658d5c600..f63fac820 100644 --- a/common/mekanism/common/util/ChargeUtils.java +++ b/common/mekanism/common/util/ChargeUtils.java @@ -83,7 +83,7 @@ public final class ChargeUtils } else if(Mekanism.hooks.IC2Loaded && storer.inventory[slotID].getItem() instanceof IElectricItem) { - double sent = ElectricItem.manager.charge(storer.inventory[slotID], (int)(storer.getEnergy()*Mekanism.TO_IC2), 3, true, false)*Mekanism.FROM_IC2; + double sent = ElectricItem.manager.charge(storer.inventory[slotID], (int)(storer.getEnergy()*Mekanism.TO_IC2), 4, true, false)*Mekanism.FROM_IC2; storer.setEnergy(storer.getEnergy() - sent); } else if(storer.inventory[slotID].getItem() instanceof IEnergyContainerItem) From d2753abc9265fc06a3ccdd3f60f8f534d4d10a97 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sun, 8 Dec 2013 16:39:03 -0500 Subject: [PATCH 14/40] Fixed tiny factory sort issue --- common/mekanism/common/util/StackUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/mekanism/common/util/StackUtils.java b/common/mekanism/common/util/StackUtils.java index fa90c2d8b..7f9486bab 100644 --- a/common/mekanism/common/util/StackUtils.java +++ b/common/mekanism/common/util/StackUtils.java @@ -50,7 +50,7 @@ public final class StackUtils return false; } - return stack1.itemID != stack2.itemID; + return stack1.itemID != stack2.itemID || stack1.getItemDamage() != stack2.getItemDamage(); } public static boolean equalsWildcard(ItemStack wild, ItemStack check) From af1f32da8e093b59061b52cf281db78f2d663ea9 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sun, 8 Dec 2013 19:22:59 -0500 Subject: [PATCH 15/40] Fix double chest crash --- .../mekanism/common/util/InventoryUtils.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/common/mekanism/common/util/InventoryUtils.java b/common/mekanism/common/util/InventoryUtils.java index 308ca3755..e7331edbe 100644 --- a/common/mekanism/common/util/InventoryUtils.java +++ b/common/mekanism/common/util/InventoryUtils.java @@ -50,6 +50,8 @@ public final class InventoryUtils public static ItemStack putStackInInventory(IInventory inventory, ItemStack itemStack, int side, boolean force) { + inventory = checkChestInv(inventory); + if(force && inventory instanceof TileEntityLogisticalSorter) { return ((TileEntityLogisticalSorter)inventory).sendHome(itemStack.copy()); @@ -59,8 +61,6 @@ public final class InventoryUtils if(!(inventory instanceof ISidedInventory)) { - inventory = checkChestInv(inventory); - for(int i = 0; i <= inventory.getSizeInventory() - 1; i++) { if(!force) @@ -167,6 +167,8 @@ public final class InventoryUtils public static ItemStack takeTopItemFromInventory(IInventory inventory, int side) { + inventory = checkChestInv(inventory); + if(!(inventory instanceof ISidedInventory)) { for(int i = inventory.getSizeInventory() - 1; i >= 0; i--) @@ -213,12 +215,12 @@ public final class InventoryUtils public static InvStack takeDefinedItem(IInventory inventory, int side, ItemStack type, int min, int max) { + inventory = checkChestInv(inventory); + InvStack ret = new InvStack(inventory); if(!(inventory instanceof ISidedInventory)) - { - inventory = checkChestInv(inventory); - + { for(int i = inventory.getSizeInventory() - 1; i >= 0; i--) { if(inventory.getStackInSlot(i) != null && inventory.getStackInSlot(i).isItemEqual(type)) @@ -296,10 +298,10 @@ public final class InventoryUtils public static InvStack takeTopStack(IInventory inventory, int side) { + inventory = checkChestInv(inventory); + if(!(inventory instanceof ISidedInventory)) - { - inventory = checkChestInv(inventory); - + { for(int i = inventory.getSizeInventory() - 1; i >= 0; i--) { if(inventory.getStackInSlot(i) != null) @@ -359,12 +361,10 @@ public final class InventoryUtils } } - IInventory inventory = (IInventory)tileEntity; + IInventory inventory = checkChestInv((IInventory)tileEntity); if(!(inventory instanceof ISidedInventory)) - { - inventory = InventoryUtils.checkChestInv(inventory); - + { for(int i = 0; i <= inventory.getSizeInventory() - 1; i++) { if(!force) From 8b25c1acb331051824a645673a713a6f19d1465e Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sun, 8 Dec 2013 20:22:04 -0500 Subject: [PATCH 16/40] Attempt to fix a few jetpack bugs --- .../client/ClientPlayerTickHandler.java | 33 +++++++------------ common/mekanism/client/MekanismClient.java | 12 ++++--- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/common/mekanism/client/ClientPlayerTickHandler.java b/common/mekanism/client/ClientPlayerTickHandler.java index 96ac3b7a2..6bf1445bb 100644 --- a/common/mekanism/client/ClientPlayerTickHandler.java +++ b/common/mekanism/client/ClientPlayerTickHandler.java @@ -38,7 +38,7 @@ import cpw.mods.fml.relauncher.SideOnly; public class ClientPlayerTickHandler implements ITickHandler { public boolean lastTickUpdate = false; - public Minecraft mc = Minecraft.getMinecraft(); + public static Minecraft mc = Minecraft.getMinecraft(); @Override public void tickStart(EnumSet type, Object... tickData) {} @@ -134,7 +134,7 @@ public class ClientPlayerTickHandler implements ITickHandler if(Mekanism.jetpackOn.contains(entityPlayer) != isJetpackOn(entityPlayer)) { - if(isJetpackOn(entityPlayer) && mc.currentScreen == null) + if(isJetpackOn(entityPlayer)) { Mekanism.jetpackOn.add(entityPlayer); } @@ -142,10 +142,7 @@ public class ClientPlayerTickHandler implements ITickHandler Mekanism.jetpackOn.remove(entityPlayer); } - if(!isGasMaskOn(entityPlayer) || mc.currentScreen == null) - { - PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.UPDATE, entityPlayer, isJetpackOn(entityPlayer))); - } + PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.UPDATE, entityPlayer, isJetpackOn(entityPlayer))); } if(Mekanism.gasmaskOn.contains(entityPlayer) != isGasMaskOn(entityPlayer)) @@ -158,10 +155,7 @@ public class ClientPlayerTickHandler implements ITickHandler Mekanism.gasmaskOn.remove(entityPlayer); } - if(!isGasMaskOn(entityPlayer) || mc.currentScreen == null) - { - PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(PacketType.UPDATE, entityPlayer, isGasMaskOn(entityPlayer))); - } + PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(PacketType.UPDATE, entityPlayer, isGasMaskOn(entityPlayer))); } for(EntityPlayer entry : Mekanism.jetpackOn) @@ -180,27 +174,24 @@ public class ClientPlayerTickHandler implements ITickHandler } } - if(mc.currentScreen == null) + if(entityPlayer.getCurrentItemOrArmor(3) != null && entityPlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) { - if(entityPlayer.getCurrentItemOrArmor(3) != null && entityPlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) - { - MekanismClient.updateKey(entityPlayer, Keyboard.KEY_SPACE); - MekanismClient.updateKey(entityPlayer, Keyboard.KEY_LSHIFT); - } + MekanismClient.updateKey(Keyboard.KEY_SPACE); + MekanismClient.updateKey(Keyboard.KEY_LSHIFT); } if(isJetpackOn(entityPlayer)) { ItemJetpack jetpack = (ItemJetpack)entityPlayer.getCurrentItemOrArmor(3).getItem(); - if(jetpack.getMode(entityPlayer.getCurrentItemOrArmor(3)) == JetpackMode.NORMAL && mc.currentScreen == null) + if(jetpack.getMode(entityPlayer.getCurrentItemOrArmor(3)) == JetpackMode.NORMAL) { entityPlayer.motionY = Math.min(mc.thePlayer.motionY + 0.15D, 0.5D); entityPlayer.fallDistance = 0.0F; } else if(jetpack.getMode(entityPlayer.getCurrentItemOrArmor(3)) == JetpackMode.HOVER) { - if(((!Keyboard.isKeyDown(Keyboard.KEY_SPACE) && !Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) || (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && Keyboard.isKeyDown(Keyboard.KEY_LSHIFT))) || mc.currentScreen != null) + if((!Keyboard.isKeyDown(Keyboard.KEY_SPACE) && !Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) || (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) || mc.currentScreen != null) { if(entityPlayer.motionY > 0) { @@ -212,11 +203,11 @@ public class ClientPlayerTickHandler implements ITickHandler } } else { - if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)) + if(Keyboard.isKeyDown(Keyboard.KEY_SPACE) && mc.currentScreen == null) { entityPlayer.motionY = Math.min(mc.thePlayer.motionY + 0.15D, 0.2D); } - else if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) + else if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && mc.currentScreen == null) { entityPlayer.motionY = Math.max(mc.thePlayer.motionY - 0.15D, -0.2D); } @@ -251,7 +242,7 @@ public class ClientPlayerTickHandler implements ITickHandler if(jetpack.getGas(stack) != null) { - if((Keyboard.isKeyDown(Keyboard.KEY_SPACE) && jetpack.getMode(stack) == JetpackMode.NORMAL)) + if((Keyboard.isKeyDown(Keyboard.KEY_SPACE) && jetpack.getMode(stack) == JetpackMode.NORMAL) && mc.currentScreen == null) { return true; } diff --git a/common/mekanism/client/MekanismClient.java b/common/mekanism/client/MekanismClient.java index 8673bdbee..b2431b9a7 100644 --- a/common/mekanism/client/MekanismClient.java +++ b/common/mekanism/client/MekanismClient.java @@ -5,7 +5,7 @@ import mekanism.common.Mekanism; import mekanism.common.PacketHandler; import mekanism.common.PacketHandler.Transmission; import mekanism.common.network.PacketKey; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.client.Minecraft; import org.lwjgl.input.Keyboard; @@ -25,12 +25,14 @@ public class MekanismClient extends Mekanism public static long ticksPassed = 0; - public static void updateKey(EntityPlayer player, int key) + public static void updateKey(int key) { - if(Keyboard.isKeyDown(key) != keyMap.has(player, key)) + boolean down = Minecraft.getMinecraft().currentScreen == null ? Keyboard.isKeyDown(key) : false; + + if(down != keyMap.has(Minecraft.getMinecraft().thePlayer, key)) { - PacketHandler.sendPacket(Transmission.SERVER, new PacketKey().setParams(key, Keyboard.isKeyDown(key))); - keyMap.update(player, key, Keyboard.isKeyDown(key)); + PacketHandler.sendPacket(Transmission.SERVER, new PacketKey().setParams(key, down)); + keyMap.update(Minecraft.getMinecraft().thePlayer, key, down); } } } From 0d830d6136558771d019e4e28fa436f53b55adad Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sun, 8 Dec 2013 20:35:45 -0500 Subject: [PATCH 17/40] Attempt a few jetpack fixes --- .../client/ClientPlayerTickHandler.java | 147 ---------------- common/mekanism/client/ClientTickHandler.java | 163 +++++++++++++++++- .../client/render/RenderTickHandler.java | 4 +- .../mekanism/client/sound/GasMaskSound.java | 6 +- .../mekanism/client/sound/JetpackSound.java | 7 +- 5 files changed, 170 insertions(+), 157 deletions(-) diff --git a/common/mekanism/client/ClientPlayerTickHandler.java b/common/mekanism/client/ClientPlayerTickHandler.java index 6bf1445bb..4792233e3 100644 --- a/common/mekanism/client/ClientPlayerTickHandler.java +++ b/common/mekanism/client/ClientPlayerTickHandler.java @@ -131,156 +131,9 @@ public class ClientPlayerTickHandler implements ITickHandler lastTickUpdate = false; } } - - if(Mekanism.jetpackOn.contains(entityPlayer) != isJetpackOn(entityPlayer)) - { - if(isJetpackOn(entityPlayer)) - { - Mekanism.jetpackOn.add(entityPlayer); - } - else { - Mekanism.jetpackOn.remove(entityPlayer); - } - - PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.UPDATE, entityPlayer, isJetpackOn(entityPlayer))); - } - - if(Mekanism.gasmaskOn.contains(entityPlayer) != isGasMaskOn(entityPlayer)) - { - if(isGasMaskOn(entityPlayer) && mc.currentScreen == null) - { - Mekanism.gasmaskOn.add(entityPlayer); - } - else { - Mekanism.gasmaskOn.remove(entityPlayer); - } - - PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(PacketType.UPDATE, entityPlayer, isGasMaskOn(entityPlayer))); - } - - for(EntityPlayer entry : Mekanism.jetpackOn) - { - if(MekanismClient.audioHandler.getFrom(entry) == null) - { - new JetpackSound(MekanismClient.audioHandler.getIdentifier(), entry); - } - } - - for(EntityPlayer entry : Mekanism.gasmaskOn) - { - if(MekanismClient.audioHandler.getFrom(entry) == null) - { - new GasMaskSound(MekanismClient.audioHandler.getIdentifier(), entry); - } - } - - if(entityPlayer.getCurrentItemOrArmor(3) != null && entityPlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) - { - MekanismClient.updateKey(Keyboard.KEY_SPACE); - MekanismClient.updateKey(Keyboard.KEY_LSHIFT); - } - - if(isJetpackOn(entityPlayer)) - { - ItemJetpack jetpack = (ItemJetpack)entityPlayer.getCurrentItemOrArmor(3).getItem(); - - if(jetpack.getMode(entityPlayer.getCurrentItemOrArmor(3)) == JetpackMode.NORMAL) - { - entityPlayer.motionY = Math.min(mc.thePlayer.motionY + 0.15D, 0.5D); - entityPlayer.fallDistance = 0.0F; - } - else if(jetpack.getMode(entityPlayer.getCurrentItemOrArmor(3)) == JetpackMode.HOVER) - { - if((!Keyboard.isKeyDown(Keyboard.KEY_SPACE) && !Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) || (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) || mc.currentScreen != null) - { - if(entityPlayer.motionY > 0) - { - entityPlayer.motionY = Math.max(entityPlayer.motionY - 0.15D, 0); - } - else if(entityPlayer.motionY < 0) - { - entityPlayer.motionY = Math.min(entityPlayer.motionY + 0.15D, 0); - } - } - else { - if(Keyboard.isKeyDown(Keyboard.KEY_SPACE) && mc.currentScreen == null) - { - entityPlayer.motionY = Math.min(mc.thePlayer.motionY + 0.15D, 0.2D); - } - else if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && mc.currentScreen == null) - { - entityPlayer.motionY = Math.max(mc.thePlayer.motionY - 0.15D, -0.2D); - } - } - - entityPlayer.fallDistance = 0.0F; - } - - jetpack.useGas(entityPlayer.getCurrentItemOrArmor(3)); - } - - if(isGasMaskOn(entityPlayer)) - { - ItemScubaTank tank = (ItemScubaTank)entityPlayer.getCurrentItemOrArmor(3).getItem(); - - tank.useGas(entityPlayer.getCurrentItemOrArmor(3)); - entityPlayer.setAir(300); - entityPlayer.clearActivePotions(); - } } } - public static boolean isJetpackOn(EntityPlayer player) - { - ItemStack stack = player.inventory.armorInventory[2]; - - if(stack != null) - { - if(stack.getItem() instanceof ItemJetpack) - { - ItemJetpack jetpack = (ItemJetpack)stack.getItem(); - - if(jetpack.getGas(stack) != null) - { - if((Keyboard.isKeyDown(Keyboard.KEY_SPACE) && jetpack.getMode(stack) == JetpackMode.NORMAL) && mc.currentScreen == null) - { - return true; - } - else if(jetpack.getMode(stack) == JetpackMode.HOVER) - { - return true; - } - } - } - } - - return false; - } - - public static boolean isGasMaskOn(EntityPlayer player) - { - ItemStack tank = player.inventory.armorInventory[2]; - ItemStack mask = player.inventory.armorInventory[3]; - - if(tank != null && mask != null) - { - if(tank.getItem() instanceof ItemScubaTank && mask.getItem() instanceof ItemGasMask) - { - ItemScubaTank scubaTank = (ItemScubaTank)tank.getItem(); - - if(scubaTank.getGas(tank) != null) - { - if(scubaTank.getFlowing(tank)) - { - return true; - } - } - } - } - - return false; - } - @Override public EnumSet ticks() { diff --git a/common/mekanism/client/ClientTickHandler.java b/common/mekanism/client/ClientTickHandler.java index d428557e6..0780aa6a3 100644 --- a/common/mekanism/client/ClientTickHandler.java +++ b/common/mekanism/client/ClientTickHandler.java @@ -8,13 +8,27 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.lwjgl.input.Keyboard; + import mekanism.api.IClientTicker; +import mekanism.client.sound.GasMaskSound; +import mekanism.client.sound.JetpackSound; import mekanism.common.Mekanism; import mekanism.common.ObfuscatedNames; +import mekanism.common.PacketHandler; +import mekanism.common.PacketHandler.Transmission; +import mekanism.common.item.ItemGasMask; +import mekanism.common.item.ItemJetpack; +import mekanism.common.item.ItemScubaTank; +import mekanism.common.item.ItemJetpack.JetpackMode; +import mekanism.common.network.PacketJetpackData; +import mekanism.common.network.PacketScubaTankData; +import mekanism.common.network.PacketJetpackData.PacketType; import mekanism.common.util.MekanismUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.util.StringUtils; import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.common.ITickHandler; @@ -34,7 +48,7 @@ public class ClientTickHandler implements ITickHandler public boolean preloadedSounds = false; - public Minecraft mc = FMLClientHandler.instance().getClient(); + public static Minecraft mc = FMLClientHandler.instance().getClient(); public static final String MIKE_CAPE = "https://dl.dropboxusercontent.com/s/ji06yflixnszcby/cape.png"; public static final String DONATE_CAPE = "https://dl.dropboxusercontent.com/u/90411166/donate.png"; @@ -160,9 +174,156 @@ public class ClientTickHandler implements ITickHandler } } } + + if(Mekanism.jetpackOn.contains(mc.thePlayer) != isJetpackOn(mc.thePlayer)) + { + if(isJetpackOn(mc.thePlayer)) + { + Mekanism.jetpackOn.add(mc.thePlayer); + } + else { + Mekanism.jetpackOn.remove(mc.thePlayer); + } + + PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.UPDATE, mc.thePlayer, isJetpackOn(mc.thePlayer))); + } + + if(Mekanism.gasmaskOn.contains(mc.thePlayer) != isGasMaskOn(mc.thePlayer)) + { + if(isGasMaskOn(mc.thePlayer) && mc.currentScreen == null) + { + Mekanism.gasmaskOn.add(mc.thePlayer); + } + else { + Mekanism.gasmaskOn.remove(mc.thePlayer); + } + + PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(PacketType.UPDATE, mc.thePlayer, isGasMaskOn(mc.thePlayer))); + } + + for(EntityPlayer entry : Mekanism.jetpackOn) + { + if(MekanismClient.audioHandler.getFrom(entry) == null) + { + new JetpackSound(MekanismClient.audioHandler.getIdentifier(), entry); + } + } + + for(EntityPlayer entry : Mekanism.gasmaskOn) + { + if(MekanismClient.audioHandler.getFrom(entry) == null) + { + new GasMaskSound(MekanismClient.audioHandler.getIdentifier(), entry); + } + } + + if(mc.thePlayer.getCurrentItemOrArmor(3) != null && mc.thePlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) + { + MekanismClient.updateKey(Keyboard.KEY_SPACE); + MekanismClient.updateKey(Keyboard.KEY_LSHIFT); + } + + if(isJetpackOn(mc.thePlayer)) + { + ItemJetpack jetpack = (ItemJetpack)mc.thePlayer.getCurrentItemOrArmor(3).getItem(); + + if(jetpack.getMode(mc.thePlayer.getCurrentItemOrArmor(3)) == JetpackMode.NORMAL) + { + mc.thePlayer.motionY = Math.min(mc.thePlayer.motionY + 0.15D, 0.5D); + mc.thePlayer.fallDistance = 0.0F; + } + else if(jetpack.getMode(mc.thePlayer.getCurrentItemOrArmor(3)) == JetpackMode.HOVER) + { + if((!Keyboard.isKeyDown(Keyboard.KEY_SPACE) && !Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) || (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) || mc.currentScreen != null) + { + if(mc.thePlayer.motionY > 0) + { + mc.thePlayer.motionY = Math.max(mc.thePlayer.motionY - 0.15D, 0); + } + else if(mc.thePlayer.motionY < 0) + { + mc.thePlayer.motionY = Math.min(mc.thePlayer.motionY + 0.15D, 0); + } + } + else { + if(Keyboard.isKeyDown(Keyboard.KEY_SPACE) && mc.currentScreen == null) + { + mc.thePlayer.motionY = Math.min(mc.thePlayer.motionY + 0.15D, 0.2D); + } + else if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && mc.currentScreen == null) + { + mc.thePlayer.motionY = Math.max(mc.thePlayer.motionY - 0.15D, -0.2D); + } + } + + mc.thePlayer.fallDistance = 0.0F; + } + + jetpack.useGas(mc.thePlayer.getCurrentItemOrArmor(3)); + } + + if(isGasMaskOn(mc.thePlayer)) + { + ItemScubaTank tank = (ItemScubaTank)mc.thePlayer.getCurrentItemOrArmor(3).getItem(); + + tank.useGas(mc.thePlayer.getCurrentItemOrArmor(3)); + mc.thePlayer.setAir(300); + mc.thePlayer.clearActivePotions(); + } } } + public static boolean isJetpackOn(EntityPlayer player) + { + ItemStack stack = player.inventory.armorInventory[2]; + + if(stack != null) + { + if(stack.getItem() instanceof ItemJetpack) + { + ItemJetpack jetpack = (ItemJetpack)stack.getItem(); + + if(jetpack.getGas(stack) != null) + { + if((Keyboard.isKeyDown(Keyboard.KEY_SPACE) && jetpack.getMode(stack) == JetpackMode.NORMAL) && mc.currentScreen == null) + { + return true; + } + else if(jetpack.getMode(stack) == JetpackMode.HOVER) + { + return true; + } + } + } + } + + return false; + } + + public static boolean isGasMaskOn(EntityPlayer player) + { + ItemStack tank = player.inventory.armorInventory[2]; + ItemStack mask = player.inventory.armorInventory[3]; + + if(tank != null && mask != null) + { + if(tank.getItem() instanceof ItemScubaTank && mask.getItem() instanceof ItemGasMask) + { + ItemScubaTank scubaTank = (ItemScubaTank)tank.getItem(); + + if(scubaTank.getGas(tank) != null) + { + if(scubaTank.getFlowing(tank)) + { + return true; + } + } + } + } + + return false; + } + @Override public void tickEnd(EnumSet type, Object... tickData) { diff --git a/common/mekanism/client/render/RenderTickHandler.java b/common/mekanism/client/render/RenderTickHandler.java index 9a06f33f4..9e0019a94 100644 --- a/common/mekanism/client/render/RenderTickHandler.java +++ b/common/mekanism/client/render/RenderTickHandler.java @@ -8,6 +8,7 @@ import mekanism.common.Mekanism; import mekanism.common.item.ItemJetpack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiChat; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.particle.EntityFX; import net.minecraft.client.particle.EntityFlameFX; @@ -18,7 +19,6 @@ import net.minecraft.util.MathHelper; import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; import universalelectricity.core.vector.Vector3; -import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.TickType; import cpw.mods.fml.relauncher.Side; @@ -74,7 +74,7 @@ public class RenderTickHandler implements ITickHandler } } - if(player != null) + if(player != null && !(mc.currentScreen instanceof GuiChat)) { if(player.getCurrentItemOrArmor(3) != null && player.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) { diff --git a/common/mekanism/client/sound/GasMaskSound.java b/common/mekanism/client/sound/GasMaskSound.java index a06df019c..63a7f9374 100644 --- a/common/mekanism/client/sound/GasMaskSound.java +++ b/common/mekanism/client/sound/GasMaskSound.java @@ -1,6 +1,6 @@ package mekanism.client.sound; -import mekanism.client.ClientPlayerTickHandler; +import mekanism.client.ClientTickHandler; import mekanism.common.item.ItemGasMask; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; @@ -24,9 +24,9 @@ public class GasMaskSound extends PlayerSound return false; } else { - if(ClientPlayerTickHandler.isGasMaskOn(player) != isPlaying) + if(ClientTickHandler.isGasMaskOn(player) != isPlaying) { - if(ClientPlayerTickHandler.isGasMaskOn(player)) + if(ClientTickHandler.isGasMaskOn(player)) { play(); } diff --git a/common/mekanism/client/sound/JetpackSound.java b/common/mekanism/client/sound/JetpackSound.java index 5dd369874..748cead3e 100644 --- a/common/mekanism/client/sound/JetpackSound.java +++ b/common/mekanism/client/sound/JetpackSound.java @@ -1,10 +1,9 @@ package mekanism.client.sound; -import mekanism.client.ClientPlayerTickHandler; +import mekanism.client.ClientTickHandler; import mekanism.common.item.ItemJetpack; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; -import universalelectricity.core.vector.Vector3; public class JetpackSound extends PlayerSound { @@ -25,9 +24,9 @@ public class JetpackSound extends PlayerSound return false; } else { - if(ClientPlayerTickHandler.isJetpackOn(player) != isPlaying) + if(ClientTickHandler.isJetpackOn(player) != isPlaying) { - if(ClientPlayerTickHandler.isJetpackOn(player)) + if(ClientTickHandler.isJetpackOn(player)) { play(); } From 4125ef57c6dc228ffc51deb933a646d1e2fa9552 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Sun, 8 Dec 2013 21:40:00 -0500 Subject: [PATCH 18/40] minor changes --- .../render/block/MachineRenderingHandler.java | 2 +- common/mekanism/client/sound/Sound.java | 14 ++++++++------ common/mekanism/client/sound/SoundHandler.java | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/common/mekanism/client/render/block/MachineRenderingHandler.java b/common/mekanism/client/render/block/MachineRenderingHandler.java index 38c85f724..512b96479 100644 --- a/common/mekanism/client/render/block/MachineRenderingHandler.java +++ b/common/mekanism/client/render/block/MachineRenderingHandler.java @@ -86,7 +86,7 @@ public class MachineRenderingHandler implements ISimpleBlockRenderingHandler { GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F); GL11.glRotatef(270F, 0.0F, -1.0F, 0.0F); - GL11.glTranslatef(0.0F, -1F, 0.05F); + GL11.glTranslatef(0.0F, -1.06F, 0.05F); Minecraft.getMinecraft().renderEngine.bindTexture(MekanismUtils.getResource(ResourceType.RENDER, "RotaryCondensentrator.png")); rotaryCondensentrator.render(0.0625F); } diff --git a/common/mekanism/client/sound/Sound.java b/common/mekanism/client/sound/Sound.java index a45a95641..57d1b22a7 100644 --- a/common/mekanism/client/sound/Sound.java +++ b/common/mekanism/client/sound/Sound.java @@ -21,6 +21,8 @@ public abstract class Sound private Object objRef; + protected Minecraft mc = Minecraft.getMinecraft(); + /** * A sound that runs off of the PaulsCode sound system. * @param id - unique identifier @@ -50,7 +52,7 @@ public abstract class Sound if(SoundHandler.getSoundSystem() != null) { SoundHandler.getSoundSystem().newSource(false, id, url, sound, true, (float)loc.x, (float)loc.y, (float)loc.z, 0, 16F); - updateVolume(Minecraft.getMinecraft().thePlayer); + updateVolume(); SoundHandler.getSoundSystem().activate(id); } @@ -72,7 +74,7 @@ public abstract class Sound if(SoundHandler.getSoundSystem() != null) { - updateVolume(Minecraft.getMinecraft().thePlayer); + updateVolume(); SoundHandler.getSoundSystem().play(identifier); } @@ -94,7 +96,7 @@ public abstract class Sound if(SoundHandler.getSoundSystem() != null) { - updateVolume(Minecraft.getMinecraft().thePlayer); + updateVolume(); SoundHandler.getSoundSystem().stop(identifier); } @@ -118,7 +120,7 @@ public abstract class Sound if(SoundHandler.getSoundSystem() != null) { - updateVolume(Minecraft.getMinecraft().thePlayer); + updateVolume(); SoundHandler.getSoundSystem().removeSource(identifier); } } @@ -134,7 +136,7 @@ public abstract class Sound * Updates the volume based on how far away the player is from the machine. * @param entityplayer - player who is near the machine, always Minecraft.thePlayer */ - public void updateVolume(EntityPlayer entityplayer) + public void updateVolume() { synchronized(MekanismClient.audioHandler.sounds) { @@ -143,7 +145,7 @@ public abstract class Sound float volume = 0; float masterVolume = MekanismClient.audioHandler.masterVolume; - double distance = entityplayer.getDistance(getLocation().x, getLocation().y, getLocation().z); + double distance = mc.thePlayer.getDistance(getLocation().x, getLocation().y, getLocation().z); volume = (float)Math.min(Math.max(masterVolume-((distance*.08F)*masterVolume), 0)*multiplier, 1); volume *= Math.max(0, Math.min(1, MekanismClient.baseSoundVolume)); diff --git a/common/mekanism/client/sound/SoundHandler.java b/common/mekanism/client/sound/SoundHandler.java index da39e87f5..8f23a2016 100644 --- a/common/mekanism/client/sound/SoundHandler.java +++ b/common/mekanism/client/sound/SoundHandler.java @@ -193,7 +193,7 @@ public class SoundHandler { if(sound.isPlaying) { - sound.updateVolume(FMLClientHandler.instance().getClient().thePlayer); + sound.updateVolume(); } } From 781aef807cd6368ccb45152a35163cbabbdbe7ae Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Mon, 9 Dec 2013 07:11:00 -0500 Subject: [PATCH 19/40] Add lapis lazuli dust Enrichment Chamber recipe --- common/mekanism/common/Mekanism.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index 6aee6e931..ae71a30e9 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -957,6 +957,11 @@ public class Mekanism RecipeHandler.addCombinerRecipe(MekanismUtils.size(ore, 8), new ItemStack(Block.oreGold)); } + for(ItemStack ore : OreDictionary.getOres("dustLapisLazuli")) + { + RecipeHandler.addCrusherRecipe(new ItemStack(Item.dyePowder, 1, 4), MekanismUtils.size(ore, 1)); + } + for(ItemStack ore : OreDictionary.getOres("dustObsidian")) { RecipeHandler.addCombinerRecipe(MekanismUtils.size(ore, 2), new ItemStack(Block.obsidian)); From 4ebf11ed5a5274cd495b92e673a135957e8542dd Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Mon, 9 Dec 2013 07:19:16 -0500 Subject: [PATCH 20/40] Fix crash --- common/mekanism/client/ClientProxy.java | 6 +++- common/mekanism/client/ClientTickHandler.java | 30 +++++++++++-------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/common/mekanism/client/ClientProxy.java b/common/mekanism/client/ClientProxy.java index 62309c9ac..2aeaab02e 100644 --- a/common/mekanism/client/ClientProxy.java +++ b/common/mekanism/client/ClientProxy.java @@ -135,7 +135,7 @@ public class ClientProxy extends CommonProxy Mekanism.configuration.load(); MekanismClient.enableSounds = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "EnableSounds", true).getBoolean(true); MekanismClient.fancyUniversalCableRender = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "FancyUniversalCableRender", true).getBoolean(true); - MekanismClient.baseSoundVolume = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "baseSoundVolume", 1).getDouble(1); + MekanismClient.baseSoundVolume = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "SoundVolume", 1).getDouble(1); Mekanism.configuration.save(); } @@ -324,6 +324,7 @@ public class ClientProxy extends CommonProxy return new GuiTeleporter(player.inventory, (TileEntityTeleporter)tileEntity); case 14: ItemStack itemStack = player.getCurrentEquippedItem(); + if(itemStack != null && itemStack.getItem() instanceof ItemPortableTeleporter) { return new GuiPortableTeleporter(player, itemStack); @@ -342,6 +343,7 @@ public class ClientProxy extends CommonProxy return new GuiPasswordModify((TileEntityElectricChest)tileEntity); case 21: EntityRobit robit = (EntityRobit)world.getEntityByID(x); + if(robit != null) { return new GuiRobitMain(player.inventory, robit); @@ -350,12 +352,14 @@ public class ClientProxy extends CommonProxy return new GuiRobitCrafting(player.inventory, world, x); case 23: EntityRobit robit1 = (EntityRobit)world.getEntityByID(x); + if(robit1 != null) { return new GuiRobitInventory(player.inventory, robit1); } case 24: EntityRobit robit2 = (EntityRobit)world.getEntityByID(x); + if(robit2 != null) { return new GuiRobitSmelting(player.inventory, robit2); diff --git a/common/mekanism/client/ClientTickHandler.java b/common/mekanism/client/ClientTickHandler.java index 0780aa6a3..d5eb342f9 100644 --- a/common/mekanism/client/ClientTickHandler.java +++ b/common/mekanism/client/ClientTickHandler.java @@ -8,8 +8,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.lwjgl.input.Keyboard; - import mekanism.api.IClientTicker; import mekanism.client.sound.GasMaskSound; import mekanism.client.sound.JetpackSound; @@ -19,17 +17,20 @@ import mekanism.common.PacketHandler; import mekanism.common.PacketHandler.Transmission; import mekanism.common.item.ItemGasMask; import mekanism.common.item.ItemJetpack; -import mekanism.common.item.ItemScubaTank; import mekanism.common.item.ItemJetpack.JetpackMode; +import mekanism.common.item.ItemScubaTank; import mekanism.common.network.PacketJetpackData; -import mekanism.common.network.PacketScubaTankData; import mekanism.common.network.PacketJetpackData.PacketType; +import mekanism.common.network.PacketScubaTankData; import mekanism.common.util.MekanismUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.StringUtils; + +import org.lwjgl.input.Keyboard; + import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.TickType; @@ -201,19 +202,22 @@ public class ClientTickHandler implements ITickHandler PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(PacketType.UPDATE, mc.thePlayer, isGasMaskOn(mc.thePlayer))); } - for(EntityPlayer entry : Mekanism.jetpackOn) + if(MekanismClient.audioHandler != null) { - if(MekanismClient.audioHandler.getFrom(entry) == null) + for(EntityPlayer entry : Mekanism.jetpackOn) { - new JetpackSound(MekanismClient.audioHandler.getIdentifier(), entry); + if(MekanismClient.audioHandler.getFrom(entry) == null) + { + new JetpackSound(MekanismClient.audioHandler.getIdentifier(), entry); + } } - } - - for(EntityPlayer entry : Mekanism.gasmaskOn) - { - if(MekanismClient.audioHandler.getFrom(entry) == null) + + for(EntityPlayer entry : Mekanism.gasmaskOn) { - new GasMaskSound(MekanismClient.audioHandler.getIdentifier(), entry); + if(MekanismClient.audioHandler.getFrom(entry) == null) + { + new GasMaskSound(MekanismClient.audioHandler.getIdentifier(), entry); + } } } From 13b8c3f7935de83130ac60c77f58fb12881439c8 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Mon, 9 Dec 2013 07:25:11 -0500 Subject: [PATCH 21/40] Fix MI config --- .../induction/common/InductionCommonProxy.java | 16 +++++++++------- .../induction/common/MekanismInduction.java | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/common/mekanism/induction/common/InductionCommonProxy.java b/common/mekanism/induction/common/InductionCommonProxy.java index e5387512a..93bce3794 100644 --- a/common/mekanism/induction/common/InductionCommonProxy.java +++ b/common/mekanism/induction/common/InductionCommonProxy.java @@ -20,16 +20,18 @@ import cpw.mods.fml.common.network.IGuiHandler; */ public class InductionCommonProxy implements IGuiHandler { - public void registerRenderers() + public void registerRenderers() {} + + public void loadConfiguration() { Mekanism.configuration.load(); - MekanismInduction.SOUND_FXS = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "Tesla Sound FXs", MekanismInduction.SOUND_FXS).getBoolean(MekanismInduction.SOUND_FXS); - MekanismInduction.MAX_CONTRACTOR_DISTANCE = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "Max EM Contractor Path", MekanismInduction.MAX_CONTRACTOR_DISTANCE).getInt(MekanismInduction.MAX_CONTRACTOR_DISTANCE); + MekanismInduction.SOUND_FXS = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "TeslaSoundFXs", MekanismInduction.SOUND_FXS).getBoolean(MekanismInduction.SOUND_FXS); + MekanismInduction.MAX_CONTRACTOR_DISTANCE = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "MaxEMContractor Path", MekanismInduction.MAX_CONTRACTOR_DISTANCE).getInt(MekanismInduction.MAX_CONTRACTOR_DISTANCE); - TileEntityEMContractor.ACCELERATION = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "Contractor Item Acceleration", TileEntityEMContractor.ACCELERATION).getDouble(TileEntityEMContractor.ACCELERATION); - TileEntityEMContractor.MAX_REACH = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "Contractor Max Item Reach", TileEntityEMContractor.MAX_REACH).getInt(TileEntityEMContractor.MAX_REACH); - TileEntityEMContractor.MAX_SPEED = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "Contractor Max Item Speed", TileEntityEMContractor.MAX_SPEED).getDouble(TileEntityEMContractor.MAX_SPEED); - TileEntityEMContractor.PUSH_DELAY = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "Contractor Item Push Delay", TileEntityEMContractor.PUSH_DELAY).getInt(TileEntityEMContractor.PUSH_DELAY); + TileEntityEMContractor.ACCELERATION = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "ContractorItemAcceleration", TileEntityEMContractor.ACCELERATION).getDouble(TileEntityEMContractor.ACCELERATION); + TileEntityEMContractor.MAX_REACH = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "ContractorMaxItemReach", TileEntityEMContractor.MAX_REACH).getInt(TileEntityEMContractor.MAX_REACH); + TileEntityEMContractor.MAX_SPEED = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "ContractorMaxItemSpeed", TileEntityEMContractor.MAX_SPEED).getDouble(TileEntityEMContractor.MAX_SPEED); + TileEntityEMContractor.PUSH_DELAY = Mekanism.configuration.get(Configuration.CATEGORY_GENERAL, "ContractorItemPushDelay", TileEntityEMContractor.PUSH_DELAY).getInt(TileEntityEMContractor.PUSH_DELAY); Mekanism.configuration.save(); } diff --git a/common/mekanism/induction/common/MekanismInduction.java b/common/mekanism/induction/common/MekanismInduction.java index 055b807c3..26c303e7f 100644 --- a/common/mekanism/induction/common/MekanismInduction.java +++ b/common/mekanism/induction/common/MekanismInduction.java @@ -94,6 +94,7 @@ public class MekanismInduction implements IModule GameRegistry.registerTileEntity(TileEntityBattery.class, "Battery"); MekanismInduction.proxy.registerRenderers(); + MekanismInduction.proxy.loadConfiguration(); } @EventHandler From 4035ba9b364ef417352323f9796859b00f73b130 Mon Sep 17 00:00:00 2001 From: "Aidan C. Brady" Date: Mon, 9 Dec 2013 09:52:49 -0500 Subject: [PATCH 22/40] Add overlay for scuba tank --- .../client/render/RenderTickHandler.java | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/common/mekanism/client/render/RenderTickHandler.java b/common/mekanism/client/render/RenderTickHandler.java index 9e0019a94..0c9455269 100644 --- a/common/mekanism/client/render/RenderTickHandler.java +++ b/common/mekanism/client/render/RenderTickHandler.java @@ -3,9 +3,11 @@ package mekanism.client.render; import java.util.EnumSet; import java.util.Random; +import mekanism.api.EnumColor; import mekanism.api.Object3D; import mekanism.common.Mekanism; import mekanism.common.item.ItemJetpack; +import mekanism.common.item.ItemScubaTank; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiChat; @@ -74,20 +76,29 @@ public class RenderTickHandler implements ITickHandler } } - if(player != null && !(mc.currentScreen instanceof GuiChat)) + if(player != null && !(mc.currentScreen instanceof GuiChat) && player.getCurrentItemOrArmor(3) != null) { - if(player.getCurrentItemOrArmor(3) != null && player.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) + ItemStack stack = player.getCurrentItemOrArmor(3); + + ScaledResolution scaledresolution = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight); + int x = scaledresolution.getScaledWidth(); + int y = scaledresolution.getScaledHeight(); + + if(stack.getItem() instanceof ItemJetpack) { - ItemStack stack = player.getCurrentItemOrArmor(3); ItemJetpack jetpack = (ItemJetpack)stack.getItem(); - ScaledResolution scaledresolution = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight); - int x = scaledresolution.getScaledWidth(); - int y = scaledresolution.getScaledHeight(); - font.drawStringWithShadow("Mode: " + jetpack.getMode(stack).getName(), 1, y - 20, 0x404040); font.drawStringWithShadow("Hydrogen: " + jetpack.getStored(stack), 1, y - 11, 0x404040); } + else if(stack.getItem() instanceof ItemScubaTank) + { + ItemScubaTank scubaTank = (ItemScubaTank)stack.getItem(); + String state = (scubaTank.getFlowing(stack) ? EnumColor.DARK_GREEN + "On" : EnumColor.DARK_RED + "Off"); + + font.drawStringWithShadow("Mode: " + state, 1, y - 20, 0x404040); + font.drawStringWithShadow("Oxygen: " + scubaTank.getStored(stack), 1, y - 11, 0x404040); + } } for(EntityPlayer p : Mekanism.jetpackOn) From 5661b20b27a595c303af959e51d63c157d80472c Mon Sep 17 00:00:00 2001 From: "Aidan C. Brady" Date: Mon, 9 Dec 2013 11:56:48 -0500 Subject: [PATCH 23/40] A few fixes --- .../client/ClientPlayerTickHandler.java | 148 ------------------ common/mekanism/client/ClientProxy.java | 1 - common/mekanism/client/ClientTickHandler.java | 93 +++++++++++ common/mekanism/common/Mekanism.java | 1 + .../common/voice/VoiceConnection.java | 2 +- .../common/voice/VoiceServerManager.java | 3 +- 6 files changed, 96 insertions(+), 152 deletions(-) delete mode 100644 common/mekanism/client/ClientPlayerTickHandler.java diff --git a/common/mekanism/client/ClientPlayerTickHandler.java b/common/mekanism/client/ClientPlayerTickHandler.java deleted file mode 100644 index 4792233e3..000000000 --- a/common/mekanism/client/ClientPlayerTickHandler.java +++ /dev/null @@ -1,148 +0,0 @@ -package mekanism.client; - -import java.util.EnumSet; - -import mekanism.api.EnumColor; -import mekanism.client.sound.GasMaskSound; -import mekanism.client.sound.JetpackSound; -import mekanism.common.Mekanism; -import mekanism.common.PacketHandler; -import mekanism.common.PacketHandler.Transmission; -import mekanism.common.item.ItemConfigurator; -import mekanism.common.item.ItemElectricBow; -import mekanism.common.item.ItemGasMask; -import mekanism.common.item.ItemJetpack; -import mekanism.common.item.ItemJetpack.JetpackMode; -import mekanism.common.item.ItemScubaTank; -import mekanism.common.item.ItemWalkieTalkie; -import mekanism.common.network.PacketConfiguratorState; -import mekanism.common.network.PacketElectricBowState; -import mekanism.common.network.PacketJetpackData; -import mekanism.common.network.PacketJetpackData.PacketType; -import mekanism.common.network.PacketScubaTankData; -import mekanism.common.network.PacketWalkieTalkieState; -import mekanism.common.util.StackUtils; -import net.minecraft.client.Minecraft; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ChatMessageComponent; - -import org.lwjgl.input.Keyboard; - -import cpw.mods.fml.common.ITickHandler; -import cpw.mods.fml.common.TickType; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ClientPlayerTickHandler implements ITickHandler -{ - public boolean lastTickUpdate = false; - public static Minecraft mc = Minecraft.getMinecraft(); - - @Override - public void tickStart(EnumSet type, Object... tickData) {} - - @Override - public void tickEnd(EnumSet type, Object... tickData) - { - if(tickData[0] instanceof EntityPlayer) - { - EntityPlayer entityPlayer = (EntityPlayer)tickData[0]; - - ItemStack stack = entityPlayer.getCurrentEquippedItem(); - - if(mc.currentScreen == null) - { - if(entityPlayer.isSneaking() && StackUtils.getItem(entityPlayer.getCurrentEquippedItem()) instanceof ItemConfigurator) - { - ItemConfigurator item = (ItemConfigurator)entityPlayer.getCurrentEquippedItem().getItem(); - - if(MekanismKeyHandler.modeSwitchKey.pressed) - { - if(!lastTickUpdate) - { - item.setState(stack, (byte)(item.getState(stack) < 3 ? item.getState(stack)+1 : 0)); - PacketHandler.sendPacket(Transmission.SERVER, new PacketConfiguratorState().setParams(item.getState(stack))); - entityPlayer.sendChatToPlayer(ChatMessageComponent.createFromText(EnumColor.DARK_BLUE + "[Mekanism] " + EnumColor.GREY + "Configure State: " + item.getColor(item.getState(stack)) + item.getStateDisplay(item.getState(stack)))); - lastTickUpdate = true; - } - } - else { - lastTickUpdate = false; - } - } - else if(entityPlayer.isSneaking() && StackUtils.getItem(entityPlayer.getCurrentEquippedItem()) instanceof ItemElectricBow) - { - ItemElectricBow item = (ItemElectricBow)entityPlayer.getCurrentEquippedItem().getItem(); - - if(MekanismKeyHandler.modeSwitchKey.pressed) - { - if(!lastTickUpdate) - { - item.setFireState(stack, !item.getFireState(stack)); - PacketHandler.sendPacket(Transmission.SERVER, new PacketElectricBowState().setParams(item.getFireState(stack))); - entityPlayer.sendChatToPlayer(ChatMessageComponent.createFromText(EnumColor.DARK_BLUE + "[Mekanism] " + EnumColor.GREY + "Fire Mode: " + (item.getFireState(stack) ? (EnumColor.DARK_GREEN + "ON") : (EnumColor.DARK_RED + "OFF")))); - lastTickUpdate = true; - } - } - else { - lastTickUpdate = false; - } - } - else if(entityPlayer.isSneaking() && StackUtils.getItem(entityPlayer.getCurrentEquippedItem()) instanceof ItemWalkieTalkie) - { - ItemWalkieTalkie item = (ItemWalkieTalkie)entityPlayer.getCurrentEquippedItem().getItem(); - - if(MekanismKeyHandler.modeSwitchKey.pressed && item.getOn(stack)) - { - if(!lastTickUpdate) - { - int newChan = item.getChannel(stack) < 9 ? item.getChannel(stack)+1 : 1; - item.setChannel(stack, newChan); - PacketHandler.sendPacket(Transmission.SERVER, new PacketWalkieTalkieState().setParams(newChan)); - Minecraft.getMinecraft().sndManager.playSoundFX("mekanism:etc.Ding", 1.0F, 1.0F); - lastTickUpdate = true; - } - } - else { - lastTickUpdate = false; - } - } - else if(entityPlayer.getCurrentItemOrArmor(3) != null && entityPlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) - { - ItemStack jetpack = entityPlayer.getCurrentItemOrArmor(3); - - if(MekanismKeyHandler.modeSwitchKey.pressed) - { - if(!lastTickUpdate) - { - ((ItemJetpack)jetpack.getItem()).incrementMode(jetpack); - PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.MODE)); - Minecraft.getMinecraft().sndManager.playSoundFX("mekanism:etc.Hydraulic", 1.0F, 1.0F); - lastTickUpdate = true; - } - } - else { - lastTickUpdate = false; - } - } - else { - lastTickUpdate = false; - } - } - } - } - - @Override - public EnumSet ticks() - { - return EnumSet.of(TickType.PLAYER); - } - - @Override - public String getLabel() - { - return "MekanismClientPlayer"; - } -} diff --git a/common/mekanism/client/ClientProxy.java b/common/mekanism/client/ClientProxy.java index 2aeaab02e..0228c7fd4 100644 --- a/common/mekanism/client/ClientProxy.java +++ b/common/mekanism/client/ClientProxy.java @@ -383,7 +383,6 @@ public class ClientProxy extends CommonProxy super.loadUtilities(); TickRegistry.registerTickHandler(new ClientTickHandler(), Side.CLIENT); - TickRegistry.registerTickHandler(new ClientPlayerTickHandler(), Side.CLIENT); TickRegistry.registerTickHandler(new RenderTickHandler(), Side.CLIENT); NetworkRegistry.instance().registerConnectionHandler(new ClientConnectionHandler()); diff --git a/common/mekanism/client/ClientTickHandler.java b/common/mekanism/client/ClientTickHandler.java index d5eb342f9..33b4dcf5c 100644 --- a/common/mekanism/client/ClientTickHandler.java +++ b/common/mekanism/client/ClientTickHandler.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import mekanism.api.EnumColor; import mekanism.api.IClientTicker; import mekanism.client.sound.GasMaskSound; import mekanism.client.sound.JetpackSound; @@ -15,18 +16,26 @@ import mekanism.common.Mekanism; import mekanism.common.ObfuscatedNames; import mekanism.common.PacketHandler; import mekanism.common.PacketHandler.Transmission; +import mekanism.common.item.ItemConfigurator; +import mekanism.common.item.ItemElectricBow; import mekanism.common.item.ItemGasMask; import mekanism.common.item.ItemJetpack; +import mekanism.common.item.ItemWalkieTalkie; import mekanism.common.item.ItemJetpack.JetpackMode; import mekanism.common.item.ItemScubaTank; +import mekanism.common.network.PacketConfiguratorState; +import mekanism.common.network.PacketElectricBowState; import mekanism.common.network.PacketJetpackData; +import mekanism.common.network.PacketWalkieTalkieState; import mekanism.common.network.PacketJetpackData.PacketType; import mekanism.common.network.PacketScubaTankData; import mekanism.common.util.MekanismUtils; +import mekanism.common.util.StackUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; +import net.minecraft.util.ChatMessageComponent; import net.minecraft.util.StringUtils; import org.lwjgl.input.Keyboard; @@ -49,6 +58,8 @@ public class ClientTickHandler implements ITickHandler public boolean preloadedSounds = false; + public boolean lastTickUpdate; + public static Minecraft mc = FMLClientHandler.instance().getClient(); public static final String MIKE_CAPE = "https://dl.dropboxusercontent.com/s/ji06yflixnszcby/cape.png"; @@ -176,6 +187,88 @@ public class ClientTickHandler implements ITickHandler } } + ItemStack stack = mc.thePlayer.getCurrentEquippedItem(); + + if(mc.currentScreen == null) + { + if(mc.thePlayer.isSneaking() && StackUtils.getItem(mc.thePlayer.getCurrentEquippedItem()) instanceof ItemConfigurator) + { + ItemConfigurator item = (ItemConfigurator)mc.thePlayer.getCurrentEquippedItem().getItem(); + + if(MekanismKeyHandler.modeSwitchKey.pressed) + { + if(!lastTickUpdate) + { + item.setState(stack, (byte)(item.getState(stack) < 3 ? item.getState(stack)+1 : 0)); + PacketHandler.sendPacket(Transmission.SERVER, new PacketConfiguratorState().setParams(item.getState(stack))); + mc.thePlayer.sendChatToPlayer(ChatMessageComponent.createFromText(EnumColor.DARK_BLUE + "[Mekanism] " + EnumColor.GREY + "Configure State: " + item.getColor(item.getState(stack)) + item.getStateDisplay(item.getState(stack)))); + lastTickUpdate = true; + } + } + else { + lastTickUpdate = false; + } + } + else if(mc.thePlayer.isSneaking() && StackUtils.getItem(mc.thePlayer.getCurrentEquippedItem()) instanceof ItemElectricBow) + { + ItemElectricBow item = (ItemElectricBow)mc.thePlayer.getCurrentEquippedItem().getItem(); + + if(MekanismKeyHandler.modeSwitchKey.pressed) + { + if(!lastTickUpdate) + { + item.setFireState(stack, !item.getFireState(stack)); + PacketHandler.sendPacket(Transmission.SERVER, new PacketElectricBowState().setParams(item.getFireState(stack))); + mc.thePlayer.sendChatToPlayer(ChatMessageComponent.createFromText(EnumColor.DARK_BLUE + "[Mekanism] " + EnumColor.GREY + "Fire Mode: " + (item.getFireState(stack) ? (EnumColor.DARK_GREEN + "ON") : (EnumColor.DARK_RED + "OFF")))); + lastTickUpdate = true; + } + } + else { + lastTickUpdate = false; + } + } + else if(mc.thePlayer.isSneaking() && StackUtils.getItem(mc.thePlayer.getCurrentEquippedItem()) instanceof ItemWalkieTalkie) + { + ItemWalkieTalkie item = (ItemWalkieTalkie)mc.thePlayer.getCurrentEquippedItem().getItem(); + + if(MekanismKeyHandler.modeSwitchKey.pressed && item.getOn(stack)) + { + if(!lastTickUpdate) + { + int newChan = item.getChannel(stack) < 9 ? item.getChannel(stack)+1 : 1; + item.setChannel(stack, newChan); + PacketHandler.sendPacket(Transmission.SERVER, new PacketWalkieTalkieState().setParams(newChan)); + Minecraft.getMinecraft().sndManager.playSoundFX("mekanism:etc.Ding", 1.0F, 1.0F); + lastTickUpdate = true; + } + } + else { + lastTickUpdate = false; + } + } + else if(mc.thePlayer.getCurrentItemOrArmor(3) != null && mc.thePlayer.getCurrentItemOrArmor(3).getItem() instanceof ItemJetpack) + { + ItemStack jetpack = mc.thePlayer.getCurrentItemOrArmor(3); + + if(MekanismKeyHandler.modeSwitchKey.pressed) + { + if(!lastTickUpdate) + { + ((ItemJetpack)jetpack.getItem()).incrementMode(jetpack); + PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.MODE)); + Minecraft.getMinecraft().sndManager.playSoundFX("mekanism:etc.Hydraulic", 1.0F, 1.0F); + lastTickUpdate = true; + } + } + else { + lastTickUpdate = false; + } + } + else { + lastTickUpdate = false; + } + } + if(Mekanism.jetpackOn.contains(mc.thePlayer) != isJetpackOn(mc.thePlayer)) { if(isJetpackOn(mc.thePlayer)) diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index ae71a30e9..0b0ab8866 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -589,6 +589,7 @@ public class Mekanism Jetpack = (ItemJetpack)new ItemJetpack(configuration.getItem("Jetpack", 11223).getInt()).setUnlocalizedName("Jetpack"); WalkieTalkie = new ItemWalkieTalkie(configuration.getItem("WalkieTalkie", 11224).getInt()).setUnlocalizedName("WalkieTalkie"); configuration.save(); + //TODO 1.7, fix item shifts //Registrations GameRegistry.registerItem(ElectricBow, "ElectricBow"); diff --git a/common/mekanism/common/voice/VoiceConnection.java b/common/mekanism/common/voice/VoiceConnection.java index ae88b37b6..c09866596 100644 --- a/common/mekanism/common/voice/VoiceConnection.java +++ b/common/mekanism/common/voice/VoiceConnection.java @@ -56,7 +56,7 @@ public class VoiceConnection EntityPlayerMP playerMP = (EntityPlayerMP)obj; String playerIP = playerMP.getPlayerIP(); - if(playerIP.equals("127.0.0.1") && !Mekanism.voiceManager.foundLocal) + if(!server.isDedicatedServer() && playerIP.equals("127.0.0.1") && !Mekanism.voiceManager.foundLocal) { Mekanism.voiceManager.foundLocal = true; username = playerMP.username; diff --git a/common/mekanism/common/voice/VoiceServerManager.java b/common/mekanism/common/voice/VoiceServerManager.java index 4626eb166..8ac10fdbb 100644 --- a/common/mekanism/common/voice/VoiceServerManager.java +++ b/common/mekanism/common/voice/VoiceServerManager.java @@ -25,11 +25,10 @@ public class VoiceServerManager System.out.println("[Mekanism] VoiceServer: Starting up server..."); try { + running = true; serverSocket = new ServerSocket(Mekanism.VOICE_PORT); (listenThread = new ListenThread()).start(); } catch(Exception e) {} - - running = true; } public void stop() From 02fcac896753951d136be4069d3e31de35ce35ec Mon Sep 17 00:00:00 2001 From: Vexatos Date: Mon, 9 Dec 2013 19:22:05 +0100 Subject: [PATCH 24/40] Loads of work done. (Updated de_DE.lang) Yes, "Minierer" is a German word. --- resources/assets/mekanism/lang/de_DE.lang | 37 +++++++++++++++++++---- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/resources/assets/mekanism/lang/de_DE.lang b/resources/assets/mekanism/lang/de_DE.lang index 688212e7d..784de0bfd 100644 --- a/resources/assets/mekanism/lang/de_DE.lang +++ b/resources/assets/mekanism/lang/de_DE.lang @@ -22,6 +22,9 @@ item.TeleportationCore.name=Teleportationskern item.Configurator.name=Konfigurator item.NetworkReader.name=Netzwerklesegerät item.WalkieTalkie.name=Walkie-Talkie +item.Jetpack.name=Jetpack +item.ScubaTank.name=Taucherflasche +item.GasMask.name=Gasmaske //Gas Tank tile.GasTank.GasTank.name=Gastank @@ -242,6 +245,28 @@ tooltip.configurator.noLink=Kein Link tooltip.configurator.linkMsg=Verbunden mit tooltip.configurator.dim=Dimension +tooltip.jetpack.regular=Regulär +tooltip.jetpack.hover=Schweben +tooltip.jetpack.disabled=Deaktiviert + +tooltip.EnrichmentChamber=Eine einfache Maschine, genutzt, um Erze zu !nzwei ihrer entsprechenden Stäube anzureichern !nsowie viele andere Operationen auszuführen. +tooltip.OsmiumCompressor=Eine ziemlich fortschrittliche Maschine, genutzt, !num Osmium in verschiedene Stäube zu pressen, !num ihre entsprechenden Barren zu kreieren. +tooltip.Combiner=Eine Maschine, genutzt, um Stäube mit Pflasterstein !nzu kombinieren, um entsprechende Erze zu formen. +tooltip.Crusher=Eine Maschine, genutzt, um Barren in ihre entsprechenden !nStäube zu zerstoßen sowie viele andere Operationen auszuführen. +tooltip.DigitalMiner=Ein äußerst fortschrittlicher, Filter-basierter !nAuto-Minierer, der alles abbauen kann, was du willst, !ninnerhalb eines Radius von 32 Blöcken (max). +tooltip.BasicFactory=Die niedrigste Stufe in der Reihe der Fabriken, !nwelche genutzt werden kann, um mehrere !nMaschinenoperationen auf einmal auszuführen. +tooltip.AdvancedFactory=Die mittlere Stufe in der Reihe der Fabriken, !nwelche genutzt werden kann, um mehrere !nMaschinenoperationen auf einmal auszuführen. +tooltip.EliteFactory=Die höchste Stufe in der Reihe der Fabriken, !nwelche genutzt werden kann, um mehrere !nMaschinenoperationen auf einmal auszuführen. +tooltip.MetallurgicInfuser=Eine Maschine, genutzt, um verschiedene Materialien !n(generell) in Metalle einzuflößen, um Legierungen !nund andere Komponenten zu kreieren. +tooltip.PurificationChamber=Eine fortgeschrittene Maschine, fähig, Erze zu !ndrei Klumpen zu verarbeiten, was im Anfangsstadium !n300% an Erzverarbeitung bietet. +tooltip.EnergizedSmelter=Eine einfache Maschine, die einen Mekanism-basierten !nOfen bietet, der mit Energie läuft. +tooltip.Teleporter=Eine Maschine, fähig, Spieler zu verschiedenen Orten, !ndefiniert durch andere Teleporter, zu teleportieren. +tooltip.ElectricPump=Eine fortgeschrittene Pumpe, fähig, !nganze Lavaseen auszupumpen. +tooltip.ElectricChest=Eine Tragbare, 54-Slot-Truhe, die Energie nutzt, !num sich selbst zu sperren, per Passwortschutz. +tooltip.Chargepad=Ein universelles Ladepad, dass jegliches energetisiertes !nItem jeglicher Mods aufladen kann. +tooltip.LogisticalSorter=Eine Filter-basierte, fortgeschrittene Sortiermaschine, die !nautomatisch spezifische Items aus einem Inventar oder !nLogistischen Transporter heraus und in eines hinein treiben kann. +tooltip.RotaryCondensentrator=Eine Maschine, die fähig ist, Gase in ihre !nflüssige Form zu konvertieren und umgekehrt. + //Redstone control control.disabled=Deaktiviert control.high=High @@ -289,6 +314,12 @@ tile.Generator.BioGenerator.name=Bio-Generator tile.Generator.AdvancedSolarGenerator.name=Fortgeschrittener Solargenerator tile.Generator.WindTurbine.name=Windturbine +//Gui text +gui.heatGenerator.fuel=Brennstoff +gui.solarGenerator.sun=Sonne +gui.bioGenerator.bioFuel=Biobrennstoff +gui.electrolyticSeparator.dump=Entsorge + //*****// //TOOLS// //*****// @@ -385,9 +416,3 @@ tile.Battery.name=Modulare Batterie //General text text.contractor.success=Kontraktor erfolgreich verbunden text.tesla.success=Teslaspule erfolgreich verbunden - -//Gui text -gui.heatGenerator.fuel=Brennstoff -gui.solarGenerator.sun=Sonne -gui.bioGenerator.bioFuel=Biobrennstoff -gui.electrolyticSeparator.dump=Entsorge From 461e2886ab07561c7658c9bbf6532c1e371dc0ad Mon Sep 17 00:00:00 2001 From: Vexatos Date: Mon, 9 Dec 2013 19:23:03 +0100 Subject: [PATCH 25/40] Typo fix. Let's hope is was a typo. Let's hope is was a typo. --- resources/assets/mekanism/lang/en_US.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/assets/mekanism/lang/en_US.lang b/resources/assets/mekanism/lang/en_US.lang index 8b97e99d0..b1645b5a7 100644 --- a/resources/assets/mekanism/lang/en_US.lang +++ b/resources/assets/mekanism/lang/en_US.lang @@ -260,7 +260,7 @@ tooltip.EliteFactory=The highest tier of the line of Factories, which can !nbe u tooltip.MetallurgicInfuser=A machine used to infuse various materials !ninto (generally) metals to create metal alloys !nand other compounds. tooltip.PurificationChamber=An advanced machine capable of processing !nores into three clumps, serving as the initial !nstage of 300% ore processing. tooltip.EnergizedSmelter=A simple machine that serves as a Mekanism-based !nfurnace that runs off of energy. -tooltip.Teleporter=A machine capable of teleporting players to various !nlocations defined by another teleported. +tooltip.Teleporter=A machine capable of teleporting players to various !nlocations defined by another teleporter. tooltip.ElectricPump=An advanced pump capable of pumping out an entire !nlava lake. tooltip.ElectricChest=A portable, 54-slot chest that uses energy to lock !nitself from others by means of password protection. tooltip.Chargepad=A universal chargepad that can charge any energized item !nfrom any mod. From 54a10af2d72f3a38fc655d242f6f7b5e7db94ec6 Mon Sep 17 00:00:00 2001 From: "Aidan C. Brady" Date: Mon, 9 Dec 2013 17:00:08 -0500 Subject: [PATCH 26/40] A few tiny fixes --- common/mekanism/client/ClientTickHandler.java | 10 ++++++++++ .../mekanism/client/render/RenderTickHandler.java | 14 +++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/common/mekanism/client/ClientTickHandler.java b/common/mekanism/client/ClientTickHandler.java index 33b4dcf5c..ce66f098d 100644 --- a/common/mekanism/client/ClientTickHandler.java +++ b/common/mekanism/client/ClientTickHandler.java @@ -372,6 +372,11 @@ public class ClientTickHandler implements ITickHandler public static boolean isJetpackOn(EntityPlayer player) { + if(player != mc.thePlayer) + { + return Mekanism.jetpackOn.contains(player); + } + ItemStack stack = player.inventory.armorInventory[2]; if(stack != null) @@ -399,6 +404,11 @@ public class ClientTickHandler implements ITickHandler public static boolean isGasMaskOn(EntityPlayer player) { + if(player != mc.thePlayer) + { + return Mekanism.gasmaskOn.contains(player); + } + ItemStack tank = player.inventory.armorInventory[2]; ItemStack mask = player.inventory.armorInventory[3]; diff --git a/common/mekanism/client/render/RenderTickHandler.java b/common/mekanism/client/render/RenderTickHandler.java index 0c9455269..c21aca882 100644 --- a/common/mekanism/client/render/RenderTickHandler.java +++ b/common/mekanism/client/render/RenderTickHandler.java @@ -9,6 +9,7 @@ import mekanism.common.Mekanism; import mekanism.common.item.ItemJetpack; import mekanism.common.item.ItemScubaTank; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiChat; import net.minecraft.client.gui.ScaledResolution; @@ -108,6 +109,13 @@ public class RenderTickHandler implements ITickHandler continue; } + Vector3 playerPos = new Vector3(p); + + if(p != mc.thePlayer) + { + playerPos.translate(new Vector3(0, 1.7, 0)); + } + float random = (rand.nextFloat()-0.5F)*0.1F; Vector3 vLeft = new Vector3(); @@ -138,15 +146,15 @@ public class RenderTickHandler implements ITickHandler mLeft.translate(rLeft); mRight.translate(rRight); - Vector3 v = new Vector3(p).translate(vLeft); + Vector3 v = new Vector3(playerPos).translate(vLeft); spawnAndSetParticle("flame", world, v.x, v.y, v.z, mLeft.x, mLeft.y, mLeft.z); spawnAndSetParticle("smoke", world, v.x, v.y, v.z, mLeft.x, mLeft.y, mLeft.z); - v = new Vector3(p).translate(vRight); + v = new Vector3(playerPos).translate(vRight); spawnAndSetParticle("flame", world, v.x, v.y, v.z, mRight.x, mRight.y, mRight.z); spawnAndSetParticle("smoke", world, v.x, v.y, v.z, mRight.x, mRight.y, mRight.z); - v = new Vector3(p).translate(vCenter); + v = new Vector3(playerPos).translate(vCenter); spawnAndSetParticle("flame", world, v.x, v.y, v.z, mCenter.x, mCenter.y, mCenter.z); spawnAndSetParticle("smoke", world, v.x, v.y, v.z, mCenter.x, mCenter.y, mCenter.z); } From 7506b8fed82ce61c26cfa9974df0f3b5432e9eb0 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Mon, 9 Dec 2013 17:00:21 -0500 Subject: [PATCH 27/40] Fix particles --- common/mekanism/client/render/RenderTickHandler.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/mekanism/client/render/RenderTickHandler.java b/common/mekanism/client/render/RenderTickHandler.java index 0c9455269..4b5f4ebf9 100644 --- a/common/mekanism/client/render/RenderTickHandler.java +++ b/common/mekanism/client/render/RenderTickHandler.java @@ -166,8 +166,11 @@ public class RenderTickHandler implements ITickHandler fx = new EntitySmokeFX(world, x, y, z, velX, velY, velZ); } + fx.prevPosX = fx.posX = x; + fx.prevPosY = fx.posY = y; + fx.prevPosZ = fx.posZ = z; + mc.effectRenderer.addEffect(fx); - fx.onUpdate(); } @Override From 26f0f83574e7fc3d8558c9141d48f30205da3257 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Mon, 9 Dec 2013 17:08:47 -0500 Subject: [PATCH 28/40] Work on initial data system for jetpacks/gasmasks --- common/mekanism/client/ClientTickHandler.java | 8 ++-- .../mekanism/common/CommonPlayerTracker.java | 26 ++++++++++- .../common/network/PacketJetpackData.java | 44 +++++++++++++++---- .../common/network/PacketScubaTankData.java | 44 +++++++++++++++---- 4 files changed, 99 insertions(+), 23 deletions(-) diff --git a/common/mekanism/client/ClientTickHandler.java b/common/mekanism/client/ClientTickHandler.java index ce66f098d..99357cbba 100644 --- a/common/mekanism/client/ClientTickHandler.java +++ b/common/mekanism/client/ClientTickHandler.java @@ -27,7 +27,7 @@ import mekanism.common.network.PacketConfiguratorState; import mekanism.common.network.PacketElectricBowState; import mekanism.common.network.PacketJetpackData; import mekanism.common.network.PacketWalkieTalkieState; -import mekanism.common.network.PacketJetpackData.PacketType; +import mekanism.common.network.PacketJetpackData.JetpackPacket; import mekanism.common.network.PacketScubaTankData; import mekanism.common.util.MekanismUtils; import mekanism.common.util.StackUtils; @@ -255,7 +255,7 @@ public class ClientTickHandler implements ITickHandler if(!lastTickUpdate) { ((ItemJetpack)jetpack.getItem()).incrementMode(jetpack); - PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.MODE)); + PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(JetpackPacket.MODE)); Minecraft.getMinecraft().sndManager.playSoundFX("mekanism:etc.Hydraulic", 1.0F, 1.0F); lastTickUpdate = true; } @@ -279,7 +279,7 @@ public class ClientTickHandler implements ITickHandler Mekanism.jetpackOn.remove(mc.thePlayer); } - PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(PacketType.UPDATE, mc.thePlayer, isJetpackOn(mc.thePlayer))); + PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(JetpackPacket.UPDATE, mc.thePlayer, isJetpackOn(mc.thePlayer))); } if(Mekanism.gasmaskOn.contains(mc.thePlayer) != isGasMaskOn(mc.thePlayer)) @@ -292,7 +292,7 @@ public class ClientTickHandler implements ITickHandler Mekanism.gasmaskOn.remove(mc.thePlayer); } - PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(PacketType.UPDATE, mc.thePlayer, isGasMaskOn(mc.thePlayer))); + PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(JetpackPacket.UPDATE, mc.thePlayer, isGasMaskOn(mc.thePlayer))); } if(MekanismClient.audioHandler != null) diff --git a/common/mekanism/common/CommonPlayerTracker.java b/common/mekanism/common/CommonPlayerTracker.java index 376c64994..bc84a32f9 100644 --- a/common/mekanism/common/CommonPlayerTracker.java +++ b/common/mekanism/common/CommonPlayerTracker.java @@ -1,22 +1,46 @@ package mekanism.common; +import mekanism.common.PacketHandler.Transmission; +import mekanism.common.network.PacketJetpackData; +import mekanism.common.network.PacketJetpackData.JetpackPacket; +import mekanism.common.network.PacketScubaTankData; +import mekanism.common.network.PacketScubaTankData.ScubaTankPacket; import net.minecraft.entity.player.EntityPlayer; import cpw.mods.fml.common.IPlayerTracker; public class CommonPlayerTracker implements IPlayerTracker { @Override - public void onPlayerLogin(EntityPlayer player) {} + public void onPlayerLogin(EntityPlayer player) + { + if(!player.worldObj.isRemote) + { + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketJetpackData().setParams(JetpackPacket.FULL), player.worldObj.provider.dimensionId); + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketScubaTankData().setParams(ScubaTankPacket.FULL), player.worldObj.provider.dimensionId); + } + } @Override public void onPlayerLogout(EntityPlayer player) { Mekanism.jetpackOn.remove(player); + + if(!player.worldObj.isRemote) + { + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketJetpackData().setParams(JetpackPacket.FULL), player.worldObj.provider.dimensionId); + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketScubaTankData().setParams(ScubaTankPacket.FULL), player.worldObj.provider.dimensionId); + } } @Override public void onPlayerChangedDimension(EntityPlayer player) { Mekanism.jetpackOn.remove(player); + + if(!player.worldObj.isRemote) + { + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketJetpackData().setParams(JetpackPacket.FULL), player.worldObj.provider.dimensionId); + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketScubaTankData().setParams(ScubaTankPacket.FULL), player.worldObj.provider.dimensionId); + } } @Override diff --git a/common/mekanism/common/network/PacketJetpackData.java b/common/mekanism/common/network/PacketJetpackData.java index a1530c845..00a0025ba 100644 --- a/common/mekanism/common/network/PacketJetpackData.java +++ b/common/mekanism/common/network/PacketJetpackData.java @@ -14,7 +14,7 @@ import com.google.common.io.ByteArrayDataInput; public class PacketJetpackData implements IMekanismPacket { - public PacketType packetType; + public JetpackPacket packetType; public EntityPlayer updatePlayer; public boolean value; @@ -28,9 +28,9 @@ public class PacketJetpackData implements IMekanismPacket @Override public IMekanismPacket setParams(Object... data) { - packetType = (PacketType)data[0]; + packetType = (JetpackPacket)data[0]; - if(packetType == PacketType.UPDATE) + if(packetType == JetpackPacket.UPDATE) { updatePlayer = (EntityPlayer)data[1]; value = (Boolean)data[2]; @@ -42,9 +42,25 @@ public class PacketJetpackData implements IMekanismPacket @Override public void read(ByteArrayDataInput dataStream, EntityPlayer player, World world) throws Exception { - packetType = PacketType.values()[dataStream.readInt()]; + packetType = JetpackPacket.values()[dataStream.readInt()]; - if(packetType == PacketType.UPDATE) + if(packetType == JetpackPacket.FULL) + { + Mekanism.jetpackOn.clear(); + + int amount = dataStream.readInt(); + + for(int i = 0; i < amount; i++) + { + EntityPlayer p = world.getPlayerEntityByName(dataStream.readUTF()); + + if(p != null) + { + Mekanism.jetpackOn.add(p); + } + } + } + else if(packetType == JetpackPacket.UPDATE) { String username = dataStream.readUTF(); boolean value = dataStream.readBoolean(); @@ -63,11 +79,11 @@ public class PacketJetpackData implements IMekanismPacket if(!world.isRemote) { - PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketJetpackData().setParams(PacketType.UPDATE, p, value), world.provider.dimensionId); + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketJetpackData().setParams(JetpackPacket.UPDATE, p, value), world.provider.dimensionId); } } } - else if(packetType == PacketType.MODE) + else if(packetType == JetpackPacket.MODE) { ItemStack stack = player.getCurrentItemOrArmor(3); @@ -83,16 +99,26 @@ public class PacketJetpackData implements IMekanismPacket { dataStream.writeInt(packetType.ordinal()); - if(packetType == PacketType.UPDATE) + if(packetType == JetpackPacket.UPDATE) { dataStream.writeUTF(updatePlayer.username); dataStream.writeBoolean(value); } + else if(packetType == JetpackPacket.FULL) + { + dataStream.writeInt(Mekanism.jetpackOn.size()); + + for(EntityPlayer player : Mekanism.jetpackOn) + { + dataStream.writeUTF(player.username); + } + } } - public static enum PacketType + public static enum JetpackPacket { UPDATE, + FULL, MODE; } } diff --git a/common/mekanism/common/network/PacketScubaTankData.java b/common/mekanism/common/network/PacketScubaTankData.java index 84f2abc93..d6dc2b9b6 100644 --- a/common/mekanism/common/network/PacketScubaTankData.java +++ b/common/mekanism/common/network/PacketScubaTankData.java @@ -14,7 +14,7 @@ import com.google.common.io.ByteArrayDataInput; public class PacketScubaTankData implements IMekanismPacket { - public PacketType packetType; + public ScubaTankPacket packetType; public EntityPlayer updatePlayer; public boolean value; @@ -28,9 +28,9 @@ public class PacketScubaTankData implements IMekanismPacket @Override public IMekanismPacket setParams(Object... data) { - packetType = (PacketType)data[0]; + packetType = (ScubaTankPacket)data[0]; - if(packetType == PacketType.UPDATE) + if(packetType == ScubaTankPacket.UPDATE) { updatePlayer = (EntityPlayer)data[1]; value = (Boolean)data[2]; @@ -42,9 +42,25 @@ public class PacketScubaTankData implements IMekanismPacket @Override public void read(ByteArrayDataInput dataStream, EntityPlayer player, World world) throws Exception { - packetType = PacketType.values()[dataStream.readInt()]; + packetType = ScubaTankPacket.values()[dataStream.readInt()]; - if(packetType == PacketType.UPDATE) + if(packetType == ScubaTankPacket.FULL) + { + Mekanism.gasmaskOn.clear(); + + int amount = dataStream.readInt(); + + for(int i = 0; i < amount; i++) + { + EntityPlayer p = world.getPlayerEntityByName(dataStream.readUTF()); + + if(p != null) + { + Mekanism.gasmaskOn.add(p); + } + } + } + else if(packetType == ScubaTankPacket.UPDATE) { String username = dataStream.readUTF(); boolean value = dataStream.readBoolean(); @@ -63,11 +79,11 @@ public class PacketScubaTankData implements IMekanismPacket if(!world.isRemote) { - PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketScubaTankData().setParams(PacketType.UPDATE, p, value), world.provider.dimensionId); + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketScubaTankData().setParams(ScubaTankPacket.UPDATE, p, value), world.provider.dimensionId); } } } - else if(packetType == PacketType.MODE) + else if(packetType == ScubaTankPacket.MODE) { ItemStack stack = player.getCurrentItemOrArmor(3); @@ -83,16 +99,26 @@ public class PacketScubaTankData implements IMekanismPacket { dataStream.writeInt(packetType.ordinal()); - if(packetType == PacketType.UPDATE) + if(packetType == ScubaTankPacket.UPDATE) { dataStream.writeUTF(updatePlayer.username); dataStream.writeBoolean(value); } + else if(packetType == ScubaTankPacket.FULL) + { + dataStream.writeInt(Mekanism.gasmaskOn.size()); + + for(EntityPlayer player : Mekanism.gasmaskOn) + { + dataStream.writeUTF(player.username); + } + } } - public static enum PacketType + public static enum ScubaTankPacket { UPDATE, + FULL, MODE; } } From ac31fc2b4eb8cd8870fad27a0031ba76677db8af Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Mon, 9 Dec 2013 17:34:53 -0500 Subject: [PATCH 29/40] More work on networking system, unstable --- common/mekanism/client/ClientTickHandler.java | 38 ++++++++++------- .../client/render/RenderTickHandler.java | 6 ++- common/mekanism/common/Mekanism.java | 4 +- .../common/network/PacketJetpackData.java | 42 +++++++------------ .../common/network/PacketScubaTankData.java | 42 +++++++------------ 5 files changed, 60 insertions(+), 72 deletions(-) diff --git a/common/mekanism/client/ClientTickHandler.java b/common/mekanism/client/ClientTickHandler.java index 99357cbba..a024245f2 100644 --- a/common/mekanism/client/ClientTickHandler.java +++ b/common/mekanism/client/ClientTickHandler.java @@ -269,47 +269,53 @@ public class ClientTickHandler implements ITickHandler } } - if(Mekanism.jetpackOn.contains(mc.thePlayer) != isJetpackOn(mc.thePlayer)) + if(Mekanism.jetpackOn.contains(mc.thePlayer.username) != isJetpackOn(mc.thePlayer)) { if(isJetpackOn(mc.thePlayer)) { - Mekanism.jetpackOn.add(mc.thePlayer); + Mekanism.jetpackOn.add(mc.thePlayer.username); } else { - Mekanism.jetpackOn.remove(mc.thePlayer); + Mekanism.jetpackOn.remove(mc.thePlayer.username); } - PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(JetpackPacket.UPDATE, mc.thePlayer, isJetpackOn(mc.thePlayer))); + PacketHandler.sendPacket(Transmission.SERVER, new PacketJetpackData().setParams(JetpackPacket.UPDATE, mc.thePlayer.username, isJetpackOn(mc.thePlayer))); } - if(Mekanism.gasmaskOn.contains(mc.thePlayer) != isGasMaskOn(mc.thePlayer)) + if(Mekanism.gasmaskOn.contains(mc.thePlayer.username) != isGasMaskOn(mc.thePlayer)) { if(isGasMaskOn(mc.thePlayer) && mc.currentScreen == null) { - Mekanism.gasmaskOn.add(mc.thePlayer); + Mekanism.gasmaskOn.add(mc.thePlayer.username); } else { - Mekanism.gasmaskOn.remove(mc.thePlayer); + Mekanism.gasmaskOn.remove(mc.thePlayer.username); } - PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(JetpackPacket.UPDATE, mc.thePlayer, isGasMaskOn(mc.thePlayer))); + PacketHandler.sendPacket(Transmission.SERVER, new PacketScubaTankData().setParams(JetpackPacket.UPDATE, mc.thePlayer.username, isGasMaskOn(mc.thePlayer))); } if(MekanismClient.audioHandler != null) { - for(EntityPlayer entry : Mekanism.jetpackOn) + for(String username : Mekanism.jetpackOn) { - if(MekanismClient.audioHandler.getFrom(entry) == null) + if(mc.theWorld.getPlayerEntityByName(username) != null) { - new JetpackSound(MekanismClient.audioHandler.getIdentifier(), entry); + if(MekanismClient.audioHandler.getFrom(mc.theWorld.getPlayerEntityByName(username)) == null) + { + new JetpackSound(MekanismClient.audioHandler.getIdentifier(), mc.theWorld.getPlayerEntityByName(username)); + } } } - for(EntityPlayer entry : Mekanism.gasmaskOn) + for(String username : Mekanism.gasmaskOn) { - if(MekanismClient.audioHandler.getFrom(entry) == null) + if(mc.theWorld.getPlayerEntityByName(username) != null) { - new GasMaskSound(MekanismClient.audioHandler.getIdentifier(), entry); + if(MekanismClient.audioHandler.getFrom(mc.theWorld.getPlayerEntityByName(username)) == null) + { + new GasMaskSound(MekanismClient.audioHandler.getIdentifier(), mc.theWorld.getPlayerEntityByName(username)); + } } } } @@ -374,7 +380,7 @@ public class ClientTickHandler implements ITickHandler { if(player != mc.thePlayer) { - return Mekanism.jetpackOn.contains(player); + return Mekanism.jetpackOn.contains(player.username); } ItemStack stack = player.inventory.armorInventory[2]; @@ -406,7 +412,7 @@ public class ClientTickHandler implements ITickHandler { if(player != mc.thePlayer) { - return Mekanism.gasmaskOn.contains(player); + return Mekanism.gasmaskOn.contains(player.username); } ItemStack tank = player.inventory.armorInventory[2]; diff --git a/common/mekanism/client/render/RenderTickHandler.java b/common/mekanism/client/render/RenderTickHandler.java index a766659f3..0195bd909 100644 --- a/common/mekanism/client/render/RenderTickHandler.java +++ b/common/mekanism/client/render/RenderTickHandler.java @@ -102,9 +102,11 @@ public class RenderTickHandler implements ITickHandler } } - for(EntityPlayer p : Mekanism.jetpackOn) + for(String s : Mekanism.jetpackOn) { - if(p.getDistance(player.posX, player.posY, player.posZ) > 40) + EntityPlayer p = mc.theWorld.getPlayerEntityByName(s); + + if(p == null) { continue; } diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index 0b0ab8866..ced1e4958 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -184,8 +184,8 @@ public class Mekanism public static KeySync keyMap = new KeySync(); - public static Set jetpackOn = new HashSet(); - public static Set gasmaskOn = new HashSet(); + public static Set jetpackOn = new HashSet(); + public static Set gasmaskOn = new HashSet(); public static Set ic2Registered = new HashSet(); diff --git a/common/mekanism/common/network/PacketJetpackData.java b/common/mekanism/common/network/PacketJetpackData.java index 00a0025ba..bb31b3073 100644 --- a/common/mekanism/common/network/PacketJetpackData.java +++ b/common/mekanism/common/network/PacketJetpackData.java @@ -16,7 +16,7 @@ public class PacketJetpackData implements IMekanismPacket { public JetpackPacket packetType; - public EntityPlayer updatePlayer; + public String username; public boolean value; @Override @@ -32,7 +32,7 @@ public class PacketJetpackData implements IMekanismPacket if(packetType == JetpackPacket.UPDATE) { - updatePlayer = (EntityPlayer)data[1]; + username = (String)data[1]; value = (Boolean)data[2]; } @@ -52,12 +52,7 @@ public class PacketJetpackData implements IMekanismPacket for(int i = 0; i < amount; i++) { - EntityPlayer p = world.getPlayerEntityByName(dataStream.readUTF()); - - if(p != null) - { - Mekanism.jetpackOn.add(p); - } + Mekanism.jetpackOn.add(dataStream.readUTF()); } } else if(packetType == JetpackPacket.UPDATE) @@ -65,22 +60,17 @@ public class PacketJetpackData implements IMekanismPacket String username = dataStream.readUTF(); boolean value = dataStream.readBoolean(); - EntityPlayer p = world.getPlayerEntityByName(username); - - if(p != null) + if(value) { - if(value) - { - Mekanism.jetpackOn.add(p); - } - else { - Mekanism.jetpackOn.remove(p); - } - - if(!world.isRemote) - { - PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketJetpackData().setParams(JetpackPacket.UPDATE, p, value), world.provider.dimensionId); - } + Mekanism.jetpackOn.add(username); + } + else { + Mekanism.jetpackOn.remove(username); + } + + if(!world.isRemote) + { + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketJetpackData().setParams(JetpackPacket.UPDATE, username, value), world.provider.dimensionId); } } else if(packetType == JetpackPacket.MODE) @@ -101,16 +91,16 @@ public class PacketJetpackData implements IMekanismPacket if(packetType == JetpackPacket.UPDATE) { - dataStream.writeUTF(updatePlayer.username); + dataStream.writeUTF(username); dataStream.writeBoolean(value); } else if(packetType == JetpackPacket.FULL) { dataStream.writeInt(Mekanism.jetpackOn.size()); - for(EntityPlayer player : Mekanism.jetpackOn) + for(String username : Mekanism.jetpackOn) { - dataStream.writeUTF(player.username); + dataStream.writeUTF(username); } } } diff --git a/common/mekanism/common/network/PacketScubaTankData.java b/common/mekanism/common/network/PacketScubaTankData.java index d6dc2b9b6..78df284e2 100644 --- a/common/mekanism/common/network/PacketScubaTankData.java +++ b/common/mekanism/common/network/PacketScubaTankData.java @@ -16,7 +16,7 @@ public class PacketScubaTankData implements IMekanismPacket { public ScubaTankPacket packetType; - public EntityPlayer updatePlayer; + public String username; public boolean value; @Override @@ -32,7 +32,7 @@ public class PacketScubaTankData implements IMekanismPacket if(packetType == ScubaTankPacket.UPDATE) { - updatePlayer = (EntityPlayer)data[1]; + username = (String)data[1]; value = (Boolean)data[2]; } @@ -52,12 +52,7 @@ public class PacketScubaTankData implements IMekanismPacket for(int i = 0; i < amount; i++) { - EntityPlayer p = world.getPlayerEntityByName(dataStream.readUTF()); - - if(p != null) - { - Mekanism.gasmaskOn.add(p); - } + Mekanism.gasmaskOn.add(dataStream.readUTF()); } } else if(packetType == ScubaTankPacket.UPDATE) @@ -65,22 +60,17 @@ public class PacketScubaTankData implements IMekanismPacket String username = dataStream.readUTF(); boolean value = dataStream.readBoolean(); - EntityPlayer p = world.getPlayerEntityByName(username); - - if(p != null) + if(value) { - if(value) - { - Mekanism.gasmaskOn.add(p); - } - else { - Mekanism.gasmaskOn.remove(p); - } - - if(!world.isRemote) - { - PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketScubaTankData().setParams(ScubaTankPacket.UPDATE, p, value), world.provider.dimensionId); - } + Mekanism.gasmaskOn.add(username); + } + else { + Mekanism.gasmaskOn.remove(username); + } + + if(!world.isRemote) + { + PacketHandler.sendPacket(Transmission.CLIENTS_DIM, new PacketScubaTankData().setParams(ScubaTankPacket.UPDATE, username, value), world.provider.dimensionId); } } else if(packetType == ScubaTankPacket.MODE) @@ -101,16 +91,16 @@ public class PacketScubaTankData implements IMekanismPacket if(packetType == ScubaTankPacket.UPDATE) { - dataStream.writeUTF(updatePlayer.username); + dataStream.writeUTF(username); dataStream.writeBoolean(value); } else if(packetType == ScubaTankPacket.FULL) { dataStream.writeInt(Mekanism.gasmaskOn.size()); - for(EntityPlayer player : Mekanism.gasmaskOn) + for(String username : Mekanism.gasmaskOn) { - dataStream.writeUTF(player.username); + dataStream.writeUTF(username); } } } From add3cf0bf698aeca9f5075d4096665eceb2016c9 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Mon, 9 Dec 2013 17:54:59 -0500 Subject: [PATCH 30/40] Bug fixes! --- .../client/ClientConnectionHandler.java | 27 ++++--------------- .../mekanism/client/ClientPlayerTracker.java | 18 +++++++++++++ common/mekanism/client/MekanismClient.java | 3 +++ 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/common/mekanism/client/ClientConnectionHandler.java b/common/mekanism/client/ClientConnectionHandler.java index 36eb12f1c..3602f9859 100644 --- a/common/mekanism/client/ClientConnectionHandler.java +++ b/common/mekanism/client/ClientConnectionHandler.java @@ -17,8 +17,6 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) public class ClientConnectionHandler implements IConnectionHandler { - public VoiceClient voiceClient; - @Override public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager) {} @@ -35,8 +33,8 @@ public class ClientConnectionHandler implements IConnectionHandler if(Mekanism.voiceServerEnabled) { try { - voiceClient = new VoiceClient(server, Mekanism.VOICE_PORT); - voiceClient.start(); + MekanismClient.voiceClient = new VoiceClient(server, Mekanism.VOICE_PORT); + MekanismClient.voiceClient.start(); } catch(Exception e) {} } } @@ -48,29 +46,14 @@ public class ClientConnectionHandler implements IConnectionHandler if(Mekanism.voiceServerEnabled) { try { - voiceClient = new VoiceClient(InetAddress.getLocalHost().getHostAddress(), Mekanism.VOICE_PORT); - voiceClient.start(); + MekanismClient.voiceClient = new VoiceClient(InetAddress.getLocalHost().getHostAddress(), Mekanism.VOICE_PORT); + MekanismClient.voiceClient.start(); } catch(Exception e) {} } } @Override - public void connectionClosed(INetworkManager manager) - { - if(Mekanism.voiceServerEnabled) - { - if(voiceClient != null) - { - voiceClient.disconnect(); - voiceClient = null; - } - } - - ClientTickHandler.tickingSet.clear(); - Mekanism.jetpackOn.clear(); - Mekanism.gasmaskOn.clear(); - Mekanism.proxy.unloadSoundHandler(); - } + public void connectionClosed(INetworkManager manager) {} @Override public void clientLoggedIn(NetHandler clientHandler, INetworkManager manager, Packet1Login login) {} diff --git a/common/mekanism/client/ClientPlayerTracker.java b/common/mekanism/client/ClientPlayerTracker.java index 1124c9ad3..75863eb04 100644 --- a/common/mekanism/client/ClientPlayerTracker.java +++ b/common/mekanism/client/ClientPlayerTracker.java @@ -1,6 +1,7 @@ package mekanism.client; import mekanism.common.Mekanism; +import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import cpw.mods.fml.common.IPlayerTracker; @@ -13,6 +14,23 @@ public class ClientPlayerTracker implements IPlayerTracker public void onPlayerLogout(EntityPlayer player) { Mekanism.jetpackOn.remove(player); + + if(player.username.equals(Minecraft.getMinecraft().thePlayer.username)) + { + if(Mekanism.voiceServerEnabled) + { + if(MekanismClient.voiceClient != null) + { + MekanismClient.voiceClient.disconnect(); + MekanismClient.voiceClient = null; + } + } + + ClientTickHandler.tickingSet.clear(); + Mekanism.jetpackOn.clear(); + Mekanism.gasmaskOn.clear(); + Mekanism.proxy.unloadSoundHandler(); + } } @Override diff --git a/common/mekanism/client/MekanismClient.java b/common/mekanism/client/MekanismClient.java index b2431b9a7..2cf3a4e44 100644 --- a/common/mekanism/client/MekanismClient.java +++ b/common/mekanism/client/MekanismClient.java @@ -1,6 +1,7 @@ package mekanism.client; import mekanism.client.sound.SoundHandler; +import mekanism.client.voice.VoiceClient; import mekanism.common.Mekanism; import mekanism.common.PacketHandler; import mekanism.common.PacketHandler.Transmission; @@ -18,6 +19,8 @@ public class MekanismClient extends Mekanism /** The main SoundHandler instance that is used by all audio sources */ public static SoundHandler audioHandler; + public static VoiceClient voiceClient; + //General Configuration public static boolean enableSounds = true; public static boolean fancyUniversalCableRender = true; From 3c4d776e24ba8c8c8115274df0afc2a78314d367 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Mon, 9 Dec 2013 18:30:50 -0500 Subject: [PATCH 31/40] Added lead ore processing --- common/mekanism/common/Mekanism.java | 32 +++++++++++++----- common/mekanism/common/item/ItemClump.java | 6 ++-- .../mekanism/common/item/ItemDirtyDust.java | 6 ++-- common/mekanism/common/item/ItemDust.java | 7 ++-- resources/assets/mekanism/lang/en_US.lang | 3 ++ .../mekanism/textures/items/DirtyLeadDust.png | Bin 0 -> 1433 bytes .../mekanism/textures/items/LeadClump.png | Bin 0 -> 1695 bytes .../mekanism/textures/items/LeadDust.png | Bin 0 -> 1449 bytes 8 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 resources/assets/mekanism/textures/items/DirtyLeadDust.png create mode 100644 resources/assets/mekanism/textures/items/LeadClump.png create mode 100644 resources/assets/mekanism/textures/items/LeadDust.png diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index ced1e4958..6613333ac 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -664,6 +664,7 @@ public class Mekanism OreDictionary.registerOre("dustCopper", new ItemStack(Dust, 1, 6)); OreDictionary.registerOre("dustTin", new ItemStack(Dust, 1, 7)); OreDictionary.registerOre("dustSilver", new ItemStack(Dust, 1, 8)); + OreDictionary.registerOre("dustLead", new ItemStack(Dust, 1, 9)); OreDictionary.registerOre("ingotRefinedObsidian", new ItemStack(Ingot, 1, 0)); OreDictionary.registerOre("ingotOsmium", new ItemStack(Ingot, 1, 1)); @@ -689,6 +690,7 @@ public class Mekanism OreDictionary.registerOre("dustDirtyTin", new ItemStack(DirtyDust, 1, 4)); OreDictionary.registerOre("dustDirtySilver", new ItemStack(DirtyDust, 1, 5)); OreDictionary.registerOre("dustDirtyObsidian", new ItemStack(DirtyDust, 1, 6)); + OreDictionary.registerOre("dustDirtyLead", new ItemStack(DirtyDust, 1, 7)); //for RailCraft/IC2. OreDictionary.registerOre("dustObsidian", new ItemStack(DirtyDust, 1, 6)); @@ -700,6 +702,7 @@ public class Mekanism OreDictionary.registerOre("clumpTin", new ItemStack(Clump, 1, 4)); OreDictionary.registerOre("clumpSilver", new ItemStack(Clump, 1, 5)); OreDictionary.registerOre("clumpObsidian", new ItemStack(Clump, 1, 6)); + OreDictionary.registerOre("clumpLead", new ItemStack(Clump, 1, 7)); OreDictionary.registerOre("oreOsmium", new ItemStack(OreBlock, 1, 0)); OreDictionary.registerOre("oreCopper", new ItemStack(OreBlock, 1, 1)); @@ -784,6 +787,11 @@ public class Mekanism RecipeHandler.addCrusherRecipe(MekanismUtils.size(ore, 1), new ItemStack(DirtyDust, 1, 6)); } + for(ItemStack ore : OreDictionary.getOres("clumpLead")) + { + RecipeHandler.addCrusherRecipe(MekanismUtils.size(ore, 1), new ItemStack(DirtyDust, 1, 7)); + } + for(ItemStack ore : OreDictionary.getOres("dustDirtyIron")) { RecipeHandler.addEnrichmentChamberRecipe(MekanismUtils.size(ore, 1), new ItemStack(Dust, 1, 0)); @@ -814,6 +822,11 @@ public class Mekanism RecipeHandler.addEnrichmentChamberRecipe(MekanismUtils.size(ore, 1), new ItemStack(Dust, 1, 8)); } + for(ItemStack ore : OreDictionary.getOres("dustDirtyLead")) + { + RecipeHandler.addEnrichmentChamberRecipe(MekanismUtils.size(ore, 1), new ItemStack(Dust, 1, 9)); + } + for(ItemStack ore : OreDictionary.getOres("oreCopper")) { RecipeHandler.addEnrichmentChamberRecipe(MekanismUtils.size(ore, 1), new ItemStack(Dust, 2, 6)); @@ -844,15 +857,22 @@ public class Mekanism RecipeHandler.addPurificationChamberRecipe(new ItemStack(Block.oreGold), new ItemStack(Clump, 3, 1)); } + for(ItemStack ore : OreDictionary.getOres("oreGold")) + { + RecipeHandler.addEnrichmentChamberRecipe(new ItemStack(Block.oreGold), new ItemStack(Dust, 2, 1)); + RecipeHandler.addPurificationChamberRecipe(new ItemStack(Block.oreGold), new ItemStack(Clump, 3, 1)); + } + try { for(ItemStack ore : OreDictionary.getOres("oreLead")) { - RecipeHandler.addEnrichmentChamberRecipe(MekanismUtils.size(ore, 1), MekanismUtils.size(OreDictionary.getOres("dustLead").get(0), 2)); + RecipeHandler.addEnrichmentChamberRecipe(MekanismUtils.size(ore, 1), new ItemStack(Dust, 2, 9)); + RecipeHandler.addPurificationChamberRecipe(MekanismUtils.size(ore, 1), new ItemStack(Clump, 3, 7)); } for(ItemStack ore : OreDictionary.getOres("ingotLead")) { - RecipeHandler.addCrusherRecipe(MekanismUtils.size(ore, 1), MekanismUtils.size(OreDictionary.getOres("dustLead").get(0), 1)); + RecipeHandler.addCrusherRecipe(MekanismUtils.size(ore, 1), new ItemStack(Dust, 1, 9)); } } catch(Exception e) {} @@ -903,15 +923,11 @@ public class Mekanism } catch(Exception e) {} try { - FurnaceRecipes.smelting().addSmelting(Dust.itemID, 6, new ItemStack(Ingot, 1, 5), 0.0F); + FurnaceRecipes.smelting().addSmelting(Dust.itemID, 8, MekanismUtils.size(OreDictionary.getOres("ingotSilver").get(0), 1), 0.0F); } catch(Exception e) {} try { - FurnaceRecipes.smelting().addSmelting(Dust.itemID, 7, new ItemStack(Ingot, 1, 6), 0.0F); - } catch(Exception e) {} - - try { - FurnaceRecipes.smelting().addSmelting(Dust.itemID, 8, MekanismUtils.size(OreDictionary.getOres("ingotSilver").get(0), 1), 1.0F); + FurnaceRecipes.smelting().addSmelting(Dust.itemID, 9, MekanismUtils.size(OreDictionary.getOres("ingotLead").get(0), 1), 0.0F); } catch(Exception e) {} try { diff --git a/common/mekanism/common/item/ItemClump.java b/common/mekanism/common/item/ItemClump.java index 7df17fe54..fd2da0cfd 100644 --- a/common/mekanism/common/item/ItemClump.java +++ b/common/mekanism/common/item/ItemClump.java @@ -13,7 +13,7 @@ public class ItemClump extends ItemMekanism public Icon[] icons = new Icon[256]; public static String[] en_USNames = {"Iron", "Gold", "Osmium", "Copper", "Tin", "Silver", - "Obsidian"}; + "Obsidian", "Lead"}; public ItemClump(int id) { @@ -25,7 +25,7 @@ public class ItemClump extends ItemMekanism @Override public void registerIcons(IconRegister register) { - for(int i = 0; i <= 6; i++) + for(int i = 0; i <= 7; i++) { icons[i] = register.registerIcon("mekanism:" + en_USNames[i] + "Clump"); } @@ -40,7 +40,7 @@ public class ItemClump extends ItemMekanism @Override public void getSubItems(int id, CreativeTabs tabs, List itemList) { - for(int counter = 0; counter <= 6; ++counter) + for(int counter = 0; counter <= 7; ++counter) { itemList.add(new ItemStack(this, 1, counter)); } diff --git a/common/mekanism/common/item/ItemDirtyDust.java b/common/mekanism/common/item/ItemDirtyDust.java index 6ed68799f..e3fc08dbc 100644 --- a/common/mekanism/common/item/ItemDirtyDust.java +++ b/common/mekanism/common/item/ItemDirtyDust.java @@ -13,7 +13,7 @@ public class ItemDirtyDust extends ItemMekanism public Icon[] icons = new Icon[256]; public static String[] en_USNames = {"Iron", "Gold", "Osmium", "Copper", "Tin", "Silver", - "Obsidian"}; + "Obsidian", "Lead"}; public ItemDirtyDust(int id) { @@ -25,7 +25,7 @@ public class ItemDirtyDust extends ItemMekanism @Override public void registerIcons(IconRegister register) { - for(int i = 0; i <= 6; i++) + for(int i = 0; i <= 7; i++) { icons[i] = register.registerIcon("mekanism:Dirty" + en_USNames[i] + "Dust"); } @@ -40,7 +40,7 @@ public class ItemDirtyDust extends ItemMekanism @Override public void getSubItems(int id, CreativeTabs tabs, List itemList) { - for (int counter = 0; counter <= 6; ++counter) + for (int counter = 0; counter <= 7; ++counter) { itemList.add(new ItemStack(this, 1, counter)); } diff --git a/common/mekanism/common/item/ItemDust.java b/common/mekanism/common/item/ItemDust.java index 859c98647..b98390053 100644 --- a/common/mekanism/common/item/ItemDust.java +++ b/common/mekanism/common/item/ItemDust.java @@ -13,7 +13,8 @@ public class ItemDust extends ItemMekanism public Icon[] icons = new Icon[256]; public static String[] en_USNames = {"Iron", "Gold", "Osmium", "Obsidian", "Diamond", "Steel", - "Copper", "Tin", "Silver"}; + "Copper", "Tin", "Silver", + "Lead"}; public ItemDust(int id) { @@ -25,7 +26,7 @@ public class ItemDust extends ItemMekanism @Override public void registerIcons(IconRegister register) { - for(int i = 0; i <= 8; i++) + for(int i = 0; i <= 9; i++) { icons[i] = register.registerIcon("mekanism:" + en_USNames[i] + "Dust"); } @@ -40,7 +41,7 @@ public class ItemDust extends ItemMekanism @Override public void getSubItems(int id, CreativeTabs tabs, List itemList) { - for(int counter = 0; counter <= 8; ++counter) + for(int counter = 0; counter <= 9; ++counter) { itemList.add(new ItemStack(this, 1, counter)); } diff --git a/resources/assets/mekanism/lang/en_US.lang b/resources/assets/mekanism/lang/en_US.lang index b1645b5a7..621faad0c 100644 --- a/resources/assets/mekanism/lang/en_US.lang +++ b/resources/assets/mekanism/lang/en_US.lang @@ -95,6 +95,7 @@ item.steelDust.name=Steel Dust item.copperDust.name=Copper Dust item.tinDust.name=Tin Dust item.silverDust.name=Silver Dust +item.leadDust.name=Lead Dust //Clumps item.ironClump.name=Iron Clump @@ -104,6 +105,7 @@ item.copperClump.name=Copper Clump item.tinClump.name=Tin Clump item.silverClump.name=Silver Clump item.obsidianClump.name=Obsidian Clump +item.leadClump.name=Lead Clump //Dirty Dust item.dirtyIronDust.name=Dirty Iron Dust @@ -113,6 +115,7 @@ item.dirtyCopperDust.name=Dirty Copper Dust item.dirtyTinDust.name=Dirty Tin Dust item.dirtySilverDust.name=Dirty Silver Dust item.dirtyObsidianDust.name=Dirty Obsidian Dust +item.dirtyLeadDust.name=Dirty Lead Dust //Ingots item.obsidianIngot.name=Obsidian Ingot diff --git a/resources/assets/mekanism/textures/items/DirtyLeadDust.png b/resources/assets/mekanism/textures/items/DirtyLeadDust.png new file mode 100644 index 0000000000000000000000000000000000000000..40e31ce1c07979116290843affcd342caa73b013 GIT binary patch literal 1433 zcmV;K1!nq*P)4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH z9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK zVkc9?T=n|PIo~X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1 zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#mZ8eu=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7 zqW-CFs9&fT)ZaU5gc&=gBz-DaCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaER0003nNkl$hIFP1|wJxbx2XEgqjXAeBX`@kpY6t$^f#$ac`2PH< z-W!JNujXp0li0X!m;F=7N8^Qlt2k2DiQjPm@*r3W`TY@z-mV8x*PG%gckQx+oLY9Wd^KPsvl*NfF0KX_1wrc$*394rDR_IRvB~Qc~aRPo&lD zxT5FFmLa)n%7k?Xj2VDjCx#qM#!;hW!EuJPa<#e+u&*KJS(}J;ydrYOSI+_Ee!mh`=9QW+>keej0ak``E>J6PJz6Pcztc34^LzCjV5O+; n2z|7Om~p6e2Utk0|LedDok3(T|GFSf00000NkvXXu0mjf??bjw literal 0 HcmV?d00001 diff --git a/resources/assets/mekanism/textures/items/LeadClump.png b/resources/assets/mekanism/textures/items/LeadClump.png new file mode 100644 index 0000000000000000000000000000000000000000..77ac97addc3baa7ea9cb75c241e8cb93834ec262 GIT binary patch literal 1695 zcmV;Q24MM#P)4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH z9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK zVkc9?T=n|PIo~X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1 zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#mZ8eu=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7 zqW-CFs9&fT)ZaU5gc&=gBz-DaCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaER0006uNkl63(1lH)Qg_UJ%BDDlcQd15o0+IRrJG9n~DzbIz zH0l8WRR6)?UCb?THacUCFTcg&SDd*(=@R&7pOXiWtTZ5Vc=)z*JRW~he^l(l;fIh@ zV}k(T4oYBdbh~eI=4f*gUaB04N)M#qWOFi(NHQm}|Li1OUVL(wfI|KL$BHf8WP8AC z>T7~&wpGK$T%*zFIH%wk9o%DL!0Incz#B|!5;z%dkJO#cahT0U>ztFxx6p3C3MeG9 ziX+DRi=Zq4WmCs%fBWMs=*F^XK6-f?mk>$^aiviqK$m*cxr74tuIEP6>3PhZD}jR& z?@H;cLO@2%k`5^ym~)ygHz33ha_)mN*wd$2c?D@g)n9fJN={~OM7^Z~egJF8SNq(& zp+H&&f+W8uOyvYv;PO{&>gz-{K14cHxAGnECnOa}O26HtI=N<;&uqa=0er~TFh pNT5DZGUmD)yYFtjQ{cZ);5XTo9du-~;M)KI002ovPDHLkV1nC&H2eSn literal 0 HcmV?d00001 diff --git a/resources/assets/mekanism/textures/items/LeadDust.png b/resources/assets/mekanism/textures/items/LeadDust.png new file mode 100644 index 0000000000000000000000000000000000000000..ec2eaec0b2803fa3a1ef75209ebd945c1819ecf9 GIT binary patch literal 1449 zcmV;a1y=frP)4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH z9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK zVkc9?T=n|PIo~X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1 zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#mZ8eu=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7 zqW-CFs9&fT)ZaU5gc&=gBz-DaCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaER0003%Nkl(#`Xr-Qhja84k$2XL+(;~a;_za6)h(hFWau<|;{E&=v+qtTb5 zPp426GTMoblbka@djyP=OZG37qME>RF_t0ixE+inKl>es8tY2T#W{hSbAZZF&IMxQ zt4GRG_B+Wq=Zt5c0F|Pe2zfNgG4oL81Slle_a$%v&3su*JTCaT00000NkvXXu0mjf DDvi66 literal 0 HcmV?d00001 From 250ddadcf0dc5c6aab1fa2529d3fdf5a116bf3ed Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Mon, 9 Dec 2013 20:52:49 -0500 Subject: [PATCH 32/40] Dictionary! :) --- common/mekanism/client/ClientProxy.java | 3 + common/mekanism/client/gui/GuiDictionary.java | 155 ++++++++++++++++++ common/mekanism/common/CommonProxy.java | 3 + common/mekanism/common/Mekanism.java | 11 +- .../container/ContainerDictionary.java | 85 ++++++++++ .../mekanism/common/item/ItemDictionary.java | 63 +++++++ .../tileentity/TileEntityDigitalMiner.java | 2 +- resources/assets/mekanism/gui/GuiCrusher.png | Bin 3275 -> 4537 bytes .../assets/mekanism/gui/GuiDictionary.png | Bin 0 -> 3402 bytes resources/assets/mekanism/lang/en_US.lang | 4 + .../mekanism/textures/items/Dictionary.png | Bin 0 -> 1546 bytes 11 files changed, 322 insertions(+), 4 deletions(-) create mode 100644 common/mekanism/client/gui/GuiDictionary.java create mode 100644 common/mekanism/common/inventory/container/ContainerDictionary.java create mode 100644 common/mekanism/common/item/ItemDictionary.java create mode 100644 resources/assets/mekanism/gui/GuiDictionary.png create mode 100644 resources/assets/mekanism/textures/items/Dictionary.png diff --git a/common/mekanism/client/ClientProxy.java b/common/mekanism/client/ClientProxy.java index 0228c7fd4..9d43d2778 100644 --- a/common/mekanism/client/ClientProxy.java +++ b/common/mekanism/client/ClientProxy.java @@ -8,6 +8,7 @@ import mekanism.client.gui.GuiCombiner; import mekanism.client.gui.GuiConfiguration; import mekanism.client.gui.GuiCredits; import mekanism.client.gui.GuiCrusher; +import mekanism.client.gui.GuiDictionary; import mekanism.client.gui.GuiDigitalMiner; import mekanism.client.gui.GuiDynamicTank; import mekanism.client.gui.GuiElectricChest; @@ -296,6 +297,8 @@ public class ClientProxy extends CommonProxy switch(ID) { + case 0: + return new GuiDictionary(player.inventory); case 1: return new GuiCredits(); case 2: diff --git a/common/mekanism/client/gui/GuiDictionary.java b/common/mekanism/client/gui/GuiDictionary.java new file mode 100644 index 000000000..6fa10d839 --- /dev/null +++ b/common/mekanism/client/gui/GuiDictionary.java @@ -0,0 +1,155 @@ +package mekanism.client.gui; + +import mekanism.common.inventory.container.ContainerDictionary; +import mekanism.common.util.MekanismUtils; +import mekanism.common.util.MekanismUtils.ResourceType; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; + +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; + +public class GuiDictionary extends GuiMekanism +{ + public ItemStack itemType; + + public String oreDictName; + + public GuiDictionary(InventoryPlayer inventory) + { + super(new ContainerDictionary(inventory)); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) + { + int xAxis = (mouseX - (width - xSize) / 2); + int yAxis = (mouseY - (height - ySize) / 2); + + fontRenderer.drawString(MekanismUtils.localize("item.Dictionary.name"), 64, 5, 0x404040); + fontRenderer.drawString(MekanismUtils.localize("container.inventory"), 8, ySize - 96 + 2, 0x404040); + + if(itemType != null) + { + if(oreDictName != null && !oreDictName.isEmpty()) + { + fontRenderer.drawString(MekanismUtils.localize("gui.dictionary.key") + ": " + oreDictName, 9, 57, 0x00CD00); + } + else { + fontRenderer.drawString(MekanismUtils.localize("gui.dictionary.noKey"), 9, 57, 0x00CD00); + } + } + + if(itemType != null) + { + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_LIGHTING); + itemRenderer.renderItemAndEffectIntoGUI(fontRenderer, mc.getTextureManager(), itemType, 80, 23); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); + } + + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float partialTick, int mouseX, int mouseY) + { + super.drawGuiContainerBackgroundLayer(partialTick, mouseX, mouseY); + + mc.renderEngine.bindTexture(MekanismUtils.getResource(ResourceType.GUI, "GuiDictionary.png")); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + int guiWidth = (width - xSize) / 2; + int guiHeight = (height - ySize) / 2; + drawTexturedModalRect(guiWidth, guiHeight, 0, 0, xSize, ySize); + + int xAxis = mouseX - guiWidth; + int yAxis = mouseY - guiHeight; + + if(xAxis >= 80 && xAxis <= 96 && yAxis >= 23 && yAxis <= 39) + { + GL11.glPushMatrix(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_DEPTH_TEST); + + int x = guiWidth + 80; + int y = guiHeight + 23; + drawGradientRect(x, y, x + 16, y + 16, -2130706433, -2130706433); + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL11.glPopMatrix(); + } + } + + @Override + public boolean doesGuiPauseGame() + { + return false; + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int button) + { + int xAxis = (mouseX - (width - xSize) / 2); + int yAxis = (mouseY - (height - ySize) / 2); + + if(button == 0) + { + if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) + { + Slot hovering = null; + + for(int i = 0; i < inventorySlots.inventorySlots.size(); i++) + { + Slot slot = (Slot)inventorySlots.inventorySlots.get(i); + + if(isMouseOverSlot(slot, mouseX, mouseY)) + { + hovering = slot; + break; + } + } + + if(hovering != null) + { + ItemStack stack = hovering.getStack(); + + if(stack != null) + { + itemType = stack.copy(); + itemType.stackSize = 1; + + oreDictName = MekanismUtils.getOreDictName(itemType); + mc.sndManager.playSoundFX("random.click", 1.0F, 1.0F); + + return; + } + } + } + + if(xAxis >= 80 && xAxis <= 96 && yAxis >= 23 && yAxis <= 39) + { + ItemStack stack = mc.thePlayer.inventory.getItemStack(); + + if(stack != null && !Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) + { + itemType = stack.copy(); + itemType.stackSize = 1; + + oreDictName = MekanismUtils.getOreDictName(itemType); + } + else if(stack == null && Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) + { + itemType = null; + oreDictName = null; + } + + mc.sndManager.playSoundFX("random.click", 1.0F, 1.0F); + } + } + + super.mouseClicked(mouseX, mouseY, button); + } +} diff --git a/common/mekanism/common/CommonProxy.java b/common/mekanism/common/CommonProxy.java index 98e2ff217..f73706628 100644 --- a/common/mekanism/common/CommonProxy.java +++ b/common/mekanism/common/CommonProxy.java @@ -3,6 +3,7 @@ package mekanism.common; import java.io.File; import mekanism.common.inventory.container.ContainerAdvancedElectricMachine; +import mekanism.common.inventory.container.ContainerDictionary; import mekanism.common.inventory.container.ContainerDigitalMiner; import mekanism.common.inventory.container.ContainerDynamicTank; import mekanism.common.inventory.container.ContainerElectricMachine; @@ -262,6 +263,8 @@ public class CommonProxy switch(ID) { + case 0: + return new ContainerDictionary(player.inventory); case 2: return new ContainerDigitalMiner(player.inventory, (TileEntityDigitalMiner)tileEntity); case 3: diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index 6613333ac..f0facbb33 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -48,6 +48,7 @@ import mekanism.common.item.ItemBlockOre; import mekanism.common.item.ItemBlockTransmitter; import mekanism.common.item.ItemClump; import mekanism.common.item.ItemConfigurator; +import mekanism.common.item.ItemDictionary; import mekanism.common.item.ItemDirtyDust; import mekanism.common.item.ItemDust; import mekanism.common.item.ItemElectricBow; @@ -90,13 +91,11 @@ import mekanism.common.network.PacketWalkieTalkieState; import mekanism.common.tileentity.TileEntityAdvancedBoundingBlock; import mekanism.common.tileentity.TileEntityBoundingBlock; import mekanism.common.tileentity.TileEntityElectricBlock; -import mekanism.common.tileentity.TileEntityTeleporter; import mekanism.common.transporter.TransporterManager; import mekanism.common.util.MekanismUtils; import mekanism.common.util.MekanismUtils.ResourceType; import mekanism.common.voice.VoiceServerManager; import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; @@ -221,6 +220,7 @@ public class Mekanism public static ItemJetpack Jetpack; public static ItemScubaTank ScubaTank; public static ItemGasMask GasMask; + public static Item Dictionary; //Blocks public static Block BasicBlock; @@ -478,6 +478,9 @@ public class Mekanism CraftingManager.getInstance().getRecipeList().add(new MekanismRecipe(Jetpack.getEmptyItem(), new Object[] { "SCS", "TGT", " T ", Character.valueOf('S'), "ingotSteel", Character.valueOf('C'), "circuitBasic", Character.valueOf('T'), "ingotTin", Character.valueOf('G'), MekanismUtils.getEmptyGasTank() })); + CraftingManager.getInstance().getRecipeList().add(new MekanismRecipe(new ItemStack(Dictionary), new Object[] { + "C", "B", Character.valueOf('C'), "circuitBasic", Character.valueOf('B'), Item.book + })); for(RecipeType type : RecipeType.values()) { @@ -566,7 +569,8 @@ public class Mekanism //Declarations configuration.load(); ElectricBow = (ItemElectricBow)new ItemElectricBow(configuration.getItem("ElectricBow", 11200).getInt()).setUnlocalizedName("ElectricBow"); - //OPEN 11201-11203 + Dictionary = new ItemDictionary(configuration.getItem("Dictionary", 11201).getInt()).setUnlocalizedName("Dictionary"); + //OPEN 11202-11203 Dust = new ItemDust(configuration.getItem("Dust", 11204).getInt()-256); Ingot = new ItemIngot(configuration.getItem("Ingot", 11205).getInt()-256); EnergyTablet = (ItemEnergized)new ItemEnergized(configuration.getItem("EnergyTablet", 11206).getInt(), 1000000, 120).setUnlocalizedName("EnergyTablet"); @@ -614,6 +618,7 @@ public class Mekanism GameRegistry.registerItem(NetworkReader, "NetworkReader"); GameRegistry.registerItem(WalkieTalkie, "WalkieTalkie"); GameRegistry.registerItem(Jetpack, "Jetpack"); + GameRegistry.registerItem(Dictionary, "Dictionary"); } /** diff --git a/common/mekanism/common/inventory/container/ContainerDictionary.java b/common/mekanism/common/inventory/container/ContainerDictionary.java new file mode 100644 index 000000000..bc289b23b --- /dev/null +++ b/common/mekanism/common/inventory/container/ContainerDictionary.java @@ -0,0 +1,85 @@ +package mekanism.common.inventory.container; + +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; + +public class ContainerDictionary extends Container +{ + public ContainerDictionary(InventoryPlayer inventory) + { + int slotX; + + for(slotX = 0; slotX < 3; ++slotX) + { + for(int slotY = 0; slotY < 9; ++slotY) + { + addSlotToContainer(new Slot(inventory, slotY + slotX * 9 + 9, 8 + slotY * 18, 84 + slotX * 18)); + } + } + + for(slotX = 0; slotX < 9; ++slotX) + { + addSlotToContainer(new Slot(inventory, slotX, 8 + slotX * 18, 142)); + } + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) + { + return true; + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer player, int slotID) + { + ItemStack stack = null; + Slot currentSlot = (Slot)inventorySlots.get(slotID); + + if(currentSlot != null && currentSlot.getHasStack()) + { + ItemStack slotStack = currentSlot.getStack(); + stack = slotStack.copy(); + + if(slotID >= 0 && slotID <= 26) + { + if(!mergeItemStack(slotStack, 27, inventorySlots.size(), false)) + { + return null; + } + } + else if(slotID > 26) + { + if(!mergeItemStack(slotStack, 0, 26, false)) + { + return null; + } + } + else { + if(!mergeItemStack(slotStack, 0, inventorySlots.size(), true)) + { + return null; + } + } + + if(slotStack.stackSize == 0) + { + currentSlot.putStack((ItemStack)null); + } + else { + currentSlot.onSlotChanged(); + } + + if(slotStack.stackSize == stack.stackSize) + { + return null; + } + + currentSlot.onPickupFromSlot(player, slotStack); + } + + return stack; + } +} diff --git a/common/mekanism/common/item/ItemDictionary.java b/common/mekanism/common/item/ItemDictionary.java new file mode 100644 index 000000000..2b609c74b --- /dev/null +++ b/common/mekanism/common/item/ItemDictionary.java @@ -0,0 +1,63 @@ +package mekanism.common.item; + +import mekanism.api.EnumColor; +import mekanism.api.transmitters.ITransmitter; +import mekanism.api.transmitters.TransmitterNetworkRegistry; +import mekanism.common.Mekanism; +import mekanism.common.util.MekanismUtils; +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatMessageComponent; +import net.minecraft.world.World; + +public class ItemDictionary extends ItemMekanism +{ + public ItemDictionary(int id) + { + super(id); + setMaxStackSize(1); + } + + @Override + public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) + { + if(!player.isSneaking()) + { + Block block = Block.blocksList[world.getBlockId(x, y, z)]; + + if(block != null) + { + if(world.isRemote) + { + ItemStack testStack = new ItemStack(block, 1, world.getBlockMetadata(x, y, z)); + String name = MekanismUtils.getOreDictName(testStack); + + if(name != null && !name.isEmpty()) + { + player.addChatMessage(EnumColor.DARK_BLUE + "[Mekanism]" + EnumColor.GREY + " Key found: " + EnumColor.DARK_GREEN + name); + } + else { + player.addChatMessage(EnumColor.DARK_BLUE + "[Mekanism]" + EnumColor.GREY + " No key."); + } + } + + return true; + } + } + + return false; + } + + @Override + public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) + { + if(entityplayer.isSneaking()) + { + entityplayer.openGui(Mekanism.instance, 0, world, 0, 0, 0); + } + + return itemstack; + } +} diff --git a/common/mekanism/common/tileentity/TileEntityDigitalMiner.java b/common/mekanism/common/tileentity/TileEntityDigitalMiner.java index 7ce0e125e..239d10e4d 100644 --- a/common/mekanism/common/tileentity/TileEntityDigitalMiner.java +++ b/common/mekanism/common/tileentity/TileEntityDigitalMiner.java @@ -868,7 +868,7 @@ public class TileEntityDigitalMiner extends TileEntityElectricBlock implements I @Override public boolean renderUpdate() { - return true; + return false; } @Override diff --git a/resources/assets/mekanism/gui/GuiCrusher.png b/resources/assets/mekanism/gui/GuiCrusher.png index 017bf15fe3dcd842f6baa5b89d1371e9d47e6fa8..384b876f668305263df72e9eb82f6b3c91af9e05 100644 GIT binary patch literal 4537 zcmeHLSx{5yy4~4?m>`JEh@^>(iXtE=GG^PNfXE<|AR-8@K}JD93`a89Wi&ck`yU;S14tF_kmt@ZEPan_b5 zLIN@Z000P?nHt*w00J%%02&29t_J4Z1OTMst+QvX&CZ_1SqJ*xyybHP08WeCw;%H# zu@g6n^S5~=iN`sb#Kboi+S@u;9+b&%LYX~!&AuS{dUjA%@w=W*T<*a=BeUgnt1yZV zY6k%g@d=w691=pghYfAimzvqesM5_$!)87TA5v!X+kdSNaaXbZcy;|}i|&~2wEpz9 z5o1HwTV>A=*vF>k6{L44raa1)e4Jqs-(Avc&exkaYpIsp(k6QRgT#;a`LEb`bPGFq zk!!i3z#t}k>57xLs`rz?k`8PNUTW?2E;kov?AhMDRe}1#kzMXNg#`1!C!`mmpw_Mkh zx9S%4VcpZEPB5b%ypyU`dwJ=#KC|#P<5RIC-gXGFBj;YSpmC5O_Nqu{Fl_;C{z31< zK7N5fUp)!c9@61;PK{NtouraR8anaZ#HV}uKe0b=f33T`sKLhNcE2C zdqp46f1^lJB^}*8Oj04K?_P`#a;lQwRdh+IOFqu8TfJ0EQyL5_biFRdig)qs^QN6t zv9_U)*BLUy ze=J*uPiehO*t1?$`)xYQ^gAlqR^~&^yYjE*7*Ap>@(i^)IwRiD zVY#>atQAp6I*^^a-*BOfP&UaqGvZX{tILveA$kZ!tu3oGZ-c{d@k-uYvEAsrt z>R2BGTbbF@mIeb?86l+7d~e!HUplPqGZ}B`FBD_8dXu8 z6e^dsv#!2W#m!9SOhDhM0r0PxiLg&^N;v3vhkT$GQl*7(nSR;Mn84WWY$xU^fMzS=G}GK z`p-0me>L1u@$)ZNBAY)szFw48)vH1&D=RD4pP!#^dzi-a-9xHsqzV=9P#L?m*zwtI z?aT?f9A9KOul(H}-mCT5g7Iu-#EDoFa``rjx0&l!iK48v(omtLTM5pt4+<7nNIvF# zdZ@@NQXEG)vqPweW7))Sme*JBM3=jDaLs6lwYSbyT8fk)XIjRr$9NOjvVx;o)Kle1 z+enynjGVhKHB6zQ!hPhdWJu+YfuFK0%9@%>Sx=v#%O@4uiU(u!!n|$eV_DJ5bQPuO z(mE=KkF@aENXW!(eTS3PKDr%LQpvg2Gf&vKMA)ll3f#xpm)r$4mp!T?2}{G)^T~!_ zuZ%8R*&2et!{i(RuuQ-dC_8UijS=6U1PI{hzeD+;D3qVv;|KC170F;M9cP_KMp}D+ zFHM6GlxsZM`o@$#pO+ra_{;CARyr1lcFR0W4UfAm%nqIWoHA85a4pQUR$>dRwFExg zS;*HZdF;@h(V|+oyaq1SZ7-Jp%9PsyJIYh)j>wOTWTLY!pnH$t5WNR<@|CTPVN?w{ zqF^wLD!9oa4{NHV6cGdYL zE?w!q;NZY}Pfo4v_1T%fy!UkC*@gRLWRcVyKXt1=jd9p<R(2NlXW7J`tot?wzTNPr4FEMkBV_ z*nub4?tS|h*KJRy)|@!ZXF_9cxC!;l5XI}=S0rxsb&ZD0S6Nn2v@B1*^B=LbyIopBn%lrs@14Wmu5 zIm`L(a@Le4+2b}1A6a*AYx2nm%e@meopf&iKlKCcjcvAN*^NY5-EM=8L65dF?}1@O zktkkXVV&2&>($%`x|Dku!Q+S^p|t{EeSTcQXuy3&_*P&^UES!lu8D0^K}~$nj5TNS ziEDXF@_u=zk6I+fKSnD2D=u$4K6zs*sbZDkBd;rK5UP=XN<~A5^1%>%<-GgpLq@-q z0`~Hfbm^^SrduMD{M3E7ElnrQpRrqRft;w=D7NyUu4zP5E z%iSm*e@4hSz!LgsqzrN-lYkTVUBg!zH|X4jl8*9@MOeK;>G~D){+1OdsCA;>XewZm z8mMWt&0<6{EJTyVHAu>A=bQqW}N^q466S;!#Ud()uGcyi)19bPzBJ(vYa3U_t1! zn6YV^gYVK0e8kS?sE#{MZ6+98R;K-IclW<~&8O7>Jk~$bg+7)7XNKL^PH8YfA_Fp{kEqdr4i1qg!K?@&|C?JIA(uZ`;U5eenoO4QD27gS~LkrRh5-F>sAbk z*1OkYAJ*GoOaXI=eGd;6IU+D_#iNPm-E!fGdo2*twBPY9G_B5;61v_GyKngF``d@A zFVD>?!|OIT=XH15H{B^y3t^le;68cLzh>op8qix(B2PIEW%+yx*m8EMso6;xidx_-fe*>dLm>2 z@0CSYw*z<|Ch)JcNnhfN9s5chW45RF_NX;yk1+eUFbgAe;vH`aqget+aJ)(Dla zgH>xHtUiRiy}j9#fq?;!U#5$0ou{zHjY!Uj9>IGW z3)#t1TA$Udym6*>Wc~B_Fd?r42wZ!tWL*gl=pJyA1|^b_Nm<#)D4$`?Kl9~mAp>FH zvW7P>cE{oC4Rt*=4$ z_xBIe|7Q|#OlUP6IiD#Ezbp4LM;LiiJPEiNZTkR{L+as?2Jn3rB4=KQ-DtSKceo@0 zqNS^h3DoSR^l71kl*u{jmTzBta`vzO#|)XylEc48HNmv>|-6q@;|!w|9_tDbN|o(p7WgNywC5P_kF+TJ@5PZ#haTM9zQ003;=-R za3lSn0RRG;5P*#Zydh98+yQ`b)k{y$9ImG)VUF^1_wu<30P63Pu1)w6t$4NL{SeRi zwF|3~Ir$PQuUR@YoD_c5#R5++{;Dh7&^Idgtmn3`u;s|P--dp3F7Z-6`|0sI+Wy?82s2MxCbwX{`*Z>U7)Wkh9@J zE~GU_)q>QNg6yn|){_6iUplj)Q}R5_tP!Eepx6~-__5tt@(oFib!_1<;I?&X38PHD zu8)mogc#KelTmuHf=hyAu(K*Vd1;)gF)gZiI?ncba2ENec4ZN9E_KWKA6>H&o{iMW zO`q!6SBCBQaIA~msgu5{FfZKL8)|`G%DMi*w(+X@Azsz*oIN#^`gQHg>6GcF6oOMw z_b_)RVViZKU`6kbrUD5A1;`DN~O@Hon!fe z?Q6){7Y|}NT15RVEEyS1GR%j6&Jc_*xz2fWDP$JYj_k-jUOw_j)xZn?nP>T~NN(T{ zF^k<43E4Eg8`+5%6OxQyYP(Fr2OgCF&~G9Mc-M(f8|zvs1M+0i=-!5W183fq@~{sB zl~Ehp{ND7`JTLizVAi&F&f087>Tadt{%iTQDqY3qu$qPW6DAs^t);}$&EaFqFH7s< zQg=1$?zLVsa`Sb6FsPwr@E}&;y@XTy&G7I6|3k(QbYlG}*S-rQKX}=mnPV-EJ*7?* zhi6V^XlL@xvd=c7f*c+a(Quj-&6;LGGov}tgl>FJ^S7hHu~OmEh{VSPGR19uF*?+N zaMrZR$x^8}vDP6J{`(cEQKeDmyMkeb<8ZeRV#A9hjr!o`U3Q>z zYGciL#esQ=*DDgOMdB~sY%5f)hsvx^vZ!weknGf?J_RyPd2x@3e22Ix#KoIJM zYU44h{a0loA*;9O+tesWq2^p))m*OCmU$YJ3z_V`UNGw(KsMfJW%2LX6R-o2!F4s8 z!yp1!T#XI&fy1M-5Lc28uKdg2$Swc?*nc>>AV5x@Ah^gH2sgdVI>7Nno78q^PD>OS$q1b^C9emN>VJBSclI! z2eWw-YFb^t{jcPx!vxjfnC%L+TFFJfxv$_bRYV!Yv4OnL9W+CC9~OW@e6# zAJ`nJoTdAmI~ldV?mRu-+xw(=ziT%%FZWT%Eb4HoR9C+v)>1rg&k{&4u(+0oUn%IF z)ZDKKzpag}g%+8QYnu*@+B$0omieRS7oT`DozVi6?%zKZjx=*FXWN4AC#3Yb*Uav_ z*L(u20z2$Eb5xEqdteG@6(-=GEw#+Cxly2Uh80g8$?=X5hl<&BJTXsH=9I?_#_uUj14P87$i9;}w^-a_@sjUQY5%v-Q0{{#F8zAwA z;kKfGDAG3ncDl{Y#PAgV$*6Uc5W|+8FS&Z+VHj`pKSF*!#2ipP8nxr=yVcA9=EKa^(C*Zq>~NUWix;3JQ8k zTrx+p`oFwh6W*=6BKMA91gb@>Fw>E{{+k8pO=1UDo*#iRc9{)KcVJF zN=y)d8t8W{FZ=Gaj4WKvx(SA`&~lHA)Jl_y55#p&@ zyP{CleqNJb1Et!EXZPjgF1ow|~XI zzP>&?v%DD!Q&SUwr|Dg5a`mcV&U54n2^V~@7Xs$e2dfF?Kwo&Q9mu$_5U6mHvbi&%!ORdAkZF*~G(CRu5kAs5)rxJrw z`5uOoLFsKWiqQJHwwBk}*f?Jk%koE;djopYlo0_IF>-G=kMqHApC8=;5{oAH*FNf` z9JcS>#-9K?&Klszyc#uLFV5t$*t{nmwpSvW=ml8Y*w7D}>+1MyDiG9bG3jC$0)e2X z4P8;2>%uP^h(RO$MY`mG%G|x^y^hH?9{4t%<>lr2`4qk(TDCRNDd575Zie+2l1F*oss3-> z+#o+ndx)z$*eP)zzRQ8)5CG`6!Qu0tpzKvYw6_Tfl2tu%% zPbZ&}856^77@hi=VTx!W+rr3wv>Bpe?^?L5iR%FvmPmS&Cs0E1i@fJ8v%LPW720KgRkOik^rOieNN5uttoL0195K;*W|ROp2B zu`@}bjxW#zjJri*@*BE~lUIX`ba^MjD)Z&)IrPgyaYGoO_^!lj0@+!Z}OjGnF6{pu1w!iflP8lv5Enb{3 zGa&`kK9O>{n^jhk+o$+2vk3hl?|kxL^{_SHaM>qYTt-i?s7AZ^?(fSpvdPGv)r_@$ z+Z~0rn3N9#Nmx5Zh`208igVcE-EiP5>tk&KTuwk8;=`BY8$)_#wA3i5$l&xU4Gv;qHjhsJ-qJp!BLIusI3+6 zpWL}QFB>k`A5CJb?>M(65#HBs9pA97B+(nJeB=2!>E8z9K(d^}R>^%zBzw_GpG! z(#NDH;jRk_lRed*kKcg`=~vo{dgrJDR6 zp7vv-i|Jh_gPR_9Jdo=-(ir_rst0|pbKsM5e7RrDHIZ=^e^Z{s_|N&1gDa5;$(t-f zGhTB6aeTsi*zwY<=M0M_GcyHSH15(!$vLAJ_IcV5Ubp<9XRM^%m2msF9^cbgyFt;Q z$(x4hADIdFewAp!6*#;!V$#Ff-d4F2oW@{#a+j)Cv}CS{y{Ob@Wv?Ku+wtv3_=O^Z z@#1Pj6xHo7&2~}FXuPfc<{puvde`Civ32Qhz3KaRo>W?^ZzaC^ayppj2Za@Mo%jpz=ay zNz6akYu@|SSf=t=1L;I&(Ok>Mir`M~VV-P@WTa5__4Bo{xWB@-qt^^}0G)TM9+d7jovalF9hIWEIP#^%T3;%vl|o}&Bceinr{h3X7~4c-$G0sDX=Pw9@Xm>cN?RZ(oYJ;b=PZqk60v%_v(uG z&8zC&sBh^=d9K*{6EESuYE9zA(Dc+JZ!@u0(K+11~xSd6lY+HR8`zq4T*x1dvy zBCy@qGQ0TPat@K|{0LU3Dv$M`**y`k2M;Rj&!iW5j8z$fw7W*U% z=lP}gPSWbAB`KSrcl*uPG5W{(_a!a zJGPBB#?-YRI$a-oW@SB$p2=5d`Qp0yD zY<%jefFv6f!)VzOfqT_Au7bbu!xv_UyQIM0Htp++Fk<^pp{vz;EsG6vdQlyPM1}OA@ZjN$?uKh<4 zMp2vKl73a;QnfjXWB*hdxFx_f)zKGy^aI0-8sHfq4EL$>1X0w5|C> zsGGqDa(fyvK2dY3CK``V?VCv>HchUrc5r#EakxHT<~iDDb*i@C%>s)fM(p8jPTbm$ z966_!jusqv3(;RNUj#JrWhZV2~; z!-*+bOwmU+M8Ia$zDK?vYE91?<1EG%aD)e}I6JND9g#+R9Twq=P{AuBkzZp zX~d}Iu9guu;Og{XSC=m{yYWPRA7usUte^a0`5GW%QVYKib;X>pE(H{UCd7b~HKqZ2 z6E<;31qG$`XKf%x5dcWark+LJGuvhL`dIr(5moI>5hgcAMGLJDCKB_I!NbuBsn%#=HlhPNnbfRx!y%hP{&AaO=wR7)Tg8V zK#~q2ndlw5920kDw@N*1QZ<5J_otQgFID@a<|g*&KWp}Jo4%VjE)PcYuQAtfM1r+~ zh$S=;25a9X2yQ_@@lK^ig0$UV4pi!gl{Fl0A<6qO&Bi7sx$To?eYpD!>;^aACFbis zj~kIF29i7&`TWa6xl?>k?{NmNxj#o4G%{v>++C80gn@7*3PYp<|9AdJL4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH z9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK zVkc9?T=n|PIo~X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1 zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#mZ8eu=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7 zqW-CFs9&fT)ZaU5gc&=gBz-DaCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaER0004@Nklsm`hD*(7Hu*|4!TcRVOByc1+C8Hx@yaE_EO+$TH&2bzX?N$Wv!pWf@$I<9SC-i-v ziQsb>hRfBL5cSiu*o%M=0Xe<03p{WkV=w}$^m-sJbA=SnlVAjx#y>AkC$P!`ssQlc zvr4|_Oh^j28^>`-mSuZiL$^TUC`3Bu!K0Ie#ek3<3dO@zFZZ zbEY!SGbziG?Vnj#695Q+F{Wu+W}AmK0f6rTres$H&_?&LS`fY1&nJZv}(&$cYgDDe{Ldh wSHG=PmGe*kn8*aM=SwQ~a)!g%Yix Date: Tue, 10 Dec 2013 18:51:16 -0500 Subject: [PATCH 33/40] Add GUIs for T3 ore processing machinery --- common/mekanism/client/ClientPlayerTracker.java | 3 ++- common/mekanism/common/Mekanism.java | 3 +++ .../tileentity/TileEntityChemicalInfuser.java | 9 +++++++++ .../mekanism/gui/GuiChemicalFormulator.png | Bin 0 -> 4186 bytes .../assets/mekanism/gui/GuiChemicalInfuser.png | Bin 0 -> 4307 bytes 5 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 common/mekanism/common/tileentity/TileEntityChemicalInfuser.java create mode 100644 resources/assets/mekanism/gui/GuiChemicalFormulator.png create mode 100644 resources/assets/mekanism/gui/GuiChemicalInfuser.png diff --git a/common/mekanism/client/ClientPlayerTracker.java b/common/mekanism/client/ClientPlayerTracker.java index 75863eb04..24e3aa963 100644 --- a/common/mekanism/client/ClientPlayerTracker.java +++ b/common/mekanism/client/ClientPlayerTracker.java @@ -27,9 +27,10 @@ public class ClientPlayerTracker implements IPlayerTracker } ClientTickHandler.tickingSet.clear(); + Mekanism.proxy.unloadSoundHandler(); + Mekanism.jetpackOn.clear(); Mekanism.gasmaskOn.clear(); - Mekanism.proxy.unloadSoundHandler(); } } diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index f0facbb33..8195b23b7 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -525,6 +525,7 @@ public class Mekanism //Combiner recipes RecipeHandler.addCombinerRecipe(new ItemStack(Item.redstone, 16), new ItemStack(Block.oreRedstone)); RecipeHandler.addCombinerRecipe(new ItemStack(Item.dyePowder, 16, 4), new ItemStack(Block.oreLapis)); + RecipeHandler.addCombinerRecipe(new ItemStack(Item.flint), new ItemStack(Block.gravel)); //Osmium Compressor Recipes RecipeHandler.addOsmiumCompressorRecipe(new ItemStack(Item.glowstone), new ItemStack(Ingot, 1, 3)); @@ -539,9 +540,11 @@ public class Mekanism RecipeHandler.addCrusherRecipe(new ItemStack(Block.stoneBrick, 1, 2), new ItemStack(Block.stone)); RecipeHandler.addCrusherRecipe(new ItemStack(Block.stoneBrick, 1, 0), new ItemStack(Block.stoneBrick, 1, 2)); RecipeHandler.addCrusherRecipe(new ItemStack(Block.stoneBrick, 1, 3), new ItemStack(Block.stoneBrick, 1, 0)); + RecipeHandler.addCrusherRecipe(new ItemStack(Item.flint, 4), new ItemStack(Item.gunpowder)); //Purification Chamber Recipes RecipeHandler.addPurificationChamberRecipe(new ItemStack(Block.obsidian), new ItemStack(Clump, 2, 6)); + RecipeHandler.addPurificationChamberRecipe(new ItemStack(Block.cobblestone), new ItemStack(Block.gravel)); //Metallurgic Infuser Recipes RecipeHandler.addMetallurgicInfuserRecipe(InfusionInput.getInfusion(InfuseRegistry.get("CARBON"), 10, new ItemStack(Item.ingotIron)), new ItemStack(EnrichedIron)); diff --git a/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java b/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java new file mode 100644 index 000000000..622fc4189 --- /dev/null +++ b/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java @@ -0,0 +1,9 @@ +package mekanism.common.tileentity; + +public class TileEntityChemicalInfuser extends TileEntityElectricBlock +{ + public TileEntityChemicalInfuser() + { + super("ChemicalInfuser", 0 /*TODO*/); + } +} diff --git a/resources/assets/mekanism/gui/GuiChemicalFormulator.png b/resources/assets/mekanism/gui/GuiChemicalFormulator.png new file mode 100644 index 0000000000000000000000000000000000000000..4d94ee187d81a55243d3228fc9e890b72e6ed394 GIT binary patch literal 4186 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 UclY|R{tN&^Jrmuci}nxy3vtB=xc~qF literal 0 HcmV?d00001 diff --git a/resources/assets/mekanism/gui/GuiChemicalInfuser.png b/resources/assets/mekanism/gui/GuiChemicalInfuser.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e1bc9f88886c7452dd511075155b62a4b296ff GIT binary patch literal 4307 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 literal 0 HcmV?d00001 From 7e48fa27438ca4ad24658f0a5e9508457f111d73 Mon Sep 17 00:00:00 2001 From: "Aidan C. Brady" Date: Wed, 11 Dec 2013 16:34:54 -0500 Subject: [PATCH 34/40] Work on container code --- .../client/gui/GuiChemicalFormulator.java | 6 + .../client/gui/GuiChemicalInfuser.java | 6 + .../ContainerChemicalFormulator.java | 153 +++++++++++++++++ .../container/ContainerChemicalInfuser.java | 155 ++++++++++++++++++ .../TileEntityChemicalFormulator.java | 9 + .../mekanism/gui/GuiChemicalFormulator.png | Bin 4186 -> 4074 bytes .../mekanism/gui/GuiChemicalInfuser.png | Bin 4307 -> 4307 bytes 7 files changed, 329 insertions(+) create mode 100644 common/mekanism/client/gui/GuiChemicalFormulator.java create mode 100644 common/mekanism/client/gui/GuiChemicalInfuser.java create mode 100644 common/mekanism/common/inventory/container/ContainerChemicalFormulator.java create mode 100644 common/mekanism/common/inventory/container/ContainerChemicalInfuser.java create mode 100644 common/mekanism/common/tileentity/TileEntityChemicalFormulator.java diff --git a/common/mekanism/client/gui/GuiChemicalFormulator.java b/common/mekanism/client/gui/GuiChemicalFormulator.java new file mode 100644 index 000000000..24b68cce4 --- /dev/null +++ b/common/mekanism/client/gui/GuiChemicalFormulator.java @@ -0,0 +1,6 @@ +package mekanism.client.gui; + +public class GuiChemicalFormulator +{ + +} diff --git a/common/mekanism/client/gui/GuiChemicalInfuser.java b/common/mekanism/client/gui/GuiChemicalInfuser.java new file mode 100644 index 000000000..3a4ca36b4 --- /dev/null +++ b/common/mekanism/client/gui/GuiChemicalInfuser.java @@ -0,0 +1,6 @@ +package mekanism.client.gui; + +public class GuiChemicalInfuser +{ + +} diff --git a/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java b/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java new file mode 100644 index 000000000..794b0e6ef --- /dev/null +++ b/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java @@ -0,0 +1,153 @@ +package mekanism.common.inventory.container; + +import mekanism.common.inventory.slot.SlotEnergy.SlotDischarge; +import mekanism.common.inventory.slot.SlotStorageTank; +import mekanism.common.item.ItemMachineUpgrade; +import mekanism.common.tileentity.TileEntityChemicalInfuser; +import mekanism.common.util.ChargeUtils; +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; + +public class ContainerChemicalFormulator extends Container +{ + private TileEntityChemicalInfuser tileEntity; + + public ContainerChemicalFormulator(InventoryPlayer inventory, TileEntityChemicalInfuser tentity) + { + tileEntity = tentity; + addSlotToContainer(new SlotStorageTank(tentity, null, true, 0, 5, 25)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 1, 5, 56)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 2, 155, 25)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 3, 155, 56)); + addSlotToContainer(new SlotDischarge(tentity, 4, 155, 5)); + + int slotX; + + for(slotX = 0; slotX < 3; slotX++) + { + for(int slotY = 0; slotY < 9; slotY++) + { + addSlotToContainer(new Slot(inventory, slotY + slotX * 9 + 9, 8 + slotY * 18, 84 + slotX * 18)); + } + } + + for(slotX = 0; slotX < 9; ++slotX) + { + addSlotToContainer(new Slot(inventory, slotX, 8 + slotX * 18, 142)); + } + + tileEntity.playersUsing.add(inventory.player); + tileEntity.openChest(); + } + + @Override + public void onContainerClosed(EntityPlayer entityplayer) + { + super.onContainerClosed(entityplayer); + + tileEntity.playersUsing.remove(entityplayer); + tileEntity.closeChest(); + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) + { + return tileEntity.isUseableByPlayer(entityplayer); + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer player, int slotID) + { + ItemStack stack = null; + Slot currentSlot = (Slot)inventorySlots.get(slotID); + + if(currentSlot != null && currentSlot.getHasStack()) + { + ItemStack slotStack = currentSlot.getStack(); + stack = slotStack.copy(); + + if(slotID == 2) + { + if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + { + return null; + } + } + else if(ChargeUtils.canBeDischarged(slotStack)) + { + if(slotID != 1) + { + if(!mergeItemStack(slotStack, 1, 2, false)) + { + return null; + } + } + else if(slotID == 1) + { + if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + { + return null; + } + } + } + else if(slotStack.getItem() instanceof ItemMachineUpgrade) + { + if(slotID != 0 && slotID != 1 && slotID != 2 && slotID != 3) + { + if(!mergeItemStack(slotStack, 3, 4, false)) + { + return null; + } + } + else { + if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + { + return null; + } + } + } + else { + if(slotID >= 4 && slotID <= 30) + { + if(!mergeItemStack(slotStack, 31, inventorySlots.size(), false)) + { + return null; + } + } + else if(slotID > 30) + { + if(!mergeItemStack(slotStack, 4, 30, false)) + { + return null; + } + } + else { + if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + { + return null; + } + } + } + + if(slotStack.stackSize == 0) + { + currentSlot.putStack((ItemStack)null); + } + else { + currentSlot.onSlotChanged(); + } + + if(slotStack.stackSize == stack.stackSize) + { + return null; + } + + currentSlot.onPickupFromSlot(player, slotStack); + } + + return stack; + } +} diff --git a/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java b/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java new file mode 100644 index 000000000..54738485e --- /dev/null +++ b/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java @@ -0,0 +1,155 @@ +package mekanism.common.inventory.container; + +import mekanism.common.RecipeHandler; +import mekanism.common.inventory.slot.SlotEnergy.SlotDischarge; +import mekanism.common.inventory.slot.SlotMachineUpgrade; +import mekanism.common.inventory.slot.SlotOutput; +import mekanism.common.inventory.slot.SlotStorageTank; +import mekanism.common.item.ItemMachineUpgrade; +import mekanism.common.tileentity.TileEntityChemicalInfuser; +import mekanism.common.util.ChargeUtils; +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; + +public class ContainerChemicalInfuser extends Container +{ + private TileEntityChemicalInfuser tileEntity; + + public ContainerChemicalInfuser(InventoryPlayer inventory, TileEntityChemicalInfuser tentity) + { + tileEntity = tentity; + addSlotToContainer(new Slot(tentity, 0, 26, 36)); + addSlotToContainer(new SlotDischarge(tentity, 1, 155, 5)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 2, 155, 25)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 3, 155, 56)); + + int slotX; + + for(slotX = 0; slotX < 3; ++slotX) + { + for(int slotY = 0; slotY < 9; ++slotY) + { + addSlotToContainer(new Slot(inventory, slotY + slotX * 9 + 9, 8 + slotY * 18, 84 + slotX * 18)); + } + } + + for(slotX = 0; slotX < 9; ++slotX) + { + addSlotToContainer(new Slot(inventory, slotX, 8 + slotX * 18, 142)); + } + + tileEntity.playersUsing.add(inventory.player); + tileEntity.openChest(); + } + + @Override + public void onContainerClosed(EntityPlayer entityplayer) + { + super.onContainerClosed(entityplayer); + + tileEntity.playersUsing.remove(entityplayer); + tileEntity.closeChest(); + } + + @Override + public boolean canInteractWith(EntityPlayer entityplayer) + { + return tileEntity.isUseableByPlayer(entityplayer); + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer player, int slotID) + { + ItemStack stack = null; + Slot currentSlot = (Slot)inventorySlots.get(slotID); + + if(currentSlot != null && currentSlot.getHasStack()) + { + ItemStack slotStack = currentSlot.getStack(); + stack = slotStack.copy(); + + if(slotID == 2) + { + if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + { + return null; + } + } + else if(ChargeUtils.canBeDischarged(slotStack)) + { + if(slotID != 1) + { + if(!mergeItemStack(slotStack, 1, 2, false)) + { + return null; + } + } + else if(slotID == 1) + { + if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + { + return null; + } + } + } + else if(slotStack.getItem() instanceof ItemMachineUpgrade) + { + if(slotID != 0 && slotID != 1 && slotID != 2 && slotID != 3) + { + if(!mergeItemStack(slotStack, 3, 4, false)) + { + return null; + } + } + else { + if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + { + return null; + } + } + } + else { + if(slotID >= 4 && slotID <= 30) + { + if(!mergeItemStack(slotStack, 31, inventorySlots.size(), false)) + { + return null; + } + } + else if(slotID > 30) + { + if(!mergeItemStack(slotStack, 4, 30, false)) + { + return null; + } + } + else { + if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + { + return null; + } + } + } + + if(slotStack.stackSize == 0) + { + currentSlot.putStack((ItemStack)null); + } + else { + currentSlot.onSlotChanged(); + } + + if(slotStack.stackSize == stack.stackSize) + { + return null; + } + + currentSlot.onPickupFromSlot(player, slotStack); + } + + return stack; + } +} diff --git a/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java b/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java new file mode 100644 index 000000000..567dd33c0 --- /dev/null +++ b/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java @@ -0,0 +1,9 @@ +package mekanism.common.tileentity; + +public class TileEntityChemicalFormulator extends TileEntityElectricBlock +{ + public TileEntityChemicalFormulator() + { + super("ChemicalFormulator", 0 /*TODO*/); + } +} diff --git a/resources/assets/mekanism/gui/GuiChemicalFormulator.png b/resources/assets/mekanism/gui/GuiChemicalFormulator.png index 4d94ee187d81a55243d3228fc9e890b72e6ed394..0b6799cb08711739c6c3071bd82c7603c551edbd 100644 GIT binary patch delta 2602 zcmb`HX;f3^7KYC`Bn*KI1Sx|Rh)_yU5bV_=M##~EB8Ulk2ANKdTEPi~ zFjNqTq6U;f3xbLXQ4y|!g&3JtVnM@97(xgl=~-QO-F5rtuGO{f_vicf?)^UR-g|&F zZgR&HhoF0%c6ug(Q*ZA^uk$kmL|d;pxn!EU=4+n)+T+lA%jiN58}{5}LlaHt!$0i+ zJfp8gv>WA-T~D8OawFbg@ATf{VqhY!shvs+36)Xf7FQ@kE;&;r_MxltRR_g%M}LQL zb^5`Y^rh}&xQBY%eD}!e0*#D1<`vqjR!N8sZ7K@dyUzsT?jB4KssDqID7j!_cC@I68tx5(;Rd9M% zqP6^!tRdl5#qvmT%KMe6+S}b_iUldR&G^%>otY4A_PfWuwt6s?OT7s!lwQTRcq=1@ zlElJh5#$&9l6&da>5`$6O;xj*Dv^y*_pEfSe7Ewiq`$5#PXoi1Elcg< z+ufZ=tRj!y*r#P~%mFfTpPy^n+?$bLd}is>P8PbLj?Ygnz589 z>D3ac$W9`g&+`BlhoftIpcN`U33FRl~d@ER+9tT~V9+4>PKs_r?ocdevff7S{o_-YN7F=q1PX?anhDt2l4vODz zTGeIGuS{A$y6XeztI7%r#wlLFEtc`_3}yM@kyxPz87MwoHRFp7i4o!j!g7$+! z=_-Q{7p?e@cbQXd@uU-wn1E#YFdqbU&rCxE{&a$`GQKBJb^Gg=>(l+Zx~0c|;%XSh zO|%6dN@3Q~$a#ITGg}`w10+9hfrcw)2}43gQSK93nd93?uivNNmoOn)^N5BqUxq`) zL(RFJG3Fm-Ged#gq}iZajuL@?s%2@u4s#s5V~s8|c;v)HdB+y@OJhcSmIW>PxJS@C z*=|$i4Z2L_h)<;tq5$HGgSW13!Z0y~5m9^So)-lP+$#w16n~SRzhE->C7gw)9 zul2f3P$vwEj(Nm^ikWxZ!TP-~q&9)PeTIo=*k3R;dmCmO%tqW~oC$TvT^_3a~IM@CUoiRA0Tst9teXK$8PO`!g0H2ROqW(h+NSpaHbBQOl?i8 zDxonJn!vZjFaw^3ZzB2V@Vq1o=6xB{mo~Vyd%ZCN}UD4Pi^voG{YZ@xJEMm_P zn3v^dYIdIT?gBC~+dny+1rP7exmN=^E!3M|^2czN!td8)VxWl*QEFddQRG_CmvE+- zB`2C6^c({}qNeMJW-=jdfv^BRj`e#2`k6*DWdnax0{M>yD)^Y)$szCXm_aO?sC4;?Bf`(Pj0@4>g^XT=l|x8Xp%Nc-1O1Jy|~8<Dkotz6F{wGgA!VH=wtP=iGH;O0Pd zvA|Zt?J`sC^%`t7e8wwL{_+%ZD!@8O|AVPWAUz(Rp3XbjlzD~X0yRR3&0b^U(uv;2 zjVrs@pKn=S9Y Q0AO#g^M0qAU5t}|05mzGjQ{`u delta 2727 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 From 2d626f2279ab78c332e8db2f627946f1bb31a1de Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Wed, 11 Dec 2013 17:08:15 -0500 Subject: [PATCH 35/40] Work on Chemical Infuser & Chemical Formulator recipe system --- common/mekanism/common/ChemicalInput.java | 38 +++++++++++ common/mekanism/common/RecipeHandler.java | 59 ++++++++++++++++-- .../ContainerChemicalFormulator.java | 9 ++- .../container/ContainerChemicalInfuser.java | 1 - .../ContainerMetallurgicInfuser.java | 2 +- .../TileEntityMetallurgicInfuser.java | 6 +- .../mekanism/gui/GuiChemicalFormulator.png | Bin 4074 -> 4056 bytes .../mekanism/gui/GuiChemicalInfuser.png | Bin 4307 -> 4387 bytes 8 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 common/mekanism/common/ChemicalInput.java diff --git a/common/mekanism/common/ChemicalInput.java b/common/mekanism/common/ChemicalInput.java new file mode 100644 index 000000000..fa2ed8bd8 --- /dev/null +++ b/common/mekanism/common/ChemicalInput.java @@ -0,0 +1,38 @@ +package mekanism.common; + +import mekanism.api.Object3D; +import mekanism.api.gas.Gas; + +public class ChemicalInput +{ + public Gas leftGas; + public Gas rightGas; + + public ChemicalInput(Gas left, Gas right) + { + leftGas = left; + rightGas = right; + } + + public boolean isValid() + { + return leftGas != null && rightGas != null; + } + + @Override + public boolean equals(Object obj) + { + return obj instanceof ChemicalInput && + ((ChemicalInput)obj).leftGas == leftGas && + ((ChemicalInput)obj).rightGas == rightGas; + } + + @Override + public int hashCode() + { + int code = 1; + code = 31 * code + leftGas.getID(); + code = 31 * code + rightGas.getID(); + return code; + } +} diff --git a/common/mekanism/common/RecipeHandler.java b/common/mekanism/common/RecipeHandler.java index adb4451f0..60ab79c3b 100644 --- a/common/mekanism/common/RecipeHandler.java +++ b/common/mekanism/common/RecipeHandler.java @@ -3,6 +3,7 @@ package mekanism.common; import java.util.HashMap; import java.util.Map; +import mekanism.api.gas.GasStack; import mekanism.api.infuse.InfusionInput; import mekanism.api.infuse.InfusionOutput; import mekanism.common.util.StackUtils; @@ -80,6 +81,16 @@ public final class RecipeHandler Recipe.METALLURGIC_INFUSER.put(input, InfusionOutput.getInfusion(input, output)); } + public static void addChemicalInfuserRecipe(ChemicalInput input, GasStack output) + { + Recipe.CHEMICAL_INFUSER.put(input, output); + } + + public static void addChemicalFormulatorRecipe(ItemStack input, GasStack output) + { + Recipe.CHEMICAL_FORMULATOR.put(input, output); + } + /** * Gets the InfusionOutput of the InfusionInput in the parameters. * @param infusion - input Infusion @@ -87,11 +98,13 @@ public final class RecipeHandler * @param recipes - Map of recipes * @return InfusionOutput */ - public static InfusionOutput getOutput(InfusionInput infusion, boolean stackDecrease, Map recipes) - { + public static InfusionOutput getOutput(InfusionInput infusion, boolean stackDecrease) + { if(infusion != null && infusion.inputStack != null) { - for(Map.Entry entry : recipes.entrySet()) + HashMap recipes = Recipe.METALLURGIC_INFUSER.get(); + + for(Map.Entry entry : recipes.entrySet()) { InfusionInput input = (InfusionInput)entry.getKey(); @@ -113,6 +126,42 @@ public final class RecipeHandler return null; } + public static GasStack getOutput(ChemicalInput input) + { + if(input != null && input.isValid()) + { + HashMap recipes = Recipe.CHEMICAL_INFUSER.get(); + return recipes.get(input); + } + + return null; + } + + public GasStack getOutput(ItemStack itemstack, boolean stackDecrease) + { + if(itemstack != null) + { + HashMap recipes = Recipe.CHEMICAL_FORMULATOR.get(); + + for(Map.Entry entry : recipes.entrySet()) + { + ItemStack stack = (ItemStack)entry.getKey(); + + if(StackUtils.equalsWildcard(stack, itemstack) && itemstack.stackSize >= stack.stackSize) + { + if(stackDecrease) + { + itemstack.stackSize -= stack.stackSize; + } + + return entry.getValue().copy(); + } + } + } + + return null; + } + /** * Gets the output ItemStack of the ItemStack in the parameters. * @param itemstack - input ItemStack @@ -150,7 +199,9 @@ public final class RecipeHandler COMBINER(new HashMap()), CRUSHER(new HashMap()), PURIFICATION_CHAMBER(new HashMap()), - METALLURGIC_INFUSER(new HashMap()); + METALLURGIC_INFUSER(new HashMap()), + CHEMICAL_INFUSER(new HashMap()), + CHEMICAL_FORMULATOR(new HashMap()); private HashMap recipes; diff --git a/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java b/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java index 794b0e6ef..d6ae8260f 100644 --- a/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java +++ b/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java @@ -18,11 +18,10 @@ public class ContainerChemicalFormulator extends Container public ContainerChemicalFormulator(InventoryPlayer inventory, TileEntityChemicalInfuser tentity) { tileEntity = tentity; - addSlotToContainer(new SlotStorageTank(tentity, null, true, 0, 5, 25)); - addSlotToContainer(new SlotStorageTank(tentity, null, true, 1, 5, 56)); - addSlotToContainer(new SlotStorageTank(tentity, null, true, 2, 155, 25)); - addSlotToContainer(new SlotStorageTank(tentity, null, true, 3, 155, 56)); - addSlotToContainer(new SlotDischarge(tentity, 4, 155, 5)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 0, 5, 56)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 1, 80, 65)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 2, 155, 56)); + addSlotToContainer(new SlotDischarge(tentity, 3, 155, 5)); int slotX; diff --git a/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java b/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java index 54738485e..7daead959 100644 --- a/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java +++ b/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java @@ -24,7 +24,6 @@ public class ContainerChemicalInfuser extends Container addSlotToContainer(new Slot(tentity, 0, 26, 36)); addSlotToContainer(new SlotDischarge(tentity, 1, 155, 5)); addSlotToContainer(new SlotStorageTank(tentity, null, true, 2, 155, 25)); - addSlotToContainer(new SlotStorageTank(tentity, null, true, 3, 155, 56)); int slotX; diff --git a/common/mekanism/common/inventory/container/ContainerMetallurgicInfuser.java b/common/mekanism/common/inventory/container/ContainerMetallurgicInfuser.java index c1fcb1366..80066d0aa 100644 --- a/common/mekanism/common/inventory/container/ContainerMetallurgicInfuser.java +++ b/common/mekanism/common/inventory/container/ContainerMetallurgicInfuser.java @@ -156,7 +156,7 @@ public class ContainerMetallurgicInfuser extends Container { if(tileEntity.type != null) { - if(RecipeHandler.getOutput(InfusionInput.getInfusion(tileEntity.type, tileEntity.infuseStored, itemStack), false, Recipe.METALLURGIC_INFUSER.get()) != null) + if(RecipeHandler.getOutput(InfusionInput.getInfusion(tileEntity.type, tileEntity.infuseStored, itemStack), false) != null) { return true; } diff --git a/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java b/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java index 4cbbd6dbd..b5fe4e704 100644 --- a/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java +++ b/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java @@ -226,7 +226,7 @@ public class TileEntityMetallurgicInfuser extends TileEntityElectricBlock implem { if(type != null) { - if(RecipeHandler.getOutput(InfusionInput.getInfusion(type, infuseStored, itemstack), false, Recipe.METALLURGIC_INFUSER.get()) != null) + if(RecipeHandler.getOutput(InfusionInput.getInfusion(type, infuseStored, itemstack), false) != null) { return true; } @@ -257,7 +257,7 @@ public class TileEntityMetallurgicInfuser extends TileEntityElectricBlock implem return; } - InfusionOutput output = RecipeHandler.getOutput(InfusionInput.getInfusion(type, infuseStored, inventory[2]), true, Recipe.METALLURGIC_INFUSER.get()); + InfusionOutput output = RecipeHandler.getOutput(InfusionInput.getInfusion(type, infuseStored, inventory[2]), true); infuseStored -= output.getInfuseRequired(); @@ -284,7 +284,7 @@ public class TileEntityMetallurgicInfuser extends TileEntityElectricBlock implem return false; } - InfusionOutput output = RecipeHandler.getOutput(InfusionInput.getInfusion(type, infuseStored, inventory[2]), false, Recipe.METALLURGIC_INFUSER.get()); + InfusionOutput output = RecipeHandler.getOutput(InfusionInput.getInfusion(type, infuseStored, inventory[2]), false); if(output == null) { diff --git a/resources/assets/mekanism/gui/GuiChemicalFormulator.png b/resources/assets/mekanism/gui/GuiChemicalFormulator.png index 0b6799cb08711739c6c3071bd82c7603c551edbd..cbe664e582a382521464a4cb3688a7d8eb06eb6b 100644 GIT binary patch delta 2584 zcmcgsYdDna8vf>6-(*ZFF{YE4NX=wKr$vsRP^+9K)N%+@c8OS%Q{(*2kcb+JBs4~) z+Qkx6SSh{|%DHBBn9xj1&SB&b<1qVc{n*$3y{~KU_t$&f*Yn=*b3ga&)Z z2y4HswOb@^q`T}lO|Lb8blVNvUs7}qTv>j8(?OpNw1ICVQc6>AuX5}Hn8H)yG&!C% zU^8w|SE{KQ*kvUw@qSG?8aw@|b;|V9cnd%5L_5;Aj#kcQw_Q`jDq3pI!ro? zoAX`RD+u6b28UbC_U<>H8$lFNJ7Op9AfG2bRQMIoP9#er;=`){?BdlZlhjRii!~<; zR%C@sCm+m@<@N3xPwaFwow>@ctY5}$Zf^ebar#ZmxeEgKPAQzpT zoxMFaJUsk)U+wC1eow;Qt?fb^ zUu4UeF)D(@!qt0*!9k$SqphuN3Cm@7f^UW6dw>oRirrwGd%#~Rd9WG-_^JdQrc2kN zshN^D9Z1CVl#>ZEH*7RNo9;Ve{=Fm7H{C&L@r?U)s@!J$(PBQ>5q<8ks;}vc2#2s| z=aQ?_rxl|V32R5M#vQ;ls~B;0WJ;bXN)hwLQD1|*8WF`nF;!fmGF6ypRX;P)Undh4 zjPTVSl4A_VP4EMHnfS(o!}ez1ZRWdKHE~yKy$BWB3vpmo>7o8IkkPm+w$wf@z&}Q2 zCQBDKQ-Q{i%C}zJaGB!scZrLpoW~+lSiiae-{v1$GMF(k?Px^GGCoCS>W6%A#!HQi zOSa=H`W4r@Px5I@GDV#c242F)f+_h=Q_B={!waI*R*OxVadvXM>carJmnYn&6qSFZ z*Y+OpWgx)JgW{-vySCr(X%7CS`k^16@TnQ2UtD`mXq~`q+Qe)R+zO6z$9Hmf5oVwV z=jg^p4Mj+ePZ!FtNfH2O54;b3_AUqSJ~Uk4Oskh%234(+5A9`=1;kTf*S7$zMYeDl z)B?7=mWO)drS|IWkebobjH`4Z5EbvaN^NFlyeDJPBU^(3WKUJ>0v(l2@F%ydAAwx` z$b##y&;LVT00imHcdc|kMwS+)&$A0+^)DhAM$Hxy#cE%V^ejutQI+yIS^ z8L=JYiZ0~Du5fU&yhg9M7^_F7>cYGh-QdOFklWG(L}3TD9RNsi@&yh|D-U1N}?|o?Y&juE>7SQ0KisgL`Io zdq(;Rfvu`q1_t%U#QrYLfPci z3()E4=-lmYXuVr|)D=~J@# zbZF;P>qxoy`NBHGD&3CwnQ)}zvFP=7%kN`^@c8%|v21E8LVj)fXfqeQSpc{c1ng_~ z=o&w9B)z@I^1CFb!7DO?$2kRrJuJ2t?7-3yo?W|~yBj2;ng+va0}e25fL?gchRNfA zM*Er{L#FBsz|{WkXVn~C0nqZgd@HvN8_hPgKoh8sK>b03{MS5~K&jKN9&w-WLi^0& zC%L*(9;`IKB-+f%Br zsv+jw=bJOI?Ea1X9{_Y<0l=ziULBi_jIWWT{u+kaMaUABRX~Bt`2_{6$2B!IPF5nz zpxq3VhH_8mt{kw&YP%t=0hYozyc9NRB}`I`qF2f$CwInN&>LGG6B4q4Zvk4ENow_F zTA;Hw#mEzIK>`|^Ji4aN{O#W;(fqfpiF>XbO^aY<2;2Dyn;A0*6pA_WpUD3jSp8I+ zQ~inOf3zHi?`In}B8>o#)RLAJuHDDQo#FB1RE5b`9;BnekuwRM9T(NAci y5+8!ws;b(t!xDjt@Y!-zTqbilcMVq#DwM`))%7}`=1&0F*>C4$`}-bd!oL9fhnN`v delta 2602 zcmb`HX;f3^7KYC`B+M5GQU)s!p_HItuvHNwaI~NZVnU@LlSC|&41$zFrjui>-~>V# zDhNbT1InNULB$Lz!d0*kBeO~@XqX8@2tg$GtggH6y8Uz4>RR{v^Zk4GexG;m-Df&( zddCZgp!=M6c_o8WZ|}ye^EU!STdz60W|_GaXr2Aq^YD7Bm?Aa{_S!_IiY5%;pLPOX zG1ns7jq^!vr%yY(6K=3}`D}4DG!@s@O(lnh$(-UBS13cSxl^U~VXN|02gP(pe}_p; z#-ZAbrS9Xnhx*(7_R8vmjEy_y7kP?De(5q~YJ9P;r)|5q(-aw!cT2w!XDoQIiunS; zOBTh^lKcb^fzwE*CSTyXf0c zp-@=DC6mcMPV!^-2HG}?15{+?yh*X1=wq_x>VsFehK7fSZJ(6b9rvy~%z4;LMJD1u zrc#_3PCdPVmWZ})_Y4#Q>@8$6nFR(_S)!uo_N{;h2x)vl1N4iNGd)q1(`_j}>)DRED(NrV^h}4Oo-a;wDjXLcGosT-_-%}zB*dWR70)j*Zil%`OyN4NR2 z7mye)+(5eHsL)QVI7#DM!#cEh=raD1(m$_ojE*W~c29+|PM-(XeZH{Z(d-QrpAh$7 z-c@Gllk55gBde^DiGR@$ELW`DGpGkPd*X>7*-~fpgk`yX%*P}8^k7JNTRb5aXnl$+ zB#Mmry1%`7jBIXPPL5N_EZ%^_6MuL(fTy%s!?$w`nhw6;S>lO^R+v3h57ggD?5%>j z0^M*87a6{c=mzc^Z*b{Vi}_hx2h@@mqK{Qdut0N6ooZh=x%-27R!tL!FzUv)f_=tD zEq}ES1()r2%W!@j(9Xp|#q?1sQtrqxU^6^UNO-RNRHz*NcD9ZkS3T6SFr@}JIc?)q%eU#6z1 zwq+ym9hm%xiuTk4gIwv%L7N~ib(ni)>)HFytYN0oU8X09r{}l5c!zHd1p|n0kSh*& zdcCKQf7+7dh;&6REfV|2;56s@*6aeaG9Y9$gLup{_4-MF8zfn~G?+H@f@%rWZ4F9ff>4~2>n#S=H zZGnhVxJ?Xl-hkx7GQiCMDbHJ=;mTR{AtAju?+LZs@okj%AJgwk8IY|-WaF40-J$ZK z*4(aGi;uFIp&(B3Y;YZ0NuB?5%hG&3<~U^M8a+nH$jOO{jx8FO#*Fz)OKQvs&)|2m z+lZPo*q0I>-o=Eq#e%`){HD(#pG=eyv zORlW!re~*a|6L$9KvU_F=r{N{N(SFb>? z^}9_`XAFw2MdZQCnRlGQhJ7!jTqogyeFBqD>17@vF$A@C>CMZe}$JE8B8$d^q zB^#LUAHNLCAaz(~rAtKRI6a0uO1htw3ibjIse(kXFg{cRt-^46RpAB;&WCLJ)xy5p z7st6c<}_EE+8~aO*SI~E3ZWI8e$YYJ)tm)f-&X*uy*8i$<0a#{@LCX0^tgp{V{sV} zZOAJJ_X@kf5#L+TASt%Z%QsWLy0ixdU6~tD-AXbGcx~5hj&8v`6nm-V!|B*1;8vNa zT_@0hSJ&NGxPR}tEAb)&y7cuAkOe{ug2Bq;xAsC2xIHr}v{h|HuILlEI1QglYfY~% zrP3Fg!MB8PL$0P@66x6Ryd)duei_@BKDf1F25<}eaMr~4&1`5uPG_iT5^k;Cx$1;} z5U;Uq&=IVMIh=Yq>`J2Ux|O=o3pFtQWJC0bSQkEZ{3D!jh;tW2CX;iOa)| z(DOBCwC{u>&9k+|?qn_qgYwZ5Hwv2*Eg^+nbD=3Ut-)2dsve1vVrXlspm=ESKocCI)xN@_$g`v^;mj~g z&QyQsIR<`2P0ta{Vn8|qVIh11>-Qw|3zcZb0{*51@*fRU@Cm#>{4zOF-Y{!4bp9Rz z6;L3T9X*Bo0Eo?I+XV(4K3rJ-!9J?rlW)b(jx8o^$ANf}&TpfJs*@xZFsaHmLch~7 zk7pcYJ!q@-ecp^iQcA- zE4x`?V33BlB_&A%9-F;&pebd&Z8QI=czTl3pj3ZE>oCZqYkg~E%i}9RdrFu4Y(@74 P0DJpf4mj8Drl0y3`;(!% diff --git a/resources/assets/mekanism/gui/GuiChemicalInfuser.png b/resources/assets/mekanism/gui/GuiChemicalInfuser.png index 2f3bdb90baa70bec70b31a54f8d7b28f2b373a09..362a6f1d5f0d48b4d4af88ac7e4301932d6b4730 100644 GIT binary patch delta 2917 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 delta 2837 zcmbuBc~p~E8pglxBTyn%HkTR;rpO|S2`y0Eh#!g;M1;zYgrFiQ6sYV0$(JYvEUT;n zC5dQdRThP?la2~yN06NWHiT8SU;<&C=**cpbI$af&YAn~J?Fj8`+MH!-up#HIw z6yk1TWM~xx&T{I!#vJwn3+OB(!CFPW40qgW# z_c{&l*;JiAo%O4or{UdaH{zv_RrFRQw)AmVmWnsXl$2))nTw+3wcE9Q4Za2%8S|`+ zc|@>}c2?#W-I}#Vyt$3<(B?8jKf`HwtTI7P zec$xT{-v2X`AX)7c`C zh{);f?akP~arJo`7w`7;w~Yz>k|Q(}(=b-J%SJ$_)5GP5YeHD$rSaCg!B1*k5lY9( zw#_#MV1e_&@FG9jH?#wT{r&y*`*R~lz4}X}oDaaG#*(Vk1D{u4Q9KAKP`OmLyo{a1 z(LYA$h>EAroHWz1N2WfSj3sqUQg@`F)2H6FN#WIoW{8V&Z z&BjKTux!8);}Ve2JoF2*O=N?+K-zN8Jf8Kl8uh?7VP|-yH$RoIxz2N4 z>S7pFtJ*n?^mZ~#aG-mrw96d!3)>KsF!aX6;&9zsD+}SV6b*f+=eLg*+hii<3BdW@ z-qo+v3%Bes;3sRh1Oj$Bx z>t{45T?JJ@%&Q`X0$W@E*E>+F04c(}z6;GkC~%iXyuEXY4i!N-l*W9Er>q&E(7W6So?iJ-Z z=)-on*=sifUUsg&F!}{5pbh9*UF^9gJ)Y1oS?=KK7oY%7xyHn?9FCC2!H%AM%wpax z$5O$_%mzxRPNke>l%;m_v&pSB%MM&U)=cMsScI16=<4$wU?6z)RuXWPa=u+_6bEYo z=Cv{lqNNElQTsXP3t&U{gY=D=U>|6bRBC{r!#L!_hSI4q^MQ$z(v7 z$@i`ku8WrL&KCMx_m}Soul0|Zy_VB|bFGxnU~Spfeg&#gU>D^jt5}ejGdP&h6BjC9 zYzy_Zy)p|QraYB>5h{IhcOM}aW(YZl0nEP{jLy$^t2YNz``DP^7*K$yo3THTCwJ%Mn#L&=Iy7{@#d&ymYk)~$&kDvZpI5OX^V8t*E)ku)m({5}f6F-O z_j`Wa<6LJtVyi~2y(GN+m|6uC7ulhrMVe;VQYtF``0eB7Sat1wHFjTqQ}LBJ+kx`> z=T==GKIQ_G-_+$hTXw^-O5LgPKnHRd)Fln|eXBJx-KowM;Aq8h`5A+=V*xYnT_LiP z1>ngK3x$uN>wJyb)dJ3(ztkvxz2IvHPwq7(+v|Kp#OJl;x~d#(kGw6I?#^q|4pyUf zE7PP>oSZ}WslVyo!)~zEF>Dt!+g)TNuauisTJNDs@3zvhhl(8NGY=XOg~F1_%!GP}23AkF<1q%3I34UBXGK)V&=Z zdZKqPBOI*T9p-0x3*9`C))-UZaMaw|^1Q8H)*igm4?EPT>2AOv18+A-+VWu<1NrH= z2K@&Ey*!Vt+q6MygT7nz%00+qy?I2=7>EgDpoG!|WQ3pkt`gO!_@M=#?BTkPRtqV> zq+HZm^6Qc_GOp^fV^dxk2 z7>)K*r(W_sR;2Rr{ouT^Zl|0jtP#^~qvGOn^fBBmKeTpjE(ZNrJ|5@{JO3Rz8jl5| zy^*|g&`p#oRrg`%_Yhac7~p2)-G?zC8f%v0m&9Iy6xb_I+*RYx!H}`yAtg2KS}N+l z)%mMsm`h}UxAhLcbt=Hm(wv1w7+(A5dlVgKoI|jZDh2+J@Wo2v8#-Pl0iG|1MbCdkE`s}J* z^XE_}w^=eGVSPCtSy+tR!0QL`I{F=tb~ z&s~1OYE*3abLpT%3qkL3p!lLxr1^dt+peI$6Q- z!r}4yKgOwyOPP#1Ij?yndkxoyhHQnCq_ynXy?0_1GiOm2?$vv<9ZKbLa0@GaPluUO m&+p3ygNYrod-lSiv@MB+%y6EyFbe~Sm&w_SM$b+=-}yUMy-WW9 From 123ae05dcd859e7932fafa94346af80f2594bd5b Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Wed, 11 Dec 2013 18:10:01 -0500 Subject: [PATCH 36/40] Cleaned up contractor code --- .../client/render/RenderEMContractor.java | 13 +- .../common/PathfinderEMContractor.java | 103 +++++----- .../induction/common/ThreadEMPathfinding.java | 20 +- .../common/block/BlockEMContractor.java | 2 +- .../common/item/ItemBlockContractor.java | 14 +- .../tileentity/TileEntityEMContractor.java | 183 ++++++++---------- 6 files changed, 150 insertions(+), 185 deletions(-) diff --git a/common/mekanism/induction/client/render/RenderEMContractor.java b/common/mekanism/induction/client/render/RenderEMContractor.java index 641d2216e..860316534 100644 --- a/common/mekanism/induction/client/render/RenderEMContractor.java +++ b/common/mekanism/induction/client/render/RenderEMContractor.java @@ -7,6 +7,7 @@ import mekanism.induction.client.model.ModelEMContractor; import mekanism.induction.common.tileentity.TileEntityEMContractor; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.ForgeDirection; import org.lwjgl.opengl.GL11; @@ -24,7 +25,7 @@ public class RenderEMContractor extends TileEntitySpecialRenderer GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F); GL11.glRotatef(90F, 0.0F, 1.0F, 0.0F); - switch (((TileEntityEMContractor) t).getFacing()) + switch(ForgeDirection.getOrientation(((TileEntityEMContractor)t).getFacing())) { case DOWN: GL11.glRotatef(180, 0, 0, 1); @@ -50,21 +51,19 @@ public class RenderEMContractor extends TileEntitySpecialRenderer break; } - if (((TileEntityEMContractor) t).suck) + if(((TileEntityEMContractor) t).suck) { bindTexture(MekanismUtils.getResource(ResourceType.RENDER, "ElectromagneticContractor.png")); } - else - { + else { bindTexture(MekanismUtils.getResource(ResourceType.RENDER, "ElectromagneticContractorOn.png")); } - if (((TileEntityEMContractor) t).canFunction() && !Mekanism.proxy.isPaused()) + if(((TileEntityEMContractor)t).canFunction() && !Mekanism.proxy.isPaused()) { MODEL_SPIN.render(0.0625f); } - else - { + else { model.render(0.0625f); } diff --git a/common/mekanism/induction/common/PathfinderEMContractor.java b/common/mekanism/induction/common/PathfinderEMContractor.java index 3fa2b1fef..31dec0e83 100644 --- a/common/mekanism/induction/common/PathfinderEMContractor.java +++ b/common/mekanism/induction/common/PathfinderEMContractor.java @@ -9,10 +9,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import mekanism.api.Object3D; import mekanism.induction.common.tileentity.TileEntityEMContractor; import net.minecraft.world.World; import net.minecraftforge.common.ForgeDirection; -import universalelectricity.core.vector.Vector3; /** * Uses the well known A* Pathfinding algorithm. @@ -22,111 +22,108 @@ import universalelectricity.core.vector.Vector3; */ public class PathfinderEMContractor { - public final Set openSet, closedSet; + public final Set openSet, closedSet; - public final HashMap navMap; + public final HashMap navMap; - public final HashMap gScore, fScore; + public final HashMap gScore, fScore; - public final Vector3 target; + public final Object3D target; - public List results; + public List results; private World world; - public PathfinderEMContractor(World world, Vector3 target) + public PathfinderEMContractor(World w, Object3D t) { - this.world = world; - this.target = target; + world = w; + target = t; - /** - * Instantiate Variables - */ - this.openSet = new HashSet(); - this.closedSet = new HashSet(); - this.navMap = new HashMap(); - this.gScore = new HashMap(); - this.fScore = new HashMap(); - this.results = new ArrayList(); + openSet = new HashSet(); + closedSet = new HashSet(); + navMap = new HashMap(); + gScore = new HashMap(); + fScore = new HashMap(); + results = new ArrayList(); } - public boolean find(final Vector3 start) + public boolean find(final Object3D start) { - this.openSet.add(start); - this.gScore.put(start, 0d); - this.fScore.put(start, this.gScore.get(start) + getEstimate(start, this.target)); + openSet.add(start); + gScore.put(start, 0d); + fScore.put(start, gScore.get(start) + getEstimate(start, target)); int blockCount = 0; for (int i = 0; i < 6; i++) { ForgeDirection direction = ForgeDirection.getOrientation(i); - Vector3 neighbor = this.target.clone().translate(new Vector3(direction.offsetX, direction.offsetY, direction.offsetZ)); + Object3D neighbor = target.translate(direction.offsetX, direction.offsetY, direction.offsetZ); - if (!TileEntityEMContractor.canBePath(this.world, neighbor)) + if(!TileEntityEMContractor.canBePath(world, neighbor)) { blockCount++; } } - if (blockCount >= 6) + if(blockCount >= 6) { return false; } - double maxSearchDistance = start.distance(this.target) * 2; + double maxSearchDistance = start.distanceTo(target) * 2; - while (!this.openSet.isEmpty()) + while(!openSet.isEmpty()) { - Vector3 currentNode = null; + Object3D currentNode = null; double lowestFScore = 0; - for (Vector3 node : this.openSet) + for(Object3D node : openSet) { - if (currentNode == null || this.fScore.get(node) < lowestFScore) + if(currentNode == null || fScore.get(node) < lowestFScore) { currentNode = node; - lowestFScore = this.fScore.get(node); + lowestFScore = fScore.get(node); } } - if (currentNode == null && start.distance(currentNode) > maxSearchDistance) + if(currentNode == null && start.distanceTo(currentNode) > maxSearchDistance) { break; } - if (currentNode.equals(this.target)) + if(currentNode.equals(target)) { - this.results = this.reconstructPath(this.navMap, this.target); + results = reconstructPath(navMap, target); return true; } - this.openSet.remove(currentNode); - this.closedSet.add(currentNode); + openSet.remove(currentNode); + closedSet.add(currentNode); - for (int i = 0; i < 6; i++) + for(int i = 0; i < 6; i++) { ForgeDirection direction = ForgeDirection.getOrientation(i); - Vector3 neighbor = currentNode.clone().modifyPositionFromSide(direction); + Object3D neighbor = currentNode.getFromSide(direction); - if (TileEntityEMContractor.canBePath(this.world, neighbor)) + if(TileEntityEMContractor.canBePath(world, neighbor)) { - double tentativeG = this.gScore.get(currentNode) + currentNode.distance(neighbor); + double tentativeG = gScore.get(currentNode) + currentNode.distanceTo(neighbor); - if (this.closedSet.contains(neighbor)) + if(closedSet.contains(neighbor)) { - if (tentativeG >= this.gScore.get(neighbor)) + if(tentativeG >= gScore.get(neighbor)) { continue; } } - if (!this.openSet.contains(neighbor) || tentativeG < this.gScore.get(neighbor)) + if(!openSet.contains(neighbor) || tentativeG < gScore.get(neighbor)) { - this.navMap.put(neighbor, currentNode); - this.gScore.put(neighbor, tentativeG); - this.fScore.put(neighbor, this.gScore.get(neighbor) + this.getEstimate(neighbor, this.target)); - this.openSet.add(neighbor); + navMap.put(neighbor, currentNode); + gScore.put(neighbor, tentativeG); + fScore.put(neighbor, gScore.get(neighbor) + getEstimate(neighbor, target)); + openSet.add(neighbor); } } } @@ -135,21 +132,21 @@ public class PathfinderEMContractor return false; } - private List reconstructPath(HashMap naviMap, Vector3 currentNode) + private List reconstructPath(HashMap naviMap, Object3D currentNode) { - List path = new ArrayList(); + List path = new ArrayList(); path.add(currentNode); - if (naviMap.containsKey(currentNode)) + if(naviMap.containsKey(currentNode)) { - path.addAll(this.reconstructPath(naviMap, naviMap.get(currentNode))); + path.addAll(reconstructPath(naviMap, naviMap.get(currentNode))); } return path; } - private double getEstimate(Vector3 start, Vector3 target2) + private double getEstimate(Object3D start, Object3D target2) { - return start.distance(target2); + return start.distanceTo(target2); } } diff --git a/common/mekanism/induction/common/ThreadEMPathfinding.java b/common/mekanism/induction/common/ThreadEMPathfinding.java index 7c84e6e86..b482a1281 100644 --- a/common/mekanism/induction/common/ThreadEMPathfinding.java +++ b/common/mekanism/induction/common/ThreadEMPathfinding.java @@ -3,7 +3,7 @@ */ package mekanism.induction.common; -import universalelectricity.core.vector.Vector3; +import mekanism.api.Object3D; /** * @author Calclavia @@ -13,27 +13,27 @@ public class ThreadEMPathfinding extends Thread { private boolean isCompleted = false; private PathfinderEMContractor pathfinder; - private Vector3 start; + private Object3D start; - public ThreadEMPathfinding(PathfinderEMContractor pathfinder, Vector3 start) + public ThreadEMPathfinding(PathfinderEMContractor p, Object3D s) { - this.pathfinder = pathfinder; - this.start = start; - this.setPriority(Thread.MIN_PRIORITY); + pathfinder = p; + start = s; + setPriority(Thread.MIN_PRIORITY); } @Override public void run() { - this.pathfinder.find(this.start); - this.isCompleted = true; + pathfinder.find(start); + isCompleted = true; } public PathfinderEMContractor getPath() { - if (this.isCompleted) + if(isCompleted) { - return this.pathfinder; + return pathfinder; } return null; diff --git a/common/mekanism/induction/common/block/BlockEMContractor.java b/common/mekanism/induction/common/block/BlockEMContractor.java index 90497c288..e8b8dc2c4 100644 --- a/common/mekanism/induction/common/block/BlockEMContractor.java +++ b/common/mekanism/induction/common/block/BlockEMContractor.java @@ -110,7 +110,7 @@ public class BlockEMContractor extends Block implements ITileEntityProvider if(tileEntity instanceof IInventory) { - tileContractor.setFacing(side.getOpposite()); + tileContractor.setFacing((short)side.getOpposite().ordinal()); return; } } diff --git a/common/mekanism/induction/common/item/ItemBlockContractor.java b/common/mekanism/induction/common/item/ItemBlockContractor.java index 4d4a844f2..a35104dc2 100644 --- a/common/mekanism/induction/common/item/ItemBlockContractor.java +++ b/common/mekanism/induction/common/item/ItemBlockContractor.java @@ -21,20 +21,20 @@ public class ItemBlockContractor extends ItemBlock { boolean place = super.placeBlockAt(stack, player, world, x, y, z, side, hitX, hitY, hitZ, metadata); - if (place) + if(place) { - TileEntityEMContractor tileContractor = (TileEntityEMContractor) world.getBlockTileEntity(x, y, z); - tileContractor.setFacing(ForgeDirection.getOrientation(side)); + TileEntityEMContractor tileContractor = (TileEntityEMContractor)world.getBlockTileEntity(x, y, z); + tileContractor.setFacing((short)ForgeDirection.getOrientation(side).ordinal()); - if (!tileContractor.isLatched()) + if(!tileContractor.isLatched()) { - for (ForgeDirection side1 : ForgeDirection.VALID_DIRECTIONS) + for(ForgeDirection side1 : ForgeDirection.VALID_DIRECTIONS) { TileEntity tileEntity = world.getBlockTileEntity(x + side1.offsetX, y + side1.offsetY, z + side1.offsetZ); - if (tileEntity instanceof IInventory) + if(tileEntity instanceof IInventory) { - tileContractor.setFacing(side1.getOpposite()); + tileContractor.setFacing((short)side1.getOpposite().ordinal()); break; } } diff --git a/common/mekanism/induction/common/tileentity/TileEntityEMContractor.java b/common/mekanism/induction/common/tileentity/TileEntityEMContractor.java index 2660b5ed6..18a92575d 100644 --- a/common/mekanism/induction/common/tileentity/TileEntityEMContractor.java +++ b/common/mekanism/induction/common/tileentity/TileEntityEMContractor.java @@ -6,11 +6,10 @@ import java.util.List; import java.util.Set; import mekanism.api.Object3D; -import mekanism.common.ITileNetwork; import mekanism.common.PacketHandler; import mekanism.common.PacketHandler.Transmission; import mekanism.common.network.PacketDataRequest; -import mekanism.common.network.PacketTileEntity; +import mekanism.common.tileentity.TileEntityBasicBlock; import mekanism.common.util.InventoryUtils; import mekanism.induction.common.MekanismInduction; import mekanism.induction.common.PathfinderEMContractor; @@ -30,16 +29,10 @@ import net.minecraft.world.World; import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.fluids.IFluidBlock; import universalelectricity.core.vector.Vector3; -import universalelectricity.prefab.tile.TileEntityAdvanced; import com.google.common.io.ByteArrayDataInput; -/** - * - * @author AidanBrady - * - */ -public class TileEntityEMContractor extends TileEntityAdvanced implements ITileNetwork +public class TileEntityEMContractor extends TileEntityBasicBlock { public static int MAX_REACH = 40; public static int PUSH_DELAY = 5; @@ -50,17 +43,12 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN private AxisAlignedBB operationBounds; private AxisAlignedBB suckBounds; - - public ForgeDirection facing = ForgeDirection.UP; /** * true = suck, false = push */ public boolean suck = true; - /** - * Pathfinding - */ private ThreadEMPathfinding thread; private PathfinderEMContractor pathfinder; private Set pathfindingTrackers = new HashSet(); @@ -69,19 +57,15 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN /** Color of beam */ private int dyeID = TileEntityTesla.DEFAULT_COLOR; - private Vector3 tempLinkVector; + private Object3D tempLinkVector; @Override - public void initiate() + public void onUpdate() { - super.initiate(); - updateBounds(); - } - - @Override - public void updateEntity() - { - super.updateEntity(); + if(ticker == 1) + { + updateBounds(); + } pushDelay = Math.max(0, pushDelay - 1); @@ -102,7 +86,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN if(!suck && pushDelay == 0) { - ItemStack retrieved = InventoryUtils.takeTopItemFromInventory(inventory, getFacing().getOpposite().ordinal()); + ItemStack retrieved = InventoryUtils.takeTopItemFromInventory(inventory, ForgeDirection.OPPOSITES[getFacing()]); if(retrieved != null) { @@ -124,7 +108,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN { for(EntityItem item : (List)worldObj.getEntitiesWithinAABB(EntityItem.class, suckBounds)) { - ItemStack remains = InventoryUtils.putStackInInventory(inventory, item.getEntityItem(), getFacing().getOpposite().ordinal(), false); + ItemStack remains = InventoryUtils.putStackInInventory(inventory, item.getEntityItem(), ForgeDirection.OPPOSITES[getFacing()], false); if(remains == null) { @@ -150,7 +134,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN } final int renderFrequency = MekanismInduction.proxy.isFancy() ? 1 + worldObj.rand.nextInt(2) : 10 + worldObj.rand.nextInt(2); - final boolean renderBeam = ticks % renderFrequency == 0 && hasLink() && linked.suck != suck; + final boolean renderBeam = ticker % renderFrequency == 0 && hasLink() && linked.suck != suck; if(hasLink()) { @@ -166,23 +150,23 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN { for(int i = 0; i < pathfinder.results.size(); i++) { - Vector3 result = pathfinder.results.get(i).clone(); + Object3D result = pathfinder.results.get(i); if(TileEntityEMContractor.canBePath(worldObj, result)) { if(i - 1 >= 0) { - Vector3 prevResult = pathfinder.results.get(i - 1).clone(); + Object3D prevResult = pathfinder.results.get(i - 1); - Vector3 difference = prevResult.clone().difference(result); - final ForgeDirection direction = difference.toForgeDirection(); + Object3D difference = prevResult.difference(result); + final ForgeDirection direction = toForge(difference); if(renderBeam) { - MekanismInduction.proxy.renderElectricShock(worldObj, prevResult.clone().translate(0.5), result.clone().translate(0.5), MekanismInduction.DYE_COLORS[dyeID], false); + MekanismInduction.proxy.renderElectricShock(worldObj, toVec(prevResult).translate(0.5), toVec(result).translate(0.5), MekanismInduction.DYE_COLORS[dyeID], false); } - AxisAlignedBB bounds = AxisAlignedBB.getAABBPool().getAABB(result.x, result.y, result.z, result.x + 1, result.y + 1, result.z + 1); + AxisAlignedBB bounds = AxisAlignedBB.getAABBPool().getAABB(result.xCoord, result.yCoord, result.zCoord, result.xCoord + 1, result.yCoord + 1, result.zCoord + 1); List entities = worldObj.getEntitiesWithinAABB(EntityItem.class, bounds); for(EntityItem entityItem : entities) @@ -210,8 +194,8 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN pathfinder = null; - Vector3 searchVec = new Vector3(this).modifyPositionFromSide(getFacing()); - AxisAlignedBB searchBounds = AxisAlignedBB.getAABBPool().getAABB(searchVec.x, searchVec.y, searchVec.z, searchVec.x + 1, searchVec.y + 1, searchVec.z + 1); + Object3D searchVec = Object3D.get(this).getFromSide(ForgeDirection.getOrientation(getFacing())); + AxisAlignedBB searchBounds = AxisAlignedBB.getAABBPool().getAABB(searchVec.xCoord, searchVec.yCoord, searchVec.zCoord, searchVec.xCoord + 1, searchVec.yCoord + 1, searchVec.zCoord + 1); if(searchBounds != null) { @@ -222,7 +206,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN MekanismInduction.proxy.renderElectricShock(worldObj, new Vector3(this).translate(0.5), new Vector3(entityItem), MekanismInduction.DYE_COLORS[dyeID], false); } - moveEntity(entityItem, getFacing(), new Vector3(this)); + moveEntity(entityItem, ForgeDirection.getOrientation(getFacing()), Object3D.get(this)); } } } @@ -231,7 +215,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN { for(EntityItem entityItem : (List)worldObj.getEntitiesWithinAABB(EntityItem.class, operationBounds)) { - moveEntity(entityItem, getFacing(), new Vector3(this)); + moveEntity(entityItem, ForgeDirection.getOrientation(getFacing()), Object3D.get(this)); } } @@ -243,10 +227,28 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN lastCalcTime--; } } - - public static boolean canBePath(World world, Vector3 position) + + private static Vector3 toVec(Object3D obj) { - Block block = Block.blocksList[position.getBlockID(world)]; + return new Vector3(obj.xCoord, obj.yCoord, obj.zCoord); + } + + private static ForgeDirection toForge(Object3D obj) + { + for(ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) + { + if(side.offsetX == obj.xCoord && side.offsetY == obj.yCoord && side.offsetZ == obj.zCoord) + { + return side; + } + } + + return ForgeDirection.UNKNOWN; + } + + public static boolean canBePath(World world, Object3D position) + { + Block block = Block.blocksList[position.getBlockId(world)]; return block == null || (block instanceof BlockSnow || block instanceof BlockVine || block instanceof BlockLadder || ((block instanceof BlockFluid || block instanceof IFluidBlock) && block.blockID != Block.lavaMoving.blockID && block.blockID != Block.lavaStill.blockID)); } @@ -255,12 +257,12 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN return linked != null && !linked.isInvalid() && linked.linked == this; } - private void moveEntity(EntityItem entityItem, ForgeDirection direction, Vector3 lockVector) + private void moveEntity(EntityItem entityItem, ForgeDirection direction, Object3D lockVector) { switch(direction) { case DOWN: - entityItem.setPosition(lockVector.x + 0.5, entityItem.posY, lockVector.z + 0.5); + entityItem.setPosition(lockVector.xCoord + 0.5, entityItem.posY, lockVector.zCoord + 0.5); entityItem.motionX = 0; entityItem.motionZ = 0; @@ -275,8 +277,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN break; case UP: - - entityItem.setPosition(lockVector.x + 0.5, entityItem.posY, lockVector.z + 0.5); + entityItem.setPosition(lockVector.xCoord + 0.5, entityItem.posY, lockVector.zCoord + 0.5); entityItem.motionX = 0; entityItem.motionZ = 0; @@ -291,8 +292,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN break; case NORTH: - - entityItem.setPosition(lockVector.x + 0.5, lockVector.y + 0.5, entityItem.posZ); + entityItem.setPosition(lockVector.xCoord + 0.5, lockVector.yCoord + 0.5, entityItem.posZ); entityItem.motionX = 0; entityItem.motionY = 0; @@ -307,8 +307,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN break; case SOUTH: - - entityItem.setPosition(lockVector.x + 0.5, lockVector.y + 0.5, entityItem.posZ); + entityItem.setPosition(lockVector.xCoord + 0.5, lockVector.yCoord + 0.5, entityItem.posZ); entityItem.motionX = 0; entityItem.motionY = 0; @@ -323,8 +322,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN break; case WEST: - - entityItem.setPosition(entityItem.posX, lockVector.y + 0.5, lockVector.z + 0.5); + entityItem.setPosition(entityItem.posX, lockVector.yCoord + 0.5, lockVector.zCoord + 0.5); entityItem.motionY = 0; entityItem.motionZ = 0; @@ -339,7 +337,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN break; case EAST: - entityItem.setPosition(entityItem.posX, lockVector.y + 0.5, lockVector.z + 0.5); + entityItem.setPosition(entityItem.posX, lockVector.yCoord + 0.5, lockVector.zCoord + 0.5); entityItem.motionY = 0; entityItem.motionZ = 0; @@ -367,7 +365,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN { EntityItem item = null; - switch (getFacing()) + switch(ForgeDirection.getOrientation(getFacing())) { case DOWN: item = new EntityItem(worldObj, xCoord + 0.5, yCoord - 0.2, zCoord + 0.5, toSend); @@ -398,20 +396,9 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN return item; } - @Override - public void validate() - { - super.validate(); - - if(worldObj.isRemote) - { - PacketHandler.sendPacket(Transmission.SERVER, new PacketDataRequest().setParams(Object3D.get(this))); - } - } - public void updateBounds() { - switch (getFacing()) + switch(ForgeDirection.getOrientation(getFacing())) { case DOWN: operationBounds = AxisAlignedBB.getBoundingBox(xCoord, Math.max(yCoord - MAX_REACH, 1), zCoord, xCoord + 1, yCoord, zCoord + 1); @@ -449,7 +436,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN public TileEntity getLatched() { - ForgeDirection side = getFacing().getOpposite(); + ForgeDirection side = ForgeDirection.getOrientation(getFacing()).getOpposite(); TileEntity tile = worldObj.getBlockTileEntity(xCoord + side.offsetX, yCoord + side.offsetY, zCoord + side.offsetZ); @@ -463,25 +450,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN public void incrementFacing() { - int newOrdinal = getFacing().ordinal() < 5 ? getFacing().ordinal() + 1 : 0; - setFacing(ForgeDirection.getOrientation(newOrdinal)); - } - - public ForgeDirection getFacing() - { - return facing; - } - - public void setFacing(ForgeDirection side) - { - facing = side; - - if(!worldObj.isRemote) - { - PacketHandler.sendPacket(Transmission.ALL_CLIENTS, new PacketTileEntity().setParams(Object3D.get(this), getNetworkedData(new ArrayList()))); - } - - updateBounds(); + setFacing((short)(facing == 5 ? 0 : facing+1)); } public boolean canFunction() @@ -490,45 +459,44 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN } @Override - public void readFromNBT(NBTTagCompound nbt) + public void readFromNBT(NBTTagCompound nbtTags) { - super.readFromNBT(nbt); + super.readFromNBT(nbtTags); - facing = ForgeDirection.getOrientation(nbt.getInteger("facing")); - suck = nbt.getBoolean("suck"); - dyeID = nbt.getInteger("dyeID"); + suck = nbtTags.getBoolean("suck"); + dyeID = nbtTags.getInteger("dyeID"); - if(nbt.hasKey("link")) + if(nbtTags.hasKey("link")) { - tempLinkVector = new Vector3(nbt.getCompoundTag("link")); + tempLinkVector = Object3D.read(nbtTags.getCompoundTag("link")); } } @Override - public void writeToNBT(NBTTagCompound nbt) + public void writeToNBT(NBTTagCompound nbtTags) { - super.writeToNBT(nbt); + super.writeToNBT(nbtTags); - nbt.setInteger("facing", facing.ordinal()); - nbt.setBoolean("suck", suck); - nbt.setInteger("dyeID", dyeID); + nbtTags.setBoolean("suck", suck); + nbtTags.setInteger("dyeID", dyeID); if(linked != null) { - nbt.setCompoundTag("link", new Vector3(linked).writeToNBT(new NBTTagCompound())); + nbtTags.setCompoundTag("link", Object3D.get(linked).write(new NBTTagCompound())); } } @Override - public void handlePacketData(ByteArrayDataInput input) + public void handlePacketData(ByteArrayDataInput dataStream) { - facing = ForgeDirection.getOrientation(input.readInt()); - suck = input.readBoolean(); - dyeID = input.readInt(); + super.handlePacketData(dataStream); + + suck = dataStream.readBoolean(); + dyeID = dataStream.readInt(); - if(input.readBoolean()) + if(dataStream.readBoolean()) { - tempLinkVector = new Vector3(input.readInt(), input.readInt(), input.readInt()); + tempLinkVector = new Object3D(dataStream.readInt(), dataStream.readInt(), dataStream.readInt()); } worldObj.markBlockForRenderUpdate(xCoord, yCoord, zCoord); @@ -538,7 +506,8 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN @Override public ArrayList getNetworkedData(ArrayList data) { - data.add(facing.ordinal()); + super.getNetworkedData(data); + data.add(suck); data.add(dyeID); @@ -583,10 +552,10 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements ITileN { pathfinder = null; - Vector3 start = new Vector3(this).modifyPositionFromSide(getFacing()); - Vector3 target = new Vector3(linked).modifyPositionFromSide(linked.getFacing()); + Object3D start = Object3D.get(this).getFromSide(ForgeDirection.getOrientation(getFacing())); + Object3D target = Object3D.get(linked).getFromSide(ForgeDirection.getOrientation(linked.getFacing())); - if(start.distance(target) < MekanismInduction.MAX_CONTRACTOR_DISTANCE) + if(start.distanceTo(target) < MekanismInduction.MAX_CONTRACTOR_DISTANCE) { if(TileEntityEMContractor.canBePath(worldObj, start) && TileEntityEMContractor.canBePath(worldObj, target)) { From 7a3c678d7623c2ca2e4d9fd05b1d98b8107830f5 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Wed, 11 Dec 2013 18:26:10 -0500 Subject: [PATCH 37/40] Work on new machines --- common/mekanism/common/RecipeHandler.java | 6 +-- .../ContainerChemicalFormulator.java | 44 +++++++++---------- .../container/ContainerChemicalInfuser.java | 40 +++++++---------- .../ContainerMetallurgicInfuser.java | 2 +- .../tileentity/TileEntityChemicalInfuser.java | 5 +++ .../TileEntityMetallurgicInfuser.java | 6 +-- 6 files changed, 50 insertions(+), 53 deletions(-) diff --git a/common/mekanism/common/RecipeHandler.java b/common/mekanism/common/RecipeHandler.java index 60ab79c3b..1db05e69c 100644 --- a/common/mekanism/common/RecipeHandler.java +++ b/common/mekanism/common/RecipeHandler.java @@ -98,7 +98,7 @@ public final class RecipeHandler * @param recipes - Map of recipes * @return InfusionOutput */ - public static InfusionOutput getOutput(InfusionInput infusion, boolean stackDecrease) + public static InfusionOutput getMetallurgicInfuserOutput(InfusionInput infusion, boolean stackDecrease) { if(infusion != null && infusion.inputStack != null) { @@ -126,7 +126,7 @@ public final class RecipeHandler return null; } - public static GasStack getOutput(ChemicalInput input) + public static GasStack getChemicalInfuserOutput(ChemicalInput input) { if(input != null && input.isValid()) { @@ -137,7 +137,7 @@ public final class RecipeHandler return null; } - public GasStack getOutput(ItemStack itemstack, boolean stackDecrease) + public static GasStack getChemicalFormulatorOutput(ItemStack itemstack, boolean stackDecrease) { if(itemstack != null) { diff --git a/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java b/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java index d6ae8260f..6a7ca250c 100644 --- a/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java +++ b/common/mekanism/common/inventory/container/ContainerChemicalFormulator.java @@ -1,9 +1,10 @@ package mekanism.common.inventory.container; +import mekanism.api.gas.IGasItem; +import mekanism.common.RecipeHandler; import mekanism.common.inventory.slot.SlotEnergy.SlotDischarge; import mekanism.common.inventory.slot.SlotStorageTank; -import mekanism.common.item.ItemMachineUpgrade; -import mekanism.common.tileentity.TileEntityChemicalInfuser; +import mekanism.common.tileentity.TileEntityChemicalFormulator; import mekanism.common.util.ChargeUtils; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; @@ -13,21 +14,20 @@ import net.minecraft.item.ItemStack; public class ContainerChemicalFormulator extends Container { - private TileEntityChemicalInfuser tileEntity; + private TileEntityChemicalFormulator tileEntity; - public ContainerChemicalFormulator(InventoryPlayer inventory, TileEntityChemicalInfuser tentity) + public ContainerChemicalFormulator(InventoryPlayer inventory, TileEntityChemicalFormulator tentity) { tileEntity = tentity; - addSlotToContainer(new SlotStorageTank(tentity, null, true, 0, 5, 56)); - addSlotToContainer(new SlotStorageTank(tentity, null, true, 1, 80, 65)); - addSlotToContainer(new SlotStorageTank(tentity, null, true, 2, 155, 56)); - addSlotToContainer(new SlotDischarge(tentity, 3, 155, 5)); - + addSlotToContainer(new Slot(tentity, 0, 26, 36)); + addSlotToContainer(new SlotDischarge(tentity, 1, 155, 5)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 2, 155, 25)); + int slotX; - for(slotX = 0; slotX < 3; slotX++) + for(slotX = 0; slotX < 3; ++slotX) { - for(int slotY = 0; slotY < 9; slotY++) + for(int slotY = 0; slotY < 9; ++slotY) { addSlotToContainer(new Slot(inventory, slotY + slotX * 9 + 9, 8 + slotY * 18, 84 + slotX * 18)); } @@ -68,9 +68,9 @@ public class ContainerChemicalFormulator extends Container ItemStack slotStack = currentSlot.getStack(); stack = slotStack.copy(); - if(slotID == 2) + if(RecipeHandler.getChemicalFormulatorOutput(slotStack, false) != null) { - if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + if(!mergeItemStack(slotStack, 0, 1, true)) { return null; } @@ -86,45 +86,45 @@ public class ContainerChemicalFormulator extends Container } else if(slotID == 1) { - if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + if(!mergeItemStack(slotStack, 3, inventorySlots.size(), true)) { return null; } } } - else if(slotStack.getItem() instanceof ItemMachineUpgrade) + else if(slotStack.getItem() instanceof IGasItem) { - if(slotID != 0 && slotID != 1 && slotID != 2 && slotID != 3) + if(slotID != 0 && slotID != 1 && slotID != 2) { - if(!mergeItemStack(slotStack, 3, 4, false)) + if(!mergeItemStack(slotStack, 2, 3, false)) { return null; } } else { - if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + if(!mergeItemStack(slotStack, 3, inventorySlots.size(), true)) { return null; } } } else { - if(slotID >= 4 && slotID <= 30) + if(slotID >= 3 && slotID <= 29) { - if(!mergeItemStack(slotStack, 31, inventorySlots.size(), false)) + if(!mergeItemStack(slotStack, 30, inventorySlots.size(), false)) { return null; } } else if(slotID > 30) { - if(!mergeItemStack(slotStack, 4, 30, false)) + if(!mergeItemStack(slotStack, 3, 29, false)) { return null; } } else { - if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + if(!mergeItemStack(slotStack, 3, inventorySlots.size(), true)) { return null; } diff --git a/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java b/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java index 7daead959..decfd139e 100644 --- a/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java +++ b/common/mekanism/common/inventory/container/ContainerChemicalInfuser.java @@ -1,9 +1,7 @@ package mekanism.common.inventory.container; -import mekanism.common.RecipeHandler; +import mekanism.api.gas.IGasItem; import mekanism.common.inventory.slot.SlotEnergy.SlotDischarge; -import mekanism.common.inventory.slot.SlotMachineUpgrade; -import mekanism.common.inventory.slot.SlotOutput; import mekanism.common.inventory.slot.SlotStorageTank; import mekanism.common.item.ItemMachineUpgrade; import mekanism.common.tileentity.TileEntityChemicalInfuser; @@ -21,15 +19,16 @@ public class ContainerChemicalInfuser extends Container public ContainerChemicalInfuser(InventoryPlayer inventory, TileEntityChemicalInfuser tentity) { tileEntity = tentity; - addSlotToContainer(new Slot(tentity, 0, 26, 36)); - addSlotToContainer(new SlotDischarge(tentity, 1, 155, 5)); - addSlotToContainer(new SlotStorageTank(tentity, null, true, 2, 155, 25)); - + addSlotToContainer(new SlotStorageTank(tentity, null, true, 0, 5, 56)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 1, 155, 56)); + addSlotToContainer(new SlotStorageTank(tentity, null, true, 2, 80, 65)); + addSlotToContainer(new SlotDischarge(tentity, 3, 155, 5)); + int slotX; - for(slotX = 0; slotX < 3; ++slotX) + for(slotX = 0; slotX < 3; slotX++) { - for(int slotY = 0; slotY < 9; ++slotY) + for(int slotY = 0; slotY < 9; slotY++) { addSlotToContainer(new Slot(inventory, slotY + slotX * 9 + 9, 8 + slotY * 18, 84 + slotX * 18)); } @@ -70,23 +69,16 @@ public class ContainerChemicalInfuser extends Container ItemStack slotStack = currentSlot.getStack(); stack = slotStack.copy(); - if(slotID == 2) + if(ChargeUtils.canBeDischarged(slotStack)) { - if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) - { - return null; - } - } - else if(ChargeUtils.canBeDischarged(slotStack)) - { - if(slotID != 1) + if(slotID != 3) { - if(!mergeItemStack(slotStack, 1, 2, false)) + if(!mergeItemStack(slotStack, 3, 4, false)) { return null; } } - else if(slotID == 1) + else if(slotID == 3) { if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) { @@ -94,17 +86,17 @@ public class ContainerChemicalInfuser extends Container } } } - else if(slotStack.getItem() instanceof ItemMachineUpgrade) + else if(slotStack.getItem() instanceof IGasItem) { - if(slotID != 0 && slotID != 1 && slotID != 2 && slotID != 3) + if(slotID != 0 && slotID != 1 && slotID != 2) { - if(!mergeItemStack(slotStack, 3, 4, false)) + if(!mergeItemStack(slotStack, 0, 3, false)) { return null; } } else { - if(!mergeItemStack(slotStack, 4, inventorySlots.size(), true)) + if(!mergeItemStack(slotStack, 5, inventorySlots.size(), true)) { return null; } diff --git a/common/mekanism/common/inventory/container/ContainerMetallurgicInfuser.java b/common/mekanism/common/inventory/container/ContainerMetallurgicInfuser.java index 80066d0aa..2b42c151b 100644 --- a/common/mekanism/common/inventory/container/ContainerMetallurgicInfuser.java +++ b/common/mekanism/common/inventory/container/ContainerMetallurgicInfuser.java @@ -156,7 +156,7 @@ public class ContainerMetallurgicInfuser extends Container { if(tileEntity.type != null) { - if(RecipeHandler.getOutput(InfusionInput.getInfusion(tileEntity.type, tileEntity.infuseStored, itemStack), false) != null) + if(RecipeHandler.getMetallurgicInfuserOutput(InfusionInput.getInfusion(tileEntity.type, tileEntity.infuseStored, itemStack), false) != null) { return true; } diff --git a/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java b/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java index 622fc4189..12a950162 100644 --- a/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java +++ b/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java @@ -1,7 +1,12 @@ package mekanism.common.tileentity; +import mekanism.api.gas.GasStack; + public class TileEntityChemicalInfuser extends TileEntityElectricBlock { + public GasStack leftStack; + public GasStack rightStack; + public TileEntityChemicalInfuser() { super("ChemicalInfuser", 0 /*TODO*/); diff --git a/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java b/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java index b5fe4e704..8a2c8b47e 100644 --- a/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java +++ b/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java @@ -226,7 +226,7 @@ public class TileEntityMetallurgicInfuser extends TileEntityElectricBlock implem { if(type != null) { - if(RecipeHandler.getOutput(InfusionInput.getInfusion(type, infuseStored, itemstack), false) != null) + if(RecipeHandler.getMetallurgicInfuserOutput(InfusionInput.getInfusion(type, infuseStored, itemstack), false) != null) { return true; } @@ -257,7 +257,7 @@ public class TileEntityMetallurgicInfuser extends TileEntityElectricBlock implem return; } - InfusionOutput output = RecipeHandler.getOutput(InfusionInput.getInfusion(type, infuseStored, inventory[2]), true); + InfusionOutput output = RecipeHandler.getMetallurgicInfuserOutput(InfusionInput.getInfusion(type, infuseStored, inventory[2]), true); infuseStored -= output.getInfuseRequired(); @@ -284,7 +284,7 @@ public class TileEntityMetallurgicInfuser extends TileEntityElectricBlock implem return false; } - InfusionOutput output = RecipeHandler.getOutput(InfusionInput.getInfusion(type, infuseStored, inventory[2]), false); + InfusionOutput output = RecipeHandler.getMetallurgicInfuserOutput(InfusionInput.getInfusion(type, infuseStored, inventory[2]), false); if(output == null) { From 6114463852343652956ac9ff907adc313b81c93b Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Wed, 11 Dec 2013 19:53:12 -0500 Subject: [PATCH 38/40] Work on TileEntity code of Chemical Formulator --- common/mekanism/common/Mekanism.java | 2 + .../TileEntityAdvancedElectricMachine.java | 2 +- .../TileEntityChemicalFormulator.java | 365 +++++++++++++- .../tileentity/TileEntityChemicalInfuser.java | 463 +++++++++++++++++- .../tileentity/TileEntityElectricMachine.java | 2 +- .../common/tileentity/TileEntityFactory.java | 2 +- .../TileEntityMetallurgicInfuser.java | 2 +- 7 files changed, 831 insertions(+), 7 deletions(-) diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index 8195b23b7..eabe48eef 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -281,6 +281,8 @@ public class Mekanism public static double energizedSmelterUsage; public static double digitalMinerUsage; public static double rotaryCondensentratorUsage; + public static double chemicalFormulatorUsage; + public static double chemicalInfuserUsage; /** * Adds all in-game crafting and smelting recipes. diff --git a/common/mekanism/common/tileentity/TileEntityAdvancedElectricMachine.java b/common/mekanism/common/tileentity/TileEntityAdvancedElectricMachine.java index b698a72b3..5dc50bd12 100644 --- a/common/mekanism/common/tileentity/TileEntityAdvancedElectricMachine.java +++ b/common/mekanism/common/tileentity/TileEntityAdvancedElectricMachine.java @@ -168,7 +168,7 @@ public abstract class TileEntityAdvancedElectricMachine extends TileEntityBasicM return getFuelTicks(itemstack) > 0; } - return true; + return false; } @Override diff --git a/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java b/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java index 567dd33c0..abdeaf147 100644 --- a/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java +++ b/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java @@ -1,9 +1,372 @@ package mekanism.common.tileentity; -public class TileEntityChemicalFormulator extends TileEntityElectricBlock +import java.util.ArrayList; + +import mekanism.api.Object3D; +import mekanism.api.gas.GasRegistry; +import mekanism.api.gas.GasStack; +import mekanism.api.gas.GasTransmission; +import mekanism.api.gas.IGasAcceptor; +import mekanism.api.gas.IGasItem; +import mekanism.api.gas.IGasStorage; +import mekanism.api.gas.ITubeConnection; +import mekanism.common.IActiveState; +import mekanism.common.IRedstoneControl; +import mekanism.common.Mekanism; +import mekanism.common.PacketHandler; +import mekanism.common.PacketHandler.Transmission; +import mekanism.common.RecipeHandler; +import mekanism.common.network.PacketTileEntity; +import mekanism.common.util.ChargeUtils; +import mekanism.common.util.MekanismUtils; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.ForgeDirection; + +import com.google.common.io.ByteArrayDataInput; + +public class TileEntityChemicalFormulator extends TileEntityElectricBlock implements IActiveState, IGasStorage, ITubeConnection, IRedstoneControl { + public GasStack gasTank; + + public static final int MAX_GAS = 10000; + + public int updateDelay; + + public int gasOutput = 16; + + public boolean isActive; + + public boolean clientActive; + + public double prevEnergy; + + public int operatingTicks = 0; + + public int TICKS_REQUIRED = 100; + + public final double ENERGY_USAGE = Mekanism.rotaryCondensentratorUsage; + + public RedstoneControl controlType = RedstoneControl.DISABLED; + public TileEntityChemicalFormulator() { super("ChemicalFormulator", 0 /*TODO*/); + inventory = new ItemStack[3]; + } + + @Override + public void onUpdate() + { + if(worldObj.isRemote) + { + if(updateDelay > 0) + { + updateDelay--; + + if(updateDelay == 0 && clientActive != isActive) + { + isActive = clientActive; + MekanismUtils.updateBlock(worldObj, xCoord, yCoord, zCoord); + } + } + } + + if(!worldObj.isRemote) + { + if(updateDelay > 0) + { + updateDelay--; + + if(updateDelay == 0 && clientActive != isActive) + { + PacketHandler.sendPacket(Transmission.ALL_CLIENTS, new PacketTileEntity().setParams(Object3D.get(this), getNetworkedData(new ArrayList()))); + } + } + + ChargeUtils.discharge(1, this); + + if(getGas() != null) + { + if(inventory[2] != null) + { + setGas(new GasStack(getGas().getGas(), getGas().amount - GasTransmission.addGas(inventory[2], getGas()))); + } + } + + if(canOperate() && getEnergy() >= ENERGY_USAGE && MekanismUtils.canFunction(this)) + { + setActive(true); + setEnergy(getEnergy() - ENERGY_USAGE); + + if(operatingTicks < TICKS_REQUIRED) + { + operatingTicks++; + } + else { + GasStack stack = RecipeHandler.getChemicalFormulatorOutput(inventory[0], true); + + setGas(new GasStack(stack.getGas(), getStoredGas()+stack.amount)); + operatingTicks = 0; + } + } + else { + if(prevEnergy >= getEnergy()) + { + setActive(false); + } + } + + prevEnergy = getEnergy(); + + if(getGas() != null) + { + GasStack toSend = new GasStack(getGas().getGas(), Math.min(getGas().amount, gasOutput)); + setGas(new GasStack(getGas().getGas(), getGas().amount - GasTransmission.emitGasToNetwork(toSend, this, MekanismUtils.getLeft(facing)))); + + TileEntity tileEntity = Object3D.get(this).getFromSide(MekanismUtils.getRight(facing)).getTileEntity(worldObj); + + if(tileEntity instanceof IGasAcceptor) + { + if(((IGasAcceptor)tileEntity).canReceiveGas(MekanismUtils.getLeft(facing).getOpposite(), getGas().getGas())) + { + int added = ((IGasAcceptor)tileEntity).receiveGas(new GasStack(getGas().getGas(), Math.min(getGas().amount, gasOutput))); + + setGas(new GasStack(getGas().getGas(), getGas().amount - added)); + } + } + } + } + } + + @Override + public boolean isItemValidForSlot(int slotID, ItemStack itemstack) + { + if(slotID == 0) + { + return RecipeHandler.getChemicalFormulatorOutput(itemstack, false) != null; + } + else if(slotID == 1) + { + return ChargeUtils.canBeDischarged(itemstack); + } + + return false; + } + + @Override + public boolean canExtractItem(int slotID, ItemStack itemstack, int side) + { + if(slotID == 2) + { + return inventory[2] != null && inventory[2].getItem() instanceof IGasItem && ((IGasItem)inventory[2].getItem()).canProvideGas(inventory[2], null); + } + + return false; + } + + @Override + public int[] getAccessibleSlotsFromSide(int side) + { + if(side == MekanismUtils.getLeft(facing).ordinal()) + { + return new int[] {0}; + } + else if(side == 0 || side == 1) + { + return new int[] {1}; + } + else if(side == MekanismUtils.getRight(facing).ordinal()) + { + return new int[] {2}; + } + + return new int[0]; + } + + public int getStoredGas() + { + return gasTank != null ? gasTank.amount : 0; + } + + public int getScaledProgress(int i) + { + return operatingTicks*i / TICKS_REQUIRED; + } + + public boolean canOperate() + { + if(inventory[0] == null) + { + return false; + } + + GasStack stack = RecipeHandler.getChemicalFormulatorOutput(inventory[0], false); + + if(stack == null || (getGas() != null && (getGas().getGas() != stack.getGas() || getMaxGas()-getGas().amount < stack.amount))) + { + return false; + } + + return true; + } + + @Override + public void handlePacketData(ByteArrayDataInput dataStream) + { + super.handlePacketData(dataStream); + + isActive = dataStream.readBoolean(); + controlType = RedstoneControl.values()[dataStream.readInt()]; + operatingTicks = dataStream.readInt(); + + if(dataStream.readBoolean()) + { + gasTank = new GasStack(GasRegistry.getGas(dataStream.readInt()), dataStream.readInt()); + } + else { + gasTank = null; + } + + + MekanismUtils.updateBlock(worldObj, xCoord, yCoord, zCoord); + } + + @Override + public ArrayList getNetworkedData(ArrayList data) + { + super.getNetworkedData(data); + + data.add(isActive); + data.add(controlType.ordinal()); + data.add(operatingTicks); + + if(gasTank != null) + { + data.add(true); + data.add(gasTank.getGas().getID()); + data.add(gasTank.amount); + } + else { + data.add(false); + } + + return data; + } + + @Override + public void readFromNBT(NBTTagCompound nbtTags) + { + super.readFromNBT(nbtTags); + + isActive = nbtTags.getBoolean("isActive"); + controlType = RedstoneControl.values()[nbtTags.getInteger("controlType")]; + operatingTicks = nbtTags.getInteger("operatingTicks"); + + gasTank = GasStack.readFromNBT(nbtTags.getCompoundTag("gasTank")); + } + + @Override + public void writeToNBT(NBTTagCompound nbtTags) + { + super.writeToNBT(nbtTags); + + nbtTags.setBoolean("isActive", isActive); + nbtTags.setInteger("controlType", controlType.ordinal()); + nbtTags.setInteger("operatingTicks", operatingTicks); + + if(gasTank != null) + { + nbtTags.setCompoundTag("gasTank", gasTank.write(new NBTTagCompound())); + } + } + + @Override + public boolean canSetFacing(int i) + { + return i != 0 && i != 1; + } + + public int getScaledGasLevel(int i) + { + return gasTank != null ? gasTank.amount*i / MAX_GAS : 0; + } + + @Override + public void setActive(boolean active) + { + isActive = active; + + if(clientActive != active && updateDelay == 0) + { + PacketHandler.sendPacket(Transmission.ALL_CLIENTS, new PacketTileEntity().setParams(Object3D.get(this), getNetworkedData(new ArrayList()))); + + updateDelay = 10; + clientActive = active; + } + } + + @Override + public boolean getActive() + { + return isActive; + } + + @Override + public boolean renderUpdate() + { + return false; + } + + @Override + public boolean lightUpdate() + { + return true; + } + + @Override + public boolean canTubeConnect(ForgeDirection side) + { + return side == MekanismUtils.getRight(facing); + } + + @Override + public GasStack getGas(Object... data) + { + return gasTank; + } + + @Override + public void setGas(GasStack stack, Object... data) + { + if(stack == null || stack.amount == 0) + { + gasTank = null; + } + else { + gasTank = new GasStack(stack.getGas(), Math.max(Math.min(stack.amount, getMaxGas()), 0)); + } + + MekanismUtils.saveChunk(this); + } + + @Override + public int getMaxGas(Object... data) + { + return MAX_GAS; + } + + @Override + public RedstoneControl getControlType() + { + return controlType; + } + + @Override + public void setControlType(RedstoneControl type) + { + controlType = type; + MekanismUtils.saveChunk(this); } } diff --git a/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java b/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java index 12a950162..5d42b6904 100644 --- a/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java +++ b/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java @@ -1,14 +1,473 @@ package mekanism.common.tileentity; -import mekanism.api.gas.GasStack; +import java.util.ArrayList; -public class TileEntityChemicalInfuser extends TileEntityElectricBlock +import mekanism.api.Object3D; +import mekanism.api.gas.Gas; +import mekanism.api.gas.GasRegistry; +import mekanism.api.gas.GasStack; +import mekanism.api.gas.GasTransmission; +import mekanism.api.gas.IGasAcceptor; +import mekanism.common.IRedstoneControl.RedstoneControl; +import mekanism.common.Mekanism; +import mekanism.common.PacketHandler; +import mekanism.common.PacketHandler.Transmission; +import mekanism.common.network.PacketTileEntity; +import mekanism.common.util.ChargeUtils; +import mekanism.common.util.MekanismUtils; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidStack; + +import com.google.common.io.ByteArrayDataInput; + +public class TileEntityChemicalInfuser extends TileEntityElectricBlock //implements IActiveState, IGasStorage, IGasAcceptor, ITubeConnection, IRedstoneControl { public GasStack leftStack; public GasStack rightStack; + public GasStack centerStack; + + public static final int MAX_GAS = 10000; + + public int updateDelay; + + public int gasOutput = 16; + + public boolean isActive; + + public boolean clientActive; + + public double prevEnergy; + + public final double ENERGY_USAGE = Mekanism.chemicalInfuserUsage; + + /** This machine's current RedstoneControl type. */ + public RedstoneControl controlType = RedstoneControl.DISABLED; + public TileEntityChemicalInfuser() { super("ChemicalInfuser", 0 /*TODO*/); + inventory = new ItemStack[4]; } + + /*@Override + public void onUpdate() + { + if(worldObj.isRemote) + { + if(updateDelay > 0) + { + updateDelay--; + + if(updateDelay == 0 && clientActive != isActive) + { + isActive = clientActive; + MekanismUtils.updateBlock(worldObj, xCoord, yCoord, zCoord); + } + } + } + + if(!worldObj.isRemote) + { + if(updateDelay > 0) + { + updateDelay--; + + if(updateDelay == 0 && clientActive != isActive) + { + PacketHandler.sendPacket(Transmission.ALL_CLIENTS, new PacketTileEntity().setParams(Object3D.get(this), getNetworkedData(new ArrayList()))); + } + } + + ChargeUtils.discharge(4, this); + + if(mode == 0) + { + if(inventory[1] != null && (getGas() == null || getGas().amount < getMaxGas())) + { + if(getGas() == null) + { + setGas(GasTransmission.removeGas(inventory[1], null, getMaxGas())); + } + else { + GasStack removed = GasTransmission.removeGas(inventory[1], getGas().getGas(), getMaxGas()-getGas().amount); + setGas(new GasStack(getGas().getGas(), getGas().amount + (removed != null ? removed.amount : 0))); + } + } + + if(getEnergy() >= ENERGY_USAGE && MekanismUtils.canFunction(this) && isValidGas(gasTank) && (fluidTank.getFluid() == null || (fluidTank.getFluid().amount < 10000 && gasEquals(gasTank, fluidTank.getFluid())))) + { + setActive(true); + fluidTank.fill(new FluidStack(getGas().getGas().getFluid(), 1), true); + setGas(new GasStack(getGas().getGas(), getGas().amount-1)); + setEnergy(getEnergy() - ENERGY_USAGE); + } + else { + if(prevEnergy >= getEnergy()) + { + setActive(false); + } + } + } + else if(mode == 1) + { + if(getGas() != null) + { + if(inventory[0] != null) + { + setGas(new GasStack(getGas().getGas(), getGas().amount - GasTransmission.addGas(inventory[0], getGas()))); + } + } + + if(getGas() != null) + { + GasStack toSend = new GasStack(getGas().getGas(), Math.min(getGas().amount, gasOutput)); + setGas(new GasStack(getGas().getGas(), getGas().amount - GasTransmission.emitGasToNetwork(toSend, this, MekanismUtils.getLeft(facing)))); + + TileEntity tileEntity = Object3D.get(this).getFromSide(MekanismUtils.getLeft(facing)).getTileEntity(worldObj); + + if(tileEntity instanceof IGasAcceptor) + { + if(((IGasAcceptor)tileEntity).canReceiveGas(MekanismUtils.getLeft(facing).getOpposite(), getGas().getGas())) + { + int added = ((IGasAcceptor)tileEntity).receiveGas(new GasStack(getGas().getGas(), Math.min(getGas().amount, gasOutput))); + + setGas(new GasStack(getGas().getGas(), getGas().amount - added)); + } + } + } + + if(FluidContainerRegistry.isFilledContainer(inventory[2])) + { + FluidStack itemFluid = FluidContainerRegistry.getFluidForFilledItem(inventory[2]); + + if((fluidTank.getFluid() == null && itemFluid.amount <= 10000) || fluidTank.getFluid().amount+itemFluid.amount <= 10000) + { + if(fluidTank.getFluid() != null && !fluidTank.getFluid().isFluidEqual(itemFluid)) + { + return; + } + + ItemStack containerItem = inventory[2].getItem().getContainerItemStack(inventory[2]); + + boolean filled = false; + + if(containerItem != null) + { + if(inventory[3] == null || (inventory[3].isItemEqual(containerItem) && inventory[3].stackSize+1 <= containerItem.getMaxStackSize())) + { + inventory[2] = null; + + if(inventory[3] == null) + { + inventory[3] = containerItem; + } + else { + inventory[3].stackSize++; + } + + filled = true; + } + } + else { + inventory[2].stackSize--; + + if(inventory[2].stackSize == 0) + { + inventory[2] = null; + } + + filled = true; + } + + if(filled) + { + fluidTank.fill(itemFluid, true); + } + } + } + + if(getEnergy() >= ENERGY_USAGE && MekanismUtils.canFunction(this) && isValidFluid(fluidTank.getFluid()) && (gasTank == null || (gasTank.amount < MAX_GAS && gasEquals(gasTank, fluidTank.getFluid())))) + { + setActive(true); + setGas(new GasStack(GasRegistry.getGas(fluidTank.getFluid().getFluid()), getGas() != null ? getGas().amount+1 : 1)); + fluidTank.drain(1, true); + setEnergy(getEnergy() - ENERGY_USAGE); + } + else { + if(prevEnergy >= getEnergy()) + { + setActive(false); + } + } + } + + prevEnergy = getEnergy(); + } + } + + public boolean isValidGas(GasStack g) + { + if(g == null) + { + return false; + } + + return g.getGas().hasFluid(); + } + + public boolean gasEquals(GasStack gas, FluidStack fluid) + { + if(fluid == null || gas == null || !gas.getGas().hasFluid()) + { + return false; + } + + return gas.getGas().getFluid() == fluid.getFluid(); + } + + public boolean isValidFluid(FluidStack f) + { + if(f == null) + { + return false; + } + + return GasRegistry.getGas(f.getFluid()) != null; + } + + @Override + public void handlePacketData(ByteArrayDataInput dataStream) + { + if(!worldObj.isRemote) + { + int type = dataStream.readInt(); + + if(type == 0) + { + mode = mode == 0 ? 1 : 0; + } + + for(EntityPlayer player : playersUsing) + { + PacketHandler.sendPacket(Transmission.SINGLE_CLIENT, new PacketTileEntity().setParams(Object3D.get(this), getNetworkedData(new ArrayList())), player); + } + + return; + } + + super.handlePacketData(dataStream); + + mode = dataStream.readInt(); + isActive = dataStream.readBoolean(); + controlType = RedstoneControl.values()[dataStream.readInt()]; + + if(dataStream.readBoolean()) + { + fluidTank.setFluid(new FluidStack(dataStream.readInt(), dataStream.readInt())); + } + else { + fluidTank.setFluid(null); + } + + if(dataStream.readBoolean()) + { + gasTank = new GasStack(GasRegistry.getGas(dataStream.readInt()), dataStream.readInt()); + } + else { + gasTank = null; + } + + + MekanismUtils.updateBlock(worldObj, xCoord, yCoord, zCoord); + } + + @Override + public ArrayList getNetworkedData(ArrayList data) + { + super.getNetworkedData(data); + + data.add(mode); + data.add(isActive); + data.add(controlType.ordinal()); + + if(fluidTank.getFluid() != null) + { + data.add(true); + data.add(fluidTank.getFluid().fluidID); + data.add(fluidTank.getFluid().amount); + } + else { + data.add(false); + } + + if(gasTank != null) + { + data.add(true); + data.add(gasTank.getGas().getID()); + data.add(gasTank.amount); + } + else { + data.add(false); + } + + return data; + } + + @Override + public void readFromNBT(NBTTagCompound nbtTags) + { + super.readFromNBT(nbtTags); + + mode = nbtTags.getInteger("mode"); + isActive = nbtTags.getBoolean("isActive"); + controlType = RedstoneControl.values()[nbtTags.getInteger("controlType")]; + + gasTank = GasStack.readFromNBT(nbtTags.getCompoundTag("gasTank")); + + if(nbtTags.hasKey("fluidTank")) + { + fluidTank.readFromNBT(nbtTags.getCompoundTag("fluidTank")); + } + } + + @Override + public void writeToNBT(NBTTagCompound nbtTags) + { + super.writeToNBT(nbtTags); + + nbtTags.setInteger("mode", mode); + nbtTags.setBoolean("isActive", isActive); + nbtTags.setInteger("controlType", controlType.ordinal()); + + if(gasTank != null) + { + nbtTags.setCompoundTag("gasTank", gasTank.write(new NBTTagCompound())); + } + + if(fluidTank.getFluid() != null) + { + nbtTags.setTag("fluidTank", fluidTank.writeToNBT(new NBTTagCompound())); + } + } + + @Override + public boolean canSetFacing(int i) + { + return i != 0 && i != 1; + } + + public int getScaledFluidLevel(int i) + { + return fluidTank.getFluid() != null ? fluidTank.getFluid().amount*i / 10000 : 0; + } + + public int getScaledGasLevel(int i) + { + return gasTank != null ? gasTank.amount*i / MAX_GAS : 0; + } + + @Override + public void setActive(boolean active) + { + isActive = active; + + if(clientActive != active && updateDelay == 0) + { + PacketHandler.sendPacket(Transmission.ALL_CLIENTS, new PacketTileEntity().setParams(Object3D.get(this), getNetworkedData(new ArrayList()))); + + updateDelay = 10; + clientActive = active; + } + } + + @Override + public boolean getActive() + { + return isActive; + } + + @Override + public boolean renderUpdate() + { + return false; + } + + @Override + public boolean lightUpdate() + { + return true; + } + + @Override + public boolean canTubeConnect(ForgeDirection side) + { + return side == MekanismUtils.getLeft(facing); + } + + @Override + public int receiveGas(GasStack stack) + { + if(gasTank == null || (gasTank != null && gasTank.getGas() == stack.getGas())) + { + int stored = getGas() != null ? getGas().amount : 0; + int toUse = Math.min(getMaxGas()-stored, stack.amount); + + setGas(new GasStack(stack.getGas(), stored + toUse)); + + return toUse; + } + + return 0; + } + + @Override + public boolean canReceiveGas(ForgeDirection side, Gas type) + { + return mode == 0 && (getGas() == null || getGas().getGas() == type) && side == MekanismUtils.getLeft(facing); + } + + @Override + public GasStack getGas(Object... data) + { + return gasTank; + } + + @Override + public void setGas(GasStack stack, Object... data) + { + if(stack == null || stack.amount == 0) + { + gasTank = null; + } + else { + gasTank = new GasStack(stack.getGas(), Math.max(Math.min(stack.amount, getMaxGas()), 0)); + } + + MekanismUtils.saveChunk(this); + } + + @Override + public int getMaxGas(Object... data) + { + return MAX_GAS; + } + + @Override + public RedstoneControl getControlType() + { + return controlType; + } + + @Override + public void setControlType(RedstoneControl type) + { + controlType = type; + MekanismUtils.saveChunk(this); + }*/ } diff --git a/common/mekanism/common/tileentity/TileEntityElectricMachine.java b/common/mekanism/common/tileentity/TileEntityElectricMachine.java index d3c508cb0..3c3374ae0 100644 --- a/common/mekanism/common/tileentity/TileEntityElectricMachine.java +++ b/common/mekanism/common/tileentity/TileEntityElectricMachine.java @@ -106,7 +106,7 @@ public abstract class TileEntityElectricMachine extends TileEntityBasicMachine return ChargeUtils.canBeDischarged(itemstack); } - return true; + return false; } @Override diff --git a/common/mekanism/common/tileentity/TileEntityFactory.java b/common/mekanism/common/tileentity/TileEntityFactory.java index e66587eb8..fbd31f66d 100644 --- a/common/mekanism/common/tileentity/TileEntityFactory.java +++ b/common/mekanism/common/tileentity/TileEntityFactory.java @@ -449,7 +449,7 @@ public class TileEntityFactory extends TileEntityElectricBlock implements IPerip return RecipeType.values()[recipeType].getFuelTicks(itemstack) > 0; } - return true; + return false; } @Override diff --git a/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java b/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java index 8a2c8b47e..2af404501 100644 --- a/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java +++ b/common/mekanism/common/tileentity/TileEntityMetallurgicInfuser.java @@ -247,7 +247,7 @@ public class TileEntityMetallurgicInfuser extends TileEntityElectricBlock implem return ChargeUtils.canBeDischarged(itemstack); } - return true; + return false; } public void operate() From 5a241ce8ee688b9f0a99d0143eda32c6a0abc8e4 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Wed, 11 Dec 2013 20:24:37 -0500 Subject: [PATCH 39/40] Work on GUIs --- common/mekanism/client/ClientProxy.java | 4 + .../client/gui/GuiChemicalFormulator.java | 126 +++++++++++++++++- .../mekanism/client/gui/GuiDynamicTank.java | 13 +- .../client/gui/GuiElectricMachine.java | 3 - .../mekanism/client/gui/GuiElectricPump.java | 14 +- .../client/gui/GuiRotaryCondensentrator.java | 10 +- common/mekanism/common/CommonProxy.java | 11 ++ resources/assets/mekanism/lang/en_US.lang | 2 + 8 files changed, 156 insertions(+), 27 deletions(-) diff --git a/common/mekanism/client/ClientProxy.java b/common/mekanism/client/ClientProxy.java index 9d43d2778..fe43bfa7f 100644 --- a/common/mekanism/client/ClientProxy.java +++ b/common/mekanism/client/ClientProxy.java @@ -4,6 +4,7 @@ package mekanism.client; import java.io.File; import java.util.HashMap; +import mekanism.client.gui.GuiChemicalFormulator; import mekanism.client.gui.GuiCombiner; import mekanism.client.gui.GuiConfiguration; import mekanism.client.gui.GuiCredits; @@ -72,6 +73,7 @@ import mekanism.common.tileentity.TileEntityAdvancedElectricMachine; import mekanism.common.tileentity.TileEntityAdvancedFactory; import mekanism.common.tileentity.TileEntityBin; import mekanism.common.tileentity.TileEntityChargepad; +import mekanism.common.tileentity.TileEntityChemicalFormulator; import mekanism.common.tileentity.TileEntityCombiner; import mekanism.common.tileentity.TileEntityCrusher; import mekanism.common.tileentity.TileEntityDigitalMiner; @@ -369,6 +371,8 @@ public class ClientProxy extends CommonProxy } case 25: return new GuiRobitRepair(player.inventory, world, x); + case 29: + return new GuiChemicalFormulator(player.inventory, (TileEntityChemicalFormulator)tileEntity); } return null; diff --git a/common/mekanism/client/gui/GuiChemicalFormulator.java b/common/mekanism/client/gui/GuiChemicalFormulator.java index 24b68cce4..e986f6d90 100644 --- a/common/mekanism/client/gui/GuiChemicalFormulator.java +++ b/common/mekanism/client/gui/GuiChemicalFormulator.java @@ -1,6 +1,128 @@ package mekanism.client.gui; -public class GuiChemicalFormulator +import mekanism.api.gas.GasStack; +import mekanism.client.render.MekanismRenderer; +import mekanism.common.inventory.container.ContainerChemicalFormulator; +import mekanism.common.tileentity.TileEntityChemicalFormulator; +import mekanism.common.util.MekanismUtils; +import mekanism.common.util.MekanismUtils.ResourceType; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraftforge.fluids.FluidStack; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class GuiChemicalFormulator extends GuiMekanism { - + public TileEntityChemicalFormulator tileEntity; + + public GuiChemicalFormulator(InventoryPlayer inventory, TileEntityChemicalFormulator tentity) + { + super(tentity, new ContainerChemicalFormulator(inventory, tentity)); + tileEntity = tentity; + + guiElements.add(new GuiRedstoneControl(this, tileEntity, MekanismUtils.getResource(ResourceType.GUI, "GuiChemicalFormulator.png"))); + } + + @Override + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) + { + int xAxis = (mouseX - (width - xSize) / 2); + int yAxis = (mouseY - (height - ySize) / 2); + + fontRenderer.drawString(tileEntity.getInvName(), 45, 6, 0x404040); + fontRenderer.drawString(MekanismUtils.localize("container.inventory"), 8, (ySize - 96) + 2, 0x404040); + + if(xAxis >= 116 && xAxis <= 168 && yAxis >= 76 && yAxis <= 80) + { + drawCreativeTabHoveringText(MekanismUtils.getEnergyDisplay(tileEntity.getEnergy()), xAxis, yAxis); + } + + if(xAxis >= 134 && xAxis <= 150 && yAxis >= 14 && yAxis <= 72) + { + drawCreativeTabHoveringText(tileEntity.gasTank != null ? tileEntity.gasTank.getGas().getLocalizedName() + ": " + tileEntity.gasTank.amount : MekanismUtils.localize("gui.empty"), xAxis, yAxis); + } + + super.drawGuiContainerForegroundLayer(mouseX, mouseY); + } + + @Override + protected void drawGuiContainerBackgroundLayer(float partialTick, int mouseX, int mouseY) + { + super.drawGuiContainerBackgroundLayer(partialTick, mouseX, mouseY); + + mc.renderEngine.bindTexture(MekanismUtils.getResource(ResourceType.GUI, "GuiChemicalFormulator.png")); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + int guiWidth = (width - xSize) / 2; + int guiHeight = (height - ySize) / 2; + drawTexturedModalRect(guiWidth, guiHeight, 0, 0, xSize, ySize); + + int xAxis = mouseX - guiWidth; + int yAxis = mouseY - guiHeight; + + int displayInt; + + displayInt = tileEntity.getScaledEnergyLevel(52); + drawTexturedModalRect(guiWidth + 116, guiHeight + 76, 176, 36, displayInt, 4); + + displayInt = tileEntity.getScaledProgress(48); + drawTexturedModalRect(guiWidth + 64, guiHeight + 40, 176, 63, displayInt + 1, 8); + + if(tileEntity.getScaledGasLevel(58) > 0) + { + displayGauge(134, 14, tileEntity.getScaledGasLevel(58), null, tileEntity.gasTank); + } + } + + public void displayGauge(int xPos, int yPos, int scale, FluidStack fluid, GasStack gas) + { + if(fluid == null && gas == null) + { + return; + } + + int guiWidth = (width - xSize) / 2; + int guiHeight = (height - ySize) / 2; + + int start = 0; + + while(true) + { + int renderRemaining = 0; + + if(scale > 16) + { + renderRemaining = 16; + scale -= 16; + } + else { + renderRemaining = scale; + scale = 0; + } + + mc.renderEngine.bindTexture(MekanismRenderer.getBlocksTexture()); + + if(fluid != null) + { + drawTexturedModelRectFromIcon(guiWidth + xPos, guiHeight + yPos + 58 - renderRemaining - start, fluid.getFluid().getIcon(), 16, 16 - (16 - renderRemaining)); + } + else if(gas != null) + { + drawTexturedModelRectFromIcon(guiWidth + xPos, guiHeight + yPos + 58 - renderRemaining - start, gas.getGas().getIcon(), 16, 16 - (16 - renderRemaining)); + } + + start+=16; + + if(renderRemaining == 0 || scale == 0) + { + break; + } + } + + mc.renderEngine.bindTexture(MekanismUtils.getResource(ResourceType.GUI, "GuiChemicalFormulator.png")); + drawTexturedModalRect(guiWidth + xPos, guiHeight + yPos, 176, 40, 16, 59); + } } diff --git a/common/mekanism/client/gui/GuiDynamicTank.java b/common/mekanism/client/gui/GuiDynamicTank.java index b38058774..342dc8085 100644 --- a/common/mekanism/client/gui/GuiDynamicTank.java +++ b/common/mekanism/client/gui/GuiDynamicTank.java @@ -19,9 +19,6 @@ public class GuiDynamicTank extends GuiMekanism { public TileEntityDynamicTank tileEntity; - private int guiWidth; - private int guiHeight; - public GuiDynamicTank(InventoryPlayer inventory, TileEntityDynamicTank tentity) { super(new ContainerDynamicTank(inventory, tentity)); @@ -59,8 +56,8 @@ public class GuiDynamicTank extends GuiMekanism mc.renderEngine.bindTexture(MekanismUtils.getResource(ResourceType.GUI, "GuiDynamicTank.png")); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - guiWidth = (width - xSize) / 2; - guiHeight = (height - ySize) / 2; + int guiWidth = (width - xSize) / 2; + int guiHeight = (height - ySize) / 2; drawTexturedModalRect(guiWidth, guiHeight, 0, 0, xSize, ySize); if(tileEntity.getScaledFluidLevel(58) > 0) @@ -70,9 +67,6 @@ public class GuiDynamicTank extends GuiMekanism } } - /* - * Credit to BuildCraft for both the gauge texture and parts of the code. - */ public void displayGauge(int xPos, int yPos, int scale, FluidStack fluid, int side /*0-left, 1-right*/) { if(fluid == null) @@ -80,6 +74,9 @@ public class GuiDynamicTank extends GuiMekanism return; } + int guiWidth = (width - xSize) / 2; + int guiHeight = (height - ySize) / 2; + int start = 0; while(true) diff --git a/common/mekanism/client/gui/GuiElectricMachine.java b/common/mekanism/client/gui/GuiElectricMachine.java index 1f58ed3d8..092c8f0d5 100644 --- a/common/mekanism/client/gui/GuiElectricMachine.java +++ b/common/mekanism/client/gui/GuiElectricMachine.java @@ -3,7 +3,6 @@ package mekanism.client.gui; import mekanism.common.inventory.container.ContainerElectricMachine; import mekanism.common.tileentity.TileEntityElectricMachine; import mekanism.common.util.MekanismUtils; -import net.minecraft.client.renderer.RenderHelper; import net.minecraft.entity.player.InventoryPlayer; import org.lwjgl.opengl.GL11; @@ -37,9 +36,7 @@ public class GuiElectricMachine extends GuiMekanism if(xAxis >= 165 && xAxis <= 169 && yAxis >= 17 && yAxis <= 69) { - GL11.glPushMatrix(); drawCreativeTabHoveringText(MekanismUtils.getEnergyDisplay(tileEntity.getEnergy()), xAxis, yAxis); - GL11.glPopMatrix(); } super.drawGuiContainerForegroundLayer(mouseX, mouseY); diff --git a/common/mekanism/client/gui/GuiElectricPump.java b/common/mekanism/client/gui/GuiElectricPump.java index 1a1b6eedf..2c5109d68 100644 --- a/common/mekanism/client/gui/GuiElectricPump.java +++ b/common/mekanism/client/gui/GuiElectricPump.java @@ -1,7 +1,6 @@ package mekanism.client.gui; import mekanism.client.render.MekanismRenderer; -import mekanism.common.Mekanism; import mekanism.common.inventory.container.ContainerElectricPump; import mekanism.common.tileentity.TileEntityElectricPump; import mekanism.common.util.MekanismUtils; @@ -19,9 +18,6 @@ public class GuiElectricPump extends GuiMekanism { public TileEntityElectricPump tileEntity; - private int guiWidth; - private int guiHeight; - public GuiElectricPump(InventoryPlayer inventory, TileEntityElectricPump tentity) { super(new ContainerElectricPump(inventory, tentity)); @@ -59,8 +55,8 @@ public class GuiElectricPump extends GuiMekanism mc.renderEngine.bindTexture(MekanismUtils.getResource(ResourceType.GUI, "GuiElectricPump.png")); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - guiWidth = (width - xSize) / 2; - guiHeight = (height - ySize) / 2; + int guiWidth = (width - xSize) / 2; + int guiHeight = (height - ySize) / 2; drawTexturedModalRect(guiWidth, guiHeight, 0, 0, xSize, ySize); int displayInt; @@ -73,9 +69,6 @@ public class GuiElectricPump extends GuiMekanism } } - /* - * Credit to BuildCraft for both the gauge texture and parts of the code. - */ public void displayGauge(int xPos, int yPos, int scale, FluidStack fluid) { if(fluid == null) @@ -83,6 +76,9 @@ public class GuiElectricPump extends GuiMekanism return; } + int guiWidth = (width - xSize) / 2; + int guiHeight = (height - ySize) / 2; + int start = 0; while(true) diff --git a/common/mekanism/client/gui/GuiRotaryCondensentrator.java b/common/mekanism/client/gui/GuiRotaryCondensentrator.java index fb4ba2ede..f85485ebd 100644 --- a/common/mekanism/client/gui/GuiRotaryCondensentrator.java +++ b/common/mekanism/client/gui/GuiRotaryCondensentrator.java @@ -26,9 +26,6 @@ public class GuiRotaryCondensentrator extends GuiMekanism { public TileEntityRotaryCondensentrator tileEntity; - private int guiWidth; - private int guiHeight; - public GuiRotaryCondensentrator(InventoryPlayer inventory, TileEntityRotaryCondensentrator tentity) { super(new ContainerRotaryCondensentrator(inventory, tentity)); @@ -76,8 +73,8 @@ public class GuiRotaryCondensentrator extends GuiMekanism mc.renderEngine.bindTexture(MekanismUtils.getResource(ResourceType.GUI, "GuiRotaryCondensentrator.png")); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - guiWidth = (width - xSize) / 2; - guiHeight = (height - ySize) / 2; + int guiWidth = (width - xSize) / 2; + int guiHeight = (height - ySize) / 2; drawTexturedModalRect(guiWidth, guiHeight, 0, 0, xSize, ySize); int displayInt; @@ -143,6 +140,9 @@ public class GuiRotaryCondensentrator extends GuiMekanism return; } + int guiWidth = (width - xSize) / 2; + int guiHeight = (height - ySize) / 2; + int start = 0; while(true) diff --git a/common/mekanism/common/CommonProxy.java b/common/mekanism/common/CommonProxy.java index f73706628..35026bc62 100644 --- a/common/mekanism/common/CommonProxy.java +++ b/common/mekanism/common/CommonProxy.java @@ -3,6 +3,8 @@ package mekanism.common; import java.io.File; import mekanism.common.inventory.container.ContainerAdvancedElectricMachine; +import mekanism.common.inventory.container.ContainerChemicalFormulator; +import mekanism.common.inventory.container.ContainerChemicalInfuser; import mekanism.common.inventory.container.ContainerDictionary; import mekanism.common.inventory.container.ContainerDigitalMiner; import mekanism.common.inventory.container.ContainerDynamicTank; @@ -25,6 +27,8 @@ import mekanism.common.tileentity.TileEntityAdvancedElectricMachine; import mekanism.common.tileentity.TileEntityAdvancedFactory; import mekanism.common.tileentity.TileEntityBin; import mekanism.common.tileentity.TileEntityChargepad; +import mekanism.common.tileentity.TileEntityChemicalFormulator; +import mekanism.common.tileentity.TileEntityChemicalInfuser; import mekanism.common.tileentity.TileEntityCombiner; import mekanism.common.tileentity.TileEntityContainerBlock; import mekanism.common.tileentity.TileEntityCrusher; @@ -299,6 +303,7 @@ public class CommonProxy return new ContainerDynamicTank(player.inventory, (TileEntityDynamicTank)tileEntity); case 21: EntityRobit robit = (EntityRobit)world.getEntityByID(x); + if(robit != null) { return new ContainerRobitMain(player.inventory, robit); @@ -307,12 +312,14 @@ public class CommonProxy return new ContainerRobitCrafting(player.inventory, world); case 23: EntityRobit robit1 = (EntityRobit)world.getEntityByID(x); + if(robit1 != null) { return new ContainerRobitInventory(player.inventory, robit1); } case 24: EntityRobit robit2 = (EntityRobit)world.getEntityByID(x); + if(robit2 != null) { return new ContainerRobitSmelting(player.inventory, robit2); @@ -325,6 +332,10 @@ public class CommonProxy return new ContainerFilter(player.inventory, (TileEntityContainerBlock)tileEntity); case 28: return new ContainerFilter(player.inventory, (TileEntityContainerBlock)tileEntity); + case 29: + return new ContainerChemicalFormulator(player.inventory, (TileEntityChemicalFormulator)tileEntity); + case 30: + return new ContainerChemicalInfuser(player.inventory, (TileEntityChemicalInfuser)tileEntity); } return null; diff --git a/resources/assets/mekanism/lang/en_US.lang b/resources/assets/mekanism/lang/en_US.lang index 5dff38305..c5cfe8764 100644 --- a/resources/assets/mekanism/lang/en_US.lang +++ b/resources/assets/mekanism/lang/en_US.lang @@ -66,6 +66,8 @@ tile.MachineBlock.DigitalMiner.name=Digital Miner //Machine Block 2 (second ID iteration) tile.MachineBlock2.RotaryCondensentrator.name=Rotary Condensentrator +tile.MachineBlock2.ChemicalFormulator.name=Chemical Formulator +tile.MachineBlock2.ChemicalInfuser.name=Chemical Infuser //Ore Block tile.OreBlock.OsmiumOre.name=Osmium Ore From faa127ddd84eea7898abc68a205fb29cefe4e3bc Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Wed, 11 Dec 2013 20:46:39 -0500 Subject: [PATCH 40/40] Add textures for Sulfuric Gas & Sulfuric Acid --- common/mekanism/common/CommonProxy.java | 2 ++ common/mekanism/common/RecipeHandler.java | 24 ++++++++++++++++-- .../mekanism/gui/GuiChemicalInfuser.png | Bin 4387 -> 4545 bytes resources/assets/mekanism/lang/en_US.lang | 4 +++ .../textures/blocks/LiquidSulfuricAcid.png | Bin 0 -> 11376 bytes .../blocks/LiquidSulfuricAcid.png.mcmeta | 5 ++++ .../textures/blocks/LiquidSulfuricGas.png | Bin 0 -> 11587 bytes .../blocks/LiquidSulfuricGas.png.mcmeta | 5 ++++ 8 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 resources/assets/mekanism/textures/blocks/LiquidSulfuricAcid.png create mode 100644 resources/assets/mekanism/textures/blocks/LiquidSulfuricAcid.png.mcmeta create mode 100644 resources/assets/mekanism/textures/blocks/LiquidSulfuricGas.png create mode 100644 resources/assets/mekanism/textures/blocks/LiquidSulfuricGas.png.mcmeta diff --git a/common/mekanism/common/CommonProxy.java b/common/mekanism/common/CommonProxy.java index 35026bc62..a28bc77d1 100644 --- a/common/mekanism/common/CommonProxy.java +++ b/common/mekanism/common/CommonProxy.java @@ -106,6 +106,8 @@ public class CommonProxy GameRegistry.registerTileEntity(TileEntityObsidianTNT.class, "ObsidianTNT"); GameRegistry.registerTileEntity(TileEntityRotaryCondensentrator.class, "RotaryCondensentrator"); GameRegistry.registerTileEntity(TileEntityTeleporter.class, "MekanismTeleporter"); + GameRegistry.registerTileEntity(TileEntityChemicalFormulator.class, "ChemicalFormulator"); + GameRegistry.registerTileEntity(TileEntityChemicalInfuser.class, "ChemicalInfuser"); } /** diff --git a/common/mekanism/common/RecipeHandler.java b/common/mekanism/common/RecipeHandler.java index 1db05e69c..e3dc2dd24 100644 --- a/common/mekanism/common/RecipeHandler.java +++ b/common/mekanism/common/RecipeHandler.java @@ -81,11 +81,21 @@ public final class RecipeHandler Recipe.METALLURGIC_INFUSER.put(input, InfusionOutput.getInfusion(input, output)); } + /** + * Add a Chemical Infuser recipe. + * @param input - input ChemicalInput + * @param output - output GasStack + */ public static void addChemicalInfuserRecipe(ChemicalInput input, GasStack output) { Recipe.CHEMICAL_INFUSER.put(input, output); } - + + /** + * Add a Chemical Formulator recipe. + * @param input - input ItemStack + * @param output - output GasStack + */ public static void addChemicalFormulatorRecipe(ItemStack input, GasStack output) { Recipe.CHEMICAL_FORMULATOR.put(input, output); @@ -95,7 +105,6 @@ public final class RecipeHandler * Gets the InfusionOutput of the InfusionInput in the parameters. * @param infusion - input Infusion * @param stackDecrease - whether or not to decrease the input slot's stack size AND the infuse amount - * @param recipes - Map of recipes * @return InfusionOutput */ public static InfusionOutput getMetallurgicInfuserOutput(InfusionInput infusion, boolean stackDecrease) @@ -126,6 +135,11 @@ public final class RecipeHandler return null; } + /** + * Gets the GasStack of the ChemicalInput in the parameters. + * @param input - input ChemicalInput + * @return GasStack + */ public static GasStack getChemicalInfuserOutput(ChemicalInput input) { if(input != null && input.isValid()) @@ -137,6 +151,12 @@ public final class RecipeHandler return null; } + /** + * Gets the InfusionOutput of the ItemStack in the parameters. + * @param itemstack - input ItemStack + * @param stackDecrease - whether or not to decrease the input slot's stack size + * @return GasStack + */ public static GasStack getChemicalFormulatorOutput(ItemStack itemstack, boolean stackDecrease) { if(itemstack != null) diff --git a/resources/assets/mekanism/gui/GuiChemicalInfuser.png b/resources/assets/mekanism/gui/GuiChemicalInfuser.png index 362a6f1d5f0d48b4d4af88ac7e4301932d6b4730..0a2fc0627217d0986c6610ceb5bfae5b9725c2e1 100644 GIT binary patch delta 2726 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