diff --git a/src/api b/src/api index 2054012fa..3050910ef 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 2054012fae799fa233b99824b4f649d311eff86f +Subproject commit 3050910efbc6e301e4ef18fefc20529c507a7bae diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java index 7a1d9babf..d87ed05ee 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCharge.java @@ -18,6 +18,8 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityCharge; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityCharge; + import java.util.HashSet; import java.util.List; import java.util.Set; @@ -25,7 +27,7 @@ import java.util.Set; /** * Charge ability: Rush attack where NPC charges in a line, damaging all targets hit. */ -public class AbilityCharge extends Ability { +public class AbilityCharge extends Ability implements IAbilityCharge { // Type-specific parameters private float chargeSpeed = 0.8f; diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCutter.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCutter.java index b3052eeac..1d77e9219 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCutter.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityCutter.java @@ -15,6 +15,8 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityCutter; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityCutter; + import java.util.HashSet; import java.util.List; import java.util.Set; @@ -24,7 +26,7 @@ import java.util.Set; * Deals damage to all entities in a cone/arc in front of the caster. * Can sweep outward over time or hit instantly. */ -public class AbilityCutter extends Ability { +public class AbilityCutter extends Ability implements IAbilityCutter { public enum SweepMode { SWIPE, @@ -254,14 +256,25 @@ public class AbilityCutter extends Ability { this.knockback = knockback; } - public SweepMode getSweepMode() { + public SweepMode getSweepModeEnum() { return sweepMode; } - public void setSweepMode(SweepMode sweepMode) { + public void setSweepModeEnum(SweepMode sweepMode) { this.sweepMode = sweepMode; } + @Override + public int getSweepMode() { + return sweepMode.ordinal(); + } + + @Override + public void setSweepMode(int mode) { + SweepMode[] values = SweepMode.values(); + this.sweepMode = mode >= 0 && mode < values.length ? values[mode] : SweepMode.SWIPE; + } + public float getSweepSpeed() { return sweepSpeed; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java index cd4d42ac7..677578745 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDash.java @@ -14,13 +14,15 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityDash; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityDash; + import java.util.Random; /** * Dash ability: Quick evasive sidestep with NO telegraph. * Defensive repositioning move to evade attacks. */ -public class AbilityDash extends Ability { +public class AbilityDash extends Ability implements IAbilityDash { /** * Dash behavior mode. @@ -245,14 +247,25 @@ public class AbilityDash extends Ability { } // Getters & Setters - public DashMode getDashMode() { + public DashMode getDashModeEnum() { return dashMode; } - public void setDashMode(DashMode dashMode) { + public void setDashModeEnum(DashMode dashMode) { this.dashMode = dashMode; } + @Override + public int getDashMode() { + return dashMode.ordinal(); + } + + @Override + public void setDashMode(int mode) { + DashMode[] values = DashMode.values(); + this.dashMode = mode >= 0 && mode < values.length ? values[mode] : DashMode.AGGRESSIVE; + } + public float getDashDistance() { return dashDistance; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java index 67fa23cdf..2c7b8e43c 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDisc.java @@ -17,13 +17,14 @@ import net.minecraft.world.World; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityDisc; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.api.ability.type.IAbilityDisc; import noppes.npcs.entity.EntityNPCInterface; /** * Disc ability: Spawns a flat spinning disc projectile. * Has optional boomerang behavior to return to owner. */ -public class AbilityDisc extends Ability { +public class AbilityDisc extends Ability implements IAbilityDisc { // Movement properties private float speed = 0.6f; @@ -312,6 +313,12 @@ public class AbilityDisc extends Ability { public void setLightningDensity(float lightningDensity) { this.lightningDensity = lightningDensity; } public float getLightningRadius() { return lightningRadius; } public void setLightningRadius(float lightningRadius) { this.lightningRadius = lightningRadius; } - public AnchorPoint getAnchorPoint() { return anchorPoint; } - public void setAnchorPoint(AnchorPoint anchorPoint) { this.anchorPoint = anchorPoint; } + public AnchorPoint getAnchorPointEnum() { return anchorPoint; } + public void setAnchorPointEnum(AnchorPoint anchorPoint) { this.anchorPoint = anchorPoint; } + + @Override + public int getAnchorPoint() { return anchorPoint.getId(); } + + @Override + public void setAnchorPoint(int point) { this.anchorPoint = AnchorPoint.fromId(point); } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java index 2dea02f5a..790489b2c 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityEnergyBeam.java @@ -12,12 +12,12 @@ import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import kamkeel.npcs.entity.EntityAbilityBeam; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.DamageSource; +import net.minecraft.nbt.NBTTagCompound;; import net.minecraft.world.World; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityEnergyBeam; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.api.ability.type.IAbilityEnergyBeam; import noppes.npcs.controllers.data.Animation; import noppes.npcs.entity.EntityNPCInterface; @@ -26,7 +26,7 @@ import noppes.npcs.entity.EntityNPCInterface; * The beam stays attached to the origin and curves as it homes in on target. * Cannot cross over itself (self-intersection prevention). */ -public class AbilityEnergyBeam extends Ability { +public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam { // Movement properties private float speed = 0.4f; @@ -310,9 +310,8 @@ public class AbilityEnergyBeam extends Ability { public void setLightningDensity(float lightningDensity) { this.lightningDensity = lightningDensity; } public float getLightningRadius() { return lightningRadius; } public void setLightningRadius(float lightningRadius) { this.lightningRadius = lightningRadius; } - public AnchorPoint getAnchorPoint() { return anchorPoint; } - public void setAnchorPoint(AnchorPoint anchorPoint) { this.anchorPoint = anchorPoint; } + @Override public Animation getWindUpAnimation() { if (windUpAnimationId == -1) @@ -328,4 +327,13 @@ public class AbilityEnergyBeam extends Ability { return super.getActiveAnimation(); } + + public AnchorPoint getAnchorPointEnum() { return anchorPoint; } + public void setAnchorPointEnum(AnchorPoint anchorPoint) { this.anchorPoint = anchorPoint; } + + @Override + public int getAnchorPoint() { return anchorPoint.getId(); } + + @Override + public void setAnchorPoint(int point) { this.anchorPoint = AnchorPoint.fromId(point); } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java index fd9f25a24..84701b79e 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityGuard.java @@ -14,13 +14,15 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityGuard; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityGuard; + import java.util.Random; /** * Guard ability: Defensive stance that reduces incoming damage. * Can optionally counter-attack when hit. */ -public class AbilityGuard extends Ability { +public class AbilityGuard extends Ability implements IAbilityGuard { private static final Random RANDOM = new Random(); @@ -228,18 +230,34 @@ public class AbilityGuard extends Ability { return canCounter; } + @Override + public boolean canCounter() { + return canCounter; + } + public void setCanCounter(boolean canCounter) { this.canCounter = canCounter; } - public CounterType getCounterType() { + public CounterType getCounterTypeEnum() { return counterType; } - public void setCounterType(CounterType counterType) { + public void setCounterTypeEnum(CounterType counterType) { this.counterType = counterType; } + @Override + public int getCounterType() { + return counterType.ordinal(); + } + + @Override + public void setCounterType(int type) { + CounterType[] values = CounterType.values(); + this.counterType = type >= 0 && type < values.length ? values[type] : CounterType.FLAT; + } + public float getCounterValue() { return counterValue; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java index 3e9998f6f..79e43e2cc 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHazard.java @@ -18,6 +18,8 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityHazard; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityHazard; + import java.util.HashSet; import java.util.List; import java.util.Random; @@ -27,7 +29,7 @@ import java.util.Set; * Hazard ability: Creates persistent ground effect zones. * Deals damage and/or applies debuffs to entities in the zone over time. */ -public class AbilityHazard extends Ability { +public class AbilityHazard extends Ability implements IAbilityHazard { public enum HazardShape { CIRCLE, @@ -443,22 +445,44 @@ public class AbilityHazard extends Ability { this.coneAngle = coneAngle; } - public HazardShape getShape() { + public HazardShape getShapeEnum() { return shape; } - public void setShape(HazardShape shape) { + public void setShapeEnum(HazardShape shape) { this.shape = shape; } - public PlacementMode getPlacement() { + @Override + public int getShape() { + return shape.ordinal(); + } + + @Override + public void setShape(int shape) { + HazardShape[] values = HazardShape.values(); + this.shape = shape >= 0 && shape < values.length ? values[shape] : HazardShape.CIRCLE; + } + + public PlacementMode getPlacementEnum() { return placement; } - public void setPlacement(PlacementMode placement) { + public void setPlacementEnum(PlacementMode placement) { this.placement = placement; } + @Override + public int getPlacement() { + return placement.ordinal(); + } + + @Override + public void setPlacement(int placement) { + PlacementMode[] values = PlacementMode.values(); + this.placement = placement >= 0 && placement < values.length ? values[placement] : PlacementMode.AT_CASTER; + } + public float getDamagePerSecond() { return damagePerSecond; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeal.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeal.java index f19a7cb02..11aed6c47 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeal.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeal.java @@ -15,6 +15,8 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityHeal; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityHeal; + import java.util.ArrayList; import java.util.List; @@ -22,7 +24,7 @@ import java.util.List; * Heal ability: Restore health to self or allies. * Can heal a fixed amount or percentage of max health. */ -public class AbilityHeal extends Ability { +public class AbilityHeal extends Ability implements IAbilityHeal { // Type-specific parameters private int durationTicks = 60; diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeavyHit.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeavyHit.java index 32335daeb..82091c041 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeavyHit.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityHeavyHit.java @@ -11,13 +11,14 @@ import net.minecraft.world.World; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityHeavyHit; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.api.ability.type.IAbilityHeavyHit; import noppes.npcs.entity.EntityNPCInterface; /** * Heavy Hit ability: Single-target melee attack with optional stun. * Deals high damage to one target and can stun them. */ -public class AbilityHeavyHit extends Ability { +public class AbilityHeavyHit extends Ability implements IAbilityHeavyHit { private float damage = 8.0f; private float knockback = 2.0f; diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java index 8084aaad4..44b6bc0b5 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityLaserShot.java @@ -13,13 +13,14 @@ import net.minecraft.world.World; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityLaserShot; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.api.ability.type.IAbilityLaserShot; import noppes.npcs.entity.EntityNPCInterface; /** * Laser Shot ability: Fast expanding thin line that pierces through targets. * Travels in a straight line from origin, damaging all entities it passes through. */ -public class AbilityLaserShot extends Ability { +public class AbilityLaserShot extends Ability implements IAbilityLaserShot { // Laser properties private float laserWidth = 0.3f; diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java index 4832c2281..fabdf6ab0 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityOrb.java @@ -19,6 +19,7 @@ import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityOrb; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.controllers.data.Animation; +import noppes.npcs.api.ability.type.IAbilityOrb; import noppes.npcs.entity.EntityNPCInterface; /** @@ -26,7 +27,7 @@ import noppes.npcs.entity.EntityNPCInterface; * The EntityAbilityOrb handles all movement, collision, and damage logic. * This ability just configures and spawns the orb entity. */ -public class AbilityOrb extends Ability { +public class AbilityOrb extends Ability implements IAbilityOrb { // Movement properties private float orbSpeed = 0.5f; @@ -456,11 +457,11 @@ public class AbilityOrb extends Ability { this.lightningFadeTime = lightningFadeTime; } - public AnchorPoint getAnchorPoint() { + public AnchorPoint getAnchorPointEnum() { return anchorPoint; } - public void setAnchorPoint(AnchorPoint anchorPoint) { + public void setAnchorPointEnum(AnchorPoint anchorPoint) { this.anchorPoint = anchorPoint; } @@ -471,4 +472,13 @@ public class AbilityOrb extends Ability { return animation.windUp(); } + + public int getAnchorPoint() { + return anchorPoint.getId(); + } + + @Override + public void setAnchorPoint(int point) { + this.anchorPoint = AnchorPoint.fromId(point); + } } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java index 4a12ae4eb..56b12028e 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityProjectile.java @@ -14,13 +14,15 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityProjectile; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityProjectile; + import java.util.List; /** * Projectile ability: Ranged attack that deals damage to target. * Currently instant damage - can be enhanced with custom projectile entities. */ -public class AbilityProjectile extends Ability { +public class AbilityProjectile extends Ability implements IAbilityProjectile { // Type-specific parameters private float damage = 6.0f; diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityShockwave.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityShockwave.java index 71d888978..c6b93134a 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityShockwave.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityShockwave.java @@ -15,13 +15,15 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityShockwave; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityShockwave; + import java.util.List; /** * Shockwave ability: Pushes targets away from the caster with damage. * Opposite of Vortex - instant knockback rather than gradual pull. */ -public class AbilityShockwave extends Ability { +public class AbilityShockwave extends Ability implements IAbilityShockwave { private float pushRadius = 8.0f; private float pushStrength = 1.5f; diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java index dcb914a96..ba49ffb2c 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySlam.java @@ -17,6 +17,8 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilitySlam; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilitySlam; + import java.util.List; /** @@ -28,7 +30,7 @@ import java.util.List; * - Landing: When NPC hits ground, deal AOE damage * - RECOVERY: Landing recovery animation */ -public class AbilitySlam extends Ability { +public class AbilitySlam extends Ability implements IAbilitySlam { // Type-specific config private float damage = 10.0f; diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java index 5a61c5dce..66f589a00 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilitySweeper.java @@ -15,6 +15,7 @@ import noppes.npcs.LogWriter; import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig; import noppes.npcs.client.gui.advanced.ability.SubGuiAbilitySweeper; import noppes.npcs.client.gui.util.IAbilityConfigCallback; +import noppes.npcs.api.ability.type.IAbilitySweeper; import noppes.npcs.entity.EntityNPCInterface; /** @@ -25,7 +26,7 @@ import noppes.npcs.entity.EntityNPCInterface; * All damage logic is handled by the EntityAbilitySweeper entity to ensure * visual and damage hitbox alignment. */ -public class AbilitySweeper extends Ability { +public class AbilitySweeper extends Ability implements IAbilitySweeper { // Type-specific parameters private float beamLength = 10.0f; diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTeleport.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTeleport.java index 218432fc9..05293a467 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTeleport.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTeleport.java @@ -18,13 +18,15 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityTeleport; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityTeleport; + import java.util.List; import java.util.Random; /** * Teleport ability: Instant reposition with wall/line-of-sight checks. */ -public class AbilityTeleport extends Ability { +public class AbilityTeleport extends Ability implements IAbilityTeleport { /** * Teleport behavior mode. @@ -440,14 +442,25 @@ public class AbilityTeleport extends Ability { } // Getters & Setters - public TeleportMode getMode() { + public TeleportMode getModeEnum() { return mode; } - public void setMode(TeleportMode mode) { + public void setModeEnum(TeleportMode mode) { this.mode = mode; } + @Override + public int getMode() { + return mode.ordinal(); + } + + @Override + public void setMode(int mode) { + TeleportMode[] values = TeleportMode.values(); + this.mode = mode >= 0 && mode < values.length ? values[mode] : TeleportMode.BLINK; + } + public int getBlinkCount() { return blinkCount; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTrap.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTrap.java index dbb7273cd..b14a9ad67 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTrap.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityTrap.java @@ -16,6 +16,8 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityTrap; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityTrap; + import java.util.HashSet; import java.util.List; import java.util.Random; @@ -26,7 +28,7 @@ import java.util.UUID; * Trap ability: Places a proximity-triggered trap. * Features arm time, trigger radius, and various effects on trigger. */ -public class AbilityTrap extends Ability { +public class AbilityTrap extends Ability implements IAbilityTrap { public enum TrapPlacement { AT_CASTER, @@ -330,14 +332,25 @@ public class AbilityTrap extends Ability { this.durationTicks = Math.max(1, durationTicks); } - public TrapPlacement getPlacement() { + public TrapPlacement getPlacementEnum() { return placement; } - public void setPlacement(TrapPlacement placement) { + public void setPlacementEnum(TrapPlacement placement) { this.placement = placement; } + @Override + public int getPlacement() { + return placement.ordinal(); + } + + @Override + public void setPlacement(int placement) { + TrapPlacement[] values = TrapPlacement.values(); + this.placement = placement >= 0 && placement < values.length ? values[placement] : TrapPlacement.AT_TARGET; + } + public float getPlacementDistance() { return placementDistance; } diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityVortex.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityVortex.java index fef61779e..a85bbc442 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityVortex.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityVortex.java @@ -14,6 +14,8 @@ import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityVortex; import noppes.npcs.client.gui.util.IAbilityConfigCallback; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.api.ability.type.IAbilityVortex; + import java.util.HashSet; import java.util.List; import java.util.Set; @@ -23,7 +25,7 @@ import java.util.UUID; * Vortex ability: Pulls targets toward the caster. * Can pull single target or AOE, with optional damage and stun on arrival. */ -public class AbilityVortex extends Ability { +public class AbilityVortex extends Ability implements IAbilityVortex { private float pullRadius = 8.0f; private float pullStrength = 0.8f; diff --git a/src/main/java/noppes/npcs/DataAbilities.java b/src/main/java/noppes/npcs/DataAbilities.java index 0ff0aa8a1..2ddabc588 100644 --- a/src/main/java/noppes/npcs/DataAbilities.java +++ b/src/main/java/noppes/npcs/DataAbilities.java @@ -604,6 +604,50 @@ public class DataAbilities { } } + /** + * Force start a specific ability, bypassing normal selection and cooldown. + * If an ability is currently executing, it will be cancelled. + * + * @param ability The ability to start + * @param target The target entity (can be null for self-targeted abilities) + * @return true if the ability was started successfully + */ + public boolean forceStartAbility(Ability ability, EntityLivingBase target) { + if (ability == null || npc.worldObj.isRemote) { + return false; + } + + // Stop any currently executing ability + stopCurrentAbility(); + + // Reset the ability state + ability.reset(); + + // Start the ability directly + return startAbility(ability, target); + } + + /** + * Execute a preset ability on this NPC. + * The NPC does NOT need to have this ability assigned. + * + * @param presetName The name of the saved ability preset + * @param target The target entity (can be null for self-targeted abilities) + * @return true if the ability was started successfully + */ + public boolean executePresetAbility(String presetName, EntityLivingBase target) { + if (presetName == null || presetName.isEmpty() || npc.worldObj.isRemote) { + return false; + } + + Ability preset = AbilityController.Instance.getSavedAbility(presetName); + if (preset == null) { + return false; + } + + return forceStartAbility(preset, target); + } + // ═══════════════════════════════════════════════════════════════════ // SCRIPT EVENTS // ═══════════════════════════════════════════════════════════════════ diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java index f10c63eef..a1539536d 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityCutter.java @@ -61,7 +61,7 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig { // Row 4: Sweep Mode + Piercing addLabel(new GuiNpcLabel(106, "ability.sweepMode", labelX, y + 5)); String[] sweepModes = {"Swipe", "Spin"}; - GuiNpcButton sweepModeBtn = new GuiNpcButton(106, fieldX, y, 70, 20, sweepModes, cutter.getSweepMode().ordinal()); + GuiNpcButton sweepModeBtn = new GuiNpcButton(106, fieldX, y, 70, 20, sweepModes, cutter.getSweepModeEnum().ordinal()); sweepModeBtn.setHoverText("ability.hover.sweepMode"); addButton(sweepModeBtn); @@ -73,7 +73,7 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig { y += 24; // Row 5: Spin Duration (only for SPIN mode) + Effects button - if (cutter.getSweepMode() == AbilityCutter.SweepMode.SPIN) { + if (cutter.getSweepModeEnum() == AbilityCutter.SweepMode.SPIN) { addLabel(new GuiNpcLabel(108, "ability.duration", labelX, y + 5)); GuiNpcTextField durationField = createIntField(108, fieldX, y, 50, cutter.getSpinDurationTicks()); durationField.setMinMaxDefault(1, 1000, 60); @@ -88,7 +88,7 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig { int value = button.getValue(); switch (id) { case 106: - cutter.setSweepMode(AbilityCutter.SweepMode.values()[value]); + cutter.setSweepModeEnum(AbilityCutter.SweepMode.values()[value]); initGui(); // Refresh to show/hide duration field break; case 107: diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDash.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDash.java index f113b3c1c..9d7bd63b6 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDash.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDash.java @@ -30,7 +30,7 @@ public class SubGuiAbilityDash extends SubGuiAbilityConfig { // Row 1: Dash Mode addLabel(new GuiNpcLabel(100, "ability.mode", labelX, y + 5)); String[] dashModes = {"Aggressive", "Defensive"}; - GuiNpcButton modeBtn = new GuiNpcButton(100, fieldX, y, 80, 20, dashModes, dash.getDashMode().ordinal()); + GuiNpcButton modeBtn = new GuiNpcButton(100, fieldX, y, 80, 20, dashModes, dash.getDashModeEnum().ordinal()); modeBtn.setHoverText("ability.hover.dashMode"); addButton(modeBtn); @@ -47,7 +47,7 @@ public class SubGuiAbilityDash extends SubGuiAbilityConfig { @Override protected void handleTypeButton(int id, GuiNpcButton button) { if (id == 100) { - dash.setDashMode(AbilityDash.DashMode.values()[button.getValue()]); + dash.setDashModeEnum(AbilityDash.DashMode.values()[button.getValue()]); } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDisc.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDisc.java index 2b804d99b..00383853f 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDisc.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityDisc.java @@ -122,7 +122,7 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig { // Row 1: Anchor Point addLabel(new GuiNpcLabel(210, "ability.anchorPoint", labelX, y + 5)); - GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), disc.getAnchorPoint().getId()); + GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), disc.getAnchorPointEnum().getId()); anchorBtn.setHoverText("ability.hover.anchorPoint"); addButton(anchorBtn); @@ -227,7 +227,7 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig { initGui(); break; case 210: - disc.setAnchorPoint(AnchorPoint.fromId(value)); + disc.setAnchorPointEnum(AnchorPoint.fromId(value)); break; } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEnergyBeam.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEnergyBeam.java index 6e90428ce..d878c9381 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEnergyBeam.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityEnergyBeam.java @@ -118,7 +118,7 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig { // Row 1: Anchor Point addLabel(new GuiNpcLabel(210, "ability.anchorPoint", labelX, y + 5)); - GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), beam.getAnchorPoint().getId()); + GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), beam.getAnchorPointEnum().getId()); anchorBtn.setHoverText("ability.hover.anchorPoint"); addButton(anchorBtn); @@ -219,7 +219,7 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig { initGui(); break; case 210: - beam.setAnchorPoint(AnchorPoint.fromId(value)); + beam.setAnchorPointEnum(AnchorPoint.fromId(value)); break; } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java index a975a97fc..0d2ec667b 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityGuard.java @@ -50,7 +50,7 @@ public class SubGuiAbilityGuard extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(102, "ability.counterType", col2LabelX, y + 5)); String[] types = {"Flat", "Percent"}; - GuiNpcButton counterTypeButton = new GuiNpcButton(102, col2FieldX, y, 60, 20, types, guard.getCounterType().ordinal()); + GuiNpcButton counterTypeButton = new GuiNpcButton(102, col2FieldX, y, 60, 20, types, guard.getCounterTypeEnum().ordinal()); counterTypeButton.setHoverText("ability.hover.counterType"); counterTypeButton.setEnabled(guard.isCanCounter()); addButton(counterTypeButton); @@ -97,7 +97,7 @@ public class SubGuiAbilityGuard extends SubGuiAbilityConfig { initGui(); break; case 102: - guard.setCounterType(AbilityGuard.CounterType.values()[button.getValue()]); + guard.setCounterTypeEnum(AbilityGuard.CounterType.values()[button.getValue()]); break; case 150: setSubGui(new SubGuiAbilityEffects(guard.getEffects())); diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java index 9822d9f90..5b8be7976 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityHazard.java @@ -39,7 +39,7 @@ public class SubGuiAbilityHazard extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(100, "ability.shape", col2LabelX, y + 5)); String[] shapes = {"Circle", "Ring", "Cone"}; - GuiNpcButton shapeBtn = new GuiNpcButton(100, col2FieldX, y, 55, 20, shapes, hazard.getShape().ordinal()); + GuiNpcButton shapeBtn = new GuiNpcButton(100, col2FieldX, y, 55, 20, shapes, hazard.getShapeEnum().ordinal()); shapeBtn.setHoverText("ability.hover.shape"); addButton(shapeBtn); @@ -48,7 +48,7 @@ public class SubGuiAbilityHazard extends SubGuiAbilityConfig { // Row 2: Placement addLabel(new GuiNpcLabel(101, "ability.placement", labelX, y + 5)); String[] placements = {"Caster", "Target", "FollowCast", "FollowTgt"}; - GuiNpcButton placementBtn = new GuiNpcButton(101, fieldX, y, 70, 20, placements, hazard.getPlacement().ordinal()); + GuiNpcButton placementBtn = new GuiNpcButton(101, fieldX, y, 70, 20, placements, hazard.getPlacementEnum().ordinal()); placementBtn.setHoverText("ability.hover.placement"); addButton(placementBtn); @@ -101,10 +101,10 @@ public class SubGuiAbilityHazard extends SubGuiAbilityConfig { int value = button.getValue(); switch (id) { case 100: - hazard.setShape(AbilityHazard.HazardShape.values()[value]); + hazard.setShapeEnum(AbilityHazard.HazardShape.values()[value]); break; case 101: - hazard.setPlacement(AbilityHazard.PlacementMode.values()[value]); + hazard.setPlacementEnum(AbilityHazard.PlacementMode.values()[value]); break; case 109: hazard.setAffectsCaster(value == 1); diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityOrb.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityOrb.java index 858eeefa7..40cff112f 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityOrb.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityOrb.java @@ -106,7 +106,7 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig { // Row 1: Anchor Point addLabel(new GuiNpcLabel(210, "ability.anchorPoint", labelX, y + 5)); - GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), orb.getAnchorPoint().getId()); + GuiNpcButton anchorBtn = new GuiNpcButton(210, fieldX, y, 80, 20, AnchorPoint.getDisplayNames(), orb.getAnchorPointEnum().getId()); anchorBtn.setHoverText("ability.hover.anchorPoint"); addButton(anchorBtn); @@ -207,7 +207,7 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig { initGui(); break; case 210: - orb.setAnchorPoint(AnchorPoint.fromId(value)); + orb.setAnchorPointEnum(AnchorPoint.fromId(value)); break; } } diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java index e39918d2d..4b23b0ca0 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTeleport.java @@ -34,11 +34,11 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig { // Row 1: Mode addLabel(new GuiNpcLabel(100, "ability.mode", labelX, y + 5)); String[] modes = {"Blink", "Behind", "Single"}; - addButton(new GuiNpcButton(100, fieldX, y, 80, 20, modes, teleport.getMode().ordinal())); + addButton(new GuiNpcButton(100, fieldX, y, 80, 20, modes, teleport.getModeEnum().ordinal())); y += 24; - switch (teleport.getMode()) { + switch (teleport.getModeEnum()) { case BLINK: // Row 2: Blink Radius + Blink Count addLabel(new GuiNpcLabel(101, "ability.blinkRadius", labelX, y + 5)); @@ -109,7 +109,7 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig { int value = button.getValue(); switch (id) { case 100: - teleport.setMode(AbilityTeleport.TeleportMode.values()[value]); + teleport.setModeEnum(AbilityTeleport.TeleportMode.values()[value]); initGui(); break; case 105: diff --git a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java index edeb59635..5c9c52558 100644 --- a/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java +++ b/src/main/java/noppes/npcs/client/gui/advanced/ability/SubGuiAbilityTrap.java @@ -39,7 +39,7 @@ public class SubGuiAbilityTrap extends SubGuiAbilityConfig { addLabel(new GuiNpcLabel(100, "ability.placement", col2LabelX, y + 5)); String[] placements = {"Caster", "Target", "Ahead"}; - GuiNpcButton placementBtn = new GuiNpcButton(100, col2FieldX, y, 55, 20, placements, trap.getPlacement().ordinal()); + GuiNpcButton placementBtn = new GuiNpcButton(100, col2FieldX, y, 55, 20, placements, trap.getPlacementEnum().ordinal()); placementBtn.setHoverText("ability.hover.placement"); addButton(placementBtn); @@ -79,7 +79,7 @@ public class SubGuiAbilityTrap extends SubGuiAbilityConfig { @Override protected void handleTypeButton(int id, GuiNpcButton button) { if (id == 100) { - trap.setPlacement(AbilityTrap.TrapPlacement.values()[button.getValue()]); + trap.setPlacementEnum(AbilityTrap.TrapPlacement.values()[button.getValue()]); } else if (id == 150) { setSubGui(new SubGuiAbilityEffects(trap.getEffects())); } diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java index 8b632f7ce..26f7a1ba7 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java @@ -1457,4 +1457,8 @@ public class ScriptNpc extends ScriptLiving imp public IMagicData getMagicData() { return npc.stats.magicData; } + + public noppes.npcs.api.ability.IDataAbilities getAbilityData() { + return new noppes.npcs.scripted.wrapper.ScriptDataAbilities(npc); + } } diff --git a/src/main/java/noppes/npcs/scripted/wrapper/ScriptDataAbilities.java b/src/main/java/noppes/npcs/scripted/wrapper/ScriptDataAbilities.java new file mode 100644 index 000000000..d097a892c --- /dev/null +++ b/src/main/java/noppes/npcs/scripted/wrapper/ScriptDataAbilities.java @@ -0,0 +1,163 @@ +package noppes.npcs.scripted.wrapper; + +import kamkeel.npcs.controllers.data.ability.Ability; +import kamkeel.npcs.controllers.data.ability.AbilityController; +import net.minecraft.entity.EntityLivingBase; +import noppes.npcs.DataAbilities; +import noppes.npcs.api.ability.IAbility; +import noppes.npcs.api.ability.IDataAbilities; +import noppes.npcs.entity.EntityNPCInterface; + +/** + * Script wrapper for DataAbilities providing API access to NPC abilities. + */ +public class ScriptDataAbilities implements IDataAbilities { + + private final DataAbilities data; + private final EntityNPCInterface npc; + + public ScriptDataAbilities(EntityNPCInterface npc) { + this.npc = npc; + this.data = npc.abilities; + } + + @Override + public boolean isEnabled() { + return data.enabled; + } + + @Override + public void setEnabled(boolean enabled) { + data.enabled = enabled; + } + + @Override + public IAbility[] getAbilities() { + return data.getAbilities().toArray(new IAbility[0]); + } + + @Override + public void addAbility(IAbility ability) { + if (ability instanceof Ability) { + data.addAbility((Ability) ability); + } + } + + @Override + public void removeAbility(String abilityId) { + data.removeAbility(abilityId); + } + + @Override + public IAbility getAbility(String abilityId) { + return data.getAbility(abilityId); + } + + @Override + public boolean hasAbility(String abilityId) { + return data.getAbility(abilityId) != null; + } + + @Override + public void clearAbilities() { + data.clearAbilities(); + } + + @Override + public IAbility getCurrentAbility() { + return data.getCurrentAbility(); + } + + @Override + public boolean isExecutingAbility() { + return data.isExecutingAbility(); + } + + @Override + public void interruptCurrentAbility() { + data.interruptCurrentAbility(null, 0); + } + + @Override + public int getGlobalCooldown() { + return (int) data.getRemainingCooldown(); + } + + @Override + public void setGlobalCooldown(int ticks) { + // Set the cooldown by manipulating the internal cooldown end time + // Not directly exposed, but we can reset and let it tick down + data.resetCooldown(); + // This is a best-effort implementation + } + + @Override + public void resetCooldowns() { + data.resetCooldown(); + } + + @Override + public boolean forceStartAbility(String abilityId) { + return forceStartAbility(abilityId, null); + } + + @Override + public boolean forceStartAbility(String abilityId, Object target) { + // Find the ability + Ability ability = data.getAbility(abilityId); + if (ability == null) { + return false; + } + + // Resolve target + EntityLivingBase targetEntity = resolveTarget(target); + + // Use the direct force start method + return data.forceStartAbility(ability, targetEntity); + } + + @Override + public boolean executePresetAbility(String presetName) { + return executePresetAbility(presetName, null); + } + + @Override + public boolean executePresetAbility(String presetName, Object target) { + // Resolve target + EntityLivingBase targetEntity = resolveTarget(target); + + // Use the direct preset execution method + return data.executePresetAbility(presetName, targetEntity); + } + + @Override + public IAbility createAbility(String typeId) { + if (AbilityController.Instance == null) { + return null; + } + return AbilityController.Instance.create(typeId); + } + + /** + * Resolve a target object to an EntityLivingBase. + */ + private EntityLivingBase resolveTarget(Object target) { + if (target == null) { + // Try to use the NPC's current attack target + return npc.getAttackTarget(); + } + + if (target instanceof EntityLivingBase) { + return (EntityLivingBase) target; + } + + if (target instanceof noppes.npcs.api.entity.IEntityLivingBase) { + Object mcEntity = ((noppes.npcs.api.entity.IEntityLivingBase) target).getMCEntity(); + if (mcEntity instanceof EntityLivingBase) { + return (EntityLivingBase) mcEntity; + } + } + + return null; + } +}