fix(ai): guard zero-int detection cooldown and duplicate pet friends (#2667)
Supersedes #2658 (rebased onto main; edits by maintainers were not enabled on the original branch). Credit to @MithrilHammer for both fixes and the regression tests; their three commits are kept as authored. Addresses two items from #2627: - The detect-hidden cooldown clamps its divisor to at least one. A creature whose effective intelligence reaches zero now uses the existing capped cooldown instead of throwing. - Pet friends are unique. `AddPetFriend` ignores an existing friend, so one removal revokes the membership. On top of that, `AddPetFriend` and `RemovePetFriend` now go through the generated `AddToFriends` / `RemoveFromFriends`, which mark the creature dirty. `Friends` goes back to null when the last friend is removed, and removing a non-friend no longer touches the list. Duplicates already stored in saves are not migrated. ## Tests `DetectHiddenTimerTests` (7 cases) drives the real AI timer and checks cooldown bounds and retry timing. `PetFriendMembershipTests` (3 cases) covers duplicate adds, removal, and re-adding without disturbing other friends. `UOContent.Tests`: 1158 passed, 2 skipped, 0 failed on Windows.
This commit is contained in:
parent
3eb3f0fb5c
commit
00688a04cf
4 changed files with 193 additions and 5 deletions
|
|
@ -225,7 +225,7 @@ public sealed class AITimer : Timer
|
|||
|
||||
private void CacheDetectHiddenDelays()
|
||||
{
|
||||
var delay = Math.Min(30000 / _owner.Mobile.Int, 120);
|
||||
var delay = Math.Min(30000 / Math.Max(1, _owner.Mobile.Int), 120);
|
||||
_detectHiddenMinDelay = delay * 900; // 26s to 108s
|
||||
_detectHiddenMaxDelay = delay * 1100; // 32s to 132s
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4304,16 +4304,27 @@ namespace Server.Mobiles
|
|||
|
||||
public virtual void AddPetFriend(Mobile m)
|
||||
{
|
||||
if (IsPetFriend(m))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Friends ??= [];
|
||||
Friends.Add(m);
|
||||
this.MarkDirty();
|
||||
AddToFriends(m);
|
||||
}
|
||||
|
||||
public virtual void RemovePetFriend(Mobile m)
|
||||
{
|
||||
if (Friends?.Remove(m) == true)
|
||||
if (Friends == null)
|
||||
{
|
||||
this.MarkDirty();
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveFromFriends(m);
|
||||
|
||||
if (Friends.Count == 0)
|
||||
{
|
||||
Friends = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue