diff --git a/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java b/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java index 455cf6929..728439bd9 100644 --- a/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java +++ b/src/main/java/noppes/npcs/ScriptPlayerEventHandler.java @@ -25,6 +25,8 @@ import noppes.npcs.api.entity.IPlayer; import noppes.npcs.api.item.IItemCustomizable; import noppes.npcs.attribute.AttributeController; import noppes.npcs.attribute.AttributeAttackHelper; +import noppes.npcs.attribute.player.PlayerAttributeTracker; +import noppes.npcs.config.ConfigMain; import noppes.npcs.constants.EnumQuestType; import noppes.npcs.controllers.CustomEffectController; import noppes.npcs.controllers.PartyController; @@ -62,7 +64,8 @@ public class ScriptPlayerEventHandler { } } - AttributeController.getTracker(player).updateIfChanged(player); + if(ConfigMain.AttributesEnabled) + AttributeController.getTracker(player).updateIfChanged(player); } if (PlayerDataController.Instance != null) { @@ -473,7 +476,11 @@ public class ScriptPlayerEventHandler { } if(event.source.getEntity() instanceof EntityPlayer) { - noppes.npcs.scripted.event.PlayerEvent.AttackEvent pevent1 = new noppes.npcs.scripted.event.PlayerEvent.AttackEvent((IPlayer)NpcAPI.Instance().getIEntity((EntityPlayer)event.source.getEntity()), event.entityLiving, event.ammount, event.source); + float attackAmount = event.ammount; + if(ConfigMain.AttributesEnabled) + attackAmount = AttributeAttackHelper.calculateOutgoing((EntityPlayer) event.source.getEntity(), event.ammount); + + noppes.npcs.scripted.event.PlayerEvent.AttackEvent pevent1 = new noppes.npcs.scripted.event.PlayerEvent.AttackEvent((IPlayer)NpcAPI.Instance().getIEntity((EntityPlayer)event.source.getEntity()), event.entityLiving, attackAmount, event.source); cancel = cancel || EventHooks.onPlayerAttack(handler, pevent1); } event.setCanceled(cancel); @@ -489,6 +496,16 @@ public class ScriptPlayerEventHandler { boolean cancel = event.isCanceled(); Entity source = NoppesUtilServer.GetDamageSource(event.source); PlayerDataScript handler = ScriptController.Instance.playerScripts; + + // Player to Player Interaction + if(ConfigMain.AttributesEnabled){ + if(event.entityLiving instanceof EntityPlayer && source instanceof EntityPlayer){ + event.ammount = AttributeAttackHelper.calculateDamagePlayer((EntityPlayer) event.entityLiving, (EntityPlayer) source, event.ammount); + } else if (!(event.entityLiving instanceof EntityNPCInterface) && source instanceof EntityPlayer){ + event.ammount = AttributeAttackHelper.calculateOutgoing((EntityPlayer) event.entityLiving, event.ammount); + } + } + if(event.entityLiving instanceof EntityPlayer) { noppes.npcs.scripted.event.PlayerEvent.DamagedEvent pevent = new noppes.npcs.scripted.event.PlayerEvent.DamagedEvent((IPlayer)NpcAPI.Instance().getIEntity((EntityPlayer)event.entityLiving), source, event.ammount, event.source); cancel = EventHooks.onPlayerDamaged(handler, pevent); diff --git a/src/main/java/noppes/npcs/attribute/AttributeAttackHelper.java b/src/main/java/noppes/npcs/attribute/AttributeAttackHelper.java index a8fa92ccd..0ff177f63 100644 --- a/src/main/java/noppes/npcs/attribute/AttributeAttackHelper.java +++ b/src/main/java/noppes/npcs/attribute/AttributeAttackHelper.java @@ -8,18 +8,20 @@ import noppes.npcs.entity.EntityNPCInterface; import java.util.Map; import java.util.Random; +import static noppes.npcs.attribute.AttributeController.getTracker; + public class AttributeAttackHelper { private static final Random random = new Random(); public static float calculateDamagePlayer(EntityPlayer attacker, EntityPlayer defender, float base){ - return calculateDamagePlayer(AttributeController.getTracker(attacker), AttributeController.getTracker(defender), base); + return calculateDamagePlayer(getTracker(attacker), getTracker(defender), base); } public static float calculateDamagePlayer(PlayerAttributeTracker attacker, PlayerAttributeTracker defender, float baseDamage) { // Calculate physical damage float mainAttack = attacker.getAttributeValue(ModAttributes.MAIN_ATTACK); - float mainBoost = attacker.getAttributeValue(ModAttributes.MAGIC_BOOST) + 1; + float mainBoost = attacker.getAttributeValue(ModAttributes.MAIN_BOOST) + 1; float physicalDamage = (baseDamage * mainBoost) + mainAttack; // Calculate neutral damage @@ -64,7 +66,7 @@ public class AttributeAttackHelper { // Calculate physical damage float mainAttack = attacker.getAttributeValue(ModAttributes.MAIN_ATTACK); - float mainBoost = attacker.getAttributeValue(ModAttributes.MAGIC_BOOST) + 1; + float mainBoost = attacker.getAttributeValue(ModAttributes.MAIN_BOOST) + 1; float physicalDamage = (baseDamage * mainBoost) + mainAttack; // Calculate neutral damage @@ -105,4 +107,47 @@ public class AttributeAttackHelper { return 0; } + /** + * Calculates a player's total damage when attacking an opponent with no defense. + * In this calculation, any defensive modifiers (such as magic defense or resistance) + * are assumed to be zero. + * + * @param attacker The attacker's attribute tracker. + * @return The total calculated damage. + */ + public static float calculateMaximumOutput(PlayerAttributeTracker attacker) { + // Neutral damage remains unchanged. + float neutralDamage = attacker.getAttributeValue(ModAttributes.NEUTRAL_ATTACK); + float neutralBoost = attacker.getAttributeValue(ModAttributes.NEUTRAL_BOOST) + 1; + float neutralTotal = neutralDamage * neutralBoost; + + // For magic damage, we ignore any defensive values. + float magicTotal = 0.0f; + MagicController magicController = MagicController.getInstance(); + for (Map.Entry entry : attacker.magicDamage.entrySet()) { + int magicId = entry.getKey(); + if (magicController.getMagic(magicId) != null) { + float attackMagic = entry.getValue(); + // No defender, so effective magic equals attack magic. + float effectiveMagic = attackMagic; + + float boostMagic = attacker.magicBoost.getOrDefault(magicId, 0.0f); + // No resistance present. + float effectiveBoost = boostMagic; + + float magicDamageForMagic = effectiveMagic * (effectiveBoost + 1); + magicTotal += Math.max(0, magicDamageForMagic); + } + } + return neutralTotal + magicTotal; + } + + public static float calculateOutgoing(EntityPlayer entityPlayer, float baseDamage) { + PlayerAttributeTracker attacker = getTracker(entityPlayer); + + float mainAttack = attacker.getAttributeValue(ModAttributes.MAIN_ATTACK); + float mainBoost = attacker.getAttributeValue(ModAttributes.MAIN_BOOST) + 1; + float physicalDamage = (baseDamage * mainBoost) + mainAttack; + return attacker.maximumOutput + physicalDamage; + } } diff --git a/src/main/java/noppes/npcs/attribute/player/PlayerAttributeTracker.java b/src/main/java/noppes/npcs/attribute/player/PlayerAttributeTracker.java index 8c4825e9d..6b0ac7ee7 100644 --- a/src/main/java/noppes/npcs/attribute/player/PlayerAttributeTracker.java +++ b/src/main/java/noppes/npcs/attribute/player/PlayerAttributeTracker.java @@ -13,7 +13,9 @@ public class PlayerAttributeTracker { private final UUID playerId; private PlayerAttributeMap playerAttributes = new PlayerAttributeMap(); - public final int extraHealth = 0; + public int extraHealth = 0; + public float maximumOutput = 0.0f; + public final Map magicDamage = new HashMap<>(); public final Map magicBoost = new HashMap<>(); public final Map magicDefense = new HashMap<>(); @@ -90,6 +92,7 @@ public class PlayerAttributeTracker { } } equipmentTracker = currentEquip; + maximumOutput = AttributeAttackHelper.calculateMaximumOutput(this); } } diff --git a/src/main/java/noppes/npcs/config/ConfigMain.java b/src/main/java/noppes/npcs/config/ConfigMain.java index 7732dd7c5..0f5b2e569 100644 --- a/src/main/java/noppes/npcs/config/ConfigMain.java +++ b/src/main/java/noppes/npcs/config/ConfigMain.java @@ -20,6 +20,7 @@ public class ConfigMain public final static String UPDATE = "Update"; public final static String PARTY = "PARTY"; public final static String PROFILES = "Profile"; + public final static String ATTRIBUTES = "Attributes"; /** * General Main Properties @@ -82,6 +83,11 @@ public class ConfigMain public static Property DefaultMaxPartySizeProperty; public static int DefaultMaxPartySize = 4; + /** + * Attribute Properties + **/ + public static boolean AttributesEnabled = true; + /** * Profile Properties **/