mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-14 00:14:09 +00:00
Add trap presets & trigger-reveal visuals
Introduce client-side trap presets and a visual "trigger reveal" for traps, plus related entity/renderer changes. - AbilityTrap: add TrapPreset enum and applyTrapPresetDefaults; wire a SubGuiTrapPresetSelector hook to apply presets from the GUI; pass visibility into created trap entities. - EntityAbilityZone: add visible flag, TRIGGER_FLASH_STATUS state, setEntityState usage to notify clients of triggers, handleHealthUpdate to start client-side flash, and adjust construction/serialization accordingly. - RenderAbilityZone: implement trigger-reveal visuals (revealFade, triggerReveal) that briefly show a burst when traps trigger, skip rendering for invisible traps unless revealing, and tweak flash/timing logic. - Minor cleanup: remove/condense comment blocks and refactor noisy helpers across AbilityZone/AbilityHazard, plus language entry update and new SubGuiTrapPresetSelector GUI class. These changes enable preset application for traps and improve client-side feedback when traps trigger.
This commit is contained in:
1 parent
89464ce6c0
commit
45d05b9157
7 files changed
+271
-323
No files matched your search
@@ -22,10 +22,6 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Renders zone effects for Trap and Hazard abilities.
|
||||
* Supports CIRCLE and SQUARE shapes with composable visual layers.
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderAbilityZone extends Render {
|
||||
|
||||
@@ -33,43 +29,35 @@ public class RenderAbilityZone extends Render {
|
||||
private static final int ACCENT_LINE_COUNT = 12;
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
// Track last particle spawn tick per entity to avoid duplicate spawns
|
||||
private final Map<Integer, Integer> lastParticleTick = new HashMap<>();
|
||||
|
||||
// Persistent lightning state
|
||||
private final Map<Integer, AttachedLightningRenderer.LightningState> lightningStates = new HashMap<>();
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// RENDER CONTEXT
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
private static final int TRIGGER_REVEAL_TICKS = 10;
|
||||
|
||||
private static class Ctx {
|
||||
EntityAbilityZone zone;
|
||||
ZoneShape shape;
|
||||
float radius, height;
|
||||
float ir, ig, ib; // inner color
|
||||
float ir, ig, ib;
|
||||
float outerR, outerG, outerB;
|
||||
boolean outerEnabled;
|
||||
float time, pulse, rotation, brightness;
|
||||
boolean flash, newTick;
|
||||
float particleDensity, particleScale, animSpeed, lightningDensity;
|
||||
// Visual layer fields (always populated)
|
||||
boolean groundFill, rings, border, accents, lightning, particles;
|
||||
float groundAlpha, borderSpeed;
|
||||
int ringCount, accentStyle, particleMotion, particleSize;
|
||||
boolean particleGlow;
|
||||
String particleDir;
|
||||
boolean trapVisible;
|
||||
boolean triggerReveal;
|
||||
float revealFade;
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// MAIN RENDER
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
@Override
|
||||
public void doRender(Entity entity, double x, double y, double z, float yaw, float partialTicks) {
|
||||
EntityAbilityZone zone = (EntityAbilityZone) entity;
|
||||
|
||||
// Build context
|
||||
Ctx c = new Ctx();
|
||||
c.zone = zone;
|
||||
c.shape = zone.getShape();
|
||||
@@ -92,7 +80,6 @@ public class RenderAbilityZone extends Render {
|
||||
c.animSpeed = zone.getAnimSpeed();
|
||||
c.lightningDensity = zone.getLightningDensity();
|
||||
|
||||
// Visual layer fields — always populated
|
||||
c.groundFill = zone.isGroundFill();
|
||||
c.groundAlpha = zone.getGroundAlpha();
|
||||
c.rings = zone.isRings();
|
||||
@@ -113,7 +100,27 @@ public class RenderAbilityZone extends Render {
|
||||
c.rotation = c.time * 1.5f * c.animSpeed;
|
||||
|
||||
c.brightness = 1.0f;
|
||||
c.trapVisible = true;
|
||||
c.triggerReveal = false;
|
||||
c.revealFade = 0.0f;
|
||||
|
||||
if (zone.getZoneType() == ZoneType.TRAP) {
|
||||
c.trapVisible = zone.isVisible();
|
||||
|
||||
// Trigger reveal: 10-tick full visual burst that fades out
|
||||
if (zone.getTriggerFlashTick() >= 0) {
|
||||
float ticksSinceTrigger = zone.ticksExisted - zone.getTriggerFlashTick() + partialTicks;
|
||||
if (ticksSinceTrigger < TRIGGER_REVEAL_TICKS) {
|
||||
c.triggerReveal = true;
|
||||
c.revealFade = Math.max(0.0f, 1.0f - ticksSinceTrigger / TRIGGER_REVEAL_TICKS);
|
||||
}
|
||||
}
|
||||
|
||||
// Skip render entirely if invisible and not in reveal
|
||||
if (!c.trapVisible && !c.triggerReveal) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!zone.isArmed()) {
|
||||
c.brightness = 0.4f;
|
||||
} else {
|
||||
@@ -121,16 +128,14 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
c.flash = zone.getTriggerFlashTick() >= 0
|
||||
&& zone.ticksExisted - zone.getTriggerFlashTick() < 4;
|
||||
// White flash during first 2 ticks of reveal
|
||||
c.flash = c.triggerReveal && c.revealFade > 0.8f;
|
||||
|
||||
c.newTick = isNewTick(zone);
|
||||
|
||||
// Render
|
||||
setupRenderState();
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslated(x, y, z);
|
||||
|
||||
GL11.glDepthMask(false);
|
||||
|
||||
renderZone(c);
|
||||
@@ -161,14 +166,21 @@ public class RenderAbilityZone extends Render {
|
||||
return state;
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// UNIFIED RENDER — Composable visual layers
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
private void renderZone(Ctx c) {
|
||||
// During trigger reveal, override visual layers for dramatic burst
|
||||
if (c.triggerReveal) {
|
||||
c.brightness = c.revealFade;
|
||||
c.groundFill = true;
|
||||
c.groundAlpha = 0.35f * c.revealFade;
|
||||
c.rings = true;
|
||||
c.ringCount = 3;
|
||||
c.accents = true;
|
||||
c.accentStyle = 2; // FLICKERING
|
||||
c.border = true;
|
||||
}
|
||||
|
||||
float rR = ringR(c), rG = ringG(c), rB = ringB(c);
|
||||
|
||||
// 1. Ground fill
|
||||
if (c.groundFill) {
|
||||
if (c.flash) {
|
||||
renderShapeFill(c.shape, c.radius, 1, 1, 1, 0.5f);
|
||||
@@ -178,7 +190,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Pulse rings
|
||||
if (c.rings) {
|
||||
int count = Math.max(1, Math.min(5, c.ringCount));
|
||||
for (int i = 0; i < count; i++) {
|
||||
@@ -188,18 +199,15 @@ public class RenderAbilityZone extends Render {
|
||||
renderRingLine(c.shape, c.radius * frac,
|
||||
rR, rG, rB, ra, yOff);
|
||||
}
|
||||
// Always include outer edge ring
|
||||
float edgeA = (0.5f + 0.4f * sin(c.pulse + count * Math.PI / 3)) * c.brightness;
|
||||
renderRingLine(c.shape, c.radius, rR, rG, rB, edgeA, 0.02f + count * 0.01f);
|
||||
}
|
||||
|
||||
// 3. Rotating border
|
||||
if (c.border) {
|
||||
renderRotatingBorder(c.shape, c.radius, rR, rG, rB,
|
||||
0.7f * c.brightness, c.rotation * c.borderSpeed, 0.05f);
|
||||
}
|
||||
|
||||
// 4. Vertical accents
|
||||
if (c.accents) {
|
||||
float aa = 0.5f * c.brightness * (0.3f + 0.2f * sin(c.pulse * 0.7f));
|
||||
AccentStyle style = AccentStyle.values()[Math.min(c.accentStyle, AccentStyle.values().length - 1)];
|
||||
@@ -216,7 +224,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Lightning
|
||||
if (c.lightning) {
|
||||
int innerColor = c.zone.getInnerColor();
|
||||
int outerColor = c.outerEnabled ? c.zone.getOuterColor() : innerColor;
|
||||
@@ -246,10 +253,9 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
state.render();
|
||||
GL11.glDepthMask(false); // Reset after lightning
|
||||
GL11.glDepthMask(false);
|
||||
}
|
||||
|
||||
// 6. Particles
|
||||
if (c.particles && c.newTick && c.particleDensity > 0) {
|
||||
if (c.particleDir != null && !c.particleDir.isEmpty()) {
|
||||
if (c.particleDir.startsWith("mc:")) {
|
||||
@@ -263,7 +269,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
/** Spawn vanilla Minecraft particles using mc: prefix (e.g. "mc:flame"). */
|
||||
private void spawnVanillaParticle(Ctx c) {
|
||||
String particleName = c.particleDir.substring(3);
|
||||
int count = Math.round(3 * c.particleDensity);
|
||||
@@ -276,7 +281,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
/** Spawn CustomFX particles using a texture directory. */
|
||||
private void spawnCustomFXParticle(Ctx c) {
|
||||
int count = Math.round(3 * c.particleDensity);
|
||||
for (int i = 0; i < count; i++) {
|
||||
@@ -308,7 +312,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
/** Spawn default ZoneParticleFX with motion style from ParticleMotion enum. */
|
||||
private void spawnDefaultParticles(Ctx c) {
|
||||
int count = Math.round(3 * c.particleDensity);
|
||||
ParticleMotion motion = ParticleMotion.values()[Math.min(c.particleMotion, ParticleMotion.values().length - 1)];
|
||||
@@ -346,7 +349,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
/** Get motion vector for a CustomFX particle based on ParticleMotion ordinal. */
|
||||
private double[] getMotionForStyle(int motionOrdinal) {
|
||||
ParticleMotion motion = ParticleMotion.values()[Math.min(motionOrdinal, ParticleMotion.values().length - 1)];
|
||||
switch (motion) {
|
||||
@@ -371,18 +373,12 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// STYLE HELPERS
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
/** Get the ring/outer color (falls back to inner if outer not enabled). */
|
||||
private float ringR(Ctx c) { return c.outerEnabled ? c.outerR : c.ir; }
|
||||
private float ringG(Ctx c) { return c.outerEnabled ? c.outerG : c.ig; }
|
||||
private float ringB(Ctx c) { return c.outerEnabled ? c.outerB : c.ib; }
|
||||
|
||||
private static float sin(double v) { return (float) Math.sin(v); }
|
||||
|
||||
/** Vertical accents with sinusoidal sway per line. */
|
||||
private void renderSwayingAccents(Ctx c, float r, float g, float b, float a, float height) {
|
||||
if (height <= 0.1f) return;
|
||||
float rotRad = (float) Math.toRadians(c.rotation * 0.2f);
|
||||
@@ -436,7 +432,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
/** Vertical accents with per-line random alpha flicker. */
|
||||
private void renderFlickeringAccents(Ctx c, float r, float g, float b, float baseAlpha, float height) {
|
||||
if (height <= 0.1f) return;
|
||||
float rotRad = (float) Math.toRadians(c.rotation * 0.4f);
|
||||
@@ -492,7 +487,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
/** Pick a random position within the zone's area. Returns {x, y, z} offsets from zone center. */
|
||||
private double[] randomPosInZone(Ctx c) {
|
||||
if (c.shape == ZoneShape.SQUARE) {
|
||||
double px = (RANDOM.nextDouble() * 2 - 1) * c.radius;
|
||||
@@ -507,7 +501,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
/** Pick a random position on the edge of the zone. Returns {x, z}. */
|
||||
private double[] randomEdgePos(Ctx c) {
|
||||
if (c.shape == ZoneShape.SQUARE) {
|
||||
int side = RANDOM.nextInt(4);
|
||||
@@ -525,7 +518,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
/** Spawn a zone particle at world position. */
|
||||
private void spawnParticle(EntityAbilityZone zone, double offsetX, double offsetY, double offsetZ,
|
||||
double mx, double my, double mz,
|
||||
float r, float g, float b, float alpha,
|
||||
@@ -537,10 +529,6 @@ public class RenderAbilityZone extends Render {
|
||||
Minecraft.getMinecraft().effectRenderer.addEffect(particle);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// GL STATE
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
private void setupRenderState() {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
@@ -561,10 +549,6 @@ public class RenderAbilityZone extends Render {
|
||||
GL11.glPopAttrib();
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// SHAPE FILL (Ground plane)
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
private void renderShapeFill(ZoneShape shape, float radius, float r, float g, float b, float a) {
|
||||
GL11.glEnable(GL11.GL_POLYGON_OFFSET_FILL);
|
||||
GL11.glPolygonOffset(-1.0f, -1.0f);
|
||||
@@ -602,10 +586,6 @@ public class RenderAbilityZone extends Render {
|
||||
tess.draw();
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// RING LINES (Concentric pulse rings)
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
private void renderRingLine(ZoneShape shape, float radius,
|
||||
float r, float g, float b, float a, float yOffset) {
|
||||
switch (shape) {
|
||||
@@ -640,18 +620,13 @@ public class RenderAbilityZone extends Render {
|
||||
tess.draw();
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// ROTATING BORDER
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
private void renderRotatingBorder(ZoneShape shape, float radius,
|
||||
float r, float g, float b, float a,
|
||||
float rotationDeg, float yOffset) {
|
||||
int dashCount = 16;
|
||||
|
||||
if (shape == ZoneShape.SQUARE) {
|
||||
// Dashes along 4 rectangle edges with offset
|
||||
float perimeter = radius * 8; // total perimeter = 4 * (2*radius)
|
||||
float perimeter = radius * 8;
|
||||
float dashLen = perimeter / dashCount;
|
||||
float offset = (rotationDeg % 360.0f) / 360.0f * perimeter;
|
||||
|
||||
@@ -691,7 +666,6 @@ public class RenderAbilityZone extends Render {
|
||||
}
|
||||
}
|
||||
|
||||
/** Convert a distance along the square perimeter to an x,z position. */
|
||||
private double[] perimeterPos(float dist, float radius) {
|
||||
float sideLen = radius * 2;
|
||||
if (dist < sideLen) {
|
||||
@@ -713,10 +687,6 @@ public class RenderAbilityZone extends Render {
|
||||
return new double[]{-radius, radius - dist};
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// VERTICAL ACCENT LINES
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
private void renderVerticalAccents(ZoneShape shape, float radius,
|
||||
float r, float g, float b, float a,
|
||||
float height, float rotationDeg) {
|
||||
@@ -725,7 +695,6 @@ public class RenderAbilityZone extends Render {
|
||||
Tessellator tess = Tessellator.instance;
|
||||
|
||||
if (shape == ZoneShape.SQUARE) {
|
||||
// Lines at corners + distributed along edges
|
||||
int perSide = Math.max(1, ACCENT_LINE_COUNT / 4);
|
||||
for (int side = 0; side < 4; side++) {
|
||||
for (int j = 0; j < perSide; j++) {
|
||||
@@ -745,7 +714,6 @@ public class RenderAbilityZone extends Render {
|
||||
tess.draw();
|
||||
}
|
||||
}
|
||||
// Corner accent lines
|
||||
float[][] corners = {{-radius, -radius}, {radius, -radius}, {radius, radius}, {-radius, radius}};
|
||||
for (float[] corner : corners) {
|
||||
tess.startDrawing(GL11.GL_LINES);
|
||||
|
||||
@@ -19,14 +19,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Hazard ability: Creates persistent ground effect zones around the caster.
|
||||
* Spawns one or more EntityAbilityZone entities in random positions
|
||||
* within spawnRadius. Damage and zone logic handled by the entity.
|
||||
*/
|
||||
public class AbilityHazard extends AbilityZone implements IAbilityHazard {
|
||||
|
||||
// Hazard-specific fields
|
||||
private float radius = 2.0f;
|
||||
private float damagePerSecond = 1.0f;
|
||||
private int damageInterval = 20;
|
||||
@@ -51,7 +45,6 @@ public class AbilityHazard extends AbilityZone implements IAbilityHazard {
|
||||
public void onExecute(EntityLivingBase caster, EntityLivingBase target) {
|
||||
activeEntities.clear();
|
||||
|
||||
// Use pre-calculated positions from telegraph phase, or generate new ones
|
||||
List<double[]> positions;
|
||||
if (!preCalculatedPositions.isEmpty() && preCalculatedPositions.size() == zoneCount) {
|
||||
positions = new ArrayList<>(preCalculatedPositions);
|
||||
@@ -93,10 +86,6 @@ public class AbilityHazard extends AbilityZone implements IAbilityHazard {
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// NBT
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
@Override
|
||||
public void writeTypeNBT(NBTTagCompound nbt) {
|
||||
writeZoneNBT(nbt);
|
||||
@@ -117,10 +106,6 @@ public class AbilityHazard extends AbilityZone implements IAbilityHazard {
|
||||
this.affectsCaster = nbt.getBoolean("affectsCaster");
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// HAZARD-SPECIFIC GETTERS & SETTERS
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
public float getRadius() { return radius; }
|
||||
public void setRadius(float radius) { this.radius = radius; }
|
||||
|
||||
@@ -136,10 +121,6 @@ public class AbilityHazard extends AbilityZone implements IAbilityHazard {
|
||||
public boolean isAffectsCaster() { return affectsCaster; }
|
||||
public void setAffectsCaster(boolean affectsCaster) { this.affectsCaster = affectsCaster; }
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// GUI FIELD DEFINITIONS
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void getAbilityDefinitions(List<FieldDef> defs) {
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package kamkeel.npcs.controllers.data.ability.type;
|
||||
|
||||
import kamkeel.npcs.controllers.data.ability.AbilityEffect;
|
||||
import kamkeel.npcs.controllers.data.ability.data.EnergyDisplayData;
|
||||
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
|
||||
import kamkeel.npcs.entity.EntityAbilityZone;
|
||||
import kamkeel.npcs.entity.EntityAbilityZone.ZoneShape;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
|
||||
import noppes.npcs.api.ability.type.IAbilityTrap;
|
||||
|
||||
import noppes.npcs.client.gui.SubGuiTrapPresetSelector;
|
||||
import noppes.npcs.client.gui.builder.FieldDef;
|
||||
import kamkeel.npcs.controllers.data.ability.gui.AbilityFieldDefs;
|
||||
import noppes.npcs.constants.EnumPotionType;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
@@ -19,14 +19,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Trap ability: Places proximity-triggered traps around the caster.
|
||||
* Spawns one or more EntityAbilityZone entities in random positions
|
||||
* within spawnRadius of the caster. Damage and trigger logic handled by the entity.
|
||||
*/
|
||||
public class AbilityTrap extends AbilityZone implements IAbilityTrap {
|
||||
|
||||
// Trap-specific fields
|
||||
private float triggerRadius = 2.0f;
|
||||
private int armTime = 20;
|
||||
private int maxTriggers = 1;
|
||||
@@ -54,7 +48,6 @@ public class AbilityTrap extends AbilityZone implements IAbilityTrap {
|
||||
public void onExecute(EntityLivingBase caster, EntityLivingBase target) {
|
||||
activeEntities.clear();
|
||||
|
||||
// Use pre-calculated positions from telegraph phase, or generate new ones
|
||||
List<double[]> positions;
|
||||
if (!preCalculatedPositions.isEmpty() && preCalculatedPositions.size() == zoneCount) {
|
||||
positions = new ArrayList<>(preCalculatedPositions);
|
||||
@@ -81,6 +74,7 @@ public class AbilityTrap extends AbilityZone implements IAbilityTrap {
|
||||
colorData.innerColor, colorData.outerColor, colorData.outerColorEnabled,
|
||||
zoneHeight,
|
||||
particleDensity, particleScale, animSpeed, lightningDensity,
|
||||
visible,
|
||||
getEffects());
|
||||
|
||||
applyVisualToEntity(entity);
|
||||
@@ -94,9 +88,81 @@ public class AbilityTrap extends AbilityZone implements IAbilityTrap {
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// NBT
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
@SideOnly(Side.CLIENT)
|
||||
public enum TrapPreset {
|
||||
HIDDEN, VENOM, EXPLOSIVE, CURSED, SHOCK, SNARE;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ability.preset." + name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
private void applyTrapPresetDefaults(String preset) {
|
||||
effects.clear();
|
||||
particleDir = "";
|
||||
|
||||
groundFill = true;
|
||||
rings = false;
|
||||
ringCount = 1;
|
||||
border = false;
|
||||
borderSpeed = 1.0f;
|
||||
accents = false;
|
||||
accentStyle = 0;
|
||||
lightning = false;
|
||||
particleGlow = false;
|
||||
|
||||
switch (preset) {
|
||||
case "VENOM":
|
||||
groundAlpha = 0.04f;
|
||||
particles = true; particleDensity = 0.3f; particleScale = 0.5f;
|
||||
particleMotion = 1; particleDir = "mc:mobSpell";
|
||||
colorData.innerColor = 0x44DD44; colorData.outerColor = 0x116611;
|
||||
windUpColor = 0x6044DD44; activeColor = 0xC044FF44;
|
||||
effects.add(new AbilityEffect(EnumPotionType.Poison, 100, 0));
|
||||
break;
|
||||
case "EXPLOSIVE":
|
||||
groundAlpha = 0.04f;
|
||||
particles = true; particleDensity = 0.3f; particleScale = 0.6f;
|
||||
particleMotion = 0; particleDir = "mc:smoke";
|
||||
colorData.innerColor = 0xFF6611; colorData.outerColor = 0xCC2200;
|
||||
windUpColor = 0x60FF6611; activeColor = 0xC0FF4400;
|
||||
effects.add(new AbilityEffect(EnumPotionType.Fire, 60, 0));
|
||||
break;
|
||||
case "CURSED":
|
||||
groundAlpha = 0.04f;
|
||||
particles = true; particleDensity = 0.3f; particleScale = 0.5f;
|
||||
particleMotion = 1; particleDir = "mc:portal";
|
||||
colorData.innerColor = 0xAA44FF; colorData.outerColor = 0x6622BB;
|
||||
windUpColor = 0x60AA44FF; activeColor = 0xC0CC66FF;
|
||||
effects.add(new AbilityEffect(EnumPotionType.Weakness, 100, 0));
|
||||
break;
|
||||
case "SHOCK":
|
||||
groundAlpha = 0.04f;
|
||||
particles = true; particleDensity = 0.3f; particleScale = 0.4f;
|
||||
particleMotion = 2; particleDir = "mc:enchantmenttable";
|
||||
colorData.innerColor = 0x4488FF; colorData.outerColor = 0x2244BB;
|
||||
windUpColor = 0x604488FF; activeColor = 0xC066AAFF;
|
||||
effects.add(new AbilityEffect(EnumPotionType.MiningFatigue, 80, 1));
|
||||
break;
|
||||
case "SNARE":
|
||||
groundAlpha = 0.04f;
|
||||
particles = true; particleDensity = 0.3f; particleScale = 0.5f;
|
||||
particleMotion = 1; particleDir = "mc:snowshovel";
|
||||
colorData.innerColor = 0x88CCFF; colorData.outerColor = 0x4488CC;
|
||||
windUpColor = 0x6088CCFF; activeColor = 0xC0AADDFF;
|
||||
effects.add(new AbilityEffect(EnumPotionType.Slowness, 100, 1));
|
||||
break;
|
||||
case "HIDDEN":
|
||||
default:
|
||||
groundAlpha = 0.03f;
|
||||
particles = false; particleDensity = 0.0f; particleScale = 1.0f;
|
||||
particleMotion = 0;
|
||||
colorData.innerColor = 0x888888; colorData.outerColor = 0x444444;
|
||||
windUpColor = 0x60888888; activeColor = 0xC0AAAAAA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTypeNBT(NBTTagCompound nbt) {
|
||||
@@ -124,10 +190,6 @@ public class AbilityTrap extends AbilityZone implements IAbilityTrap {
|
||||
this.visible = nbt.getBoolean("visible");
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// TRAP-SPECIFIC GETTERS & SETTERS
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
public float getTriggerRadius() { return triggerRadius; }
|
||||
public void setTriggerRadius(float triggerRadius) { this.triggerRadius = triggerRadius; }
|
||||
public int getArmTime() { return armTime; }
|
||||
@@ -145,9 +207,18 @@ public class AbilityTrap extends AbilityZone implements IAbilityTrap {
|
||||
public boolean isVisible() { return visible; }
|
||||
public void setVisible(boolean visible) { this.visible = visible; }
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// GUI FIELD DEFINITIONS
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
protected void addPresetFieldDef(List<FieldDef> defs) {
|
||||
defs.add(FieldDef.subGuiField("gui.applyPreset",
|
||||
SubGuiTrapPresetSelector::new,
|
||||
gui -> {
|
||||
SubGuiTrapPresetSelector selector = (SubGuiTrapPresetSelector) gui;
|
||||
if (selector.selectedPreset != null) {
|
||||
applyTrapPresetDefaults(selector.selectedPreset);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
|
||||
@@ -31,27 +31,20 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Abstract base class for zone-based abilities (Trap, Hazard).
|
||||
* Extracts shared fields: duration, shape, spawn, visual, lifecycle, and FieldDefs.
|
||||
*/
|
||||
public abstract class AbilityZone extends Ability {
|
||||
|
||||
// Zone properties
|
||||
protected int durationTicks;
|
||||
protected ZoneShape zoneShape = ZoneShape.CIRCLE;
|
||||
protected float spawnRadius = 10.0f;
|
||||
protected int zoneCount = 3;
|
||||
protected float zoneHeight = 2.0f;
|
||||
|
||||
// Visual parameters
|
||||
protected float particleDensity = 1.0f;
|
||||
protected float particleScale = 1.0f;
|
||||
protected float animSpeed = 1.0f;
|
||||
protected float lightningDensity = 1.0f;
|
||||
protected EnergyDisplayData colorData;
|
||||
|
||||
// Visual layer fields (always active)
|
||||
protected boolean groundFill = true;
|
||||
protected float groundAlpha = 0.25f;
|
||||
protected boolean rings = true;
|
||||
@@ -67,7 +60,6 @@ public abstract class AbilityZone extends Ability {
|
||||
protected int particleSize = 32;
|
||||
protected boolean particleGlow = true;
|
||||
|
||||
// Runtime state
|
||||
protected static final Random RANDOM = new Random();
|
||||
protected transient List<EntityAbilityZone> activeEntities = new ArrayList<>();
|
||||
protected transient List<double[]> preCalculatedPositions = new ArrayList<>();
|
||||
@@ -82,10 +74,6 @@ public abstract class AbilityZone extends Ability {
|
||||
this.allowedBy = UserType.NPC_ONLY;
|
||||
}
|
||||
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
// SHARED OVERRIDES
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
|
||||
@Override
|
||||
public boolean allowBurst() {
|
||||
return false;
|
||||
@@ -101,17 +89,12 @@ public abstract class AbilityZone extends Ability {
|
||||
return new TargetingMode[]{TargetingMode.AGGRO_TARGET};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual zone effect radius for telegraph sizing.
|
||||
* AbilityHazard returns its damage radius, AbilityTrap returns triggerRadius.
|
||||
*/
|
||||
public abstract float getZoneRadius();
|
||||
|
||||
@Override
|
||||
public List<TelegraphInstance> createTelegraphs(EntityLivingBase caster, EntityLivingBase target) {
|
||||
if (!showTelegraph || windUpTicks <= 0) return new ArrayList<>();
|
||||
|
||||
// Pre-calculate zone positions
|
||||
preCalculatedPositions.clear();
|
||||
List<double[]> placedPositions = new ArrayList<>();
|
||||
float minSeparation = getZoneRadius() * 2.0f;
|
||||
@@ -122,7 +105,6 @@ public abstract class AbilityZone extends Ability {
|
||||
preCalculatedPositions.add(pos);
|
||||
}
|
||||
|
||||
// Create a telegraph for each zone position
|
||||
List<TelegraphInstance> telegraphs = new ArrayList<>();
|
||||
float zoneRadius = getZoneRadius();
|
||||
|
||||
@@ -152,7 +134,6 @@ public abstract class AbilityZone extends Ability {
|
||||
|
||||
@Override
|
||||
public void onActiveTick(EntityLivingBase caster, EntityLivingBase target, int tick) {
|
||||
// Remove dead entities
|
||||
Iterator<EntityAbilityZone> it = activeEntities.iterator();
|
||||
while (it.hasNext()) {
|
||||
EntityAbilityZone entity = it.next();
|
||||
@@ -192,13 +173,6 @@ public abstract class AbilityZone extends Ability {
|
||||
return durationTicks + 10;
|
||||
}
|
||||
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
// SHARED SPAWN HELPER
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* Find a non-overlapping spawn position within spawnRadius of the caster.
|
||||
*/
|
||||
protected double[] findSpawnPosition(EntityLivingBase caster, List<double[]> placedPositions, float minSeparation) {
|
||||
double spawnX = caster.posX;
|
||||
double spawnZ = caster.posZ;
|
||||
@@ -227,9 +201,6 @@ public abstract class AbilityZone extends Ability {
|
||||
return new double[]{spawnX, spawnZ};
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply visual settings to a zone entity.
|
||||
*/
|
||||
protected void applyVisualToEntity(EntityAbilityZone entity) {
|
||||
entity.applyVisual(groundFill, groundAlpha,
|
||||
rings, ringCount, border, borderSpeed,
|
||||
@@ -238,13 +209,6 @@ public abstract class AbilityZone extends Ability {
|
||||
particleSize, particleGlow);
|
||||
}
|
||||
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
// PRESET SUPPORT
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* Apply preset defaults by style name.
|
||||
*/
|
||||
private void applyPresetDefaults(String styleName) {
|
||||
effects.clear();
|
||||
particleDir = "";
|
||||
@@ -307,10 +271,6 @@ public abstract class AbilityZone extends Ability {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Client-only preset enum for the GUI dropdown.
|
||||
* Not persisted — presets simply set field values.
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public enum ZonePreset {
|
||||
DEFAULT, TOXIC, INFERNO, ARCANE, ELECTRIC, FROST;
|
||||
@@ -321,10 +281,6 @@ public abstract class AbilityZone extends Ability {
|
||||
}
|
||||
}
|
||||
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
// SHARED NBT
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
|
||||
protected void writeZoneNBT(NBTTagCompound nbt) {
|
||||
nbt.setInteger("durationTicks", durationTicks);
|
||||
nbt.setString("zoneShape", zoneShape.name());
|
||||
@@ -337,7 +293,6 @@ public abstract class AbilityZone extends Ability {
|
||||
nbt.setFloat("lightningDensity", lightningDensity);
|
||||
colorData.writeNBT(nbt);
|
||||
|
||||
// Visual layer fields — always written as top-level keys
|
||||
nbt.setBoolean("groundFill", groundFill);
|
||||
nbt.setFloat("groundAlpha", groundAlpha);
|
||||
nbt.setBoolean("rings", rings);
|
||||
@@ -367,7 +322,6 @@ public abstract class AbilityZone extends Ability {
|
||||
this.lightningDensity = nbt.getFloat("lightningDensity");
|
||||
colorData.readNBT(nbt);
|
||||
|
||||
// Visual layer fields
|
||||
this.groundFill = nbt.getBoolean("groundFill");
|
||||
this.groundAlpha = nbt.getFloat("groundAlpha");
|
||||
this.rings = nbt.getBoolean("rings");
|
||||
@@ -384,10 +338,6 @@ public abstract class AbilityZone extends Ability {
|
||||
this.particleGlow = nbt.getBoolean("particleGlow");
|
||||
}
|
||||
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
// SHARED GETTERS & SETTERS
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
|
||||
public int getDurationTicks() { return durationTicks; }
|
||||
public void setDurationTicks(int durationTicks) { this.durationTicks = Math.max(1, durationTicks); }
|
||||
|
||||
@@ -416,7 +366,6 @@ public abstract class AbilityZone extends Ability {
|
||||
public float getLightningDensity() { return lightningDensity; }
|
||||
public void setLightningDensity(float v) { this.lightningDensity = Math.max(0, Math.min(3, v)); }
|
||||
|
||||
// Color getters/setters
|
||||
public int getInnerColor() { return colorData.innerColor; }
|
||||
public void setInnerColor(int color) { colorData.innerColor = color; }
|
||||
public int getOuterColor() { return colorData.outerColor; }
|
||||
@@ -424,7 +373,6 @@ public abstract class AbilityZone extends Ability {
|
||||
public boolean isOuterColorEnabled() { return colorData.outerColorEnabled; }
|
||||
public void setOuterColorEnabled(boolean enabled) { colorData.outerColorEnabled = enabled; }
|
||||
|
||||
// Visual layer getters/setters
|
||||
public boolean isGroundFill() { return groundFill; }
|
||||
public void setGroundFill(boolean v) { this.groundFill = v; }
|
||||
public float getGroundAlpha() { return groundAlpha; }
|
||||
@@ -458,10 +406,6 @@ public abstract class AbilityZone extends Ability {
|
||||
public boolean isParticleGlow() { return particleGlow; }
|
||||
public void setParticleGlow(boolean v) { this.particleGlow = v; }
|
||||
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
// SHARED FIELD DEFINITIONS (client-only)
|
||||
// ═════════════════════════════════════════════════════════════════
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
protected void addPresetFieldDef(List<FieldDef> defs) {
|
||||
defs.add(FieldDef.subGuiField("gui.applyPreset",
|
||||
@@ -477,42 +421,36 @@ public abstract class AbilityZone extends Ability {
|
||||
@SideOnly(Side.CLIENT)
|
||||
protected void addVisualFieldDefs(List<FieldDef> defs) {
|
||||
defs.addAll(Arrays.asList(
|
||||
// Ground Fill
|
||||
FieldDef.section("ability.section.ground").tab("ability.tab.visual"),
|
||||
FieldDef.row(
|
||||
FieldDef.boolField("gui.enabled", this::isGroundFill, this::setGroundFill),
|
||||
FieldDef.floatField("gui.alpha", this::getGroundAlpha, this::setGroundAlpha)
|
||||
).tab("ability.tab.visual"),
|
||||
|
||||
// Rings
|
||||
FieldDef.section("ability.section.rings").tab("ability.tab.visual"),
|
||||
FieldDef.row(
|
||||
FieldDef.boolField("gui.enabled", this::isRings, this::setRings),
|
||||
FieldDef.intField("gui.count", this::getRingCount, this::setRingCount).range(1, 5)
|
||||
).tab("ability.tab.visual"),
|
||||
|
||||
// Border
|
||||
FieldDef.section("ability.section.border").tab("ability.tab.visual"),
|
||||
FieldDef.row(
|
||||
FieldDef.boolField("gui.enabled", this::isBorder, this::setBorder),
|
||||
FieldDef.floatField("gui.speed", this::getBorderSpeed, this::setBorderSpeed)
|
||||
).tab("ability.tab.visual"),
|
||||
|
||||
// Accents
|
||||
FieldDef.section("ability.section.accents").tab("ability.tab.visual"),
|
||||
FieldDef.row(
|
||||
FieldDef.boolField("gui.enabled", this::isAccents, this::setAccents),
|
||||
FieldDef.enumField("gui.style", AccentStyle.class, this::getAccentStyleEnum, this::setAccentStyleEnum)
|
||||
).tab("ability.tab.visual"),
|
||||
|
||||
// Lightning
|
||||
FieldDef.section("ability.section.lightning").tab("ability.tab.visual"),
|
||||
FieldDef.row(
|
||||
FieldDef.boolField("gui.enabled", this::isLightning, this::setLightning),
|
||||
FieldDef.floatField("gui.density", this::getLightningDensity, this::setLightningDensity)
|
||||
).tab("ability.tab.visual"),
|
||||
|
||||
// Particles
|
||||
FieldDef.section("ability.section.particles").tab("ability.tab.visual"),
|
||||
FieldDef.boolField("gui.enabled", this::isParticles, this::setParticles)
|
||||
.tab("ability.tab.visual"),
|
||||
@@ -527,12 +465,10 @@ public abstract class AbilityZone extends Ability {
|
||||
FieldDef.stringField("gui.texture", this::getParticleDir, this::setParticleDir)
|
||||
.tab("ability.tab.visual").visibleWhen(this::isParticles),
|
||||
|
||||
// Animation
|
||||
FieldDef.section("ability.section.animation").tab("ability.tab.visual"),
|
||||
FieldDef.floatField("gui.speed", this::getAnimSpeed, this::setAnimSpeed)
|
||||
.tab("ability.tab.visual"),
|
||||
|
||||
// Colors
|
||||
FieldDef.section("ability.section.colors").tab("ability.tab.visual"),
|
||||
FieldDef.colorSubGui("ability.innerColor", this::getInnerColor, this::setInnerColor)
|
||||
.tab("ability.tab.visual"),
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Shared zone entity for Trap and Hazard abilities.
|
||||
* Handles rendering, positioning, and damage logic.
|
||||
* ZoneType distinguishes behavior: TRAP (proximity-triggered burst) vs HAZARD (persistent AoE).
|
||||
*/
|
||||
public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnData {
|
||||
|
||||
@@ -76,11 +76,11 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
}
|
||||
}
|
||||
|
||||
/** Tiny Y offset above ground to prevent z-clipping */
|
||||
private static final double GROUND_OFFSET = 0.005;
|
||||
private static final byte TRIGGER_FLASH_STATUS = 60;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// COMMON PROPERTIES (synced via ByteBuf)
|
||||
// COMMON PROPERTIES
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
private ZoneType zoneType = ZoneType.TRAP;
|
||||
@@ -99,13 +99,12 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
|
||||
private float zoneHeight = 2.0f;
|
||||
|
||||
// Visual parameters (synced for renderer)
|
||||
private float particleDensity = 1.0f;
|
||||
private float particleScale = 1.0f;
|
||||
private float animSpeed = 1.0f;
|
||||
private float lightningDensity = 1.0f;
|
||||
|
||||
// Visual layer parameters (always active)
|
||||
// Visual layer fields
|
||||
private boolean groundFill = true;
|
||||
private float groundAlpha = 0.25f;
|
||||
private boolean rings = true;
|
||||
@@ -113,18 +112,15 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
private boolean border = true;
|
||||
private float borderSpeed = 1.0f;
|
||||
private boolean accents = true;
|
||||
private int accentStyle = 0; // AccentStyle ordinal
|
||||
private int accentStyle = 0;
|
||||
private boolean lightning = false;
|
||||
private boolean particles = true;
|
||||
private int particleMotion = 0; // ParticleMotion ordinal
|
||||
private int particleMotion = 0;
|
||||
private String particleDir = "";
|
||||
private int particleSize = 32;
|
||||
private boolean particleGlow = true;
|
||||
|
||||
// Lifetime
|
||||
private long deathWorldTime = -1;
|
||||
|
||||
// Effects
|
||||
private List<AbilityEffect> effects = new ArrayList<>();
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
@@ -138,6 +134,7 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
private float damage = 6.0f;
|
||||
private float damageRadius = 0.0f;
|
||||
private float knockback = 0.5f;
|
||||
private boolean visible = true;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// HAZARD-SPECIFIC PROPERTIES
|
||||
@@ -149,21 +146,18 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
private boolean affectsCaster = false;
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// RUNTIME STATE (transient)
|
||||
// RUNTIME STATE
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
// Trap runtime
|
||||
private transient boolean armed = false;
|
||||
private transient int triggerCount = 0;
|
||||
private transient int ticksSinceLastTrigger = 0;
|
||||
private transient Set<UUID> triggeredEntities = new HashSet<>();
|
||||
private transient int triggerFlashTick = -1; // For visual flash on trigger
|
||||
private transient int triggerFlashTick = -1;
|
||||
|
||||
// Hazard runtime
|
||||
private transient int ticksSinceDamage = 0;
|
||||
private transient Set<Integer> damagedThisTick = new HashSet<>();
|
||||
|
||||
// Preview mode
|
||||
private boolean previewMode = false;
|
||||
private EntityLivingBase previewOwner = null;
|
||||
|
||||
@@ -179,11 +173,6 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
this.ignoreFrustumCheck = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full constructor for creating a zone entity.
|
||||
* Use the static factory methods for cleaner creation.
|
||||
* Position is snapped to ground level with a tiny offset to avoid z-clipping.
|
||||
*/
|
||||
private EntityAbilityZone(World world, ZoneType type, EntityLivingBase owner,
|
||||
double x, double y, double z) {
|
||||
this(world);
|
||||
@@ -194,9 +183,6 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
this.setPosition(x, groundY, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Trap zone entity.
|
||||
*/
|
||||
public static EntityAbilityZone createTrap(World world, EntityLivingBase owner,
|
||||
double x, double y, double z,
|
||||
ZoneShape shape,
|
||||
@@ -207,6 +193,7 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
float zoneHeight,
|
||||
float particleDensity, float particleScale,
|
||||
float animSpeed, float lightningDensity,
|
||||
boolean visible,
|
||||
List<AbilityEffect> effects) {
|
||||
EntityAbilityZone zone = new EntityAbilityZone(world, ZoneType.TRAP, owner, x, y, z);
|
||||
zone.shape = shape;
|
||||
@@ -228,19 +215,16 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
zone.particleScale = particleScale;
|
||||
zone.animSpeed = animSpeed;
|
||||
zone.lightningDensity = lightningDensity;
|
||||
zone.visible = visible;
|
||||
if (effects != null) {
|
||||
for (AbilityEffect e : effects) {
|
||||
zone.effects.add(e.copy());
|
||||
}
|
||||
}
|
||||
// Ready to trigger immediately after arm time
|
||||
zone.ticksSinceLastTrigger = triggerCooldown;
|
||||
return zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Hazard zone entity.
|
||||
*/
|
||||
public static EntityAbilityZone createHazard(World world, EntityLivingBase owner,
|
||||
double x, double y, double z,
|
||||
ZoneShape shape,
|
||||
@@ -275,7 +259,6 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
zone.effects.add(e.copy());
|
||||
}
|
||||
}
|
||||
// Ready to deal damage immediately
|
||||
zone.ticksSinceDamage = damageInterval;
|
||||
return zone;
|
||||
}
|
||||
@@ -285,8 +268,15 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
@Override
|
||||
protected void entityInit() {
|
||||
// No DataWatcher needed
|
||||
protected void entityInit() {}
|
||||
|
||||
@Override
|
||||
public void handleHealthUpdate(byte id) {
|
||||
if (id == TRIGGER_FLASH_STATUS) {
|
||||
this.triggerFlashTick = this.ticksExisted;
|
||||
} else {
|
||||
super.handleHealthUpdate(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -297,18 +287,15 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
|
||||
super.onUpdate();
|
||||
|
||||
// Set death time on first tick
|
||||
if (deathWorldTime < 0 && worldObj != null) {
|
||||
deathWorldTime = worldObj.getTotalWorldTime() + maxTicks;
|
||||
}
|
||||
|
||||
// Check lifetime
|
||||
if (deathWorldTime > 0 && worldObj.getTotalWorldTime() >= deathWorldTime) {
|
||||
this.setDead();
|
||||
return;
|
||||
}
|
||||
|
||||
// Server handles damage
|
||||
if (!worldObj.isRemote && !previewMode) {
|
||||
switch (zoneType) {
|
||||
case TRAP:
|
||||
@@ -322,11 +309,10 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// TRAP LOGIC (server-only)
|
||||
// TRAP LOGIC
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
private void tickTrap() {
|
||||
// Arm time countdown
|
||||
if (!armed) {
|
||||
if (ticksExisted >= armTime) {
|
||||
armed = true;
|
||||
@@ -336,18 +322,15 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
|
||||
ticksSinceLastTrigger++;
|
||||
|
||||
// All triggers used
|
||||
if (maxTriggers > 0 && triggerCount >= maxTriggers) {
|
||||
this.setDead();
|
||||
return;
|
||||
}
|
||||
|
||||
// Cooldown between triggers
|
||||
if (ticksSinceLastTrigger < triggerCooldown) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Proximity detection
|
||||
AxisAlignedBB box = AxisAlignedBB.getBoundingBox(
|
||||
posX - triggerRadius, posY - 0.5, posZ - triggerRadius,
|
||||
posX + triggerRadius, posY + zoneHeight, posZ + triggerRadius
|
||||
@@ -419,7 +402,6 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
anyDamaged = true;
|
||||
}
|
||||
|
||||
// Apply knockback only if damage landed
|
||||
if (hit && knockback > 0) {
|
||||
double dx = entity.posX - posX;
|
||||
double dz = entity.posZ - posZ;
|
||||
@@ -430,23 +412,22 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
}
|
||||
}
|
||||
|
||||
// Apply effects only if damage landed
|
||||
if (hit) {
|
||||
applyEffects(entity);
|
||||
}
|
||||
}
|
||||
|
||||
// Only count the trigger if at least one entity was actually damaged
|
||||
if (anyDamaged) {
|
||||
triggerCount++;
|
||||
ticksSinceLastTrigger = 0;
|
||||
triggeredEntities.add(triggerer.getUniqueID());
|
||||
triggerFlashTick = ticksExisted;
|
||||
worldObj.setEntityState(this, TRIGGER_FLASH_STATUS);
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// HAZARD LOGIC (server-only)
|
||||
// HAZARD LOGIC
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
private void tickHazard() {
|
||||
@@ -545,12 +526,12 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean isInRangeToRenderDist(double distance) {
|
||||
return distance < 16384.0D; // 128 blocks
|
||||
return distance < 16384.0D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderInPass(int pass) {
|
||||
return pass == 1; // Translucent pass
|
||||
return pass == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -576,6 +557,7 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
public boolean isOuterColorEnabled() { return outerColorEnabled; }
|
||||
public float getZoneHeight() { return zoneHeight; }
|
||||
public boolean isArmed() { return armed || ticksExisted >= armTime; }
|
||||
public boolean isVisible() { return visible; }
|
||||
public int getTriggerFlashTick() { return triggerFlashTick; }
|
||||
public int getDurationTicks() { return durationTicks; }
|
||||
public int getMaxTicks() { return maxTicks; }
|
||||
@@ -584,7 +566,6 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
public float getAnimSpeed() { return animSpeed; }
|
||||
public float getLightningDensity() { return lightningDensity; }
|
||||
|
||||
// Visual layer getters
|
||||
public boolean isGroundFill() { return groundFill; }
|
||||
public float getGroundAlpha() { return groundAlpha; }
|
||||
public boolean isRings() { return rings; }
|
||||
@@ -600,9 +581,6 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
public int getParticleSize() { return particleSize; }
|
||||
public boolean isParticleGlow() { return particleGlow; }
|
||||
|
||||
/**
|
||||
* Apply visual settings from ability data.
|
||||
*/
|
||||
public void applyVisual(boolean groundFill, float groundAlpha,
|
||||
boolean rings, int ringCount,
|
||||
boolean border, float borderSpeed,
|
||||
@@ -626,44 +604,6 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
this.particleGlow = particleGlow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply preset defaults by old style name (for backward compatibility).
|
||||
*/
|
||||
private void applyPresetDefaults(String styleName) {
|
||||
switch (styleName) {
|
||||
case "TOXIC":
|
||||
groundFill = true; groundAlpha = 0.30f; rings = true; ringCount = 3;
|
||||
border = false; borderSpeed = 1.0f; accents = true; accentStyle = 1;
|
||||
lightning = false; particles = true; particleMotion = 0; particleGlow = true;
|
||||
break;
|
||||
case "INFERNO":
|
||||
groundFill = true; groundAlpha = 0.35f; rings = true; ringCount = 3;
|
||||
border = true; borderSpeed = 2.0f; accents = true; accentStyle = 2;
|
||||
lightning = false; particles = true; particleMotion = 0; particleGlow = true;
|
||||
break;
|
||||
case "ARCANE":
|
||||
groundFill = true; groundAlpha = 0.20f; rings = true; ringCount = 1;
|
||||
border = true; borderSpeed = 0.8f; accents = true; accentStyle = 0;
|
||||
lightning = false; particles = true; particleMotion = 1; particleGlow = true;
|
||||
break;
|
||||
case "ELECTRIC":
|
||||
groundFill = true; groundAlpha = 0.15f; rings = false; ringCount = 1;
|
||||
border = false; borderSpeed = 1.0f; accents = false; accentStyle = 0;
|
||||
lightning = true; particles = true; particleMotion = 2; particleGlow = true;
|
||||
break;
|
||||
case "FROST":
|
||||
groundFill = true; groundAlpha = 0.25f; rings = true; ringCount = 3;
|
||||
border = true; borderSpeed = 0.3f; accents = true; accentStyle = 0;
|
||||
lightning = false; particles = true; particleMotion = 1; particleGlow = true;
|
||||
break;
|
||||
default: // DEFAULT
|
||||
groundFill = true; groundAlpha = 0.25f; rings = true; ringCount = 3;
|
||||
border = true; borderSpeed = 1.0f; accents = true; accentStyle = 0;
|
||||
lightning = false; particles = false; particleMotion = 0; particleGlow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
// NBT SERIALIZATION
|
||||
// ═══════════════════════════════════════════════════════════════════
|
||||
@@ -671,16 +611,9 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
@Override
|
||||
protected void readEntityFromNBT(NBTTagCompound nbt) {
|
||||
this.zoneType = ZoneType.values()[nbt.getInteger("ZoneType")];
|
||||
|
||||
// Shape: read new string key first, fall back to old ordinal (always CIRCLE for old RING/CONE)
|
||||
if (nbt.hasKey("ShapeName")) {
|
||||
try {
|
||||
this.shape = ZoneShape.valueOf(nbt.getString("ShapeName"));
|
||||
} catch (Exception e) {
|
||||
this.shape = ZoneShape.CIRCLE;
|
||||
}
|
||||
} else {
|
||||
// Legacy: old ordinal data — RING(1) and CONE(2) map to CIRCLE
|
||||
try {
|
||||
this.shape = ZoneShape.valueOf(nbt.getString("ShapeName"));
|
||||
} catch (Exception e) {
|
||||
this.shape = ZoneShape.CIRCLE;
|
||||
}
|
||||
|
||||
@@ -691,51 +624,28 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
this.innerColor = nbt.getInteger("InnerColor");
|
||||
this.outerColor = nbt.getInteger("OuterColor");
|
||||
this.outerColorEnabled = nbt.getBoolean("OuterColorEnabled");
|
||||
this.zoneHeight = nbt.hasKey("ZoneHeight") ? nbt.getFloat("ZoneHeight") : 2.0f;
|
||||
this.particleDensity = nbt.hasKey("ParticleDensity") ? nbt.getFloat("ParticleDensity") : 1.0f;
|
||||
this.particleScale = nbt.hasKey("ParticleScale") ? nbt.getFloat("ParticleScale") : 1.0f;
|
||||
this.animSpeed = nbt.hasKey("AnimSpeed") ? nbt.getFloat("AnimSpeed") : 1.0f;
|
||||
this.lightningDensity = nbt.hasKey("LightningDensity") ? nbt.getFloat("LightningDensity") : 1.0f;
|
||||
this.deathWorldTime = nbt.hasKey("DeathWorldTime") ? nbt.getLong("DeathWorldTime") : -1;
|
||||
this.zoneHeight = nbt.getFloat("ZoneHeight");
|
||||
this.particleDensity = nbt.getFloat("ParticleDensity");
|
||||
this.particleScale = nbt.getFloat("ParticleScale");
|
||||
this.animSpeed = nbt.getFloat("AnimSpeed");
|
||||
this.lightningDensity = nbt.getFloat("LightningDensity");
|
||||
this.deathWorldTime = nbt.getLong("DeathWorldTime");
|
||||
|
||||
// Visual fields — backward compat with old ZoneStyle format
|
||||
if (nbt.hasKey("ZoneStyle")) {
|
||||
// OLD FORMAT: apply preset defaults, then overlay CustomVisual
|
||||
applyPresetDefaults(nbt.getString("ZoneStyle"));
|
||||
if (nbt.hasKey("CustomVisual")) {
|
||||
NBTTagCompound cv = nbt.getCompoundTag("CustomVisual");
|
||||
this.groundFill = !cv.hasKey("GroundFill") || cv.getBoolean("GroundFill");
|
||||
this.groundAlpha = cv.hasKey("GroundAlpha") ? cv.getFloat("GroundAlpha") : 0.25f;
|
||||
this.rings = !cv.hasKey("Rings") || cv.getBoolean("Rings");
|
||||
this.ringCount = cv.hasKey("RingCount") ? cv.getInteger("RingCount") : 3;
|
||||
this.border = !cv.hasKey("Border") || cv.getBoolean("Border");
|
||||
this.borderSpeed = cv.hasKey("BorderSpeed") ? cv.getFloat("BorderSpeed") : 1.0f;
|
||||
this.accents = !cv.hasKey("Accents") || cv.getBoolean("Accents");
|
||||
this.accentStyle = cv.hasKey("AccentStyle") ? cv.getInteger("AccentStyle") : 0;
|
||||
this.lightning = cv.hasKey("Lightning") && cv.getBoolean("Lightning");
|
||||
this.particles = !cv.hasKey("Particles") || cv.getBoolean("Particles");
|
||||
this.particleMotion = cv.hasKey("ParticleMotion") ? cv.getInteger("ParticleMotion") : 0;
|
||||
this.particleDir = cv.hasKey("ParticleDir") ? cv.getString("ParticleDir") : "";
|
||||
this.particleSize = cv.hasKey("ParticleSize") ? cv.getInteger("ParticleSize") : 32;
|
||||
this.particleGlow = !cv.hasKey("ParticleGlow") || cv.getBoolean("ParticleGlow");
|
||||
}
|
||||
} else {
|
||||
// NEW FORMAT: read individual top-level keys
|
||||
this.groundFill = !nbt.hasKey("GroundFill") || nbt.getBoolean("GroundFill");
|
||||
this.groundAlpha = nbt.hasKey("GroundAlpha") ? nbt.getFloat("GroundAlpha") : 0.25f;
|
||||
this.rings = !nbt.hasKey("Rings") || nbt.getBoolean("Rings");
|
||||
this.ringCount = nbt.hasKey("RingCount") ? nbt.getInteger("RingCount") : 3;
|
||||
this.border = !nbt.hasKey("Border") || nbt.getBoolean("Border");
|
||||
this.borderSpeed = nbt.hasKey("BorderSpeed") ? nbt.getFloat("BorderSpeed") : 1.0f;
|
||||
this.accents = !nbt.hasKey("Accents") || nbt.getBoolean("Accents");
|
||||
this.accentStyle = nbt.hasKey("AccentStyle") ? nbt.getInteger("AccentStyle") : 0;
|
||||
this.lightning = nbt.hasKey("Lightning") && nbt.getBoolean("Lightning");
|
||||
this.particles = !nbt.hasKey("Particles") || nbt.getBoolean("Particles");
|
||||
this.particleMotion = nbt.hasKey("ParticleMotion") ? nbt.getInteger("ParticleMotion") : 0;
|
||||
this.particleDir = nbt.hasKey("ParticleDir") ? nbt.getString("ParticleDir") : "";
|
||||
this.particleSize = nbt.hasKey("ParticleSize") ? nbt.getInteger("ParticleSize") : 32;
|
||||
this.particleGlow = !nbt.hasKey("ParticleGlow") || nbt.getBoolean("ParticleGlow");
|
||||
}
|
||||
// Visual layer fields
|
||||
this.groundFill = nbt.getBoolean("GroundFill");
|
||||
this.groundAlpha = nbt.getFloat("GroundAlpha");
|
||||
this.rings = nbt.getBoolean("Rings");
|
||||
this.ringCount = nbt.getInteger("RingCount");
|
||||
this.border = nbt.getBoolean("Border");
|
||||
this.borderSpeed = nbt.getFloat("BorderSpeed");
|
||||
this.accents = nbt.getBoolean("Accents");
|
||||
this.accentStyle = nbt.getInteger("AccentStyle");
|
||||
this.lightning = nbt.getBoolean("Lightning");
|
||||
this.particles = nbt.getBoolean("Particles");
|
||||
this.particleMotion = nbt.getInteger("ParticleMotion");
|
||||
this.particleDir = nbt.getString("ParticleDir");
|
||||
this.particleSize = nbt.getInteger("ParticleSize");
|
||||
this.particleGlow = nbt.getBoolean("ParticleGlow");
|
||||
|
||||
// Trap
|
||||
this.armTime = nbt.getInteger("ArmTime");
|
||||
@@ -745,6 +655,7 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
this.damage = nbt.getFloat("Damage");
|
||||
this.damageRadius = nbt.getFloat("DamageRadius");
|
||||
this.knockback = nbt.getFloat("Knockback");
|
||||
this.visible = nbt.getBoolean("Visible");
|
||||
|
||||
// Hazard
|
||||
this.damagePerSecond = nbt.getFloat("DamagePerSecond");
|
||||
@@ -783,7 +694,7 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
nbt.setFloat("LightningDensity", lightningDensity);
|
||||
nbt.setLong("DeathWorldTime", deathWorldTime);
|
||||
|
||||
// Visual fields — always written as top-level keys
|
||||
// Visual layer fields
|
||||
nbt.setBoolean("GroundFill", groundFill);
|
||||
nbt.setFloat("GroundAlpha", groundAlpha);
|
||||
nbt.setBoolean("Rings", rings);
|
||||
@@ -807,6 +718,7 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
nbt.setFloat("Damage", damage);
|
||||
nbt.setFloat("DamageRadius", damageRadius);
|
||||
nbt.setFloat("Knockback", knockback);
|
||||
nbt.setBoolean("Visible", visible);
|
||||
|
||||
// Hazard
|
||||
nbt.setFloat("DamagePerSecond", damagePerSecond);
|
||||
@@ -843,7 +755,7 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
buffer.writeFloat(animSpeed);
|
||||
buffer.writeFloat(lightningDensity);
|
||||
|
||||
// Visual fields — always written individually
|
||||
// Visual layer fields
|
||||
buffer.writeBoolean(groundFill);
|
||||
buffer.writeFloat(groundAlpha);
|
||||
buffer.writeBoolean(rings);
|
||||
@@ -859,10 +771,11 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
buffer.writeInt(particleSize);
|
||||
buffer.writeBoolean(particleGlow);
|
||||
|
||||
// Trap-specific (client needs armTime for visual state)
|
||||
// Trap-specific
|
||||
buffer.writeInt(armTime);
|
||||
buffer.writeBoolean(visible);
|
||||
|
||||
// Effects via NBT in buffer
|
||||
// Effects
|
||||
NBTTagCompound effectsNbt = new NBTTagCompound();
|
||||
NBTTagList effectList = new NBTTagList();
|
||||
for (AbilityEffect effect : effects) {
|
||||
@@ -894,7 +807,7 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
this.animSpeed = buffer.readFloat();
|
||||
this.lightningDensity = buffer.readFloat();
|
||||
|
||||
// Visual fields — always read individually
|
||||
// Visual layer fields
|
||||
this.groundFill = buffer.readBoolean();
|
||||
this.groundAlpha = buffer.readFloat();
|
||||
this.rings = buffer.readBoolean();
|
||||
@@ -911,8 +824,9 @@ public class EntityAbilityZone extends Entity implements IEntityAdditionalSpawnD
|
||||
this.particleGlow = buffer.readBoolean();
|
||||
|
||||
this.armTime = buffer.readInt();
|
||||
this.visible = buffer.readBoolean();
|
||||
|
||||
// Effects via NBT
|
||||
// Effects
|
||||
NBTTagCompound effectsNbt = ByteBufUtils.readTag(buffer);
|
||||
effects.clear();
|
||||
if (effectsNbt != null && effectsNbt.hasKey("Effects")) {
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package noppes.npcs.client.gui;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import noppes.npcs.client.gui.util.GuiNpcButton;
|
||||
import noppes.npcs.client.gui.util.SubGuiInterface;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class SubGuiTrapPresetSelector extends SubGuiInterface {
|
||||
|
||||
public String selectedPreset = null;
|
||||
|
||||
private static final String[] PRESET_NAMES = {"HIDDEN", "VENOM", "EXPLOSIVE", "CURSED", "SHOCK", "SNARE"};
|
||||
private static final String[] PRESET_LABELS = {
|
||||
"ability.preset.hidden", "ability.preset.venom", "ability.preset.explosive",
|
||||
"ability.preset.cursed", "ability.preset.shock", "ability.preset.snare"
|
||||
};
|
||||
private static final int[] PRESET_COLORS = {0x888888, 0x44DD44, 0xFF6611, 0xAA44FF, 0x4488FF, 0x88CCFF};
|
||||
|
||||
public SubGuiTrapPresetSelector() {
|
||||
xSize = 170;
|
||||
ySize = 135;
|
||||
setBackground("menubg.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
super.initGui();
|
||||
int btnW = 72;
|
||||
int btnH = 20;
|
||||
int gapY = 4;
|
||||
int col1 = guiLeft + 7;
|
||||
int col2 = col1 + btnW + 6;
|
||||
int startY = guiTop + 22;
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int x = (i % 2 == 0) ? col1 : col2;
|
||||
int y = startY + (i / 2) * (btnH + gapY);
|
||||
addButton(new GuiNpcButton(i, x, y, btnW, btnH, PRESET_LABELS[i]));
|
||||
}
|
||||
|
||||
int cancelY = startY + 3 * (btnH + gapY) + 4;
|
||||
addButton(new GuiNpcButton(10, guiLeft + xSize / 2 - 36, cancelY, 72, btnH, "gui.cancel"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton btn) {
|
||||
super.actionPerformed(btn);
|
||||
if (btn.id >= 0 && btn.id < 6) {
|
||||
selectedPreset = PRESET_NAMES[btn.id];
|
||||
close();
|
||||
} else if (btn.id == 10) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float f) {
|
||||
super.drawScreen(mouseX, mouseY, f);
|
||||
drawCenteredString(fontRendererObj, StatCollector.translateToLocal("gui.applyPreset"), guiLeft + xSize / 2, guiTop + 8, 0xFFFFFF);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
GuiNpcButton btn = getButton(i);
|
||||
if (btn != null && btn.visible) {
|
||||
int x = btn.xPosition + 4;
|
||||
int y = btn.yPosition + 5;
|
||||
drawRect(x, y, x + 10, y + 10, 0xFF000000 | PRESET_COLORS[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user