Merge branch 'dev' into syntax-highlighter-unified

This commit is contained in:
bigguy345 committed 2026-03-09 06:22:28 +02:00
commit 40cac999c4
16 files changed
+454 -6

No files matched your search

@@ -2660,12 +2660,10 @@ public abstract class Ability implements IAbility, IAbilityAction {
EntityEnergyDome dome = (EntityEnergyDome) barrier;
float radius = dome.getDomeRadius();
// Check if the movement segment crosses the dome boundary from outside
// Check if the movement segment crosses the dome boundary (either direction)
double ocX = caster.posX - dome.posX;
double ocY = eyeY - dome.posY;
double ocZ = caster.posZ - dome.posZ;
double originDistSq = ocX * ocX + ocY * ocY + ocZ * ocZ;
if (originDistSq < (double) radius * radius) continue; // Inside dome, skip
double rdX = nextX - caster.posX;
double rdZ = nextZ - caster.posZ;
@@ -2676,7 +2674,8 @@ public abstract class Ability implements IAbility, IAbilityAction {
if (discriminant < 0 || a < 1e-10) continue;
double sqrtD = Math.sqrt(discriminant);
double t1 = (-b - sqrtD) / (2.0 * a);
if (t1 >= 0.0 && t1 <= 1.0) return true;
double t2 = (-b + sqrtD) / (2.0 * a);
if ((t1 >= 0.0 && t1 <= 1.0) || (t2 >= 0.0 && t2 <= 1.0)) return true;
} else if (barrier instanceof EntityEnergyPanel) {
EntityEnergyPanel panel = (EntityEnergyPanel) barrier;
float halfW = panel.getPanelData().getPanelWidth() * 0.5f;
@@ -736,6 +736,22 @@ public class EntityAbilityBeam extends EntityEnergyProjectile {
setTargetEntityId(-1);
}
// ==================== PROPERTY SYNC ====================
@Override
protected void writeProjectileClientSyncData(NBTTagCompound nbt) {
nbt.setFloat("BeamWidth", beamWidth);
nbt.setFloat("HeadSize", headSize);
nbt.setBoolean("AttachedToOwner", isAttachedToOwner());
}
@Override
protected void applyProjectileClientSyncData(NBTTagCompound nbt) {
beamWidth = nbt.getFloat("BeamWidth");
headSize = nbt.getFloat("HeadSize");
setAttachedToOwner(nbt.getBoolean("AttachedToOwner"));
}
// ==================== NBT ====================
@Override
@@ -432,6 +432,22 @@ public class EntityAbilityDisc extends EntityEnergyProjectile {
returning = nbt.getBoolean("Returning");
}
// ==================== PROPERTY SYNC ====================
@Override
protected void writeProjectileClientSyncData(NBTTagCompound nbt) {
nbt.setFloat("DiscRadius", discRadius);
nbt.setFloat("DiscThickness", discThickness);
nbt.setBoolean("Vertical", vertical);
}
@Override
protected void applyProjectileClientSyncData(NBTTagCompound nbt) {
discRadius = nbt.getFloat("DiscRadius");
discThickness = nbt.getFloat("DiscThickness");
vertical = nbt.getBoolean("Vertical");
}
// ==================== NBT ====================
@Override
@@ -865,6 +865,28 @@ public class EntityAbilityLaser extends EntityEnergyProjectile {
if (nbt.hasKey("MaxLength")) maxLength = nbt.getFloat("MaxLength");
}
// ==================== PROPERTY SYNC ====================
@Override
protected void writeProjectileClientSyncData(NBTTagCompound nbt) {
nbt.setFloat("LaserWidth", laserWidth);
nbt.setFloat("ExpansionSpeed", expansionSpeed);
nbt.setFloat("MaxLength", maxLength);
nbt.setDouble("DirX", dirX);
nbt.setDouble("DirY", dirY);
nbt.setDouble("DirZ", dirZ);
}
@Override
protected void applyProjectileClientSyncData(NBTTagCompound nbt) {
laserWidth = nbt.getFloat("LaserWidth");
expansionSpeed = nbt.getFloat("ExpansionSpeed");
maxLength = nbt.getFloat("MaxLength");
dirX = nbt.getDouble("DirX");
dirY = nbt.getDouble("DirY");
dirZ = nbt.getDouble("DirZ");
}
// ==================== NBT ====================
@Override
@@ -2,6 +2,7 @@ package kamkeel.npcs.entity;
import kamkeel.npcs.controllers.data.ability.util.AbilityTargetHelper;
import kamkeel.npcs.controllers.data.ability.data.energy.EnergyBarrierData;
import kamkeel.npcs.network.packets.data.energy.BarrierClientSyncPacket;
import kamkeel.npcs.util.AttributeAttackUtil;
import kamkeel.npcs.util.CNPCDebug;
import net.minecraft.entity.Entity;
@@ -744,6 +745,78 @@ public abstract class EntityEnergyBarrier extends EntityEnergyAbility {
return ticksAlive;
}
// ==================== CLIENT SYNC ====================
/**
* Write all client-relevant barrier state for sync.
* Subclasses should override writeBarrierClientSyncData for type-specific fields.
*/
public NBTTagCompound writeClientSyncData() {
NBTTagCompound nbt = new NBTTagCompound();
// Position
nbt.setDouble("PosX", posX);
nbt.setDouble("PosY", posY);
nbt.setDouble("PosZ", posZ);
// Display
nbt.setInteger("InnerColor", getInnerColor());
nbt.setFloat("InnerAlpha", getInnerAlpha());
nbt.setInteger("OuterColor", getOuterColor());
nbt.setBoolean("OuterColorEnabled", isOuterColorEnabled());
nbt.setFloat("OuterColorWidth", getOuterColorWidth());
nbt.setFloat("OuterColorAlpha", getOuterColorAlpha());
nbt.setFloat("RotationSpeed", getRotationSpeed());
// Lightning
nbt.setBoolean("LightningEffect", hasLightningEffect());
nbt.setFloat("LightningDensity", getLightningDensity());
nbt.setFloat("LightningRadius", getLightningRadius());
nbt.setInteger("LightningFadeTime", getLightningFadeTime());
writeBarrierClientSyncData(nbt);
return nbt;
}
/**
* Apply client sync data from server.
* Subclasses should override applyBarrierClientSyncData for type-specific fields.
*/
public void applyClientSyncData(NBTTagCompound nbt) {
// Position
setPosition(nbt.getDouble("PosX"), nbt.getDouble("PosY"), nbt.getDouble("PosZ"));
// Display
displayData.setInnerColor(nbt.getInteger("InnerColor"));
displayData.setInnerAlpha(nbt.getFloat("InnerAlpha"));
displayData.setOuterColor(nbt.getInteger("OuterColor"));
displayData.setOuterColorEnabled(nbt.getBoolean("OuterColorEnabled"));
displayData.setOuterColorWidth(nbt.getFloat("OuterColorWidth"));
displayData.setOuterColorAlpha(nbt.getFloat("OuterColorAlpha"));
displayData.setRotationSpeed(nbt.getFloat("RotationSpeed"));
// Lightning
setLightningEffect(nbt.getBoolean("LightningEffect"));
setLightningDensity(nbt.getFloat("LightningDensity"));
setLightningRadius(nbt.getFloat("LightningRadius"));
setLightningFadeTime(nbt.getInteger("LightningFadeTime"));
applyBarrierClientSyncData(nbt);
}
/**
* Subclass hook: write type-specific client sync data (dome radius, panel dimensions, etc.).
*/
protected void writeBarrierClientSyncData(NBTTagCompound nbt) {
}
/**
* Subclass hook: apply type-specific client sync data on client.
*/
protected void applyBarrierClientSyncData(NBTTagCompound nbt) {
}
/**
* Send full client sync to all tracking clients.
*/
public void sendClientSync() {
if (worldObj == null || worldObj.isRemote) return;
BarrierClientSyncPacket.sendToTracking(this, writeClientSyncData());
}
// ==================== NBT HELPERS ====================
/**
@@ -681,6 +681,18 @@ public class EntityEnergyDome extends EntityEnergyBarrier {
);
}
// ==================== CLIENT SYNC ====================
@Override
protected void writeBarrierClientSyncData(NBTTagCompound nbt) {
nbt.setFloat("DomeRadius", domeRadius);
}
@Override
protected void applyBarrierClientSyncData(NBTTagCompound nbt) {
setDomeRadius(nbt.getFloat("DomeRadius"));
}
// ==================== NBT ====================
@Override
@@ -712,6 +712,22 @@ public class EntityEnergyPanel extends EntityEnergyBarrier {
this.mode = mode;
}
// ==================== CLIENT SYNC ====================
@Override
protected void writeBarrierClientSyncData(NBTTagCompound nbt) {
nbt.setFloat("PanelWidth", panelData.panelWidth);
nbt.setFloat("PanelHeight", panelData.panelHeight);
nbt.setFloat("PanelYaw", panelYaw);
}
@Override
protected void applyBarrierClientSyncData(NBTTagCompound nbt) {
panelData.panelWidth = nbt.getFloat("PanelWidth");
panelData.panelHeight = nbt.getFloat("PanelHeight");
panelYaw = nbt.getFloat("PanelYaw");
}
// ==================== NBT ====================
@Override
@@ -15,6 +15,7 @@ import kamkeel.npcs.controllers.data.ability.data.energy.EnergyDisplayData;
import kamkeel.npcs.controllers.data.ability.data.energy.EnergyHomingData;
import kamkeel.npcs.controllers.data.ability.data.energy.EnergyLifespanData;
import kamkeel.npcs.controllers.data.ability.data.energy.EnergyLightningData;
import kamkeel.npcs.network.packets.data.energy.ProjectileClientSyncPacket;
import kamkeel.npcs.network.packets.data.energy.ProjectileReflectPacket;
import kamkeel.npcs.network.packets.data.energyexplosion.EnergyExplosionSpawnPacket;
import kamkeel.npcs.util.AnchorPointHelper;
@@ -690,6 +691,93 @@ public abstract class EntityEnergyProjectile extends EntityEnergyAbility {
ProjectileReflectPacket.sendToTracking(this, writeReflectionData());
}
// ==================== CLIENT SYNC ====================
/**
* Write all client-relevant state: position, motion, visual, and movement properties.
* Subclasses should override writeProjectileClientSyncData for type-specific fields.
*/
public NBTTagCompound writeClientSyncData() {
NBTTagCompound nbt = new NBTTagCompound();
// Position & motion
nbt.setDouble("PosX", posX);
nbt.setDouble("PosY", posY);
nbt.setDouble("PosZ", posZ);
nbt.setDouble("MotionX", motionX);
nbt.setDouble("MotionY", motionY);
nbt.setDouble("MotionZ", motionZ);
// Size & visual
nbt.setFloat("Size", size);
nbt.setFloat("RotationSpeed", displayData.getRotationSpeed());
nbt.setFloat("InnerAlpha", displayData.getInnerAlpha());
nbt.setBoolean("OuterColorEnabled", displayData.isOuterColorEnabled());
nbt.setFloat("OuterColorWidth", displayData.getOuterColorWidth());
nbt.setFloat("OuterColorAlpha", displayData.getOuterColorAlpha());
// Lightning
nbt.setBoolean("LightningEffect", hasLightningEffect());
nbt.setFloat("LightningDensity", getLightningDensity());
nbt.setFloat("LightningRadius", getLightningRadius());
nbt.setInteger("LightningFadeTime", getLightningFadeTime());
// Movement
nbt.setFloat("Speed", getSpeed());
nbt.setBoolean("Homing", isHoming());
nbt.setFloat("HomingStrength", getHomingStrength());
nbt.setFloat("HomingRange", getHomingRange());
writeProjectileClientSyncData(nbt);
return nbt;
}
/**
* Apply client sync data from server.
* Subclasses should override applyProjectileClientSyncData for type-specific fields.
*/
public void applyClientSyncData(NBTTagCompound nbt) {
// Position & motion
setPosition(nbt.getDouble("PosX"), nbt.getDouble("PosY"), nbt.getDouble("PosZ"));
motionX = nbt.getDouble("MotionX");
motionY = nbt.getDouble("MotionY");
motionZ = nbt.getDouble("MotionZ");
syncPositionStateToCurrent(true);
// Size & visual
setProjectileSize(nbt.getFloat("Size"));
displayData.setRotationSpeed(nbt.getFloat("RotationSpeed"));
displayData.setInnerAlpha(nbt.getFloat("InnerAlpha"));
displayData.setOuterColorEnabled(nbt.getBoolean("OuterColorEnabled"));
displayData.setOuterColorWidth(nbt.getFloat("OuterColorWidth"));
displayData.setOuterColorAlpha(nbt.getFloat("OuterColorAlpha"));
// Lightning
setLightningEffect(nbt.getBoolean("LightningEffect"));
setLightningDensity(nbt.getFloat("LightningDensity"));
setLightningRadius(nbt.getFloat("LightningRadius"));
setLightningFadeTime(nbt.getInteger("LightningFadeTime"));
// Movement
setSpeed(nbt.getFloat("Speed"));
setHomingEnabled(nbt.getBoolean("Homing"));
setHomingStrength(nbt.getFloat("HomingStrength"));
setHomingRange(nbt.getFloat("HomingRange"));
applyProjectileClientSyncData(nbt);
}
/**
* Subclass hook: write type-specific client sync data.
*/
protected void writeProjectileClientSyncData(NBTTagCompound nbt) {
}
/**
* Subclass hook: apply type-specific client sync data on client.
*/
protected void applyProjectileClientSyncData(NBTTagCompound nbt) {
}
/**
* Send full client sync to all tracking clients.
*/
public void sendClientSync() {
if (worldObj == null || worldObj.isRemote) return;
ProjectileClientSyncPacket.sendToTracking(this, writeClientSyncData());
}
protected double[] getBarrierImpactNormal(EntityEnergyBarrier barrier, double velocityX, double velocityY, double velocityZ) {
return barrier.getSurfaceNormal(posX, posY, posZ, velocityX, velocityY, velocityZ);
}
@@ -1662,7 +1750,7 @@ public abstract class EntityEnergyProjectile extends EntityEnergyAbility {
/**
* Sync prev/lastTick and optional interpolation state to current entity position.
*/
protected void syncPositionStateToCurrent(boolean resetInterpolation) {
public void syncPositionStateToCurrent(boolean resetInterpolation) {
syncPositionState(posX, posY, posZ, resetInterpolation);
}
@@ -2264,7 +2352,18 @@ public abstract class EntityEnergyProjectile extends EntityEnergyAbility {
}
public void setSpeed(float speed) {
float oldSpeed = homingData.getSpeed();
homingData.setSpeed(speed);
// Rescale current motion vector to match new speed
if (addedToChunk && !worldObj.isRemote) {
double len = Math.sqrt(motionX * motionX + motionY * motionY + motionZ * motionZ);
if (len > 0) {
double scale = speed / len;
motionX *= scale;
motionY *= scale;
motionZ *= scale;
}
}
}
public AnchorPoint getAnchorPoint() {
@@ -218,6 +218,20 @@ public class EntityEnergySlicer extends EntityEnergyProjectile {
this.sliceThickness = thickness;
}
// ==================== PROPERTY SYNC ====================
@Override
protected void writeProjectileClientSyncData(NBTTagCompound nbt) {
nbt.setFloat("SliceWidth", sliceWidth);
nbt.setFloat("SliceThickness", sliceThickness);
}
@Override
protected void applyProjectileClientSyncData(NBTTagCompound nbt) {
sliceWidth = nbt.getFloat("SliceWidth");
sliceThickness = nbt.getFloat("SliceThickness");
}
// ==================== NBT ====================
@Override
@@ -39,6 +39,8 @@ import kamkeel.npcs.network.packets.data.script.ScriptedParticlePacket;
import kamkeel.npcs.network.packets.data.energycharge.EnergyChargeRemovePacket;
import kamkeel.npcs.network.packets.data.energycharge.EnergyChargeSpawnPacket;
import kamkeel.npcs.network.packets.data.energyexplosion.EnergyExplosionSpawnPacket;
import kamkeel.npcs.network.packets.data.energy.BarrierClientSyncPacket;
import kamkeel.npcs.network.packets.data.energy.ProjectileClientSyncPacket;
import kamkeel.npcs.network.packets.data.energy.ProjectileReflectPacket;
import kamkeel.npcs.network.packets.data.telegraph.TelegraphRemovePacket;
import kamkeel.npcs.network.packets.data.telegraph.TelegraphSpawnPacket;
@@ -612,6 +614,8 @@ public class PacketHandler {
DATA_PACKET.registerPacket(new EnergyChargeRemovePacket());
DATA_PACKET.registerPacket(new EnergyExplosionSpawnPacket());
DATA_PACKET.registerPacket(new ProjectileReflectPacket());
DATA_PACKET.registerPacket(new ProjectileClientSyncPacket());
DATA_PACKET.registerPacket(new BarrierClientSyncPacket());
DATA_PACKET.registerPacket(new PlayerAbilitySyncPacket());
DATA_PACKET.registerPacket(new PlayerAbilityStatePacket());
DATA_PACKET.registerPacket(new AbilityHotbarSyncPacket());
@@ -79,4 +79,10 @@ public enum EnumDataPacket {
// Energy Projectile Reflection Sync
PROJECTILE_REFLECT,
// Energy Projectile Client Sync (position, motion, visual, and movement properties)
PROJECTILE_CLIENT_SYNC,
// Energy Barrier Client Sync (visual properties and barrier-specific data)
BARRIER_CLIENT_SYNC,
}
@@ -0,0 +1,77 @@
package kamkeel.npcs.network.packets.data.energy;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import kamkeel.npcs.entity.EntityEnergyBarrier;
import kamkeel.npcs.network.AbstractPacket;
import kamkeel.npcs.network.PacketChannel;
import kamkeel.npcs.network.PacketHandler;
import kamkeel.npcs.network.enums.EnumDataPacket;
import kamkeel.npcs.util.ByteBufUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import java.io.IOException;
/**
* Syncs all barrier client-relevant state to tracking clients.
* Includes visual properties and barrier-specific data (dome radius, panel dimensions, etc.).
* Sent server->client when scripts call syncClient() on an already-spawned energy barrier.
*/
public final class BarrierClientSyncPacket extends AbstractPacket {
private int entityId;
private NBTTagCompound syncData;
public BarrierClientSyncPacket() {
}
public BarrierClientSyncPacket(int entityId, NBTTagCompound syncData) {
this.entityId = entityId;
this.syncData = syncData;
}
@Override
public Enum getType() {
return EnumDataPacket.BARRIER_CLIENT_SYNC;
}
@Override
public PacketChannel getChannel() {
return PacketHandler.DATA_PACKET;
}
@Override
public void sendData(ByteBuf out) throws IOException {
out.writeInt(entityId);
ByteBufUtils.writeNBT(out, syncData);
}
@SideOnly(Side.CLIENT)
@Override
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
int id = in.readInt();
NBTTagCompound nbt = ByteBufUtils.readNBT(in);
if (nbt == null) return;
World world = Minecraft.getMinecraft().theWorld;
if (world == null) return;
Entity entity = world.getEntityByID(id);
if (entity instanceof EntityEnergyBarrier) {
((EntityEnergyBarrier) entity).applyClientSyncData(nbt);
}
}
public static void sendToTracking(EntityEnergyBarrier barrier, NBTTagCompound syncData) {
if (barrier == null || syncData == null) return;
PacketHandler.Instance.sendTracking(
new BarrierClientSyncPacket(barrier.getEntityId(), syncData),
barrier
);
}
}
@@ -0,0 +1,78 @@
package kamkeel.npcs.network.packets.data.energy;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import kamkeel.npcs.entity.EntityEnergyProjectile;
import kamkeel.npcs.network.AbstractPacket;
import kamkeel.npcs.network.PacketChannel;
import kamkeel.npcs.network.PacketHandler;
import kamkeel.npcs.network.enums.EnumDataPacket;
import kamkeel.npcs.util.ByteBufUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import java.io.IOException;
/**
* Syncs all projectile client-relevant state to tracking clients.
* Includes position, motion, visual properties, and movement settings.
* Sent server->client when scripts call syncClient() or fireAt() on
* an already-spawned energy projectile.
*/
public final class ProjectileClientSyncPacket extends AbstractPacket {
private int entityId;
private NBTTagCompound syncData;
public ProjectileClientSyncPacket() {
}
public ProjectileClientSyncPacket(int entityId, NBTTagCompound syncData) {
this.entityId = entityId;
this.syncData = syncData;
}
@Override
public Enum getType() {
return EnumDataPacket.PROJECTILE_CLIENT_SYNC;
}
@Override
public PacketChannel getChannel() {
return PacketHandler.DATA_PACKET;
}
@Override
public void sendData(ByteBuf out) throws IOException {
out.writeInt(entityId);
ByteBufUtils.writeNBT(out, syncData);
}
@SideOnly(Side.CLIENT)
@Override
public void receiveData(ByteBuf in, EntityPlayer player) throws IOException {
int id = in.readInt();
NBTTagCompound nbt = ByteBufUtils.readNBT(in);
if (nbt == null) return;
World world = Minecraft.getMinecraft().theWorld;
if (world == null) return;
Entity entity = world.getEntityByID(id);
if (entity instanceof EntityEnergyProjectile) {
((EntityEnergyProjectile) entity).applyClientSyncData(nbt);
}
}
public static void sendToTracking(EntityEnergyProjectile projectile, NBTTagCompound syncData) {
if (projectile == null || syncData == null) return;
PacketHandler.Instance.sendTracking(
new ProjectileClientSyncPacket(projectile.getEntityId(), syncData),
projectile
);
}
}
@@ -140,4 +140,12 @@ public class ScriptEnergyBarrier<T extends EntityEnergyBarrier> extends ScriptEn
public int getBarrierType() {
return entity instanceof EntityEnergyDome ? 0 : 1;
}
// ==================== SYNC ====================
public void syncClient() {
if (entity.addedToChunk) {
entity.sendClientSync();
}
}
}
@@ -353,12 +353,20 @@ public class ScriptEnergyProjectile<T extends EntityEnergyProjectile> extends Sc
}
}
public void syncClient() {
if (entity.addedToChunk) {
entity.sendClientSync();
}
}
protected void ensureSpawned() {
if (!entity.addedToChunk && entity.worldObj != null) {
entity.worldObj.spawnEntityInWorld(entity);
if (!entity.worldObj.isRemote) {
EventHooks.onEnergyProjectileFired(entity);
}
} else if (entity.addedToChunk) {
entity.sendClientSync();
}
}