fix: Moves PlayerBarkeeper to Serialization Generator (#2323)

This commit is contained in:
Kamron Batman 2026-02-01 17:01:39 -08:00 committed by GitHub
parent 3c0d6cb9d6
commit 06bb2f552e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 995 additions and 1020 deletions

View file

@ -0,0 +1,22 @@
{
"version": 0,
"type": "Server.Mobiles.BarkeeperRumor",
"properties": [
{
"name": "Message",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Keyword",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,34 @@
{
"version": 2,
"type": "Server.Mobiles.PlayerBarkeeper",
"properties": [
{
"name": "House",
"type": "Server.Multis.BaseHouse",
"rule": "SerializableInterfaceMigrationRule"
},
{
"name": "Owner",
"type": "Server.Mobile",
"rule": "SerializableInterfaceMigrationRule"
},
{
"name": "Rumors",
"type": "Server.Mobiles.BarkeeperRumor[]",
"rule": "ArrayMigrationRule",
"ruleArguments": [
"Server.Mobiles.BarkeeperRumor",
"RawSerializableMigrationRule",
"DeserializationRequiresParent"
]
},
{
"name": "TipMessage",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
@ -8,17 +9,17 @@ using Server.Multis;
using Server.Network;
using Server.Prompts;
namespace Server.Mobiles
namespace Server.Mobiles;
public class ChangeRumorMessagePrompt : Prompt
{
public class ChangeRumorMessagePrompt : Prompt
{
private readonly PlayerBarkeeper m_Barkeeper;
private readonly int m_RumorIndex;
private readonly PlayerBarkeeper _barkeeper;
private readonly int _rumorIndex;
public ChangeRumorMessagePrompt(PlayerBarkeeper barkeeper, int rumorIndex)
{
m_Barkeeper = barkeeper;
m_RumorIndex = rumorIndex;
_barkeeper = barkeeper;
_rumorIndex = rumorIndex;
}
public override void OnCancel(Mobile from)
@ -33,19 +34,19 @@ namespace Server.Mobiles
text = text[..130];
}
m_Barkeeper.EndChangeRumor(from, m_RumorIndex, text);
}
_barkeeper.EndChangeRumor(from, _rumorIndex, text);
}
}
public class ChangeRumorKeywordPrompt : Prompt
{
private readonly PlayerBarkeeper m_Barkeeper;
private readonly int m_RumorIndex;
public class ChangeRumorKeywordPrompt : Prompt
{
private readonly PlayerBarkeeper _barkeeper;
private readonly int _rumorIndex;
public ChangeRumorKeywordPrompt(PlayerBarkeeper barkeeper, int rumorIndex)
{
m_Barkeeper = barkeeper;
m_RumorIndex = rumorIndex;
_barkeeper = barkeeper;
_rumorIndex = rumorIndex;
}
public override void OnCancel(Mobile from)
@ -60,15 +61,15 @@ namespace Server.Mobiles
text = text[..130];
}
m_Barkeeper.EndChangeKeyword(from, m_RumorIndex, text);
}
_barkeeper.EndChangeKeyword(from, _rumorIndex, text);
}
}
public class ChangeTipMessagePrompt : Prompt
{
private readonly PlayerBarkeeper m_Barkeeper;
public class ChangeTipMessagePrompt : Prompt
{
private readonly PlayerBarkeeper _barkeeper;
public ChangeTipMessagePrompt(PlayerBarkeeper barkeeper) => m_Barkeeper = barkeeper;
public ChangeTipMessagePrompt(PlayerBarkeeper barkeeper) => _barkeeper = barkeeper;
public override void OnCancel(Mobile from)
{
@ -82,49 +83,34 @@ namespace Server.Mobiles
text = text[..130];
}
m_Barkeeper.EndChangeTip(from, text);
_barkeeper.EndChangeTip(from, text);
}
}
[SerializationGenerator(0)]
public partial class BarkeeperRumor
{
[DirtyTrackingEntity]
private PlayerBarkeeper _barkeeper;
[SerializableField(0)]
private string _message;
[SerializableField(1)]
private string _keyword;
public BarkeeperRumor(PlayerBarkeeper barkeeper, string message, string keyword)
{
_message = message;
_keyword = keyword;
_barkeeper = barkeeper;
}
public class BarkeeperRumor
{
public BarkeeperRumor(string message, string keyword)
{
Message = message;
Keyword = keyword;
}
public BarkeeperRumor(PlayerBarkeeper barkeeper) => _barkeeper = barkeeper;
}
public string Message { get; set; }
public string Keyword { get; set; }
public static BarkeeperRumor Deserialize(IGenericReader reader)
{
if (!reader.ReadBool())
{
return null;
}
return new BarkeeperRumor(reader.ReadString(), reader.ReadString());
}
public static void Serialize(IGenericWriter writer, BarkeeperRumor rumor)
{
if (rumor == null)
{
writer.Write(false);
}
else
{
writer.Write(true);
writer.Write(rumor.Message);
writer.Write(rumor.Keyword);
}
}
}
public class ManageBarkeeperEntry : ContextMenuEntry
{
public class ManageBarkeeperEntry : ContextMenuEntry
{
public ManageBarkeeperEntry() : base(6151, 12)
{
}
@ -133,12 +119,25 @@ namespace Server.Mobiles
{
(target as PlayerBarkeeper)?.BeginManagement(from);
}
}
}
public class PlayerBarkeeper : BaseVendor
{
private readonly List<SBInfo> m_SBInfos = new();
private BaseHouse m_House;
[SerializationGenerator(2, false)]
public partial class PlayerBarkeeper : BaseVendor
{
public static readonly BarkeeperRumor[] EmptyRumors = new BarkeeperRumor[RumorCount];
private const int RumorCount = 3;
private readonly List<SBInfo> _sbInfos = [];
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private Mobile _owner;
[SerializableField(2)]
private BarkeeperRumor[] _rumors;
[SerializableField(3)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private string _tipMessage;
private Timer _newsTimer;
@ -146,44 +145,32 @@ namespace Server.Mobiles
{
Owner = owner;
House = house;
Rumors = new BarkeeperRumor[3];
LoadSBInfo();
}
public PlayerBarkeeper(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Owner { get; set; }
[SerializableProperty(0)]
public BaseHouse House
{
get => m_House;
get => _house;
set
{
m_House?.PlayerBarkeepers.Remove(this);
_house?.PlayerBarkeepers.Remove(this);
value?.PlayerBarkeepers.Add(this);
m_House = value;
_house = value;
this.MarkDirty();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public string TipMessage { get; set; }
public override bool IsActiveBuyer => false;
public override bool IsActiveSeller => m_SBInfos.Count > 0;
public override bool IsActiveSeller => _sbInfos.Count > 0;
public override bool DisallowAllMoves => true;
public override bool NoHouseRestrictions => true;
public BarkeeperRumor[] Rumors { get; private set; }
public override VendorShoeType ShoeType => Utility.RandomBool() ? VendorShoeType.ThighBoots : VendorShoeType.Boots;
protected override List<SBInfo> SBInfos => m_SBInfos;
protected override List<SBInfo> SBInfos => _sbInfos;
public override bool GetGender() => false;
@ -202,18 +189,8 @@ namespace Server.Mobiles
{
base.InitBody();
if (Body == 0x340 || Body == 0x402)
{
Hue = 0;
}
else
{
Hue = 0x83F4; // hue is not random
}
var pack = Backpack;
pack?.Delete();
Hue = Body == 0x340 || Body == 0x402 ? 0 : 0x83F4; // hue is not random
Backpack?.Delete();
}
public override bool HandlesOnSpeech(Mobile from) => InRange(from, 3) || base.HandlesOnSpeech(from);
@ -260,8 +237,11 @@ namespace Server.Mobiles
{
base.OnSpeech(e);
if (!e.Handled && InRange(e.Mobile, 3))
if (e.Handled || !InRange(e.Mobile, 3))
{
return;
}
if (_newsTimer == null && e.HasKeyword(0x30)) // *news*
{
var tce = GlobalTownCrierEntryList.Instance.GetRandomEntry();
@ -283,9 +263,14 @@ namespace Server.Mobiles
}
}
for (var i = 0; i < Rumors.Length; ++i)
if (_rumors == null)
{
var rumor = Rumors[i];
return;
}
for (var i = 0; i < _rumors.Length; ++i)
{
var rumor = _rumors[i];
var keyword = rumor?.Keyword;
@ -307,7 +292,6 @@ namespace Server.Mobiles
}
}
}
}
public override bool CheckGold(Mobile from, Item dropped)
{
@ -353,20 +337,8 @@ namespace Server.Mobiles
return false;
}
public bool IsOwner(Mobile from)
{
if (from?.Deleted != false || Deleted)
{
return false;
}
if (from.AccessLevel > AccessLevel.GameMaster)
{
return true;
}
return Owner == from;
}
public bool IsOwner(Mobile from) =>
from?.Deleted == false && !Deleted && (from.AccessLevel > AccessLevel.GameMaster || Owner == from);
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
@ -395,7 +367,7 @@ namespace Server.Mobiles
public void BeginChangeRumor(Mobile from, int index)
{
if (index < 0 || index >= Rumors.Length)
if (index is < 0 or >= RumorCount)
{
return;
}
@ -412,69 +384,68 @@ namespace Server.Mobiles
public void EndChangeRumor(Mobile from, int index, string text)
{
if (index < 0 || index >= Rumors.Length)
if (index is < 0 or >= RumorCount)
{
return;
}
Rumors ??= new BarkeeperRumor[RumorCount];
if (Rumors[index] == null)
{
Rumors[index] = new BarkeeperRumor(text, null);
Rumors[index] = new BarkeeperRumor(this, text, null);
}
else
{
Rumors[index].Message = text;
}
this.MarkDirty();
from.Prompt = new ChangeRumorKeywordPrompt(this, index);
PrivateOverheadMessage(
MessageType.Regular,
0x3B2,
false,
"What keyword should a guest say to me to get this news?",
from.NetState
);
// What keyword should a guest say to me to get this news?
PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1079267, from.NetState);
}
public void EndChangeKeyword(Mobile from, int index, string text)
{
if (index < 0 || index >= Rumors.Length)
if (index is < 0 or >= RumorCount)
{
return;
}
Rumors ??= new BarkeeperRumor[RumorCount];
if (Rumors[index] == null)
{
Rumors[index] = new BarkeeperRumor(null, text);
Rumors[index] = new BarkeeperRumor(this, null, text);
}
else
{
Rumors[index].Keyword = text;
}
this.MarkDirty();
PrivateOverheadMessage(MessageType.Regular, 0x3B2, false, "I'll pass on the message.", from.NetState);
}
public void RemoveRumor(Mobile from, int index)
public void RemoveRumor(int index)
{
if (index < 0 || index >= Rumors.Length)
if (index is >= 0 and < RumorCount && _rumors != null)
{
return;
_rumors[index] = null;
this.MarkDirty();
}
Rumors[index] = null;
}
public void BeginChangeTip(Mobile from)
{
from.Prompt = new ChangeTipMessagePrompt(this);
PrivateOverheadMessage(
MessageType.Regular,
0x3B2,
false,
"Say what you want me to tell guests when they give me a good tip.",
from.NetState
);
// Say what you want me to tell guests when they give me a good tip.
PrivateOverheadMessage(MessageType.Regular, 0x3B2, 1079268, from.NetState);
}
public void EndChangeTip(Mobile from, string text)
@ -489,20 +460,13 @@ namespace Server.Mobiles
);
}
public void RemoveTip(Mobile from)
{
TipMessage = null;
}
public void RemoveTip() => TipMessage = null;
public void BeginChangeTitle(Mobile from)
{
from.SendGump(new BarkeeperTitleGump(this));
}
public void BeginChangeTitle(Mobile from) => from.SendGump(new BarkeeperTitleGump(this));
public void EndChangeTitle(Mobile from, string title, bool vendor)
public void EndChangeTitle(string title)
{
Title = title;
LoadSBInfo();
}
@ -516,7 +480,7 @@ namespace Server.Mobiles
from.SendGump(new PlayerVendorCustomizeGump(this, from));
}
public void ChangeGender(Mobile from)
public void ChangeGender()
{
Female = !Female;
@ -536,86 +500,45 @@ namespace Server.Mobiles
public override void InitSBInfo()
{
if (Title is "the waiter" or "the barkeeper" or "the baker" or "the innkeeper" or "the chef")
if (Title is not ("the waiter" or "the barkeeper" or "the baker" or "the innkeeper" or "the chef"))
{
if (m_SBInfos.Count == 0)
_sbInfos.Clear();
return;
}
if (_sbInfos.Count == 0)
{
m_SBInfos.Add(new SBPlayerBarkeeper());
_sbInfos.Add(new SBPlayerBarkeeper());
}
}
else
private void Deserialize(IGenericReader reader, int version)
{
m_SBInfos.Clear();
}
}
_house = (BaseHouse)reader.ReadEntity<Item>();
_owner = reader.ReadEntity<Mobile>();
public override void Serialize(IGenericWriter writer)
_rumors = new BarkeeperRumor[reader.ReadEncodedInt()];
for (var i = 0; i < _rumors.Length; ++i)
{
base.Serialize(writer);
writer.Write(1); // version;
writer.Write(m_House);
writer.Write(Owner);
writer.WriteEncodedInt(Rumors.Length);
for (var i = 0; i < Rumors.Length; ++i)
if (reader.ReadBool())
{
BarkeeperRumor.Serialize(writer, Rumors[i]);
}
writer.Write(TipMessage);
}
public override void Deserialize(IGenericReader reader)
_rumors[i] = new BarkeeperRumor(this)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 1:
{
House = (BaseHouse)reader.ReadEntity<Item>();
goto case 0;
}
case 0:
{
Owner = reader.ReadEntity<Mobile>();
Rumors = new BarkeeperRumor[reader.ReadEncodedInt()];
for (var i = 0; i < Rumors.Length; ++i)
{
Rumors[i] = BarkeeperRumor.Deserialize(reader);
}
TipMessage = reader.ReadString();
break;
Message = reader.ReadString(),
Keyword = reader.ReadString()
};
}
}
if (version < 1)
{
Timer.StartTimer(UpgradeFromVersion0);
}
_tipMessage = reader.ReadString();
}
}
private void UpgradeFromVersion0()
{
House = BaseHouse.FindHouseAt(this);
}
}
public class BarkeeperTitleGump : StaticGump<BarkeeperTitleGump>
{
public class BarkeeperTitleGump : StaticGump<BarkeeperTitleGump>
{
private static readonly Entry[] _entries =
{
[
new(1076083, "the alchemist"),
new(1077244, "the animal tamer"),
new(1078440, "the apothecary"),
@ -676,7 +599,7 @@ namespace Server.Mobiles
new(1077242, "the warrior"),
new(1078496, "the watchman"),
new(1078495, null) // No Title
};
];
private static readonly int _pageCount = (_entries.Length + 19) / 20;
@ -821,7 +744,7 @@ namespace Server.Mobiles
if (buttonID < _entries.Length)
{
var entry = _entries[buttonID];
_barkeeper.EndChangeTitle(from, entry.Title, entry.Vendor);
_barkeeper.EndChangeTitle(entry.Title);
}
}
@ -838,10 +761,10 @@ namespace Server.Mobiles
Vendor = vendor;
}
}
}
}
public class BarkeeperGump : DynamicGump
{
public class BarkeeperGump : DynamicGump
{
private readonly PlayerBarkeeper _barkeeper;
public override bool Singleton => true;
@ -852,10 +775,7 @@ namespace Server.Mobiles
from.SendGump(new BarkeeperGump(barkeeper));
}
public BarkeeperGump(PlayerBarkeeper barkeeper) : base(0, 0)
{
_barkeeper = barkeeper;
}
public BarkeeperGump(PlayerBarkeeper barkeeper) : base(0, 0) => _barkeeper = barkeeper;
protected override void BuildLayout(ref DynamicGumpBuilder builder)
{
@ -977,7 +897,7 @@ namespace Server.Mobiles
builder.AddHtmlLocalized(250, 60, 500, 25, 1078360); // Add or change a message
var rumors = _barkeeper.Rumors;
var rumors = _barkeeper.Rumors ?? PlayerBarkeeper.EmptyRumors;
for (var i = 0; i < rumors.Length; ++i)
{
@ -1003,7 +923,7 @@ namespace Server.Mobiles
builder.AddHtmlLocalized(190, 60, 500, 25, 1078362); // Choose the message you would like to remove
var rumors = _barkeeper.Rumors;
var rumors = _barkeeper.Rumors ?? PlayerBarkeeper.EmptyRumors;
for (var i = 0; i < rumors.Length; ++i)
{
@ -1118,7 +1038,7 @@ namespace Server.Mobiles
}
case 2: // Remove message
{
_barkeeper.RemoveRumor(from, index);
_barkeeper.RemoveRumor(index);
break;
}
case 3: // Change tip
@ -1128,7 +1048,7 @@ namespace Server.Mobiles
}
case 4: // Remove tip
{
_barkeeper.RemoveTip(from);
_barkeeper.RemoveTip();
break;
}
case 5: // Appearance category selection
@ -1147,7 +1067,7 @@ namespace Server.Mobiles
}
case 2:
{
_barkeeper.ChangeGender(from);
_barkeeper.ChangeGender();
break;
}
}
@ -1156,5 +1076,4 @@ namespace Server.Mobiles
}
}
}
}
}