fix: Overhauls murder system (#1419)
## MAJOR CHANGE (API BREAKING) Added a player murder system to facilitate reporting murders. This should make it easier to extend to create a bounty system or other related game content. Player murders will be saved in a folder called _PlayerMurders_. ### Motivation The motivation was two-fold, performance, and bug fixes. First, murders are one of two systems that do a pre-world-save check on _every mobile in the game_ to decay kills and set their expiring murders. This is taxing since it freezes the world and makes world saves take longer. Every mobile has ShortTermMurders even though it is a player concept. And next, 90%+ of players are not murderers but had an ever increasing MurderElapse time that was being tracked against GameTime. These properties were also serialized unnecessarily for all mobs. Second, when I tried to optimize/refactor the code, it was obvious that the system has bugs. ### Major API Changes - [X] Created a player murder system and moved `ShortTermMurders`, `ShortTermElapse`, and `LongTermElapse` to the system. - [X] Added convenience property `PlayerMobile.ShortTermMurders`. - [X] Added convenience properties `PlayerMobile.ShortTermMurderExpiration` and `PlayerMobile.LongTermMurderExpiration` - [X] Moved ReportMurdererGump.cs - [X] Adds an `EventSink.PlayerDeleted` event. ### Notes The system currently does not support NPCs. To support expiring murders on NPCs I highly recommend a different architecture for large servers (500k+ mobs including players). Specifically switching from looping through all MurderContext to a time-order link list.
This commit is contained in:
parent
d65e5bb37b
commit
26f784f45d
13 changed files with 650 additions and 335 deletions
|
|
@ -109,6 +109,9 @@ public static partial class EventSink
|
|||
public static event Action<NetState, int> DeleteRequest;
|
||||
public static void InvokeDeleteRequest(NetState state, int index) => DeleteRequest?.Invoke(state, index);
|
||||
|
||||
public static event Action<Mobile> PlayerDeleted;
|
||||
public static void InvokePlayerDeleted(Mobile m) => PlayerDeleted?.Invoke(m);
|
||||
|
||||
public static event Action ServerStarted;
|
||||
public static void InvokeServerStarted() => ServerStarted?.Invoke();
|
||||
|
||||
|
|
|
|||
|
|
@ -15,4 +15,16 @@ public partial class Mobile
|
|||
StableMigrations[m] = stabled;
|
||||
}
|
||||
}
|
||||
|
||||
// Migrating murders to the murder system
|
||||
public static Dictionary<Mobile, int> MurderMigrations { get; private set; }
|
||||
|
||||
public static void AddToMurderMigrations(Mobile m, int shortTermMurders)
|
||||
{
|
||||
if (shortTermMurders > 0)
|
||||
{
|
||||
MurderMigrations ??= new Dictionary<Mobile, int>();
|
||||
MurderMigrations[m] = shortTermMurders;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
private int m_Hunger;
|
||||
|
||||
private bool m_InDeltaQueue;
|
||||
private int m_Kills, m_ShortTermMurders;
|
||||
private int m_Kills;
|
||||
private string m_Language;
|
||||
private int m_LightLevel;
|
||||
private Point3D m_Location;
|
||||
|
|
@ -1626,19 +1626,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ShortTermMurders
|
||||
{
|
||||
get => m_ShortTermMurders;
|
||||
set
|
||||
{
|
||||
if (m_ShortTermMurders != value)
|
||||
{
|
||||
m_ShortTermMurders = Math.Max(value, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
|
||||
public virtual bool Criminal
|
||||
{
|
||||
|
|
@ -2277,7 +2264,7 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
|
||||
public virtual void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.Write(34); // version
|
||||
writer.Write(35); // version
|
||||
|
||||
writer.WriteDeltaTime(LastStrGain);
|
||||
writer.WriteDeltaTime(LastIntGain);
|
||||
|
|
@ -2313,18 +2300,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
|
||||
writer.Write(Corpse);
|
||||
|
||||
// writer.Write(CreationTime);
|
||||
|
||||
// if (Stabled == null)
|
||||
// {
|
||||
// writer.Write(0);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Stabled.Tidy();
|
||||
// writer.Write(Stabled);
|
||||
// }
|
||||
|
||||
writer.Write(CantWalk);
|
||||
|
||||
VirtueInfo.Serialize(writer, Virtues);
|
||||
|
|
@ -2332,11 +2307,6 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
writer.Write(Thirst);
|
||||
writer.Write(BAC);
|
||||
|
||||
writer.Write(m_ShortTermMurders);
|
||||
// writer.Write( m_ShortTermElapse );
|
||||
// writer.Write( m_LongTermElapse );
|
||||
|
||||
// writer.Write( m_Followers );
|
||||
writer.Write(m_FollowersMax);
|
||||
|
||||
writer.Write(MagicDamageAbsorb);
|
||||
|
|
@ -6074,21 +6044,10 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
|
||||
switch (version)
|
||||
{
|
||||
case 34:
|
||||
{
|
||||
// Moved Stabled to PlayerMobile
|
||||
goto case 33;
|
||||
}
|
||||
case 33:
|
||||
{
|
||||
// Removed created
|
||||
goto case 32;
|
||||
}
|
||||
case 32:
|
||||
{
|
||||
// Removed StuckMenu
|
||||
goto case 31;
|
||||
}
|
||||
case 35: // Moved short term murders to PlayerMurderSystem
|
||||
case 34: // Moved Stabled to PlayerMobile
|
||||
case 33: // Removed created
|
||||
case 32: // Removed StuckMenu
|
||||
case 31:
|
||||
{
|
||||
LastStrGain = reader.ReadDeltaTime();
|
||||
|
|
@ -6183,7 +6142,11 @@ public partial class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPro
|
|||
}
|
||||
case 16:
|
||||
{
|
||||
m_ShortTermMurders = reader.ReadInt();
|
||||
if (version < 35)
|
||||
{
|
||||
// Migrated to PlayerMurderSystem
|
||||
AddToMurderMigrations(this, reader.ReadInt());
|
||||
}
|
||||
|
||||
if (version <= 24)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue