From a18503dfe97698478a2aab66e2b76ad5b4106ad8 Mon Sep 17 00:00:00 2001 From: Kam Date: Sat, 21 Feb 2026 01:09:39 -0500 Subject: [PATCH] Fix Domes --- .../data/ability/data/EnergyBarrierData.java | 63 ++++++------------- .../data/ability/type/energy/AbilityDome.java | 9 --- .../type/energy/AbilityEnergyBarrier.java | 61 ++++++------------ .../npcs/entity/EntityEnergyBarrier.java | 52 ++++++--------- .../java/noppes/npcs/ServerEventsHandler.java | 8 +-- .../scripted/entity/ScriptEnergyBarrier.java | 16 +++-- .../assets/customnpcs/lang/en_US.lang | 15 ++--- 7 files changed, 80 insertions(+), 144 deletions(-) diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyBarrierData.java b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyBarrierData.java index 6f3610376..d54f205cc 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyBarrierData.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyBarrierData.java @@ -8,10 +8,14 @@ import java.util.Map; /** * Groups barrier properties shared by energy barrier abilities (Dome, Wall, Shield). * Handles health/durability, duration, and per-projectile-type damage multipliers. + * + * Properties: + * - Solid: Hard wall — entities cannot pass through the barrier boundary (either direction) + * - Knockback: Repulsion field — entities near the surface get pushed away + * - Absorbing: Caster's incoming damage is redirected to the barrier + * - Allows Melee: Barrier can be hit by melee attacks (punching) */ public class EnergyBarrierData { - // Knockback target display keys - private static final String[] KNOCKBACK_TARGET_KEYS = {"gui.both", "gui.players", "gui.npcs"}; public float maxHealth = 100.0f; public boolean useHealth = true; @@ -19,23 +23,20 @@ public class EnergyBarrierData { public boolean useDuration = true; public float defaultMultiplier = 1.0f; - // Knockback settings + // Solid: entities cannot pass through the barrier boundary + public boolean solid = false; + + // Knockback: repulsion field pushing entities away from surface public boolean knockbackEnabled = false; public float knockbackStrength = 1.0f; - /** - * 0=Both, 1=Player only, 2=NPC only - */ - public int knockbackTarget = 0; - // Melee settings + // Absorbing: caster's damage is redirected to the barrier + public boolean absorbing = false; + + // Melee: barrier can be hit by melee attacks public boolean meleeEnabled = false; public float meleeDamageMultiplier = 1.0f; - // Jail settings (dome only - captures entities inside at spawn) - public boolean jailEnabled = false; - public boolean damageProtection = false; - public float jailThreshold = 0.9f; - /** * Per-projectile-type damage multipliers. * Key is the ability typeId (e.g., "ability.cnpc.orb", "ability.cnpc.beam"). @@ -118,24 +119,6 @@ public class EnergyBarrierData { this.defaultMultiplier = defaultMultiplier; } - // Knockback target key helpers - public static String[] getKnockbackTargetKeys() { - return KNOCKBACK_TARGET_KEYS; - } - - public String getKnockbackTargetKey() { - return KNOCKBACK_TARGET_KEYS[Math.max(0, Math.min(knockbackTarget, 2))]; - } - - public void setKnockbackTargetFromKey(String key) { - for (int i = 0; i < KNOCKBACK_TARGET_KEYS.length; i++) { - if (KNOCKBACK_TARGET_KEYS[i].equals(key)) { - knockbackTarget = i; - return; - } - } - } - // ==================== NBT ==================== public void writeNBT(NBTTagCompound nbt) { @@ -144,14 +127,12 @@ public class EnergyBarrierData { nbt.setInteger("barrierDuration", durationTicks); nbt.setBoolean("barrierUseDuration", useDuration); nbt.setFloat("barrierDefaultMult", defaultMultiplier); + nbt.setBoolean("barrierSolid", solid); nbt.setBoolean("barrierKnockback", knockbackEnabled); nbt.setFloat("barrierKnockbackStr", knockbackStrength); - nbt.setInteger("barrierKnockbackTarget", knockbackTarget); + nbt.setBoolean("barrierAbsorbing", absorbing); nbt.setBoolean("barrierMelee", meleeEnabled); nbt.setFloat("barrierMeleeMult", meleeDamageMultiplier); - nbt.setBoolean("barrierJail", jailEnabled); - nbt.setBoolean("barrierDmgProtect", damageProtection); - nbt.setFloat("barrierJailThreshold", jailThreshold); NBTTagCompound multNbt = new NBTTagCompound(); for (Map.Entry entry : damageMultipliers.entrySet()) { @@ -166,14 +147,12 @@ public class EnergyBarrierData { durationTicks = nbt.hasKey("barrierDuration") ? nbt.getInteger("barrierDuration") : 200; useDuration = !nbt.hasKey("barrierUseDuration") || nbt.getBoolean("barrierUseDuration"); defaultMultiplier = nbt.hasKey("barrierDefaultMult") ? nbt.getFloat("barrierDefaultMult") : 1.0f; + solid = nbt.hasKey("barrierSolid") && nbt.getBoolean("barrierSolid"); knockbackEnabled = nbt.hasKey("barrierKnockback") && nbt.getBoolean("barrierKnockback"); knockbackStrength = nbt.hasKey("barrierKnockbackStr") ? nbt.getFloat("barrierKnockbackStr") : 1.0f; - knockbackTarget = nbt.hasKey("barrierKnockbackTarget") ? nbt.getInteger("barrierKnockbackTarget") : 0; + absorbing = nbt.hasKey("barrierAbsorbing") && nbt.getBoolean("barrierAbsorbing"); meleeEnabled = nbt.hasKey("barrierMelee") && nbt.getBoolean("barrierMelee"); meleeDamageMultiplier = nbt.hasKey("barrierMeleeMult") ? nbt.getFloat("barrierMeleeMult") : 1.0f; - jailEnabled = nbt.hasKey("barrierJail") && nbt.getBoolean("barrierJail"); - damageProtection = nbt.hasKey("barrierDmgProtect") && nbt.getBoolean("barrierDmgProtect"); - jailThreshold = nbt.hasKey("barrierJailThreshold") ? nbt.getFloat("barrierJailThreshold") : 0.9f; damageMultipliers.clear(); if (nbt.hasKey("barrierMultipliers")) { @@ -189,14 +168,12 @@ public class EnergyBarrierData { public EnergyBarrierData copy() { EnergyBarrierData copy = new EnergyBarrierData(maxHealth, useHealth, durationTicks, useDuration); copy.defaultMultiplier = defaultMultiplier; + copy.solid = solid; copy.knockbackEnabled = knockbackEnabled; copy.knockbackStrength = knockbackStrength; - copy.knockbackTarget = knockbackTarget; + copy.absorbing = absorbing; copy.meleeEnabled = meleeEnabled; copy.meleeDamageMultiplier = meleeDamageMultiplier; - copy.jailEnabled = jailEnabled; - copy.damageProtection = damageProtection; - copy.jailThreshold = jailThreshold; copy.damageMultipliers = new HashMap<>(damageMultipliers); return copy; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityDome.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityDome.java index cdb8f6f2f..78a317cc2 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityDome.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityDome.java @@ -135,14 +135,5 @@ public class AbilityDome extends AbilityEnergyBarrier { .range(1.0f, 50.0f)); defs.add(FieldDef.boolField("ability.followCaster", this::isFollowCaster, this::setFollowCaster) .hover("ability.hover.followCaster")); - - // Jail & protection section (dome-only: only enclosures can jail) - defs.add(FieldDef.section("ability.section.jail")); - defs.add(FieldDef.boolField("ability.jailEnabled", this::isJailEnabled, this::setJailEnabled) - .hover("ability.hover.jailEnabled")); - defs.add(FieldDef.floatField("ability.jailThreshold", this::getJailThreshold, this::setJailThreshold) - .range(0.1f, 1.0f).visibleWhen(this::isJailEnabled)); - defs.add(FieldDef.boolField("ability.damageProtection", this::isDamageProtection, this::setDamageProtection) - .hover("ability.hover.damageProtection")); } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityEnergyBarrier.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityEnergyBarrier.java index d3b543885..73f34d059 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityEnergyBarrier.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilityEnergyBarrier.java @@ -190,6 +190,15 @@ public abstract class AbilityEnergyBarrier extends AbilityEnergy { return barrierData.getMultiplier(typeId); } + // Solid data + public boolean isSolid() { + return barrierData.solid; + } + + public void setSolid(boolean solid) { + barrierData.solid = solid; + } + // Knockback data public boolean isKnockbackEnabled() { return barrierData.knockbackEnabled; @@ -207,12 +216,13 @@ public abstract class AbilityEnergyBarrier extends AbilityEnergy { barrierData.knockbackStrength = strength; } - public String getKnockbackTargetKey() { - return barrierData.getKnockbackTargetKey(); + // Absorbing data + public boolean isAbsorbing() { + return barrierData.absorbing; } - public void setKnockbackTargetKey(String key) { - barrierData.setKnockbackTargetFromKey(key); + public void setAbsorbing(boolean absorbing) { + barrierData.absorbing = absorbing; } // Melee data @@ -232,31 +242,6 @@ public abstract class AbilityEnergyBarrier extends AbilityEnergy { barrierData.meleeDamageMultiplier = mult; } - // Jail data - public boolean isJailEnabled() { - return barrierData.jailEnabled; - } - - public void setJailEnabled(boolean enabled) { - barrierData.jailEnabled = enabled; - } - - public boolean isDamageProtection() { - return barrierData.damageProtection; - } - - public void setDamageProtection(boolean enabled) { - barrierData.damageProtection = enabled; - } - - public float getJailThreshold() { - return barrierData.jailThreshold; - } - - public void setJailThreshold(float threshold) { - barrierData.jailThreshold = Math.max(0.1f, Math.min(1.0f, threshold)); - } - // ==================== GUI ==================== @SideOnly(Side.CLIENT) @@ -275,19 +260,13 @@ public abstract class AbilityEnergyBarrier extends AbilityEnergy { .range(1, 12000).visibleWhen(this::isUseDuration)); defs.add(FieldDef.floatField("ability.defaultMultiplier", this::getDefaultMultiplier, this::setDefaultMultiplier)); - // Knockback section - defs.add(FieldDef.section("ability.section.knockback")); + // Properties section + defs.add(FieldDef.section("ability.section.properties")); + defs.add(FieldDef.boolField("ability.solid", this::isSolid, this::setSolid)); defs.add(FieldDef.boolField("ability.knockbackEnabled", this::isKnockbackEnabled, this::setKnockbackEnabled)); - defs.add(FieldDef.row( - FieldDef.floatField("ability.knockbackStrength", this::getKnockbackStrength, this::setKnockbackStrength) - .range(0, 10).visibleWhen(this::isKnockbackEnabled), - FieldDef.stringEnumField("ability.knockbackTarget", EnergyBarrierData.getKnockbackTargetKeys(), - this::getKnockbackTargetKey, this::setKnockbackTargetKey) - .visibleWhen(this::isKnockbackEnabled) - )); - - // Melee section - defs.add(FieldDef.section("ability.section.melee")); + defs.add(FieldDef.floatField("ability.knockbackStrength", this::getKnockbackStrength, this::setKnockbackStrength) + .range(0, 10).visibleWhen(this::isKnockbackEnabled)); + defs.add(FieldDef.boolField("ability.absorbing", this::isAbsorbing, this::setAbsorbing)); defs.add(FieldDef.boolField("ability.meleeEnabled", this::isMeleeEnabled, this::setMeleeEnabled)); defs.add(FieldDef.floatField("ability.meleeDamageMultiplier", this::getMeleeDamageMultiplier, this::setMeleeDamageMultiplier) .range(0, 10).visibleWhen(this::isMeleeEnabled)); diff --git a/src/main/java/kamkeel/npcs/entity/EntityEnergyBarrier.java b/src/main/java/kamkeel/npcs/entity/EntityEnergyBarrier.java index 1027fe93e..2db51fd14 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityEnergyBarrier.java +++ b/src/main/java/kamkeel/npcs/entity/EntityEnergyBarrier.java @@ -4,7 +4,6 @@ import kamkeel.npcs.controllers.data.ability.AbilityTargetHelper; import kamkeel.npcs.controllers.data.ability.data.EnergyBarrierData; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; @@ -94,9 +93,10 @@ public abstract class EntityEnergyBarrier extends EntityEnergyAbility { public abstract void finishCharging(); /** - * Push entities away from the barrier surface. + * Process entity physics for this barrier. + * Handles solid wall (entity repositioning) and knockback (repulsion force). */ - protected abstract void knockbackEntities(); + protected abstract void processEntityPhysics(); /** * Get the maximum extent of this barrier for distance pre-filtering. @@ -203,6 +203,16 @@ public abstract class EntityEnergyBarrier extends EntityEnergyAbility { return barrierData.meleeEnabled; } + @Override + public boolean isEntityInsideOpaqueBlock() { + return false; + } + + @Override + protected boolean func_145771_j(double x, double y, double z) { + return false; + } + @Override public boolean attackEntityFrom(DamageSource source, float amount) { if (worldObj.isRemote || !barrierData.meleeEnabled) return false; @@ -324,20 +334,9 @@ public abstract class EntityEnergyBarrier extends EntityEnergyAbility { return this.dataWatcher.getWatchableObjectFloat(DW_HEALTH_PERCENT); } - protected boolean isKnockbackTarget(EntityLivingBase entity) { - switch (barrierData.knockbackTarget) { - case 1: - return entity instanceof EntityPlayer; - case 2: - return entity instanceof EntityNPCInterface; - default: - return entity instanceof EntityPlayer || entity instanceof EntityNPCInterface; - } - } - /** * Check if an entity is an ally of this barrier's owner. - * Allies should not be knocked back by barriers. + * Allies are not affected by barrier physics. */ protected boolean isAllyOfOwner(EntityLivingBase entity) { Entity owner = getOwnerEntity(); @@ -345,7 +344,7 @@ public abstract class EntityEnergyBarrier extends EntityEnergyAbility { return AbilityTargetHelper.isAlly((EntityLivingBase) owner, entity); } - // ==================== CONTAINMENT & PROTECTION ==================== + // ==================== CONTAINMENT & ABSORBING ==================== /** * Check if an entity is geometrically inside this barrier's protected zone. @@ -356,27 +355,16 @@ public abstract class EntityEnergyBarrier extends EntityEnergyAbility { } /** - * Check if a damage source originates from outside this barrier. - * Uses geometry-specific containment check via isEntityInside(). + * 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. */ - public boolean isDamageFromOutside(DamageSource source) { - Entity attacker = source.getEntity(); - if (attacker == null) return true; // Environmental damage treated as outside - return !isEntityInside(attacker); - } - - /** - * Find a barrier that would protect the given entity from outside damage. - * Returns the barrier if: damageProtection is enabled AND entity is inside. - * Any entity inside a dome with damageProtection gets redirected damage. - */ - public static EntityEnergyBarrier getProtectingBarrier(Entity entity) { + public static EntityEnergyBarrier getAbsorbingBarrier(Entity entity) { if (entity == null || entity.worldObj == null) return null; List barriers = getActiveBarriers(entity.worldObj); for (EntityEnergyBarrier barrier : barriers) { if (barrier.isDead) continue; - if (!barrier.barrierData.damageProtection) continue; - if (barrier.isEntityInside(entity)) { + if (!barrier.barrierData.absorbing) continue; + if (barrier.ownerEntityId == entity.getEntityId()) { return barrier; } } diff --git a/src/main/java/noppes/npcs/ServerEventsHandler.java b/src/main/java/noppes/npcs/ServerEventsHandler.java index fb2ea3d13..a13384ada 100644 --- a/src/main/java/noppes/npcs/ServerEventsHandler.java +++ b/src/main/java/noppes/npcs/ServerEventsHandler.java @@ -153,13 +153,13 @@ public class ServerEventsHandler { } @SubscribeEvent - public void barrierDamageProtection(LivingAttackEvent event) { + public void barrierAbsorbDamage(LivingAttackEvent event) { if (event.entityLiving == null || event.entityLiving.worldObj == null || event.entityLiving.worldObj.isRemote) return; - EntityEnergyBarrier barrier = EntityEnergyBarrier.getProtectingBarrier(event.entityLiving); - if (barrier != null && barrier.isDamageFromOutside(event.source)) { - // Redirect the damage to the barrier instead of preventing it + EntityEnergyBarrier barrier = EntityEnergyBarrier.getAbsorbingBarrier(event.entityLiving); + if (barrier != null) { + // Redirect the caster's damage to their barrier barrier.absorbDamage(event.ammount); event.setCanceled(true); } diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptEnergyBarrier.java b/src/main/java/noppes/npcs/scripted/entity/ScriptEnergyBarrier.java index 29f330ff7..6669bde50 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptEnergyBarrier.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptEnergyBarrier.java @@ -89,6 +89,14 @@ public class ScriptEnergyBarrier extends ScriptEn entity.getBarrierData().defaultMultiplier = multiplier; } + public boolean isSolid() { + return entity.getBarrierData().solid; + } + + public void setSolid(boolean solid) { + entity.getBarrierData().solid = solid; + } + public boolean isKnockbackEnabled() { return entity.getBarrierData().knockbackEnabled; } @@ -105,12 +113,12 @@ public class ScriptEnergyBarrier extends ScriptEn entity.getBarrierData().knockbackStrength = strength; } - public int getKnockbackTarget() { - return entity.getBarrierData().knockbackTarget; + public boolean isAbsorbing() { + return entity.getBarrierData().absorbing; } - public void setKnockbackTarget(int target) { - entity.getBarrierData().knockbackTarget = target; + public void setAbsorbing(boolean absorbing) { + entity.getBarrierData().absorbing = absorbing; } public int getBarrierType() { diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index c6d745706..c0ae3f376 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -2019,7 +2019,7 @@ ability.cnpc.shield=Shield ability.cnpc.slicer=Slicer ability.section.barrier=Barrier -ability.section.knockback=Knockback +ability.section.properties=Properties ability.section.panel=Panel ability.section.launch=Launch ability.section.slicer=Slicer @@ -2032,23 +2032,16 @@ ability.defaultMultiplier=Default Multiplier ability.innerAlpha=Inner Alpha ability.heightOffset=Height Offset +ability.solid=Solid ability.knockbackEnabled=Knockback ability.knockbackStrength=Knockback Strength -ability.knockbackTarget=Target - -ability.section.melee=Melee -ability.meleeEnabled=Melee Attackable +ability.absorbing=Absorbing +ability.meleeEnabled=Allows Melee ability.meleeDamageMultiplier=Melee Multiplier ability.followCaster=Follow Caster ability.hover.followCaster=Dome stays centered on the caster as they move -ability.section.jail=Jail & Protection -ability.jailEnabled=Jail Mode -ability.hover.jailEnabled=Entities inside stay inside, entities outside stay outside -ability.jailThreshold=Jail Threshold -ability.damageProtection=Damage Protection -ability.hover.damageProtection=Outside attacks on entities inside are redirected to the dome ability.variant.small=Small ability.variant.large=Large