feat: Adds Mobile.Murderer virtual property, consolidates kill-threshold checks (#2355)

## Summary

- Adds `public virtual bool Murderer => Kills >= 5` property to `Mobile`, replacing ~30 scattered `Kills >= 5` / `Kills < 5` magic-number checks across the codebase
- `BaseCreature` overrides `Murderer` to also return `true` when `AlwaysMurderer` is set
- Updates `Corpse` serialization to v15, storing `_murderer` as a `bool` field (migrated from `int Kills >= 5` in earlier versions)
This commit is contained in:
Jack 2026-03-07 05:36:41 +13:00 • committed by GitHub
parent 192f092ee7
commit 6745cf2075
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 200 additions and 43 deletions

View file

@ -454,7 +454,7 @@ public partial class ChampionSpawn : Item
// Justice reward
var pm = (PlayerMobile)killer;
var prot = JusticeVirtue.GetProtector(pm);
if (prot == null || prot.Map != killer.Map || prot.Kills >= 5 || prot.Criminal ||
if (prot == null || prot.Map != killer.Map || prot.Murderer || prot.Criminal ||
!JusticeVirtue.CheckMapRegion(killer, prot))
{
return;

View file

@ -42,7 +42,7 @@ namespace Server.Engines.ConPVP
{
var mob = players[j];
if (mob.Kills >= 5)
if (mob.Murderer)
{
parts[0].Players.Add(mob);
}

View file

@ -31,7 +31,7 @@ public sealed partial class HeroEthic : Ethic
}
}
public override bool IsEligible(Mobile mob) => mob.Kills < 5 && Faction.Find(mob) is TrueBritannians or CouncilOfMages;
public override bool IsEligible(Mobile mob) => !mob.Murderer && Faction.Find(mob) is TrueBritannians or CouncilOfMages;
[AfterDeserialization]
private void AfterDeserialization()

View file

@ -307,7 +307,7 @@ public sealed class HelpGump : DynamicGump
}
else if (from is PlayerMobile mobile && mobile.CanUseStuckMenu() &&
mobile.Region.CanUseStuckMenu(mobile) && !CheckCombat(mobile) && !mobile.Frozen &&
!mobile.Criminal && (Core.AOS || mobile.Kills < 5))
!mobile.Criminal && (Core.AOS || !mobile.Murderer))
{
var menu = new StuckMenu(mobile, mobile, true);

View file

@ -300,7 +300,7 @@ namespace Server.Menus.Questions
}
else
{
destMap = m_Mobile.Kills >= 5 ? Map.Felucca : Map.Trammel;
destMap = m_Mobile.Murderer ? Map.Felucca : Map.Trammel;
}
BaseCreature.TeleportPets(m_Mobile, dest, destMap);

View file

@ -179,7 +179,7 @@ public class JusticeVirtue
{
protector.SendLocalizedMessage(1049372); // You cannot use this ability here.
}
else if (pm == protector || pm.Criminal || pm.Kills >= 5)
else if (pm == protector || pm.Criminal || pm.Murderer)
{
protector.SendLocalizedMessage(1049436); // That player cannot be protected.
}
@ -219,7 +219,7 @@ public class JusticeVirtue
{
protector.SendLocalizedMessage(1049372); // You cannot use this ability here.
}
else if (protectee == protector || protectee.Criminal || protectee.Kills >= 5)
else if (protectee == protector || protectee.Criminal || protectee.Murderer)
{
protector.SendLocalizedMessage(1049436); // That player cannot be protected.
}

View file

@ -30,7 +30,7 @@ public class VirtueGump : Gump
public static void RequestVirtueGump(PlayerMobile beholder, PlayerMobile beheld)
{
if (beholder == beheld && beholder.Kills >= 5)
if (beholder == beheld && beholder.Murderer)
{
beholder.SendLocalizedMessage(1049609); // Murderers cannot invoke this virtue.
}
@ -49,7 +49,7 @@ public class VirtueGump : Gump
beholder.CloseGump<VirtueGump>();
if (beholder.Kills >= 5)
if (beholder.Murderer)
{
beholder.SendLocalizedMessage(1049609); // Murderers cannot invoke this virtue.
return;