mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 22:27:32 +00:00
Fix Critical and Attribute Handling for CNPC+ and DBC Addon
This commit is contained in:
1 parent
159b740f39
commit
c3096b320e
2 files changed
+55
-4
No files matched your search
@@ -20,6 +20,13 @@ import static kamkeel.npcs.controllers.AttributeController.getTracker;
|
||||
|
||||
public class AttributeAttackUtil {
|
||||
private static final Random random = new Random();
|
||||
|
||||
/**
|
||||
* Crit decision from the last LivingAttackEvent for vanilla/modded mob targets.
|
||||
* Set in LivingAttackEvent, consumed in LivingHurtEvent.
|
||||
* null = no roll occurred, true = critted, false = did not crit.
|
||||
*/
|
||||
public static Boolean lastAttackCritted = null;
|
||||
// --- Helper Classes & Methods ---
|
||||
|
||||
// Container for allocation results.
|
||||
@@ -168,10 +175,31 @@ public class AttributeAttackUtil {
|
||||
|
||||
public static float applyCrit(float damage, PlayerAttributeTracker tracker) {
|
||||
if (ConfigMain.AttributesEnabled) {
|
||||
if (rollCrit(tracker))
|
||||
damage = applyCritDamage(damage, tracker);
|
||||
}
|
||||
return damage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rolls for a critical hit based on the tracker's CRITICAL_CHANCE attribute.
|
||||
*/
|
||||
public static boolean rollCrit(PlayerAttributeTracker tracker) {
|
||||
if (ConfigMain.AttributesEnabled && tracker != null) {
|
||||
float critChance = tracker.getAttributeValue(CustomAttributes.CRITICAL_CHANCE);
|
||||
return random.nextFloat() < (critChance / 100f);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies crit damage unconditionally (no chance roll).
|
||||
* Use when the crit decision was already made via {@link #rollCrit}.
|
||||
*/
|
||||
public static float applyCritDamage(float damage, PlayerAttributeTracker tracker) {
|
||||
if (ConfigMain.AttributesEnabled && tracker != null) {
|
||||
float critBonus = tracker.getAttributeValue(CustomAttributes.CRITICAL_DAMAGE);
|
||||
if (random.nextFloat() < (critChance / 100f))
|
||||
damage = (damage * (1 + (float) ConfigMain.AttributesCriticalBoost / 100f)) + critBonus;
|
||||
damage = (damage * (1 + (float) ConfigMain.AttributesCriticalBoost / 100f)) + critBonus;
|
||||
}
|
||||
return damage;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import cpw.mods.fml.relauncher.Side;
|
||||
import kamkeel.npcs.addon.DBCAddon;
|
||||
import kamkeel.npcs.controllers.AbilityController;
|
||||
import kamkeel.npcs.controllers.AttributeController;
|
||||
import kamkeel.npcs.controllers.data.attribute.tracker.PlayerAttributeTracker;
|
||||
import kamkeel.npcs.controllers.SyncController;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.type.AbilityCounter;
|
||||
@@ -623,8 +624,21 @@ public class ScriptPlayerEventHandler {
|
||||
|
||||
PlayerDataScript handler = ScriptController.Instance.getPlayerScripts((EntityPlayer) event.source.getEntity());
|
||||
float attackAmount = event.ammount;
|
||||
if (ConfigMain.AttributesEnabled && !DBCAddon.IsAvailable())
|
||||
attackAmount = AttributeAttackUtil.calculateOutgoing((EntityPlayer) event.source.getEntity(), attackAmount);
|
||||
AttributeAttackUtil.lastAttackCritted = null;
|
||||
if (ConfigMain.AttributesEnabled && !DBCAddon.IsAvailable()) {
|
||||
EntityPlayer attackPlayer = (EntityPlayer) event.source.getEntity();
|
||||
attackAmount = AttributeAttackUtil.calculateOutgoing(attackPlayer, attackAmount);
|
||||
// For vanilla/modded mob targets, roll crit once and store for LivingHurtEvent
|
||||
if (!(event.entityLiving instanceof EntityPlayerMP) && !(event.entityLiving instanceof EntityNPCInterface)) {
|
||||
PlayerAttributeTracker tracker = AttributeController.getTracker(attackPlayer);
|
||||
if (AttributeAttackUtil.rollCrit(tracker)) {
|
||||
AttributeAttackUtil.lastAttackCritted = true;
|
||||
attackAmount = AttributeAttackUtil.applyCritDamage(attackAmount, tracker);
|
||||
} else {
|
||||
AttributeAttackUtil.lastAttackCritted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
noppes.npcs.scripted.event.player.PlayerEvent.AttackEvent pevent1 = new noppes.npcs.scripted.event.player.PlayerEvent.AttackEvent((IPlayer) NpcAPI.Instance().getIEntity((EntityPlayer) event.source.getEntity()), event.entityLiving, attackAmount, event.source);
|
||||
cancel = cancel || EventHooks.onPlayerAttack(handler, pevent1);
|
||||
@@ -663,6 +677,15 @@ public class ScriptPlayerEventHandler {
|
||||
event.ammount = AttributeAttackUtil.calculateDamagePlayerToPlayer((EntityPlayer) source, (EntityPlayer) event.entityLiving, event.ammount);
|
||||
} else if (!(event.entityLiving instanceof EntityNPCInterface) && source instanceof EntityPlayer) {
|
||||
event.ammount = AttributeAttackUtil.calculateOutgoing((EntityPlayer) source, event.ammount);
|
||||
if (AttributeAttackUtil.lastAttackCritted != null) {
|
||||
// Use the crit decision from LivingAttackEvent
|
||||
if (AttributeAttackUtil.lastAttackCritted)
|
||||
event.ammount = AttributeAttackUtil.applyCritDamage(event.ammount, AttributeController.getTracker((EntityPlayer) source));
|
||||
AttributeAttackUtil.lastAttackCritted = null;
|
||||
} else {
|
||||
// Fallback: roll independently (no preceding LivingAttackEvent)
|
||||
event.ammount = AttributeAttackUtil.applyCrit(event.ammount, AttributeController.getTracker((EntityPlayer) source));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user