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.
This commit is contained in:
parent
d2df7f7839
commit
a7bb8a8222
4 changed files with 158 additions and 96 deletions
|
|
@ -1623,16 +1623,9 @@ namespace Server.Mobiles
|
|||
|
||||
ReceivedHonorContext?.OnTargetDamaged(from, amount);
|
||||
|
||||
if (!willKill)
|
||||
if (!willKill && CanBeDistracted && ControlOrder == OrderType.Follow)
|
||||
{
|
||||
if (CanBeDistracted && ControlOrder == OrderType.Follow)
|
||||
{
|
||||
CheckDistracted(from);
|
||||
}
|
||||
}
|
||||
else if (from is PlayerMobile mobile)
|
||||
{
|
||||
Timer.StartTimer(TimeSpan.FromSeconds(10), mobile.RecoverAmmo);
|
||||
CheckDistracted(from);
|
||||
}
|
||||
|
||||
base.OnDamage(amount, from, willKill);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue