Tokuno scribes currently load only `SBScribe`, so the existing Zento scribe does not offer the Book of Bushido or Book of Ninjitsu. Add the existing `SBSamurai` and `SBNinja` inventories when `Core.SE && IsTokunoVendor`. This reuses the existing book prices and default stock quantities. It does not change NPC placement, trainer behavior, or inventories outside Tokuno. ### Sources and reasoning - The [official UO Ninjitsu guide](https://uo.com/wiki/ultima-online-wiki/skills/ninjitsu/) identifies the scribe at Rokuon Cultural Center in Zento as a seller of the Book of Ninjitsu. - [UOGuide: Bushido](https://www.uoguide.com/Bushido), documenting standard UO, explicitly lists Tokuno Islands scribe NPCs as a source for the Book of Bushido. This supports adding both book inventories to Tokuno scribes. - Documentation distinction: the [official UO Bushido guide](https://uo.com/wiki/ultima-online-wiki/skills/bushido/) describes the Zento seller as a samurai trainer, rather than a scribe. The Bushido scribe change follows the explicit UOGuide description. These references do not independently establish the exact historical introduction date or original prices. ### Validation - Built the change in a customized ModernUO 0.15.6.145 deployment: Release, linux-x64, zero warnings or errors. - In-game with Mondain's Legacy enabled: both books appeared on the existing Zento scribe, and a player successfully purchased both. - Reviewed the expansion/location guard for pre-SE and non-Tokuno behavior; those cases were not gameplay-tested. This exact patch has not been built against current upstream main.
65 lines
1.8 KiB
C#
65 lines
1.8 KiB
C#
using ModernUO.Serialization;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Server.Items;
|
|
|
|
namespace Server.Mobiles
|
|
{
|
|
[SerializationGenerator(0, false)]
|
|
public partial class Scribe : BaseVendor
|
|
{
|
|
public static readonly TimeSpan ShushDelay = TimeSpan.FromMinutes(1);
|
|
private readonly List<SBInfo> m_SBInfos = new();
|
|
|
|
private DateTime m_NextShush;
|
|
|
|
[Constructible]
|
|
public Scribe() : base("the scribe")
|
|
{
|
|
SetSkill(SkillName.EvalInt, 60.0, 83.0);
|
|
SetSkill(SkillName.Inscribe, 90.0, 100.0);
|
|
}
|
|
|
|
protected override List<SBInfo> SBInfos => m_SBInfos;
|
|
|
|
public override NpcGuild NpcGuild => NpcGuild.MagesGuild;
|
|
|
|
public override VendorShoeType ShoeType => Utility.RandomBool() ? VendorShoeType.Shoes : VendorShoeType.Sandals;
|
|
|
|
public override void InitSBInfo()
|
|
{
|
|
m_SBInfos.Add(new SBScribe());
|
|
|
|
if (Core.SE && IsTokunoVendor || Core.SA && IsTerMurVendor)
|
|
{
|
|
m_SBInfos.Add(new SBSamurai());
|
|
m_SBInfos.Add(new SBNinja());
|
|
}
|
|
}
|
|
|
|
public override void InitOutfit()
|
|
{
|
|
base.InitOutfit();
|
|
|
|
AddItem(new Robe(Utility.RandomNeutralHue()));
|
|
}
|
|
|
|
public override bool HandlesOnSpeech(Mobile from) => from.Player;
|
|
|
|
public override void OnSpeech(SpeechEventArgs e)
|
|
{
|
|
base.OnSpeech(e);
|
|
|
|
if (!e.Handled && m_NextShush <= Core.Now && InLOS(e.Mobile))
|
|
{
|
|
Direction = GetDirectionTo(e.Mobile);
|
|
|
|
PlaySound(Female ? 0x32F : 0x441);
|
|
PublicOverheadMessage(MessageType.Regular, 0x3B2, 1073990); // Shhhh!
|
|
|
|
m_NextShush = Core.Now + ShushDelay;
|
|
e.Handled = true;
|
|
}
|
|
}
|
|
}
|
|
}
|