mirror of
https://github.com/modernuo/ModernUO
synced 2026-08-11 22:23:06 -04:00
## 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.
60 lines
2 KiB
C#
60 lines
2 KiB
C#
using Server.Guilds;
|
|
using Server.Gumps;
|
|
using Server.Mobiles;
|
|
|
|
namespace Server.Misc
|
|
{
|
|
public static class Keywords
|
|
{
|
|
public static void Initialize()
|
|
{
|
|
// Register our speech handler
|
|
EventSink.Speech += EventSink_Speech;
|
|
}
|
|
|
|
public static void EventSink_Speech(SpeechEventArgs args)
|
|
{
|
|
var from = args.Mobile;
|
|
var keywords = args.Keywords;
|
|
|
|
for (var i = 0; i < keywords.Length; ++i)
|
|
{
|
|
switch (keywords[i])
|
|
{
|
|
case 0x002A: // *i resign from my guild*
|
|
{
|
|
((Guild)from.Guild)?.RemoveMember(from);
|
|
|
|
break;
|
|
}
|
|
case 0x0032: // *i must consider my sins*
|
|
{
|
|
if (from is PlayerMobile player)
|
|
{
|
|
if (!Core.SE)
|
|
{
|
|
from.SendMessage($"Short Term Murders : {player.ShortTermMurders}");
|
|
from.SendMessage($"Long Term Murders : {from.Kills}");
|
|
}
|
|
else
|
|
{
|
|
from.SendLocalizedMessage(1114370, $"{player.ShortTermMurders}\t{from.Kills}");
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case 0x0035: // i renounce my young player status*
|
|
{
|
|
if (from is PlayerMobile mobile && mobile.Young && !mobile.HasGump<RenounceYoungGump>())
|
|
{
|
|
mobile.SendGump(new RenounceYoungGump());
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|