ModernUO/Projects/UOContent/Items/Weapons/Ranged
Kamron Batman a7bb8a8222
refactor(archery): centralize SE ammo auto-recovery off PlayerMobile (#2496)
## Summary

Streamlines the SE-era archery ammo auto-recovery (recovering spent arrows/bolts after a miss). The mechanic was previously spread across four unrelated trigger points and a weapon-scoped timer that was divorced from the recovery state living on `PlayerMobile`. It also contained dead code.

### Problems fixed
- **Dead `!Warmode` gate** — `OnMiss` only runs from `OnSwing`, which requires warmode to fire, so the `if (!pm.Warmode)` branch that started the recovery timer could never trigger.
- **Scattered, divorced state** — banked ammo lived on `PlayerMobile.RecoverableAmmo` while the timer lived on the weapon (`_recoveryTimerToken`), and recovery was kicked off from four different places (`OnWarmodeChanged`, `PlayerMobile.OnDamage` kill, `BaseCreature.OnDamage` kill, `OnBeforeDeath`).
- **Per-player footprint** — every `PlayerMobile` carried a `RecoverableAmmo` field even though ~99% never miss with a bow (and most are offline).

### New design — `AmmoRecovery` side table
- All state (banked ammo + one repeating timer) is keyed by player in a static dictionary, so only players who actually miss carry any state. Transient by design — this was never serialized.
- **One feed point:** `OnMiss` banks the spent ammo type and starts the player's timer.
- **One drain point:** the timer self-gates and gathers ammo into the backpack only once the archer has disengaged — **alive, out of warmode, and not running** — otherwise it retries next tick, so banked ammo is never lost while online.
- **"Not running" allows standing still _or_ walking.** The `Direction.Running` bit is stale after a player stops, so it's paired with movement recency (`LastMoveTime`); only an *actively* running archer is blocked.
- Removed the redundant scattered triggers, the dead `!Warmode` branch, `RecoverableAmmo`, `RecoverAmmo()`, and the now-empty `OnWarmodeChanged` override. `PlayerMobile.OnDelete` calls `AmmoRecovery.Forget`.

### Behavior notes
- On death, banked ammo is **no longer flushed to the corpse** — it stays banked and is recovered after resurrection once the archer settles (player keeps it rather than dropping it to looters).
- `OnHit` immediate recovery (the ~40% arrow-to-defender behavior) is **unchanged**.

## Test plan
- [x] `dotnet build Projects/UOContent/UOContent.csproj -c Release` — succeeds, 0 warnings, 0 errors.
- [ ] In-game (SE era): miss bow shots, then disengage (drop warmode + stop) and confirm the "You recover N arrows/bolts" message and backpack contents; confirm recovery does **not** fire while running and **does** while walking/standing.
2026-06-21 23:22:55 -07:00
..
AmmoRecovery.cs refactor(archery): centralize SE ammo auto-recovery off PlayerMobile (#2496) 2026-06-21 23:22:55 -07:00
AssassinsShortbow.cs fix: Updates serialization to use v2.0 (#998) 2022-04-17 08:02:15 -07:00
BarbedLongbow.cs fix: Updates serialization to use v2.0 (#998) 2022-04-17 08:02:15 -07:00
BaseRanged.cs refactor(archery): centralize SE ammo auto-recovery off PlayerMobile (#2496) 2026-06-21 23:22:55 -07:00
Bow.cs fix: Optimizes items to use default weights. (Part 4) (#2243) 2025-07-24 23:29:29 -07:00
CompositeBow.cs fix: Optimizes items to use default weights. (Part 4) (#2243) 2025-07-24 23:29:29 -07:00
Crossbow.cs fix: Optimizes items to use default weights. (Part 4) (#2243) 2025-07-24 23:29:29 -07:00
FrozenLongbow.cs fix: Updates serialization to use v2.0 (#998) 2022-04-17 08:02:15 -07:00
HeavyCrossbow.cs fix: Optimizes items to use default weights. (Part 4) (#2243) 2025-07-24 23:29:29 -07:00
JukaBow.cs feat: Adds leather/metal food, fixes weapons/armors with wrong materials (#1718) 2024-04-04 19:43:02 -07:00
LightweightShortbow.cs fix: Updates serialization to use v2.0 (#998) 2022-04-17 08:02:15 -07:00
LongbowOfMight.cs fix: Updates serialization to use v2.0 (#998) 2022-04-17 08:02:15 -07:00
MysticalShortbow.cs fix: Updates serialization to use v2.0 (#998) 2022-04-17 08:02:15 -07:00
RangersShortbow.cs fix: Updates serialization to use v2.0 (#998) 2022-04-17 08:02:15 -07:00
RepeatingCrossbow.cs fix: Optimizes items to use default weights. (Part 4) (#2243) 2025-07-24 23:29:29 -07:00
SlayerLongbow.cs fix: Updates serialization to use v2.0 (#998) 2022-04-17 08:02:15 -07:00