Skip to content

[Feat] Ability pickup refund, depleted slot interactions, and chargeable ability system#278

Merged
Mere-Solace merged 7 commits into
devfrom
feat/ability-system-262
Mar 27, 2026
Merged

[Feat] Ability pickup refund, depleted slot interactions, and chargeable ability system#278
Mere-Solace merged 7 commits into
devfrom
feat/ability-system-262

Conversation

@Mere-Solace

Copy link
Copy Markdown
Owner

Summary

  • Ability projectile pickup (dash/grab/catch) now refunds a use instead of giving the raw visual item; works when holding an equipped or depleted ability slot
  • Fixed input tree lock-out: handleAbilityInput only consumes LEFT, preventing the tree from advancing past root when the player is on cooldown
  • Added ChargeableAbility abstract class, ChargeSession, and ChargeAction — chargeable abilities hook into RIGHT (charge start) and RIGHT_HOLD (release) through the input tree
  • IceSpellAbility: BLUE_ICE block that scales 0.25→3.0 over 3s with Y-axis rotation and sine-wave bob; releaseable at 0.5 scale; thrown via throwDirect at current charge scale
  • Non-ability items in an equipped slot are relocated gracefully on equip; updateInventory() added after refund to force client sync

Test plan

  • Equip IceSpellAbility to ACTIVE_1, hold RIGHT → ice block spawns and grows with bob/rotation; release after threshold → projectile fires
  • Release before 0.5 scale → charge cancels silently
  • Equip KnifeThrow, throw all uses → slot depletes; throw knife → grab it back → use refunded, slot becomes EQUIPPED again
  • With depleted ability slot held, dash toward a thrown knife → pickup triggers refund
  • Left-click while on ability cooldown → input consumed (no normal attack), next left-click works once cooldown clears
  • Equip ability to a non-empty slot → existing item moves to inventory rather than being deleted

…hrowDirect API

- Add ABILITY_ID and ABILITY_SLOT PDC keys to KeyRegistry
- Uncomment and wire AbilityItemBuilder/AbilityItemReader (PDC tagging now live)
- Fix AbilitySlotItem: isSatisfied/setEquipped/buildPlaceholder now use ABILITY_SLOT_KEY
- AbilitySkill: replace single useType() with useTypes() Set<AbilityUseType> — STACK,
  DURABILITY, and COOLDOWN are now non-exclusive and combinable per ability
- AbilitySlotManager: tracks remainingUses and remainingDurability independently per
  slot; deplete fires when any finite resource hits zero
- AbilityStateRepository: stores both remaining_uses and remaining_durability columns;
  returns SlotState record; save/saveAll updated to match
- VisualProjectile: add displayScale field (default 1.0f) — determineOrientation() now
  respects it, enabling per-throw scale overrides without subclassing
- ThrowAction.throwDirect(): new API that spawns a ThrownItem and releases immediately
  without the onReady() windup loop — suitable for instant-release abilities
- KnifeThrowAbility: fires a diamond sword projectile at 0.5 scale via throwDirect;
  useTypes() = {STACK, COOLDOWN}, 3 max uses, 10-tick cooldown overlay
- Add SkillAvailability (AVAILABLE/DEPLETED/RELINQUISHED) tracked per player
- Add SkillSlotState record persisting uses, durability, and cooldown expiry
  per ability slot so cooldowns survive log-off cycles
- Persist slot states via new SkillStateRepository (player_skill_slot_state table)
- Migrate player_available_skills schema to v2 (adds availability column)
- Refactor AbilitySlotManager to delegate uses/durability tracking to
  PlayerSkillContainer instead of local fields
- Implement handleAbilityInput in SwordPlayer — LEFT tap / RIGHT_HOLD cast
  with canPerform, persistent cooldown guard, consumeUse, and cooldown write-back
- Remove registerActiveSkillSlot from InputRegistrar (replaced by handleAbilityInput)
- Fix AbilitySlotItem EMPTY/LOCKED restore to clear stale ability items on unequip
- Add TestAlpha/Beta/Gamma no-op abilities with colored chat feedback for testing
- Add skill system README
- Replace PDC tag lookup in handleAbilityInput with slot-index check via
  AbilitySlotManager.getActiveTypeForHeldSlot — more reliable than reading
  ITEM_TYPE_KEY from the held item which may be gunpowder or untagged
- Add boolean[] slotEnabled to AbilitySlotManager, synced after initialize,
  refresh, and deplete; drives getActiveTypeForHeldSlot
- Implement notHoldingAbilityItem() in SwordPlayer using getActiveTypeForHeldSlot;
  wired into canBeginThrow() which gates the Throw Ready input node
- Fix AbilitySlotItem EMPTY/LOCKED restore to clear stale ability items on unequip
…nu replenish button

- KnifeThrowAbility now extends ActivatableAbility (not ThrowableAbility) — throw is click-to-cast with no aim windup
- Tag knife projectile with ABILITY_ID_KEY so pickup can identify it
- InteractiveItemArbiter refunds one use to the original thrower on projectile pickup, regardless of who picks it up
- AbilitySlotManager.addUse() transitions depleted slots back to EQUIPPED when a use is returned
- ThrowAction.throwDirect resets attemptingThrow on completion, fixing ability re-cast lock
- CharacterMenu: dev replenish button (TODO: remove) resets both ability slots to full uses
…bility system, and IceSpellAbility

- Dash and grab now pick up ability projectiles when holding an equipped or depleted ability item
- Thrown ability projectile pickup (dash/grab/catch) refunds a use via AbilitySlotManager
- DEPLETED slot state now recognized as an ability slot for all pickup interactions
- handleAbilityInput only consumes LEFT inputs; RIGHT paths flow through the input tree
- Fixed input tree lock-out: ability slot always returns true to prevent tree advancement
- Added AbilityType.CHARGEABLE, ChargeableAbility abstract class, ChargeSession, ChargeAction
- Chargeable abilities hook into RIGHT (charge start) and RIGHT_HOLD (charge release) in the input tree
- IceSpellAbility: BLUE_ICE block, scale 0.25→3.0 over 3s, sine-wave bob, Y-axis rotation, releaseable at 0.5 scale
- addUse() calls updateInventory() to force client sync after projectile refund
- Non-ability items in an equipped slot are relocated gracefully on equip
…o-download, and remove stale TODOs

Add PotionEffect.INFINITE_DURATION constant instead of magic number 99999999. Add downloadPlugins block to build.gradle for DisplayEntityUtils, PacketEvents, and ProtocolLib. Remove obsolete TODO about ability casting from different actions.
@Mere-Solace Mere-Solace self-assigned this Mar 27, 2026
Repository owner deleted a comment from github-actions Bot Mar 27, 2026
@Mere-Solace Mere-Solace added enhancement New feature or request architecture System design and structure decisions status: done labels Mar 27, 2026
@Mere-Solace Mere-Solace merged commit b61a13c into dev Mar 27, 2026
1 check passed
@Mere-Solace Mere-Solace deleted the feat/ability-system-262 branch March 27, 2026 03:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

architecture System design and structure decisions enhancement New feature or request status: done

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant