From efe2502be17dd35c463305150dc5d700de92ea17 Mon Sep 17 00:00:00 2001 From: "Aidan C. Brady" Date: Sat, 1 Feb 2014 16:33:27 -0500 Subject: [PATCH] Friction Boots - semi-working --- common/mekanism/client/ClientProxy.java | 1 + .../client/model/ModelFrictionBoots.java | 16 +- .../client/render/ModelCustomArmor.java | 35 ++- .../render/item/ItemRenderingHandler.java | 17 +- common/mekanism/common/Mekanism.java | 7 + .../mekanism/common/item/ItemEnergized.java | 6 - .../common/item/ItemFrictionBoots.java | 262 ++++++++++++++++++ resources/assets/mekanism/lang/en_US.lang | 4 + .../assets/mekanism/render/ChemicalWasher.png | Bin 6616 -> 4516 bytes 9 files changed, 334 insertions(+), 14 deletions(-) create mode 100644 common/mekanism/common/item/ItemFrictionBoots.java diff --git a/common/mekanism/client/ClientProxy.java b/common/mekanism/client/ClientProxy.java index 2f490cbe2..b3458e34e 100644 --- a/common/mekanism/client/ClientProxy.java +++ b/common/mekanism/client/ClientProxy.java @@ -338,6 +338,7 @@ public class ClientProxy extends CommonProxy MinecraftForgeClient.registerItemRenderer(Mekanism.GasMask.itemID, handler); MinecraftForgeClient.registerItemRenderer(Mekanism.ScubaTank.itemID, handler); MinecraftForgeClient.registerItemRenderer(Mekanism.Balloon.itemID, handler); + MinecraftForgeClient.registerItemRenderer(Mekanism.FrictionBoots.itemID, handler); //Register block handlers RenderingRegistry.registerBlockHandler(new MachineRenderingHandler()); diff --git a/common/mekanism/client/model/ModelFrictionBoots.java b/common/mekanism/client/model/ModelFrictionBoots.java index 631877ecf..92d533399 100644 --- a/common/mekanism/client/model/ModelFrictionBoots.java +++ b/common/mekanism/client/model/ModelFrictionBoots.java @@ -24,7 +24,6 @@ public class ModelFrictionBoots extends ModelBase SpringL.setTextureSize(64, 32); SpringL.mirror = true; setRotation(SpringL, 0.1047198F, 0F, 0F); - SpringR.mirror = true; SpringR = new ModelRenderer(this, 8, 0); SpringR.addBox(-2.5F, 18F, 0F, 1, 6, 1); SpringR.setRotationPoint(0F, 0F, 0F); @@ -50,7 +49,6 @@ public class ModelFrictionBoots extends ModelBase SupportL.setTextureSize(64, 32); SupportL.mirror = true; setRotation(SupportL, 0.296706F, 0F, 0F); - SupportR.mirror = true; SupportR = new ModelRenderer(this, 0, 0); SupportR.addBox(-3F, 16.5F, -4.2F, 2, 4, 2); SupportR.setRotationPoint(0F, 0F, 0F); @@ -69,6 +67,20 @@ public class ModelFrictionBoots extends ModelBase SupportL.render(size); SupportR.render(size); } + + public void renderLeft(float size) + { + SpringL.render(size); + BraceL.render(size); + SupportL.render(size); + } + + public void renderRight(float size) + { + SpringR.render(size); + BraceR.render(size); + SupportR.render(size); + } private void setRotation(ModelRenderer model, float x, float y, float z) { diff --git a/common/mekanism/client/render/ModelCustomArmor.java b/common/mekanism/client/render/ModelCustomArmor.java index f9bacd4d1..abffedf77 100644 --- a/common/mekanism/client/render/ModelCustomArmor.java +++ b/common/mekanism/client/render/ModelCustomArmor.java @@ -1,5 +1,6 @@ package mekanism.client.render; +import mekanism.client.model.ModelFrictionBoots; import mekanism.client.model.ModelGasMask; import mekanism.client.model.ModelJetpack; import mekanism.client.model.ModelScubaTank; @@ -35,8 +36,8 @@ public class ModelCustomArmor extends ModelBiped resetPart(bipedBody, 0, 0, 0); resetPart(bipedRightArm, 5, 2, 0); resetPart(bipedLeftArm, -5, 2, 0); - resetPart(bipedRightLeg, 2, 12, 0); - resetPart(bipedLeftLeg, -2, 12, 0); + resetPart(bipedRightLeg, 0, 0, 0); + resetPart(bipedLeftLeg, 0, 0, 0); bipedHeadwear.cubeList.clear(); bipedEars.cubeList.clear(); @@ -64,6 +65,13 @@ public class ModelCustomArmor extends ModelBiped bipedBody.isHidden = false; bipedBody.showModel = true; } + else if(modelType.armorSlot == 3) + { + bipedLeftLeg.isHidden = false; + bipedLeftLeg.showModel = true; + bipedRightLeg.isHidden = false; + bipedRightLeg.showModel = true; + } setRotationAngles(f, f1, f2, f3, f4, size, entity); } @@ -137,6 +145,21 @@ public class ModelCustomArmor extends ModelBiped GL11.glTranslatef(0, 0, -0.05F); ArmorModel.gasMaskModel.render(0.0625F); } + else if(biped.modelType == ArmorModel.FRICTIONBOOTS) + { + GL11.glScalef(0.99F, 0.99F, 0.99F); + + if(partRender == biped.bipedLeftLeg) + { + GL11.glTranslatef(-0.1375F, -0.75F, 0); + ArmorModel.frictionBootsModel.renderLeft(0.0625F); + } + else if(partRender == biped.bipedRightLeg) + { + GL11.glTranslatef(0.1375F, -0.75F, 0); + ArmorModel.frictionBootsModel.renderRight(0.0625F); + } + } } GL11.glPopMatrix(); @@ -161,6 +184,10 @@ public class ModelCustomArmor extends ModelBiped { return partRender == biped.bipedBody; } + else if(type.armorSlot == 3) + { + return partRender == biped.bipedLeftLeg || partRender == biped.bipedRightLeg; + } return false; } @@ -169,7 +196,8 @@ public class ModelCustomArmor extends ModelBiped { JETPACK(1, MekanismUtils.getResource(ResourceType.RENDER, "Jetpack.png")), SCUBATANK(1, MekanismUtils.getResource(ResourceType.RENDER, "ScubaSet.png")), - GASMASK(0, MekanismUtils.getResource(ResourceType.RENDER, "ScubaSet.png")); + GASMASK(0, MekanismUtils.getResource(ResourceType.RENDER, "ScubaSet.png")), + FRICTIONBOOTS(3, MekanismUtils.getResource(ResourceType.RENDER, "FrictionBoots.png")); public int armorSlot; public ResourceLocation resource; @@ -177,6 +205,7 @@ public class ModelCustomArmor extends ModelBiped public static ModelJetpack jetpackModel = new ModelJetpack(); public static ModelGasMask gasMaskModel = new ModelGasMask(); public static ModelScubaTank scubaTankModel = new ModelScubaTank(); + public static ModelFrictionBoots frictionBootsModel = new ModelFrictionBoots(); private ArmorModel(int i, ResourceLocation r) { diff --git a/common/mekanism/client/render/item/ItemRenderingHandler.java b/common/mekanism/client/render/item/ItemRenderingHandler.java index 97664a46d..0252d1d4f 100644 --- a/common/mekanism/client/render/item/ItemRenderingHandler.java +++ b/common/mekanism/client/render/item/ItemRenderingHandler.java @@ -6,6 +6,7 @@ import mekanism.client.ClientProxy; import mekanism.client.MekanismClient; import mekanism.client.model.ModelEnergyCube; import mekanism.client.model.ModelEnergyCube.ModelEnergyCore; +import mekanism.client.model.ModelFrictionBoots; import mekanism.client.model.ModelGasMask; import mekanism.client.model.ModelGasTank; import mekanism.client.model.ModelJetpack; @@ -25,6 +26,7 @@ import mekanism.common.inventory.InventoryBin; import mekanism.common.item.ItemBalloon; import mekanism.common.item.ItemBlockBasic; import mekanism.common.item.ItemBlockMachine; +import mekanism.common.item.ItemFrictionBoots; import mekanism.common.item.ItemGasMask; import mekanism.common.item.ItemJetpack; import mekanism.common.item.ItemRobit; @@ -69,9 +71,10 @@ public class ItemRenderingHandler implements IItemRenderer public ModelJetpack jetpack = new ModelJetpack(); public ModelGasMask gasMask = new ModelGasMask(); public ModelScubaTank scubaTank = new ModelScubaTank(); + public ModelFrictionBoots frictionBoots = new ModelFrictionBoots(); - public RenderBalloon balloonRenderer = new RenderBalloon(); - public RenderBin binRenderer = (RenderBin)TileEntityRenderer.instance.specialRendererMap.get(TileEntityBin.class); + private final RenderBalloon balloonRenderer = new RenderBalloon(); + private final RenderBin binRenderer = (RenderBin)TileEntityRenderer.instance.specialRendererMap.get(TileEntityBin.class); private final RenderItem renderItem = (RenderItem)RenderManager.instance.getEntityClassRenderObject(EntityItem.class); @Override @@ -343,6 +346,15 @@ public class ItemRenderingHandler implements IItemRenderer Minecraft.getMinecraft().renderEngine.bindTexture(MekanismUtils.getResource(ResourceType.RENDER, "ScubaSet.png")); scubaTank.render(0.0625F); } + else if(item.getItem() instanceof ItemFrictionBoots) + { + GL11.glRotatef(180, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(90, 0.0F, -1.0F, 0.0F); + GL11.glScalef(2.0F, 2.0F, 2.0F); + GL11.glTranslatef(0.2F, -1.43F, 0.12F); + Minecraft.getMinecraft().renderEngine.bindTexture(MekanismUtils.getResource(ResourceType.RENDER, "FrictionBoots.png")); + frictionBoots.render(0.0625F); + } else if(item.getItem() instanceof ItemBalloon) { if(type == ItemRenderType.EQUIPPED || type == ItemRenderType.EQUIPPED_FIRST_PERSON) @@ -362,7 +374,6 @@ public class ItemRenderingHandler implements IItemRenderer GL11.glDisable(GL11.GL_CULL_FACE); RenderPartTransmitter.getInstance().renderItem(TransmitterType.values()[item.getItemDamage()]); GL11.glEnable(GL11.GL_CULL_FACE); - } else { if(item.getItem() instanceof ItemBlockMachine) diff --git a/common/mekanism/common/Mekanism.java b/common/mekanism/common/Mekanism.java index 90ef1a281..f6fa42b5b 100644 --- a/common/mekanism/common/Mekanism.java +++ b/common/mekanism/common/Mekanism.java @@ -65,6 +65,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.ItemFrictionBoots; import mekanism.common.item.ItemGasMask; import mekanism.common.item.ItemIngot; import mekanism.common.item.ItemJetpack; @@ -253,6 +254,7 @@ public class Mekanism public static Item Sawdust; public static Item Salt; public static Item BrineBucket; + public static Item FrictionBoots; //Blocks public static Block BasicBlock; @@ -556,6 +558,9 @@ public class Mekanism CraftingManager.getInstance().getRecipeList().add(new MekanismRecipe(new ItemStack(MachineBlock2, 1, 8), new Object[] { "CGC", "ASA", "CGC", Character.valueOf('G'), MekanismUtils.getEmptyGasTank(), Character.valueOf('C'), "circuitBasic", Character.valueOf('A'), AtomicCore, Character.valueOf('S'), new ItemStack(BasicBlock, 1, 8) })); + CraftingManager.getInstance().getRecipeList().add(new MekanismRecipe(new ItemStack(FrictionBoots), new Object[] { + "C C", "A A", "T T", Character.valueOf('C'), "circuitBasic", Character.valueOf('A'), EnrichedAlloy, Character.valueOf('T'), EnergyTablet.getUnchargedItem() + })); for(RecipeType type : RecipeType.values()) { @@ -782,6 +787,7 @@ public class Mekanism Salt = new ItemMekanism(configuration.getItem("Salt", 11231).getInt()).setUnlocalizedName("Salt"); BrineBucket = new ItemMekanism(configuration.getItem("BrineBucket", 11232).getInt()).setMaxStackSize(1).setUnlocalizedName("BrineBucket"); Crystal = new ItemCrystal(configuration.getItem("Crystal", 11233).getInt()); + FrictionBoots = new ItemFrictionBoots(configuration.getItem("FrictionBoots", 11234).getInt()).setUnlocalizedName("FrictionBoots"); configuration.save(); @@ -822,6 +828,7 @@ public class Mekanism GameRegistry.registerItem(Salt, "Salt"); GameRegistry.registerItem(BrineBucket, "BrineBucket"); GameRegistry.registerItem(Crystal, "Crystal"); + GameRegistry.registerItem(FrictionBoots, "FrictionBoots"); } /** diff --git a/common/mekanism/common/item/ItemEnergized.java b/common/mekanism/common/item/ItemEnergized.java index 48063a6bc..a1a0c2124 100644 --- a/common/mekanism/common/item/ItemEnergized.java +++ b/common/mekanism/common/item/ItemEnergized.java @@ -38,12 +38,6 @@ public class ItemEnergized extends ItemMekanism implements IEnergizedItem, ISpec list.add(EnumColor.AQUA + "Stored Energy: " + EnumColor.GREY + MekanismUtils.getEnergyDisplay(getEnergy(itemstack))); } - @Override - public void onCreated(ItemStack itemstack, World world, EntityPlayer entityplayer) - { - itemstack = getUnchargedItem(); - } - public ItemStack getUnchargedItem() { ItemStack charged = new ItemStack(this); diff --git a/common/mekanism/common/item/ItemFrictionBoots.java b/common/mekanism/common/item/ItemFrictionBoots.java new file mode 100644 index 000000000..e7e150b42 --- /dev/null +++ b/common/mekanism/common/item/ItemFrictionBoots.java @@ -0,0 +1,262 @@ +package mekanism.common.item; + +import ic2.api.item.IElectricItemManager; +import ic2.api.item.ISpecialElectricItem; + +import java.util.List; + +import cofh.api.energy.IEnergyContainerItem; +import mekanism.api.EnumColor; +import mekanism.api.energy.IEnergizedItem; +import mekanism.client.render.ModelCustomArmor; +import mekanism.client.render.ModelCustomArmor.ArmorModel; +import mekanism.common.Mekanism; +import mekanism.common.integration.IC2ItemManager; +import mekanism.common.util.MekanismUtils; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.renderer.texture.IconRegister; +import net.minecraft.creativetab.CreativeTabs; +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.minecraft.util.DamageSource; +import net.minecraft.world.World; +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 ItemFrictionBoots extends ItemArmor implements IEnergizedItem, ISpecialElectricItem, IEnergyContainerItem +{ + /** The maximum amount of energy this item can hold. */ + public double MAX_ELECTRICITY = 12000; + + public ItemFrictionBoots(int id) + { + super(id, EnumHelper.addArmorMaterial("FRICTIONBOOTS", 0, new int[] {0, 0, 0, 0}, 0), 0, 3); + setMaxStackSize(1); + setMaxDamage(100); + setNoRepair(); + setCreativeTab(Mekanism.tabMekanism); + MinecraftForge.EVENT_BUS.register(this); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IconRegister register) {} + + @Override + public boolean isValidArmor(ItemStack stack, int armorType, Entity entity) + { + return armorType == 3; + } + + @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.FRICTIONBOOTS; + return model; + } + + @Override + public void addInformation(ItemStack itemstack, EntityPlayer entityplayer, List list, boolean flag) + { + list.add(EnumColor.AQUA + "Stored Energy: " + EnumColor.GREY + MekanismUtils.getEnergyDisplay(getEnergy(itemstack))); + } + + public ItemStack getUnchargedItem() + { + ItemStack charged = new ItemStack(this); + charged.setItemDamage(100); + return charged; + } + + @Override + public void getSubItems(int i, CreativeTabs tabs, List list) + { + ItemStack discharged = new ItemStack(this); + discharged.setItemDamage(100); + list.add(discharged); + ItemStack charged = new ItemStack(this); + setEnergy(charged, ((IEnergizedItem)charged.getItem()).getMaxEnergy(charged)); + list.add(charged); + } + + @Override + public boolean canProvideEnergy(ItemStack itemStack) + { + return canSend(itemStack); + } + + @Override + public int getChargedItemId(ItemStack itemStack) + { + return itemID; + } + + @Override + public int getEmptyItemId(ItemStack itemStack) + { + return itemID; + } + + @Override + public int getMaxCharge(ItemStack itemStack) + { + return 0; + } + + @Override + public int getTier(ItemStack itemStack) + { + return 4; + } + + @Override + public int getTransferLimit(ItemStack itemStack) + { + return 0; + } + + @Override + public double getEnergy(ItemStack itemStack) + { + if(itemStack.stackTagCompound == null) + { + return 0; + } + + double electricityStored = itemStack.stackTagCompound.getDouble("electricity"); + itemStack.setItemDamage((int)Math.max(1, (Math.abs(((electricityStored/getMaxEnergy(itemStack))*100)-100)))); + + return electricityStored; + } + + @Override + public void setEnergy(ItemStack itemStack, double amount) + { + if(itemStack.stackTagCompound == null) + { + itemStack.setTagCompound(new NBTTagCompound()); + } + + double electricityStored = Math.max(Math.min(amount, getMaxEnergy(itemStack)), 0); + itemStack.stackTagCompound.setDouble("electricity", electricityStored); + itemStack.setItemDamage((int)Math.max(1, (Math.abs(((electricityStored/getMaxEnergy(itemStack))*100)-100)))); + } + + @Override + public double getMaxEnergy(ItemStack itemStack) + { + return MAX_ELECTRICITY; + } + + @Override + public double getMaxTransfer(ItemStack itemStack) + { + return getMaxEnergy(itemStack)*0.005; + } + + @Override + public boolean canReceive(ItemStack itemStack) + { + return getMaxEnergy(itemStack)-getEnergy(itemStack) > 0; + } + + @Override + public boolean canSend(ItemStack itemStack) + { + return false; + } + + @Override + public int receiveEnergy(ItemStack theItem, int energy, boolean simulate) + { + if(canReceive(theItem)) + { + double energyNeeded = getMaxEnergy(theItem)-getEnergy(theItem); + double toReceive = Math.min(energy*Mekanism.FROM_TE, energyNeeded); + + if(!simulate) + { + setEnergy(theItem, getEnergy(theItem) + toReceive); + } + + return (int)Math.round(toReceive*Mekanism.TO_TE); + } + + return 0; + } + + @Override + public int extractEnergy(ItemStack theItem, int energy, boolean simulate) + { + if(canSend(theItem)) + { + double energyRemaining = getEnergy(theItem); + double toSend = Math.min((energy*Mekanism.FROM_TE), energyRemaining); + + if(!simulate) + { + setEnergy(theItem, getEnergy(theItem) - toSend); + } + + return (int)Math.round(toSend*Mekanism.TO_TE); + } + + return 0; + } + + @Override + public int getEnergyStored(ItemStack theItem) + { + return (int)Math.round(getEnergy(theItem)*Mekanism.TO_TE); + } + + @Override + public int getMaxEnergyStored(ItemStack theItem) + { + return (int)Math.round(getMaxEnergy(theItem)*Mekanism.TO_TE); + } + + @Override + public boolean isMetadataSpecific() + { + return false; + } + + @Override + public IElectricItemManager getManager(ItemStack itemStack) + { + return IC2ItemManager.getManager(this); + } + + @ForgeSubscribe + public void onEntityAttacked(LivingAttackEvent event) + { + EntityLivingBase base = event.entityLiving; + + if(base.getCurrentItemOrArmor(1) != null && base.getCurrentItemOrArmor(1).getItem() instanceof ItemFrictionBoots) + { + ItemFrictionBoots boots = (ItemFrictionBoots)base.getCurrentItemOrArmor(1).getItem(); + + if(event.source == DamageSource.fall) + { + event.setCanceled(true); + } + } + } +} diff --git a/resources/assets/mekanism/lang/en_US.lang b/resources/assets/mekanism/lang/en_US.lang index 5b95c6c97..affd73b65 100644 --- a/resources/assets/mekanism/lang/en_US.lang +++ b/resources/assets/mekanism/lang/en_US.lang @@ -31,6 +31,7 @@ item.CompressedRedstone.name=Compressed Redstone item.Sawdust.name=Sawdust item.Salt.name=Salt item.BrineBucket.name=Brine Bucket +item.FrictionBoots.name=Friction Boots //Gas Tank tile.GasTank.GasTank.name=Gas Tank @@ -380,6 +381,9 @@ tooltip.RotaryCondensentrator=A machine capable of converting gasses into !nthei tooltip.ChemicalInjectionChamber=An elite machine capable of processing !nores into four shards, serving as the initial !nstage of 400% ore processing. tooltip.ElectrolyticSeparator=A machine that uses the process of !nelectrolysis to split apart a certain !ngas into two different gasses. tooltip.PrecisionSawmill=A machine used to process logs and other !nwood-based items more efficiently, as well !nas to obtain sawdust. +tooltip.ChemicalDissolutionChamber=An ultimate machine used to !nchemically dissolve all impurities of an !nore, leaving an unprocessed slurry !nbehind. +tooltip.ChemicalWasher=An ultimate machine that cleans unprocessed !nslurry and prepares it for crystallization. +tooltip.ChemicalCrystalizer=An ultimate machine used to crystalize !npurified ore slurry into ore crystals. tooltip.OsmiumOre=A strong mineral that can be found !nat nearly any height in the world. !nIt is known to have many uses in !nthe construction of machinery. tooltip.CopperOre=A common, conductive material that !ncan be used in the production of !nwires. It's ability to withstand !nhigh heats also makes it essential !nto advanced machinery. diff --git a/resources/assets/mekanism/render/ChemicalWasher.png b/resources/assets/mekanism/render/ChemicalWasher.png index 7f518d815fc7cd924460116e258bd8058dbacc09..93c84aa42c6b52ffa69262906a913259aa0c268a 100644 GIT binary patch literal 4516 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 literal 6616 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 stGw&x|5@4pCmZ-5OZMfxBLA60Lw<