/** Copyright (C) <2017> <coolAlias> This file is part of coolAlias' Zelda Sword Skills Minecraft Mod; as such, you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package zeldaswordskills.item; import java.util.List; import java.util.UUID; import net.minecraft.block.Block; import net.minecraft.block.BlockSoulSand; import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.Entity; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.StatCollector; import net.minecraft.village.MerchantRecipe; import net.minecraft.village.MerchantRecipeList; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import zeldaswordskills.api.item.ArmorIndex; import zeldaswordskills.api.item.IUnenchantable; import zeldaswordskills.creativetab.ZSSCreativeTabs; import zeldaswordskills.entity.ZSSEntityInfo; import zeldaswordskills.entity.buff.Buff; import zeldaswordskills.entity.player.ZSSPlayerInfo; import zeldaswordskills.network.PacketDispatcher; import zeldaswordskills.network.client.InLiquidPacket; import zeldaswordskills.util.MerchantRecipeHelper; import zeldaswordskills.util.PlayerUtils; import zeldaswordskills.util.WorldUtils; /** * * Various boots Link may find during his adventures. Each pair has the unique attribute * of being totally indestructible, but also unenchantable. * * Heavy Boots: Made of heavy iron, these allow Link to move more quickly in liquids, * but more slowly on land. The great weight provides great resistance * to knockback effects. Wearing Heavy Boots allows Link to pull other * entities using the Hookshot. * * Hover Boots: Allow wearer to dash across chasms, liquids, and other things. * * Pegasus Boots: These greatly increase the hero's speed and evasion. * * Rubber Boots: Handy for reducing the wearer's conductivity. * */ public class ItemArmorBoots extends ItemModArmor implements IUnenchantable { /** Armor model texture resource location */ private final String resourceLocation; /** * Armor types as used on player: 0 boots, 1 legs, 2 chest, 3 helm * Armor types as used in armor class: 0 helm, 1 chest, 2 legs, 3 boots */ public ItemArmorBoots(ArmorMaterial material, int renderIndex, String resourceLocation) { super(material, renderIndex, ArmorIndex.TYPE_BOOTS); this.resourceLocation = resourceLocation; setMaxDamage(0); setCreativeTab(ZSSCreativeTabs.tabCombat); } @Override public int getItemEnchantability() { return 0; } @Override public boolean getIsRepairable(ItemStack stack1, ItemStack stack2) { return false; } @Override public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity entity) { if (entity instanceof EntityVillager && !player.worldObj.isRemote) { EntityVillager villager = (EntityVillager) entity; MerchantRecipeList trades = villager.getRecipes(player); if (villager.getProfession() == 3 && trades != null) { MerchantRecipe trade = new MerchantRecipe(stack.copy(), new ItemStack(Items.emerald, 16)); if (player.worldObj.rand.nextFloat() < 0.2F && MerchantRecipeHelper.addToListWithCheck(trades, trade)) { PlayerUtils.sendTranslatedChat(player, "chat.zss.trade.generic.sell.1"); } else { PlayerUtils.sendTranslatedChat(player, "chat.zss.trade.generic.sorry.1"); } } else { PlayerUtils.sendTranslatedChat(player, "chat.zss.trade.generic.sorry.0"); } } return true; } @Override public void onArmorTick(World world, EntityPlayer player, ItemStack stack) { ZSSPlayerInfo info = ZSSPlayerInfo.get(player); if (!info.getFlag(ZSSPlayerInfo.IS_WEARING_BOOTS)) { info.setWearingBoots(stack); } } /** * Applies modifiers for boots when equipped, calling {@link #removeModifiers} followed by {@link #applyCustomModifiers} */ public final void applyModifiers(ItemStack stack, EntityPlayer player) { removeModifiers(stack, player); applyCustomModifiers(stack, player); } /** * Called from {@link #applyModifiers} to add any special modifiers when equipped */ protected void applyCustomModifiers(ItemStack stack, EntityPlayer player) {} /** * Called when a pair of boots is unequipped to remove any modifiers */ public void removeModifiers(ItemStack stack, EntityPlayer player) {} @Override public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type) { return resourceLocation; } @Override @SideOnly(Side.CLIENT) public void addInformation(ItemStack stack, EntityPlayer player, List<String> list, boolean advanced) { list.add(EnumChatFormatting.ITALIC + StatCollector.translateToLocal("tooltip." + getUnlocalizedName().substring(5) + ".desc.0")); } // Multimap modifiers are applied both while wearing and while holding an item /* @Override public Multimap getItemAttributeModifiers() { Multimap multimap = super.getItemAttributeModifiers(); if (this == ZSSItems.bootsHeavy) { multimap.put(SharedMonsterAttributes.knockbackResistance.getAttributeUnlocalizedName(), new AttributeModifier(heavyBootsKnockbackModifierUUID, "Heavy Boots Knockback Resistance", 0.75D, 0)); multimap.put(SharedMonsterAttributes.movementSpeed.getAttributeUnlocalizedName(), new AttributeModifier(heavyBootsMovePenaltyUUID, "Heavy Boots Movement penalty", -0.6D, 1)); } return multimap; } */ //======================================================================// // Static inner classes for Masks with custom behaviors // //======================================================================// public static class ItemHeavyBoots extends ItemArmorBoots { /** Bonus to knockback resistance when wearing Heavy Boots */ private static final UUID heavyBootsKnockbackModifierUUID = UUID.fromString("71AF0F88-82E5-49DE-B9CC-844048E33D69"); private static final AttributeModifier heavyBootsKnockbackModifier = (new AttributeModifier(heavyBootsKnockbackModifierUUID, "Heavy Boots Knockback Resistance", 1.0D, 0)).setSaved(false); /** Movement penalty for wearing Heavy Boots applies at all times */ private static final UUID heavyBootsMovePenaltyUUID = UUID.fromString("B6C8CCB6-AE7B-4F14-908A-2F41BDB4D720"); private static final AttributeModifier heavyBootsMovePenalty = (new AttributeModifier(heavyBootsMovePenaltyUUID, "Heavy Boots Movement penalty", -0.6D, 1)).setSaved(false); public ItemHeavyBoots(ArmorMaterial material, int renderIndex, String resourceLocation) { super(material, renderIndex, resourceLocation); } @Override public void onArmorTick(World world, EntityPlayer player, ItemStack stack) { super.onArmorTick(world, player, stack); WorldUtils.reverseMaterialAcceleration(world, player.getEntityBoundingBox().expand(0.0D, -0.4000000059604645D, 0.0D).contract(0.001D, 0.001D, 0.001D), Material.water, player); if (!world.isRemote) { BlockPos pos = new BlockPos(player); Material m = world.getBlockState(pos).getBlock().getMaterial(); if (m.isLiquid()) { PacketDispatcher.sendTo(new InLiquidPacket(m == Material.lava), (EntityPlayerMP) player); } Material m1 = world.getBlockState(pos.down()).getBlock().getMaterial(); if ((m1 == Material.glass || m1 == Material.ice) && world.getTotalWorldTime() % 2 == 0) { if ((!player.isSneaking() && world.rand.nextFloat() < 0.15F) || world.rand.nextFloat() < 0.01F) { world.destroyBlock(pos.down(), false); } } } } @Override protected void applyCustomModifiers(ItemStack stack, EntityPlayer player) { player.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).applyModifier(heavyBootsKnockbackModifier); player.getEntityAttribute(SharedMonsterAttributes.movementSpeed).applyModifier(heavyBootsMovePenalty); ZSSEntityInfo.get(player).applyBuff(Buff.EVADE_DOWN, Integer.MAX_VALUE, 50); } @Override public void removeModifiers(ItemStack stack, EntityPlayer player) { player.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).removeModifier(heavyBootsKnockbackModifier); player.getEntityAttribute(SharedMonsterAttributes.movementSpeed).removeModifier(heavyBootsMovePenalty); ZSSEntityInfo.get(player).removeBuff(Buff.EVADE_DOWN); } } public static class ItemHoverBoots extends ItemArmorBoots { public ItemHoverBoots(ArmorMaterial material, int renderIndex, String resourceLocation) { super(material, renderIndex, resourceLocation); } @Override public void onArmorTick(World world, EntityPlayer player, ItemStack stack) { super.onArmorTick(world, player, stack); ZSSPlayerInfo info = ZSSPlayerInfo.get(player); Block block = world.getBlockState(new BlockPos(player).down()).getBlock(); boolean flag = !block.getMaterial().blocksMovement() || block.slipperiness > 0.6F || block instanceof BlockSoulSand; if (flag && player.isSprinting() && player.motionY < 0.0D && ++info.hoverTime < 40 ) { player.posY += -player.motionY; player.motionY = 0.0D; player.fallDistance = 0.0F; if (info.hoverTime % 3 == 0) { world.spawnParticle(EnumParticleTypes.CLOUD, player.posX, player.posY - 1, player.posZ, -player.motionX, player.motionY, -player.motionZ); } } else if (info.hoverTime > 0) { info.hoverTime = 0; player.setSprinting(false); if (world.isRemote && Minecraft.getMinecraft().gameSettings.keyBindSprint.isKeyDown()) { KeyBinding.setKeyBindState(Minecraft.getMinecraft().gameSettings.keyBindSprint.getKeyCode(), false); } } } } public static class ItemPegasusBoots extends ItemArmorBoots { /** Movement bonus for wearing Pegasus Boots */ private static final UUID pegasusBootsMoveBonusUUID = UUID.fromString("36A0FC05-50EB-460B-8961-615633A6D813"); private static final AttributeModifier pegasusBootsMoveBonus = (new AttributeModifier(pegasusBootsMoveBonusUUID, "Pegasus Boots Speed Bonus", 0.3D, 2)).setSaved(false); public ItemPegasusBoots(ArmorMaterial material, int renderIndex, String resourceLocation) { super(material, renderIndex, resourceLocation); } @Override protected void applyCustomModifiers(ItemStack stack, EntityPlayer player) { player.getEntityAttribute(SharedMonsterAttributes.movementSpeed).applyModifier(pegasusBootsMoveBonus); ZSSPlayerInfo.get(player).setFlag(ZSSPlayerInfo.MOBILITY, true); ZSSEntityInfo.get(player).applyBuff(Buff.EVADE_UP, Integer.MAX_VALUE, 25); } @Override public void removeModifiers(ItemStack stack, EntityPlayer player) { player.getEntityAttribute(SharedMonsterAttributes.movementSpeed).removeModifier(pegasusBootsMoveBonus); ZSSPlayerInfo.get(player).setFlag(ZSSPlayerInfo.MOBILITY, false); ZSSEntityInfo.get(player).removeBuff(Buff.EVADE_UP); } } public static class ItemRubberBoots extends ItemArmorBoots { public ItemRubberBoots(ArmorMaterial material, int renderIndex, String resourceLocation) { super(material, renderIndex, resourceLocation); } @Override protected void applyCustomModifiers(ItemStack stack, EntityPlayer player) { ZSSEntityInfo.get(player).applyBuff(Buff.RESIST_SHOCK, Integer.MAX_VALUE, 50); } @Override public void removeModifiers(ItemStack stack, EntityPlayer player) { ZSSEntityInfo.get(player).removeBuff(Buff.RESIST_SHOCK); } } }