diff --git a/src/api b/src/api index 319e77451..10f8cfdea 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 319e77451862a113b156c988a1234b2acbadfb2b +Subproject commit 10f8cfdeaa961f52f3229e07c5fc9aa0fb15e734 diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/data/energy/EnergyBarrierData.java b/src/main/java/kamkeel/npcs/controllers/data/ability/data/energy/EnergyBarrierData.java index bfd48a3b3..40c30fe95 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/data/energy/EnergyBarrierData.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/data/energy/EnergyBarrierData.java @@ -32,6 +32,11 @@ public class EnergyBarrierData { // Absorbing: caster's damage is redirected to the barrier public boolean absorbing = false; + // Absorb radius: max distance from barrier's current position for absorption to work + // -1 = no radius limit (absorb regardless of distance) + // 0 = use barrier's own extent as the radius (dome radius, panel half-size, etc.) + // positive = owner must be within this many blocks of the barrier entity + public float absorbRadius = 0.0f; // Melee: barrier can be hit by melee attacks public boolean meleeEnabled = false; @@ -148,6 +153,14 @@ public class EnergyBarrierData { this.targetOwner = targetOwner; } + public float getAbsorbRadius() { + return absorbRadius; + } + + public void setAbsorbRadius(float absorbRadius) { + this.absorbRadius = absorbRadius; + } + // ==================== NBT ==================== public void writeNBT(NBTTagCompound nbt) { @@ -160,6 +173,7 @@ public class EnergyBarrierData { nbt.setBoolean("barrierKnockback", knockbackEnabled); nbt.setFloat("barrierKnockbackStr", knockbackStrength); nbt.setBoolean("barrierAbsorbing", absorbing); + nbt.setFloat("barrierAbsorbRadius", absorbRadius); nbt.setBoolean("barrierMelee", meleeEnabled); nbt.setFloat("barrierMeleeMult", meleeDamageMultiplier); nbt.setBoolean("barrierReflect", reflect); @@ -183,6 +197,7 @@ public class EnergyBarrierData { knockbackEnabled = nbt.hasKey("barrierKnockback") && nbt.getBoolean("barrierKnockback"); knockbackStrength = nbt.hasKey("barrierKnockbackStr") ? nbt.getFloat("barrierKnockbackStr") : 1.0f; absorbing = nbt.hasKey("barrierAbsorbing") && nbt.getBoolean("barrierAbsorbing"); + absorbRadius = nbt.hasKey("barrierAbsorbRadius") ? nbt.getFloat("barrierAbsorbRadius") : 0.0f; meleeEnabled = nbt.hasKey("barrierMelee") && nbt.getBoolean("barrierMelee"); meleeDamageMultiplier = nbt.hasKey("barrierMeleeMult") ? nbt.getFloat("barrierMeleeMult") : 1.0f; reflect = nbt.hasKey("barrierReflect") && nbt.getBoolean("barrierReflect"); @@ -207,6 +222,7 @@ public class EnergyBarrierData { copy.knockbackEnabled = knockbackEnabled; copy.knockbackStrength = knockbackStrength; copy.absorbing = absorbing; + copy.absorbRadius = absorbRadius; copy.meleeEnabled = meleeEnabled; copy.meleeDamageMultiplier = meleeDamageMultiplier; copy.reflect = reflect; diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityBarrier.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityBarrier.java index 5d12b4c11..1e3df2e02 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityBarrier.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityBarrier.java @@ -292,6 +292,14 @@ public abstract class AbilityBarrier extends AbilityEnergy { barrierData.absorbing = absorbing; } + public float getAbsorbRadius() { + return barrierData.absorbRadius; + } + + public void setAbsorbRadius(float radius) { + barrierData.absorbRadius = radius; + } + // Reflection data public boolean isReflect() { return barrierData.reflect; @@ -395,6 +403,9 @@ public abstract class AbilityBarrier extends AbilityEnergy { .range(0, 10).visibleWhen(this::isKnockbackEnabled)); defs.add(FieldDef.boolField("ability.absorbing", this::isAbsorbing, this::setAbsorbing) .hover("ability.hover.absorbing")); + defs.add(FieldDef.floatField("ability.absorbRadius", this::getAbsorbRadius, this::setAbsorbRadius) + .range(-1, 128).visibleWhen(this::isAbsorbing) + .hover("ability.hover.absorbRadius")); defs.add(FieldDef.boolField("ability.reflect", this::isReflect, this::setReflect) .hover("ability.hover.reflect")); defs.add(FieldDef.floatField("ability.reflectStrength", this::getReflectStrengthPct, this::setReflectStrengthPct) diff --git a/src/main/java/kamkeel/npcs/entity/EntityEnergyBarrier.java b/src/main/java/kamkeel/npcs/entity/EntityEnergyBarrier.java index 872b7acb3..9683c2894 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityEnergyBarrier.java +++ b/src/main/java/kamkeel/npcs/entity/EntityEnergyBarrier.java @@ -630,7 +630,13 @@ public abstract class EntityEnergyBarrier extends EntityEnergyAbility { /** * Find a barrier that would absorb damage for the given entity (its caster). - * Returns the barrier if: absorbing is enabled AND entity is the barrier's owner. + * Returns the barrier if: absorbing is enabled, entity is the barrier's owner, + * and entity is within the barrier's absorb radius of the barrier's current position. + * + * Absorb radius behavior: + * -1 = no limit (absorb regardless of distance) + * 0 = uses the barrier's extent as the radius (dome radius, panel half-size, etc.) + * >0 = owner must be within this many blocks of the barrier entity */ public static EntityEnergyBarrier getAbsorbingBarrier(Entity entity) { if (entity == null || entity.worldObj == null) return null; @@ -638,7 +644,33 @@ public abstract class EntityEnergyBarrier extends EntityEnergyAbility { for (EntityEnergyBarrier barrier : barriers) { if (barrier.isDead) continue; if (!barrier.barrierData.absorbing) continue; - if (barrier.ownerEntityId == entity.getEntityId()) { + if (barrier.ownerEntityId != entity.getEntityId()) continue; + + float absorbRadius = barrier.barrierData.absorbRadius; + + // -1 = unlimited range + if (absorbRadius < 0) { + return barrier; + } + + // 0 = use barrier's own extent as the effective radius + // Domes: dome radius. Panels: max(width, height) * 0.5 + 1.0, doubled. + float effectiveRadius; + if (absorbRadius > 0) { + effectiveRadius = absorbRadius; + } else if (barrier instanceof EntityEnergyDome) { + effectiveRadius = barrier.getMaxExtent(); + } else { + effectiveRadius = barrier.getMaxExtent() * 3.0f; + } + + // Distance check from barrier's current position to the owner + double dx = entity.posX - barrier.posX; + double dy = (entity.posY + entity.height * 0.5) - barrier.posY; + double dz = entity.posZ - barrier.posZ; + double distSq = dx * dx + dy * dy + dz * dz; + + if (distSq <= (double) effectiveRadius * effectiveRadius) { return barrier; } } diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptEnergyBarrier.java b/src/main/java/noppes/npcs/scripted/entity/ScriptEnergyBarrier.java index f18b86320..16d96ddc1 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptEnergyBarrier.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptEnergyBarrier.java @@ -121,6 +121,14 @@ public class ScriptEnergyBarrier extends ScriptEn entity.getBarrierData().absorbing = absorbing; } + public float getAbsorbRadius() { + return entity.getBarrierData().absorbRadius; + } + + public void setAbsorbRadius(float radius) { + entity.getBarrierData().absorbRadius = radius; + } + public boolean isReflect() { return entity.getBarrierData().reflect; } diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index 913a3a257..f375c56c2 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -2165,6 +2165,7 @@ ability.solid=Solid ability.knockbackEnabled=Knockback ability.knockbackStrength=Knockback Strength ability.absorbing=Absorbing +ability.absorbRadius=Absorb Radius ability.reflect=Reflect ability.reflectStrength=Strength (%) ability.meleeEnabled=Allows Melee @@ -2175,6 +2176,7 @@ ability.hover.followCaster=Dome stays centered on the caster as they move ability.hover.solid=Entities cannot pass through the barrier boundary ability.hover.knockbackEnabled=Repulsion field pushing entities away from barrier surface ability.hover.absorbing=Damage dealt to the caster is redirected to the barrier's health +ability.hover.absorbRadius=Max distance from the barrier for absorption to work. -1 = unlimited, 0 = barrier extent (dome radius or panel size x3), positive = block radius ability.hover.reflect=Rebounds non-breaking projectiles and reduces their damage by Strength ability.targetOwner=Target Owner ability.hover.targetOwner=Sets the reflected projectile's target to the original caster. With homing enabled, the projectile will home toward its former caster.