diff --git a/src/api b/src/api index 4e9642531..5eb98d172 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 4e96425314a9fd2d3e48f68cff5fc7ee69f87213 +Subproject commit 5eb98d172eedfa0727e8ec9769bc2edad36a1ce4 diff --git a/src/main/java/kamkeel/npcs/client/renderer/TelegraphRenderer.java b/src/main/java/kamkeel/npcs/client/renderer/TelegraphRenderer.java index 9bcf473ac..dc653e73f 100644 --- a/src/main/java/kamkeel/npcs/client/renderer/TelegraphRenderer.java +++ b/src/main/java/kamkeel/npcs/client/renderer/TelegraphRenderer.java @@ -105,7 +105,7 @@ public class TelegraphRenderer { renderLine(telegraph.getLength(), telegraph.getWidth(), red, green, blue, alpha); break; case CONE: - renderCone(telegraph.getLength(), telegraph.getAngle(), red, green, blue, alpha); + renderCone(telegraph.getLength(), telegraph.getAngle(), telegraph.getInnerRadius(), red, green, blue, alpha); break; case POINT: renderPoint(red, green, blue, alpha); @@ -207,42 +207,98 @@ public class TelegraphRenderer { tessellator.draw(); } - private void renderCone(float length, float angle, float r, float g, float b, float a) { + private void renderCone(float length, float angle, float innerRadius, float r, float g, float b, float a) { float halfAngleRad = (float) Math.toRadians(angle / 2); Tessellator tessellator = Tessellator.instance; - tessellator.startDrawing(GL11.GL_TRIANGLE_FAN); - tessellator.setColorRGBA_F(r, g, b, a); - // Origin point - tessellator.addVertex(0, 0, 0); + if (innerRadius <= 0) { + // Standard cone: triangle fan from origin + tessellator.startDrawing(GL11.GL_TRIANGLE_FAN); + tessellator.setColorRGBA_F(r, g, b, a); - // Arc points - for (int i = 0; i <= CONE_SEGMENTS; i++) { - float segmentAngle = -halfAngleRad + (halfAngleRad * 2 * i) / CONE_SEGMENTS; - double x = Math.sin(segmentAngle) * length; - double z = Math.cos(segmentAngle) * length; - tessellator.addVertex(x, 0, z); + tessellator.addVertex(0, 0, 0); + + for (int i = 0; i <= CONE_SEGMENTS; i++) { + float segmentAngle = -halfAngleRad + (halfAngleRad * 2 * i) / CONE_SEGMENTS; + double x = Math.sin(segmentAngle) * length; + double z = Math.cos(segmentAngle) * length; + tessellator.addVertex(x, 0, z); + } + + tessellator.draw(); + + // Border + tessellator.startDrawing(GL11.GL_LINE_STRIP); + tessellator.setColorRGBA_F(r, g, b, Math.min(1.0f, a * 2)); + + tessellator.addVertex(0, 0.01, 0); + + for (int i = 0; i <= CONE_SEGMENTS; i++) { + float segmentAngle = -halfAngleRad + (halfAngleRad * 2 * i) / CONE_SEGMENTS; + double x = Math.sin(segmentAngle) * length; + double z = Math.cos(segmentAngle) * length; + tessellator.addVertex(x, 0.01, z); + } + + tessellator.addVertex(0, 0.01, 0); + + tessellator.draw(); + } else { + // Truncated cone: strip between inner and outer arcs + tessellator.startDrawing(GL11.GL_TRIANGLE_STRIP); + tessellator.setColorRGBA_F(r, g, b, a); + + for (int i = 0; i <= CONE_SEGMENTS; i++) { + float segmentAngle = -halfAngleRad + (halfAngleRad * 2 * i) / CONE_SEGMENTS; + double sinA = Math.sin(segmentAngle); + double cosA = Math.cos(segmentAngle); + + tessellator.addVertex(sinA * length, 0, cosA * length); + tessellator.addVertex(sinA * innerRadius, 0, cosA * innerRadius); + } + + tessellator.draw(); + + // Border: outer arc + float borderAlpha = Math.min(1.0f, a * 2); + tessellator.startDrawing(GL11.GL_LINE_STRIP); + tessellator.setColorRGBA_F(r, g, b, borderAlpha); + + for (int i = 0; i <= CONE_SEGMENTS; i++) { + float segmentAngle = -halfAngleRad + (halfAngleRad * 2 * i) / CONE_SEGMENTS; + tessellator.addVertex(Math.sin(segmentAngle) * length, 0.01, Math.cos(segmentAngle) * length); + } + + tessellator.draw(); + + // Border: inner arc + tessellator.startDrawing(GL11.GL_LINE_STRIP); + tessellator.setColorRGBA_F(r, g, b, borderAlpha); + + for (int i = 0; i <= CONE_SEGMENTS; i++) { + float segmentAngle = -halfAngleRad + (halfAngleRad * 2 * i) / CONE_SEGMENTS; + tessellator.addVertex(Math.sin(segmentAngle) * innerRadius, 0.01, Math.cos(segmentAngle) * innerRadius); + } + + tessellator.draw(); + + // Border: side edges connecting inner and outer arcs + tessellator.startDrawing(GL11.GL_LINES); + tessellator.setColorRGBA_F(r, g, b, borderAlpha); + + double sinStart = Math.sin(-halfAngleRad); + double cosStart = Math.cos(-halfAngleRad); + tessellator.addVertex(sinStart * innerRadius, 0.01, cosStart * innerRadius); + tessellator.addVertex(sinStart * length, 0.01, cosStart * length); + + double sinEnd = Math.sin(halfAngleRad); + double cosEnd = Math.cos(halfAngleRad); + tessellator.addVertex(sinEnd * innerRadius, 0.01, cosEnd * innerRadius); + tessellator.addVertex(sinEnd * length, 0.01, cosEnd * length); + + tessellator.draw(); } - - tessellator.draw(); - - // Draw border - tessellator.startDrawing(GL11.GL_LINE_STRIP); - tessellator.setColorRGBA_F(r, g, b, Math.min(1.0f, a * 2)); - - tessellator.addVertex(0, 0.01, 0); - - for (int i = 0; i <= CONE_SEGMENTS; i++) { - float segmentAngle = -halfAngleRad + (halfAngleRad * 2 * i) / CONE_SEGMENTS; - double x = Math.sin(segmentAngle) * length; - double z = Math.cos(segmentAngle) * length; - tessellator.addVertex(x, 0.01, z); - } - - tessellator.addVertex(0, 0.01, 0); - - tessellator.draw(); } private void renderPoint(float r, float g, float b, float a) { @@ -344,7 +400,7 @@ public class TelegraphRenderer { renderLine(telegraph.getLength(), telegraph.getWidth(), red, green, blue, alpha); break; case CONE: - renderCone(telegraph.getLength(), telegraph.getAngle(), red, green, blue, alpha); + renderCone(telegraph.getLength(), telegraph.getAngle(), telegraph.getInnerRadius(), red, green, blue, alpha); break; case POINT: renderPoint(red, green, blue, alpha); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java b/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java index fbad42cb3..f97c619ac 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/Ability.java @@ -597,6 +597,18 @@ public abstract class Ability implements IAbility, IAbilityAction { return 45.0f; } + public float getTelegraphInnerRadius() { + return 0.0f; + } + + /** + * Override to return true if the ability type manages its own telegraph GUI controls. + * When true, the base class will skip adding the default telegraph section. + */ + public boolean hasOwnTelegraphControls() { + return false; + } + /** * Returns true if the caster is a player (not an NPC). * Use this instead of checking {@code target != null} to make NPC/Player @@ -875,7 +887,7 @@ public abstract class Ability implements IAbility, IAbilityAction { .tab("Effects")); TelegraphType tType = getTelegraphType(); - if (tType != null && tType != TelegraphType.NONE) { + if (tType != null && tType != TelegraphType.NONE && !hasOwnTelegraphControls()) { defs.add(FieldDef.section("ability.section.telegraph").tab("Effects") .hover("telegraph." + tType.name().toLowerCase())); defs.add(FieldDef.boolField("ability.showTelegraph", this::isShowTelegraph, this::setShowTelegraph) @@ -1015,13 +1027,13 @@ public abstract class Ability implements IAbility, IAbilityAction { telegraph = Telegraph.circle(getTelegraphRadius()); break; case RING: - telegraph = Telegraph.ring(getTelegraphRadius(), getTelegraphRadius() * 0.5f); + telegraph = Telegraph.ring(getTelegraphRadius(), getTelegraphInnerRadius()); break; case LINE: telegraph = Telegraph.line(getTelegraphLength(), getTelegraphWidth()); break; case CONE: - telegraph = Telegraph.cone(getTelegraphLength(), getTelegraphAngle()); + telegraph = Telegraph.cone(getTelegraphLength(), getTelegraphAngle(), getTelegraphInnerRadius()); break; case POINT: telegraph = new Telegraph("", TelegraphType.POINT); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/CustomAbility.java b/src/main/java/kamkeel/npcs/controllers/data/ability/CustomAbility.java index 045a12e5d..4795e7363 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/CustomAbility.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/CustomAbility.java @@ -1,8 +1,12 @@ package kamkeel.npcs.controllers.data.ability; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import kamkeel.npcs.controllers.data.ability.enums.LockMode; import kamkeel.npcs.controllers.data.ability.enums.TargetingMode; import kamkeel.npcs.controllers.data.ability.enums.UserType; +import kamkeel.npcs.controllers.data.telegraph.Telegraph; +import kamkeel.npcs.controllers.data.telegraph.TelegraphInstance; import kamkeel.npcs.controllers.data.telegraph.TelegraphType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.nbt.NBTTagCompound; @@ -28,6 +32,17 @@ public class CustomAbility extends Ability implements ICustomAbility { private int durationTicks = 20; + // Telegraph dimension fields + private float tRadius = 5.0f; + private float tInnerRadius = 0.0f; + private float tLength = 5.0f; + private float tWidth = 2.0f; + private float tAngle = 45.0f; + + // Telegraph timing + private int telegraphActiveTicks = 0; + private boolean syncTelegraphWithDuration = true; + public CustomAbility() { this.typeId = "ability.cnpc.custom"; this.name = "Custom"; @@ -77,6 +92,139 @@ public class CustomAbility extends Ability implements ICustomAbility { return true; } + @Override + public boolean hasOwnTelegraphControls() { + return true; + } + + // ==================== TELEGRAPH OVERRIDES ==================== + + @Override + public boolean keepTelegraphDuringActive() { + return getResolvedTelegraphActiveTicks() > 0; + } + + /** + * Returns the effective telegraph active ticks: synced from duration or manual value. + */ + public int getResolvedTelegraphActiveTicks() { + if (syncTelegraphWithDuration) { + return durationTicks; + } + return telegraphActiveTicks; + } + + @Override + public TelegraphInstance createTelegraph(EntityLivingBase caster, EntityLivingBase target) { + if (!isShowTelegraph() || getTelegraphType() == TelegraphType.NONE) { + return null; + } + + Telegraph telegraph; + double x, y, z; + float yaw = caster.rotationYaw; + TelegraphType tType = getTelegraphType(); + + boolean positionAtCaster = targetingMode == TargetingMode.AOE_SELF || + targetingMode == TargetingMode.SELF || + tType == TelegraphType.LINE || + tType == TelegraphType.CONE; + + if (positionAtCaster) { + x = caster.posX; + y = findGroundLevel(caster.worldObj, caster.posX, caster.posY, caster.posZ); + z = caster.posZ; + } else if (target != null) { + x = target.posX; + y = findGroundLevel(caster.worldObj, target.posX, target.posY, target.posZ); + z = target.posZ; + } else { + x = caster.posX; + y = findGroundLevel(caster.worldObj, caster.posX, caster.posY, caster.posZ); + z = caster.posZ; + } + + switch (tType) { + case CIRCLE: + telegraph = Telegraph.circle(tRadius); + break; + case RING: + telegraph = Telegraph.ring(tRadius, tInnerRadius); + break; + case LINE: + telegraph = Telegraph.line(tLength, tWidth); + break; + case CONE: + telegraph = Telegraph.cone(tLength, tAngle, tInnerRadius); + break; + case POINT: + telegraph = new Telegraph("", TelegraphType.POINT); + break; + case SQUARE: + telegraph = Telegraph.square(tRadius); + break; + default: + return null; + } + + int activeTicks = getResolvedTelegraphActiveTicks(); + int totalDuration = windUpTicks + activeTicks; + telegraph.setDurationTicks(Math.max(1, totalDuration)); + telegraph.setColor(windUpColor); + telegraph.setWarningColor(activeColor); + if (windUpTicks > 0) { + telegraph.setWarningStartTick(windUpTicks); + } else { + telegraph.setWarningStartTick(0); + } + telegraph.setHeightOffset(telegraphHeightOffset); + + TelegraphInstance instance = new TelegraphInstance(telegraph, x, y, z, yaw); + instance.setCasterEntityId(caster.getEntityId()); + + if (positionAtCaster) { + instance.setEntityIdToFollow(caster.getEntityId()); + if (tType == TelegraphType.LINE || tType == TelegraphType.CONE) { + if (!isRotationLockedDuringWindup()) { + if (target != null) { + instance.setTargetEntityId(target.getEntityId()); + } else { + instance.setTrackFollowedEntityYaw(true); + } + } + } + } else if (target != null) { + instance.setEntityIdToFollow(target.getEntityId()); + } + + return instance; + } + + @Override + public float getTelegraphRadius() { + return tRadius; + } + + @Override + public float getTelegraphInnerRadius() { + return tInnerRadius; + } + + @Override + public float getTelegraphLength() { + return tLength; + } + + @Override + public float getTelegraphWidth() { + return tWidth; + } + + @Override + public float getTelegraphAngle() { + return tAngle; + } + // ==================== FIELDS ==================== @Override @@ -89,6 +237,62 @@ public class CustomAbility extends Ability implements ICustomAbility { this.durationTicks = Math.max(0, ticks); } + public float getTRadius() { + return tRadius; + } + + public void setTRadius(float radius) { + this.tRadius = Math.max(0, radius); + } + + public float getTInnerRadius() { + return tInnerRadius; + } + + public void setTInnerRadius(float innerRadius) { + this.tInnerRadius = Math.max(0, innerRadius); + } + + public float getTLength() { + return tLength; + } + + public void setTLength(float length) { + this.tLength = Math.max(0, length); + } + + public float getTWidth() { + return tWidth; + } + + public void setTWidth(float width) { + this.tWidth = Math.max(0, width); + } + + public float getTAngle() { + return tAngle; + } + + public void setTAngle(float angle) { + this.tAngle = Math.max(0, angle); + } + + public int getTelegraphActiveTicks() { + return telegraphActiveTicks; + } + + public void setTelegraphActiveTicks(int ticks) { + this.telegraphActiveTicks = Math.max(0, ticks); + } + + public boolean isSyncTelegraphWithDuration() { + return syncTelegraphWithDuration; + } + + public void setSyncTelegraphWithDuration(boolean sync) { + this.syncTelegraphWithDuration = sync; + } + // ==================== ICustomAbility ==================== @Override @@ -104,6 +308,31 @@ public class CustomAbility extends Ability implements ICustomAbility { } } + @Override + public void setTelegraphRadius(float radius) { + this.tRadius = Math.max(0, radius); + } + + @Override + public void setTelegraphInnerRadius(float innerRadius) { + this.tInnerRadius = Math.max(0, innerRadius); + } + + @Override + public void setTelegraphLength(float length) { + this.tLength = Math.max(0, length); + } + + @Override + public void setTelegraphWidth(float width) { + this.tWidth = Math.max(0, width); + } + + @Override + public void setTelegraphAngle(float angle) { + this.tAngle = Math.max(0, angle); + } + @Override public int getTargetingModeType() { return getTargetingMode().ordinal(); @@ -122,15 +351,30 @@ public class CustomAbility extends Ability implements ICustomAbility { @Override public void writeTypeNBT(NBTTagCompound nbt) { nbt.setInteger("durationTicks", durationTicks); + nbt.setFloat("tRadius", tRadius); + nbt.setFloat("tInnerRadius", tInnerRadius); + nbt.setFloat("tLength", tLength); + nbt.setFloat("tWidth", tWidth); + nbt.setFloat("tAngle", tAngle); + nbt.setInteger("telegraphActiveTicks", telegraphActiveTicks); + nbt.setBoolean("syncTelegraphWithDuration", syncTelegraphWithDuration); } @Override public void readTypeNBT(NBTTagCompound nbt) { this.durationTicks = Math.max(0, nbt.getInteger("durationTicks")); + this.tRadius = nbt.hasKey("tRadius") ? nbt.getFloat("tRadius") : 5.0f; + this.tInnerRadius = nbt.hasKey("tInnerRadius") ? nbt.getFloat("tInnerRadius") : 0.0f; + this.tLength = nbt.hasKey("tLength") ? nbt.getFloat("tLength") : 5.0f; + this.tWidth = nbt.hasKey("tWidth") ? nbt.getFloat("tWidth") : 2.0f; + this.tAngle = nbt.hasKey("tAngle") ? nbt.getFloat("tAngle") : 45.0f; + this.telegraphActiveTicks = nbt.hasKey("telegraphActiveTicks") ? nbt.getInteger("telegraphActiveTicks") : 0; + this.syncTelegraphWithDuration = nbt.hasKey("syncTelegraphWithDuration") ? nbt.getBoolean("syncTelegraphWithDuration") : true; } // ==================== GUI ==================== + @SideOnly(Side.CLIENT) @Override public void getAbilityDefinitions(List defs) { // User Type (NPC / Player / Both) @@ -141,10 +385,6 @@ public class CustomAbility extends Ability implements ICustomAbility { defs.add(FieldDef.enumField("ability.targetingMode", TargetingMode.class, this::getTargetingMode, this::setTargetingMode)); - // Telegraph Shape - defs.add(FieldDef.enumField("ability.telegraphShape", TelegraphType.class, - this::getTelegraphType, this::setTelegraphType)); - // Toggle section defs.add(FieldDef.section("ability.section.toggle")); defs.add(FieldDef.boolField("ability.toggleEnabled", @@ -161,5 +401,75 @@ public class CustomAbility extends Ability implements ICustomAbility { defs.add(FieldDef.intField("ability.duration", this::getDurationTicks, this::setDurationTicks) .range(0, 6000) .visibleWhen(() -> !this.isToggleable())); + + // ── Telegraph Controls (Effects tab) ───────────────────────── + defs.add(FieldDef.section("ability.section.telegraph").tab("Effects")); + defs.add(FieldDef.enumField("ability.telegraphShape", TelegraphType.class, + this::getTelegraphType, this::setTelegraphType).tab("Effects")); + defs.add(FieldDef.boolField("ability.showTelegraph", this::isShowTelegraph, this::setShowTelegraph) + .tab("Effects").visibleWhen(this::hasTelegraphShape)); + defs.add(FieldDef.colorSubGui("ability.windUpColor", this::getWindUpColor, this::setWindUpColor) + .tab("Effects").visibleWhen(this::isTelegraphVisible)); + defs.add(FieldDef.colorSubGui("ability.activeColor", this::getActiveColor, this::setActiveColor) + .tab("Effects").visibleWhen(this::isTelegraphVisible)); + defs.add(FieldDef.floatField("ability.telegraphHeight", this::getTelegraphHeightOffset, this::setTelegraphHeightOffset) + .tab("Effects").visibleWhen(this::isTelegraphVisible)); + + // Telegraph active duration with sync toggle (mirrors windup sync pattern) + defs.add(FieldDef.row( + FieldDef.intField("ability.telegraphActiveTicks", this::getTelegraphActiveTicks, this::setTelegraphActiveTicks).range(0, 6000), + FieldDef.boolField("ability.syncTelegraph", this::isSyncTelegraphWithDuration, this::setSyncTelegraphWithDuration) + .hover("ability.hover.syncTelegraph") + ).tab("Effects").visibleWhen(() -> isTelegraphVisible() && !isSyncTelegraphWithDuration())); + defs.add(FieldDef.row( + FieldDef.labelField("ability.telegraphActiveTicks", () -> getResolvedTelegraphActiveTicks() + "t"), + FieldDef.boolField("ability.syncTelegraph", this::isSyncTelegraphWithDuration, this::setSyncTelegraphWithDuration) + .hover("ability.hover.syncTelegraph") + ).tab("Effects").visibleWhen(() -> isTelegraphVisible() && isSyncTelegraphWithDuration())); + + // Shape-specific dimension fields + defs.add(FieldDef.floatField("ability.telegraphRadius", this::getTRadius, this::setTRadius) + .tab("Effects").visibleWhen(() -> isTelegraphVisible() && needsRadius())); + defs.add(FieldDef.floatField("ability.telegraphInnerRadius", this::getTInnerRadius, this::setTInnerRadius) + .tab("Effects").visibleWhen(() -> isTelegraphVisible() && needsInnerRadius())); + defs.add(FieldDef.floatField("ability.telegraphLength", this::getTLength, this::setTLength) + .tab("Effects").visibleWhen(() -> isTelegraphVisible() && needsLength())); + defs.add(FieldDef.floatField("ability.telegraphWidth", this::getTWidth, this::setTWidth) + .tab("Effects").visibleWhen(() -> isTelegraphVisible() && needsWidth())); + defs.add(FieldDef.floatField("ability.telegraphAngle", this::getTAngle, this::setTAngle) + .tab("Effects").visibleWhen(() -> isTelegraphVisible() && needsAngle())); + } + + // ==================== TELEGRAPH VISIBILITY HELPERS ==================== + + private boolean hasTelegraphShape() { + return getTelegraphType() != TelegraphType.NONE; + } + + private boolean isTelegraphVisible() { + return hasTelegraphShape() && isShowTelegraph(); + } + + private boolean needsRadius() { + TelegraphType t = getTelegraphType(); + return t == TelegraphType.CIRCLE || t == TelegraphType.RING || t == TelegraphType.SQUARE; + } + + private boolean needsInnerRadius() { + TelegraphType t = getTelegraphType(); + return t == TelegraphType.RING || t == TelegraphType.CONE; + } + + private boolean needsLength() { + TelegraphType t = getTelegraphType(); + return t == TelegraphType.LINE || t == TelegraphType.CONE; + } + + private boolean needsWidth() { + return getTelegraphType() == TelegraphType.LINE; + } + + private boolean needsAngle() { + return getTelegraphType() == TelegraphType.CONE; } } 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 8c6fecc4c..36dec1715 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 @@ -122,7 +122,7 @@ public class AbilityCutter extends Ability implements IAbilityCutter { return null; } - Telegraph telegraph = Telegraph.cone(getTelegraphLength(), getTelegraphAngle()); + Telegraph telegraph = Telegraph.cone(getTelegraphLength(), getTelegraphAngle(), getTelegraphInnerRadius()); int totalDuration = windUpTicks + getActiveDurationTicks(); telegraph.setDurationTicks(totalDuration); telegraph.setColor(windUpColor); @@ -162,6 +162,11 @@ public class AbilityCutter extends Ability implements IAbilityCutter { return arcAngle; } + @Override + public float getTelegraphInnerRadius() { + return innerRadius; + } + @Override public void onExecute(EntityLivingBase caster, EntityLivingBase target) { hitEntities.clear(); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDodge.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDodge.java index 4672998bc..2938af70b 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDodge.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityDodge.java @@ -111,9 +111,10 @@ public class AbilityDodge extends AbilityDefend implements IAbilityDodge { @SideOnly(Side.CLIENT) @Override protected void getTypeDefinitions(List defs) { - defs.add(FieldDef.section("ability.section.dodgeAnimations").tab("Effects")); - FieldDef.insertAfter(defs, "ability.dazedAnimation", + FieldDef.section("ability.section.dodgeAnimations").tab("Effects")); + + FieldDef.insertAfter(defs, "ability.section.dodgeAnimations", FieldDef.animSubGui("ability.dodgeAnimation1", this::getDodgeAnimation1Id, this::setDodgeAnimation1Id, this::getDodgeAnimation1Name, this::setDodgeAnimation1Name) diff --git a/src/main/java/kamkeel/npcs/controllers/data/telegraph/Telegraph.java b/src/main/java/kamkeel/npcs/controllers/data/telegraph/Telegraph.java index d67cadeea..a12292263 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/telegraph/Telegraph.java +++ b/src/main/java/kamkeel/npcs/controllers/data/telegraph/Telegraph.java @@ -152,6 +152,14 @@ public class Telegraph { return t; } + public static Telegraph cone(float length, float angle, float innerRadius) { + Telegraph t = new Telegraph("", TelegraphType.CONE); + t.length = length; + t.angle = angle; + t.innerRadius = innerRadius; + return t; + } + public static Telegraph point() { return new Telegraph("", TelegraphType.POINT); } diff --git a/src/main/java/noppes/npcs/AbstractDataAbilities.java b/src/main/java/noppes/npcs/AbstractDataAbilities.java index 635c4507f..63f632b5b 100644 --- a/src/main/java/noppes/npcs/AbstractDataAbilities.java +++ b/src/main/java/noppes/npcs/AbstractDataAbilities.java @@ -1021,6 +1021,11 @@ public abstract class AbstractDataAbilities { * Execute an ability immediately (no windup). Called when windUpTicks is 0. */ protected void executeImmediate(Ability ability, EntityLivingBase target) { + // Spawn telegraph for abilities that persist during active phase (e.g., Custom Ability) + if (ability.keepTelegraphDuringActive()) { + spawnTelegraph(ability, target); + } + // Play active sound and animation playAbilitySound(ability.getActiveSound()); playAbilityAnimation(ability.getActiveAnimation());