diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyColorData.java b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyColorData.java new file mode 100644 index 000000000..4bd841742 --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyColorData.java @@ -0,0 +1,50 @@ +package kamkeel.npcs.controllers.data.ability.data; + +import net.minecraft.nbt.NBTTagCompound; + +/** + * Groups visual color properties shared by all energy abilities. + * Used as a parameter object for entity constructors and ability configuration. + */ +public class EnergyColorData { + public int innerColor = 0xFFFFFF; + public int outerColor = 0x8888FF; + public boolean outerColorEnabled = true; + public float outerColorWidth = 0.4f; + public float outerColorAlpha = 0.5f; + public float rotationSpeed = 4.0f; + + public EnergyColorData() {} + + public EnergyColorData(int innerColor, int outerColor, boolean outerColorEnabled, + float outerColorWidth, float outerColorAlpha, float rotationSpeed) { + this.innerColor = innerColor; + this.outerColor = outerColor; + this.outerColorEnabled = outerColorEnabled; + this.outerColorWidth = outerColorWidth; + this.outerColorAlpha = outerColorAlpha; + this.rotationSpeed = rotationSpeed; + } + + public void writeNBT(NBTTagCompound nbt) { + nbt.setInteger("innerColor", innerColor); + nbt.setInteger("outerColor", outerColor); + nbt.setBoolean("outerColorEnabled", outerColorEnabled); + nbt.setFloat("outerColorWidth", outerColorWidth); + nbt.setFloat("outerColorAlpha", outerColorAlpha); + nbt.setFloat("rotationSpeed", rotationSpeed); + } + + public void readNBT(NBTTagCompound nbt) { + innerColor = nbt.hasKey("innerColor") ? nbt.getInteger("innerColor") : 0xFFFFFF; + outerColor = nbt.hasKey("outerColor") ? nbt.getInteger("outerColor") : 0x8888FF; + outerColorEnabled = !nbt.hasKey("outerColorEnabled") || nbt.getBoolean("outerColorEnabled"); + outerColorWidth = nbt.hasKey("outerColorWidth") ? nbt.getFloat("outerColorWidth") : 0.4f; + outerColorAlpha = nbt.hasKey("outerColorAlpha") ? nbt.getFloat("outerColorAlpha") : 0.5f; + rotationSpeed = nbt.hasKey("rotationSpeed") ? nbt.getFloat("rotationSpeed") : 4.0f; + } + + public EnergyColorData copy() { + return new EnergyColorData(innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed); + } +} diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyCombatData.java b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyCombatData.java new file mode 100644 index 000000000..fa09645a6 --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyCombatData.java @@ -0,0 +1,51 @@ +package kamkeel.npcs.controllers.data.ability.data; + +import net.minecraft.nbt.NBTTagCompound; + +/** + * Groups combat properties shared by energy projectile abilities. + * Used as a parameter object for entity constructors and ability configuration. + */ +public class EnergyCombatData { + public float damage = 7.0f; + public float knockback = 1.0f; + public float knockbackUp = 0.1f; + public boolean explosive = false; + public float explosionRadius = 3.0f; + public float explosionDamageFalloff = 0.5f; + + public EnergyCombatData() {} + + public EnergyCombatData(float damage, float knockback, float knockbackUp, + boolean explosive, float explosionRadius, float explosionDamageFalloff) { + this.damage = damage; + this.knockback = knockback; + this.knockbackUp = knockbackUp; + this.explosive = explosive; + this.explosionRadius = explosionRadius; + this.explosionDamageFalloff = explosionDamageFalloff; + } + + public void writeNBT(NBTTagCompound nbt) { + nbt.setFloat("damage", damage); + nbt.setFloat("knockback", knockback); + nbt.setFloat("knockbackUp", knockbackUp); + nbt.setBoolean("explosive", explosive); + nbt.setFloat("explosionRadius", explosionRadius); + nbt.setFloat("explosionDamageFalloff", explosionDamageFalloff); + } + + public void readNBT(NBTTagCompound nbt) { + damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 7.0f; + knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 1.0f; + knockbackUp = nbt.hasKey("knockbackUp") ? nbt.getFloat("knockbackUp") : 0.1f; + explosive = nbt.hasKey("explosive") && nbt.getBoolean("explosive"); + explosionRadius = nbt.hasKey("explosionRadius") ? nbt.getFloat("explosionRadius") : 3.0f; + explosionDamageFalloff = nbt.hasKey("explosionDamageFalloff") ? nbt.getFloat("explosionDamageFalloff") : 0.5f; + } + + public EnergyCombatData copy() { + return new EnergyCombatData(damage, knockback, knockbackUp, + explosive, explosionRadius, explosionDamageFalloff); + } +} 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..5b90bafce --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyHomingData.java @@ -0,0 +1,41 @@ +package kamkeel.npcs.controllers.data.ability.data; + +import net.minecraft.nbt.NBTTagCompound; + +/** + * Groups homing/movement properties for energy projectile abilities. + * Used by Orb, Disc, and Beam (not Laser or Sweeper). + */ +public class EnergyHomingData { + 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; + } + + 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/EnergyLifespanData.java b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyLifespanData.java new file mode 100644 index 000000000..f8f0122e8 --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyLifespanData.java @@ -0,0 +1,33 @@ +package kamkeel.npcs.controllers.data.ability.data; + +import net.minecraft.nbt.NBTTagCompound; + +/** + * Groups lifespan/range properties for energy projectile abilities. + * Used as a parameter object for entity constructors and ability configuration. + */ +public class EnergyLifespanData { + public float maxDistance = 30.0f; + public int maxLifetime = 200; + + public EnergyLifespanData() {} + + public EnergyLifespanData(float maxDistance, int maxLifetime) { + this.maxDistance = maxDistance; + this.maxLifetime = maxLifetime; + } + + public void writeNBT(NBTTagCompound nbt) { + nbt.setFloat("maxDistance", maxDistance); + nbt.setInteger("maxLifetime", maxLifetime); + } + + public void readNBT(NBTTagCompound nbt) { + maxDistance = nbt.hasKey("maxDistance") ? nbt.getFloat("maxDistance") : 30.0f; + maxLifetime = nbt.hasKey("maxLifetime") ? nbt.getInteger("maxLifetime") : 200; + } + + public EnergyLifespanData copy() { + return new EnergyLifespanData(maxDistance, maxLifetime); + } +} diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyLightningData.java b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyLightningData.java new file mode 100644 index 000000000..30d4ea6d8 --- /dev/null +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/data/EnergyLightningData.java @@ -0,0 +1,42 @@ +package kamkeel.npcs.controllers.data.ability.data; + +import net.minecraft.nbt.NBTTagCompound; + +/** + * Groups lightning visual effect properties for energy abilities. + * Used as a parameter object for entity constructors and ability configuration. + */ +public class EnergyLightningData { + public boolean lightningEffect = false; + public float lightningDensity = 0.15f; + public float lightningRadius = 0.5f; + public int lightningFadeTime = 6; + + public EnergyLightningData() {} + + public EnergyLightningData(boolean lightningEffect, float lightningDensity, + float lightningRadius, int lightningFadeTime) { + this.lightningEffect = lightningEffect; + this.lightningDensity = lightningDensity; + this.lightningRadius = lightningRadius; + this.lightningFadeTime = lightningFadeTime; + } + + public void writeNBT(NBTTagCompound nbt) { + nbt.setBoolean("lightningEffect", lightningEffect); + nbt.setFloat("lightningDensity", lightningDensity); + nbt.setFloat("lightningRadius", lightningRadius); + nbt.setInteger("lightningFadeTime", lightningFadeTime); + } + + public void readNBT(NBTTagCompound nbt) { + lightningEffect = nbt.hasKey("lightningEffect") && nbt.getBoolean("lightningEffect"); + lightningDensity = nbt.hasKey("lightningDensity") ? nbt.getFloat("lightningDensity") : 0.15f; + lightningRadius = nbt.hasKey("lightningRadius") ? nbt.getFloat("lightningRadius") : 0.5f; + lightningFadeTime = nbt.hasKey("lightningFadeTime") ? nbt.getInteger("lightningFadeTime") : 6; + } + + public EnergyLightningData copy() { + return new EnergyLightningData(lightningEffect, lightningDensity, lightningRadius, lightningFadeTime); + } +} 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 e5c15e010..006f6f128 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 @@ -6,14 +6,21 @@ import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.AnchorPoint; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; +import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; +import kamkeel.npcs.controllers.data.ability.data.EnergyCombatData; +import kamkeel.npcs.controllers.data.ability.data.EnergyHomingData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLifespanData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLightningData; import kamkeel.npcs.controllers.data.telegraph.Telegraph; import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import kamkeel.npcs.entity.EntityAbilityDisc; +import kamkeel.npcs.util.AnchorPointHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; +import net.minecraft.util.Vec3; import net.minecraft.world.World; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityDisc; @@ -27,53 +34,24 @@ import noppes.npcs.entity.EntityNPCInterface; */ public class AbilityDisc extends Ability implements IAbilityDisc { - // Movement properties - private float speed = 0.6f; + // Disc geometry private float discRadius = 1.0f; private float discThickness = 0.2f; - private float maxDistance = 35.0f; - private int maxLifetime = 200; - - // Combat properties - private float damage = 8.0f; - private float knockback = 1.2f; - private float knockbackUp = 0.15f; - - // Homing properties - private boolean homing = true; - private float homingStrength = 0.12f; - private float homingRange = 18.0f; // Boomerang properties private boolean boomerang = false; private int boomerangDelay = 40; - // Explosion properties - private boolean explosive = false; - private float explosionRadius = 3.0f; - private float explosionDamageFalloff = 0.5f; - - // Effect properties - private int stunDuration = 0; - private int slowDuration = 0; - private int slowLevel = 0; - - // Visual properties - private int innerColor = 0xFFFFFF; - private int outerColor = 0xFF8800; - private float outerColorWidth = 0.4f; // Additive offset from inner size - private float outerColorAlpha = 0.5f; // Additive offset from inner size - private boolean outerColorEnabled = true; - private float rotationSpeed = 5.0f; - - // Lightning effect properties - private boolean lightningEffect = false; - private float lightningDensity = 0.15f; - private float lightningRadius = 0.5f; - // Anchor point for charging position private AnchorPoint anchorPoint = AnchorPoint.FRONT; + // Energy data classes + private EnergyColorData colorData = new EnergyColorData(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 EnergyHomingData homingData = new EnergyHomingData(0.6f, true, 0.12f, 18.0f); + private EnergyLightningData lightningData = new EnergyLightningData(); + private EnergyLifespanData lifespanData = new EnergyLifespanData(35.0f, 200); + // Transient state for disc entity (used during windup charging) private transient EntityAbilityDisc discEntity = null; @@ -134,20 +112,16 @@ public class AbilityDisc extends Ability implements IAbilityDisc { // Spawn disc in charging mode on first tick of windup if (tick == 1) { // Create disc in charging mode - follows NPC based on anchor point during windup - discEntity = EntityAbilityDisc.createCharging( + Vec3 spawnPos = AnchorPointHelper.calculateAnchorPosition(npc, anchorPoint); + discEntity = new EntityAbilityDisc( world, npc, target, - discRadius, discThickness, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, - speed, homing, homingStrength, homingRange, - boomerang, boomerangDelay, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, - maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius, - anchorPoint, // Anchor point for charging position - windUpTicks // Charge duration = windup duration - ); + spawnPos.xCoord, spawnPos.yCoord, spawnPos.zCoord, + discRadius, discThickness, + colorData, combatData, homingData, lightningData, lifespanData, + boomerang, boomerangDelay); + discEntity.setupCharging(anchorPoint, windUpTicks); + discEntity.setEffects(this.effects); world.spawnEntityInWorld(discEntity); } } @@ -203,127 +177,83 @@ public class AbilityDisc extends Ability implements IAbilityDisc { @Override public void writeTypeNBT(NBTTagCompound nbt) { - nbt.setFloat("speed", speed); nbt.setFloat("discRadius", discRadius); nbt.setFloat("discThickness", discThickness); - nbt.setFloat("maxDistance", maxDistance); - nbt.setInteger("maxLifetime", maxLifetime); - nbt.setFloat("damage", damage); - nbt.setFloat("knockback", knockback); - nbt.setFloat("knockbackUp", knockbackUp); - nbt.setBoolean("homing", homing); - nbt.setFloat("homingStrength", homingStrength); - nbt.setFloat("homingRange", homingRange); nbt.setBoolean("boomerang", boomerang); nbt.setInteger("boomerangDelay", boomerangDelay); - nbt.setBoolean("explosive", explosive); - nbt.setFloat("explosionRadius", explosionRadius); - nbt.setFloat("explosionDamageFalloff", explosionDamageFalloff); - nbt.setInteger("stunDuration", stunDuration); - nbt.setInteger("slowDuration", slowDuration); - nbt.setInteger("slowLevel", slowLevel); - nbt.setInteger("innerColor", innerColor); - nbt.setInteger("outerColor", outerColor); - nbt.setFloat("outerColorWidth", outerColorWidth); - nbt.setFloat("outerColorAlpha", outerColorAlpha); - nbt.setBoolean("outerColorEnabled", outerColorEnabled); - nbt.setFloat("rotationSpeed", rotationSpeed); - nbt.setBoolean("lightningEffect", lightningEffect); - nbt.setFloat("lightningDensity", lightningDensity); - nbt.setFloat("lightningRadius", lightningRadius); nbt.setInteger("anchorPoint", anchorPoint.getId()); + colorData.writeNBT(nbt); + combatData.writeNBT(nbt); + homingData.writeNBT(nbt); + lightningData.writeNBT(nbt); + lifespanData.writeNBT(nbt); } @Override public void readTypeNBT(NBTTagCompound nbt) { - this.speed = nbt.hasKey("speed") ? nbt.getFloat("speed") : 0.6f; this.discRadius = nbt.hasKey("discRadius") ? nbt.getFloat("discRadius") : 1.0f; this.discThickness = nbt.hasKey("discThickness") ? nbt.getFloat("discThickness") : 0.2f; - this.maxDistance = nbt.hasKey("maxDistance") ? nbt.getFloat("maxDistance") : 35.0f; - this.maxLifetime = nbt.hasKey("maxLifetime") ? nbt.getInteger("maxLifetime") : 200; - this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 8.0f; - this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 1.2f; - this.knockbackUp = nbt.hasKey("knockbackUp") ? nbt.getFloat("knockbackUp") : 0.15f; - this.homing = !nbt.hasKey("homing") || nbt.getBoolean("homing"); - this.homingStrength = nbt.hasKey("homingStrength") ? nbt.getFloat("homingStrength") : 0.12f; - this.homingRange = nbt.hasKey("homingRange") ? nbt.getFloat("homingRange") : 18.0f; this.boomerang = nbt.hasKey("boomerang") && nbt.getBoolean("boomerang"); this.boomerangDelay = nbt.hasKey("boomerangDelay") ? nbt.getInteger("boomerangDelay") : 40; - this.explosive = nbt.hasKey("explosive") && nbt.getBoolean("explosive"); - this.explosionRadius = nbt.hasKey("explosionRadius") ? nbt.getFloat("explosionRadius") : 3.0f; - this.explosionDamageFalloff = nbt.hasKey("explosionDamageFalloff") ? nbt.getFloat("explosionDamageFalloff") : 0.5f; - this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0; - this.slowDuration = nbt.hasKey("slowDuration") ? nbt.getInteger("slowDuration") : 0; - this.slowLevel = nbt.hasKey("slowLevel") ? nbt.getInteger("slowLevel") : 0; - this.innerColor = nbt.hasKey("innerColor") ? nbt.getInteger("innerColor") : 0xFFFFFF; - this.outerColor = nbt.hasKey("outerColor") ? nbt.getInteger("outerColor") : 0xFF8800; - this.outerColorWidth = nbt.hasKey("outerColorWidth") ? nbt.getFloat("outerColorWidth") : 0.4f; - this.outerColorAlpha = nbt.hasKey("outerColorAlpha") ? nbt.getFloat("outerColorAlpha") : 0.5f; - this.outerColorEnabled = !nbt.hasKey("outerColorEnabled") || nbt.getBoolean("outerColorEnabled"); - this.rotationSpeed = nbt.hasKey("rotationSpeed") ? nbt.getFloat("rotationSpeed") : 5.0f; - this.lightningEffect = nbt.hasKey("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.anchorPoint = nbt.hasKey("anchorPoint") ? AnchorPoint.fromId(nbt.getInteger("anchorPoint")) : AnchorPoint.FRONT; + colorData.readNBT(nbt); + combatData.readNBT(nbt); + homingData.readNBT(nbt); + lightningData.readNBT(nbt); + lifespanData.readNBT(nbt); } // Getters & Setters - public float getSpeed() { return speed; } - public void setSpeed(float speed) { this.speed = speed; } + public float getSpeed() { return homingData.speed; } + public void setSpeed(float speed) { homingData.speed = speed; } public float getDiscRadius() { return discRadius; } public void setDiscRadius(float discRadius) { this.discRadius = discRadius; } public float getDiscThickness() { return discThickness; } public void setDiscThickness(float discThickness) { this.discThickness = discThickness; } - public float getMaxDistance() { return maxDistance; } - public void setMaxDistance(float maxDistance) { this.maxDistance = maxDistance; } - public int getMaxLifetime() { return maxLifetime; } - public void setMaxLifetime(int maxLifetime) { this.maxLifetime = maxLifetime; } - public float getDamage() { return damage; } - public void setDamage(float damage) { this.damage = damage; } - public float getKnockback() { return knockback; } - public void setKnockback(float knockback) { this.knockback = knockback; } - public float getKnockbackUp() { return knockbackUp; } - public void setKnockbackUp(float knockbackUp) { this.knockbackUp = knockbackUp; } - public boolean isHoming() { return homing; } - public void setHoming(boolean homing) { this.homing = homing; } - public float getHomingStrength() { return homingStrength; } - public void setHomingStrength(float homingStrength) { this.homingStrength = homingStrength; } - public float getHomingRange() { return homingRange; } - public void setHomingRange(float homingRange) { this.homingRange = homingRange; } + public float getMaxDistance() { return lifespanData.maxDistance; } + public void setMaxDistance(float maxDistance) { lifespanData.maxDistance = maxDistance; } + public int getMaxLifetime() { return lifespanData.maxLifetime; } + public void setMaxLifetime(int maxLifetime) { lifespanData.maxLifetime = maxLifetime; } + public float getDamage() { return combatData.damage; } + public void setDamage(float damage) { combatData.damage = damage; } + public float getKnockback() { return combatData.knockback; } + public void setKnockback(float knockback) { combatData.knockback = knockback; } + public float getKnockbackUp() { return combatData.knockbackUp; } + public void setKnockbackUp(float knockbackUp) { combatData.knockbackUp = knockbackUp; } + public boolean isHoming() { return homingData.homing; } + public void setHoming(boolean homing) { homingData.homing = homing; } + public float getHomingStrength() { return homingData.homingStrength; } + public void setHomingStrength(float homingStrength) { homingData.homingStrength = homingStrength; } + public float getHomingRange() { return homingData.homingRange; } + public void setHomingRange(float homingRange) { homingData.homingRange = homingRange; } public boolean isBoomerang() { return boomerang; } public void setBoomerang(boolean boomerang) { this.boomerang = boomerang; } public int getBoomerangDelay() { return boomerangDelay; } public void setBoomerangDelay(int boomerangDelay) { this.boomerangDelay = boomerangDelay; } - public boolean isExplosive() { return explosive; } - public void setExplosive(boolean explosive) { this.explosive = explosive; } - public float getExplosionRadius() { return explosionRadius; } - public void setExplosionRadius(float explosionRadius) { this.explosionRadius = explosionRadius; } - public float getExplosionDamageFalloff() { return explosionDamageFalloff; } - public void setExplosionDamageFalloff(float explosionDamageFalloff) { this.explosionDamageFalloff = explosionDamageFalloff; } - public int getStunDuration() { return stunDuration; } - public void setStunDuration(int stunDuration) { this.stunDuration = stunDuration; } - public int getSlowDuration() { return slowDuration; } - public void setSlowDuration(int slowDuration) { this.slowDuration = slowDuration; } - public int getSlowLevel() { return slowLevel; } - public void setSlowLevel(int slowLevel) { this.slowLevel = slowLevel; } - public int getInnerColor() { return innerColor; } - public void setInnerColor(int innerColor) { this.innerColor = innerColor; } - public int getOuterColor() { return outerColor; } - public void setOuterColor(int outerColor) { this.outerColor = outerColor; } - public float getOuterColorWidth() { return outerColorWidth; } - public void setOuterColorWidth(float outerColorWidth) { this.outerColorWidth = outerColorWidth; } - public float getOuterColorAlpha() { return outerColorAlpha; } - public void setOuterColorAlpha(float outerColorAlpha) { this.outerColorAlpha = outerColorAlpha; } - public boolean isOuterColorEnabled() { return outerColorEnabled; } - public void setOuterColorEnabled(boolean outerColorEnabled) { this.outerColorEnabled = outerColorEnabled; } - public float getRotationSpeed() { return rotationSpeed; } - public void setRotationSpeed(float rotationSpeed) { this.rotationSpeed = rotationSpeed; } - public boolean hasLightningEffect() { return lightningEffect; } - public void setLightningEffect(boolean lightningEffect) { this.lightningEffect = lightningEffect; } - public float getLightningDensity() { return lightningDensity; } - public void setLightningDensity(float lightningDensity) { this.lightningDensity = lightningDensity; } - public float getLightningRadius() { return lightningRadius; } - public void setLightningRadius(float lightningRadius) { this.lightningRadius = lightningRadius; } + public boolean isExplosive() { return combatData.explosive; } + public void setExplosive(boolean explosive) { combatData.explosive = explosive; } + public float getExplosionRadius() { return combatData.explosionRadius; } + public void setExplosionRadius(float explosionRadius) { combatData.explosionRadius = explosionRadius; } + public float getExplosionDamageFalloff() { return combatData.explosionDamageFalloff; } + public void setExplosionDamageFalloff(float explosionDamageFalloff) { combatData.explosionDamageFalloff = explosionDamageFalloff; } + public int getInnerColor() { return colorData.innerColor; } + public void setInnerColor(int innerColor) { colorData.innerColor = innerColor; } + public int getOuterColor() { return colorData.outerColor; } + public void setOuterColor(int outerColor) { colorData.outerColor = outerColor; } + public float getOuterColorWidth() { return colorData.outerColorWidth; } + public void setOuterColorWidth(float outerColorWidth) { colorData.outerColorWidth = outerColorWidth; } + public float getOuterColorAlpha() { return colorData.outerColorAlpha; } + public void setOuterColorAlpha(float outerColorAlpha) { colorData.outerColorAlpha = outerColorAlpha; } + public boolean isOuterColorEnabled() { return colorData.outerColorEnabled; } + public void setOuterColorEnabled(boolean outerColorEnabled) { colorData.outerColorEnabled = outerColorEnabled; } + public float getRotationSpeed() { return colorData.rotationSpeed; } + public void setRotationSpeed(float rotationSpeed) { colorData.rotationSpeed = rotationSpeed; } + public boolean hasLightningEffect() { return lightningData.lightningEffect; } + public void setLightningEffect(boolean lightningEffect) { lightningData.lightningEffect = lightningEffect; } + public float getLightningDensity() { return lightningData.lightningDensity; } + public void setLightningDensity(float lightningDensity) { lightningData.lightningDensity = lightningDensity; } + public float getLightningRadius() { return lightningData.lightningRadius; } + public void setLightningRadius(float lightningRadius) { lightningData.lightningRadius = lightningRadius; } public AnchorPoint getAnchorPointEnum() { return anchorPoint; } public void setAnchorPointEnum(AnchorPoint anchorPoint) { this.anchorPoint = anchorPoint; } @@ -338,17 +268,13 @@ public class AbilityDisc extends Ability implements IAbilityDisc { public Entity createPreviewEntity(EntityNPCInterface npc) { if (npc == null || npc.worldObj == null) return null; - return EntityAbilityDisc.createPreview( - npc.worldObj, npc, - discRadius, discThickness, innerColor, outerColor, - outerColorEnabled, outerColorWidth, rotationSpeed, - lightningEffect, lightningDensity, lightningRadius, - anchorPoint, windUpTicks - ); + EntityAbilityDisc disc = new EntityAbilityDisc(npc.worldObj); + disc.setupPreview(npc, discRadius, discThickness, colorData, lightningData, anchorPoint, windUpTicks); + return disc; } @Override public int getPreviewActiveDuration() { - return maxLifetime > 0 ? Math.min(maxLifetime, 100) : 100; + return lifespanData.maxLifetime > 0 ? Math.min(lifespanData.maxLifetime, 100) : 100; } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java index c2b452339..049c4c281 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java @@ -6,13 +6,20 @@ import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.AnchorPoint; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; +import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; +import kamkeel.npcs.controllers.data.ability.data.EnergyCombatData; +import kamkeel.npcs.controllers.data.ability.data.EnergyHomingData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLightningData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLifespanData; import kamkeel.npcs.controllers.data.telegraph.Telegraph; import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import kamkeel.npcs.entity.EntityAbilityBeam; +import kamkeel.npcs.util.AnchorPointHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.Vec3; import net.minecraft.world.World; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityEnergyBeam; @@ -27,47 +34,16 @@ import noppes.npcs.entity.EntityNPCInterface; */ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam { - // Movement properties - private float speed = 0.4f; - private float maxDistance = 25.0f; - private int maxLifetime = 200; - - // Shape properties + // Shape properties (standalone) private float beamWidth = 0.4f; private float headSize = 0.6f; - // Combat properties - private float damage = 10.0f; - private float knockback = 1.5f; - private float knockbackUp = 0.2f; - - // Homing properties - private boolean homing = true; - private float homingStrength = 0.1f; - private float homingRange = 15.0f; - - // Explosion properties - private boolean explosive = false; - private float explosionRadius = 4.0f; - private float explosionDamageFalloff = 0.5f; - - // Effect properties - private int stunDuration = 0; - private int slowDuration = 0; - private int slowLevel = 0; - - // Visual properties - private int innerColor = 0xFFFFFF; - private int outerColor = 0x00AAFF; - private float outerColorWidth = 0.4f; // Additive offset from inner size - private float outerColorAlpha = 0.5f; - private boolean outerColorEnabled = true; - private float rotationSpeed = 6.0f; - - // Lightning effect properties (only on head) - private boolean lightningEffect = false; - private float lightningDensity = 0.15f; - private float lightningRadius = 0.5f; + // Data classes + private EnergyColorData colorData = new EnergyColorData(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 EnergyHomingData homingData = new EnergyHomingData(0.4f, true, 0.1f, 15.0f); + private EnergyLightningData lightningData = new EnergyLightningData(); + private EnergyLifespanData lifespanData = new EnergyLifespanData(25.0f, 200); // Anchor point for charging position private AnchorPoint anchorPoint = AnchorPoint.RIGHT_HAND; @@ -137,21 +113,16 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam { float offsetDist = 1.0f; // Create beam in charging mode - follows NPC based on anchor point during windup - beamEntity = EntityAbilityBeam.createCharging( + Vec3 spawnPos = AnchorPointHelper.calculateAnchorPosition(npc, anchorPoint, offsetDist); + beamEntity = new EntityAbilityBeam( world, npc, target, - beamWidth, headSize, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, - speed, homing, homingStrength, homingRange, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, - maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius, - lockMovement.locksActive(), // Anchored mode during firing - windUpTicks, // Charge duration = windup duration - offsetDist, // Offset distance (used by FRONT anchor) - anchorPoint // Anchor point for charging position - ); + spawnPos.xCoord, spawnPos.yCoord, spawnPos.zCoord, + beamWidth, headSize, + colorData, combatData, homingData, lightningData, lifespanData, + lockMovement.locksActive()); + beamEntity.setupCharging(anchorPoint, windUpTicks, offsetDist); + beamEntity.setEffects(this.effects); world.spawnEntityInWorld(beamEntity); } } @@ -207,120 +178,87 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam { @Override public void writeTypeNBT(NBTTagCompound nbt) { - nbt.setFloat("speed", speed); - nbt.setFloat("maxDistance", maxDistance); - nbt.setInteger("maxLifetime", maxLifetime); nbt.setFloat("beamWidth", beamWidth); nbt.setFloat("headSize", headSize); - nbt.setFloat("damage", damage); - nbt.setFloat("knockback", knockback); - nbt.setFloat("knockbackUp", knockbackUp); - nbt.setBoolean("homing", homing); - nbt.setFloat("homingStrength", homingStrength); - nbt.setFloat("homingRange", homingRange); - nbt.setBoolean("explosive", explosive); - nbt.setFloat("explosionRadius", explosionRadius); - nbt.setFloat("explosionDamageFalloff", explosionDamageFalloff); - nbt.setInteger("stunDuration", stunDuration); - nbt.setInteger("slowDuration", slowDuration); - nbt.setInteger("slowLevel", slowLevel); - nbt.setInteger("innerColor", innerColor); - nbt.setInteger("outerColor", outerColor); - nbt.setFloat("outerColorWidth", outerColorWidth); - nbt.setFloat("outerColorAlpha", outerColorAlpha); - nbt.setBoolean("outerColorEnabled", outerColorEnabled); - nbt.setFloat("rotationSpeed", rotationSpeed); - nbt.setBoolean("lightningEffect", lightningEffect); - nbt.setFloat("lightningDensity", lightningDensity); - nbt.setFloat("lightningRadius", lightningRadius); nbt.setInteger("anchorPoint", anchorPoint.getId()); + colorData.writeNBT(nbt); + combatData.writeNBT(nbt); + homingData.writeNBT(nbt); + lightningData.writeNBT(nbt); + lifespanData.writeNBT(nbt); } @Override public void readTypeNBT(NBTTagCompound nbt) { - this.speed = nbt.hasKey("speed") ? nbt.getFloat("speed") : 0.4f; - this.maxDistance = nbt.hasKey("maxDistance") ? nbt.getFloat("maxDistance") : 25.0f; - this.maxLifetime = nbt.hasKey("maxLifetime") ? nbt.getInteger("maxLifetime") : 200; this.beamWidth = nbt.hasKey("beamWidth") ? nbt.getFloat("beamWidth") : 0.4f; this.headSize = nbt.hasKey("headSize") ? nbt.getFloat("headSize") : 0.6f; - this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 10.0f; - this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 1.5f; - this.knockbackUp = nbt.hasKey("knockbackUp") ? nbt.getFloat("knockbackUp") : 0.2f; - this.homing = !nbt.hasKey("homing") || nbt.getBoolean("homing"); - this.homingStrength = nbt.hasKey("homingStrength") ? nbt.getFloat("homingStrength") : 0.1f; - this.homingRange = nbt.hasKey("homingRange") ? nbt.getFloat("homingRange") : 15.0f; - this.explosive = nbt.hasKey("explosive") && nbt.getBoolean("explosive"); - this.explosionRadius = nbt.hasKey("explosionRadius") ? nbt.getFloat("explosionRadius") : 4.0f; - this.explosionDamageFalloff = nbt.hasKey("explosionDamageFalloff") ? nbt.getFloat("explosionDamageFalloff") : 0.5f; - this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0; - this.slowDuration = nbt.hasKey("slowDuration") ? nbt.getInteger("slowDuration") : 0; - this.slowLevel = nbt.hasKey("slowLevel") ? nbt.getInteger("slowLevel") : 0; - this.innerColor = nbt.hasKey("innerColor") ? nbt.getInteger("innerColor") : 0xFFFFFF; - this.outerColor = nbt.hasKey("outerColor") ? nbt.getInteger("outerColor") : 0x00AAFF; - this.outerColorWidth = nbt.hasKey("outerColorWidth") ? nbt.getFloat("outerColorWidth") : 0.4f; - this.outerColorAlpha = nbt.hasKey("outerColorAlpha") ? nbt.getFloat("outerColorAlpha") : 0.5f; - this.outerColorEnabled = !nbt.hasKey("outerColorEnabled") || nbt.getBoolean("outerColorEnabled"); - this.rotationSpeed = nbt.hasKey("rotationSpeed") ? nbt.getFloat("rotationSpeed") : 6.0f; - this.lightningEffect = nbt.hasKey("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.anchorPoint = nbt.hasKey("anchorPoint") ? AnchorPoint.fromId(nbt.getInteger("anchorPoint")) : AnchorPoint.FRONT; + colorData.readNBT(nbt); + combatData.readNBT(nbt); + homingData.readNBT(nbt); + lightningData.readNBT(nbt); + lifespanData.readNBT(nbt); } - // Getters & Setters - public float getSpeed() { return speed; } - public void setSpeed(float speed) { this.speed = speed; } - public float getMaxDistance() { return maxDistance; } - public void setMaxDistance(float maxDistance) { this.maxDistance = maxDistance; } - public int getMaxLifetime() { return maxLifetime; } - public void setMaxLifetime(int maxLifetime) { this.maxLifetime = maxLifetime; } + // Getters & Setters - Standalone fields public float getBeamWidth() { return beamWidth; } public void setBeamWidth(float beamWidth) { this.beamWidth = beamWidth; } public float getHeadSize() { return headSize; } public void setHeadSize(float headSize) { this.headSize = headSize; } - public float getDamage() { return damage; } - public void setDamage(float damage) { this.damage = damage; } - public float getKnockback() { return knockback; } - public void setKnockback(float knockback) { this.knockback = knockback; } - public float getKnockbackUp() { return knockbackUp; } - public void setKnockbackUp(float knockbackUp) { this.knockbackUp = knockbackUp; } - public boolean isHoming() { return homing; } - public void setHoming(boolean homing) { this.homing = homing; } - public float getHomingStrength() { return homingStrength; } - public void setHomingStrength(float homingStrength) { this.homingStrength = homingStrength; } - public float getHomingRange() { return homingRange; } - public void setHomingRange(float homingRange) { this.homingRange = homingRange; } - public boolean isExplosive() { return explosive; } - public void setExplosive(boolean explosive) { this.explosive = explosive; } - public float getExplosionRadius() { return explosionRadius; } - public void setExplosionRadius(float explosionRadius) { this.explosionRadius = explosionRadius; } - public float getExplosionDamageFalloff() { return explosionDamageFalloff; } - public void setExplosionDamageFalloff(float explosionDamageFalloff) { this.explosionDamageFalloff = explosionDamageFalloff; } - public int getStunDuration() { return stunDuration; } - public void setStunDuration(int stunDuration) { this.stunDuration = stunDuration; } - public int getSlowDuration() { return slowDuration; } - public void setSlowDuration(int slowDuration) { this.slowDuration = slowDuration; } - public int getSlowLevel() { return slowLevel; } - public void setSlowLevel(int slowLevel) { this.slowLevel = slowLevel; } - public int getInnerColor() { return innerColor; } - public void setInnerColor(int innerColor) { this.innerColor = innerColor; } - public int getOuterColor() { return outerColor; } - public void setOuterColor(int outerColor) { this.outerColor = outerColor; } - public float getOuterColorWidth() { return outerColorWidth; } - public void setOuterColorWidth(float outerColorWidth) { this.outerColorWidth = outerColorWidth; } - public float getOuterColorAlpha() { return outerColorAlpha; } - public void setOuterColorAlpha(float outerColorAlpha) { this.outerColorAlpha = outerColorAlpha; } - public boolean isOuterColorEnabled() { return outerColorEnabled; } - public void setOuterColorEnabled(boolean outerColorEnabled) { this.outerColorEnabled = outerColorEnabled; } - public float getRotationSpeed() { return rotationSpeed; } - public void setRotationSpeed(float rotationSpeed) { this.rotationSpeed = rotationSpeed; } - public boolean hasLightningEffect() { return lightningEffect; } - public void setLightningEffect(boolean lightningEffect) { this.lightningEffect = lightningEffect; } - public float getLightningDensity() { return lightningDensity; } - public void setLightningDensity(float lightningDensity) { this.lightningDensity = lightningDensity; } - public float getLightningRadius() { return lightningRadius; } - public void setLightningRadius(float lightningRadius) { this.lightningRadius = lightningRadius; } + // Getters & Setters - Color data + public int getInnerColor() { return colorData.innerColor; } + public void setInnerColor(int innerColor) { this.colorData.innerColor = innerColor; } + public int getOuterColor() { return colorData.outerColor; } + public void setOuterColor(int outerColor) { this.colorData.outerColor = outerColor; } + public boolean isOuterColorEnabled() { return colorData.outerColorEnabled; } + public void setOuterColorEnabled(boolean outerColorEnabled) { this.colorData.outerColorEnabled = outerColorEnabled; } + public float getOuterColorWidth() { return colorData.outerColorWidth; } + public void setOuterColorWidth(float outerColorWidth) { this.colorData.outerColorWidth = outerColorWidth; } + public float getOuterColorAlpha() { return colorData.outerColorAlpha; } + public void setOuterColorAlpha(float outerColorAlpha) { this.colorData.outerColorAlpha = outerColorAlpha; } + public float getRotationSpeed() { return colorData.rotationSpeed; } + public void setRotationSpeed(float rotationSpeed) { this.colorData.rotationSpeed = rotationSpeed; } + + // Getters & Setters - Combat data + public float getDamage() { return combatData.damage; } + public void setDamage(float damage) { this.combatData.damage = damage; } + public float getKnockback() { return combatData.knockback; } + public void setKnockback(float knockback) { this.combatData.knockback = knockback; } + public float getKnockbackUp() { return combatData.knockbackUp; } + public void setKnockbackUp(float knockbackUp) { this.combatData.knockbackUp = knockbackUp; } + public boolean isExplosive() { return combatData.explosive; } + public void setExplosive(boolean explosive) { this.combatData.explosive = explosive; } + public float getExplosionRadius() { return combatData.explosionRadius; } + public void setExplosionRadius(float explosionRadius) { this.combatData.explosionRadius = explosionRadius; } + public float getExplosionDamageFalloff() { return combatData.explosionDamageFalloff; } + public void setExplosionDamageFalloff(float explosionDamageFalloff) { this.combatData.explosionDamageFalloff = explosionDamageFalloff; } + + // Getters & Setters - Homing data + public float getSpeed() { return homingData.speed; } + public void setSpeed(float speed) { this.homingData.speed = speed; } + public boolean isHoming() { return homingData.homing; } + public void setHoming(boolean homing) { this.homingData.homing = homing; } + public float getHomingStrength() { return homingData.homingStrength; } + public void setHomingStrength(float homingStrength) { this.homingData.homingStrength = homingStrength; } + public float getHomingRange() { return homingData.homingRange; } + public void setHomingRange(float homingRange) { this.homingData.homingRange = homingRange; } + + // Getters & Setters - Lightning data + public boolean hasLightningEffect() { return lightningData.lightningEffect; } + public void setLightningEffect(boolean lightningEffect) { this.lightningData.lightningEffect = lightningEffect; } + public float getLightningDensity() { return lightningData.lightningDensity; } + public void setLightningDensity(float lightningDensity) { this.lightningData.lightningDensity = lightningDensity; } + public float getLightningRadius() { return lightningData.lightningRadius; } + public void setLightningRadius(float lightningRadius) { this.lightningData.lightningRadius = lightningRadius; } + + // Getters & Setters - Lifespan data + public float getMaxDistance() { return lifespanData.maxDistance; } + public void setMaxDistance(float maxDistance) { this.lifespanData.maxDistance = maxDistance; } + public int getMaxLifetime() { return lifespanData.maxLifetime; } + public void setMaxLifetime(int maxLifetime) { this.lifespanData.maxLifetime = maxLifetime; } + + // Getters & Setters - Anchor point public AnchorPoint getAnchorPointEnum() { return anchorPoint; } public void setAnchorPointEnum(AnchorPoint anchorPoint) { this.anchorPoint = anchorPoint; } @@ -335,17 +273,13 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam { public Entity createPreviewEntity(EntityNPCInterface npc) { if (npc == null || npc.worldObj == null) return null; - return EntityAbilityBeam.createPreview( - npc.worldObj, npc, - beamWidth, headSize, innerColor, outerColor, - outerColorEnabled, outerColorWidth, rotationSpeed, - lightningEffect, lightningDensity, lightningRadius, - anchorPoint, windUpTicks, 1.0f - ); + EntityAbilityBeam beam = new EntityAbilityBeam(npc.worldObj); + beam.setupPreview(npc, beamWidth, headSize, colorData, lightningData, anchorPoint, windUpTicks, 1.0f); + return beam; } @Override public int getPreviewActiveDuration() { - return maxLifetime > 0 ? Math.min(maxLifetime, 100) : 100; + return lifespanData.maxLifetime > 0 ? Math.min(lifespanData.maxLifetime, 100) : 100; } } 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 c1a94e657..3a25b9aa4 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 @@ -5,6 +5,10 @@ import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; +import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; +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.telegraph.TelegraphType; import kamkeel.npcs.entity.EntityAbilityLaser; import net.minecraft.entity.Entity; @@ -28,35 +32,12 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot { private float laserWidth = 0.3f; private float expansionSpeed = 3.0f; private int lingerTicks = 8; - private float maxDistance = 40.0f; - private int maxLifetime = 100; - // Combat properties - private float damage = 6.0f; - private float knockback = 0.5f; - private float knockbackUp = 0.05f; - - // Explosion properties - private boolean explosive = false; - private float explosionRadius = 2.0f; - private float explosionDamageFalloff = 0.5f; - - // Effect properties - private int stunDuration = 0; - private int slowDuration = 0; - private int slowLevel = 0; - - // Visual properties - private int innerColor = 0xFFFFFF; - private int outerColor = 0xFF0000; - private float outerColorWidth = 0.4f; // Additive offset from inner width - private float outerColorAlpha = 0.5f; - private boolean outerColorEnabled = true; - - // Lightning effect properties - private boolean lightningEffect = false; - private float lightningDensity = 0.15f; - private float lightningRadius = 0.5f; + // Data classes + private EnergyColorData colorData = new EnergyColorData(0xFFFFFF, 0xFF0000, true, 0.4f, 0.5f, 0.0f); + private EnergyCombatData combatData = new EnergyCombatData(6.0f, 0.5f, 0.05f, false, 2.0f, 0.5f); + private EnergyLightningData lightningData = new EnergyLightningData(); + private EnergyLifespanData lifespanData = new EnergyLifespanData(40.0f, 100); // Transient state for laser entity (used for movement locking) private transient EntityAbilityLaser laserEntity = null; @@ -97,7 +78,7 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot { @Override public float getTelegraphLength() { - return maxDistance; + return lifespanData.maxDistance; } @Override @@ -119,15 +100,12 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot { laserEntity = new EntityAbilityLaser( world, npc, target, spawnX, spawnY, spawnZ, - laserWidth, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, - damage, knockback, knockbackUp, - expansionSpeed, lingerTicks, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, - maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius + laserWidth, + colorData, combatData, lightningData, lifespanData, + expansionSpeed, lingerTicks ); + laserEntity.setEffects(this.effects); world.spawnEntityInWorld(laserEntity); // Ability stays active until entity dies (prevents firing another while projectile is alive) @@ -165,25 +143,10 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot { nbt.setFloat("laserWidth", laserWidth); nbt.setFloat("expansionSpeed", expansionSpeed); nbt.setInteger("lingerTicks", lingerTicks); - nbt.setFloat("maxDistance", maxDistance); - nbt.setInteger("maxLifetime", maxLifetime); - nbt.setFloat("damage", damage); - nbt.setFloat("knockback", knockback); - nbt.setFloat("knockbackUp", knockbackUp); - nbt.setBoolean("explosive", explosive); - nbt.setFloat("explosionRadius", explosionRadius); - nbt.setFloat("explosionDamageFalloff", explosionDamageFalloff); - nbt.setInteger("stunDuration", stunDuration); - nbt.setInteger("slowDuration", slowDuration); - nbt.setInteger("slowLevel", slowLevel); - nbt.setInteger("innerColor", innerColor); - nbt.setInteger("outerColor", outerColor); - nbt.setFloat("outerColorWidth", outerColorWidth); - nbt.setFloat("outerColorAlpha", outerColorAlpha); - nbt.setBoolean("outerColorEnabled", outerColorEnabled); - nbt.setBoolean("lightningEffect", lightningEffect); - nbt.setFloat("lightningDensity", lightningDensity); - nbt.setFloat("lightningRadius", lightningRadius); + colorData.writeNBT(nbt); + combatData.writeNBT(nbt); + lightningData.writeNBT(nbt); + lifespanData.writeNBT(nbt); } @Override @@ -191,90 +154,72 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot { this.laserWidth = nbt.hasKey("laserWidth") ? nbt.getFloat("laserWidth") : 0.3f; this.expansionSpeed = nbt.hasKey("expansionSpeed") ? nbt.getFloat("expansionSpeed") : 3.0f; this.lingerTicks = nbt.hasKey("lingerTicks") ? nbt.getInteger("lingerTicks") : 8; - this.maxDistance = nbt.hasKey("maxDistance") ? nbt.getFloat("maxDistance") : 40.0f; - this.maxLifetime = nbt.hasKey("maxLifetime") ? nbt.getInteger("maxLifetime") : 100; - this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 6.0f; - this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 0.5f; - this.knockbackUp = nbt.hasKey("knockbackUp") ? nbt.getFloat("knockbackUp") : 0.05f; - this.explosive = nbt.hasKey("explosive") && nbt.getBoolean("explosive"); - this.explosionRadius = nbt.hasKey("explosionRadius") ? nbt.getFloat("explosionRadius") : 2.0f; - this.explosionDamageFalloff = nbt.hasKey("explosionDamageFalloff") ? nbt.getFloat("explosionDamageFalloff") : 0.5f; - this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0; - this.slowDuration = nbt.hasKey("slowDuration") ? nbt.getInteger("slowDuration") : 0; - this.slowLevel = nbt.hasKey("slowLevel") ? nbt.getInteger("slowLevel") : 0; - this.innerColor = nbt.hasKey("innerColor") ? nbt.getInteger("innerColor") : 0xFFFFFF; - this.outerColor = nbt.hasKey("outerColor") ? nbt.getInteger("outerColor") : 0xFF0000; - this.outerColorWidth = nbt.hasKey("outerColorWidth") ? nbt.getFloat("outerColorWidth") : 0.4f; - this.outerColorAlpha = nbt.hasKey("outerColorAlpha") ? nbt.getFloat("outerColorAlpha") : 0.5f; - this.outerColorEnabled = !nbt.hasKey("outerColorEnabled") || nbt.getBoolean("outerColorEnabled"); - this.lightningEffect = nbt.hasKey("lightningEffect") && nbt.getBoolean("lightningEffect"); - this.lightningDensity = nbt.hasKey("lightningDensity") ? nbt.getFloat("lightningDensity") : 0.15f; - this.lightningRadius = nbt.hasKey("lightningRadius") ? nbt.getFloat("lightningRadius") : 0.5f; + colorData.readNBT(nbt); + combatData.readNBT(nbt); + lightningData.readNBT(nbt); + lifespanData.readNBT(nbt); } - // Getters & Setters + // Getters & Setters - Standalone fields public float getLaserWidth() { return laserWidth; } public void setLaserWidth(float laserWidth) { this.laserWidth = laserWidth; } public float getExpansionSpeed() { return expansionSpeed; } public void setExpansionSpeed(float expansionSpeed) { this.expansionSpeed = expansionSpeed; } public int getLingerTicks() { return lingerTicks; } public void setLingerTicks(int lingerTicks) { this.lingerTicks = lingerTicks; } - public float getMaxDistance() { return maxDistance; } - public void setMaxDistance(float maxDistance) { this.maxDistance = maxDistance; } - public int getMaxLifetime() { return maxLifetime; } - public void setMaxLifetime(int maxLifetime) { this.maxLifetime = maxLifetime; } - public float getDamage() { return damage; } - public void setDamage(float damage) { this.damage = damage; } - public float getKnockback() { return knockback; } - public void setKnockback(float knockback) { this.knockback = knockback; } - public float getKnockbackUp() { return knockbackUp; } - public void setKnockbackUp(float knockbackUp) { this.knockbackUp = knockbackUp; } - public boolean isExplosive() { return explosive; } - public void setExplosive(boolean explosive) { this.explosive = explosive; } - public float getExplosionRadius() { return explosionRadius; } - public void setExplosionRadius(float explosionRadius) { this.explosionRadius = explosionRadius; } - public float getExplosionDamageFalloff() { return explosionDamageFalloff; } - public void setExplosionDamageFalloff(float explosionDamageFalloff) { this.explosionDamageFalloff = explosionDamageFalloff; } - public int getStunDuration() { return stunDuration; } - public void setStunDuration(int stunDuration) { this.stunDuration = stunDuration; } - public int getSlowDuration() { return slowDuration; } - public void setSlowDuration(int slowDuration) { this.slowDuration = slowDuration; } - public int getSlowLevel() { return slowLevel; } - public void setSlowLevel(int slowLevel) { this.slowLevel = slowLevel; } - public int getInnerColor() { return innerColor; } - public void setInnerColor(int innerColor) { this.innerColor = innerColor; } - public int getOuterColor() { return outerColor; } - public void setOuterColor(int outerColor) { this.outerColor = outerColor; } - public float getOuterColorWidth() { return outerColorWidth; } - public void setOuterColorWidth(float outerColorWidth) { this.outerColorWidth = outerColorWidth; } - public float getOuterColorAlpha() { return outerColorAlpha; } - public void setOuterColorAlpha(float outerColorAlpha) { this.outerColorAlpha = outerColorAlpha; } - public boolean isOuterColorEnabled() { return outerColorEnabled; } - public void setOuterColorEnabled(boolean outerColorEnabled) { this.outerColorEnabled = outerColorEnabled; } - public boolean hasLightningEffect() { return lightningEffect; } - public void setLightningEffect(boolean lightningEffect) { this.lightningEffect = lightningEffect; } - public float getLightningDensity() { return lightningDensity; } - public void setLightningDensity(float lightningDensity) { this.lightningDensity = lightningDensity; } - public float getLightningRadius() { return lightningRadius; } - public void setLightningRadius(float lightningRadius) { this.lightningRadius = lightningRadius; } + + // Getters & Setters - Lifespan data + public float getMaxDistance() { return lifespanData.maxDistance; } + public void setMaxDistance(float maxDistance) { this.lifespanData.maxDistance = maxDistance; } + public int getMaxLifetime() { return lifespanData.maxLifetime; } + public void setMaxLifetime(int maxLifetime) { this.lifespanData.maxLifetime = maxLifetime; } + + // Getters & Setters - Combat data + public float getDamage() { return combatData.damage; } + public void setDamage(float damage) { this.combatData.damage = damage; } + public float getKnockback() { return combatData.knockback; } + public void setKnockback(float knockback) { this.combatData.knockback = knockback; } + public float getKnockbackUp() { return combatData.knockbackUp; } + public void setKnockbackUp(float knockbackUp) { this.combatData.knockbackUp = knockbackUp; } + public boolean isExplosive() { return combatData.explosive; } + public void setExplosive(boolean explosive) { this.combatData.explosive = explosive; } + public float getExplosionRadius() { return combatData.explosionRadius; } + public void setExplosionRadius(float explosionRadius) { this.combatData.explosionRadius = explosionRadius; } + public float getExplosionDamageFalloff() { return combatData.explosionDamageFalloff; } + public void setExplosionDamageFalloff(float explosionDamageFalloff) { this.combatData.explosionDamageFalloff = explosionDamageFalloff; } + // Getters & Setters - Color data + public int getInnerColor() { return colorData.innerColor; } + public void setInnerColor(int innerColor) { this.colorData.innerColor = innerColor; } + public int getOuterColor() { return colorData.outerColor; } + public void setOuterColor(int outerColor) { this.colorData.outerColor = outerColor; } + public float getOuterColorWidth() { return colorData.outerColorWidth; } + public void setOuterColorWidth(float outerColorWidth) { this.colorData.outerColorWidth = outerColorWidth; } + public float getOuterColorAlpha() { return colorData.outerColorAlpha; } + public void setOuterColorAlpha(float outerColorAlpha) { this.colorData.outerColorAlpha = outerColorAlpha; } + public boolean isOuterColorEnabled() { return colorData.outerColorEnabled; } + public void setOuterColorEnabled(boolean outerColorEnabled) { this.colorData.outerColorEnabled = outerColorEnabled; } + + // Getters & Setters - Lightning data + public boolean hasLightningEffect() { return lightningData.lightningEffect; } + public void setLightningEffect(boolean lightningEffect) { this.lightningData.lightningEffect = lightningEffect; } + public float getLightningDensity() { return lightningData.lightningDensity; } + public void setLightningDensity(float lightningDensity) { this.lightningData.lightningDensity = lightningDensity; } + public float getLightningRadius() { return lightningData.lightningRadius; } + public void setLightningRadius(float lightningRadius) { this.lightningData.lightningRadius = lightningRadius; } @Override @SideOnly(Side.CLIENT) public Entity createPreviewEntity(EntityNPCInterface npc) { if (npc == null || npc.worldObj == null) return null; - return EntityAbilityLaser.createPreview( - npc.worldObj, npc, - laserWidth, innerColor, outerColor, - outerColorEnabled, outerColorWidth, - expansionSpeed, maxDistance, - lightningEffect, lightningDensity, lightningRadius - ); + EntityAbilityLaser laser = new EntityAbilityLaser(npc.worldObj); + laser.setupPreview(npc, laserWidth, colorData, lightningData, expansionSpeed, lifespanData.maxDistance); + return laser; } @Override public int getPreviewActiveDuration() { - return maxLifetime > 0 ? Math.min(maxLifetime, 60) : 60; + return lifespanData.maxLifetime > 0 ? Math.min(lifespanData.maxLifetime, 60) : 60; } @Override 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 13c57478a..6c7e8c5b6 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 @@ -6,14 +6,21 @@ import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.AnchorPoint; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; +import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; +import kamkeel.npcs.controllers.data.ability.data.EnergyCombatData; +import kamkeel.npcs.controllers.data.ability.data.EnergyHomingData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLightningData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLifespanData; import kamkeel.npcs.controllers.data.telegraph.Telegraph; import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import kamkeel.npcs.entity.EntityAbilityOrb; +import kamkeel.npcs.util.AnchorPointHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; +import net.minecraft.util.Vec3; import net.minecraft.world.World; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityOrb; @@ -28,49 +35,19 @@ import noppes.npcs.entity.EntityNPCInterface; */ public class AbilityOrb extends Ability implements IAbilityOrb { - // Movement properties - private float orbSpeed = 0.5f; + // Ability-specific properties private float orbSize = 1.0f; - private float maxDistance = 30.0f; // Max distance before orb dies - private int maxLifetime = 200; // Ticks the orb lives - - // Combat properties - private float damage = 7.0f; - private float knockback = 1.0f; - private float knockbackUp = 0.1f; - - // Homing properties - private boolean homing = true; - private float homingStrength = 0.15f; - private float homingRange = 20.0f; - - // Explosion properties - private boolean explosive = false; - private float explosionRadius = 3.0f; - private float explosionDamageFalloff = 0.5f; - - // Effect properties - private int stunDuration = 0; - private int slowDuration = 0; - private int slowLevel = 0; - - // Visual properties - private int innerColor = 0xFFFFFF; // White core - private int outerColor = 0x8888FF; // Light blue glow - private float outerColorWidth = 0.4f; // Additive offset from inner size - private float outerColorAlpha = 0.5f; - private boolean outerColorEnabled = true; // Whether to render outer glow - private float rotationSpeed = 4.0f; // Degrees per tick - - // Lightning effect properties - private boolean lightningEffect = false; - private float lightningDensity = 0.15f; // Bolts spawned per tick (0.15 = ~15% chance per frame) - private float lightningRadius = 0.5f; // Max distance lightning arcs - scales with orbSize - private int lightningFadeTime = 6; // Ticks before lightning fades out // Anchor point for charging position private AnchorPoint anchorPoint = AnchorPoint.RIGHT_HAND; + // Data classes for energy properties + public final EnergyColorData colorData = new EnergyColorData(); + public final EnergyCombatData combatData = new EnergyCombatData(); + public final EnergyHomingData homingData = new EnergyHomingData(); + public final EnergyLightningData lightningData = new EnergyLightningData(); + public final EnergyLifespanData lifespanData = new EnergyLifespanData(); + // Transient state for orb entity (used during windup charging) private transient EntityAbilityOrb orbEntity = null; @@ -133,19 +110,14 @@ public class AbilityOrb extends Ability implements IAbilityOrb { // Spawn orb in charging mode on first tick of windup if (tick == 1) { // Create orb in charging mode - follows NPC based on anchor point during windup - orbEntity = EntityAbilityOrb.createCharging( + Vec3 spawnPos = AnchorPointHelper.calculateAnchorPosition(npc, anchorPoint); + orbEntity = new EntityAbilityOrb( world, npc, target, - orbSize, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, - orbSpeed, homing, homingStrength, homingRange, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, - maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius, lightningFadeTime, - anchorPoint, // Anchor point for charging position - windUpTicks // Charge duration = windup duration - ); + spawnPos.xCoord, spawnPos.yCoord, spawnPos.zCoord, orbSize, + colorData, combatData, homingData, lightningData, lifespanData); + orbEntity.setupCharging(anchorPoint, windUpTicks); + orbEntity.setEffects(this.effects); world.spawnEntityInWorld(orbEntity); } } @@ -202,73 +174,39 @@ public class AbilityOrb extends Ability implements IAbilityOrb { @Override public void writeTypeNBT(NBTTagCompound nbt) { - nbt.setFloat("orbSpeed", orbSpeed); nbt.setFloat("orbSize", orbSize); - nbt.setFloat("maxDistance", maxDistance); - nbt.setInteger("maxLifetime", maxLifetime); - nbt.setFloat("damage", damage); - nbt.setFloat("knockback", knockback); - nbt.setFloat("knockbackUp", knockbackUp); - nbt.setBoolean("homing", homing); - nbt.setFloat("homingStrength", homingStrength); - nbt.setFloat("homingRange", homingRange); - nbt.setBoolean("explosive", explosive); - nbt.setFloat("explosionRadius", explosionRadius); - nbt.setFloat("explosionDamageFalloff", explosionDamageFalloff); - nbt.setInteger("stunDuration", stunDuration); - nbt.setInteger("slowDuration", slowDuration); - nbt.setInteger("slowLevel", slowLevel); - nbt.setInteger("innerColor", innerColor); - nbt.setInteger("outerColor", outerColor); - nbt.setFloat("outerColorWidth", outerColorWidth); - nbt.setFloat("outerColorAlpha", outerColorAlpha); - nbt.setBoolean("outerColorEnabled", outerColorEnabled); - nbt.setFloat("rotationSpeed", rotationSpeed); - nbt.setBoolean("lightningEffect", lightningEffect); - nbt.setFloat("lightningDensity", lightningDensity); - nbt.setFloat("lightningRadius", lightningRadius); - nbt.setInteger("lightningFadeTime", lightningFadeTime); nbt.setInteger("anchorPoint", anchorPoint.getId()); + colorData.writeNBT(nbt); + combatData.writeNBT(nbt); + homingData.writeNBT(nbt); + lightningData.writeNBT(nbt); + lifespanData.writeNBT(nbt); + // Backward compat: old key was "orbSpeed" + nbt.setFloat("orbSpeed", homingData.speed); } @Override public void readTypeNBT(NBTTagCompound nbt) { - this.orbSpeed = nbt.hasKey("orbSpeed") ? nbt.getFloat("orbSpeed") : 0.5f; this.orbSize = nbt.hasKey("orbSize") ? nbt.getFloat("orbSize") : 1.0f; - this.maxDistance = nbt.hasKey("maxDistance") ? nbt.getFloat("maxDistance") : 30.0f; - this.maxLifetime = nbt.hasKey("maxLifetime") ? nbt.getInteger("maxLifetime") : 200; - this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 7.0f; - this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 1.0f; - this.knockbackUp = nbt.hasKey("knockbackUp") ? nbt.getFloat("knockbackUp") : 0.1f; - 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.explosive = nbt.hasKey("explosive") && nbt.getBoolean("explosive"); - this.explosionRadius = nbt.hasKey("explosionRadius") ? nbt.getFloat("explosionRadius") : 3.0f; - this.explosionDamageFalloff = nbt.hasKey("explosionDamageFalloff") ? nbt.getFloat("explosionDamageFalloff") : 0.5f; - this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0; - this.slowDuration = nbt.hasKey("slowDuration") ? nbt.getInteger("slowDuration") : 0; - this.slowLevel = nbt.hasKey("slowLevel") ? nbt.getInteger("slowLevel") : 0; - this.innerColor = nbt.hasKey("innerColor") ? nbt.getInteger("innerColor") : 0xFFFFFF; - this.outerColor = nbt.hasKey("outerColor") ? nbt.getInteger("outerColor") : 0x8888FF; - this.outerColorWidth = nbt.hasKey("outerColorWidth") ? nbt.getFloat("outerColorWidth") : 0.4f; - this.outerColorAlpha = nbt.hasKey("outerColorAlpha") ? nbt.getFloat("outerColorAlpha") : 0.5f; - this.outerColorEnabled = !nbt.hasKey("outerColorEnabled") || nbt.getBoolean("outerColorEnabled"); - this.rotationSpeed = nbt.hasKey("rotationSpeed") ? nbt.getFloat("rotationSpeed") : 4.0f; - this.lightningEffect = nbt.hasKey("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; this.anchorPoint = nbt.hasKey("anchorPoint") ? AnchorPoint.fromId(nbt.getInteger("anchorPoint")) : AnchorPoint.FRONT; + colorData.readNBT(nbt); + combatData.readNBT(nbt); + homingData.readNBT(nbt); + lightningData.readNBT(nbt); + lifespanData.readNBT(nbt); + // Backward compat: old key was "orbSpeed" + if (nbt.hasKey("orbSpeed")) { + homingData.speed = nbt.getFloat("orbSpeed"); + } } // Getters & Setters public float getOrbSpeed() { - return orbSpeed; + return homingData.speed; } public void setOrbSpeed(float orbSpeed) { - this.orbSpeed = orbSpeed; + homingData.speed = orbSpeed; } public float getOrbSize() { @@ -280,195 +218,171 @@ public class AbilityOrb extends Ability implements IAbilityOrb { } public float getMaxDistance() { - return maxDistance; + return lifespanData.maxDistance; } public void setMaxDistance(float maxDistance) { - this.maxDistance = maxDistance; + lifespanData.maxDistance = maxDistance; } public int getMaxLifetime() { - return maxLifetime; + return lifespanData.maxLifetime; } public void setMaxLifetime(int maxLifetime) { - this.maxLifetime = maxLifetime; + lifespanData.maxLifetime = maxLifetime; } public float getDamage() { - return damage; + return combatData.damage; } public void setDamage(float damage) { - this.damage = damage; + combatData.damage = damage; } public float getKnockback() { - return knockback; + return combatData.knockback; } public void setKnockback(float knockback) { - this.knockback = knockback; + combatData.knockback = knockback; } public float getKnockbackUp() { - return knockbackUp; + return combatData.knockbackUp; } public void setKnockbackUp(float knockbackUp) { - this.knockbackUp = knockbackUp; + combatData.knockbackUp = knockbackUp; } public boolean isHoming() { - return homing; + return homingData.homing; } public void setHoming(boolean homing) { - this.homing = homing; + homingData.homing = homing; } public float getHomingStrength() { - return homingStrength; + return homingData.homingStrength; } public void setHomingStrength(float homingStrength) { - this.homingStrength = homingStrength; + homingData.homingStrength = homingStrength; } public float getHomingRange() { - return homingRange; + return homingData.homingRange; } public void setHomingRange(float homingRange) { - this.homingRange = homingRange; + homingData.homingRange = homingRange; } public boolean isExplosive() { - return explosive; + return combatData.explosive; } public void setExplosive(boolean explosive) { - this.explosive = explosive; + combatData.explosive = explosive; } public float getExplosionRadius() { - return explosionRadius; + return combatData.explosionRadius; } public void setExplosionRadius(float explosionRadius) { - this.explosionRadius = explosionRadius; + combatData.explosionRadius = explosionRadius; } public float getExplosionDamageFalloff() { - return explosionDamageFalloff; + return combatData.explosionDamageFalloff; } public void setExplosionDamageFalloff(float explosionDamageFalloff) { - this.explosionDamageFalloff = explosionDamageFalloff; - } - - public int getStunDuration() { - return stunDuration; - } - - public void setStunDuration(int stunDuration) { - this.stunDuration = stunDuration; - } - - public int getSlowDuration() { - return slowDuration; - } - - public void setSlowDuration(int slowDuration) { - this.slowDuration = slowDuration; - } - - public int getSlowLevel() { - return slowLevel; - } - - public void setSlowLevel(int slowLevel) { - this.slowLevel = slowLevel; + combatData.explosionDamageFalloff = explosionDamageFalloff; } public int getInnerColor() { - return innerColor; + return colorData.innerColor; } public void setInnerColor(int innerColor) { - this.innerColor = innerColor; + colorData.innerColor = innerColor; } public int getOuterColor() { - return outerColor; + return colorData.outerColor; } public void setOuterColor(int outerColor) { - this.outerColor = outerColor; + colorData.outerColor = outerColor; } public float getOuterColorWidth() { - return outerColorWidth; + return colorData.outerColorWidth; } public void setOuterColorWidth(float outerColorWidth) { - this.outerColorWidth = outerColorWidth; + colorData.outerColorWidth = outerColorWidth; } public float getOuterColorAlpha() { - return outerColorAlpha; + return colorData.outerColorAlpha; } public void setOuterColorAlpha(float outerColorAlpha) { - this.outerColorAlpha = outerColorAlpha; + colorData.outerColorAlpha = outerColorAlpha; } public boolean isOuterColorEnabled() { - return outerColorEnabled; + return colorData.outerColorEnabled; } public void setOuterColorEnabled(boolean outerColorEnabled) { - this.outerColorEnabled = outerColorEnabled; + colorData.outerColorEnabled = outerColorEnabled; } public float getRotationSpeed() { - return rotationSpeed; + return colorData.rotationSpeed; } public void setRotationSpeed(float rotationSpeed) { - this.rotationSpeed = rotationSpeed; + colorData.rotationSpeed = rotationSpeed; } public boolean hasLightningEffect() { - return lightningEffect; + return lightningData.lightningEffect; } public void setLightningEffect(boolean lightningEffect) { - this.lightningEffect = lightningEffect; + lightningData.lightningEffect = lightningEffect; } public float getLightningDensity() { - return lightningDensity; + return lightningData.lightningDensity; } public void setLightningDensity(float lightningDensity) { - this.lightningDensity = lightningDensity; + lightningData.lightningDensity = lightningDensity; } public float getLightningRadius() { - return lightningRadius; + return lightningData.lightningRadius; } public void setLightningRadius(float lightningRadius) { - this.lightningRadius = lightningRadius; + lightningData.lightningRadius = lightningRadius; } public int getLightningFadeTime() { - return lightningFadeTime; + return lightningData.lightningFadeTime; } public void setLightningFadeTime(int lightningFadeTime) { - this.lightningFadeTime = lightningFadeTime; + lightningData.lightningFadeTime = lightningFadeTime; } public AnchorPoint getAnchorPointEnum() { @@ -493,17 +407,13 @@ public class AbilityOrb extends Ability implements IAbilityOrb { public Entity createPreviewEntity(EntityNPCInterface npc) { if (npc == null || npc.worldObj == null) return null; - return EntityAbilityOrb.createPreview( - npc.worldObj, npc, - orbSize, innerColor, outerColor, - outerColorEnabled, outerColorWidth, rotationSpeed, - lightningEffect, lightningDensity, lightningRadius, lightningFadeTime, - anchorPoint, windUpTicks - ); + EntityAbilityOrb orb = new EntityAbilityOrb(npc.worldObj); + orb.setupPreview(npc, orbSize, colorData, lightningData, anchorPoint, windUpTicks); + return orb; } @Override public int getPreviewActiveDuration() { - return maxLifetime > 0 ? Math.min(maxLifetime, 100) : 100; + return lifespanData.maxLifetime > 0 ? Math.min(lifespanData.maxLifetime, 100) : 100; } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java index a46100c96..46faef9c9 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java @@ -58,7 +58,7 @@ public class AbilitySlam extends Ability implements IAbilitySlam { this.maxRange = 15.0f; this.telegraphType = TelegraphType.CIRCLE; this.windUpSound = "mob.irongolem.throw"; - this.activeSound = "random.explode"; + this.activeSound = ""; } @Override @@ -278,6 +278,9 @@ public class AbilitySlam extends Ability implements IAbilitySlam { if (world.isRemote) return; + // Play slam impact sound on landing + world.playSoundAtEntity(npc, "random.explode", 1.0f, 1.0f); + // Find all entities in radius @SuppressWarnings("unchecked") List entities = world.getEntitiesWithinAABBExcludingEntity( diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java index d2dced201..976d9e44e 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java @@ -5,6 +5,7 @@ import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.Ability; import kamkeel.npcs.controllers.data.ability.LockMovementType; import kamkeel.npcs.controllers.data.ability.TargetingMode; +import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; import kamkeel.npcs.controllers.data.telegraph.Telegraph; import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; @@ -41,10 +42,7 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper { private boolean lockOnTarget = false; // Visual properties - private int innerColor = 0xFF6600; - private int outerColor = 0xFF0000; - private float outerColorWidth = 1.8f; - private boolean outerColorEnabled = true; + private EnergyColorData colorData = new EnergyColorData(0xFF6600, 0xFF0000, true, 1.8f, 0.5f, 0.0f); // Runtime state (transient) private transient EntityAbilitySweeper activeEntity = null; @@ -94,7 +92,7 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper { // Spawn the entity that handles BOTH visuals AND damage activeEntity = new EntityAbilitySweeper(world, npc, target, beamLength, beamWidth, beamHeight, - innerColor, outerColor, outerColorEnabled, outerColorWidth, + colorData, sweepSpeed, numberOfRotations, damage, damageInterval, piercing, lockOnTarget); @@ -163,10 +161,7 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper { nbt.setFloat("sweepSpeed", sweepSpeed); nbt.setInteger("numberOfRotations", numberOfRotations); nbt.setBoolean("lockOnTarget", lockOnTarget); - nbt.setInteger("innerColor", innerColor); - nbt.setInteger("outerColor", outerColor); - nbt.setFloat("outerColorWidth", outerColorWidth); - nbt.setBoolean("outerColorEnabled", outerColorEnabled); + colorData.writeNBT(nbt); } @Override @@ -180,10 +175,7 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper { this.sweepSpeed = nbt.hasKey("sweepSpeed") ? nbt.getFloat("sweepSpeed") : 3.0f; this.numberOfRotations = nbt.hasKey("numberOfRotations") ? nbt.getInteger("numberOfRotations") : 2; this.lockOnTarget = nbt.hasKey("lockOnTarget") && nbt.getBoolean("lockOnTarget"); - this.innerColor = nbt.hasKey("innerColor") ? nbt.getInteger("innerColor") : 0xFF6600; - this.outerColor = nbt.hasKey("outerColor") ? nbt.getInteger("outerColor") : 0xFF0000; - this.outerColorWidth = nbt.hasKey("outerColorWidth") ? nbt.getFloat("outerColorWidth") : 1.8f; - this.outerColorEnabled = !nbt.hasKey("outerColorEnabled") || nbt.getBoolean("outerColorEnabled"); + colorData.readNBT(nbt); } // Getters & Setters @@ -205,12 +197,12 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper { public void setNumberOfRotations(int numberOfRotations) { this.numberOfRotations = numberOfRotations; } public boolean isLockOnTarget() { return lockOnTarget; } public void setLockOnTarget(boolean lockOnTarget) { this.lockOnTarget = lockOnTarget; } - public int getInnerColor() { return innerColor; } - public void setInnerColor(int innerColor) { this.innerColor = innerColor; } - public int getOuterColor() { return outerColor; } - public void setOuterColor(int outerColor) { this.outerColor = outerColor; } - public float getOuterColorWidth() { return outerColorWidth; } - public void setOuterColorWidth(float outerColorWidth) { this.outerColorWidth = outerColorWidth; } - public boolean isOuterColorEnabled() { return outerColorEnabled; } - public void setOuterColorEnabled(boolean outerColorEnabled) { this.outerColorEnabled = outerColorEnabled; } + public int getInnerColor() { return colorData.innerColor; } + public void setInnerColor(int innerColor) { colorData.innerColor = innerColor; } + public int getOuterColor() { return colorData.outerColor; } + public void setOuterColor(int outerColor) { colorData.outerColor = outerColor; } + public float getOuterColorWidth() { return colorData.outerColorWidth; } + public void setOuterColorWidth(float outerColorWidth) { colorData.outerColorWidth = outerColorWidth; } + public boolean isOuterColorEnabled() { return colorData.outerColorEnabled; } + public void setOuterColorEnabled(boolean outerColorEnabled) { colorData.outerColorEnabled = outerColorEnabled; } } diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityBeam.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityBeam.java index c841ee0f9..ca600b84f 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityBeam.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityBeam.java @@ -1,6 +1,11 @@ package kamkeel.npcs.entity; import kamkeel.npcs.controllers.data.ability.AnchorPoint; +import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; +import kamkeel.npcs.controllers.data.ability.data.EnergyCombatData; +import kamkeel.npcs.controllers.data.ability.data.EnergyHomingData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLifespanData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLightningData; import kamkeel.npcs.util.AnchorPointHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -103,79 +108,27 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { } /** - * Full constructor with all parameters (no lightning). - */ - public EntityAbilityBeam(World world, EntityNPCInterface owner, EntityLivingBase target, - double x, double y, double z, - float beamWidth, float headSize, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - float speed, boolean homing, float homingStrength, float homingRange, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime) { - this(world, owner, target, x, y, z, - beamWidth, headSize, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, speed, homing, homingStrength, homingRange, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, maxDistance, maxLifetime, - false, 0.15f, 0.5f); - } - - /** - * Full constructor with all parameters including lightning. - */ - public EntityAbilityBeam(World world, EntityNPCInterface owner, EntityLivingBase target, - double x, double y, double z, - float beamWidth, float headSize, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - float speed, boolean homing, float homingStrength, float homingRange, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime, - boolean lightningEffect, float lightningDensity, float lightningRadius) { - this(world, owner, target, x, y, z, - beamWidth, headSize, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, speed, homing, homingStrength, homingRange, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius, - true); // Default to anchored mode - } - - /** - * Full constructor with all parameters including lightning and anchored mode. + * Full constructor with all parameters using data classes. * @param anchoredMode If true, origin follows owner and tail orb is rendered. * If false, beam is free-moving with trailing length (no tail orb). */ public EntityAbilityBeam(World world, EntityNPCInterface owner, EntityLivingBase target, double x, double y, double z, - float beamWidth, float headSize, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - float speed, boolean homing, float homingStrength, float homingRange, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime, - boolean lightningEffect, float lightningDensity, float lightningRadius, + float beamWidth, float headSize, + EnergyColorData color, EnergyCombatData combat, + EnergyHomingData homing, EnergyLightningData lightning, + EnergyLifespanData lifespan, boolean anchoredMode) { super(world); - // Initialize base properties with lightning - initProjectile(owner, target, x, y, z, - headSize, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, - maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius, 6); + // Initialize base properties via parent + initProjectile(owner, target, x, y, z, headSize, color, combat, lightning, lifespan); - // Beam-specific properties - this.speed = speed; - this.homing = homing; - this.homingStrength = homingStrength; - this.homingRange = homingRange; + // Beam-specific properties from homing data + this.speed = homing.speed; + this.homing = homing.homing; + this.homingStrength = homing.homingStrength; + this.homingRange = homing.homingRange; this.beamWidth = beamWidth; this.headSize = headSize; @@ -195,13 +148,13 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { trailPoints.add(Vec3.createVectorHelper(0, 0, 0)); if (DEBUG_LOGGING && !world.isRemote) { - LogWriter.info("[Beam] Created at origin " + x + ", " + y + ", " + z + " maxDist=" + maxDistance); + LogWriter.info("[Beam] Created at origin " + x + ", " + y + ", " + z + " maxDist=" + lifespan.maxDistance); } // Calculate initial velocity toward target if (target != null) { double dx = target.posX - x; - double dy = (target.posY + target.height * 0.5) - y; + double dy = (target.posY + target.getEyeHeight()) - y; double dz = target.posZ - z; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { @@ -218,118 +171,69 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { } } - /** - * Create a beam in charging mode (for windup phase). - * The beam will grow from 0 to headSize over chargeDuration ticks. - * Position follows the owner based on anchor point. - */ - public static EntityAbilityBeam createCharging(World world, EntityNPCInterface owner, EntityLivingBase target, - float beamWidth, float headSize, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - float speed, boolean homing, float homingStrength, float homingRange, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime, - boolean lightningEffect, float lightningDensity, float lightningRadius, - boolean anchoredMode, int chargeDuration, float chargeOffsetDistance, - AnchorPoint anchorPoint) { - // Calculate initial position based on anchor point - Vec3 spawnPos = AnchorPointHelper.calculateAnchorPosition(owner, anchorPoint, chargeOffsetDistance); - double spawnX = spawnPos.xCoord; - double spawnY = spawnPos.yCoord; - double spawnZ = spawnPos.zCoord; - - EntityAbilityBeam beam = new EntityAbilityBeam( - world, owner, target, - spawnX, spawnY, spawnZ, - beamWidth, headSize, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, speed, homing, homingStrength, homingRange, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius, - anchoredMode); - - // Set charging state (uses data watcher for client sync) - beam.setCharging(true); - beam.chargeDuration = chargeDuration; - beam.chargeTick = 0; - beam.chargeOffsetDistance = chargeOffsetDistance; - beam.anchorPoint = anchorPoint; - - // Non-anchored beams have fading trail (comet effect) - beam.fadeTrail = !anchoredMode; - - // Clear motion while charging - beam.motionX = 0; - beam.motionY = 0; - beam.motionZ = 0; - - return beam; + public void setupCharging(AnchorPoint anchorPoint, int chargeDuration, float chargeOffsetDistance) { + setCharging(true); + this.chargeDuration = chargeDuration; + this.chargeTick = 0; + this.chargeOffsetDistance = chargeOffsetDistance; + this.anchorPoint = anchorPoint; + this.fadeTrail = !attachedToOwner; + this.motionX = 0; + this.motionY = 0; + this.motionZ = 0; } - /** - * Create a beam in preview mode for GUI display. - * Follows anchor point and animations like in the real game. - * Can be fired when transitioning to active phase. - */ - public static EntityAbilityBeam createPreview(World world, EntityNPCInterface owner, - float beamWidth, float headSize, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float rotationSpeed, - boolean lightningEffect, float lightningDensity, float lightningRadius, - AnchorPoint anchorPoint, int chargeDuration, float chargeOffsetDistance) { - EntityAbilityBeam beam = new EntityAbilityBeam(world); - beam.setPreviewMode(true); - beam.setPreviewOwner(owner); + public void setupPreview(EntityNPCInterface owner, float beamWidth, float headSize, EnergyColorData color, EnergyLightningData lightning, AnchorPoint anchorPoint, int chargeDuration, float chargeOffsetDistance) { + this.setPreviewMode(true); + this.setPreviewOwner(owner); // Set visual properties - beam.beamWidth = beamWidth; - beam.headSize = headSize; - beam.size = headSize; - beam.innerColor = innerColor; - beam.outerColor = outerColor; - beam.outerColorEnabled = outerColorEnabled; - beam.outerColorWidth = outerColorWidth; - beam.rotationSpeed = rotationSpeed; - beam.lightningEffect = lightningEffect; - beam.lightningDensity = lightningDensity; - beam.lightningRadius = lightningRadius; + 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; // Set charging state - beam.setCharging(true); - beam.chargeDuration = chargeDuration; - beam.chargeTick = 0; - beam.chargeOffsetDistance = chargeOffsetDistance; - beam.anchorPoint = anchorPoint; + this.setCharging(true); + this.chargeDuration = chargeDuration; + this.chargeTick = 0; + this.chargeOffsetDistance = chargeOffsetDistance; + this.anchorPoint = anchorPoint; // Initial position at anchor point Vec3 pos = AnchorPointHelper.calculateAnchorPosition(owner, anchorPoint, chargeOffsetDistance); - beam.setPosition(pos.xCoord, pos.yCoord, pos.zCoord); - beam.prevPosX = pos.xCoord; - beam.prevPosY = pos.yCoord; - beam.prevPosZ = pos.zCoord; - beam.startX = pos.xCoord; - beam.startY = pos.yCoord; - beam.startZ = pos.zCoord; + this.setPosition(pos.xCoord, pos.yCoord, pos.zCoord); + this.prevPosX = pos.xCoord; + this.prevPosY = pos.yCoord; + this.prevPosZ = pos.zCoord; + this.startX = pos.xCoord; + this.startY = pos.yCoord; + this.startZ = pos.zCoord; // Initialize head offsets - beam.headOffsetX = 0; - beam.headOffsetY = 0; - beam.headOffsetZ = 0; - beam.prevHeadOffsetX = 0; - beam.prevHeadOffsetY = 0; - beam.prevHeadOffsetZ = 0; + this.headOffsetX = 0; + this.headOffsetY = 0; + this.headOffsetZ = 0; + this.prevHeadOffsetX = 0; + this.prevHeadOffsetY = 0; + this.prevHeadOffsetZ = 0; // Attach to owner for anchor following - beam.attachedToOwner = true; - beam.renderTailOrb = true; + this.attachedToOwner = true; + this.renderTailOrb = true; - // Clear motion while charging - beam.motionX = 0; - beam.motionY = 0; - beam.motionZ = 0; - - return beam; + // Clear motion + this.motionX = 0; + this.motionY = 0; + this.motionZ = 0; } /** @@ -406,7 +310,7 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { if (target != null) { double dx = target.posX - startX; - double dy = (target.posY + target.height * 0.5) - startY; + double dy = (target.posY + target.getEyeHeight()) - startY; double dz = target.posZ - startZ; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { @@ -660,7 +564,7 @@ public class EntityAbilityBeam extends EntityAbilityProjectile { double headWorldZ = startZ + headOffsetZ; double dx = target.posX - headWorldX; - double dy = (target.posY + target.height * 0.5) - headWorldY; + double dy = (target.posY + target.getEyeHeight()) - headWorldY; double dz = target.posZ - headWorldZ; double dist = Math.sqrt(dx * dx + dy * dy + dz * dz); diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityDisc.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityDisc.java index e3896a839..20a43a98a 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityDisc.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityDisc.java @@ -1,6 +1,11 @@ package kamkeel.npcs.entity; import kamkeel.npcs.controllers.data.ability.AnchorPoint; +import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; +import kamkeel.npcs.controllers.data.ability.data.EnergyCombatData; +import kamkeel.npcs.controllers.data.ability.data.EnergyHomingData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLifespanData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLightningData; import kamkeel.npcs.util.AnchorPointHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -81,56 +86,25 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { } /** - * Full constructor with all parameters (no lightning). + * Full constructor with all parameters using data classes. */ public EntityAbilityDisc(World world, EntityNPCInterface owner, EntityLivingBase target, double x, double y, double z, - float discRadius, float discThickness, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - float speed, boolean homing, float homingStrength, float homingRange, - boolean boomerang, int boomerangDelay, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime) { - this(world, owner, target, x, y, z, - discRadius, discThickness, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, speed, homing, homingStrength, homingRange, - boomerang, boomerangDelay, explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, maxDistance, maxLifetime, - false, 0.15f, 0.5f); - } - - /** - * Full constructor with all parameters including lightning. - */ - public EntityAbilityDisc(World world, EntityNPCInterface owner, EntityLivingBase target, - double x, double y, double z, - float discRadius, float discThickness, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - float speed, boolean homing, float homingStrength, float homingRange, - boolean boomerang, int boomerangDelay, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime, - boolean lightningEffect, float lightningDensity, float lightningRadius) { + float discRadius, float discThickness, + EnergyColorData color, EnergyCombatData combat, + EnergyHomingData homing, EnergyLightningData lightning, + EnergyLifespanData lifespan, + boolean boomerang, int boomerangDelay) { super(world); - // Initialize base properties with lightning (use discRadius as size for base) - initProjectile(owner, target, x, y, z, - discRadius, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, - maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius, 6); + // Initialize base properties + initProjectile(owner, target, x, y, z, discRadius, color, combat, lightning, lifespan); - // Disc-specific properties - this.speed = speed; - this.homing = homing; - this.homingStrength = homingStrength; - this.homingRange = homingRange; + // Disc-specific properties from homing data + this.speed = homing.speed; + this.homing = homing.homing; + this.homingStrength = homing.homingStrength; + this.homingRange = homing.homingRange; this.boomerang = boomerang; this.boomerangDelay = boomerangDelay; @@ -141,7 +115,7 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { // Calculate initial velocity toward target if (target != null) { double dx = target.posX - x; - double dy = (target.posY + target.height * 0.5) - y; + double dy = (target.posY + target.getEyeHeight()) - y; double dz = target.posZ - z; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { @@ -159,113 +133,73 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { } /** - * Create a disc in charging mode (for windup phase). + * Setup this disc in charging mode (for windup phase). * The disc will grow from 0 to discRadius over chargeDuration ticks. * Position follows the owner based on anchor point. */ - public static EntityAbilityDisc createCharging(World world, EntityNPCInterface owner, EntityLivingBase target, - float discRadius, float discThickness, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - float speed, boolean homing, float homingStrength, float homingRange, - boolean boomerang, int boomerangDelay, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime, - boolean lightningEffect, float lightningDensity, float lightningRadius, - AnchorPoint anchorPoint, int chargeDuration) { - // Calculate initial position based on anchor point - Vec3 spawnPos = AnchorPointHelper.calculateAnchorPosition(owner, anchorPoint); - double spawnX = spawnPos.xCoord; - double spawnY = spawnPos.yCoord; - double spawnZ = spawnPos.zCoord; - - EntityAbilityDisc disc = new EntityAbilityDisc( - world, owner, target, - spawnX, spawnY, spawnZ, - discRadius, discThickness, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, speed, homing, homingStrength, homingRange, - boomerang, boomerangDelay, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius); - - // Set charging state (uses data watcher for client sync) - disc.setCharging(true); - disc.chargeDuration = chargeDuration; - disc.chargeTick = 0; - disc.anchorPoint = anchorPoint; - - // Store target size and start at 0 for grow effect - disc.targetDiscRadius = disc.discRadius; - disc.targetDiscThickness = disc.discThickness; - disc.discRadius = 0.01f; // Start very small - disc.discThickness = 0.01f; - disc.size = 0.01f; // Base size used for rendering - disc.renderCurrentSize = 0.01f; - disc.prevRenderSize = 0.01f; - - // Clear motion while charging - disc.motionX = 0; - disc.motionY = 0; - disc.motionZ = 0; - - return disc; + public void setupCharging(AnchorPoint anchorPoint, int chargeDuration) { + setCharging(true); + this.chargeDuration = chargeDuration; + this.chargeTick = 0; + this.anchorPoint = anchorPoint; + this.targetDiscRadius = this.discRadius; + this.targetDiscThickness = this.discThickness; + this.discRadius = 0.01f; + this.discThickness = 0.01f; + this.size = 0.01f; + this.renderCurrentSize = 0.01f; + this.prevRenderSize = 0.01f; + this.motionX = 0; + this.motionY = 0; + this.motionZ = 0; } /** - * Create a disc in preview mode for GUI display. + * Setup this disc in preview mode for GUI display. * Follows anchor point and animations like in the real game. * Can be fired when transitioning to active phase. */ - public static EntityAbilityDisc createPreview(World world, EntityNPCInterface owner, - float discRadius, float discThickness, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float rotationSpeed, - boolean lightningEffect, float lightningDensity, float lightningRadius, - AnchorPoint anchorPoint, int chargeDuration) { - EntityAbilityDisc disc = new EntityAbilityDisc(world); - disc.setPreviewMode(true); - disc.setPreviewOwner(owner); + public void setupPreview(EntityNPCInterface owner, float discRadius, float discThickness, EnergyColorData color, EnergyLightningData lightning, AnchorPoint anchorPoint, int chargeDuration) { + this.setPreviewMode(true); + this.setPreviewOwner(owner); // Set visual properties - disc.innerColor = innerColor; - disc.outerColor = outerColor; - disc.outerColorEnabled = outerColorEnabled; - disc.outerColorWidth = outerColorWidth; - disc.rotationSpeed = rotationSpeed; - disc.lightningEffect = lightningEffect; - disc.lightningDensity = lightningDensity; - disc.lightningRadius = lightningRadius; + 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; // Set charging state - disc.setCharging(true); - disc.chargeDuration = chargeDuration; - disc.chargeTick = 0; - disc.anchorPoint = anchorPoint; + this.setCharging(true); + this.chargeDuration = chargeDuration; + this.chargeTick = 0; + this.anchorPoint = anchorPoint; // Store target size and start at 0 for grow effect - disc.targetDiscRadius = discRadius; - disc.targetDiscThickness = discThickness; - disc.discRadius = 0.01f; - disc.discThickness = 0.01f; - disc.size = 0.01f; + this.targetDiscRadius = discRadius; + this.targetDiscThickness = discThickness; + this.discRadius = 0.01f; + this.discThickness = 0.01f; + this.size = 0.01f; // Initial position at anchor point Vec3 pos = AnchorPointHelper.calculateAnchorPosition(owner, anchorPoint); - disc.setPosition(pos.xCoord, pos.yCoord, pos.zCoord); - disc.prevPosX = pos.xCoord; - disc.prevPosY = pos.yCoord; - disc.prevPosZ = pos.zCoord; - disc.startX = pos.xCoord; - disc.startY = pos.yCoord; - disc.startZ = pos.zCoord; + this.setPosition(pos.xCoord, pos.yCoord, pos.zCoord); + this.prevPosX = pos.xCoord; + this.prevPosY = pos.yCoord; + this.prevPosZ = pos.zCoord; + this.startX = pos.xCoord; + this.startY = pos.yCoord; + this.startZ = pos.zCoord; - // Clear motion while charging - disc.motionX = 0; - disc.motionY = 0; - disc.motionZ = 0; - - return disc; + // Clear motion + this.motionX = 0; + this.motionY = 0; + this.motionZ = 0; } /** @@ -320,7 +254,7 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { if (target != null) { double dx = target.posX - posX; - double dy = (target.posY + target.height * 0.5) - posY; + double dy = (target.posY + target.getEyeHeight()) - posY; double dz = target.posZ - posZ; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { @@ -447,7 +381,7 @@ public class EntityAbilityDisc extends EntityAbilityProjectile { if (target == null || !target.isEntityAlive()) return; double dx = target.posX - posX; - double dy = (target.posY + target.height * 0.5) - posY; + double dy = (target.posY + target.getEyeHeight()) - posY; double dz = target.posZ - posZ; double dist = Math.sqrt(dx * dx + dy * dy + dz * dz); diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java index ec208e2cf..c45a6ee9e 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityLaser.java @@ -1,5 +1,9 @@ package kamkeel.npcs.entity; +import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; +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 net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; @@ -45,48 +49,19 @@ public class EntityAbilityLaser extends EntityAbilityProjectile { } /** - * Full constructor with all parameters (no lightning). + * Full constructor with all parameters using data classes. */ public EntityAbilityLaser(World world, EntityNPCInterface owner, EntityLivingBase target, double x, double y, double z, - float laserWidth, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, - float damage, float knockback, float knockbackUp, - float expansionSpeed, int lingerTicks, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime) { - this(world, owner, target, x, y, z, - laserWidth, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, - damage, knockback, knockbackUp, expansionSpeed, lingerTicks, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, maxDistance, maxLifetime, - false, 0.15f, 0.5f); - } - - /** - * Full constructor with all parameters including lightning. - */ - public EntityAbilityLaser(World world, EntityNPCInterface owner, EntityLivingBase target, - double x, double y, double z, - float laserWidth, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, - float damage, float knockback, float knockbackUp, - float expansionSpeed, int lingerTicks, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime, - boolean lightningEffect, float lightningDensity, float lightningRadius) { + float laserWidth, + EnergyColorData color, EnergyCombatData combat, + EnergyLightningData lightning, EnergyLifespanData lifespan, + float expansionSpeed, int lingerTicks) { super(world); - // Initialize base properties with lightning - initProjectile(owner, target, x, y, z, - laserWidth, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, 0.0f, // No rotation for laser - damage, knockback, knockbackUp, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, - maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius, 6); + // Initialize base properties (laser doesn't rotate) + initProjectile(owner, target, x, y, z, laserWidth, color, combat, lightning, lifespan); + this.rotationSpeed = 0.0f; // Laser-specific properties this.laserWidth = laserWidth; @@ -96,7 +71,7 @@ public class EntityAbilityLaser extends EntityAbilityProjectile { // Calculate direction toward target or forward if (target != null) { double dx = target.posX - x; - double dy = (target.posY + target.height * 0.5) - y; + double dy = (target.posY + target.getEyeHeight()) - y; double dz = target.posZ - z; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { @@ -349,54 +324,48 @@ public class EntityAbilityLaser extends EntityAbilityProjectile { } /** - * Create a laser in preview mode for GUI display. + * Setup this laser in preview mode for GUI display. * Laser doesn't have charging state - spawns at active phase and fires immediately. */ - public static EntityAbilityLaser createPreview(World world, EntityNPCInterface owner, - float laserWidth, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, - float expansionSpeed, float maxDistance, - boolean lightningEffect, float lightningDensity, float lightningRadius) { - EntityAbilityLaser laser = new EntityAbilityLaser(world); - laser.setPreviewMode(true); - laser.setPreviewOwner(owner); + public void setupPreview(EntityNPCInterface owner, float laserWidth, EnergyColorData color, + EnergyLightningData lightning, float expansionSpeed, float maxDistance) { + this.setPreviewMode(true); + this.setPreviewOwner(owner); // Set visual properties - laser.laserWidth = laserWidth; - laser.size = laserWidth; - laser.innerColor = innerColor; - laser.outerColor = outerColor; - laser.outerColorEnabled = outerColorEnabled; - laser.outerColorWidth = outerColorWidth; - laser.expansionSpeed = expansionSpeed; - laser.maxDistance = Math.min(maxDistance, 5.0f); // Limit for GUI preview - laser.lightningEffect = lightningEffect; - laser.lightningDensity = lightningDensity; - laser.lightningRadius = lightningRadius; + this.laserWidth = laserWidth; + this.size = laserWidth; + this.innerColor = color.innerColor; + this.outerColor = color.outerColor; + this.outerColorEnabled = color.outerColorEnabled; + this.outerColorWidth = color.outerColorWidth; + 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; // Position at chest height double x = owner.posX; double y = owner.posY + owner.height * 0.7; double z = owner.posZ; - laser.setPosition(x, y, z); - laser.prevPosX = x; - laser.prevPosY = y; - laser.prevPosZ = z; - laser.startX = x; - laser.startY = y; - laser.startZ = z; + this.setPosition(x, y, z); + this.prevPosX = x; + this.prevPosY = y; + this.prevPosZ = z; + this.startX = x; + this.startY = y; + this.startZ = z; // Fire in owner's facing direction float yaw = (float) Math.toRadians(owner.rotationYaw); - laser.dirX = -Math.sin(yaw); - laser.dirY = 0; - laser.dirZ = Math.cos(yaw); + this.dirX = -Math.sin(yaw); + this.dirY = 0; + this.dirZ = Math.cos(yaw); // Initialize end point (same as start, will expand) - laser.endX = x; - laser.endY = y; - laser.endZ = z; - - return laser; + this.endX = x; + this.endY = y; + this.endZ = z; } } diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityOrb.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityOrb.java index bad2bc955..2473730c3 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityOrb.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityOrb.java @@ -1,6 +1,11 @@ package kamkeel.npcs.entity; import kamkeel.npcs.controllers.data.ability.AnchorPoint; +import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; +import kamkeel.npcs.controllers.data.ability.data.EnergyCombatData; +import kamkeel.npcs.controllers.data.ability.data.EnergyHomingData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLifespanData; +import kamkeel.npcs.controllers.data.ability.data.EnergyLightningData; import kamkeel.npcs.util.AnchorPointHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -70,181 +75,110 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { } /** - * Full constructor with all parameters. + * Full constructor using data classes for grouped parameters. */ public EntityAbilityOrb(World world, EntityNPCInterface owner, EntityLivingBase target, - double x, double y, double z, - float orbSize, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - float speed, boolean homing, float homingStrength, float homingRange, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime) { - this(world, owner, target, x, y, z, - orbSize, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, - speed, homing, homingStrength, homingRange, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, - maxDistance, maxLifetime, - false, 0.15f, 0.5f, 6); // Default: no lightning, low density, small radius, 6 tick fade - } - - /** - * Full constructor with lightning effect support. - */ - public EntityAbilityOrb(World world, EntityNPCInterface owner, EntityLivingBase target, - double x, double y, double z, - float orbSize, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - float speed, boolean homing, float homingStrength, float homingRange, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime, - boolean lightningEffect, float lightningDensity, float lightningRadius, int lightningFadeTime) { + double x, double y, double z, float orbSize, + EnergyColorData color, EnergyCombatData combat, + EnergyHomingData homing, EnergyLightningData lightning, + EnergyLifespanData lifespan) { super(world); - // Initialize base properties with lightning - initProjectile(owner, target, x, y, z, - orbSize, innerColor, outerColor, outerColorEnabled, outerColorAlpha, outerColorWidth, rotationSpeed, - damage, knockback, knockbackUp, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, - maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius, lightningFadeTime); + // Initialize base properties + initProjectile(owner, target, x, y, z, orbSize, color, combat, lightning, lifespan); // Orb-specific properties - this.speed = speed; - this.homing = homing; - this.homingStrength = homingStrength; - this.homingRange = homingRange; + this.speed = homing.speed; + this.homing = homing.homing; + this.homingStrength = homing.homingStrength; + this.homingRange = homing.homingRange; // Calculate initial velocity toward target if (target != null) { double dx = target.posX - x; - double dy = (target.posY + target.height * 0.5) - y; + double dy = (target.posY + target.getEyeHeight()) - y; 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) * homing.speed; + this.motionY = (dy / len) * homing.speed; + this.motionZ = (dz / len) * homing.speed; } } else { // Fire in NPC's facing direction 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) * homing.speed; + this.motionY = -Math.sin(pitch) * homing.speed; + this.motionZ = Math.cos(yaw) * Math.cos(pitch) * homing.speed; } } /** - * Create an orb in charging mode (for windup phase). + * Setup this orb in charging mode (for windup phase). * The orb will grow from 0 to orbSize over chargeDuration ticks. * Position follows the owner based on anchor point. */ - public static EntityAbilityOrb createCharging(World world, EntityNPCInterface owner, EntityLivingBase target, - float orbSize, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - float speed, boolean homing, float homingStrength, float homingRange, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime, - boolean lightningEffect, float lightningDensity, float lightningRadius, int lightningFadeTime, - AnchorPoint anchorPoint, int chargeDuration) { - // Calculate initial position based on anchor point - Vec3 spawnPos = AnchorPointHelper.calculateAnchorPosition(owner, anchorPoint); - double spawnX = spawnPos.xCoord; - double spawnY = spawnPos.yCoord; - double spawnZ = spawnPos.zCoord; - - EntityAbilityOrb orb = new EntityAbilityOrb( - world, owner, target, - spawnX, spawnY, spawnZ, - orbSize, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, speed, homing, homingStrength, homingRange, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, maxDistance, maxLifetime, - lightningEffect, lightningDensity, lightningRadius, lightningFadeTime); - - // Set charging state (uses data watcher for client sync) - orb.setCharging(true); - orb.chargeDuration = chargeDuration; - orb.chargeTick = 0; - orb.anchorPoint = anchorPoint; - - // Store target size and start at 0 for grow effect - orb.targetSize = orb.size; - orb.size = 0.01f; // Start very small - orb.renderCurrentSize = 0.01f; - orb.prevRenderSize = 0.01f; - - // Clear motion while charging - orb.motionX = 0; - orb.motionY = 0; - orb.motionZ = 0; - - return orb; + public void setupCharging(AnchorPoint anchorPoint, int chargeDuration) { + setCharging(true); + this.chargeDuration = chargeDuration; + this.chargeTick = 0; + this.anchorPoint = anchorPoint; + this.targetSize = this.size; + this.size = 0.01f; + this.renderCurrentSize = 0.01f; + this.prevRenderSize = 0.01f; + this.motionX = 0; + this.motionY = 0; + this.motionZ = 0; } /** - * Create an orb in preview mode for GUI display. + * Setup this orb in preview mode for GUI display. * Follows anchor point and animations like in the real game. * Can be fired when transitioning to active phase. */ - public static EntityAbilityOrb createPreview(World world, EntityNPCInterface owner, - float orbSize, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float rotationSpeed, - boolean lightningEffect, float lightningDensity, float lightningRadius, int lightningFadeTime, - AnchorPoint anchorPoint, int chargeDuration) { - EntityAbilityOrb orb = new EntityAbilityOrb(world); - orb.setPreviewMode(true); - orb.setPreviewOwner(owner); + public void setupPreview(EntityNPCInterface owner, float orbSize, EnergyColorData color, EnergyLightningData lightning, AnchorPoint anchorPoint, int chargeDuration) { + this.setPreviewMode(true); + this.setPreviewOwner(owner); // Set visual properties - orb.innerColor = innerColor; - orb.outerColor = outerColor; - orb.outerColorEnabled = outerColorEnabled; - orb.outerColorWidth = outerColorWidth; - orb.rotationSpeed = rotationSpeed; - orb.lightningEffect = lightningEffect; - orb.lightningDensity = lightningDensity; - orb.lightningRadius = lightningRadius; - orb.lightningFadeTime = lightningFadeTime; + 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; - // Set charging state (like createCharging does) - orb.setCharging(true); - orb.chargeDuration = chargeDuration; - orb.chargeTick = 0; - orb.anchorPoint = anchorPoint; + // Set charging state + this.setCharging(true); + this.chargeDuration = chargeDuration; + this.chargeTick = 0; + this.anchorPoint = anchorPoint; // Store target size and start at 0 for grow effect - orb.targetSize = orbSize; - orb.size = 0.01f; - orb.renderCurrentSize = 0.01f; - orb.prevRenderSize = 0.01f; + this.targetSize = orbSize; + this.size = 0.01f; + this.renderCurrentSize = 0.01f; + this.prevRenderSize = 0.01f; // Initial position at anchor point Vec3 pos = AnchorPointHelper.calculateAnchorPosition(owner, anchorPoint); - orb.setPosition(pos.xCoord, pos.yCoord, pos.zCoord); - orb.prevPosX = pos.xCoord; - orb.prevPosY = pos.yCoord; - orb.prevPosZ = pos.zCoord; - orb.startX = pos.xCoord; - orb.startY = pos.yCoord; - orb.startZ = pos.zCoord; + this.setPosition(pos.xCoord, pos.yCoord, pos.zCoord); + this.prevPosX = pos.xCoord; + this.prevPosY = pos.yCoord; + this.prevPosZ = pos.zCoord; + this.startX = pos.xCoord; + this.startY = pos.yCoord; + this.startZ = pos.zCoord; - // Clear motion while charging - orb.motionX = 0; - orb.motionY = 0; - orb.motionZ = 0; - - return orb; + // Clear motion + this.motionX = 0; + this.motionY = 0; + this.motionZ = 0; } /** @@ -300,7 +234,7 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { if (target != null) { double dx = target.posX - posX; - double dy = (target.posY + target.height * 0.5) - posY; + double dy = (target.posY + target.getEyeHeight()) - posY; double dz = target.posZ - posZ; double len = Math.sqrt(dx * dx + dy * dy + dz * dz); if (len > 0) { @@ -370,7 +304,7 @@ public class EntityAbilityOrb extends EntityAbilityProjectile { if (target == null || !target.isEntityAlive()) return; double dx = target.posX - posX; - double dy = (target.posY + target.height * 0.5) - posY; + double dy = (target.posY + target.getEyeHeight()) - posY; double dz = target.posZ - posZ; double dist = Math.sqrt(dx * dx + dy * dy + dz * dz); diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilityProjectile.java b/src/main/java/kamkeel/npcs/entity/EntityAbilityProjectile.java index 149ffd329..5508ecd94 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilityProjectile.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilityProjectile.java @@ -4,17 +4,22 @@ import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; 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.EnergyColorData; +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 net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.potion.Potion; -import net.minecraft.potion.PotionEffect; +import net.minecraft.nbt.NBTTagList; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.Vec3; import net.minecraft.world.World; import noppes.npcs.NpcDamageSource; import noppes.npcs.entity.EntityNPCInterface; +import java.util.ArrayList; import java.util.List; /** @@ -40,9 +45,7 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA protected float knockbackUp = 0.1f; // ==================== EFFECT PROPERTIES ==================== - protected int stunDuration = 0; - protected int slowDuration = 0; - protected int slowLevel = 0; + protected List effects = new ArrayList<>(); // ==================== EXPLOSION PROPERTIES ==================== protected boolean explosive = false; @@ -96,37 +99,12 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA } /** - * Initialize common properties. Call from subclass constructors. + * Initialize common properties using data classes. Call from subclass constructors. */ protected void initProjectile(EntityNPCInterface owner, EntityLivingBase target, - double x, double y, double z, - float size, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime) { - initProjectile(owner, target, x, y, z, - size, innerColor, outerColor, outerColorEnabled, outerColorWidth, outerColorAlpha, rotationSpeed, - damage, knockback, knockbackUp, - explosive, explosionRadius, explosionDamageFalloff, - stunDuration, slowDuration, slowLevel, - maxDistance, maxLifetime, - false, 0.15f, 0.5f, 6); // Default: no lightning, low density, small radius, 6 tick fade - } - - /** - * Initialize common properties with lightning effect support. - */ - protected void initProjectile(EntityNPCInterface owner, EntityLivingBase target, - double x, double y, double z, - float size, int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, float outerColorAlpha, float rotationSpeed, - float damage, float knockback, float knockbackUp, - boolean explosive, float explosionRadius, float explosionDamageFalloff, - int stunDuration, int slowDuration, int slowLevel, - float maxDistance, int maxLifetime, - boolean lightningEffect, float lightningDensity, float lightningRadius, int lightningFadeTime) { + double x, double y, double z, float size, + EnergyColorData color, EnergyCombatData combat, + EnergyLightningData lightning, EnergyLifespanData lifespan) { this.setPosition(x, y, z); this.startX = x; this.startY = y; @@ -137,38 +115,33 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA // Visual this.size = size; - this.innerColor = innerColor; - this.outerColor = outerColor; - this.outerColorEnabled = outerColorEnabled; - this.outerColorWidth = outerColorWidth; - this.outerColorAlpha = outerColorAlpha; - this.rotationSpeed = rotationSpeed; + 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 = damage; - this.knockback = knockback; - this.knockbackUp = knockbackUp; + this.damage = combat.damage; + this.knockback = combat.knockback; + this.knockbackUp = combat.knockbackUp; // Explosion - this.explosive = explosive; - this.explosionRadius = explosionRadius; - this.explosionDamageFalloff = explosionDamageFalloff; - - // Effects - this.stunDuration = stunDuration; - this.slowDuration = slowDuration; - this.slowLevel = slowLevel; + this.explosive = combat.explosive; + this.explosionRadius = combat.explosionRadius; + this.explosionDamageFalloff = combat.explosionDamageFalloff; // Lifespan - this.maxDistance = maxDistance; - this.maxLifetime = maxLifetime; + this.maxDistance = lifespan.maxDistance; + this.maxLifetime = lifespan.maxLifetime; // deathWorldTime will be set on first tick when world is available // Lightning - this.lightningEffect = lightningEffect; - this.lightningDensity = lightningDensity; - this.lightningRadius = lightningRadius; - this.lightningFadeTime = lightningFadeTime; + this.lightningEffect = lightning.lightningEffect; + this.lightningDensity = lightning.lightningDensity; + this.lightningRadius = lightning.lightningRadius; + this.lightningFadeTime = lightning.lightningFadeTime; // Initialize render size this.renderCurrentSize = size; @@ -370,15 +343,18 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA } protected void applyEffects(EntityLivingBase target) { - if (stunDuration > 0) { - target.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunDuration, 10)); - target.addPotionEffect(new PotionEffect(Potion.weakness.id, stunDuration, 2)); - } - if (slowDuration > 0 && slowLevel > 0) { - target.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, slowDuration, slowLevel)); + for (AbilityEffect effect : effects) { + effect.apply(target); } } + /** + * Set the effects list from the ability's configured effects. + */ + public void setEffects(List effects) { + this.effects = effects != null ? effects : new ArrayList<>(); + } + protected void doExplosion() { if (previewMode) return; // Skip explosion in preview mode worldObj.playSoundEffect(posX, posY, posZ, "random.explode", 1.0f, 1.0f); @@ -559,9 +535,14 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA this.explosionRadius = nbt.getFloat("ExplosionRadius"); this.explosionDamageFalloff = nbt.getFloat("ExplosionDamageFalloff"); - this.stunDuration = nbt.getInteger("StunDuration"); - this.slowDuration = nbt.getInteger("SlowDuration"); - this.slowLevel = nbt.getInteger("SlowLevel"); + // Read effects list + this.effects.clear(); + if (nbt.hasKey("Effects")) { + NBTTagList effectsList = nbt.getTagList("Effects", 10); // 10 = compound tag + for (int i = 0; i < effectsList.tagCount(); i++) { + effects.add(AbilityEffect.fromNBT(effectsList.getCompoundTagAt(i))); + } + } this.maxDistance = nbt.getFloat("MaxDistance"); this.maxLifetime = nbt.getInteger("MaxLifetime"); @@ -610,9 +591,14 @@ public abstract class EntityAbilityProjectile extends Entity implements IEntityA nbt.setFloat("ExplosionRadius", explosionRadius); nbt.setFloat("ExplosionDamageFalloff", explosionDamageFalloff); - nbt.setInteger("StunDuration", stunDuration); - nbt.setInteger("SlowDuration", slowDuration); - nbt.setInteger("SlowLevel", slowLevel); + // Write effects list + if (!effects.isEmpty()) { + NBTTagList effectsList = new NBTTagList(); + for (AbilityEffect effect : effects) { + effectsList.appendTag(effect.writeNBT()); + } + nbt.setTag("Effects", effectsList); + } nbt.setFloat("MaxDistance", maxDistance); nbt.setLong("DeathWorldTime", deathWorldTime); diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java b/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java index 6ec4f8b38..ffb5f558a 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java @@ -4,6 +4,7 @@ import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; +import kamkeel.npcs.controllers.data.ability.data.EnergyColorData; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; @@ -71,8 +72,7 @@ public class EntityAbilitySweeper extends Entity implements IEntityAdditionalSpa public EntityAbilitySweeper(World world, EntityNPCInterface owner, EntityLivingBase target, float beamLength, float beamWidth, float beamHeight, - int innerColor, int outerColor, - boolean outerColorEnabled, float outerColorWidth, + EnergyColorData colorData, float sweepSpeed, int numberOfRotations, float damage, int damageInterval, boolean piercing, boolean lockOnTarget) { @@ -83,10 +83,10 @@ public class EntityAbilitySweeper extends Entity implements IEntityAdditionalSpa this.beamLength = beamLength; this.beamWidth = beamWidth; this.beamHeight = beamHeight; - this.innerColor = innerColor; - this.outerColor = outerColor; - this.outerColorEnabled = outerColorEnabled; - this.outerColorWidth = outerColorWidth; + this.innerColor = colorData.innerColor; + this.outerColor = colorData.outerColor; + this.outerColorEnabled = colorData.outerColorEnabled; + this.outerColorWidth = colorData.outerColorWidth; this.sweepSpeed = sweepSpeed; this.numberOfRotations = numberOfRotations; this.damage = damage; diff --git a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java index ae292d59d..16389f74d 100644 --- a/src/main/java/noppes/npcs/entity/EntityNPCInterface.java +++ b/src/main/java/noppes/npcs/entity/EntityNPCInterface.java @@ -1934,6 +1934,13 @@ public abstract class EntityNPCInterface extends EntityCreature implements IEnti if (NPCMountUtil.isFlyingMountWithFlightEnabled(this)) { return; } + // Skip fall damage during abilities that control NPC movement (e.g., Slam leap) + if (this.abilities != null && this.abilities.isExecutingAbility() + && this.abilities.getCurrentAbility() != null + && this.abilities.getCurrentAbility().hasAbilityMovement()) { + this.fallDistance = 0; + return; + } if (!this.stats.noFallDamage) super.fall(distance); }