package cyano.basemetals.items; import cyano.basemetals.BaseMetals; import cyano.basemetals.init.Achievements; import cyano.basemetals.init.Materials; import cyano.basemetals.material.IMetalObject; import cyano.basemetals.material.MetalMaterial; import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.oredict.OreDictionary; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; public class ItemMetalArmor extends net.minecraft.item.ItemArmor implements IMetalObject { private static final ResourceLocation speedPotionKey = new ResourceLocation("speed"); private static final ResourceLocation jumpPotionKey = new ResourceLocation("jump_boost"); private static final ResourceLocation slowPotionKey = new ResourceLocation("slowness"); private static final ResourceLocation protectionPotionKey = new ResourceLocation("resistance"); private static final ResourceLocation waterBreathingPotionKey = new ResourceLocation("water_breathing"); private static final ResourceLocation waterBuffPotionKey = new ResourceLocation("resistance"); private static final ResourceLocation fatiguePotionKey = new ResourceLocation("mining_fatigue"); private static final ResourceLocation fireproofPotionKey = new ResourceLocation("fire_resistance"); protected final String customTexture; protected final MetalMaterial metal; protected final String repairOreDictName; protected ItemMetalArmor(MetalMaterial metal, ArmorMaterial armorMat, int renderIndex, EntityEquipmentSlot slot) { super(armorMat, renderIndex, slot); this.metal = metal; this.repairOreDictName = "ingot"+metal.getCapitalizedName(); this.customTexture = BaseMetals.MODID+":textures/models/armor/"+metal.getName()+"_layer_"+(slot == EntityEquipmentSlot.LEGS ? 2 : 1)+".png"; } private static final int UPDATE_INTERVAL = 11; private static final int EFFECT_DURATION = 45; private static final Map<EntityPlayer,AtomicLong> playerUpdateTimestampMap = new HashMap<>(); private static final Map<EntityPlayer,AtomicInteger> playerUpdateCountMap = new HashMap<>(); @Override public void onArmorTick(World w, EntityPlayer player, ItemStack armor){ if(playerUpdateTimestampMap.containsKey(player) == false){ playerUpdateTimestampMap.put(player, new AtomicLong(0)); playerUpdateCountMap.put(player, new AtomicInteger(0)); return; } if(!w.isRemote && w.getTotalWorldTime() > playerUpdateTimestampMap.get(player).get()){ // FMLLog.info("onArmorTick update triggered at time="+w.getTotalWorldTime()+" (update target was "+playerUpdateTimestampMap.get(player).get()+") for player "+player.getName()+" by item "+armor); // debug code playerUpdateTimestampMap.get(player).set(w.getTotalWorldTime() + UPDATE_INTERVAL); int updateCount = playerUpdateCountMap.get(player).getAndIncrement(); for(int i = 0; i < 4; i++){ if(player.inventory.armorInventory[i] != null && player.inventory.armorInventory[i].getItem() instanceof ItemMetalArmor){ doArmorUpdate(w,player,player.inventory.armorInventory[i],updateCount); } } } } private static final Map<EntityPlayer,AtomicInteger> starsteelUpdateCache = new HashMap<>(); private static final Map<EntityPlayer,AtomicInteger> adamantineUpdateCache = new HashMap<>(); private static final Map<EntityPlayer,AtomicInteger> leadUpdateCache = new HashMap<>(); protected void doArmorUpdate(final World w, final EntityPlayer player, final ItemStack armor, int i) { // some sanity checks if(armor == null) return; if(armor.getItem() == null) return; if(player == null) return; // FMLLog.info("doArmorUpdate "+i+" for "+player.getName()+" on item "+armor); // debug code Item armorItem = armor.getItem(); if(i % 2 == 0){ // count armor pieces if(((ItemMetalArmor)armorItem).metal.equals(Materials.starsteel)){ starsteel:{ // used to count up the starsteel armor items if(starsteelUpdateCache.containsKey(player) == false){ starsteelUpdateCache.put(player, new AtomicInteger(0)); } starsteelUpdateCache.get(player).incrementAndGet(); if(armorItem == cyano.basemetals.init.Items.starsteel_boots) player.addStat(Achievements.moon_boots, 1); break starsteel; } } if(((ItemMetalArmor)armorItem).metal.equals(Materials.lead)){ lead:{ // used to count up the starsteel armor items if(leadUpdateCache.containsKey(player) == false){ leadUpdateCache.put(player, new AtomicInteger(0)); } leadUpdateCache.get(player).incrementAndGet(); break lead; } } if(((ItemMetalArmor)armorItem).metal.equals(Materials.adamantine)){ adamantine:{ // used to count up the adamantine armor items if(adamantineUpdateCache.containsKey(player) == false){ adamantineUpdateCache.put(player, new AtomicInteger(0)); } adamantineUpdateCache.get(player).incrementAndGet(); break adamantine; } } } else { // apply potion effects. Note that "Level I" is actually effect level 0 in the effect constructor starsteel:{ if(starsteelUpdateCache.containsKey(player) == false) break starsteel; int num = starsteelUpdateCache.get(player).getAndSet(0); if(num == 0) break starsteel; final PotionEffect jumpBoost = new PotionEffect(Potion.REGISTRY.getObject(jumpPotionKey),EFFECT_DURATION,num-1,false,false); player.addPotionEffect(jumpBoost); if(num > 1){ final PotionEffect speedBoost = new PotionEffect(Potion.REGISTRY.getObject(speedPotionKey),EFFECT_DURATION,num-2,false,false); player.addPotionEffect(speedBoost); } break starsteel; } lead:{ if(leadUpdateCache.containsKey(player) == false) break lead; int level = leadUpdateCache.get(player).getAndSet(0) / 2; if(level == 0) break lead; if(level > 0){ final PotionEffect speedLoss = new PotionEffect(Potion.REGISTRY.getObject(slowPotionKey),EFFECT_DURATION,level-1,false,false); player.addPotionEffect(speedLoss); } break lead; } adamantine:{ if(adamantineUpdateCache.containsKey(player) == false) break adamantine; int num = adamantineUpdateCache.get(player).getAndSet(0); int level = num / 2; if(level == 0) break adamantine; if(level > 0){ final PotionEffect protection = new PotionEffect(Potion.REGISTRY.getObject(protectionPotionKey),EFFECT_DURATION,level-1,false,false); player.addPotionEffect(protection); } if(num == 4){ player.addStat(Achievements.juggernaut, 1); } break adamantine; } // full suit of cold-iron makes you fire-proof if(armorItem == cyano.basemetals.init.Items.coldiron_helmet){ if(player.inventory.armorInventory[2] != null && player.inventory.armorInventory[2].getItem() == cyano.basemetals.init.Items.coldiron_chestplate && player.inventory.armorInventory[1] != null && player.inventory.armorInventory[1].getItem() == cyano.basemetals.init.Items.coldiron_leggings && player.inventory.armorInventory[0] != null && player.inventory.armorInventory[0].getItem() == cyano.basemetals.init.Items.coldiron_boots){ final PotionEffect fireProtection = new PotionEffect(Potion.REGISTRY.getObject(fireproofPotionKey),EFFECT_DURATION,0,false,false); player.addPotionEffect(fireProtection); if(player.getHeldItemMainhand() != null && player.getHeldItemMainhand().getItem() == cyano.basemetals.init.Items.coldiron_sword){ player.addStat(Achievements.demon_slayer, 1); } } } // full suit of mithril protects you from withering, poison, nausea, and hunger effects if(armorItem == cyano.basemetals.init.Items.mithril_helmet){ if(player.inventory.armorInventory[2] != null && player.inventory.armorInventory[2].getItem() == cyano.basemetals.init.Items.mithril_chestplate && player.inventory.armorInventory[1] != null && player.inventory.armorInventory[1].getItem() == cyano.basemetals.init.Items.mithril_leggings && player.inventory.armorInventory[0] != null && player.inventory.armorInventory[0].getItem() == cyano.basemetals.init.Items.mithril_boots){ final List<Potion> removeList = new LinkedList<>(); // needed to avoid concurrent modification error Iterator<PotionEffect> effectIterator = player.getActivePotionEffects().iterator(); while(effectIterator.hasNext()){ PotionEffect pe = effectIterator.next(); Potion p = pe.getPotion(); if(p.isBadEffect()){ removeList.add(p); } } for(Potion p : removeList){ player.removePotionEffect(p); } if(player.getHeldItemMainhand() != null && player.getHeldItemMainhand().getItem() == cyano.basemetals.init.Items.mithril_sword){ player.addStat(Achievements.angel_of_death, 1); } } } // full suit of aquarium makes you breathe and heal underwater if(armorItem == cyano.basemetals.init.Items.aquarium_helmet && player.posY > 0 && player.posY < 255){ if(player.inventory.armorInventory[2] != null && player.inventory.armorInventory[2].getItem() == cyano.basemetals.init.Items.aquarium_chestplate && player.inventory.armorInventory[1] != null && player.inventory.armorInventory[1].getItem() == cyano.basemetals.init.Items.aquarium_leggings && player.inventory.armorInventory[0] != null && player.inventory.armorInventory[0].getItem() == cyano.basemetals.init.Items.aquarium_boots){ Block b1 = w.getBlockState(new BlockPos(player.posX,player.posY, player.posZ)).getBlock(); Block b2 = w.getBlockState(new BlockPos(player.posX,player.posY+1, player.posZ)).getBlock(); if(b1 == Blocks.WATER && b2 == Blocks.WATER){ final PotionEffect waterBreathing = new PotionEffect(Potion.REGISTRY.getObject(waterBreathingPotionKey),EFFECT_DURATION,0,false,false); player.addPotionEffect(waterBreathing); final PotionEffect protection = new PotionEffect(Potion.REGISTRY.getObject(waterBuffPotionKey),EFFECT_DURATION,0,false,false); player.addPotionEffect(protection); player.removePotionEffect(Potion.REGISTRY.getObject(fatiguePotionKey)); player.addStat(Achievements.scuba_diver, 1); } } } } } public static ItemMetalArmor createHelmet(MetalMaterial metal){ ArmorMaterial material = cyano.basemetals.init.Materials.getArmorMaterialFor(metal); if(material == null){ // uh-oh FMLLog.severe("Failed to load armor material enum for "+metal); } return new ItemMetalArmor(metal,material,material.ordinal(),EntityEquipmentSlot.HEAD); } public static ItemMetalArmor createChestplate(MetalMaterial metal){ ArmorMaterial material = cyano.basemetals.init.Materials.getArmorMaterialFor(metal); if(material == null){ // uh-oh FMLLog.severe("Failed to load armor material enum for "+metal); } return new ItemMetalArmor(metal,material,material.ordinal(),EntityEquipmentSlot.CHEST); } public static ItemMetalArmor createLeggings(MetalMaterial metal){ ArmorMaterial material = cyano.basemetals.init.Materials.getArmorMaterialFor(metal); if(material == null){ // uh-oh FMLLog.severe("Failed to load armor material enum for "+metal); } return new ItemMetalArmor(metal,material,material.ordinal(),EntityEquipmentSlot.LEGS); } public static ItemMetalArmor createBoots(MetalMaterial metal){ ArmorMaterial material = cyano.basemetals.init.Materials.getArmorMaterialFor(metal); if(material == null){ // uh-oh FMLLog.severe("Failed to load armor material enum for "+metal); } return new ItemMetalArmor(metal,material,material.ordinal(),EntityEquipmentSlot.FEET); } @Override public void onCreated(final ItemStack item, final World world, final EntityPlayer crafter) { super.onCreated(item, world, crafter); extraEffectsOnCrafting(item, world, crafter); } public void extraEffectsOnCrafting(final ItemStack item, final World world, final EntityPlayer crafter){ // } /** * Return whether this item is repairable in an anvil. */ @Override public boolean getIsRepairable(ItemStack srcItemStack, ItemStack repairMaterial) { // repair with string or wool List<ItemStack> acceptableItems = OreDictionary.getOres(repairOreDictName); for(ItemStack i : acceptableItems ){ if(ItemStack.areItemsEqual(i, repairMaterial)) return true; } return false; } @SideOnly(Side.CLIENT) @Override public String getArmorTexture(ItemStack stack, Entity e, EntityEquipmentSlot slot, String layer){ return customTexture; } @Override public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean b){ super.addInformation(stack,player,list,b); MetalToolEffects.addArmorSpecialPropertiesToolTip(metal,list); } @Override public MetalMaterial getMetalMaterial(){ return metal; } }