Ability Effects

This commit is contained in:
Kam committed 2026-01-26 22:02:51 -05:00
1 parent d6d29613e8
commit 563b6f7a26
26 files changed
+799 -324

No files matched your search

@@ -78,6 +78,9 @@ public abstract class Ability implements IAbility {
// Custom data for external mods
protected NBTTagCompound customData = new NBTTagCompound();
// Configurable potion effects
protected List<AbilityEffect> effects = new ArrayList<>();
// ═══════════════════════════════════════════════════════════════════
// EXECUTION STATE (not saved, reset each combat)
// ═══════════════════════════════════════════════════════════════════
@@ -224,6 +227,21 @@ public abstract class Ability implements IAbility {
hitEntity.velocityChanged = true;
}
/**
* Applies all configured effects to the given entity.
* Call this after damage is applied to the target.
*
* @param entity The entity to apply effects to
*/
protected void applyEffects(EntityLivingBase entity) {
if (entity == null || effects.isEmpty()) {
return;
}
for (AbilityEffect effect : effects) {
effect.apply(entity);
}
}
public float getTelegraphRadius() {
return 5.0f;
}
@@ -662,6 +680,13 @@ public abstract class Ability implements IAbility {
for (Condition c : conditions) condList.appendTag(c.writeNBT());
nbt.setTag("conditions", condList);
// Effects
NBTTagList effectList = new NBTTagList();
for (AbilityEffect effect : effects) {
effectList.appendTag(effect.writeNBT());
}
nbt.setTag("effects", effectList);
// Type-specific
NBTTagCompound typeNBT = new NBTTagCompound();
writeTypeNBT(typeNBT);
@@ -735,6 +760,18 @@ public abstract class Ability implements IAbility {
if (c != null) conditions.add(c);
}
// Effects
effects.clear();
if (nbt.hasKey("effects")) {
NBTTagList effectList = nbt.getTagList("effects", 10);
for (int i = 0; i < effectList.tagCount(); i++) {
AbilityEffect effect = AbilityEffect.fromNBT(effectList.getCompoundTagAt(i));
if (effect != null && effect.isValid()) {
effects.add(effect);
}
}
}
readTypeNBT(nbt.getCompoundTag("typeData"));
}
@@ -807,7 +844,7 @@ public abstract class Ability implements IAbility {
}
public void setCooldownTicks(int cooldownTicks) {
this.cooldownTicks = cooldownTicks;
this.cooldownTicks = Math.max(0, cooldownTicks);
}
public int getWindUpTicks() {
@@ -815,7 +852,7 @@ public abstract class Ability implements IAbility {
}
public void setWindUpTicks(int windUpTicks) {
this.windUpTicks = windUpTicks;
this.windUpTicks = Math.max(0, windUpTicks);
}
public int getActiveTicks() {
@@ -823,7 +860,7 @@ public abstract class Ability implements IAbility {
}
public void setActiveTicks(int activeTicks) {
this.activeTicks = activeTicks;
this.activeTicks = Math.max(1, activeTicks);
}
public int getRecoveryTicks() {
@@ -831,7 +868,7 @@ public abstract class Ability implements IAbility {
}
public void setRecoveryTicks(int recoveryTicks) {
this.recoveryTicks = recoveryTicks;
this.recoveryTicks = Math.max(0, recoveryTicks);
}
public boolean isInterruptible() {
@@ -963,6 +1000,24 @@ public abstract class Ability implements IAbility {
conditions.add(c);
}
public List<AbilityEffect> getEffects() {
return effects;
}
public void setEffects(List<AbilityEffect> effects) {
this.effects = effects != null ? effects : new ArrayList<>();
}
public void addEffect(AbilityEffect effect) {
if (effect != null && effect.isValid()) {
effects.add(effect);
}
}
public void clearEffects() {
effects.clear();
}
// ═══════════════════════════════════════════════════════════════════
// IAbility API METHODS
// ═══════════════════════════════════════════════════════════════════
@@ -0,0 +1,146 @@
package kamkeel.npcs.controllers.data.ability;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
/**
* Represents a configurable potion effect that can be applied by abilities.
* Provides a unified system for managing debuffs like slowness, weakness, poison, etc.
*/
public class AbilityEffect {
public enum EffectType {
NONE("gui.none", -1),
SLOWNESS("potion.moveSlowdown", Potion.moveSlowdown.id),
WEAKNESS("potion.weakness", Potion.weakness.id),
POISON("potion.poison", Potion.poison.id),
WITHER("potion.wither", Potion.wither.id),
BLINDNESS("potion.blindness", Potion.blindness.id),
NAUSEA("potion.confusion", Potion.confusion.id),
HUNGER("potion.hunger", Potion.hunger.id),
MINING_FATIGUE("potion.digSlowDown", Potion.digSlowdown.id);
private final String langKey;
private final int potionId;
EffectType(String langKey, int potionId) {
this.langKey = langKey;
this.potionId = potionId;
}
public String getLangKey() {
return langKey;
}
public int getPotionId() {
return potionId;
}
public static EffectType fromOrdinal(int ordinal) {
EffectType[] values = values();
if (ordinal >= 0 && ordinal < values.length) {
return values[ordinal];
}
return NONE;
}
}
private EffectType type = EffectType.NONE;
private int durationTicks = 60;
private int amplifier = 0; // 0-10
public AbilityEffect() {
}
public AbilityEffect(EffectType type, int durationTicks, int amplifier) {
this.type = type;
this.durationTicks = Math.max(1, durationTicks);
this.amplifier = Math.max(0, Math.min(10, amplifier));
}
/**
* Creates a copy of this effect.
*/
public AbilityEffect copy() {
return new AbilityEffect(type, durationTicks, amplifier);
}
/**
* Applies this effect to the given entity.
* Does nothing if type is NONE.
*/
public void apply(EntityLivingBase entity) {
if (entity == null || type == EffectType.NONE) {
return;
}
int potionId = type.getPotionId();
if (potionId >= 0) {
entity.addPotionEffect(new PotionEffect(potionId, durationTicks, amplifier));
}
}
/**
* Writes this effect to NBT.
*/
public NBTTagCompound writeNBT() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("type", type.ordinal());
nbt.setInteger("duration", durationTicks);
nbt.setInteger("amplifier", amplifier);
return nbt;
}
/**
* Reads this effect from NBT.
*/
public void readNBT(NBTTagCompound nbt) {
this.type = EffectType.fromOrdinal(nbt.getInteger("type"));
this.durationTicks = nbt.hasKey("duration") ? nbt.getInteger("duration") : 60;
this.amplifier = nbt.hasKey("amplifier") ? nbt.getInteger("amplifier") : 0;
}
/**
* Creates an AbilityEffect from NBT.
*/
public static AbilityEffect fromNBT(NBTTagCompound nbt) {
AbilityEffect effect = new AbilityEffect();
effect.readNBT(nbt);
return effect;
}
// Getters & Setters
public EffectType getType() {
return type;
}
public void setType(EffectType type) {
this.type = type != null ? type : EffectType.NONE;
}
public int getDurationTicks() {
return durationTicks;
}
public void setDurationTicks(int durationTicks) {
this.durationTicks = Math.max(1, durationTicks);
}
public int getAmplifier() {
return amplifier;
}
public void setAmplifier(int amplifier) {
this.amplifier = Math.max(0, Math.min(10, amplifier));
}
/**
* Returns true if this effect is configured (not NONE).
*/
public boolean isValid() {
return type != EffectType.NONE;
}
}
@@ -7,8 +7,6 @@ import kamkeel.npcs.controllers.data.ability.TargetingMode;
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
@@ -41,9 +39,6 @@ public class AbilityCutter extends Ability {
private SweepMode sweepMode = SweepMode.SWIPE;
private float sweepSpeed = 6.0f;
private int stunDuration = 0;
private int poisonDurationSeconds = 0;
private int poisonLevel = 0;
private boolean piercing = true;
private float innerRadius = 0.0f;
@@ -161,15 +156,9 @@ public class AbilityCutter extends Ability {
// Apply damage with scripted event support
boolean wasHit = applyAbilityDamage(npc, entity, actualDamage, knockback);
// Only apply effects if hit wasn't cancelled
// Apply effects if hit wasn't cancelled
if (wasHit) {
if (stunDuration > 0) {
entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunDuration, 10));
entity.addPotionEffect(new PotionEffect(Potion.weakness.id, stunDuration, 2));
}
if (poisonDurationSeconds > 0) {
entity.addPotionEffect(new PotionEffect(Potion.poison.id, poisonDurationSeconds * 20, poisonLevel));
}
applyEffects(entity);
}
}
}
@@ -206,9 +195,6 @@ public class AbilityCutter extends Ability {
nbt.setFloat("knockback", knockback);
nbt.setString("sweepMode", sweepMode.name());
nbt.setFloat("sweepSpeed", sweepSpeed);
nbt.setInteger("stunDuration", stunDuration);
nbt.setInteger("poisonDurationSeconds", poisonDurationSeconds);
nbt.setInteger("poisonLevel", poisonLevel);
nbt.setBoolean("piercing", piercing);
nbt.setFloat("innerRadius", innerRadius);
}
@@ -225,9 +211,6 @@ public class AbilityCutter extends Ability {
this.sweepMode = SweepMode.SWIPE;
}
this.sweepSpeed = nbt.hasKey("sweepSpeed") ? nbt.getFloat("sweepSpeed") : 6.0f;
this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0;
this.poisonDurationSeconds = nbt.hasKey("poisonDurationSeconds") ? nbt.getInteger("poisonDurationSeconds") : 0;
this.poisonLevel = nbt.hasKey("poisonLevel") ? nbt.getInteger("poisonLevel") : 0;
this.piercing = !nbt.hasKey("piercing") || nbt.getBoolean("piercing");
this.innerRadius = nbt.hasKey("innerRadius") ? nbt.getFloat("innerRadius") : 0.0f;
}
@@ -281,30 +264,6 @@ public class AbilityCutter extends Ability {
this.sweepSpeed = sweepSpeed;
}
public int getStunDuration() {
return stunDuration;
}
public void setStunDuration(int stunDuration) {
this.stunDuration = stunDuration;
}
public int getPoisonDurationSeconds() {
return poisonDurationSeconds;
}
public void setPoisonDurationSeconds(int poisonDurationSeconds) {
this.poisonDurationSeconds = poisonDurationSeconds;
}
public int getPoisonLevel() {
return poisonLevel;
}
public void setPoisonLevel(int poisonLevel) {
this.poisonLevel = poisonLevel;
}
public boolean isPiercing() {
return piercing;
}
@@ -7,8 +7,6 @@ import kamkeel.npcs.controllers.data.ability.TargetingMode;
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.world.World;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.advanced.ability.SubGuiAbilityHeavyHit;
@@ -23,9 +21,6 @@ public class AbilityHeavyHit extends Ability {
private float damage = 8.0f;
private float knockback = 2.0f;
private int slownessLevel = 1;
private int weaknessLevel = 0;
private int potionDurationSeconds = 2;
public AbilityHeavyHit() {
this.typeId = "ability.cnpc.heavy_hit";
@@ -73,14 +68,9 @@ public class AbilityHeavyHit extends Ability {
// Apply damage with scripted event support
boolean wasHit = applyAbilityDamage(npc, target, damage, knockback);
if (wasHit && potionDurationSeconds > 0) {
int durationTicks = potionDurationSeconds * 20;
if (slownessLevel >= 0) {
target.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, durationTicks, slownessLevel));
}
if (weaknessLevel >= 0) {
target.addPotionEffect(new PotionEffect(Potion.weakness.id, durationTicks, weaknessLevel));
}
// Apply effects if hit wasn't cancelled
if (wasHit) {
applyEffects(target);
}
}
@@ -93,18 +83,12 @@ public class AbilityHeavyHit extends Ability {
public void writeTypeNBT(NBTTagCompound nbt) {
nbt.setFloat("damage", damage);
nbt.setFloat("knockback", knockback);
nbt.setInteger("slownessLevel", slownessLevel);
nbt.setInteger("weaknessLevel", weaknessLevel);
nbt.setInteger("potionDurationSeconds", potionDurationSeconds);
}
@Override
public void readTypeNBT(NBTTagCompound nbt) {
this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 8.0f;
this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 2.0f;
this.slownessLevel = nbt.hasKey("slownessLevel") ? nbt.getInteger("slownessLevel") : 1;
this.weaknessLevel = nbt.hasKey("weaknessLevel") ? nbt.getInteger("weaknessLevel") : 0;
this.potionDurationSeconds = nbt.hasKey("potionDurationSeconds") ? nbt.getInteger("potionDurationSeconds") : 2;
}
// Getters & Setters
@@ -123,28 +107,4 @@ public class AbilityHeavyHit extends Ability {
public void setKnockback(float knockback) {
this.knockback = knockback;
}
public int getSlownessLevel() {
return slownessLevel;
}
public void setSlownessLevel(int slownessLevel) {
this.slownessLevel = slownessLevel;
}
public int getWeaknessLevel() {
return weaknessLevel;
}
public void setWeaknessLevel(int weaknessLevel) {
this.weaknessLevel = weaknessLevel;
}
public int getPotionDurationSeconds() {
return potionDurationSeconds;
}
public void setPotionDurationSeconds(int potionDurationSeconds) {
this.potionDurationSeconds = potionDurationSeconds;
}
}
@@ -7,8 +7,6 @@ import kamkeel.npcs.controllers.data.ability.TargetingMode;
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
@@ -28,7 +26,6 @@ public class AbilityShockwave extends Ability {
private float pushRadius = 8.0f;
private float pushStrength = 1.5f;
private float damage = 8.0f;
private int stunDuration = 0;
private int maxTargets = 10;
// Runtime state
@@ -122,10 +119,9 @@ public class AbilityShockwave extends Ability {
// Apply damage with custom knockback direction
boolean wasHit = applyAbilityDamageWithDirection(npc, entity, damage * distFactor, finalPush, dx, dz);
// Apply stun if hit connected
if (wasHit && stunDuration > 0) {
entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunDuration, 10));
entity.addPotionEffect(new PotionEffect(Potion.weakness.id, stunDuration, 2));
// Apply effects if hit connected
if (wasHit) {
applyEffects(entity);
}
}
}
@@ -145,7 +141,6 @@ public class AbilityShockwave extends Ability {
nbt.setFloat("pushRadius", pushRadius);
nbt.setFloat("pushStrength", pushStrength);
nbt.setFloat("damage", damage);
nbt.setInteger("stunDuration", stunDuration);
nbt.setInteger("maxTargets", maxTargets);
}
@@ -154,7 +149,6 @@ public class AbilityShockwave extends Ability {
this.pushRadius = nbt.hasKey("pushRadius") ? nbt.getFloat("pushRadius") : 8.0f;
this.pushStrength = nbt.hasKey("pushStrength") ? nbt.getFloat("pushStrength") : 1.5f;
this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 8.0f;
this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0;
this.maxTargets = nbt.hasKey("maxTargets") ? nbt.getInteger("maxTargets") : 10;
}
@@ -183,14 +177,6 @@ public class AbilityShockwave extends Ability {
this.damage = damage;
}
public int getStunDuration() {
return stunDuration;
}
public void setStunDuration(int stunDuration) {
this.stunDuration = stunDuration;
}
public int getMaxTargets() {
return maxTargets;
}
@@ -261,8 +261,13 @@ public class AbilityTeleport extends Ability {
int blockY = MathHelper.floor_double(checkY);
int blockZ = MathHelper.floor_double(checkZ);
// Skip out-of-world coordinates
if (blockY < 0 || blockY >= 256) {
continue;
}
Block block = world.getBlock(blockX, blockY, blockZ);
if (block.getMaterial().isSolid() && block.isOpaqueCube()) {
if (block != null && block.getMaterial().isSolid() && block.isOpaqueCube()) {
return false;
}
}
@@ -327,10 +332,20 @@ public class AbilityTeleport extends Ability {
}
private boolean isSafeLocation(World world, int x, int y, int z) {
// Bounds check - ensure we're within valid world coordinates
if (y < 1 || y >= 255) {
return false;
}
Block groundBlock = world.getBlock(x, y - 1, z);
Block feetBlock = world.getBlock(x, y, z);
Block headBlock = world.getBlock(x, y + 1, z);
// Defensive null checks (shouldn't happen in MC 1.7.10, but safe)
if (groundBlock == null || feetBlock == null || headBlock == null) {
return false;
}
return groundBlock.getMaterial().isSolid() &&
!feetBlock.getMaterial().isSolid() &&
!headBlock.getMaterial().isSolid();
@@ -8,8 +8,6 @@ import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance;
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
@@ -45,12 +43,6 @@ public class AbilityTrap extends Ability {
private float damage = 6.0f;
private float damageRadius = 0.0f;
private float knockback = 0.5f;
private int stunDuration = 0;
private int rootDuration = 40;
private int slowDuration = 0;
private int slowLevel = 1;
private int poisonDuration = 0;
private int poisonLevel = 0;
private boolean visible = true;
// Offset parameters - trap spawns near target, not exactly on them
@@ -262,24 +254,9 @@ public class AbilityTrap extends Ability {
// Apply damage with scripted event support
boolean wasHit = applyAbilityDamage(npc, entity, damage, knockback);
// Only apply effects if the hit wasn't cancelled
// Apply effects if the hit wasn't cancelled
if (wasHit) {
if (stunDuration > 0) {
entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunDuration, 10));
entity.addPotionEffect(new PotionEffect(Potion.weakness.id, stunDuration, 2));
}
if (rootDuration > 0) {
entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, rootDuration, 127));
}
if (slowDuration > 0) {
entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, slowDuration, slowLevel));
}
if (poisonDuration > 0 && poisonLevel >= 0) {
entity.addPotionEffect(new PotionEffect(Potion.poison.id, poisonDuration, poisonLevel));
}
applyEffects(entity);
}
}
}
@@ -309,12 +286,6 @@ public class AbilityTrap extends Ability {
nbt.setFloat("damage", damage);
nbt.setFloat("damageRadius", damageRadius);
nbt.setFloat("knockback", knockback);
nbt.setInteger("stunDuration", stunDuration);
nbt.setInteger("rootDuration", rootDuration);
nbt.setInteger("slowDuration", slowDuration);
nbt.setInteger("slowLevel", slowLevel);
nbt.setInteger("poisonDuration", poisonDuration);
nbt.setInteger("poisonLevel", poisonLevel);
nbt.setBoolean("visible", visible);
nbt.setFloat("minOffset", minOffset);
nbt.setFloat("maxOffset", maxOffset);
@@ -336,12 +307,6 @@ public class AbilityTrap extends Ability {
this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 6.0f;
this.damageRadius = nbt.hasKey("damageRadius") ? nbt.getFloat("damageRadius") : 0.0f;
this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 0.5f;
this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0;
this.rootDuration = nbt.hasKey("rootDuration") ? nbt.getInteger("rootDuration") : 40;
this.slowDuration = nbt.hasKey("slowDuration") ? nbt.getInteger("slowDuration") : 0;
this.slowLevel = nbt.hasKey("slowLevel") ? nbt.getInteger("slowLevel") : 1;
this.poisonDuration = nbt.hasKey("poisonDuration") ? nbt.getInteger("poisonDuration") : 0;
this.poisonLevel = nbt.hasKey("poisonLevel") ? nbt.getInteger("poisonLevel") : 0;
this.visible = !nbt.hasKey("visible") || nbt.getBoolean("visible");
this.minOffset = nbt.hasKey("minOffset") ? nbt.getFloat("minOffset") : 0.0f;
this.maxOffset = nbt.hasKey("maxOffset") ? nbt.getFloat("maxOffset") : 1.5f;
@@ -421,54 +386,6 @@ public class AbilityTrap extends Ability {
this.knockback = knockback;
}
public int getStunDuration() {
return stunDuration;
}
public void setStunDuration(int stunDuration) {
this.stunDuration = stunDuration;
}
public int getRootDuration() {
return rootDuration;
}
public void setRootDuration(int rootDuration) {
this.rootDuration = rootDuration;
}
public int getSlowDuration() {
return slowDuration;
}
public void setSlowDuration(int slowDuration) {
this.slowDuration = slowDuration;
}
public int getSlowLevel() {
return slowLevel;
}
public void setSlowLevel(int slowLevel) {
this.slowLevel = slowLevel;
}
public int getPoisonDuration() {
return poisonDuration;
}
public void setPoisonDuration(int poisonDuration) {
this.poisonDuration = poisonDuration;
}
public int getPoisonLevel() {
return poisonLevel;
}
public void setPoisonLevel(int poisonLevel) {
this.poisonLevel = poisonLevel;
}
public boolean isVisible() {
return visible;
}
@@ -7,8 +7,6 @@ import kamkeel.npcs.controllers.data.ability.TargetingMode;
import kamkeel.npcs.controllers.data.telegraph.TelegraphType;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
@@ -32,8 +30,6 @@ public class AbilityVortex extends Ability {
private float pullStrength = 0.8f;
private float damage = 0.0f;
private float knockback = 0.0f;
private int stunDuration = 0;
private int rootDuration = 0;
private boolean aoe = false;
private int maxTargets = 5;
private boolean damageOnPull = false;
@@ -134,7 +130,7 @@ public class AbilityVortex extends Ability {
ticksSincePullDamage++;
for (UUID uuid : new HashSet<>(pulledEntities)) {
EntityLivingBase entity = findEntity(world, uuid);
EntityLivingBase entity = findEntity(npc, world, uuid);
if (entity == null || entity.isDead) {
pulledEntities.remove(uuid);
continue;
@@ -187,25 +183,23 @@ public class AbilityVortex extends Ability {
// Only apply effects if hit wasn't cancelled
if (wasHit) {
if (stunDuration > 0) {
entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, stunDuration, 10));
entity.addPotionEffect(new PotionEffect(Potion.weakness.id, stunDuration, 2));
}
if (rootDuration > 0) {
entity.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, rootDuration, 127));
}
applyEffects(entity);
}
}
/**
* Find an entity by UUID within the vortex pull area.
* Uses AABB search instead of iterating all loaded entities.
*/
@SuppressWarnings("unchecked")
private EntityLivingBase findEntity(World world, UUID uuid) {
for (Object obj : world.loadedEntityList) {
if (obj instanceof EntityLivingBase) {
EntityLivingBase entity = (EntityLivingBase) obj;
if (entity.getUniqueID().equals(uuid)) {
return entity;
}
private EntityLivingBase findEntity(EntityNPCInterface npc, World world, UUID uuid) {
// Search within pull radius (entities being pulled should be within this area)
AxisAlignedBB searchBox = npc.boundingBox.expand(pullRadius, pullRadius / 2, pullRadius);
List<EntityLivingBase> nearbyEntities = world.getEntitiesWithinAABB(EntityLivingBase.class, searchBox);
for (EntityLivingBase entity : nearbyEntities) {
if (entity.getUniqueID().equals(uuid)) {
return entity;
}
}
return null;
@@ -231,8 +225,6 @@ public class AbilityVortex extends Ability {
nbt.setFloat("pullStrength", pullStrength);
nbt.setFloat("damage", damage);
nbt.setFloat("knockback", knockback);
nbt.setInteger("stunDuration", stunDuration);
nbt.setInteger("rootDuration", rootDuration);
nbt.setBoolean("aoe", aoe);
nbt.setInteger("maxTargets", maxTargets);
nbt.setBoolean("damageOnPull", damageOnPull);
@@ -245,8 +237,6 @@ public class AbilityVortex extends Ability {
this.pullStrength = nbt.hasKey("pullStrength") ? nbt.getFloat("pullStrength") : 0.8f;
this.damage = nbt.hasKey("damage") ? nbt.getFloat("damage") : 0.0f;
this.knockback = nbt.hasKey("knockback") ? nbt.getFloat("knockback") : 0.0f;
this.stunDuration = nbt.hasKey("stunDuration") ? nbt.getInteger("stunDuration") : 0;
this.rootDuration = nbt.hasKey("rootDuration") ? nbt.getInteger("rootDuration") : 0;
this.aoe = nbt.hasKey("aoe") && nbt.getBoolean("aoe");
this.maxTargets = nbt.hasKey("maxTargets") ? nbt.getInteger("maxTargets") : 5;
this.damageOnPull = nbt.hasKey("damageOnPull") && nbt.getBoolean("damageOnPull");
@@ -286,22 +276,6 @@ public class AbilityVortex extends Ability {
this.knockback = knockback;
}
public int getStunDuration() {
return stunDuration;
}
public void setStunDuration(int stunDuration) {
this.stunDuration = stunDuration;
}
public int getRootDuration() {
return rootDuration;
}
public void setRootDuration(int rootDuration) {
this.rootDuration = rootDuration;
}
public boolean isAoe() {
return aoe;
}
@@ -1,10 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityCharge;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Charge ability type-specific settings.
@@ -41,10 +46,30 @@ public class SubGuiAbilityCharge extends SubGuiAbilityConfig {
y += 24;
// Row 3: Hit Width
// Row 3: Hit Width + Effects
addLabel(new GuiNpcLabel(104, "ability.hitWidth", labelX, y + 5));
addTextField(createFloatField(104, fieldX, y, 50, charge.getHitWidth()));
addButton(new GuiNpcButton(150, col2LabelX, y, 80, 20, "ability.effects"));
}
@Override
protected void handleTypeButton(int id, GuiNpcButton button) {
if (id == 150) {
setSubGui(new SubGuiAbilityEffects(charge.getEffects()));
}
}
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
charge.setEffects(result);
}
}
}
@Override
@@ -1,11 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityCutter;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Cutter ability type-specific settings.
@@ -64,18 +68,8 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig {
y += 24;
// Row 5: Stun Duration + Poison Time
addLabel(new GuiNpcLabel(108, "ability.stunDuration", labelX, y + 5));
addTextField(createIntField(108, fieldX, y, 50, cutter.getStunDuration()));
addLabel(new GuiNpcLabel(109, "ability.poisonTime", col2LabelX, y + 5));
addTextField(createIntField(109, col2FieldX, y, 50, cutter.getPoisonDurationSeconds()));
y += 24;
// Row 6: Poison Level
addLabel(new GuiNpcLabel(110, "ability.poisonLvl", labelX, y + 5));
addTextField(createIntField(110, fieldX, y, 50, cutter.getPoisonLevel()));
// Row 5: Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
}
@Override
@@ -88,6 +82,21 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig {
case 107:
cutter.setPiercing(value == 1);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(cutter.getEffects()));
break;
}
}
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
cutter.setEffects(result);
}
}
}
@@ -112,15 +121,6 @@ public class SubGuiAbilityCutter extends SubGuiAbilityConfig {
case 105:
cutter.setSweepSpeed(parseFloat(field, cutter.getSweepSpeed()));
break;
case 108:
cutter.setStunDuration(field.getInteger());
break;
case 109:
cutter.setPoisonDurationSeconds(field.getInteger());
break;
case 110:
cutter.setPoisonLevel(field.getInteger());
break;
}
}
}
@@ -1,5 +1,6 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityDisc;
import noppes.npcs.client.gui.SubGuiColorSelector;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
@@ -9,6 +10,8 @@ import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Disc ability type-specific settings.
*/
@@ -86,6 +89,11 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig {
addLabel(new GuiNpcLabel(111, "ability.maxDist", col2LabelX, y + 5));
addTextField(createFloatField(111, col2FieldX, y, 50, disc.getMaxDistance()));
y += 24;
// Row 7: Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
}
@Override
@@ -163,6 +171,9 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig {
case 108:
disc.setExplosive(value == 1);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(disc.getEffects()));
break;
}
}
@@ -201,6 +212,12 @@ public class SubGuiAbilityDisc extends SubGuiAbilityConfig {
}
editingVisualColorId = 0;
initGui();
} else if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
disc.setEffects(result);
}
} else {
super.subGuiClosed(subgui);
}
@@ -0,0 +1,197 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import net.minecraft.client.gui.GuiButton;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.ITextfieldListener;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.ArrayList;
import java.util.List;
/**
* SubGui for editing ability effects (potion effects that apply to targets).
* Allows adding/removing effects and configuring type, duration, and amplifier.
*/
public class SubGuiAbilityEffects extends SubGuiInterface implements ITextfieldListener {
private static final int MAX_EFFECTS = 5;
// Effect type names for display
private static final String[] EFFECT_TYPE_NAMES = {
"gui.none",
"potion.moveSlowdown",
"potion.weakness",
"potion.poison",
"potion.wither",
"potion.blindness",
"potion.confusion",
"potion.hunger",
"potion.digSlowDown"
};
// Working copy of effects
private List<AbilityEffect> effects;
private boolean cancelled = false;
public SubGuiAbilityEffects(List<AbilityEffect> existingEffects) {
// Create working copies of effects
this.effects = new ArrayList<>();
if (existingEffects != null) {
for (AbilityEffect effect : existingEffects) {
this.effects.add(effect.copy());
}
}
setBackground("menubg.png");
xSize = 280;
ySize = 180;
}
@Override
public void initGui() {
super.initGui();
int y = guiTop + 8;
int labelX = guiLeft + 8;
// Title
addLabel(new GuiNpcLabel(0, "ability.effects", labelX, y));
y += 16;
// Column headers
addLabel(new GuiNpcLabel(1, "gui.type", guiLeft + 10, y));
addLabel(new GuiNpcLabel(2, "gui.duration", guiLeft + 115, y));
addLabel(new GuiNpcLabel(3, "gui.amp", guiLeft + 175, y));
y += 14;
// Effect rows
for (int i = 0; i < effects.size() && i < MAX_EFFECTS; i++) {
AbilityEffect effect = effects.get(i);
int baseId = 1 + i * 10;
// Type selector button
int typeIndex = effect.getType().ordinal();
addButton(new GuiNpcButton(baseId, guiLeft + 8, y, 100, 20, EFFECT_TYPE_NAMES, typeIndex));
// Duration text field
GuiNpcTextField durField = new GuiNpcTextField(baseId + 1, this, fontRendererObj,
guiLeft + 112, y, 50, 20, String.valueOf(effect.getDurationTicks()));
durField.setIntegersOnly();
durField.setMinMaxDefault(1, 12000, 60);
addTextField(durField);
// Amplifier selector (0-10)
String[] ampValues = new String[11];
for (int a = 0; a <= 10; a++) {
ampValues[a] = String.valueOf(a);
}
addButton(new GuiNpcButton(baseId + 2, guiLeft + 168, y, 40, 20, ampValues, effect.getAmplifier()));
// Delete button
addButton(new GuiNpcButton(baseId + 3, guiLeft + 215, y, 20, 20, "X"));
y += 24;
}
// Add button (if space available)
if (effects.size() < MAX_EFFECTS) {
addButton(new GuiNpcButton(100, guiLeft + 8, y, 50, 20, "gui.add"));
}
// Bottom buttons
addButton(new GuiNpcButton(65, guiLeft + 8, guiTop + ySize - 28, 60, 20, "gui.cancel"));
addButton(new GuiNpcButton(66, guiLeft + xSize - 68, guiTop + ySize - 28, 60, 20, "gui.done"));
}
@Override
public void buttonEvent(GuiButton guibutton) {
int id = guibutton.id;
// Add button
if (id == 100) {
if (effects.size() < MAX_EFFECTS) {
// Add new effect with default values (Slowness, 60 ticks, amp 0)
effects.add(new AbilityEffect(AbilityEffect.EffectType.SLOWNESS, 60, 0));
initGui();
}
return;
}
// Cancel button
if (id == 65) {
cancelled = true;
close();
return;
}
// Done button
if (id == 66) {
// Remove any NONE effects before saving
effects.removeIf(e -> !e.isValid());
cancelled = false;
close();
return;
}
// Effect row buttons (id >= 1 and < 100)
if (id >= 1 && id < 100) {
int effectIndex = (id - 1) / 10;
int action = (id - 1) % 10;
if (effectIndex >= 0 && effectIndex < effects.size()) {
AbilityEffect effect = effects.get(effectIndex);
switch (action) {
case 0: // Type selector
int typeIndex = ((GuiNpcButton) guibutton).getValue();
effect.setType(AbilityEffect.EffectType.fromOrdinal(typeIndex));
break;
case 2: // Amplifier selector
int amp = ((GuiNpcButton) guibutton).getValue();
effect.setAmplifier(amp);
break;
case 3: // Delete button
effects.remove(effectIndex);
initGui();
break;
}
}
}
}
@Override
public void unFocused(GuiNpcTextField textField) {
int id = textField.id;
// Duration text fields (baseId + 1)
if (id >= 2 && id < 100) {
int effectIndex = (id - 1) / 10;
int action = (id - 1) % 10;
if (action == 1 && effectIndex >= 0 && effectIndex < effects.size()) {
effects.get(effectIndex).setDurationTicks(textField.getInteger());
}
}
}
/**
* Returns the resulting effects list after the dialog closes.
* Returns null if cancelled.
*/
public List<AbilityEffect> getResult() {
if (cancelled) {
return null;
}
return effects;
}
/**
* Returns true if the dialog was cancelled.
*/
public boolean wasCancelled() {
return cancelled;
}
}
@@ -1,5 +1,6 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityEnergyBeam;
import noppes.npcs.client.gui.SubGuiColorSelector;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
@@ -9,6 +10,8 @@ import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Energy Beam ability type-specific settings.
* Energy Beam is a homing head with trailing path (DBZ-style).
@@ -87,6 +90,11 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig {
addLabel(new GuiNpcLabel(111, "ability.lifetime", col2LabelX, y + 5));
addTextField(createIntField(111, col2FieldX, y, 50, beam.getMaxLifetime()));
y += 24;
// Row 7: Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
}
@Override
@@ -161,6 +169,9 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig {
case 108:
beam.setExplosive(value == 1);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(beam.getEffects()));
break;
}
}
@@ -199,6 +210,12 @@ public class SubGuiAbilityEnergyBeam extends SubGuiAbilityConfig {
}
editingVisualColorId = 0;
initGui();
} else if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
beam.setEffects(result);
}
} else {
super.subGuiClosed(subgui);
}
@@ -1,11 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityGuard;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Guard ability type-specific settings.
@@ -68,6 +72,13 @@ public class SubGuiAbilityGuard extends SubGuiAbilityConfig {
GuiNpcTextField counterAnimField = createIntField(106, col2FieldX, y, 50, guard.getCounterAnimationId());
counterAnimField.setEnabled(guard.isCanCounter());
addTextField(counterAnimField);
y += 24;
// Row 5: Effects button (applies on counter)
GuiNpcButton effectsBtn = new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects");
effectsBtn.setEnabled(guard.isCanCounter());
addButton(effectsBtn);
}
@Override
@@ -80,6 +91,21 @@ public class SubGuiAbilityGuard extends SubGuiAbilityConfig {
case 102:
guard.setCounterType(AbilityGuard.CounterType.values()[button.getValue()]);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(guard.getEffects()));
break;
}
}
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
guard.setEffects(result);
}
}
}
@@ -1,11 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityHazard;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Hazard ability type-specific settings.
@@ -71,6 +75,11 @@ public class SubGuiAbilityHazard extends SubGuiAbilityConfig {
addLabel(new GuiNpcLabel(109, "ability.affectsCaster", col2LabelX, y + 5));
addButton(new GuiNpcButton(109, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, hazard.isAffectsCaster() ? 1 : 0));
y += 24;
// Row 6: Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
}
@Override
@@ -86,6 +95,21 @@ public class SubGuiAbilityHazard extends SubGuiAbilityConfig {
case 109:
hazard.setAffectsCaster(value == 1);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(hazard.getEffects()));
break;
}
}
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
hazard.setEffects(result);
}
}
}
@@ -1,10 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityHeavyHit;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Heavy Hit ability type-specific settings.
@@ -24,29 +29,37 @@ public class SubGuiAbilityHeavyHit extends SubGuiAbilityConfig {
int labelX = guiLeft + 8;
int fieldX = guiLeft + 85;
int col2LabelX = guiLeft + 145;
int col2FieldX = guiLeft + 205;
// Row 1: Damage + Potion Time
// Row 1: Damage + Knockback
addLabel(new GuiNpcLabel(100, "enchantment.damage", labelX, y + 5));
addTextField(createFloatField(100, fieldX, y, 50, heavyHit.getDamage()));
addLabel(new GuiNpcLabel(101, "ability.potionTime", col2LabelX, y + 5));
addTextField(createIntField(101, col2FieldX, y, 50, heavyHit.getPotionDurationSeconds()));
addLabel(new GuiNpcLabel(102, "ability.knockback", col2LabelX, y + 5));
addTextField(createFloatField(102, guiLeft + 205, y, 50, heavyHit.getKnockback()));
y += 24;
// Row 2: Knockback + Slowness Level
addLabel(new GuiNpcLabel(102, "ability.knockback", labelX, y + 5));
addTextField(createFloatField(102, fieldX, y, 50, heavyHit.getKnockback()));
// Row 2: Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
}
addLabel(new GuiNpcLabel(103, "ability.slownessLvl", col2LabelX, y + 5));
addTextField(createIntField(103, col2FieldX, y, 50, heavyHit.getSlownessLevel()));
@Override
protected void handleTypeButton(int id, GuiNpcButton button) {
if (id == 150) {
setSubGui(new SubGuiAbilityEffects(heavyHit.getEffects()));
}
}
y += 24;
// Row 3: Weakness Level
addLabel(new GuiNpcLabel(104, "ability.weaknessLvl", labelX, y + 5));
addTextField(createIntField(104, fieldX, y, 50, heavyHit.getWeaknessLevel()));
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
heavyHit.setEffects(result);
}
}
}
@Override
@@ -55,18 +68,9 @@ public class SubGuiAbilityHeavyHit extends SubGuiAbilityConfig {
case 100:
heavyHit.setDamage(parseFloat(field, heavyHit.getDamage()));
break;
case 101:
heavyHit.setPotionDurationSeconds(field.getInteger());
break;
case 102:
heavyHit.setKnockback(parseFloat(field, heavyHit.getKnockback()));
break;
case 103:
heavyHit.setSlownessLevel(field.getInteger());
break;
case 104:
heavyHit.setWeaknessLevel(field.getInteger());
break;
}
}
}
@@ -1,5 +1,6 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityLaserShot;
import noppes.npcs.client.gui.SubGuiColorSelector;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
@@ -9,6 +10,8 @@ import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Laser Shot ability type-specific settings.
*/
@@ -77,6 +80,11 @@ public class SubGuiAbilityLaserShot extends SubGuiAbilityConfig {
addLabel(new GuiNpcLabel(109, "ability.knockbackUp", col2LabelX, y + 5));
addTextField(createFloatField(109, col2FieldX, y, 50, laser.getKnockbackUp()));
y += 24;
// Row 6: Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
}
@Override
@@ -142,6 +150,9 @@ public class SubGuiAbilityLaserShot extends SubGuiAbilityConfig {
case 106:
laser.setExplosive(value == 1);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(laser.getEffects()));
break;
}
}
@@ -180,6 +191,12 @@ public class SubGuiAbilityLaserShot extends SubGuiAbilityConfig {
}
editingVisualColorId = 0;
initGui();
} else if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
laser.setEffects(result);
}
} else {
super.subGuiClosed(subgui);
}
@@ -1,5 +1,6 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityOrb;
import noppes.npcs.client.gui.SubGuiColorSelector;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
@@ -9,6 +10,8 @@ import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Orb ability type-specific settings.
*/
@@ -77,6 +80,11 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig {
addLabel(new GuiNpcLabel(109, "ability.lifetime", col2LabelX, y + 5));
addTextField(createIntField(109, col2FieldX, y, 50, orb.getMaxLifetime()));
y += 24;
// Row 6: Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
}
@Override
@@ -151,6 +159,9 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig {
case 106:
orb.setExplosive(value == 1);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(orb.getEffects()));
break;
}
}
@@ -189,6 +200,12 @@ public class SubGuiAbilityOrb extends SubGuiAbilityConfig {
}
editingVisualColorId = 0;
initGui();
} else if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
orb.setEffects(result);
}
} else {
super.subGuiClosed(subgui);
}
@@ -1,11 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityProjectile;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Projectile ability type-specific settings.
@@ -69,6 +73,11 @@ public class SubGuiAbilityProjectile extends SubGuiAbilityConfig {
addLabel(new GuiNpcLabel(107, "ability.homingStr", col2LabelX, y + 5));
addTextField(createFloatField(107, col2FieldX, y, 50, projectile.getHomingStrength()));
y += 24;
// Row 5: Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
}
@Override
@@ -85,6 +94,21 @@ public class SubGuiAbilityProjectile extends SubGuiAbilityConfig {
case 106:
projectile.setHoming(value == 1);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(projectile.getEffects()));
break;
}
}
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
projectile.setEffects(result);
}
}
}
@@ -1,10 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityShockwave;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Shockwave ability type-specific settings.
@@ -41,17 +46,35 @@ public class SubGuiAbilityShockwave extends SubGuiAbilityConfig {
y += 24;
// Row 3: Stun Duration + Max Targets
addLabel(new GuiNpcLabel(103, "ability.stunDuration", labelX, y + 5));
addTextField(createIntField(103, fieldX, y, 50, shockwave.getStunDuration()));
// Row 3: Max Targets + Effects button
addLabel(new GuiNpcLabel(104, "ability.maxTargets", labelX, y + 5));
addTextField(createIntField(104, fieldX, y, 50, shockwave.getMaxTargets()));
addLabel(new GuiNpcLabel(104, "ability.maxTargets", col2LabelX, y + 5));
addTextField(createIntField(104, col2FieldX, y, 50, shockwave.getMaxTargets()));
addButton(new GuiNpcButton(150, col2LabelX, y, 80, 20, "ability.effects"));
y += 24;
addLabel(new GuiNpcLabel(105, "ability.shockwaveFalloff", labelX, y + 5));
}
@Override
protected void handleTypeButton(int id, GuiNpcButton button) {
if (id == 150) {
setSubGui(new SubGuiAbilityEffects(shockwave.getEffects()));
}
}
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
shockwave.setEffects(result);
}
}
}
@Override
protected void handleTypeTextField(int id, GuiNpcTextField field) {
switch (id) {
@@ -64,9 +87,6 @@ public class SubGuiAbilityShockwave extends SubGuiAbilityConfig {
case 102:
shockwave.setPushStrength(parseFloat(field, shockwave.getPushStrength()));
break;
case 103:
shockwave.setStunDuration(field.getInteger());
break;
case 104:
shockwave.setMaxTargets(field.getInteger());
break;
@@ -1,10 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilitySlam;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Slam ability type-specific settings.
@@ -44,9 +49,30 @@ public class SubGuiAbilitySlam extends SubGuiAbilityConfig {
y += 24;
// Row 3: Leap Height
// Row 3: Leap Height + Effects
addLabel(new GuiNpcLabel(104, "ability.leapHeight", labelX, y + 5));
addTextField(createFloatField(104, fieldX, y, 50, slam.getLeapHeight()));
addButton(new GuiNpcButton(150, col2LabelX, y, 80, 20, "ability.effects"));
}
@Override
protected void handleTypeButton(int id, GuiNpcButton button) {
if (id == 150) {
setSubGui(new SubGuiAbilityEffects(slam.getEffects()));
}
}
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
slam.setEffects(result);
}
}
}
@Override
@@ -1,5 +1,6 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilitySweeper;
import noppes.npcs.client.gui.SubGuiColorSelector;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
@@ -9,6 +10,8 @@ import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Sweeper ability type-specific settings.
* Sweeper is a low rotating beam that players can jump over.
@@ -75,6 +78,11 @@ public class SubGuiAbilitySweeper extends SubGuiAbilityConfig {
// Row 5: Lock On Target
addLabel(new GuiNpcLabel(108, "ability.lockTarget", labelX, y + 5));
addButton(new GuiNpcButton(108, fieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, sweeper.isLockOnTarget() ? 1 : 0));
y += 24;
// Row 6: Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
}
@Override
@@ -121,6 +129,9 @@ public class SubGuiAbilitySweeper extends SubGuiAbilityConfig {
case 108:
sweeper.setLockOnTarget(value == 1);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(sweeper.getEffects()));
break;
}
}
@@ -155,6 +166,12 @@ public class SubGuiAbilitySweeper extends SubGuiAbilityConfig {
}
editingVisualColorId = 0;
initGui();
} else if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
sweeper.setEffects(result);
}
} else {
super.subGuiClosed(subgui);
}
@@ -1,11 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityTeleport;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Teleport ability type-specific settings.
@@ -85,6 +89,11 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig {
addLabel(new GuiNpcLabel(109, "ability.dmgAtEnd", col2LabelX, y + 5));
addButton(new GuiNpcButton(109, col2FieldX, y, 50, 20, new String[]{"gui.no", "gui.yes"}, teleport.isDamageAtEnd() ? 1 : 0));
y += 24;
// Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
}
@Override
@@ -104,6 +113,21 @@ public class SubGuiAbilityTeleport extends SubGuiAbilityConfig {
case 109:
teleport.setDamageAtEnd(value == 1);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(teleport.getEffects()));
break;
}
}
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
teleport.setEffects(result);
}
}
}
@@ -1,11 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityTrap;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Trap ability type-specific settings.
@@ -55,24 +59,31 @@ public class SubGuiAbilityTrap extends SubGuiAbilityConfig {
y += 24;
// Row 4: Root Duration + Stun Duration
addLabel(new GuiNpcLabel(106, "ability.rootDuration", labelX, y + 5));
addTextField(createIntField(106, fieldX, y, 50, trap.getRootDuration()));
addLabel(new GuiNpcLabel(107, "ability.stunDuration", col2LabelX, y + 5));
addTextField(createIntField(107, col2FieldX, y, 50, trap.getStunDuration()));
y += 24;
// Row 5: Knockback
// Row 4: Knockback + Effects button
addLabel(new GuiNpcLabel(108, "ability.knockback", labelX, y + 5));
addTextField(createFloatField(108, fieldX, y, 50, trap.getKnockback()));
addButton(new GuiNpcButton(150, col2LabelX, y, 80, 20, "ability.effects"));
}
@Override
protected void handleTypeButton(int id, GuiNpcButton button) {
if (id == 100) {
trap.setPlacement(AbilityTrap.TrapPlacement.values()[button.getValue()]);
} else if (id == 150) {
setSubGui(new SubGuiAbilityEffects(trap.getEffects()));
}
}
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
trap.setEffects(result);
}
}
}
@@ -94,12 +105,6 @@ public class SubGuiAbilityTrap extends SubGuiAbilityConfig {
case 105:
trap.setMaxTriggers(field.getInteger());
break;
case 106:
trap.setRootDuration(field.getInteger());
break;
case 107:
trap.setStunDuration(field.getInteger());
break;
case 108:
trap.setKnockback(parseFloat(field, trap.getKnockback()));
break;
@@ -1,11 +1,15 @@
package noppes.npcs.client.gui.advanced.ability;
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
import kamkeel.npcs.controllers.data.ability.type.AbilityVortex;
import noppes.npcs.client.gui.advanced.SubGuiAbilityConfig;
import noppes.npcs.client.gui.util.GuiNpcButton;
import noppes.npcs.client.gui.util.GuiNpcLabel;
import noppes.npcs.client.gui.util.GuiNpcTextField;
import noppes.npcs.client.gui.util.IAbilityConfigCallback;
import noppes.npcs.client.gui.util.SubGuiInterface;
import java.util.List;
/**
* GUI for configuring Vortex ability type-specific settings.
@@ -54,12 +58,8 @@ public class SubGuiAbilityVortex extends SubGuiAbilityConfig {
y += 24;
// Row 4: Stun Duration + Root Duration
addLabel(new GuiNpcLabel(106, "ability.stunDuration", labelX, y + 5));
addTextField(createIntField(106, fieldX, y, 50, vortex.getStunDuration()));
addLabel(new GuiNpcLabel(107, "ability.rootDuration", col2LabelX, y + 5));
addTextField(createIntField(107, col2FieldX, y, 50, vortex.getRootDuration()));
// Row 4: Effects button
addButton(new GuiNpcButton(150, labelX, y, 80, 20, "ability.effects"));
y += 24;
@@ -81,6 +81,21 @@ public class SubGuiAbilityVortex extends SubGuiAbilityConfig {
case 108:
vortex.setDamageOnPull(value == 1);
break;
case 150:
setSubGui(new SubGuiAbilityEffects(vortex.getEffects()));
break;
}
}
@Override
public void subGuiClosed(SubGuiInterface subgui) {
super.subGuiClosed(subgui);
if (subgui instanceof SubGuiAbilityEffects) {
SubGuiAbilityEffects effectsGui = (SubGuiAbilityEffects) subgui;
List<AbilityEffect> result = effectsGui.getResult();
if (result != null) {
vortex.setEffects(result);
}
}
}
@@ -102,12 +117,6 @@ public class SubGuiAbilityVortex extends SubGuiAbilityConfig {
case 105:
vortex.setMaxTargets(field.getInteger());
break;
case 106:
vortex.setStunDuration(field.getInteger());
break;
case 107:
vortex.setRootDuration(field.getInteger());
break;
case 109:
vortex.setPullDamage(parseFloat(field, vortex.getPullDamage()));
break;