diff --git a/src/main/java/kamkeel/npcs/client/renderer/RenderAbilitySweeper.java b/src/main/java/kamkeel/npcs/client/renderer/RenderAbilitySweeper.java index b72be7a7c..fc7bc33c7 100644 --- a/src/main/java/kamkeel/npcs/client/renderer/RenderAbilitySweeper.java +++ b/src/main/java/kamkeel/npcs/client/renderer/RenderAbilitySweeper.java @@ -25,6 +25,7 @@ public class RenderAbilitySweeper extends Render { float beamLength = sweeper.getBeamLength(); float beamWidth = sweeper.getBeamWidth(); + float beamHeight = sweeper.getBeamHeight(); int innerColor = sweeper.getInnerColor(); int outerColor = sweeper.getOuterColor(); boolean outerColorEnabled = sweeper.isOuterColorEnabled(); @@ -38,7 +39,7 @@ public class RenderAbilitySweeper extends Render { GL11.glRotatef(-angle, 0, 1, 0); // Negative for correct direction // Render the beam extending in the +Z direction (like beam trail segments) - renderBeam(beamLength, beamWidth, innerColor, outerColor, outerColorEnabled, outerColorWidth); + renderBeam(beamLength, beamWidth, beamHeight, innerColor, outerColor, outerColorEnabled, outerColorWidth); GL11.glPopMatrix(); @@ -71,8 +72,9 @@ public class RenderAbilitySweeper extends Render { * Render beam using the same style as the Beam entity trail. * Three layers: outer glow, middle, inner core. * outerColorWidth is an additive offset from inner width (consistent with other renderers). + * Width and height control the rectangular cross-section independently. */ - private void renderBeam(float length, float width, int innerColor, int outerColor, + private void renderBeam(float length, float width, float height, int innerColor, int outerColor, boolean outerColorEnabled, float outerColorWidth) { // Extract colors float outerR = ((outerColor >> 16) & 0xFF) / 255.0f; @@ -83,37 +85,40 @@ public class RenderAbilitySweeper extends Render { float innerG = ((innerColor >> 8) & 0xFF) / 255.0f; float innerB = (innerColor & 0xFF) / 255.0f; - // Inner scale defines the core width (consistent with other renderers) + // Inner scale defines the core size (consistent with other renderers) float innerScale = 0.6f; float innerWidth = width * innerScale; + float innerHeight = height * innerScale; // Render from origin (0,0,0) to (0,0,length) in local coords // After rotation this extends in the correct world direction // Outer glow (wider, translucent) - only if enabled - // outerColorWidth is additive offset from inner width + // outerColorWidth is additive offset from inner size if (outerColorEnabled) { float outerWidth = innerWidth + outerColorWidth * width; + float outerHeight = innerHeight + outerColorWidth * height; GL11.glDepthMask(false); - renderBeamSegment(0, 0, 0, 0, 0, length, outerWidth, outerR, outerG, outerB, 0.3f); + renderBeamSegment(0, 0, 0, 0, 0, length, outerWidth, outerHeight, outerR, outerG, outerB, 0.3f); GL11.glDepthMask(true); // Middle layer (halfway between inner and outer) float midWidth = innerWidth + (outerWidth - innerWidth) * 0.5f; - renderBeamSegment(0, 0, 0, 0, 0, length, midWidth, outerR, outerG, outerB, 0.6f); + float midHeight = innerHeight + (outerHeight - innerHeight) * 0.5f; + renderBeamSegment(0, 0, 0, 0, 0, length, midWidth, midHeight, outerR, outerG, outerB, 0.6f); } // Inner core (solid) - renderBeamSegment(0, 0, 0, 0, 0, length, innerWidth, innerR, innerG, innerB, 1.0f); + renderBeamSegment(0, 0, 0, 0, 0, length, innerWidth, innerHeight, innerR, innerG, innerB, 1.0f); } /** - * Render a beam segment as a 3D rectangular prism. + * Render a beam segment as a 3D rectangular prism with independent width and height. * Uses the same approach as RenderAbilityBeam.renderBeamRectangle. */ private void renderBeamSegment(double x1, double y1, double z1, double x2, double y2, double z2, - float width, float r, float g, float b, float a) { + float width, float height, float r, float g, float b, float a) { // Calculate direction double dx = x2 - x1; double dy = y2 - y1; @@ -151,39 +156,40 @@ public class RenderAbilitySweeper extends Render { double vertZ = dx * horzY - dy * horzX; float halfWidth = width * 0.5f; + float halfHeight = height * 0.5f; - // Calculate 8 corners of the box - double s1x = x1 - horzX * halfWidth - vertX * halfWidth; - double s1y = y1 - horzY * halfWidth - vertY * halfWidth; - double s1z = z1 - horzZ * halfWidth - vertZ * halfWidth; + // Calculate 8 corners of the box (horz scaled by halfWidth, vert scaled by halfHeight) + double s1x = x1 - horzX * halfWidth - vertX * halfHeight; + double s1y = y1 - horzY * halfWidth - vertY * halfHeight; + double s1z = z1 - horzZ * halfWidth - vertZ * halfHeight; - double s2x = x1 + horzX * halfWidth - vertX * halfWidth; - double s2y = y1 + horzY * halfWidth - vertY * halfWidth; - double s2z = z1 + horzZ * halfWidth - vertZ * halfWidth; + double s2x = x1 + horzX * halfWidth - vertX * halfHeight; + double s2y = y1 + horzY * halfWidth - vertY * halfHeight; + double s2z = z1 + horzZ * halfWidth - vertZ * halfHeight; - double s3x = x1 + horzX * halfWidth + vertX * halfWidth; - double s3y = y1 + horzY * halfWidth + vertY * halfWidth; - double s3z = z1 + horzZ * halfWidth + vertZ * halfWidth; + double s3x = x1 + horzX * halfWidth + vertX * halfHeight; + double s3y = y1 + horzY * halfWidth + vertY * halfHeight; + double s3z = z1 + horzZ * halfWidth + vertZ * halfHeight; - double s4x = x1 - horzX * halfWidth + vertX * halfWidth; - double s4y = y1 - horzY * halfWidth + vertY * halfWidth; - double s4z = z1 - horzZ * halfWidth + vertZ * halfWidth; + double s4x = x1 - horzX * halfWidth + vertX * halfHeight; + double s4y = y1 - horzY * halfWidth + vertY * halfHeight; + double s4z = z1 - horzZ * halfWidth + vertZ * halfHeight; - double e1x = x2 - horzX * halfWidth - vertX * halfWidth; - double e1y = y2 - horzY * halfWidth - vertY * halfWidth; - double e1z = z2 - horzZ * halfWidth - vertZ * halfWidth; + double e1x = x2 - horzX * halfWidth - vertX * halfHeight; + double e1y = y2 - horzY * halfWidth - vertY * halfHeight; + double e1z = z2 - horzZ * halfWidth - vertZ * halfHeight; - double e2x = x2 + horzX * halfWidth - vertX * halfWidth; - double e2y = y2 + horzY * halfWidth - vertY * halfWidth; - double e2z = z2 + horzZ * halfWidth - vertZ * halfWidth; + double e2x = x2 + horzX * halfWidth - vertX * halfHeight; + double e2y = y2 + horzY * halfWidth - vertY * halfHeight; + double e2z = z2 + horzZ * halfWidth - vertZ * halfHeight; - double e3x = x2 + horzX * halfWidth + vertX * halfWidth; - double e3y = y2 + horzY * halfWidth + vertY * halfWidth; - double e3z = z2 + horzZ * halfWidth + vertZ * halfWidth; + double e3x = x2 + horzX * halfWidth + vertX * halfHeight; + double e3y = y2 + horzY * halfWidth + vertY * halfHeight; + double e3z = z2 + horzZ * halfWidth + vertZ * halfHeight; - double e4x = x2 - horzX * halfWidth + vertX * halfWidth; - double e4y = y2 - horzY * halfWidth + vertY * halfWidth; - double e4z = z2 - horzZ * halfWidth + vertZ * halfWidth; + double e4x = x2 - horzX * halfWidth + vertX * halfHeight; + double e4y = y2 - horzY * halfWidth + vertY * halfHeight; + double e4z = z2 - horzZ * halfWidth + vertZ * halfHeight; Tessellator tess = Tessellator.instance; tess.startDrawingQuads(); diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityZone.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityZone.java index b5cc53a9e..7f2a92329 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityZone.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/AbilityZone.java @@ -67,7 +67,7 @@ public abstract class AbilityZone extends Ability { this.maxRange = 20.0f; this.lockMovement = LockMovementType.WINDUP; this.cooldownTicks = 0; - this.allowedBy = UserType.NPC_ONLY; + this.allowedBy = UserType.BOTH; } @Override diff --git a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilitySweeper.java b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilitySweeper.java index 5c9a9fe37..a1340ae39 100644 --- a/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilitySweeper.java +++ b/src/main/java/kamkeel/npcs/controllers/data/ability/type/energy/AbilitySweeper.java @@ -31,7 +31,7 @@ public class AbilitySweeper extends AbilityEnergy implements IAbilitySweeper { // Type-specific parameters private float beamLength = 10.0f; private float beamWidth = 0.3f; // Thin like beam trail - private float beamHeight = 0.5f; // Height above ground (low enough to jump over) + private float beamHeight = 1.0f; // Beam vertical size in blocks (1 block tall, jumpable) private float damage = 5.0f; private int damageInterval = 5; private boolean piercing = true; diff --git a/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java b/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java index fd739876d..4323141f5 100644 --- a/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java +++ b/src/main/java/kamkeel/npcs/entity/EntityAbilitySweeper.java @@ -34,7 +34,7 @@ public class EntityAbilitySweeper extends EntityEnergyAbility { // Beam properties private float beamLength = 10.0f; private float beamWidth = 0.3f; // Thin like beam trail - private float beamHeight = 0.8f; + private float beamHeight = 1.0f; // Combat properties private float damage = 5.0f; @@ -100,8 +100,8 @@ public class EntityAbilitySweeper extends EntityEnergyAbility { this.baseYaw = owner.rotationYaw; } - // Position at owner - this.setPosition(owner.posX, owner.posY + beamHeight, owner.posZ); + // Position at beam center (bottom at feet, top at feet + beamHeight) + this.setPosition(owner.posX, owner.posY + beamHeight / 2.0, owner.posZ); // Ready to deal damage immediately this.ticksSinceDamage = damageInterval; @@ -149,7 +149,7 @@ public class EntityAbilitySweeper extends EntityEnergyAbility { } if (owner != null) { - this.setPosition(owner.posX, owner.posY + beamHeight, owner.posZ); + this.setPosition(owner.posX, owner.posY + beamHeight / 2.0, owner.posZ); } // Check if sweep is done @@ -204,10 +204,10 @@ public class EntityAbilitySweeper extends EntityEnergyAbility { double checkY = startY; double checkZ = startZ + dirZ * beamLength * progress; - // Narrow hitbox for thin beam + // Hitbox: beam center ± half-height vertically, generous width for thin beams AxisAlignedBB checkBox = AxisAlignedBB.getBoundingBox( - checkX - beamWidth * 2, checkY - 0.5, checkZ - beamWidth * 2, - checkX + beamWidth * 2, checkY + 1.0, checkZ + beamWidth * 2 + checkX - beamWidth * 2, checkY - beamHeight / 2.0, checkZ - beamWidth * 2, + checkX + beamWidth * 2, checkY + beamHeight / 2.0, checkZ + beamWidth * 2 ); @SuppressWarnings("unchecked") @@ -259,11 +259,14 @@ public class EntityAbilitySweeper extends EntityEnergyAbility { return false; } - // Height check - entity's feet must be below beam top (allows jumping over) + // Height check - entity must overlap beam vertically + double beamTopY = startY + beamHeight / 2.0; + double beamBottomY = startY - beamHeight / 2.0; double entityFeetY = entity.posY; - double beamTopY = startY + 0.5; + double entityTopY = entity.posY + entity.height; - return entityFeetY < beamTopY; + // Entity feet must be below beam top AND entity top must be above beam bottom + return entityFeetY < beamTopY && entityTopY > beamBottomY; } /** @@ -366,7 +369,7 @@ public class EntityAbilitySweeper extends EntityEnergyAbility { readEnergyBaseNBT(nbt); this.beamLength = sanitize(nbt.getFloat("BeamLength"), 10.0f, MAX_ENTITY_SIZE); this.beamWidth = sanitize(nbt.getFloat("BeamWidth"), 0.3f, MAX_ENTITY_SIZE); - this.beamHeight = sanitize(nbt.getFloat("BeamHeight"), 0.8f, MAX_ENTITY_SIZE); + this.beamHeight = sanitize(nbt.getFloat("BeamHeight"), 1.0f, MAX_ENTITY_SIZE); this.sweepSpeed = nbt.hasKey("SweepSpeed") ? nbt.getFloat("SweepSpeed") : 3.0f; if (Float.isNaN(sweepSpeed) || Float.isInfinite(sweepSpeed) || sweepSpeed <= 0) sweepSpeed = 3.0f; this.numberOfRotations = nbt.hasKey("NumRotations") ? nbt.getInteger("NumRotations") : 2;