Better API Handling for Scripting Energy Utilitizes / Damage Handling

This commit is contained in:
Kam committed 2026-03-03 02:02:13 -05:00
1 parent 572a51ad32
commit ee192a247f
3 files changed
+523

No files matched your search

@@ -0,0 +1,197 @@
package kamkeel.npcs.controllers;
import kamkeel.npcs.controllers.data.energy.IEnergyHandler;
import kamkeel.npcs.entity.*;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import noppes.npcs.api.IEnergyController;
import noppes.npcs.api.IWorld;
import noppes.npcs.api.entity.*;
import noppes.npcs.scripted.NpcAPI;
import java.util.ArrayList;
import java.util.List;
/**
* Central controller for script-created energy entities and handler registration.
* Provides factory methods for creating all energy entity types and routes
* damage through registered handlers when entities have customDamageData
* but no sourceAbility.
*/
public class EnergyController implements IEnergyController {
public static EnergyController Instance = new EnergyController();
private final List<IEnergyHandler> handlers = new ArrayList<>();
// ═══════════════════════════════════════════════════════════════════
// HANDLER REGISTRATION
// ═══════════════════════════════════════════════════════════════════
public void registerHandler(IEnergyHandler handler) {
handlers.add(handler);
}
public List<IEnergyHandler> getHandlers() {
return handlers;
}
// ═══════════════════════════════════════════════════════════════════
// DAMAGE ROUTING
// ═══════════════════════════════════════════════════════════════════
/**
* Fire onEnergyDamage on all handlers. Chain of responsibility — first true wins.
*/
public boolean fireOnEnergyDamage(Entity energyEntity, EntityLivingBase owner,
EntityLivingBase target, float damage,
float knockback, float knockbackUp,
double kbDirX, double kbDirZ,
float damageMultiplier,
NBTTagCompound damageData) {
for (IEnergyHandler handler : handlers) {
if (handler.onEnergyDamage(energyEntity, owner, target, damage,
knockback, knockbackUp, kbDirX, kbDirZ, damageMultiplier, damageData)) {
return true;
}
}
return false;
}
/**
* Fire modifyEnergyDamage on all handlers. Cumulative — each handler's output feeds the next.
*/
public float fireModifyEnergyDamage(Entity energyEntity, EntityLivingBase owner,
float baseDamage, NBTTagCompound damageData) {
float damage = baseDamage;
for (IEnergyHandler handler : handlers) {
damage = handler.modifyEnergyDamage(energyEntity, owner, damage, damageData);
}
return damage;
}
// ═══════════════════════════════════════════════════════════════════
// INTERNAL FACTORY METHODS (MC types)
// ═══════════════════════════════════════════════════════════════════
public EntityAbilityOrb createOrbInternal(World world, Entity owner, double x, double y, double z, float size) {
EntityAbilityOrb entity = new EntityAbilityOrb(world);
entity.setPosition(x, y, z);
entity.setStartPosition(x, y, z);
entity.setOwnerEntityId(owner.getEntityId());
entity.setProjectileSize(size);
return entity;
}
public EntityAbilityBeam createBeamInternal(World world, Entity owner, double x, double y, double z,
float beamWidth, float headSize) {
EntityAbilityBeam entity = new EntityAbilityBeam(world);
entity.setPosition(x, y, z);
entity.setStartPosition(x, y, z);
entity.setOwnerEntityId(owner.getEntityId());
entity.setBeamWidth(beamWidth);
entity.setHeadSize(headSize);
return entity;
}
public EntityAbilityDisc createDiscInternal(World world, Entity owner, double x, double y, double z,
float radius, float thickness) {
EntityAbilityDisc entity = new EntityAbilityDisc(world);
entity.setPosition(x, y, z);
entity.setStartPosition(x, y, z);
entity.setOwnerEntityId(owner.getEntityId());
entity.setDiscRadius(radius);
entity.setDiscThickness(thickness);
return entity;
}
public EntityAbilityLaser createLaserInternal(World world, Entity owner, double x, double y, double z,
float laserWidth) {
EntityAbilityLaser entity = new EntityAbilityLaser(world);
entity.setPosition(x, y, z);
entity.setStartPosition(x, y, z);
entity.setOwnerEntityId(owner.getEntityId());
entity.setLaserWidth(laserWidth);
return entity;
}
public EntityAbilityZone createHazardInternal(World world, Entity owner, double x, double y, double z) {
EntityAbilityZone entity = new EntityAbilityZone(world);
entity.initAsHazard(owner, x, y, z);
return entity;
}
public EntityAbilityZone createTrapInternal(World world, Entity owner, double x, double y, double z) {
EntityAbilityZone entity = new EntityAbilityZone(world);
entity.initAsTrap(owner, x, y, z);
return entity;
}
public EntityEnergySweeper createSweeperInternal(World world, Entity owner, double x, double y, double z) {
EntityEnergySweeper entity = new EntityEnergySweeper(world);
entity.setPosition(x, y, z);
entity.setOwnerEntityId(owner.getEntityId());
return entity;
}
public EntityEnergyPanel createPanelInternal(World world, Entity owner, double x, double y, double z) {
EntityEnergyPanel entity = new EntityEnergyPanel(world);
entity.setPosition(x, y, z);
entity.setOwnerEntityId(owner.getEntityId());
return entity;
}
// ═══════════════════════════════════════════════════════════════════
// IEnergyController (Script API methods)
// ═══════════════════════════════════════════════════════════════════
@Override
public IEnergyOrb createOrb(IWorld world, IEntity owner, double x, double y, double z, float size) {
EntityAbilityOrb entity = createOrbInternal((World) world.getMCWorld(), owner.getMCEntity(), x, y, z, size);
return (IEnergyOrb) NpcAPI.Instance().getIEntity(entity);
}
@Override
public IEnergyBeam createBeam(IWorld world, IEntity owner, double x, double y, double z, float beamWidth, float headSize) {
EntityAbilityBeam entity = createBeamInternal((World) world.getMCWorld(), owner.getMCEntity(), x, y, z, beamWidth, headSize);
return (IEnergyBeam) NpcAPI.Instance().getIEntity(entity);
}
@Override
public IEnergyDisc createDisc(IWorld world, IEntity owner, double x, double y, double z, float radius, float thickness) {
EntityAbilityDisc entity = createDiscInternal((World) world.getMCWorld(), owner.getMCEntity(), x, y, z, radius, thickness);
return (IEnergyDisc) NpcAPI.Instance().getIEntity(entity);
}
@Override
public IEnergyLaser createLaser(IWorld world, IEntity owner, double x, double y, double z, float laserWidth) {
EntityAbilityLaser entity = createLaserInternal((World) world.getMCWorld(), owner.getMCEntity(), x, y, z, laserWidth);
return (IEnergyLaser) NpcAPI.Instance().getIEntity(entity);
}
@Override
public IEnergyZone createHazard(IWorld world, IEntity owner, double x, double y, double z) {
EntityAbilityZone entity = createHazardInternal((World) world.getMCWorld(), owner.getMCEntity(), x, y, z);
return (IEnergyZone) NpcAPI.Instance().getIEntity(entity);
}
@Override
public IEnergyZone createTrap(IWorld world, IEntity owner, double x, double y, double z) {
EntityAbilityZone entity = createTrapInternal((World) world.getMCWorld(), owner.getMCEntity(), x, y, z);
return (IEnergyZone) NpcAPI.Instance().getIEntity(entity);
}
@Override
public IEnergySweeper createSweeper(IWorld world, IEntity owner, double x, double y, double z) {
EntityEnergySweeper entity = createSweeperInternal((World) world.getMCWorld(), owner.getMCEntity(), x, y, z);
return (IEnergySweeper) NpcAPI.Instance().getIEntity(entity);
}
@Override
public IEnergyPanel createPanel(IWorld world, IEntity owner, double x, double y, double z) {
EntityEnergyPanel entity = createPanelInternal((World) world.getMCWorld(), owner.getMCEntity(), x, y, z);
return (IEnergyPanel) NpcAPI.Instance().getIEntity(entity);
}
}
@@ -0,0 +1,49 @@
package kamkeel.npcs.controllers.data.energy;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
/**
* Extension point for handling energy entity damage without a sourceAbility.
* Registered with EnergyController. DBC Addon implements this to route
* script-created energy entity damage through the DBC damage pipeline.
*/
public interface IEnergyHandler {
/**
* Handle damage for an energy entity with custom damage data.
* Chain of Responsibility — first handler returning true claims the damage.
*
* @param energyEntity The energy entity dealing damage
* @param owner The entity that owns/created the energy entity
* @param target The entity being damaged
* @param damage Base damage amount
* @param knockback Horizontal knockback strength
* @param knockbackUp Vertical knockback strength
* @param kbDirX Knockback direction X
* @param kbDirZ Knockback direction Z
* @param damageMultiplier Damage multiplier (e.g. falloff)
* @param damageData Custom damage configuration NBT (e.g. DBC stats)
* @return true if this handler processed the damage, false to pass to next handler
*/
boolean onEnergyDamage(Entity energyEntity, EntityLivingBase owner,
EntityLivingBase target, float damage,
float knockback, float knockbackUp,
double kbDirX, double kbDirZ,
float damageMultiplier,
NBTTagCompound damageData);
/**
* Modify outgoing damage for an energy entity with custom damage data.
* Cumulative — each handler receives the previous handler's output.
*
* @param energyEntity The energy entity dealing damage
* @param owner The entity that owns/created the energy entity
* @param baseDamage Current damage value (after previous handlers)
* @param damageData Custom damage configuration NBT
* @return Modified damage value
*/
float modifyEnergyDamage(Entity energyEntity, EntityLivingBase owner,
float baseDamage, NBTTagCompound damageData);
}
@@ -0,0 +1,277 @@
package noppes.npcs.scripted.entity;
import kamkeel.npcs.entity.EntityAbilityZone;
import net.minecraft.nbt.NBTTagCompound;
import noppes.npcs.api.INbt;
import noppes.npcs.api.entity.IEnergyZone;
import noppes.npcs.scripted.NpcAPI;
/**
* Script wrapper for EntityAbilityZone (Hazard and Trap zones).
*/
public class ScriptEnergyZone<T extends EntityAbilityZone> extends ScriptEntity<T> implements IEnergyZone {
public ScriptEnergyZone(T entity) {
super(entity);
}
// ==================== ZONE TYPE ====================
@Override
public int getZoneType() {
return entity.getZoneType().ordinal();
}
// ==================== COMMON ZONE PROPERTIES ====================
@Override
public int getZoneShape() {
return entity.getShape().ordinal();
}
@Override
public void setZoneShape(int shape) {
EntityAbilityZone.ZoneShape[] values = EntityAbilityZone.ZoneShape.values();
if (shape >= 0 && shape < values.length) {
entity.setShape(values[shape]);
}
}
@Override
public float getRadius() {
return entity.getRadius();
}
@Override
public void setRadius(float radius) {
entity.setRadius(radius);
}
@Override
public float getZoneHeight() {
return entity.getZoneHeight();
}
@Override
public void setZoneHeight(float height) {
entity.setZoneHeight(height);
}
@Override
public int getDuration() {
return entity.getDurationTicks();
}
@Override
public void setDuration(int ticks) {
entity.setDurationTicks(ticks);
}
// ==================== COLORS ====================
@Override
public int getInnerColor() {
return entity.getInnerColor();
}
@Override
public void setInnerColor(int color) {
entity.setInnerColor(color);
}
@Override
public int getOuterColor() {
return entity.getOuterColor();
}
@Override
public void setOuterColor(int color) {
entity.setOuterColor(color);
}
@Override
public boolean isOuterColorEnabled() {
return entity.isOuterColorEnabled();
}
@Override
public void setOuterColorEnabled(boolean enabled) {
entity.setOuterColorEnabled(enabled);
}
// ==================== VISUALS ====================
@Override
public float getParticleDensity() {
return entity.getParticleDensity();
}
@Override
public void setParticleDensity(float density) {
entity.setParticleDensity(density);
}
@Override
public float getParticleScale() {
return entity.getParticleScale();
}
@Override
public void setParticleScale(float scale) {
entity.setParticleScale(scale);
}
@Override
public float getAnimSpeed() {
return entity.getAnimSpeed();
}
@Override
public void setAnimSpeed(float speed) {
entity.setAnimSpeed(speed);
}
@Override
public boolean isIgnoreIFrames() {
return entity.isIgnoreIFrames();
}
@Override
public void setIgnoreIFrames(boolean ignore) {
entity.setIgnoreIFrames(ignore);
}
// ==================== HAZARD-SPECIFIC ====================
@Override
public float getDamagePerSecond() {
return entity.getDamagePerSecond();
}
@Override
public void setDamagePerSecond(float dps) {
entity.setDamagePerSecond(dps);
}
@Override
public int getDamageInterval() {
return entity.getDamageInterval();
}
@Override
public void setDamageInterval(int ticks) {
entity.setDamageInterval(ticks);
}
@Override
public boolean isAffectsCaster() {
return entity.isAffectsCaster();
}
@Override
public void setAffectsCaster(boolean affects) {
entity.setAffectsCaster(affects);
}
// ==================== TRAP-SPECIFIC ====================
@Override
public float getTriggerRadius() {
return entity.getTriggerRadius();
}
@Override
public void setTriggerRadius(float radius) {
entity.setTriggerRadius(radius);
}
@Override
public int getArmTime() {
return entity.getArmTime();
}
@Override
public void setArmTime(int ticks) {
entity.setArmTime(ticks);
}
@Override
public int getMaxTriggers() {
return entity.getMaxTriggers();
}
@Override
public void setMaxTriggers(int max) {
entity.setMaxTriggers(max);
}
@Override
public int getTriggerCooldown() {
return entity.getTriggerCooldown();
}
@Override
public void setTriggerCooldown(int ticks) {
entity.setTriggerCooldown(ticks);
}
@Override
public float getDamage() {
return entity.getDamage();
}
@Override
public void setDamage(float damage) {
entity.setDamage(damage);
}
@Override
public float getKnockback() {
return entity.getKnockback();
}
@Override
public void setKnockback(float knockback) {
entity.setKnockback(knockback);
}
@Override
public boolean isVisible() {
return entity.isVisible();
}
@Override
public void setVisible(boolean visible) {
entity.setVisible(visible);
}
// ==================== CUSTOM DAMAGE DATA ====================
@Override
public INbt getDamageData() {
NBTTagCompound data = entity.getCustomDamageData();
if (data == null) {
data = new NBTTagCompound();
entity.setCustomDamageData(data);
}
return NpcAPI.Instance().getINbt(data);
}
@Override
public void setDamageData(INbt data) {
if (data == null) {
entity.setCustomDamageData(null);
} else {
entity.setCustomDamageData((NBTTagCompound) data.getMCNBT());
}
}
// ==================== SPAWNING ====================
@Override
public void spawn() {
if (!entity.addedToChunk && entity.worldObj != null) {
entity.worldObj.spawnEntityInWorld(entity);
}
}
}