diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index 6cf756a2e..7cb01fe99 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -55,6 +55,7 @@ import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.inventory.ContainerRepair; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemArmor; @@ -268,7 +269,7 @@ public class ForgeHooks public static int getTotalArmorValue(EntityPlayer player) { - int ret = 0; + int ret = player.getTotalArmorValue(); for (int x = 0; x < player.inventory.armorInventory.size(); x++) { ItemStack stack = player.inventory.armorInventory.get(x); @@ -276,10 +277,6 @@ public class ForgeHooks { ret += ((ISpecialArmor)stack.getItem()).getArmorDisplay(player, stack, x); } - else if (stack.getItem() instanceof ItemArmor) - { - ret += ((ItemArmor)stack.getItem()).damageReduceAmount; - } } return ret; } diff --git a/src/main/java/net/minecraftforge/common/ISpecialArmor.java b/src/main/java/net/minecraftforge/common/ISpecialArmor.java index 129ba9166..2b7ab4968 100644 --- a/src/main/java/net/minecraftforge/common/ISpecialArmor.java +++ b/src/main/java/net/minecraftforge/common/ISpecialArmor.java @@ -27,9 +27,12 @@ package net.minecraftforge.common; import java.util.ArrayList; import java.util.Arrays; +import net.minecraft.util.CombatRules; import net.minecraft.util.DamageSource; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; import net.minecraft.util.NonNullList; @@ -90,17 +93,22 @@ public interface ISpecialArmor public static class ArmorProperties implements Comparable { - public int Priority = 0; - public int AbsorbMax = Integer.MAX_VALUE; - public double AbsorbRatio = 0; - public int Slot = 0; + public int Priority = 0; + public int AbsorbMax = Integer.MAX_VALUE; + public double AbsorbRatio = 0; + public double Armor = 0; //Additional armor, separate from the armor added by vanilla attributes. + public double Toughness = 0; //Additional toughness, separate from the armor added by vanilla attributes. + public int Slot = 0; private static final boolean DEBUG = false; //Only enable this if you wish to be spammed with debugging information. //Left it in because I figured it'd be useful for modders developing custom armor. + public ArmorProperties(int priority, double ratio, int max) { Priority = priority; AbsorbRatio = ratio; + Armor = 0; + Toughness = 0; AbsorbMax = max; } @@ -117,31 +125,40 @@ public interface ISpecialArmor { if (DEBUG) { - System.out.println("Start: " + damage + " " + (damage * 25)); + System.out.println("Start: " + damage); } - damage *= 25; + + double totalArmor = entity.getTotalArmorValue(); + double totalToughness = entity.getEntityAttribute(SharedMonsterAttributes.ARMOR_TOUGHNESS).getAttributeValue(); + ArrayList dmgVals = new ArrayList(); - for (int x = 0; x < inventory.size(); x++) + for (int slot = 0; slot < inventory.size(); slot++) { - ItemStack stack = inventory.get(x); + ItemStack stack = inventory.get(slot); + if (stack.isEmpty()) { continue; } + ArmorProperties prop = null; if (stack.getItem() instanceof ISpecialArmor) { ISpecialArmor armor = (ISpecialArmor)stack.getItem(); - prop = armor.getProperties(entity, stack, source, damage / 25D, x).copy(); + prop = armor.getProperties(entity, stack, source, damage, slot).copy(); + totalArmor += prop.Armor; + totalToughness += prop.Toughness; } else if (stack.getItem() instanceof ItemArmor && !source.isUnblockable()) { ItemArmor armor = (ItemArmor)stack.getItem(); - prop = new ArmorProperties(0, armor.damageReduceAmount / 25D, Integer.MAX_VALUE); + prop = new ArmorProperties(0, 0, Integer.MAX_VALUE); + prop.Armor = armor.damageReduceAmount; + prop.Toughness = armor.toughness; } if (prop != null) { - prop.Slot = x; + prop.Slot = slot; dmgVals.add(prop); } } @@ -165,7 +182,7 @@ public interface ISpecialArmor if (absorb > 0) { ItemStack stack = inventory.get(prop.Slot); - int itemDamage = (int)(absorb / 25D < 1 ? 1 : absorb / 25D); + int itemDamage = (int)Math.max(1, absorb); if (stack.getItem() instanceof ISpecialArmor) { ((ISpecialArmor)stack.getItem()).damageArmor(entity, stack, source, itemDamage, prop.Slot); @@ -174,7 +191,7 @@ public interface ISpecialArmor { if (DEBUG) { - System.out.println("Item: " + stack.toString() + " Absorbed: " + (absorb / 25D) + " Damaged: " + itemDamage); + System.out.println("Item: " + stack.toString() + " Absorbed: " + absorb + " Damaged: " + itemDamage); } stack.damageItem(itemDamage, entity); } @@ -190,11 +207,29 @@ public interface ISpecialArmor } damage -= (damage * ratio); } + if (damage > 0 && (totalArmor > 0 || totalToughness > 0)) + { + double armorDamage = Math.max(1.0F, damage / 4.0F); + + for (int i = 0; i < inventory.size(); i++) + { + if (inventory.get(i).getItem() instanceof ItemArmor) + { + inventory.get(i).damageItem((int)armorDamage, entity); + + if (inventory.get(i).getCount() == 0) + { + inventory.set(i, ItemStack.EMPTY); + } + } + } + damage = CombatRules.getDamageAfterAbsorb((float)damage, (float)totalArmor, (float)totalToughness); + } if (DEBUG) { - System.out.println("Return: " + (int)(damage / 25.0F) + " " + damage); + System.out.println("Return: " + (int)(damage) + " " + damage); } - return (float)(damage / 25.0F); + return (float)(damage); } /** @@ -336,7 +371,10 @@ public interface ISpecialArmor public ArmorProperties copy() { - return new ArmorProperties(Priority, AbsorbRatio, AbsorbMax); + ArmorProperties copy = new ArmorProperties(Priority, AbsorbRatio, AbsorbMax); + copy.Armor = Armor; + copy.Toughness = Toughness; + return copy; } } } diff --git a/src/test/java/net/minecraftforge/test/PlayerDamageReworkTest.java b/src/test/java/net/minecraftforge/test/PlayerDamageReworkTest.java new file mode 100644 index 000000000..133f37d9f --- /dev/null +++ b/src/test/java/net/minecraftforge/test/PlayerDamageReworkTest.java @@ -0,0 +1,47 @@ +package net.minecraftforge.test; + +import java.util.UUID; + +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.Mod.EventHandler; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +@Mod(modid = "playerdamagereworktest", name = "PlayerDamageReworkTest", version = "0.0.0") +public class PlayerDamageReworkTest +{ + private static final boolean ENABLE = false; + private static final UUID ARMOR_MODIFIER_UUID = UUID.fromString("23373DC8-1F3D-11E7-93AE-92361F002671"); + private static final AttributeModifier mod = new AttributeModifier(ARMOR_MODIFIER_UUID, "Player Damage Rework Test", 20, 0); + + @EventHandler + public void init(FMLInitializationEvent event) + { + if (ENABLE) MinecraftForge.EVENT_BUS.register(this); + } + + @SubscribeEvent + public void checkForSneakEvent(LivingUpdateEvent event) + { + if (event.getEntityLiving() instanceof EntityPlayer) + { + EntityPlayer player = (EntityPlayer) event.getEntityLiving(); + if (player.isSneaking()) + { + if (!player.getEntityAttribute(SharedMonsterAttributes.ARMOR).hasModifier(mod)) + { + player.getEntityAttribute(SharedMonsterAttributes.ARMOR).applyModifier(mod); + } + } + else if (player.getEntityAttribute(SharedMonsterAttributes.ARMOR).hasModifier(mod)) + { + player.getEntityAttribute(SharedMonsterAttributes.ARMOR).removeModifier(ARMOR_MODIFIER_UUID); + } + } + } +} \ No newline at end of file