From 8a998c6f621bb401ec535a8b536d7bea8b4429c6 Mon Sep 17 00:00:00 2001 From: Kam Date: Tue, 24 Feb 2026 23:52:01 -0500 Subject: [PATCH] Fix Barrier + DBC Logic --- .../npcs/controllers/AbilityController.java | 5 ++-- .../controllers/data/ability/Ability.java | 2 +- .../ability/extender/IAbilityExtender.java | 6 +++- .../npcs/entity/EntityAbilityLaser.java | 4 +-- .../npcs/entity/EntityEnergyProjectile.java | 30 ++++++++++++++++--- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/main/java/kamkeel/npcs/controllers/AbilityController.java b/src/main/java/kamkeel/npcs/controllers/AbilityController.java index 9e9d3de07..8a67683bc 100644 --- a/src/main/java/kamkeel/npcs/controllers/AbilityController.java +++ b/src/main/java/kamkeel/npcs/controllers/AbilityController.java @@ -1132,10 +1132,11 @@ public class AbilityController implements IAbilityHandler { */ public boolean fireOnAbilityDamage(Ability ability, EntityLivingBase caster, EntityLivingBase target, float damage, float knockback, float knockbackUp, - double knockbackDirX, double knockbackDirZ) { + double knockbackDirX, double knockbackDirZ, + float damageRatio) { for (IAbilityExtender ext : extenders) { if (ext.onAbilityDamage(ability, caster, target, damage, knockback, knockbackUp, - knockbackDirX, knockbackDirZ)) { + knockbackDirX, knockbackDirZ, damageRatio)) { return true; } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java b/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java index 257df22d0..1b3b290fe 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java @@ -476,7 +476,7 @@ public abstract class Ability implements IAbility, IAbilityAction { // Check for ability extenders (e.g., DBC Addon damage routing) boolean handled = AbilityController.Instance.fireOnAbilityDamage( this, caster, hitEntity, damage, knockback, knockbackUp, - knockbackDirX, knockbackDirZ); + knockbackDirX, knockbackDirZ, 1.0f); if (!handled) { // Default damage path if (caster instanceof EntityNPCInterface) { diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/extender/IAbilityExtender.java b/src/main/java/kamkeel/npcs/controllers/data/ability/extender/IAbilityExtender.java index 294b79ac8..38360eb85 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/extender/IAbilityExtender.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/extender/IAbilityExtender.java @@ -69,11 +69,15 @@ public interface IAbilityExtender { * @param knockbackUp The vertical knockback * @param knockbackDirX The X component of knockback direction * @param knockbackDirZ The Z component of knockback direction + * @param damageRatio Proportional damage factor from barrier interactions (0.0-1.0). + * 1.0 means full damage (no barrier reduction). Extenders that + * recalculate damage from stats should multiply by this ratio. * @return true if damage was handled (skip default), false to pass to next extender or default */ default boolean onAbilityDamage(Ability ability, EntityLivingBase caster, EntityLivingBase target, float damage, float knockback, float knockbackUp, - double knockbackDirX, double knockbackDirZ) { + double knockbackDirX, double knockbackDirZ, + float damageRatio) { return false; } diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java index d573e19fb..2d1017e38 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java @@ -442,7 +442,7 @@ public class EntityAbilityLaser extends EntityEnergyProjectile { endZ = startZ + dirZ * currentLength; } - if (handleBarrierHitOutcome(dome, hitOutcome)) { + if (handleBarrierHitOutcome(dome, hitOutcome, damage)) { return true; } return false; @@ -475,7 +475,7 @@ public class EntityAbilityLaser extends EntityEnergyProjectile { endZ = startZ + dirZ * currentLength; } - if (handleBarrierHitOutcome(barrier, hitOutcome)) { + if (handleBarrierHitOutcome(barrier, hitOutcome, damage)) { return true; } return false; diff --git a/src/main/java/kamkeel/npcs/entity/EntityEnergyProjectile.java b/src/main/java/kamkeel/npcs/entity/EntityEnergyProjectile.java index 8e9a4de1b..6d7c22776 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityEnergyProjectile.java +++ b/src/main/java/kamkeel/npcs/entity/EntityEnergyProjectile.java @@ -395,7 +395,7 @@ public abstract class EntityEnergyProjectile extends EntityEnergyAbility { if (hitOutcome == null || hitOutcome.result == EntityAbilityBarrier.ProjectileHitResult.PASS) { continue; } - if (handleBarrierHitOutcome(barrier, hitOutcome)) { + if (handleBarrierHitOutcome(barrier, hitOutcome, damage)) { return true; } return false; @@ -408,20 +408,29 @@ public abstract class EntityEnergyProjectile extends EntityEnergyAbility { /** * Handle the result of a projectile/barrier interaction. * + * @param fullDamage The DBC-scaled damage that was passed to the barrier (from getModifiedDamage). * @return true if caller should stop processing this tick. */ - protected boolean handleBarrierHitOutcome(EntityAbilityBarrier barrier, EntityAbilityBarrier.ProjectileHitOutcome hitOutcome) { + protected boolean handleBarrierHitOutcome(EntityAbilityBarrier barrier, EntityAbilityBarrier.ProjectileHitOutcome hitOutcome, float fullDamage) { if (hitOutcome == null || hitOutcome.result == EntityAbilityBarrier.ProjectileHitResult.PASS) { return false; } if (hitOutcome.result == EntityAbilityBarrier.ProjectileHitResult.BROKEN) { if (hitOutcome.remainingProjectileDamage <= 0.0f) { + barrierDamageRatio = 0.0f; setBarrierSparkTicks(Math.max(getBarrierSparkTicks(), BARRIER_BREAK_SPARK_TICKS)); hasHit = true; return true; } + // Accumulate barrier pass-through ratio for extender damage scaling. + // fullDamage is the DBC-scaled damage the barrier saw; remainingProjectileDamage + // is what survived. Multiply into the running ratio so multiple barriers stack. + if (fullDamage > 0.0f) { + barrierDamageRatio *= (hitOutcome.remainingProjectileDamage / fullDamage); + } + setCombatDamage(hitOutcome.remainingProjectileDamage); setBarrierSparkTicks(Math.max(getBarrierSparkTicks(), BARRIER_BREAK_SPARK_TICKS)); return false; @@ -524,8 +533,10 @@ public abstract class EntityEnergyProjectile extends EntityEnergyAbility { setOuterColor(barrier.getOuterColor()); float clampedStrength = Math.max(0.0f, Math.min(100.0f, reflectStrengthPct)); - float reducedDamage = getDamage() * (1.0f - clampedStrength / 100.0f); + float reductionFactor = 1.0f - clampedStrength / 100.0f; + float reducedDamage = getDamage() * reductionFactor; setCombatDamage(Math.max(0.0f, reducedDamage)); + barrierDamageRatio *= reductionFactor; hitOnceEntities.clear(); lastHitTickByEntity.clear(); @@ -948,7 +959,7 @@ public abstract class EntityEnergyProjectile extends EntityEnergyAbility { float kbUp = getKnockbackUp() > 0 ? getKnockbackUp() : 0.1f; handled = AbilityController.Instance.fireOnAbilityDamage( sourceAbility, (EntityLivingBase) owner, target, - dmg, kb, kbUp, dx, dz); + dmg, kb, kbUp, dx, dz, barrierDamageRatio); } if (!handled) { @@ -1916,6 +1927,17 @@ public abstract class EntityEnergyProjectile extends EntityEnergyAbility { // ==================== COMBAT GETTERS & SETTERS ==================== + /** + * Proportional damage factor from barrier interactions (0.0-1.0). + * Accumulates multiplicatively when the projectile breaks through barriers or is reflected. + * Used by ability extenders to scale recalculated damage proportionally. + */ + private float barrierDamageRatio = 1.0f; + + public float getBarrierDamageRatio() { + return barrierDamageRatio; + } + public float getDamage() { return combatData.getDamage(); }