mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 22:27:32 +00:00
Better API Handling for Scripting Energy Utilitizes / Damage Handling
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user