using System; using System.Collections.Generic; using Server.Engines.Craft; using Server.Engines.Craft.T2A; using Server.Items; using Server.Targeting; namespace Server.SkillHandlers { public static class Inscribe { private static readonly Dictionary m_UseTable = new(); public static void Initialize() { SkillInfo.Table[(int)SkillName.Inscribe].Callback = OnUse; } public static TimeSpan OnUse(Mobile m) { if (T2ACraftSystem.Enabled) { var target = new T2AInscribeTarget(); m.Target = target; m.SendAsciiMessage("Target the book you wish to copy or scroll you want to use."); target.BeginTimeout(m, 60000); // 1 minute return TimeSpan.FromSeconds(1.0); } Target uotdTarget = new InternalTargetSrc(); m.Target = uotdTarget; m.SendLocalizedMessage(1046295); // Target the book you wish to copy. uotdTarget.BeginTimeout(m, 60000); // 1 minute return TimeSpan.FromSeconds(1.0); } private static void SetUser(BaseBook book, Mobile mob) { m_UseTable[book] = mob; } private static void CancelUser(BaseBook book) { m_UseTable.Remove(book); } public static Mobile GetUser(BaseBook book) { m_UseTable.TryGetValue(book, out var m); return m; } public static bool IsEmpty(BaseBook book) { for (var i = 0; i < book.Pages.Length; i++) { var page = book.Pages[i]; for (var j = 0; j < page.Lines.Length; j++) { var line = page.Lines[j]; if (!string.IsNullOrEmpty(line)) { return false; } } } return true; } public static void Copy(BaseBook bookSrc, BaseBook bookDst) { bookDst.Title = bookSrc.Title; bookDst.Author = bookSrc.Author; var pagesSrc = bookSrc.Pages; var pagesDst = bookDst.Pages; for (var i = 0; i < pagesSrc.Length && i < pagesDst.Length; i++) { var pageSrc = pagesSrc[i]; var pageDst = pagesDst[i]; var length = pageSrc.Lines.Length; pageDst.Lines = new string[length]; for (var j = 0; j < length; j++) { pageDst.Lines[j] = pageSrc.Lines[j]; } } } private class T2AInscribeTarget : Target { public T2AInscribeTarget() : base(3, false, TargetFlags.None) { } protected override void OnTarget(Mobile from, object targeted) { if (targeted is BlankScroll scroll) { if (!scroll.IsChildOf(from.Backpack)) { from.SendAsciiMessage("That must be in your pack for you to use it."); } else { T2ACraftSystem.ShowMenu(from, DefInscription.CraftSystem, null); } } else if (targeted is RecallRune) { var system = DefInscription.CraftSystem; var itemDef = system.CraftItems.SearchFor(typeof(Runebook)); if (itemDef != null) { var num = system.CanCraft(from, null, itemDef.ItemType); if (num > 0) { from.SendLocalizedMessage(num); } else { system.CreateItem(from, itemDef.ItemType, null, null, itemDef); } } } else if (targeted is BaseBook book) { if (IsEmpty(book)) { from.SendLocalizedMessage(501611); // Can't copy an empty book. } else if (GetUser(book) != null) { from.SendLocalizedMessage(501621); // Someone else is inscribing that item. } else { Target target = new InternalTargetDst(book); from.Target = target; from.SendLocalizedMessage(501612); // Select a book to copy this to. target.BeginTimeout(from, 60000); SetUser(book, from); } } else { from.SendLocalizedMessage(1046296); // That is not a book } } protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType) { if (cancelType == TargetCancelType.Timeout) { from.SendLocalizedMessage(501619); } } } private class InternalTargetSrc : Target { public InternalTargetSrc() : base(3, false, TargetFlags.None) { } protected override void OnTarget(Mobile from, object targeted) { if (targeted is not BaseBook book) { from.SendLocalizedMessage(1046296); // That is not a book } else if (IsEmpty(book)) { from.SendLocalizedMessage(501611); // Can't copy an empty book. } else if (GetUser(book) != null) { from.SendLocalizedMessage(501621); // Someone else is inscribing that item. } else { Target target = new InternalTargetDst(book); from.Target = target; from.SendLocalizedMessage(501612); // Select a book to copy this to. target.BeginTimeout(from, 60000); // 1 minute SetUser(book, from); } } protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType) { if (cancelType == TargetCancelType.Timeout) { // You have waited too long to make your inscribe selection, your inscription attempt has timed out. from.SendLocalizedMessage(501619); } } } private class InternalTargetDst : Target { private readonly BaseBook m_BookSrc; public InternalTargetDst(BaseBook bookSrc) : base(3, false, TargetFlags.None) => m_BookSrc = bookSrc; protected override void OnTarget(Mobile from, object targeted) { if (m_BookSrc.Deleted) { return; } if (targeted is not BaseBook bookDst) { from.SendLocalizedMessage(1046296); // That is not a book } else if (IsEmpty(m_BookSrc)) { from.SendLocalizedMessage(501611); // Can't copy an empty book. } else if (bookDst == m_BookSrc) { from.SendLocalizedMessage(501616); // Cannot copy a book onto itself. } else if (!bookDst.Writable) { from.SendLocalizedMessage(501614); // Cannot write into that book. } else if (GetUser(bookDst) != null) { from.SendLocalizedMessage(501621); // Someone else is inscribing that item. } else if (from.CheckTargetSkill(SkillName.Inscribe, bookDst, 0, 50)) { Copy(m_BookSrc, bookDst); from.SendLocalizedMessage(501618); // You make a copy of the book. from.PlaySound(0x249); } else { from.SendLocalizedMessage(501617); // You fail to make a copy of the book. } } protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType) { if (cancelType == TargetCancelType.Timeout) { // You have waited too long to make your inscribe selection, your inscription attempt has timed out. from.SendLocalizedMessage(501619); } } protected override void OnTargetFinish(Mobile from) { CancelUser(m_BookSrc); } } } }