From bc4f82e55fbd36e10d8b4e52ad1d9fa83f651cba Mon Sep 17 00:00:00 2001 From: Vidal Date: Tue, 3 Feb 2026 17:20:36 -0300 Subject: [PATCH] Added API classes to Energy Projectile --- src/api | 2 +- .../data/ability/data/EnergyAnchorData.java | 12 +- .../data/ability/data/EnergyHomingData.java | 83 +++++ .../ability/data/EnergyTrajectoryData.java | 90 ++--- .../data/ability/type/AbilityBeam.java | 2 +- .../data/ability/type/AbilityBeamDual.java | 6 +- .../data/ability/type/AbilityDisc.java | 2 +- .../data/ability/type/AbilityDiscDual.java | 6 +- .../data/ability/type/AbilityLaserShot.java | 2 + .../data/ability/type/AbilityOrb.java | 2 +- .../data/ability/type/AbilityOrbBarrage.java | 2 +- .../data/ability/type/AbilityOrbDual.java | 6 +- .../npcs/entity/EntityAbilityBeam.java | 146 +++----- .../npcs/entity/EntityAbilityDisc.java | 166 +++------ .../npcs/entity/EntityAbilityLaser.java | 29 +- .../kamkeel/npcs/entity/EntityAbilityOrb.java | 140 ++------ .../npcs/entity/EntityAbilityProjectile.java | 339 +++++++++++------- .../npcs/entity/EntityAbilitySweeper.java | 10 +- .../java/noppes/npcs/items/ItemStaff.java | 2 +- 19 files changed, 506 insertions(+), 541 deletions(-) create mode 100644 src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyHomingData.java diff --git a/src/api b/src/api index 5fd3b7cb4..96b8d8a43 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 5fd3b7cb4044f1037fe2aae99868513dea347bda +Subproject commit 96b8d8a43cd7441f988f486dcc791c5f06771d8b diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyAnchorData.java b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyAnchorData.java index e6c36fe48..2187802a5 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyAnchorData.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyAnchorData.java @@ -35,16 +35,24 @@ public class EnergyAnchorData implements IEnergyAnchorData { this.anchorOffsetZ = anchorOffsetZ; } - @Override public AnchorPoint getAnchorPoint() { return anchorPoint; } - @Override public void setAnchorPoint(AnchorPoint anchorPoint) { this.anchorPoint = anchorPoint; } + @Override + public int getAnchor() { + return anchorPoint.ordinal(); + } + + @Override + public void setAnchor(int anchor) { + this.anchorPoint = AnchorPoint.fromOrdinal(anchor); + } + @Override public float getAnchorOffsetX() { return anchorOffsetX; diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyHomingData.java b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyHomingData.java new file mode 100644 index 000000000..1e81882c7 --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyHomingData.java @@ -0,0 +1,83 @@ +package kamkeel.npcs.controllers.data.ability.data; + +import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.api.ability.data.IEnergyHomingData; + + +/** + * Groups homing/movement properties for energy projectile abilities. + * Used by Orb, Disc, and Beam (not Laser or Sweeper). + */ +public class EnergyHomingData implements IEnergyHomingData { + public float speed = 0.5f; + public boolean homing = true; + public float homingStrength = 0.15f; + public float homingRange = 20.0f; + + public EnergyHomingData() {} + + public EnergyHomingData(float speed, boolean homing, float homingStrength, float homingRange) { + this.speed = speed; + this.homing = homing; + this.homingStrength = homingStrength; + this.homingRange = homingRange; + } + + @Override + public float getSpeed() { + return speed; + } + + @Override + public void setSpeed(float speed) { + this.speed = speed; + } + + @Override + public boolean isHoming() { + return homing; + } + + @Override + public void setHoming(boolean homing) { + this.homing = homing; + } + + @Override + public float getHomingStrength() { + return homingStrength; + } + + @Override + public void setHomingStrength(float homingStrength) { + this.homingStrength = homingStrength; + } + + @Override + public float getHomingRange() { + return homingRange; + } + + @Override + public void setHomingRange(float homingRange) { + this.homingRange = homingRange; + } + + public void writeNBT(NBTTagCompound nbt) { + nbt.setFloat("speed", speed); + nbt.setBoolean("homing", homing); + nbt.setFloat("homingStrength", homingStrength); + nbt.setFloat("homingRange", homingRange); + } + + public void readNBT(NBTTagCompound nbt) { + speed = nbt.hasKey("speed") ? nbt.getFloat("speed") : 0.5f; + homing = !nbt.hasKey("homing") || nbt.getBoolean("homing"); + homingStrength = nbt.hasKey("homingStrength") ? nbt.getFloat("homingStrength") : 0.15f; + homingRange = nbt.hasKey("homingRange") ? nbt.getFloat("homingRange") : 20.0f; + } + + public EnergyHomingData copy() { + return new EnergyHomingData(speed, homing, homingStrength, homingRange); + } +} diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyTrajectoryData.java b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyTrajectoryData.java index 11b5ef50c..77d8cda00 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyTrajectoryData.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyTrajectoryData.java @@ -1,82 +1,48 @@ package kamkeel.npcs.controllers.data.ability.data; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.Vec3; import noppes.npcs.api.ability.data.IEnergyTrajectoryData; -/** - * Groups homing/movement properties for energy projectile abilities. - * Used by Orb, Disc, and Beam (not Laser or Sweeper). - */ +import java.util.ArrayList; +import java.util.List; + public class EnergyTrajectoryData implements IEnergyTrajectoryData { public float speed = 0.5f; - public boolean homing = true; - public float homingStrength = 0.15f; - public float homingRange = 20.0f; + public int currentPath = 0; + private List trajectory = new ArrayList<>(); - public EnergyTrajectoryData() {} - - public EnergyTrajectoryData(float speed, boolean homing, float homingStrength, float homingRange) { - this.speed = speed; - this.homing = homing; - this.homingStrength = homingStrength; - this.homingRange = homingRange; + public int getDelay(int path) { + if (path < 0 || path >= trajectory.size()) return -1; + return trajectory.get(path).delayTicks; } - @Override - public float getSpeed() { - return speed; + public Vec3 getVec(int path) { + if (path < 0 || path >= trajectory.size()) return null; + return trajectory.get(path).coords; } - @Override - public void setSpeed(float speed) { - this.speed = speed; + public double getX(int path) { + if (getVec(path) == null) return 0; + return getVec(path).xCoord; } - @Override - public boolean isHoming() { - return homing; + public double getY(int path) { + if (getVec(path) == null) return 0; + return getVec(path).yCoord; } - @Override - public void setHoming(boolean homing) { - this.homing = homing; + public double getZ(int path) { + if (getVec(path) == null) return 0; + return getVec(path).zCoord; } - @Override - public float getHomingStrength() { - return homingStrength; - } + public static class Path { + public Vec3 coords; + public int delayTicks; - @Override - public void setHomingStrength(float homingStrength) { - this.homingStrength = homingStrength; - } - - @Override - public float getHomingRange() { - return homingRange; - } - - @Override - public void setHomingRange(float homingRange) { - this.homingRange = homingRange; - } - - public void writeNBT(NBTTagCompound nbt) { - nbt.setFloat("speed", speed); - nbt.setBoolean("homing", homing); - nbt.setFloat("homingStrength", homingStrength); - nbt.setFloat("homingRange", homingRange); - } - - public void readNBT(NBTTagCompound nbt) { - speed = nbt.hasKey("speed") ? nbt.getFloat("speed") : 0.5f; - homing = !nbt.hasKey("homing") || nbt.getBoolean("homing"); - homingStrength = nbt.hasKey("homingStrength") ? nbt.getFloat("homingStrength") : 0.15f; - homingRange = nbt.hasKey("homingRange") ? nbt.getFloat("homingRange") : 20.0f; - } - - public EnergyTrajectoryData copy() { - return new EnergyTrajectoryData(speed, homing, homingStrength, homingRange); + public Path(Vec3 coords, int delayTicks) { + this.coords = coords; + this.delayTicks = delayTicks; + } } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeam.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeam.java index 568d57baf..211a76230 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeam.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeam.java @@ -39,7 +39,7 @@ public class AbilityBeam extends Ability implements IAbilityEnergyBeam { // Data classes private EnergyDisplayData colorData = new EnergyDisplayData(0xFFFFFF, 0x00AAFF, true, 0.4f, 0.5f, 6.0f); private EnergyCombatData combatData = new EnergyCombatData(10.0f, 1.5f, 0.2f, false, 4.0f, 0.5f); - private EnergyTrajectoryData homingData = new EnergyTrajectoryData(0.4f, true, 0.1f, 15.0f); + private EnergyHomingData homingData = new EnergyHomingData(0.4f, true, 0.1f, 15.0f); private EnergyLightningData lightningData = new EnergyLightningData(); private EnergyLifespanData lifespanData = new EnergyLifespanData(25.0f, 200); private EnergyAnchorData anchorData = new EnergyAnchorData(AnchorPoint.RIGHT_HAND); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeamDual.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeamDual.java index 13db46d24..fb7478da1 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeamDual.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityBeamDual.java @@ -37,7 +37,7 @@ public class AbilityBeamDual extends Ability { new EnergyDisplayData(0xFFFFFF, 0xFF0000, true, 0.4f, 0.5f, 6.0f), }; private EnergyCombatData combatData = new EnergyCombatData(10.0f, 1.5f, 0.2f, false, 4.0f, 0.5f); - private EnergyTrajectoryData homingData = new EnergyTrajectoryData(0.4f, true, 0.1f, 15.0f); + private EnergyHomingData homingData = new EnergyHomingData(0.4f, true, 0.1f, 15.0f); private EnergyLightningData[] lightningData = new EnergyLightningData[]{ new EnergyLightningData(), new EnergyLightningData() }; @@ -125,8 +125,8 @@ public class AbilityBeamDual extends Ability { colorData[1], combatData, homingData, lightningData[1], lifespanData, lockMovement.locksActive()); - beamEntity.setSiblingUUID(beamEntity2.getPersistentID()); - beamEntity2.setSiblingUUID(beamEntity.getPersistentID()); + beamEntity.setSiblingEntityId(beamEntity2.getEntityId()); + beamEntity2.setSiblingEntityId(beamEntity.getEntityId()); beamEntity.setupCharging(anchorData[0], windUpTicks, offsetDist); beamEntity2.setupCharging(anchorData[1], windUpTicks, offsetDist); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java index 0a713ba2b..4746b6ccd 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java @@ -42,7 +42,7 @@ public class AbilityDisc extends Ability implements IAbilityDisc { // Energy data classes private EnergyDisplayData colorData = new EnergyDisplayData(0xFFFFFF, 0xFF8800, true, 0.4f, 0.5f, 5.0f); private EnergyCombatData combatData = new EnergyCombatData(8.0f, 1.2f, 0.15f, false, 3.0f, 0.5f); - private EnergyTrajectoryData homingData = new EnergyTrajectoryData(0.6f, true, 0.12f, 18.0f); + private EnergyHomingData homingData = new EnergyHomingData(0.6f, true, 0.12f, 18.0f); private EnergyLightningData lightningData = new EnergyLightningData(); private EnergyLifespanData lifespanData = new EnergyLifespanData(35.0f, 200); private EnergyAnchorData anchorData = new EnergyAnchorData(AnchorPoint.RIGHT_HAND); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDiscDual.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDiscDual.java index f3e80f564..33009f982 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDiscDual.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDiscDual.java @@ -45,7 +45,7 @@ public class AbilityDiscDual extends Ability { new EnergyDisplayData(0xFFFFFF, 0x8800FF, true, 0.4f, 0.5f, 5.0f) }; private EnergyCombatData combatData = new EnergyCombatData(8.0f, 1.2f, 0.15f, false, 3.0f, 0.5f); - private EnergyTrajectoryData homingData = new EnergyTrajectoryData(0.6f, true, 0.12f, 18.0f); + private EnergyHomingData homingData = new EnergyHomingData(0.6f, true, 0.12f, 18.0f); public final EnergyLightningData[] lightningData = new EnergyLightningData[]{ new EnergyLightningData(), new EnergyLightningData() }; @@ -131,8 +131,8 @@ public class AbilityDiscDual extends Ability { colorData[1], combatData, homingData, lightningData[1], lifespanData, boomerang, boomerangDelay); - discEntity.setSiblingUUID(discEntity2.getPersistentID()); - discEntity2.setSiblingUUID(discEntity.getPersistentID()); + discEntity.setSiblingEntityId(discEntity2.getEntityId()); + discEntity2.setSiblingEntityId(discEntity.getEntityId()); discEntity.setupCharging(anchorData[0], windUpTicks); discEntity2.setupCharging(anchorData[1], windUpTicks); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java index 0d8120c63..223eb2e10 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java @@ -271,6 +271,8 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot { AbilityFieldDefs.effectsListField("ability.effects", this::getEffects, this::setEffects), // Visual tab + FieldDef.enumField("ability.anchorPoint", AnchorPoint.class, this::getAnchorPointEnum, this::setAnchorPointEnum) + .tab("ability.tab.visual"), FieldDef.section("ability.section.colors").tab("ability.tab.visual"), FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor).tab("ability.tab.visual"), FieldDef.boolField("ability.outerEnabled", this::isOuterColorEnabled, this::setOuterColorEnabled).tab("ability.tab.visual"), diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java index 86202039c..db267fe59 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java @@ -38,7 +38,7 @@ public class AbilityOrb extends Ability implements IAbilityOrb { // Data classes for energy properties private final EnergyDisplayData colorData = new EnergyDisplayData(); private final EnergyCombatData combatData = new EnergyCombatData(); - private final EnergyTrajectoryData homingData = new EnergyTrajectoryData(); + private final EnergyHomingData homingData = new EnergyHomingData(); private final EnergyLightningData lightningData = new EnergyLightningData(); private final EnergyLifespanData lifespanData = new EnergyLifespanData(); private final EnergyAnchorData anchorData = new EnergyAnchorData(AnchorPoint.RIGHT_HAND); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrbBarrage.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrbBarrage.java index 1888a69c5..ca898b44b 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrbBarrage.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrbBarrage.java @@ -39,7 +39,7 @@ public class AbilityOrbBarrage extends Ability { // Data classes for energy properties private final EnergyDisplayData colorData = new EnergyDisplayData(); private final EnergyCombatData combatData = new EnergyCombatData(4.0f, 0.0f, 0.0f, false, 1.5f, 0.5f); - private final EnergyTrajectoryData homingData = new EnergyTrajectoryData(); + private final EnergyHomingData homingData = new EnergyHomingData(); private final EnergyLightningData lightningData = new EnergyLightningData(); private final EnergyLifespanData lifespanData = new EnergyLifespanData(); private final EnergyAnchorData[] anchorData = new EnergyAnchorData[]{ diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrbDual.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrbDual.java index cc6ff2b22..4ff683aef 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrbDual.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrbDual.java @@ -36,7 +36,7 @@ public class AbilityOrbDual extends Ability { new EnergyDisplayData(), new EnergyDisplayData() }; public final EnergyCombatData combatData = new EnergyCombatData(); - public final EnergyTrajectoryData homingData = new EnergyTrajectoryData(); + public final EnergyHomingData homingData = new EnergyHomingData(); public final EnergyLightningData[] lightningData = new EnergyLightningData[]{ new EnergyLightningData(), new EnergyLightningData() }; @@ -118,8 +118,8 @@ public class AbilityOrbDual extends Ability { spawnPos2.xCoord, spawnPos2.yCoord, spawnPos2.zCoord, orbSize, colorData[1], combatData, homingData, lightningData[1], lifespanData); - orbEntity.setSiblingUUID(orbEntity2.getPersistentID()); - orbEntity2.setSiblingUUID(orbEntity.getPersistentID()); + orbEntity.setSiblingEntityId(orbEntity2.getEntityId()); + orbEntity2.setSiblingEntityId(orbEntity.getEntityId()); orbEntity.setupCharging(anchorData[0], windUpTicks); orbEntity2.setupCharging(anchorData[1], windUpTicks); diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityBeam.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityBeam.java index e0bb79023..cba16d814 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityBeam.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityBeam.java @@ -1,6 +1,5 @@ package kamkeel.npcs.entity; -import kamkeel.npcs.controllers.data.ability.AnchorPoint; import kamkeel.npcs.controllers.data.ability.data.*; import kamkeel.npcs.util.AnchorPointHelper; import net.minecraft.entity.Entity; @@ -15,7 +14,6 @@ import noppes.npcs.LogWriter; import java.util.ArrayList; import java.util.List; -import java.util.UUID; /** * Beam projectile - head with trailing path that curves with homing. @@ -28,13 +26,6 @@ import java.util.UUID; */ public class EntityAbilityBeam extends EntityAbilityProjectile { - // Beam-specific movement properties - private float speed = 0.5f; - private boolean homing = true; - private float homingStrength = 0.35f; // Increased from 0.15 for better tracking - private float homingRange = 20.0f; - private UUID siblingUUID = null; - // Beam shape properties private float beamWidth = 0.3f; private float headSize = 0.5f; @@ -59,7 +50,6 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { private int chargeDuration = 40; private int chargeTick = 0; private float chargeOffsetDistance = 1.0f; - private EnergyAnchorData anchorData = new EnergyAnchorData(AnchorPoint.FRONT); // Trail fading for non-anchored beams (comet effect) private boolean fadeTrail = false; @@ -112,20 +102,18 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { public EntityAbilityBeam(World world, EntityLivingBase owner, EntityLivingBase target, double x, double y, double z, float beamWidth, float headSize, - EnergyDisplayData color, EnergyCombatData combat, - EnergyTrajectoryData homing, EnergyLightningData lightning, + EnergyDisplayData display, EnergyCombatData combat, + EnergyHomingData homing, EnergyLightningData lightning, EnergyLifespanData lifespan, boolean anchoredMode) { super(world); // Initialize base properties via parent - initProjectile(owner, target, x, y, z, headSize, color, combat, lightning, lifespan); + initProjectile(owner, target, x, y, z, headSize, display, combat, lightning, lifespan); // Beam-specific properties from homing data - this.speed = homing.speed; - this.homing = homing.homing; - this.homingStrength = homing.homingStrength; - this.homingRange = homing.homingRange; + + this.homingData = homing; this.beamWidth = beamWidth; this.headSize = headSize; @@ -155,16 +143,16 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { double dz = target.posZ - z; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { - this.motionX = (dx / len) * speed; - this.motionY = (dy / len) * speed; - this.motionZ = (dz / len) * speed; + this.motionX = (dx / len) * getSpeed(); + this.motionY = (dy / len) * getSpeed(); + this.motionZ = (dz / len) * getSpeed(); } } else { float yaw = (float) Math.toRadians(owner.rotationYaw); float pitch = (float) Math.toRadians(owner.rotationPitch); - this.motionX = -Math.sin(yaw) * Math.cos(pitch) * speed; - this.motionY = -Math.sin(pitch) * speed; - this.motionZ = Math.cos(yaw) * Math.cos(pitch) * speed; + this.motionX = -Math.sin(yaw) * Math.cos(pitch) * getSpeed(); + this.motionY = -Math.sin(pitch) * getSpeed(); + this.motionZ = Math.cos(yaw) * Math.cos(pitch) * getSpeed(); } } @@ -180,7 +168,7 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { this.motionZ = 0; } - public void setupPreview(EntityLivingBase owner, float beamWidth, float headSize, EnergyDisplayData color, EnergyLightningData lightning, EnergyAnchorData anchor, int chargeDuration, float chargeOffsetDistance) { + public void setupPreview(EntityLivingBase owner, float beamWidth, float headSize, EnergyDisplayData display, EnergyLightningData lightning, EnergyAnchorData anchor, int chargeDuration, float chargeOffsetDistance) { this.setPreviewMode(true); this.setPreviewOwner(owner); @@ -188,15 +176,8 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { this.beamWidth = beamWidth; this.headSize = headSize; this.size = headSize; - this.innerColor = color.innerColor; - this.outerColor = color.outerColor; - this.outerColorEnabled = color.outerColorEnabled; - this.outerColorWidth = color.outerColorWidth; - this.outerColorAlpha = color.outerColorAlpha; - this.rotationSpeed = color.rotationSpeed; - this.lightningEffect = lightning.lightningEffect; - this.lightningDensity = lightning.lightningDensity; - this.lightningRadius = lightning.lightningRadius; + this.displayData = display; + this.lightningData = lightning; // Set charging state this.setCharging(true); @@ -252,15 +233,15 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { prevPosZ = posZ; // Fire forward based on owner facing direction - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner != null) { float yaw = (float) Math.toRadians(owner.rotationYaw); float pitch = 0; // Fire horizontally - motionX = -Math.sin(yaw) * Math.cos(pitch) * speed; - motionY = -Math.sin(pitch) * speed; - motionZ = Math.cos(yaw) * Math.cos(pitch) * speed; + motionX = -Math.sin(yaw) * Math.cos(pitch) * getSpeed(); + motionY = -Math.sin(pitch) * getSpeed(); + motionZ = Math.cos(yaw) * Math.cos(pitch) * getSpeed(); } else { - motionX = speed; + motionX = getSpeed(); motionY = 0; motionZ = 0; } @@ -303,7 +284,7 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { if (fadeTrail) trailPointAges.add(0); // Calculate velocity toward target (head starts at origin = startX/Y/Z) - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (target != null) { double dx = target.posX - startX; @@ -311,16 +292,16 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { double dz = target.posZ - startZ; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { - motionX = (dx / len) * speed; - motionY = (dy / len) * speed; - motionZ = (dz / len) * speed; + motionX = (dx / len) * getSpeed(); + motionY = (dy / len) * getSpeed(); + motionZ = (dz / len) * getSpeed(); } } else if (owner != null) { float yaw = (float) Math.toRadians(owner.rotationYaw); float pitch = (float) Math.toRadians(owner.rotationPitch); - motionX = -Math.sin(yaw) * Math.cos(pitch) * speed; - motionY = -Math.sin(pitch) * speed; - motionZ = Math.cos(yaw) * Math.cos(pitch) * speed; + motionX = -Math.sin(yaw) * Math.cos(pitch) * getSpeed(); + motionY = -Math.sin(pitch) * getSpeed(); + motionZ = Math.cos(yaw) * Math.cos(pitch) * getSpeed(); } if (DEBUG_LOGGING && !worldObj.isRemote) { @@ -338,9 +319,9 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { headOffsetY * headOffsetY + headOffsetZ * headOffsetZ ); - boolean exceeded = distFromOrigin >= maxDistance; + boolean exceeded = distFromOrigin >= getMaxDistance(); if (exceeded && !worldObj.isRemote && DEBUG_LOGGING) { - LogWriter.info("[Beam] DEAD: Max distance exceeded. dist=" + distFromOrigin + " max=" + maxDistance); + LogWriter.info("[Beam] DEAD: Max distance exceeded. dist=" + distFromOrigin + " max=" + getMaxDistance()); } return exceeded; } @@ -394,7 +375,7 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { // Update origin if attached to owner if (attachedToOwner) { - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner != null) { startX = owner.posX; startY = owner.posY + owner.getEyeHeight() * 0.7; @@ -438,7 +419,7 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { private void updateCharging() { chargeTick++; - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner == null || owner.isDead) { setDead(); return; @@ -529,7 +510,7 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { // Update origin if attached to owner if (attachedToOwner) { - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner != null) { startX = owner.posX; startY = owner.posY + owner.getEyeHeight() * 0.7; @@ -550,9 +531,9 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { } private void updateHoming() { - if (!homing) return; + if (!isHoming()) return; - Entity target = getTarget(); + Entity target = getTargetEntity(); if (target == null || !target.isEntityAlive()) return; // Calculate world position of head @@ -565,18 +546,18 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { double dz = target.posZ - headWorldZ; double dist = Math.sqrt(dx * dx + dy * dy + dz * dz); - if (dist <= homingRange && dist > 0) { + if (dist <= getHomingRange() && dist > 0) { // Calculate effective homing strength - increases when closer to commit to target - float effectiveStrength = homingStrength; - if (dist < homingRange * 0.3) { - effectiveStrength = Math.min(1.0f, homingStrength * 2.5f); - } else if (dist < homingRange * 0.6) { - effectiveStrength = Math.min(0.8f, homingStrength * 1.5f); + float effectiveStrength = getHomingStrength(); + if (dist < getHomingRange() * 0.3) { + effectiveStrength = Math.min(1.0f, getHomingStrength() * 2.5f); + } else if (dist < getHomingRange() * 0.6) { + effectiveStrength = Math.min(0.8f, getHomingStrength() * 1.5f); } - double desiredVX = (dx / dist) * speed; - double desiredVY = (dy / dist) * speed; - double desiredVZ = (dz / dist) * speed; + double desiredVX = (dx / dist) * getSpeed(); + double desiredVY = (dy / dist) * getSpeed(); + double desiredVZ = (dz / dist) * getSpeed(); motionX += (desiredVX - motionX) * effectiveStrength; motionY += (desiredVY - motionY) * effectiveStrength; @@ -584,9 +565,9 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { double vLen = Math.sqrt(motionX * motionX + motionY * motionY + motionZ * motionZ); if (vLen > 0) { - motionX = (motionX / vLen) * speed; - motionY = (motionY / vLen) * speed; - motionZ = (motionZ / vLen) * speed; + motionX = (motionX / vLen) * getSpeed(); + motionY = (motionY / vLen) * getSpeed(); + motionZ = (motionZ / vLen) * getSpeed(); } } } @@ -604,7 +585,7 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { if (blockHit != null && blockHit.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { hasHit = true; - if (explosive) { + if (isExplosive()) { posX = blockHit.hitVec.xCoord; posY = blockHit.hitVec.yCoord; posZ = blockHit.hitVec.zCoord; @@ -632,7 +613,7 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { } hasHit = true; - if (explosive) { + if (isExplosive()) { posX = headX; posY = headY; posZ = headZ; @@ -646,12 +627,6 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { } } - @Override - protected boolean shouldIgnoreEntity(Entity entity) { - if (entity.getPersistentID().equals(siblingUUID)) return true; - return super.shouldIgnoreEntity(entity); - } - // ==================== GETTERS FOR RENDERER ==================== public float getBeamWidth() { @@ -750,26 +725,10 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { return trailFadeTime; } - public UUID getSiblingUUID() { - return siblingUUID; - } - - public void setSiblingUUID(UUID siblingUUID) { - if (siblingUUID == null) - return; - - if (this.siblingUUID == null) - this.siblingUUID = siblingUUID; - } - // ==================== NBT ==================== @Override protected void readProjectileNBT(NBTTagCompound nbt) { - this.speed = nbt.hasKey("Speed") ? nbt.getFloat("Speed") : 0.5f; - this.homing = !nbt.hasKey("Homing") || nbt.getBoolean("Homing"); - this.homingStrength = nbt.hasKey("HomingStrength") ? nbt.getFloat("HomingStrength") : 0.15f; - this.homingRange = nbt.hasKey("HomingRange") ? nbt.getFloat("HomingRange") : 20.0f; this.beamWidth = nbt.hasKey("BeamWidth") ? nbt.getFloat("BeamWidth") : 0.3f; this.headSize = nbt.hasKey("HeadSize") ? nbt.getFloat("HeadSize") : 0.5f; this.headOffsetX = nbt.hasKey("HeadOffsetX") ? nbt.getDouble("HeadOffsetX") : 0; @@ -790,7 +749,6 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { this.fadeTrail = nbt.hasKey("FadeTrail") && nbt.getBoolean("FadeTrail"); this.trailFadeTime = nbt.hasKey("TrailFadeTime") ? nbt.getInteger("TrailFadeTime") : 20; - this.anchorData.readNBT(nbt); // Read trail points (relative to origin) trailPoints.clear(); @@ -805,16 +763,10 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { )); } } - - this.siblingUUID = nbt.hasKey("SiblingUUID") ? UUID.fromString(nbt.getString("SiblingUUID")) : null; } @Override protected void writeProjectileNBT(NBTTagCompound nbt) { - nbt.setFloat("Speed", speed); - nbt.setBoolean("Homing", homing); - nbt.setFloat("HomingStrength", homingStrength); - nbt.setFloat("HomingRange", homingRange); nbt.setFloat("BeamWidth", beamWidth); nbt.setFloat("HeadSize", headSize); nbt.setDouble("HeadOffsetX", headOffsetX); @@ -841,9 +793,5 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { trailList.appendTag(pointNbt); } nbt.setTag("Trail", trailList); - - if (siblingUUID instanceof UUID) { - nbt.setString("SiblingUUID", siblingUUID.toString()); - } } } diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityDisc.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityDisc.java index eba82ac03..68523e498 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityDisc.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityDisc.java @@ -11,7 +11,6 @@ import net.minecraft.util.Vec3; import net.minecraft.world.World; import java.util.List; -import java.util.UUID; /** * Disc projectile - flat spinning disc with optional boomerang behavior. @@ -21,11 +20,7 @@ import java.util.UUID; */ public class EntityAbilityDisc extends EntityAbilityProjectile { - // Disc-specific movement properties - private float speed = 0.5f; - private boolean homing = true; - private float homingStrength = 0.35f; // Increased from 0.15 for better tracking - private float homingRange = 20.0f; + // Disc-specific movement propertie // Boomerang properties private boolean boomerang = false; @@ -48,8 +43,6 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { // Data watcher index for charging state (synced to clients) private static final int DW_CHARGING = 20; - private UUID siblingUUID = null; - public EntityAbilityDisc(World world) { super(world); } @@ -88,20 +81,16 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { public EntityAbilityDisc(World world, EntityLivingBase owner, EntityLivingBase target, double x, double y, double z, float discRadius, float discThickness, - EnergyDisplayData color, EnergyCombatData combat, - EnergyTrajectoryData homing, EnergyLightningData lightning, + EnergyDisplayData display, EnergyCombatData combat, + EnergyHomingData homing, EnergyLightningData lightning, EnergyLifespanData lifespan, boolean boomerang, int boomerangDelay) { super(world); // Initialize base properties - initProjectile(owner, target, x, y, z, discRadius, color, combat, lightning, lifespan); + initProjectile(owner, target, x, y, z, discRadius, display, combat, lightning, lifespan); - // Disc-specific properties from homing data - this.speed = homing.speed; - this.homing = homing.homing; - this.homingStrength = homing.homingStrength; - this.homingRange = homing.homingRange; + this.homingData = homing; this.boomerang = boomerang; this.boomerangDelay = boomerangDelay; @@ -116,16 +105,16 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { double dz = target.posZ - z; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { - this.motionX = (dx / len) * speed; - this.motionY = (dy / len) * speed; - this.motionZ = (dz / len) * speed; + this.motionX = (dx / len) * getSpeed(); + this.motionY = (dy / len) * getSpeed(); + this.motionZ = (dz / len) * getSpeed(); } } else { float yaw = (float) Math.toRadians(owner.rotationYaw); float pitch = (float) Math.toRadians(owner.rotationPitch); - this.motionX = -Math.sin(yaw) * Math.cos(pitch) * speed; - this.motionY = -Math.sin(pitch) * speed; - this.motionZ = Math.cos(yaw) * Math.cos(pitch) * speed; + this.motionX = -Math.sin(yaw) * Math.cos(pitch) * getSpeed(); + this.motionY = -Math.sin(pitch) * getSpeed(); + this.motionZ = Math.cos(yaw) * Math.cos(pitch) * getSpeed(); } } @@ -156,19 +145,13 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { * Follows anchor point and animations like in the real game. * Can be fired when transitioning to active phase. */ - public void setupPreview(EntityLivingBase owner, float discRadius, float discThickness, EnergyDisplayData color, EnergyLightningData lightning, EnergyAnchorData anchor, int chargeDuration) { + public void setupPreview(EntityLivingBase owner, float discRadius, float discThickness, EnergyDisplayData display, EnergyLightningData lightning, EnergyAnchorData anchor, int chargeDuration) { this.setPreviewMode(true); this.setPreviewOwner(owner); // Set visual properties - this.innerColor = color.innerColor; - this.outerColor = color.outerColor; - this.outerColorEnabled = color.outerColorEnabled; - this.outerColorWidth = color.outerColorWidth; - this.rotationSpeed = color.rotationSpeed; - this.lightningEffect = lightning.lightningEffect; - this.lightningDensity = lightning.lightningDensity; - this.lightningRadius = lightning.lightningRadius; + this.displayData = display; + this.lightningData = lightning; // Set charging state this.setCharging(true); @@ -218,15 +201,15 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { prevPosZ = posZ; // Fire forward based on owner facing direction - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner != null) { float yaw = (float) Math.toRadians(owner.rotationYaw); float pitch = 0; // Fire horizontally - motionX = -Math.sin(yaw) * Math.cos(pitch) * speed; - motionY = -Math.sin(pitch) * speed; - motionZ = Math.cos(yaw) * Math.cos(pitch) * speed; + motionX = -Math.sin(yaw) * Math.cos(pitch) * getSpeed(); + motionY = -Math.sin(pitch) * getSpeed(); + motionZ = Math.cos(yaw) * Math.cos(pitch) * getSpeed(); } else { - motionX = speed; + motionX = getSpeed(); motionY = 0; motionZ = 0; } @@ -247,7 +230,7 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { startZ = posZ; // Calculate velocity toward target - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (target != null) { double dx = target.posX - posX; @@ -255,23 +238,23 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { double dz = target.posZ - posZ; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { - motionX = (dx / len) * speed; - motionY = (dy / len) * speed; - motionZ = (dz / len) * speed; + motionX = (dx / len) * getSpeed(); + motionY = (dy / len) * getSpeed(); + motionZ = (dz / len) * getSpeed(); } } else if (owner != null) { float yaw = (float) Math.toRadians(owner.rotationYaw); float pitch = (float) Math.toRadians(owner.rotationPitch); - motionX = -Math.sin(yaw) * Math.cos(pitch) * speed; - motionY = -Math.sin(pitch) * speed; - motionZ = Math.cos(yaw) * Math.cos(pitch) * speed; + motionX = -Math.sin(yaw) * Math.cos(pitch) * getSpeed(); + motionY = -Math.sin(pitch) * getSpeed(); + motionZ = Math.cos(yaw) * Math.cos(pitch) * getSpeed(); } } @Override protected void updateRotation() { // Disc spins ONLY on Y axis (flat spin like a saw blade) - this.rotationValY += rotationSpeed; + this.rotationValY += getRotationSpeed(); // No wobble - keep X and Z at 0 for stable flight if (this.rotationValY > 360.0f) this.rotationValY -= 360.0f; } @@ -314,7 +297,7 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { if (this.isCollidedHorizontally || this.isCollidedVertically) { if (!worldObj.isRemote) { hasHit = true; - if (explosive) { + if (isExplosive()) { doExplosion(); } } @@ -333,14 +316,14 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { if (boomerang) { // If not returning yet, check if we should start returning if (!returning && !hasHit) { - if (distTraveled >= maxDistance * 0.8 || ticksSinceMiss >= boomerangDelay) { + if (distTraveled >= getMaxDistance() * 0.8 || ticksSinceMiss >= boomerangDelay) { returning = true; } } // If returning, only die when close to owner if (returning) { - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner != null) { double distToOwner = Math.sqrt( (posX - owner.posX) * (posX - owner.posX) + @@ -358,7 +341,7 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { } // Non-boomerang: standard max distance check - return distTraveled >= maxDistance; + return distTraveled >= getMaxDistance(); } /** @@ -372,9 +355,9 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { } private void updateHoming() { - if (!homing) return; + if (!isHoming()) return; - Entity target = getTarget(); + Entity target = getTargetEntity(); if (target == null || !target.isEntityAlive()) return; double dx = target.posX - posX; @@ -382,18 +365,18 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { double dz = target.posZ - posZ; double dist = Math.sqrt(dx * dx + dy * dy + dz * dz); - if (dist <= homingRange && dist > 0) { + if (dist <= getHomingRange() && dist > 0) { // Calculate effective homing strength - increases when closer to commit to target - float effectiveStrength = homingStrength; - if (dist < homingRange * 0.3) { - effectiveStrength = Math.min(1.0f, homingStrength * 2.5f); - } else if (dist < homingRange * 0.6) { - effectiveStrength = Math.min(0.8f, homingStrength * 1.5f); + float effectiveStrength = getHomingStrength(); + if (dist < getHomingRange() * 0.3) { + effectiveStrength = Math.min(1.0f, getHomingStrength() * 2.5f); + } else if (dist < getHomingRange() * 0.6) { + effectiveStrength = Math.min(0.8f, getHomingStrength() * 1.5f); } - double desiredVX = (dx / dist) * speed; - double desiredVY = (dy / dist) * speed; - double desiredVZ = (dz / dist) * speed; + double desiredVX = (dx / dist) * getSpeed(); + double desiredVY = (dy / dist) * getSpeed(); + double desiredVZ = (dz / dist) * getSpeed(); motionX += (desiredVX - motionX) * effectiveStrength; motionY += (desiredVY - motionY) * effectiveStrength; @@ -401,15 +384,15 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { double vLen = Math.sqrt(motionX * motionX + motionY * motionY + motionZ * motionZ); if (vLen > 0) { - motionX = (motionX / vLen) * speed; - motionY = (motionY / vLen) * speed; - motionZ = (motionZ / vLen) * speed; + motionX = (motionX / vLen) * getSpeed(); + motionY = (motionY / vLen) * getSpeed(); + motionZ = (motionZ / vLen) * getSpeed(); } } } private void updateReturnToOwner() { - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); // If owner is gone (unloaded/dead), head back toward start position double targetX, targetY, targetZ; @@ -431,10 +414,10 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { if (dist > 0) { // Stronger homing when returning - double returnStrength = Math.min(1.0, homingStrength * 2.5); - double desiredVX = (dx / dist) * speed; - double desiredVY = (dy / dist) * speed; - double desiredVZ = (dz / dist) * speed; + double returnStrength = Math.min(1.0, getHomingStrength() * 2.5); + double desiredVX = (dx / dist) * getSpeed(); + double desiredVY = (dy / dist) * getSpeed(); + double desiredVZ = (dz / dist) * getSpeed(); motionX += (desiredVX - motionX) * returnStrength; motionY += (desiredVY - motionY) * returnStrength; @@ -442,9 +425,9 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { double vLen = Math.sqrt(motionX * motionX + motionY * motionY + motionZ * motionZ); if (vLen > 0) { - motionX = (motionX / vLen) * speed; - motionY = (motionY / vLen) * speed; - motionZ = (motionZ / vLen) * speed; + motionX = (motionX / vLen) * getSpeed(); + motionY = (motionY / vLen) * getSpeed(); + motionZ = (motionZ / vLen) * getSpeed(); } } } @@ -457,7 +440,7 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { if (blockHit != null && blockHit.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { hasHit = true; - if (explosive) { + if (isExplosive()) { posX = blockHit.hitVec.xCoord; posY = blockHit.hitVec.yCoord; posZ = blockHit.hitVec.zCoord; @@ -484,7 +467,7 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { hasHit = true; - if (explosive) { + if (isExplosive()) { doExplosion(); } else { applyDamage(entity); @@ -501,7 +484,7 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { private void updateCharging() { chargeTick++; - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner == null || owner.isDead) { setDead(); return; @@ -543,14 +526,6 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { // ==================== GETTERS ==================== - public float getSpeed() { - return speed; - } - - public boolean isHoming() { - return homing; - } - public float getDiscRadius() { return discRadius; } @@ -567,26 +542,10 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { return returning; } - public UUID getSiblingUUID() { - return siblingUUID; - } - - public void setSiblingUUID(UUID siblingUUID) { - if (siblingUUID == null) - return; - - if (this.siblingUUID == null) - this.siblingUUID = siblingUUID; - } - // ==================== NBT ==================== @Override protected void readProjectileNBT(NBTTagCompound nbt) { - this.speed = nbt.hasKey("Speed") ? nbt.getFloat("Speed") : 0.5f; - this.homing = !nbt.hasKey("Homing") || nbt.getBoolean("Homing"); - this.homingStrength = nbt.hasKey("HomingStrength") ? nbt.getFloat("HomingStrength") : 0.15f; - this.homingRange = nbt.hasKey("HomingRange") ? nbt.getFloat("HomingRange") : 20.0f; this.boomerang = nbt.hasKey("Boomerang") && nbt.getBoolean("Boomerang"); this.boomerangDelay = nbt.hasKey("BoomerangDelay") ? nbt.getInteger("BoomerangDelay") : 40; this.discRadius = nbt.hasKey("DiscRadius") ? nbt.getFloat("DiscRadius") : 1.0f; @@ -600,16 +559,10 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { this.chargeTick = nbt.hasKey("ChargeTick") ? nbt.getInteger("ChargeTick") : 0; this.targetDiscRadius = nbt.hasKey("TargetDiscRadius") ? nbt.getFloat("TargetDiscRadius") : this.discRadius; this.targetDiscThickness = nbt.hasKey("TargetDiscThickness") ? nbt.getFloat("TargetDiscThickness") : this.discThickness; - this.anchorData.readNBT(nbt); - this.siblingUUID = nbt.hasKey("SiblingUUID") ? UUID.fromString(nbt.getString("SiblingUUID")) : null; } @Override protected void writeProjectileNBT(NBTTagCompound nbt) { - nbt.setFloat("Speed", speed); - nbt.setBoolean("Homing", homing); - nbt.setFloat("HomingStrength", homingStrength); - nbt.setFloat("HomingRange", homingRange); nbt.setBoolean("Boomerang", boomerang); nbt.setInteger("BoomerangDelay", boomerangDelay); nbt.setFloat("DiscRadius", discRadius); @@ -621,12 +574,5 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { nbt.setInteger("ChargeTick", chargeTick); nbt.setFloat("TargetDiscRadius", targetDiscRadius); nbt.setFloat("TargetDiscThickness", targetDiscThickness); - - // Anchor data - this.anchorData.writeNBT(nbt); - - if (siblingUUID instanceof UUID) { - nbt.setString("SiblingUUID", siblingUUID.toString()); - } } } diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java index a6b5ec6ed..328825bef 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java @@ -90,14 +90,14 @@ public class EntityAbilityLaser extends EntityAbilityProjectile { public EntityAbilityLaser(World world, EntityLivingBase owner, EntityLivingBase target, double x, double y, double z, float laserWidth, - EnergyDisplayData color, EnergyCombatData combat, + EnergyDisplayData display, EnergyCombatData combat, EnergyLightningData lightning, EnergyLifespanData lifespan, float expansionSpeed, int lingerTicks) { super(world); // Initialize base properties (laser doesn't rotate) - initProjectile(owner, target, x, y, z, laserWidth, color, combat, lightning, lifespan); - this.rotationSpeed = 0.0f; + initProjectile(owner, target, x, y, z, laserWidth, display, combat, lightning, lifespan); + this.displayData.rotationSpeed = 0.0f; // Laser-specific properties this.laserWidth = laserWidth; @@ -171,8 +171,8 @@ public class EntityAbilityLaser extends EntityAbilityProjectile { // Expand the laser currentLength += expansionSpeed; - if (currentLength >= maxDistance) { - currentLength = maxDistance; + if (currentLength >= getMaxDistance()) { + currentLength = getMaxDistance(); fullyExtended = true; } @@ -206,7 +206,7 @@ public class EntityAbilityLaser extends EntityAbilityProjectile { startZ = posZ; // Calculate velocity toward target - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (target != null) { double dx = target.posX - startX; @@ -253,7 +253,7 @@ public class EntityAbilityLaser extends EntityAbilityProjectile { endZ = blockHit.hitVec.zCoord; fullyExtended = true; - if (explosive) { + if (isExplosive()) { // Explode at hit point double oldPosX = posX; double oldPosY = posY; @@ -275,7 +275,7 @@ public class EntityAbilityLaser extends EntityAbilityProjectile { private void updateCharging() { chargeTick++; - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner == null || owner.isDead) { setDead(); return; @@ -481,7 +481,7 @@ public class EntityAbilityLaser extends EntityAbilityProjectile { * Setup this laser in preview mode for GUI display. * Laser doesn't have charging state - spawns at active phase and fires immediately. */ - public void setupPreview(EntityLivingBase owner, float laserWidth, EnergyDisplayData color, + public void setupPreview(EntityLivingBase owner, float laserWidth, EnergyDisplayData display, EnergyLightningData lightning, float expansionSpeed, float maxDistance) { this.setPreviewMode(true); this.setPreviewOwner(owner); @@ -489,15 +489,10 @@ public class EntityAbilityLaser extends EntityAbilityProjectile { // Set visual properties this.laserWidth = laserWidth; this.size = laserWidth; - this.innerColor = color.innerColor; - this.outerColor = color.outerColor; - this.outerColorEnabled = color.outerColorEnabled; - this.outerColorWidth = color.outerColorWidth; + this.displayData = display; this.expansionSpeed = expansionSpeed; - this.maxDistance = Math.min(maxDistance, 5.0f); // Limit for GUI preview - this.lightningEffect = lightning.lightningEffect; - this.lightningDensity = lightning.lightningDensity; - this.lightningRadius = lightning.lightningRadius; + this.lifespanData.maxDistance = Math.min(maxDistance, 5.0f); // Limit for GUI preview + this.lightningData = lightning; // Position at chest height double x = owner.posX; diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityOrb.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityOrb.java index c036364c4..906f38ace 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityOrb.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityOrb.java @@ -1,6 +1,5 @@ package kamkeel.npcs.entity; -import kamkeel.npcs.controllers.data.ability.AnchorPoint; import kamkeel.npcs.controllers.data.ability.data.*; import kamkeel.npcs.util.AnchorPointHelper; import net.minecraft.entity.Entity; @@ -12,7 +11,6 @@ import net.minecraft.util.Vec3; import net.minecraft.world.World; import java.util.List; -import java.util.UUID; /** * Orb projectile - spherical homing energy ball. @@ -22,24 +20,15 @@ import java.util.UUID; */ public class EntityAbilityOrb extends EntityAbilityProjectile { - // Orb-specific movement properties - private float speed = 0.5f; - private boolean homing = true; - private float homingStrength = 0.35f; // Increased from 0.15 for better tracking - private float homingRange = 20.0f; - // Charging state (during windup) private boolean charging = false; private int chargeDuration = 40; private int chargeTick = 0; - private EnergyAnchorData anchorData = new EnergyAnchorData(AnchorPoint.FRONT); private float targetSize = 1.0f; // Full size to grow to during charging // Data watcher index for charging state (synced to clients) private static final int DW_CHARGING = 20; - private UUID siblingUUID = null; - public EntityAbilityOrb(World world) { super(world); } @@ -77,19 +66,15 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { */ public EntityAbilityOrb(World world, EntityLivingBase owner, EntityLivingBase target, double x, double y, double z, float orbSize, - EnergyDisplayData color, EnergyCombatData combat, - EnergyTrajectoryData homing, EnergyLightningData lightning, + EnergyDisplayData display, EnergyCombatData combat, + EnergyHomingData homing, EnergyLightningData lightning, EnergyLifespanData lifespan) { super(world); // Initialize base properties - initProjectile(owner, target, x, y, z, orbSize, color, combat, lightning, lifespan); + initProjectile(owner, target, x, y, z, orbSize, display, combat, lightning, lifespan); - // Orb-specific properties - this.speed = homing.speed; - this.homing = homing.homing; - this.homingStrength = homing.homingStrength; - this.homingRange = homing.homingRange; + this.homingData = homing; // Calculate initial velocity toward target if (target != null) { @@ -136,20 +121,13 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { * Follows anchor point and animations like in the real game. * Can be fired when transitioning to active phase. */ - public void setupPreview(EntityLivingBase owner, float orbSize, EnergyDisplayData color, EnergyLightningData lightning, EnergyAnchorData anchor, int chargeDuration) { + public void setupPreview(EntityLivingBase owner, float orbSize, EnergyDisplayData display, EnergyLightningData lightning, EnergyAnchorData anchor, int chargeDuration) { this.setPreviewMode(true); this.setPreviewOwner(owner); // Set visual properties - this.innerColor = color.innerColor; - this.outerColor = color.outerColor; - this.outerColorEnabled = color.outerColorEnabled; - this.outerColorWidth = color.outerColorWidth; - this.rotationSpeed = color.rotationSpeed; - this.lightningEffect = lightning.lightningEffect; - this.lightningDensity = lightning.lightningDensity; - this.lightningRadius = lightning.lightningRadius; - this.lightningFadeTime = lightning.lightningFadeTime; + this.displayData = display; + this.lightningData = lightning; // Set charging state this.setCharging(true); @@ -198,16 +176,16 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { prevPosZ = posZ; // Fire forward based on owner facing direction - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner != null) { float yaw = (float) Math.toRadians(owner.rotationYaw); float pitch = (float) Math.toRadians(0); // Fire horizontally - motionX = -Math.sin(yaw) * Math.cos(pitch) * speed; - motionY = -Math.sin(pitch) * speed; - motionZ = Math.cos(yaw) * Math.cos(pitch) * speed; + motionX = -Math.sin(yaw) * Math.cos(pitch) * getSpeed(); + motionY = -Math.sin(pitch) * getSpeed(); + motionZ = Math.cos(yaw) * Math.cos(pitch) * getSpeed(); } else { // Default: fire forward (positive X in model space) - motionX = speed; + motionX = getSpeed(); motionY = 0; motionZ = 0; } @@ -228,7 +206,7 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { startZ = posZ; // Calculate velocity toward target - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (target != null) { double dx = target.posX - posX; @@ -236,16 +214,16 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { double dz = target.posZ - posZ; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { - motionX = (dx / len) * speed; - motionY = (dy / len) * speed; - motionZ = (dz / len) * speed; + motionX = (dx / len) * getSpeed(); + motionY = (dy / len) * getSpeed(); + motionZ = (dz / len) * getSpeed(); } } else if (owner != null) { float yaw = (float) Math.toRadians(owner.rotationYaw); float pitch = (float) Math.toRadians(owner.rotationPitch); - motionX = -Math.sin(yaw) * Math.cos(pitch) * speed; - motionY = -Math.sin(pitch) * speed; - motionZ = Math.cos(yaw) * Math.cos(pitch) * speed; + motionX = -Math.sin(yaw) * Math.cos(pitch) * getSpeed(); + motionY = -Math.sin(pitch) * getSpeed(); + motionZ = Math.cos(yaw) * Math.cos(pitch) * getSpeed(); } } @@ -277,7 +255,7 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { if (this.isCollidedHorizontally || this.isCollidedVertically) { if (!worldObj.isRemote) { hasHit = true; - if (explosive) { + if (isExplosive()) { doExplosion(); } } @@ -296,9 +274,9 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { } private void updateHoming() { - if (!homing) return; + if (!isHoming()) return; - Entity target = getTarget(); + Entity target = getTargetEntity(); if (target == null || !target.isEntityAlive()) return; double dx = target.posX - posX; @@ -306,21 +284,21 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { double dz = target.posZ - posZ; double dist = Math.sqrt(dx * dx + dy * dy + dz * dz); - if (dist <= homingRange && dist > 0) { + if (dist <= getHomingRange() && dist > 0) { // Calculate effective homing strength - increases when closer to commit to target // This prevents orbiting behavior at close range - float effectiveStrength = homingStrength; - if (dist < homingRange * 0.3) { + float effectiveStrength = getHomingStrength(); + if (dist < getHomingRange() * 0.3) { // Within 30% of homing range, dramatically increase strength to commit - effectiveStrength = Math.min(1.0f, homingStrength * 2.5f); - } else if (dist < homingRange * 0.6) { + effectiveStrength = Math.min(1.0f, getHomingStrength() * 2.5f); + } else if (dist < getHomingRange() * 0.6) { // Within 60% of homing range, moderately increase strength - effectiveStrength = Math.min(0.8f, homingStrength * 1.5f); + effectiveStrength = Math.min(0.8f, getHomingStrength() * 1.5f); } - double desiredVX = (dx / dist) * speed; - double desiredVY = (dy / dist) * speed; - double desiredVZ = (dz / dist) * speed; + double desiredVX = (dx / dist) * getSpeed(); + double desiredVY = (dy / dist) * getSpeed(); + double desiredVZ = (dz / dist) * getSpeed(); motionX += (desiredVX - motionX) * effectiveStrength; motionY += (desiredVY - motionY) * effectiveStrength; @@ -329,9 +307,9 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { // Normalize to maintain speed double vLen = Math.sqrt(motionX * motionX + motionY * motionY + motionZ * motionZ); if (vLen > 0) { - motionX = (motionX / vLen) * speed; - motionY = (motionY / vLen) * speed; - motionZ = (motionZ / vLen) * speed; + motionX = (motionX / vLen) * getSpeed(); + motionY = (motionY / vLen) * getSpeed(); + motionZ = (motionZ / vLen) * getSpeed(); } } } @@ -344,7 +322,7 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { if (blockHit != null && blockHit.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { hasHit = true; - if (explosive) { + if (isExplosive()) { posX = blockHit.hitVec.xCoord; posY = blockHit.hitVec.yCoord; posZ = blockHit.hitVec.zCoord; @@ -369,7 +347,7 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { hasHit = true; - if (explosive) { + if (isExplosive()) { doExplosion(); } else { applyDamage(entity); @@ -386,7 +364,7 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { private void updateCharging() { chargeTick++; - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner == null || owner.isDead) { setDead(); return; @@ -423,47 +401,15 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { // ==================== GETTERS ==================== - public float getSpeed() { - return speed; - } - - public boolean isHoming() { - return homing; - } - - public float getHomingStrength() { - return homingStrength; - } - - public float getHomingRange() { - return homingRange; - } - // Legacy getter for renderer compatibility public float getOrbSize() { return size; } - public UUID getSiblingUUID() { - return siblingUUID; - } - - public void setSiblingUUID(UUID siblingUUID) { - if (siblingUUID == null) - return; - - if (this.siblingUUID == null) - this.siblingUUID = siblingUUID; - } - // ==================== NBT ==================== @Override protected void readProjectileNBT(NBTTagCompound nbt) { - this.speed = nbt.hasKey("OrbSpeed") ? nbt.getFloat("OrbSpeed") : 0.5f; - this.homing = !nbt.hasKey("Homing") || nbt.getBoolean("Homing"); - this.homingStrength = nbt.hasKey("HomingStrength") ? nbt.getFloat("HomingStrength") : 0.15f; - this.homingRange = nbt.hasKey("HomingRange") ? nbt.getFloat("HomingRange") : 20.0f; // Charging state boolean isCharging = nbt.hasKey("Charging") && nbt.getBoolean("Charging"); this.charging = isCharging; @@ -471,27 +417,15 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { this.chargeDuration = nbt.hasKey("ChargeDuration") ? nbt.getInteger("ChargeDuration") : 40; this.chargeTick = nbt.hasKey("ChargeTick") ? nbt.getInteger("ChargeTick") : 0; this.targetSize = nbt.hasKey("TargetSize") ? nbt.getFloat("TargetSize") : this.size; - // Anchor data - this.anchorData.readNBT(nbt); - - this.siblingUUID = nbt.hasKey("SiblingUUID") ? UUID.fromString(nbt.getString("SiblingUUID")) : null; } @Override protected void writeProjectileNBT(NBTTagCompound nbt) { - nbt.setFloat("OrbSpeed", speed); - nbt.setBoolean("Homing", homing); - nbt.setFloat("HomingStrength", homingStrength); - nbt.setFloat("HomingRange", homingRange); // Charging state nbt.setBoolean("Charging", isCharging()); nbt.setInteger("ChargeDuration", chargeDuration); nbt.setInteger("ChargeTick", chargeTick); anchorData.writeNBT(nbt); nbt.setFloat("TargetSize", targetSize); - - if (siblingUUID instanceof UUID) { - nbt.setString("SiblingUUID", siblingUUID.toString()); - } } } diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityProjectile.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityProjectile.java index 6e6ecefc9..0e66cfc56 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityProjectile.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityProjectile.java @@ -5,10 +5,8 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; import kamkeel.npcs.controllers.data.ability.AbilityEffect; -import kamkeel.npcs.controllers.data.ability.data.EnergyDisplayData; -import kamkeel.npcs.controllers.data.ability.data.EnergyCombatData; -import kamkeel.npcs.controllers.data.ability.data.EnergyLifespanData; -import kamkeel.npcs.controllers.data.ability.data.EnergyLightningData; +import kamkeel.npcs.controllers.data.ability.AnchorPoint; +import kamkeel.npcs.controllers.data.ability.data.*; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; @@ -18,7 +16,10 @@ import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.world.World; import noppes.npcs.NpcDamageSource; +import noppes.npcs.api.entity.IEnergyProjectile; +import noppes.npcs.api.entity.IEntity; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.scripted.NpcAPI; import java.util.ArrayList; import java.util.List; @@ -29,49 +30,42 @@ import java.util.List; * * Design inspired by LouisXIV's energy attack system. */ -public abstract class EntityAbilityProjectile extends Entity implements IEntityAdditionalSpawnData { +public abstract class EntityAbilityProjectile extends Entity implements IEnergyProjectile, IEntityAdditionalSpawnData { // ==================== VISUAL PROPERTIES ==================== protected float size = 1.0f; - protected int innerColor = 0xFFFFFF; - protected int outerColor = 0x8888FF; - protected boolean outerColorEnabled = true; - protected float outerColorWidth = 0.4f; // Additive offset from inner size - protected float outerColorAlpha = 0.5f; - protected float rotationSpeed = 4.0f; // ==================== COMBAT PROPERTIES ==================== - protected float damage = 7.0f; - protected float knockback = 1.0f; - protected float knockbackUp = 0.1f; + protected EnergyCombatData combatData = new EnergyCombatData(); // ==================== EFFECT PROPERTIES ==================== protected List effects = new ArrayList<>(); - // ==================== EXPLOSION PROPERTIES ==================== - protected boolean explosive = false; - protected float explosionRadius = 3.0f; - protected float explosionDamageFalloff = 0.5f; - // ==================== LIGHTNING EFFECT PROPERTIES ==================== - protected boolean lightningEffect = false; - protected float lightningDensity = 0.15f; // Bolts spawned per tick (0.15 = ~15% chance per frame) - protected float lightningRadius = 0.5f; // Max distance lightning can arc from center - protected int lightningFadeTime = 6; // Ticks before lightning fades out + protected EnergyLightningData lightningData = new EnergyLightningData(); // Client-side lightning state (not saved to NBT) @cpw.mods.fml.relauncher.SideOnly(cpw.mods.fml.relauncher.Side.CLIENT) public transient Object lightningState; // Actually AttachedLightningRenderer.LightningState - // ==================== LIFESPAN ==================== - protected float maxDistance = 30.0f; - protected int maxLifetime = 200; + // ==================== DISPLAY PROPERTIES ==================== + protected EnergyDisplayData displayData = new EnergyDisplayData(); + + // ==================== ANCHOR PROPERTIES ==================== + protected EnergyAnchorData anchorData = new EnergyAnchorData(AnchorPoint.FRONT); + + // ==================== LIFESPAN PROPERTIES ==================== + protected EnergyLifespanData lifespanData = new EnergyLifespanData(); protected long deathWorldTime = -1; // World time when entity should die (-1 = not set) + // ==================== HOMING PROPERTIES ==================== + protected EnergyHomingData homingData = new EnergyHomingData(); + // ==================== TRACKING ==================== protected double startX, startY, startZ; protected int ownerEntityId = -1; protected int targetEntityId = -1; + protected int siblingEntityId = -1; // ==================== STATE ==================== protected boolean hasHit = false; @@ -102,9 +96,9 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA /** * Initialize common properties using data classes. Call from subclass constructors. */ - protected void initProjectile(EntityLivingBase owner, EntityLivingBase target, + protected void initProjectile(EntityLivingBase owner, EntityLivingBase target, EntityAbilityProjectile sibling, double x, double y, double z, float size, - EnergyDisplayData color, EnergyCombatData combat, + EnergyDisplayData display, EnergyCombatData combat, EnergyLightningData lightning, EnergyLifespanData lifespan) { this.setPosition(x, y, z); this.startX = x; @@ -113,42 +107,29 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA this.ownerEntityId = owner.getEntityId(); this.targetEntityId = target != null ? target.getEntityId() : -1; + this.siblingEntityId = sibling != null ? sibling.getEntityId() : -1; // Visual this.size = size; - this.innerColor = color.innerColor; - this.outerColor = color.outerColor; - this.outerColorEnabled = color.outerColorEnabled; - this.outerColorWidth = color.outerColorWidth; - this.outerColorAlpha = color.outerColorAlpha; - this.rotationSpeed = color.rotationSpeed; - // Combat - this.damage = combat.damage; - this.knockback = combat.knockback; - this.knockbackUp = combat.knockbackUp; - - // Explosion - this.explosive = combat.explosive; - this.explosionRadius = combat.explosionRadius; - this.explosionDamageFalloff = combat.explosionDamageFalloff; - - // Lifespan - this.maxDistance = lifespan.maxDistance; - this.maxLifetime = lifespan.maxLifetime; - // deathWorldTime will be set on first tick when world is available - - // Lightning - this.lightningEffect = lightning.lightningEffect; - this.lightningDensity = lightning.lightningDensity; - this.lightningRadius = lightning.lightningRadius; - this.lightningFadeTime = lightning.lightningFadeTime; + this.displayData = display; + this.combatData = combat; + this.lifespanData = lifespan; // deathWorldTime will be set on first tick when world is available + this.lightningData = lightning; // Initialize render size this.renderCurrentSize = size; this.prevRenderSize = size; } + // Initialize projectile without a sibling + protected void initProjectile(EntityLivingBase owner, EntityLivingBase target, + double x, double y, double z, float size, + EnergyDisplayData display, EnergyCombatData combat, + EnergyLightningData lightning, EnergyLifespanData lifespan) { + initProjectile(owner, target, null, x, y, z, size, display, combat, lightning, lifespan); + } + @Override protected void entityInit() { // No DataWatcher needed - using IEntityAdditionalSpawnData with NBT @@ -206,7 +187,7 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA // Set death time on first tick if not already set (handles chunk load/unload) if (deathWorldTime < 0 && worldObj != null) { - deathWorldTime = worldObj.getTotalWorldTime() + maxLifetime; + deathWorldTime = worldObj.getTotalWorldTime() + getMaxLifetime(); } // Check lifespan using world time (survives chunk unload/reload) @@ -235,9 +216,9 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA * Update rotation values. Override for custom rotation behavior. */ protected void updateRotation() { - this.rotationValX += rotationSpeed * 0.7f; - this.rotationValY += rotationSpeed; - this.rotationValZ += rotationSpeed * 0.5f; + this.rotationValX += getRotationSpeed() * 0.7f; + this.rotationValY += getRotationSpeed(); + this.rotationValZ += getRotationSpeed() * 0.5f; if (this.rotationValX > 360.0f) this.rotationValX -= 360.0f; if (this.rotationValY > 360.0f) this.rotationValY -= 360.0f; @@ -254,7 +235,7 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA (posY - startY) * (posY - startY) + (posZ - startZ) * (posZ - startZ) ); - return distTraveled >= maxDistance; + return distTraveled >= getMaxDistance(); } /** @@ -326,12 +307,12 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA protected void applyDamage(EntityLivingBase target) { if (previewMode) return; // Skip damage in preview mode - applyDamage(target, this.damage, this.knockback); + applyDamage(target, this.getDamage(), this.getKnockback()); } protected void applyDamage(EntityLivingBase target, float dmg, float kb) { if (previewMode) return; // Skip damage in preview mode - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (owner instanceof EntityNPCInterface) { target.attackEntityFrom(new NpcDamageSource("npc_ability", (EntityNPCInterface) owner), dmg); @@ -350,7 +331,7 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA if (len > 0) { double kbX = (dx / len) * kb * 0.5; double kbZ = (dz / len) * kb * 0.5; - double kbY = knockbackUp > 0 ? knockbackUp : 0.1; + double kbY = getKnockbackUp() > 0 ? getKnockbackUp() : 0.1; target.addVelocity(kbX, kbY, kbZ); target.velocityChanged = true; } @@ -376,11 +357,11 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA if (previewMode) return; // Skip explosion in preview mode worldObj.playSoundEffect(posX, posY, posZ, "random.explode", 1.0f, 1.0f); - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); AxisAlignedBB explosionBox = AxisAlignedBB.getBoundingBox( - posX - explosionRadius, posY - explosionRadius, posZ - explosionRadius, - posX + explosionRadius, posY + explosionRadius, posZ + explosionRadius + posX - getExplosionRadius(), posY - getExplosionRadius(), posZ - getExplosionRadius(), + posX + getExplosionRadius(), posY + getExplosionRadius(), posZ + getExplosionRadius() ); @SuppressWarnings("unchecked") @@ -395,20 +376,16 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA Math.pow(target.posZ - posZ, 2) ); - if (dist <= explosionRadius) { - float falloff = 1.0f - (float) (dist / explosionRadius) * explosionDamageFalloff; - applyDamage(target, damage * falloff, knockback * falloff); + if (dist <= getExplosionRadius()) { + float falloff = 1.0f - (float) (dist / getExplosionRadius()) * getExplosionDamageFalloff(); + applyDamage(target, getDamage() * falloff, getKnockback() * falloff); } } } // ==================== ENTITY HELPERS ==================== - public int getOwnerEntityId() { - return ownerEntityId; - } - - protected Entity getOwner() { + public Entity getOwnerEntity() { // In preview mode, use direct reference (no world lookup) if (previewMode && previewOwner != null) { return previewOwner; @@ -417,6 +394,18 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA return worldObj.getEntityByID(ownerEntityId); } + @Override + public int getOwnerEntityId() { + return ownerEntityId; + } + + @Override + public IEntity getOwner() { + if (previewMode) return null; + if (getOwnerEntity() == null) return null; + return NpcAPI.Instance().getIEntity(getOwnerEntity()); + } + /** * Set the preview owner for GUI preview mode. * This allows anchor point calculations without world entity lookup. @@ -425,16 +414,45 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA this.previewOwner = owner; } - protected Entity getTarget() { + @Override + public int getTargetEntityId() { + return targetEntityId; + } + + public Entity getTargetEntity() { if (targetEntityId == -1) return null; return worldObj.getEntityByID(targetEntityId); } + @Override + public IEntity getTarget() { + if (getTargetEntity() == null) return null; + return NpcAPI.Instance().getIEntity(getTargetEntity()); + } + + @Override + public int getSiblingEntityId() { + return siblingEntityId; + } + + @Override + public void setSiblingEntityId(int siblingEntityId) { + if (!(worldObj.getEntityByID(siblingEntityId) instanceof EntityAbilityProjectile)) return; + + this.siblingEntityId = siblingEntityId; + } + + @Override + public IEnergyProjectile getSibling() { + if (siblingEntityId == -1) return null; + return (EntityAbilityProjectile) worldObj.getEntityByID(siblingEntityId); + } + /** * Check if an entity should be ignored for collision. */ protected boolean shouldIgnoreEntity(Entity entity) { - Entity owner = getOwner(); + Entity owner = getOwnerEntity(); if (entity == owner) return true; if (owner instanceof EntityNPCInterface && entity instanceof EntityNPCInterface) { @@ -442,73 +460,166 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA EntityNPCInterface targetNpc = (EntityNPCInterface) entity; if (ownerNpc.faction.id == targetNpc.faction.id) return true; } + + if (entity.getEntityId() == getSiblingEntityId()) + return true; + return false; } // ==================== VISUAL GETTERS ==================== + @Override public float getSize() { return size; } + @Override public int getInnerColor() { - return innerColor; + return displayData.getInnerColor(); } + @Override public int getOuterColor() { - return outerColor; + return displayData.getOuterColor(); } + @Override public boolean isOuterColorEnabled() { - return outerColorEnabled; + return displayData.isOuterColorEnabled(); } + @Override public float getOuterColorWidth() { - return outerColorWidth; + return displayData.getOuterColorWidth(); } + @Override public float getOuterColorAlpha() { - return outerColorAlpha; + return displayData.getOuterColorAlpha(); } + @Override public float getRotationSpeed() { - return rotationSpeed; + return displayData.getRotationSpeed(); } + // ==================== ROTATION GETTERS ==================== + + @Override public float getInterpolatedRotationX(float partialTicks) { return this.prevRotationValX + (this.rotationValX - this.prevRotationValX) * partialTicks; } + @Override public float getInterpolatedRotationY(float partialTicks) { return this.prevRotationValY + (this.rotationValY - this.prevRotationValY) * partialTicks; } + @Override public float getInterpolatedRotationZ(float partialTicks) { return this.prevRotationValZ + (this.rotationValZ - this.prevRotationValZ) * partialTicks; } + @Override public float getInterpolatedSize(float partialTicks) { return this.prevRenderSize + (this.renderCurrentSize - this.prevRenderSize) * partialTicks; } // ==================== LIGHTNING GETTERS ==================== + @Override public boolean hasLightningEffect() { - return lightningEffect; + return lightningData.isLightningEffect(); } + @Override public float getLightningDensity() { - return lightningDensity; + return lightningData.getLightningDensity(); } + @Override public float getLightningRadius() { - return lightningRadius; + return lightningData.getLightningRadius(); } + @Override public int getLightningFadeTime() { - return lightningFadeTime; + return lightningData.getLightningFadeTime(); } + // ==================== LIFESPAN GETTERS ==================== + + @Override + public float getMaxDistance() { return lifespanData.getMaxDistance(); } + + @Override + public int getMaxLifetime() { return lifespanData.getMaxLifetime(); } + + // ==================== COMBAT GETTERS ==================== + + @Override + public float getDamage() { return combatData.getDamage(); } + + @Override + public float getKnockback() { return combatData.knockback; } + + @Override + public float getKnockbackUp() { return combatData.knockbackUp; } + + @Override + public boolean isExplosive() { return combatData.isExplosive(); } + + @Override + public float getExplosionRadius() { return combatData.explosionRadius; } + + @Override + public float getExplosionDamageFalloff() { return combatData.explosionDamageFalloff; } + + // ==================== VISUAL GETTERS ==================== + + @Override + public float getSpeed() { return homingData.getSpeed(); } + + @Override + public boolean isHoming() { return homingData.isHoming(); } + + @Override + public float getHomingStrength() { return homingData.getHomingStrength(); } + + @Override + public float getHomingRange() { return homingData.getHomingRange(); } + + // ==================== ANCHOR GETTERS ==================== + + public AnchorPoint getAnchorPoint() { return anchorData.getAnchorPoint(); } + + @Override + public int getAnchor() { return anchorData.getAnchor(); } + + @Override + public float getAnchorOffsetX() { return anchorData.getAnchorOffsetX(); } + + @Override + public float getAnchorOffsetY() { return anchorData.getAnchorOffsetY(); } + + @Override + public float getAnchorOffsetZ() { return anchorData.getAnchorOffsetZ(); } + + // ==================== MOVEMENT GETTERS ==================== + + @Override public double getStartX() { return startX; } + + @Override public double getStartY() { return startY; } + + @Override public double getStartZ() { return startZ; } + + @Override public double getMotionX() { return motionX; } + + @Override public double getMotionY() { return motionY; } + + @Override public double getMotionZ() { return motionZ; } + // ==================== BRIGHTNESS ==================== @Override @@ -541,20 +652,6 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA */ protected void readBaseNBT(NBTTagCompound nbt) { this.size = nbt.getFloat("Size"); - this.innerColor = nbt.getInteger("InnerColor"); - this.outerColor = nbt.getInteger("OuterColor"); - this.outerColorEnabled = !nbt.hasKey("OuterColorEnabled") || nbt.getBoolean("OuterColorEnabled"); - this.outerColorAlpha = nbt.hasKey("OuterColorAlpha") ? nbt.getFloat("OuterColorAlpha") : 0.5f; - this.outerColorWidth = nbt.hasKey("OuterColorWidth") ? nbt.getFloat("OuterColorWidth") : 0.4f; - this.rotationSpeed = nbt.hasKey("RotationSpeed") ? nbt.getFloat("RotationSpeed") : 4.0f; - - this.damage = nbt.getFloat("Damage"); - this.knockback = nbt.getFloat("Knockback"); - this.knockbackUp = nbt.getFloat("KnockbackUp"); - - this.explosive = nbt.getBoolean("Explosive"); - this.explosionRadius = nbt.getFloat("ExplosionRadius"); - this.explosionDamageFalloff = nbt.getFloat("ExplosionDamageFalloff"); // Read effects list this.effects.clear(); @@ -565,8 +662,6 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA } } - this.maxDistance = nbt.getFloat("MaxDistance"); - this.maxLifetime = nbt.getInteger("MaxLifetime"); this.deathWorldTime = nbt.hasKey("DeathWorldTime") ? nbt.getLong("DeathWorldTime") : -1; this.startX = nbt.getDouble("StartX"); @@ -575,21 +670,23 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA this.ownerEntityId = nbt.getInteger("OwnerId"); this.targetEntityId = nbt.getInteger("TargetId"); + this.siblingEntityId = nbt.getInteger("SiblingId"); this.motionX = nbt.getDouble("MotionX"); this.motionY = nbt.getDouble("MotionY"); this.motionZ = nbt.getDouble("MotionZ"); - // Lightning - this.lightningEffect = nbt.getBoolean("LightningEffect"); - this.lightningDensity = nbt.hasKey("LightningDensity") ? nbt.getFloat("LightningDensity") : 0.15f; - this.lightningRadius = nbt.hasKey("LightningRadius") ? nbt.getFloat("LightningRadius") : 0.5f; - this.lightningFadeTime = nbt.hasKey("LightningFadeTime") ? nbt.getInteger("LightningFadeTime") : 6; - if (this.worldObj != null && this.worldObj.isRemote) { this.renderCurrentSize = this.size; this.prevRenderSize = this.size; } + + anchorData.readNBT(nbt); + combatData.readNBT(nbt); + displayData.readNBT(nbt); + homingData.readNBT(nbt); + lifespanData.readNBT(nbt); + lightningData.readNBT(nbt); } /** @@ -597,20 +694,6 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA */ protected void writeBaseNBT(NBTTagCompound nbt) { nbt.setFloat("Size", size); - nbt.setInteger("InnerColor", innerColor); - nbt.setInteger("OuterColor", outerColor); - nbt.setBoolean("OuterColorEnabled", outerColorEnabled); - nbt.setFloat("OuterColorWidth", outerColorWidth); - nbt.setFloat("OuterColorAlpha", outerColorAlpha); - nbt.setFloat("RotationSpeed", rotationSpeed); - - nbt.setFloat("Damage", damage); - nbt.setFloat("Knockback", knockback); - nbt.setFloat("KnockbackUp", knockbackUp); - - nbt.setBoolean("Explosive", explosive); - nbt.setFloat("ExplosionRadius", explosionRadius); - nbt.setFloat("ExplosionDamageFalloff", explosionDamageFalloff); // Write effects list if (!effects.isEmpty()) { @@ -621,9 +704,7 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA nbt.setTag("Effects", effectsList); } - nbt.setFloat("MaxDistance", maxDistance); nbt.setLong("DeathWorldTime", deathWorldTime); - nbt.setInteger("MaxLifetime", maxLifetime); nbt.setDouble("StartX", startX); nbt.setDouble("StartY", startY); @@ -631,16 +712,18 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA nbt.setInteger("OwnerId", ownerEntityId); nbt.setInteger("TargetId", targetEntityId); + nbt.setInteger("SiblingId", targetEntityId); nbt.setDouble("MotionX", motionX); nbt.setDouble("MotionY", motionY); nbt.setDouble("MotionZ", motionZ); - // Lightning - nbt.setBoolean("LightningEffect", lightningEffect); - nbt.setFloat("LightningDensity", lightningDensity); - nbt.setFloat("LightningRadius", lightningRadius); - nbt.setInteger("LightningFadeTime", lightningFadeTime); + anchorData.writeNBT(nbt); + combatData.writeNBT(nbt); + displayData.writeNBT(nbt); + homingData.writeNBT(nbt); + lifespanData.writeNBT(nbt); + lightningData.writeNBT(nbt); } /** diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java b/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java index 001e7c62a..8eceb11de 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java @@ -74,7 +74,7 @@ public class EntityAbilitySweeper extends Entity implements IEntityAdditionalSpa public EntityAbilitySweeper(World world, EntityLivingBase owner, EntityLivingBase target, float beamLength, float beamWidth, float beamHeight, - EnergyDisplayData colorData, + EnergyDisplayData displayData, float sweepSpeed, int numberOfRotations, float damage, int damageInterval, boolean piercing, boolean lockOnTarget) { @@ -85,10 +85,10 @@ public class EntityAbilitySweeper extends Entity implements IEntityAdditionalSpa this.beamLength = beamLength; this.beamWidth = beamWidth; this.beamHeight = beamHeight; - this.innerColor = colorData.innerColor; - this.outerColor = colorData.outerColor; - this.outerColorEnabled = colorData.outerColorEnabled; - this.outerColorWidth = colorData.outerColorWidth; + this.innerColor = displayData.innerColor; + this.outerColor = displayData.outerColor; + this.outerColorEnabled = displayData.outerColorEnabled; + this.outerColorWidth = displayData.outerColorWidth; this.sweepSpeed = sweepSpeed; this.numberOfRotations = numberOfRotations; this.damage = damage; diff --git a/src/main/java/noppes/npcs/items/ItemStaff.java b/src/main/java/noppes/npcs/items/ItemStaff.java index 75387c58f..eb8b9b181 100644 --- a/src/main/java/noppes/npcs/items/ItemStaff.java +++ b/src/main/java/noppes/npcs/items/ItemStaff.java @@ -109,7 +109,7 @@ public class ItemStaff extends ItemNpcInterface implements IProjectileCallback { EnergyDisplayData colorData = new EnergyDisplayData(getOrbColor(stack, false), getOrbColor(stack, true)); EnergyLightningData lightning = new EnergyLightningData(); EnergyLifespanData lifespan = new EnergyLifespanData(100, 72000); - EnergyTrajectoryData homing = new EnergyTrajectoryData(); + EnergyHomingData homing = new EnergyHomingData(); homing.speed = 0.5f; homing.homingStrength = 0.35f;