10 KiB
Ability System Review - CustomNPC+
A comprehensive technical review of the Ability System identifying bugs, logic issues, incomplete features, and inconsistencies.
Critical Issues
1. Cooldown Uses Mixed Time Systems
Status: FIXED Files:
Ability.java- Removed cooldown tracking (cooldownEndTime, startCooldown(), isOnCooldown(), canUse())DataAbilities.java- Now sole owner of cooldown management using world time
Solution: Removed all cooldown tracking from Ability.java. Cooldowns are now managed exclusively by DataAbilities using world.getTotalWorldTime() for consistency.
2. AbilityHeal - Heal Over Time Completely Broken
Status: FIXED
File: AbilityHeal.java
Solution: Refactored to separate ally-finding from healing. The findAlliesInRadius() method is now called regardless of instantHeal flag, populating the list for HoT to use. Added heal particles during HoT ticks.
3. AbilityGuard - Counter Integration Missing
Status: FIXED Files:
DataAbilities.java:onDamage()- Added integration to callAbilityGuard.onDamageTaken()DataAbilities.java:getGuardDamageReduction()- Added helper method for damage reduction
Solution: DataAbilities.onDamage() now checks if current ability is an AbilityGuard and calls onDamageTaken() when the NPC is hit while guarding.
High Priority Issues
4. knockbackUp Stored But Never Applied
Status: FIXED
File: Ability.java
Solution: Updated applyNpcKnockback() to accept a knockbackUp parameter and use it instead of hardcoded 0.1D. Both applyAbilityDamage() and applyAbilityDamageWithDirection() now pass the knockbackUp value from the HitEvent.
5. Targeting Modes Not Implemented
Status: FIXED (Removed)
File: TargetingMode.java
Solution: Removed the unused targeting modes (RANDOM_ENEMY, LOWEST_HP, HIGHEST_THREAT) from the enum. Only the implemented modes remain: AGGRO_TARGET, SELF, AOE_SELF, AOE_TARGET.
6. Damage Source Inconsistency
Status: FIXED
File: Ability.java
Solution: Standardized both applyAbilityDamage() and applyAbilityDamageWithDirection() to use NpcDamageSource("mob", npc) for consistent damage source handling.
Incomplete Features
7. AbilityProjectile - No Actual Projectile
Status: CONFIRMED - INCOMPLETE
File: AbilityProjectile.java:88
// TODO: Use custom EntityAbilityProjectile for actual tracking
applyAbilityDamageWithDirection(npc, target, damage, knockback, dx, dz);
Current behavior:
speed,homing,homingStrengthfields exist but are unused- No projectile entity is spawned
- Damage is instant, just with particle cosmetics
8. AbilityOrb - No Visual Orb Rendering
Status: CONFIRMED - INCOMPLETE
File: AbilityOrb.java:117-179
Problem: The orb tracks position (orbX, orbY, orbZ) with runtime getters but nothing renders it client-side. Players only see particle effects on hit, not the flying orb itself.
9. AbilityBeam - No Visual Beam Rendering
Status: CONFIRMED - INCOMPLETE
File: AbilityBeam.java:213-220
Problem: Only spawns flame particles along the path. No actual beam entity or proper beam visual. The lockOnTarget telegraph during active phase isn't visually communicated.
Medium Priority Issues
10. Hazard/Trap Telegraph Offset Mismatch
Status: CONFIRMED Files:
AbilityHazard.java:119-147, 201-248AbilityTrap.java:109-138, 166-205
Problem: Telegraph is created at target position, but actual effect applies random offset:
// createTelegraph() - No offset applied, shows at target position
// onExecute() - Random offset applied AFTER telegraph locks
double[] pos = calculateOffsetPosition(telegraph.getX(), telegraph.getY(), telegraph.getZ());
zoneX = pos[0]; // Actual effect position differs from telegraph
Impact: Players see telegraph at one location, damage happens elsewhere. Misleading visual feedback.
Fix: Either apply offset during telegraph creation, or update telegraph position in onExecute().
11. AbilityCharge Telegraph Direction Timing
Status: CONFIRMED - MINOR
File: AbilityCharge.java:91, 254-286
Problem: Telegraph created at tick 0, direction locked at tick 1:
// Telegraph created during setup (tick 0) with current target direction
// Line 91: Direction locked at tick 1
if (tick == 1) {
lockChargeDirection(npc, target);
}
Impact: If target moves between tick 0-1, telegraph direction won't match actual charge.
12. AbilitySlam - activeTicks May End Before Landing
Status: CONFIRMED - MINOR
File: AbilitySlam.java:52-53, 230-250
Problem: activeTicks = 60 is fixed, but if NPC takes longer to land, ability transitions to RECOVERY without onLanding() being called.
Secondary issue: If NPC lands early (tick 15), active phase continues until tick 60 doing nothing - wasted ticks.
13. FOLLOW Mode Telegraph Not Updated
Status: CONFIRMED
Files: AbilityHazard.java:139-146, AbilityVortex.java
Problem: For FOLLOW_TARGET mode, telegraph locks position on execute, but the actual hazard zone follows the target. Visual mismatch between warning and danger.
Redundancies
14. Duplicate findGroundLevel() Methods
Status: FIXED Files:
Ability.java- MadefindGroundLevel()public staticTelegraphInstance.java- Now usesAbility.findGroundLevel()
15. Duplicate calculateOffsetPosition() Methods
Status: FIXED Files:
Ability.java- Added shared staticcalculateOffsetPosition()methodAbilityTrap.java- Removed duplicate, usesAbility.calculateOffsetPosition()AbilityHazard.java- Removed duplicate, usesAbility.calculateOffsetPosition()
16. Unused applyKnockback in AbilityOrb
Status: FIXED
File: AbilityOrb.java
Removed the unused applyKnockback() method.
17. Duplicate Reset/Interrupt Cleanup
Status: NOT FIXED (Low Priority) Multiple ability files
Most abilities override both reset() and onInterrupt() with duplicate cleanup code. Pattern should have onInterrupt() call reset() or use shared cleanup method.
Minor Issues & Inconsistencies
18. Field Naming Confusion
AbilityHazard:damagePerSecondwithdamageInterval- name suggests per-second but applied every N ticksAbilityCharge:hitWidthstored ashitRadiusin older NBT (backward compat exists)
19. AbilityVortex Entity Lookup Performance
File: AbilityVortex.java:201-212
Iterates through ALL loaded entities every tick to find pulled entities by UUID. Should cache entity references or use entity IDs.
20. Telegraph Yaw Rotation
File: TelegraphRenderer.java:95
Uses GL11.glRotatef(-instance.getYaw(), 0, 1, 0) - negative yaw. Should verify this matches Minecraft's yaw conventions.
21. Missing Null Checks
Various locations where target could be null but is used without defensive checks:
AbilityProjectile.java:73AbilityOrb.java:138-171
Missing Features (Enhancement Requests)
These are not bugs but notable missing functionality:
- No Ability Chaining/Combo System - No way to trigger abilities from other abilities
- No Cooldown Reduction on Hit - Can't reduce cooldowns based on successful hits
- No Multi-Target Hit Limit - AOE abilities hit unlimited targets (unlike Vortex's
maxTargets) - No Damage Type Configuration - All abilities use mob/melee damage, no magic/fire/etc options
- No Target Validation During Execution - If target dies/despawns mid-ability, behavior varies
Priority Summary
| Priority | Issue | Status |
|---|---|---|
| CRITICAL | Cooldown time system mismatch | FIXED |
| CRITICAL | AbilityHeal HoT broken | FIXED |
| CRITICAL | AbilityGuard counter not integrated | FIXED |
| HIGH | knockbackUp ignored | FIXED |
| HIGH | Targeting modes unimplemented | FIXED (Removed) |
| HIGH | Damage source inconsistency | FIXED |
| MEDIUM | Projectile/Orb/Beam no visuals | Not Fixed |
| MEDIUM | Hazard/Trap telegraph offset | Not Fixed |
| LOW | Charge telegraph timing | Not Fixed |
| LOW | Slam activeTicks timing | Not Fixed |
| LOW | Code redundancies | FIXED |
Remaining Issues
The following issues were not addressed in this fix round:
- Projectile/Orb/Beam Visual Rendering - These abilities still only use particles, no actual entity rendering
- Hazard/Trap Telegraph Offset Mismatch - Telegraph shows at target, effect spawns with offset
- Charge Telegraph Direction Timing - Minor visual mismatch between tick 0-1
- Slam activeTicks Timing - Fixed at 60 ticks regardless of landing time
Changes Made
Ability.java
- Removed
cooldownEndTimetransient field - Removed
startCooldown(),isOnCooldown(),canUse()methods (cooldown managed by DataAbilities) - Updated
tick()to not call startCooldown (DataAbilities handles it) - Updated
reset()to not reset cooldownEndTime - Made
findGroundLevel()public static for shared use - Added static
calculateOffsetPosition()utility method - Fixed
applyNpcKnockback()to accept and use knockbackUp parameter - Standardized damage source to
NpcDamageSource("mob", npc)in both damage methods - Removed deprecated getters/setters (telegraphColor, castSound, animationId)
IAbility.java (API)
- Removed
isOnCooldown()method from interface
DataAbilities.java
- Added AbilityGuard import
- Added guard counter integration in
onDamage() - Added
getGuardDamageReduction()helper method - Removed deprecated
isMovementBlocked()method - Updated knockbackUp javadoc (no longer deprecated)
CombatHandler.java
- Renamed
isMovementBlocked()toisAbilityControllingMovement()
TargetingMode.java
- Removed unused modes:
RANDOM_ENEMY,LOWEST_HP,HIGHEST_THREAT
AbilityHeal.java
- Fixed HoT by separating
findAlliesInRadius()from healing logic - Allies are now found in
onExecute()regardless of instantHeal flag - Added heal particles during HoT ticks
AbilityHazard.java
- Removed duplicate
calculateOffsetPosition(), usesAbility.calculateOffsetPosition() - Removed deprecated
getDamagePerTick()/setDamagePerTick()methods
AbilityTrap.java
- Removed duplicate
calculateOffsetPosition(), usesAbility.calculateOffsetPosition()
AbilityOrb.java
- Removed unused
applyKnockback()method
TelegraphInstance.java
- Removed duplicate
findGroundLevel(), usesAbility.findGroundLevel()