mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 16:37:45 +00:00
Better Lock Movement handling
This commit is contained in:
1 parent
83ccd25b33
commit
7d2bba7b95
24 files changed
+227
-60
No files matched your search
@@ -55,7 +55,7 @@ public abstract class Ability implements IAbility {
|
||||
protected boolean interruptible = true;
|
||||
|
||||
// Feedback
|
||||
protected boolean lockMovement = true;
|
||||
protected LockMovementType lockMovement = LockMovementType.WINDUP;
|
||||
protected int windUpColor = 0x80FF4400; // Telegraph color during wind up
|
||||
protected int activeColor = 0xC0FF0000; // Telegraph warning/active color
|
||||
|
||||
@@ -662,7 +662,7 @@ public abstract class Ability implements IAbility {
|
||||
nbt.setInteger("windUp", windUpTicks);
|
||||
nbt.setInteger("recovery", dazedTicks);
|
||||
nbt.setBoolean("interruptible", interruptible);
|
||||
nbt.setBoolean("lockMovement", lockMovement);
|
||||
nbt.setInteger("lockMovement", lockMovement.ordinal());
|
||||
nbt.setInteger("windUpColor", windUpColor);
|
||||
nbt.setInteger("activeColor", activeColor);
|
||||
nbt.setString("windUpSound", windUpSound);
|
||||
@@ -707,7 +707,7 @@ public abstract class Ability implements IAbility {
|
||||
windUpTicks = nbt.getInteger("windUp");
|
||||
dazedTicks = nbt.getInteger("recovery");
|
||||
interruptible = nbt.getBoolean("interruptible");
|
||||
lockMovement = nbt.getBoolean("lockMovement");
|
||||
lockMovement = LockMovementType.fromOrdinal(nbt.getInteger("lockMovement"));
|
||||
// Support old telegraphColor key for backwards compatibility
|
||||
if (nbt.hasKey("windUpColor")) {
|
||||
windUpColor = nbt.getInteger("windUpColor");
|
||||
@@ -868,14 +868,62 @@ public abstract class Ability implements IAbility {
|
||||
this.interruptible = interruptible;
|
||||
}
|
||||
|
||||
public boolean isLockMovement() {
|
||||
public LockMovementType getLockMovement() {
|
||||
return lockMovement;
|
||||
}
|
||||
|
||||
public void setLockMovement(boolean lockMovement) {
|
||||
public void setLockMovement(LockMovementType lockMovement) {
|
||||
this.lockMovement = lockMovement;
|
||||
}
|
||||
|
||||
/**
|
||||
* API method: Get lock movement type as integer.
|
||||
* @return 0=NO, 1=WINDUP, 2=ACTIVE, 3=WINDUP_AND_ACTIVE
|
||||
*/
|
||||
@Override
|
||||
public int getLockMovementType() {
|
||||
return lockMovement.ordinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* API method: Set lock movement type from integer.
|
||||
* @param type 0=NO, 1=WINDUP, 2=ACTIVE, 3=WINDUP_AND_ACTIVE
|
||||
*/
|
||||
@Override
|
||||
public void setLockMovementType(int type) {
|
||||
this.lockMovement = LockMovementType.fromOrdinal(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if movement should be locked during WINDUP phase.
|
||||
*/
|
||||
@Override
|
||||
public boolean isMovementLockedDuringWindup() {
|
||||
return lockMovement.locksWindup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if movement should be locked during ACTIVE phase.
|
||||
*/
|
||||
@Override
|
||||
public boolean isMovementLockedDuringActive() {
|
||||
return lockMovement.locksActive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if movement should be locked during the current phase.
|
||||
*/
|
||||
public boolean isMovementLockedForCurrentPhase() {
|
||||
switch (phase) {
|
||||
case WINDUP:
|
||||
return lockMovement.locksWindup();
|
||||
case ACTIVE:
|
||||
return lockMovement.locksActive();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int getWindUpColor() {
|
||||
return windUpColor;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package kamkeel.npcs.controllers.data.ability;
|
||||
|
||||
/**
|
||||
* Defines when an ability locks NPC movement and rotation.
|
||||
*/
|
||||
public enum LockMovementType {
|
||||
/**
|
||||
* No movement lock - NPC can move freely during both phases.
|
||||
*/
|
||||
NO,
|
||||
|
||||
/**
|
||||
* Lock movement during WINDUP phase only.
|
||||
* NPC can move during ACTIVE phase.
|
||||
*/
|
||||
WINDUP,
|
||||
|
||||
/**
|
||||
* Lock movement during ACTIVE phase only.
|
||||
* NPC can move during WINDUP phase.
|
||||
*/
|
||||
ACTIVE,
|
||||
|
||||
/**
|
||||
* Lock movement during both WINDUP and ACTIVE phases.
|
||||
*/
|
||||
WINDUP_AND_ACTIVE;
|
||||
|
||||
/**
|
||||
* Check if movement should be locked during WINDUP phase.
|
||||
*/
|
||||
public boolean locksWindup() {
|
||||
return this == WINDUP || this == WINDUP_AND_ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if movement should be locked during ACTIVE phase.
|
||||
*/
|
||||
public boolean locksActive() {
|
||||
return this == ACTIVE || this == WINDUP_AND_ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get display name for GUI.
|
||||
*/
|
||||
public String getDisplayKey() {
|
||||
switch (this) {
|
||||
case NO:
|
||||
return "gui.no";
|
||||
case WINDUP:
|
||||
return "ability.lockMove.windup";
|
||||
case ACTIVE:
|
||||
return "ability.lockMove.active";
|
||||
case WINDUP_AND_ACTIVE:
|
||||
return "ability.lockMove.both";
|
||||
default:
|
||||
return "gui.no";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all display keys for GUI dropdown.
|
||||
*/
|
||||
public static String[] getDisplayKeys() {
|
||||
return new String[]{
|
||||
"gui.no",
|
||||
"ability.lockMove.windup",
|
||||
"ability.lockMove.active",
|
||||
"ability.lockMove.both"
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LockMovementType from ordinal, with fallback to WINDUP.
|
||||
*/
|
||||
public static LockMovementType fromOrdinal(int ordinal) {
|
||||
LockMovementType[] values = values();
|
||||
if (ordinal >= 0 && ordinal < values.length) {
|
||||
return values[ordinal];
|
||||
}
|
||||
return WINDUP;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.Telegraph;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
|
||||
@@ -47,7 +48,7 @@ public class AbilityCharge extends Ability implements IAbilityCharge {
|
||||
this.targetingMode = TargetingMode.AGGRO_TARGET;
|
||||
this.maxRange = 20.0f;
|
||||
this.minRange = 4.0f;
|
||||
this.lockMovement = false; // Movement IS the ability
|
||||
this.lockMovement = LockMovementType.WINDUP;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 20;
|
||||
// LINE telegraph showing charge path
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
@@ -54,7 +55,7 @@ public class AbilityCutter extends Ability implements IAbilityCutter {
|
||||
this.name = "Cutter";
|
||||
this.targetingMode = TargetingMode.AOE_SELF;
|
||||
this.maxRange = 8.0f;
|
||||
this.lockMovement = true;
|
||||
this.lockMovement = LockMovementType.NO;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 20;
|
||||
this.telegraphType = TelegraphType.CONE;
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
@@ -88,7 +89,7 @@ public class AbilityDash extends Ability implements IAbilityDash {
|
||||
this.targetingMode = TargetingMode.AGGRO_TARGET;
|
||||
this.maxRange = 20.0f;
|
||||
this.minRange = 0.0f;
|
||||
this.lockMovement = false;
|
||||
this.lockMovement = LockMovementType.NO;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 5;
|
||||
// No telegraph for dash - it's a quick evasive move
|
||||
|
||||
@@ -4,6 +4,7 @@ import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.AnchorPoint;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.Telegraph;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
|
||||
@@ -83,6 +84,7 @@ public class AbilityDisc extends Ability implements IAbilityDisc {
|
||||
this.minRange = 5.0f;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 20;
|
||||
this.lockMovement = LockMovementType.WINDUP;
|
||||
this.telegraphType = TelegraphType.CIRCLE;
|
||||
this.showTelegraph = true;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.AbilityAnimation;
|
||||
import kamkeel.npcs.controllers.data.ability.AnchorPoint;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.Telegraph;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
|
||||
@@ -85,6 +86,7 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam {
|
||||
this.minRange = 5.0f;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 40;
|
||||
this.lockMovement = LockMovementType.WINDUP_AND_ACTIVE;
|
||||
this.telegraphType = TelegraphType.CIRCLE;
|
||||
this.showTelegraph = true;
|
||||
}
|
||||
@@ -145,7 +147,7 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam {
|
||||
stunDuration, slowDuration, slowLevel,
|
||||
maxDistance, maxLifetime,
|
||||
lightningEffect, lightningDensity, lightningRadius,
|
||||
lockMovement, // Anchored mode
|
||||
lockMovement.locksActive(), // Anchored mode during firing
|
||||
windUpTicks, // Charge duration = windup duration
|
||||
offsetDist, // Offset distance (used by FRONT anchor)
|
||||
anchorPoint // Anchor point for charging position
|
||||
@@ -311,7 +313,7 @@ public class AbilityEnergyBeam extends Ability implements IAbilityEnergyBeam {
|
||||
public float getLightningRadius() { return lightningRadius; }
|
||||
public void setLightningRadius(float lightningRadius) { this.lightningRadius = lightningRadius; }
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Animation getWindUpAnimation() {
|
||||
if (windUpAnimationId == -1)
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
@@ -50,7 +51,7 @@ public class AbilityGuard extends Ability implements IAbilityGuard {
|
||||
this.typeId = "ability.cnpc.guard";
|
||||
this.name = "Guard";
|
||||
this.targetingMode = TargetingMode.SELF;
|
||||
this.lockMovement = true;
|
||||
this.lockMovement = LockMovementType.ACTIVE;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 10;
|
||||
this.interruptible = false; // Hard to interrupt while guarding
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
@@ -83,7 +84,7 @@ public class AbilityHazard extends Ability implements IAbilityHazard {
|
||||
this.name = "Hazard";
|
||||
this.targetingMode = TargetingMode.AGGRO_TARGET;
|
||||
this.maxRange = 15.0f;
|
||||
this.lockMovement = true;
|
||||
this.lockMovement = LockMovementType.WINDUP;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 30;
|
||||
this.telegraphType = TelegraphType.CIRCLE;
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -49,7 +50,7 @@ public class AbilityHeal extends Ability implements IAbilityHeal {
|
||||
this.typeId = "ability.cnpc.heal";
|
||||
this.name = "Heal";
|
||||
this.targetingMode = TargetingMode.SELF;
|
||||
this.lockMovement = true;
|
||||
this.lockMovement = LockMovementType.WINDUP;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 30;
|
||||
// No telegraph for heal - it's a self/ally buff
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
@@ -29,7 +30,7 @@ public class AbilityHeavyHit extends Ability implements IAbilityHeavyHit {
|
||||
this.targetingMode = TargetingMode.AGGRO_TARGET;
|
||||
this.maxRange = 3.0f;
|
||||
this.minRange = 0.0f;
|
||||
this.lockMovement = true;
|
||||
this.lockMovement = LockMovementType.NO;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 30;
|
||||
this.telegraphType = TelegraphType.POINT;
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import kamkeel.npcs.entity.EntityAbilityLaser;
|
||||
@@ -63,6 +64,7 @@ public class AbilityLaserShot extends Ability implements IAbilityLaserShot {
|
||||
this.minRange = 3.0f;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 15;
|
||||
this.lockMovement = LockMovementType.WINDUP;
|
||||
this.telegraphType = TelegraphType.LINE;
|
||||
this.showTelegraph = true;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.AbilityAnimation;
|
||||
import kamkeel.npcs.controllers.data.ability.AnchorPoint;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.Telegraph;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
|
||||
@@ -84,6 +85,7 @@ public class AbilityOrb extends Ability implements IAbilityOrb {
|
||||
this.minRange = 5.0f;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 30;
|
||||
this.lockMovement = LockMovementType.WINDUP;
|
||||
this.telegraphType = TelegraphType.CIRCLE;
|
||||
this.showTelegraph = true;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -42,6 +43,7 @@ public class AbilityProjectile extends Ability implements IAbilityProjectile {
|
||||
this.maxRange = 20.0f;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 15;
|
||||
this.lockMovement = LockMovementType.NO;
|
||||
// No telegraph for projectile - it's a ranged attack
|
||||
this.telegraphType = TelegraphType.NONE;
|
||||
this.showTelegraph = false;
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
@@ -35,7 +36,7 @@ public class AbilityShockwave extends Ability implements IAbilityShockwave {
|
||||
this.name = "Shockwave";
|
||||
this.targetingMode = TargetingMode.AOE_SELF;
|
||||
this.maxRange = 15.0f;
|
||||
this.lockMovement = true;
|
||||
this.lockMovement = LockMovementType.WINDUP_AND_ACTIVE;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 25;
|
||||
this.telegraphType = TelegraphType.CIRCLE;
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.Telegraph;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
|
||||
@@ -52,7 +53,7 @@ public class AbilitySlam extends Ability implements IAbilitySlam {
|
||||
this.targetingMode = TargetingMode.AOE_SELF; // Can also be AOE_TARGET to leap to target
|
||||
this.windUpTicks = 30;
|
||||
this.cooldownTicks = 0;
|
||||
this.lockMovement = true;
|
||||
this.lockMovement = LockMovementType.WINDUP;
|
||||
this.minRange = 2.0f;
|
||||
this.maxRange = 15.0f;
|
||||
this.telegraphType = TelegraphType.CIRCLE;
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.Telegraph;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
|
||||
@@ -54,7 +55,7 @@ public class AbilitySweeper extends Ability implements IAbilitySweeper {
|
||||
this.targetingMode = TargetingMode.AGGRO_TARGET;
|
||||
this.maxRange = 15.0f;
|
||||
this.minRange = 0.0f;
|
||||
this.lockMovement = true;
|
||||
this.lockMovement = LockMovementType.WINDUP_AND_ACTIVE;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 60;
|
||||
// Circle telegraph to show range
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import net.minecraft.block.Block;
|
||||
@@ -63,6 +64,7 @@ public class AbilityTeleport extends Ability implements IAbilityTeleport {
|
||||
this.minRange = 5.0f;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 10;
|
||||
this.lockMovement = LockMovementType.NO;
|
||||
// No telegraph for teleport - it's instant repositioning
|
||||
this.telegraphType = TelegraphType.NONE;
|
||||
this.showTelegraph = false;
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
@@ -66,7 +67,7 @@ public class AbilityTrap extends Ability implements IAbilityTrap {
|
||||
this.name = "Trap";
|
||||
this.targetingMode = TargetingMode.AGGRO_TARGET;
|
||||
this.maxRange = 15.0f;
|
||||
this.lockMovement = true;
|
||||
this.lockMovement = LockMovementType.WINDUP;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 20;
|
||||
this.telegraphType = TelegraphType.CIRCLE;
|
||||
|
||||
@@ -3,6 +3,7 @@ package kamkeel.npcs.controllers.data.ability.type;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
@@ -53,7 +54,7 @@ public class AbilityVortex extends Ability implements IAbilityVortex {
|
||||
this.name = "Vortex";
|
||||
this.targetingMode = TargetingMode.AOE_SELF;
|
||||
this.maxRange = 15.0f;
|
||||
this.lockMovement = true;
|
||||
this.lockMovement = LockMovementType.WINDUP_AND_ACTIVE;
|
||||
this.cooldownTicks = 0;
|
||||
this.windUpTicks = 30;
|
||||
this.telegraphType = TelegraphType.CIRCLE;
|
||||
|
||||
@@ -79,7 +79,7 @@ public class DataAbilities {
|
||||
private transient List<Long> recentHitTimes = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Locked rotation values for ACTIVE phase with lockMovement.
|
||||
* Locked rotation values for ACTIVE phase when movement is locked.
|
||||
* Stored when entering ACTIVE phase, applied every tick to prevent rotation changes.
|
||||
*/
|
||||
private transient boolean rotationLocked = false;
|
||||
@@ -146,9 +146,9 @@ public class DataAbilities {
|
||||
// Remove telegraph - it has served its purpose
|
||||
removeTelegraph(currentAbility);
|
||||
|
||||
// Lock rotation if lockMovement is true
|
||||
// Lock rotation if movement is locked during ACTIVE phase
|
||||
// Capture current rotation values to force them every tick
|
||||
if (currentAbility.isLockMovement()) {
|
||||
if (currentAbility.isMovementLockedDuringActive()) {
|
||||
captureLockedRotation();
|
||||
}
|
||||
|
||||
@@ -191,6 +191,32 @@ public class DataAbilities {
|
||||
handleAbilityCompletion(target);
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply movement control if ability is still executing
|
||||
if (currentAbility != null && currentAbility.isExecuting()) {
|
||||
applyMovementControl();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply movement control based on lock movement settings.
|
||||
* Called every tick during ability execution.
|
||||
*/
|
||||
private void applyMovementControl() {
|
||||
if (currentAbility == null) return;
|
||||
|
||||
// Check if movement should be locked for the current phase
|
||||
if (currentAbility.isMovementLockedForCurrentPhase()) {
|
||||
// Clear navigator to prevent AI pathfinding
|
||||
npc.getNavigator().clearPathEntity();
|
||||
|
||||
// Zero motion if ability doesn't have its own movement
|
||||
// This allows abilities like Charge/Slam to control their own motion
|
||||
if (!currentAbility.hasAbilityMovement()) {
|
||||
npc.motionX = 0;
|
||||
npc.motionZ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,29 +236,11 @@ public class DataAbilities {
|
||||
npc.wrappedNPC, currentAbility, target);
|
||||
NpcAPI.EVENT_BUS.post(completeEvent);
|
||||
|
||||
// Clean up and roll cooldown
|
||||
// Release rotation lock before cleanup
|
||||
releaseLockedRotation();
|
||||
|
||||
// Clean up and roll cooldown (this sets currentAbility to null)
|
||||
onAbilityComplete();
|
||||
|
||||
// Clear AI pathfinding if ability is controlling movement
|
||||
// But DON'T zero motion - let the ability set it if needed
|
||||
if (currentAbility != null && currentAbility.isExecuting()) {
|
||||
if (isAbilityControllingMovement()) {
|
||||
// Clear navigator so AI doesn't fight with ability movement
|
||||
npc.getNavigator().clearPathEntity();
|
||||
|
||||
// Only zero motion if lockMovement is true AND ability doesn't have its own movement
|
||||
// This allows stationary abilities to freeze the NPC, while movement abilities can set their own motion
|
||||
if (currentAbility.isLockMovement() && !currentAbility.hasAbilityMovement()) {
|
||||
npc.motionX = 0;
|
||||
npc.motionZ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock rotation when leaving ACTIVE phase
|
||||
if (rotationLocked && currentAbility.getPhase() != AbilityPhase.ACTIVE) {
|
||||
releaseLockedRotation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -787,8 +795,8 @@ public class DataAbilities {
|
||||
* Called by AI tasks to determine if they should try to path.
|
||||
* <p>
|
||||
* Rules:
|
||||
* - WINDUP phase: Block AI if lockMovement is true
|
||||
* - ACTIVE phase: Block AI if lockMovement OR hasAbilityMovement is true
|
||||
* - WINDUP phase: Block AI if movement is locked during windup
|
||||
* - ACTIVE phase: Block AI if movement is locked during active OR hasAbilityMovement is true
|
||||
* - DAZED phase: Always block AI (NPC is stunned)
|
||||
*/
|
||||
public boolean isAbilityControllingMovement() {
|
||||
@@ -800,15 +808,15 @@ public class DataAbilities {
|
||||
|
||||
switch (phase) {
|
||||
case WINDUP:
|
||||
// During windup, only block if lockMovement is set
|
||||
// This allows NPC to keep chasing while winding up if lockMovement=false
|
||||
return currentAbility.isLockMovement();
|
||||
// During windup, only block if movement is locked during windup
|
||||
// This allows NPC to keep chasing while winding up if not locked
|
||||
return currentAbility.isMovementLockedDuringWindup();
|
||||
|
||||
case ACTIVE:
|
||||
// During active phase, block if either:
|
||||
// - lockMovement is true (stationary ability)
|
||||
// - movement is locked during active (stationary ability)
|
||||
// - hasAbilityMovement is true (ability is moving the NPC itself)
|
||||
return currentAbility.isLockMovement() || currentAbility.hasAbilityMovement();
|
||||
return currentAbility.isMovementLockedDuringActive() || currentAbility.hasAbilityMovement();
|
||||
|
||||
case DAZED:
|
||||
// During dazed phase, always block - NPC is stunned from interrupt
|
||||
@@ -821,7 +829,7 @@ public class DataAbilities {
|
||||
|
||||
/**
|
||||
* Check if NPC's look direction should be locked to target.
|
||||
* Only locks during ACTIVE phase when lockMovement is true.
|
||||
* Only locks during ACTIVE phase when movement is locked during active.
|
||||
* This allows the NPC to freely track target during WINDUP and DAZED.
|
||||
*/
|
||||
public boolean shouldLockLookDirection() {
|
||||
@@ -834,7 +842,7 @@ public class DataAbilities {
|
||||
return false;
|
||||
}
|
||||
|
||||
return currentAbility.isLockMovement();
|
||||
return currentAbility.isMovementLockedDuringActive();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -854,7 +862,7 @@ public class DataAbilities {
|
||||
|
||||
/**
|
||||
* Capture current rotation values to lock NPC's look direction.
|
||||
* Called when entering ACTIVE phase with lockMovement enabled.
|
||||
* Called when entering ACTIVE phase with movement locked during active.
|
||||
*/
|
||||
private void captureLockedRotation() {
|
||||
lockedYaw = npc.rotationYaw;
|
||||
|
||||
@@ -2,6 +2,7 @@ package noppes.npcs.client.gui.advanced;
|
||||
|
||||
import kamkeel.npcs.controllers.data.ability.Ability;
|
||||
import kamkeel.npcs.controllers.data.ability.Condition;
|
||||
import kamkeel.npcs.controllers.data.ability.LockMovementType;
|
||||
import kamkeel.npcs.controllers.data.ability.TargetingMode;
|
||||
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
|
||||
import noppes.npcs.controllers.data.Animation;
|
||||
@@ -58,7 +59,7 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
|
||||
protected String name;
|
||||
protected boolean enabled;
|
||||
protected int weight;
|
||||
protected boolean lockMovement;
|
||||
protected LockMovementType lockMovement;
|
||||
protected boolean interruptible;
|
||||
|
||||
// Timing
|
||||
@@ -111,7 +112,7 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
|
||||
this.name = ability.getName() != null ? ability.getName() : "";
|
||||
this.enabled = ability.isEnabled();
|
||||
this.weight = ability.getWeight();
|
||||
this.lockMovement = ability.isLockMovement();
|
||||
this.lockMovement = ability.getLockMovement();
|
||||
this.interruptible = ability.isInterruptible();
|
||||
|
||||
// Timing
|
||||
@@ -251,7 +252,7 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
|
||||
addTextField(weightField);
|
||||
|
||||
addLabel(new GuiNpcLabel(5, "ability.lockMove", col2LabelX, y + 5));
|
||||
GuiNpcButton lockMoveBtn = new GuiNpcButton(16, col2FieldX, y, 40, 20, new String[]{"gui.no", "gui.yes"}, lockMovement ? 1 : 0);
|
||||
GuiNpcButton lockMoveBtn = new GuiNpcButton(16, col2FieldX, y, 60, 20, LockMovementType.getDisplayKeys(), lockMovement.ordinal());
|
||||
lockMoveBtn.setHoverText("ability.hover.lockMove");
|
||||
addButton(lockMoveBtn);
|
||||
|
||||
@@ -644,7 +645,7 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
|
||||
interruptible = ((GuiNpcButton) guibutton).getValue() == 1;
|
||||
initGui(); // Refresh to show/hide dazed ticks field
|
||||
} else if (id == 16) {
|
||||
lockMovement = ((GuiNpcButton) guibutton).getValue() == 1;
|
||||
lockMovement = LockMovementType.fromOrdinal(((GuiNpcButton) guibutton).getValue());
|
||||
} else if (id == 17) {
|
||||
// Sync windup ticks with animation duration
|
||||
syncWindupWithAnimation();
|
||||
@@ -920,7 +921,7 @@ public class SubGuiAbilityConfig extends SubGuiInterface implements ITextfieldLi
|
||||
this.name = ability.getName() != null ? ability.getName() : "";
|
||||
this.enabled = ability.isEnabled();
|
||||
this.weight = ability.getWeight();
|
||||
this.lockMovement = ability.isLockMovement();
|
||||
this.lockMovement = ability.getLockMovement();
|
||||
this.interruptible = ability.isInterruptible();
|
||||
|
||||
this.cooldownTicks = ability.getCooldownTicks();
|
||||
|
||||
Reference in new issue
Block a user