ModernUO/Projects/UOContent/Spells/Ninjitsu
Kamron Batman 8e5e4f72c8
fix(ninjitsu): gate Animal Form gump by skill and stop mana drain (#2452) (#2468)
## Issue

Fixes #2452. A player with 30 Ninjitsu reported that the Animal Form menu showed **every** form; selecting one above their skill (e.g. Dog, req 40) **consumed mana** and returned "you need at least 40 skill", and afterwards the **gump never reopened** — every recast silently re-attempted the unusable form and drained more mana.

## Root cause

Three linked bugs, all reproduced from the code:

1. **Gump not gated by skill.** `AnimalFormGump.BuildLayout` compared `Skill.Fixed` (which is `Value * 10`, so 30 skill → `300`) against the raw 0–100 `ReqSkill` (Dog = `40`). `300 >= 40` is always true, so all forms were shown. `Morph` itself correctly uses `.Value`.
2. **Mana charged on a no-skill cast.** `Morph` returns `MorphResult.NoSkill` for an under-skilled form, but both call sites (`OnCast`, `OnResponse`) only special-cased `MorphResult.Fail`; `NoSkill` fell through to the branch that deducts mana.
3. **Menu never reopened.** Per OSI ([uo.com](https://uo.com/wiki/ultima-online-wiki/skills/ninjitsu/), [uoguide](https://www.uoguide.com/Animal_Form)), casting while **standing still always opens the selection menu**, and casting while **moving** quick-transforms into the last selected form. ModernUO only opened the menu when `lastAnimalForm == -1`, so once any form was selected a stationary recast skipped the menu.

## Fix

- Add `AnimalForm.CanSelectEntry` (compares `Skill.Value` to `ReqSkill`, plus the talisman check) and use it for the gump's per-entry enable check.
- `OnCast`: standing still always opens the menu; moving quick-transforms into the last form. `NoSkill` no longer costs mana.
- `OnResponse`: handle `Success` / `Fail` / `NoSkill` explicitly so `NoSkill` costs no mana.

## Tests

Adds `AnimalFormTests`:
- `CanSelectEntry` rejects forms above skill, accepts forms at/below skill, and requires a talisman for talisman-gated forms.
- `Morph` returns `NoSkill` (without transforming) when under-skilled, and `Success` when sufficiently skilled.

Verified the gating test catches the regression (reintroducing `.Fixed` fails it). Full solution build is clean; the 5 new tests plus 284 other UOContent tests pass (the pathfinding/AI sequential tests were excluded only because they deadlock under concurrent local runs — they are unrelated to this change).
2026-06-06 15:56:31 -07:00
..
AnimalForm.cs fix(ninjitsu): gate Animal Form gump by skill and stop mana drain (#2452) (#2468) 2026-06-06 15:56:31 -07:00
Backstab.cs fix: Fixes various memory leaks and spells (#1786) 2024-05-21 19:44:42 -07:00
DeathStrike.cs fix: Fixes various memory leaks and spells (#1786) 2024-05-21 19:44:42 -07:00
FocusAttack.cs fix: Fixes various memory leaks and spells (#1786) 2024-05-21 19:44:42 -07:00
KiAttack.cs fix: Fixes various memory leaks and spells (#1786) 2024-05-21 19:44:42 -07:00
MirrorImage.cs fix: Standardizes the variables for AI (#2234) 2025-07-18 17:50:32 -07:00
NinjaMove.cs fix: Fixes various memory leaks and spells (#1786) 2024-05-21 19:44:42 -07:00
NinjaSpell.cs fix: Fixes various memory leaks and spells (#1786) 2024-05-21 19:44:42 -07:00
ShadowJump.cs fix: Fixes targeting ground with spells (#1937) 2024-08-20 15:51:33 -07:00
SurpriseAttack.cs fix: Fixes various memory leaks and spells (#1786) 2024-05-21 19:44:42 -07:00