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