ModernUO/Projects/UOContent/Mobiles/AI/BaseAI
Kamron Batman 114dbba6e2
fix: a stop order silently cancelled a standing follow order (#2616)
## The bug

Pet is set to follow. It gets attacked and defends itself (the order flips to `Attack`), or the player tells it to `come`. The player then says `stop`. The pet quietly stops following and starts idle-wandering — the player has to re-issue the order to get it back.

`ResolveStop` clears `ControlTarget`, since the transient order that is ending owns it, and then resumes the standing order. Nothing restores a target, so the resumed `Follow` has none. `DoOrderFollow` checks for a target before anything else, finds none on the very next think, says "I have no one to follow" and cancels the order to `None`:

```
follow standing        order=Follow  target=set  persist=Follow  cur=0.2 => move=0.3
attacked (defends)     order=Attack  target=set  persist=Follow  cur=0.2 => move=0.3
stop issued            order=Follow  target=null persist=Follow  cur=0.2 => move=0.3
  next think           order=None    target=null persist=Follow  cur=0.4 => move=0.9
```

Two things go wrong at once:

- `PersistentOrder` still reads `Follow` while `ControlOrder` is `None`, so the pet never recovers on its own.
- The pace falls from the active clock to the passive one. A shard that tunes `SetMoveSpeed(active, passive)` sees a following pet drop from its active move speed to its passive one for no visible reason — which is how this surfaced.

Era-independent. Guard is unaffected: `DoOrderGuard` works off `ControlMaster`, not `ControlTarget`.

## The fix

A standing `Follow` does not always mean "follow the master" — a pet friend can point it elsewhere with `all follow me` / `*follow me` (0x163, 0x16C) or `*follow` plus a target pick. So `SetPersistentOrder` remembers the target the standing order was given, and `ResumePersistentOrder` restores it, falling back to the master only when that target is gone. The field is runtime-only, like `PersistentOrder` itself.

Doing this in `ResumePersistentOrder` rather than `ResolveStop` also covers the Friend/Unfriend/Transfer resumes, where `ControlTarget` points at a third party and the pet would otherwise have resumed its follow on *them*. It matches what `HandleInvalidControlTarget` already does before its own resume.

## Tests

`Stop_WhileAttacking_FallsBackToPersistentFollow` already existed and passed, because it asserted the resumed order without checking for a target or driving a think tick. Three tests added alongside it:

- `Stop_WhileAttacking_ResumedFollowTargetsTheMaster`
- `Stop_WhileAttacking_ResumedFollowKeepsAPetFriendAsItsTarget` — a friend's follow order is not hijacked back to the owner
- `Stop_WhileAttacking_ResumedFollowSurvivesTheNextThink` — the one that catches the cancellation

Each was confirmed to fail without the change (`Expected: Follow, Actual: None`; wrong target). Full suites green: 782 UOContent, 869 Server.
2026-09-07 08:51:10 -07:00
..
ActionType.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
AIGroupMovement.cs feat: derive the Running bit from the step pace and fix step-pacing bursts (#2599) 2026-08-30 16:48:52 -07:00
AIMovement.cs feat: derive the Running bit from the step pace and fix step-pacing bursts (#2599) 2026-08-30 16:48:52 -07:00
AITimer.cs feat: event-driven target acquisition with a reaction-time gradient (#2601) 2026-09-01 20:42:15 -07:00
AIType.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
BaseAI.cs feat: event-driven target acquisition with a reaction-time gradient (#2601) 2026-09-01 20:42:15 -07:00
BaseAIExtensions.cs fix: Consolidates debug check messages for AI and adds debounce (#2235) 2025-07-18 18:08:03 -07:00
ContextMenu.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
DebugInterpolatedStringHandler.cs chore: Use var everywhere (#2294) 2025-12-27 16:47:28 -08:00
InternalEntry.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
OnSpeech.cs fix: pet release never finished, summon master follows the pet, horse breeder and notoriety guards (#2613) 2026-09-06 16:12:29 -07:00
PetLogin.cs fix(ai): pet order/home refactor — stop & post-combat behavior (#2459) 2026-06-07 01:22:43 -07:00
PetOrderHandlers.cs fix: pet release never finished, summon master follows the pet, horse breeder and notoriety guards (#2613) 2026-09-06 16:12:29 -07:00
PetOrders.cs fix: a stop order silently cancelled a standing follow order (#2616) 2026-09-07 08:51:10 -07:00
SpeechEventArgsExt.cs fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
TransferItem.cs fix: pet release never finished, summon master follows the pet, horse breeder and notoriety guards (#2613) 2026-09-06 16:12:29 -07:00
WalkRandomLogic.cs fix(ai): pet order/home refactor — stop & post-combat behavior (#2459) 2026-06-07 01:22:43 -07:00