ModernUO/Projects/Scripts/Gumps/RunebookGump.cs
Kamron Batman 179cb50557 Updates Packets & Randomizer (#43)
* Fixes a bug with the main loop. Removes unnecessary optimizations for RDRand.

* WIP - Rewriting packets.

* Cleanup and updates README

* Converts more packets

* Fixes header

* Converts Effects packets.

* Forgot the send command

* Adds the start of containers packets.

* Adds message packets with caching

* Extends the send methods

* Starts to add Acquire methods

* Converted the packets

* Cleanup

* Cleanup

* Adds more packets

* Adds more packets

* Fixes clearing arrays from pool. Adds Mobile Incoming

* Converts more packets.

* Moves more packets

* Moves more packets

* Test compression

* Merges

* Migrating to an idiomatic syntax that also supports compression, and proxying.

* Optimize the stack alloc. Changes attributes

* Converted container packets

* Visual Studio doesn't auto save files. I am still getting used to subpar IDEs.

* Adds static packet caching. Will profile later. Converts more packets

* Fixes packets and changes how compression is configured

* WIP - Adds basics for Gumps. Not finished though.

* Fix file

* Fixes formatting

* Changed SpanWriter to be more idiomatic.

* Fixes Span vs RawSpan and missing stackallocs

* Converts over some more gumps

* WIP - Deletes 32bit support.

* Drops RDRand32 support.

* Fixes gump compilation

* Converting gump components

* Removes old huffman compression function

* Revert signature for backwards compatibility

* WIP - Converting more gump components

* Creates ArraySet for the strings. Updates AppendTo to reference that.

* Converts the maining gump components

* Cleans up gump components

* Cleans up directives

* Cleans up ArraySet and moves it. Adds null-coalescing-assignment

* Cleanup, Target Packets, and C# 8 changes.

* Removed OPL Packet

* World packets

* Fixing packet uses

* Cleans up code. Fixes packet uses in various places.

* More cleanup for packets

* Code cleanup

* Converts more packet uses and cleans up more code

* More code cleanup

* Finishes fixing the packets in Item

* Updates secure trade packets

* Updates core and gets it to compile.

* Moved packets to scripts. Fixed account handler use of packets

* Code cleanup

* Updates chat packets

* Code cleanuo

* Adds party packets, but need to implement them.

* Party packets WIP

* Finishes party packets

* Rearrange movement namespaces and classes

* Finishes plant packets

* Code Formatting

* Fixes moving effects

* Code cleanup, eliminates equipinfo

* Adds more packets. Fixes bugs with various packets.

* Finishes mahjon packets

* Fixes mahjong packet

* Code cleanup

* Finishes mahjong packets

* Adds Map packets

* Add multifacet maps and charts

* Cleans up some packets with UTF8

* Optimizes packets

* Cleans up more packets. Moves the MessageHelper

* Removes assistant support. Removes extended protocol. Incorporates MapUO packets as normal packets.

* Updates protocol extensions packet receiver

* Fixes a few bugs. Fixes a few more packets.

* Code cleanup and fixing more packets

* Fixes packet effects

* Cleaned up more code

* Buff Icon cleanup

* Removed unused constructors

* Code Cleanup. Adds BoatHS Packets

* Moves house files. Updates house foundation packets.

* Deployment cleanup

* Fixes:

* Code cleanup

* More code cleanup

* More code cleanup

* Cleaned up BaseHouse

* Enforces styling

* Converts foreach to linq where possible.

* Dont need that

* Goals/Readme updates

* Removes 32bit support at the highest level. Turns on HRT by default.

* Code cleanup. Fixes extended features packet.

* Fixes various bugs

* Code cleanup

* Code cleanup

* Code cleanup. Fixes gump X/Y assignment.

* Code cleanup using |= operator

* More code cleanup

* Cleanup

* Fixes spacing issues. Thanks Visual Studio. You suck.

* Compiler error

* Fixes NPE from RunUO 2.7

* Renames ScriptCompiler to AssemblyHandler. Fixes packets. Updates README

* Fixes more packets. Stupid trailing nulls.

* Fixes various bugs.

* Fixes for gumps

* Fixes more gump stuff. Going to split it out later since it is getting insane

* Recoded the gump writing

* WIP

* *Added output path of scripts project to dev branch
*Activated debugging in code
2019-11-11 12:40:16 +01:00

445 lines
13 KiB
C#
Raw Blame History

using System.Collections.Generic;
using Server.Items;
using Server.Multis;
using Server.Network;
using Server.Spells.Chivalry;
using Server.Spells.Fourth;
using Server.Spells.Seventh;
namespace Server.Gumps
{
public class RunebookGump : Gump
{
public RunebookGump(Mobile from, Runebook book) : base(150, 200)
{
Book = book;
AddBackground();
AddIndex();
for (int page = 0; page < 8; ++page)
{
AddPage(2 + page);
AddButton(125, 14, 2205, 2205, 0, GumpButtonType.Page, 1 + page);
if (page < 7)
AddButton(393, 14, 2206, 2206, 0, GumpButtonType.Page, 3 + page);
for (int half = 0; half < 2; ++half)
AddDetails(page * 2 + half, half);
}
}
public Runebook Book{ get; }
public int GetMapHue(Map map)
{
if (map == Map.Trammel)
return 10;
if (map == Map.Felucca)
return 81;
if (map == Map.Ilshenar)
return 1102;
if (map == Map.Malas)
return 1102;
if (map == Map.Tokuno)
return 1154;
return 0;
}
public string GetName(string name)
{
if (name == null || (name = name.Trim()).Length <= 0)
return "(indescript)";
return name;
}
private void AddBackground()
{
AddPage(0);
// Background image
AddImage(100, 10, 2200);
// Two separators
for (int i = 0; i < 2; ++i)
{
int xOffset = 125 + i * 165;
AddImage(xOffset, 50, 57);
xOffset += 20;
for (int j = 0; j < 6; ++j, xOffset += 15)
AddImage(xOffset, 50, 58);
AddImage(xOffset - 5, 50, 59);
}
// First four page buttons
for (int i = 0, xOffset = 130, gumpID = 2225; i < 4; ++i, xOffset += 35, ++gumpID)
AddButton(xOffset, 187, gumpID, gumpID, 0, GumpButtonType.Page, 2 + i);
// Next four page buttons
for (int i = 0, xOffset = 300, gumpID = 2229; i < 4; ++i, xOffset += 35, ++gumpID)
AddButton(xOffset, 187, gumpID, gumpID, 0, GumpButtonType.Page, 6 + i);
// Charges
AddHtmlLocalized(140, 40, 80, 18, 1011296); // Charges:
AddHtml(220, 40, 30, 18, Book.CurCharges.ToString());
// Max charges
AddHtmlLocalized(300, 40, 100, 18, 1011297); // Max Charges:
AddHtml(400, 40, 30, 18, Book.MaxCharges.ToString());
}
private void AddIndex()
{
// Index
AddPage(1);
// Rename button
AddButton(125, 15, 2472, 2473, 1);
AddHtmlLocalized(158, 22, 100, 18, 1011299); // Rename book
// List of entries
List<RunebookEntry> entries = Book.Entries;
for (int i = 0; i < 16; ++i)
{
string desc;
int hue;
if (i < entries.Count)
{
desc = GetName(entries[i].Description);
hue = GetMapHue(entries[i].Map);
}
else
{
desc = "Empty";
hue = 0;
}
// Use charge button
AddButton(130 + i / 8 * 160, 65 + i % 8 * 15, 2103, 2104, 2 + i * 6 + 0);
// Description label
AddLabelCropped(145 + i / 8 * 160, 60 + i % 8 * 15, 115, 17, hue, desc);
}
// Turn page button
AddButton(393, 14, 2206, 2206, 0, GumpButtonType.Page, 2);
}
private void AddDetails(int index, int half)
{
// Use charge button
AddButton(130 + half * 160, 65, 2103, 2104, 2 + index * 6 + 0);
string desc;
int hue;
if (index < Book.Entries.Count)
{
RunebookEntry e = Book.Entries[index];
desc = GetName(e.Description);
hue = GetMapHue(e.Map);
// Location labels
int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false;
if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast, ref ySouth))
{
AddLabel(135 + half * 160, 80, 0, $"{yLat}<7D> {yMins}'{(ySouth ? "S" : "N")}");
AddLabel(135 + half * 160, 95, 0, $"{xLong}<7D> {xMins}'{(xEast ? "E" : "W")}");
}
// Drop rune button
AddButton(135 + half * 160, 115, 2437, 2438, 2 + index * 6 + 1);
AddHtmlLocalized(150 + half * 160, 115, 100, 18, 1011298); // Drop rune
// Set as default button
int defButtonID = e != Book.Default ? 2361 : 2360;
AddButton(160 + half * 140, 20, defButtonID, defButtonID, 2 + index * 6 + 2);
AddHtmlLocalized(175 + half * 140, 15, 100, 18, 1011300); // Set default
if (Core.AOS)
{
AddButton(135 + half * 160, 140, 2103, 2104, 2 + index * 6 + 3);
AddHtmlLocalized(150 + half * 160, 136, 110, 20, 1062722); // Recall
AddButton(135 + half * 160, 158, 2103, 2104, 2 + index * 6 + 4);
AddHtmlLocalized(150 + half * 160, 154, 110, 20, 1062723); // Gate Travel
AddButton(135 + half * 160, 176, 2103, 2104, 2 + index * 6 + 5);
AddHtmlLocalized(150 + half * 160, 172, 110, 20, 1062724); // Sacred Journey
}
else
{
// Recall button
AddButton(135 + half * 160, 140, 2271, 2271, 2 + index * 6 + 3);
// Gate button
AddButton(205 + half * 160, 140, 2291, 2291, 2 + index * 6 + 4);
}
}
else
{
desc = "Empty";
hue = 0;
}
// Description label
AddLabelCropped(145 + half * 160, 60, 115, 17, hue, desc);
}
public static bool HasSpell(Mobile from, int spellID) => Spellbook.Find(from, spellID)?.HasSpell(spellID) == true;
public override void OnResponse(NetState sender, RelayInfo info)
{
Mobile from = sender.Mobile;
if (Book.Deleted || !from.InRange(Book.GetWorldLocation(), Core.ML ? 3 : 1) || !DesignContext.Check(from))
{
Book.Openers.Remove(from);
return;
}
int buttonID = info.ButtonID;
if (buttonID == 1) // Rename book
{
if (!Book.IsLockedDown || from.AccessLevel >= AccessLevel.GameMaster)
{
from.SendLocalizedMessage(502414); // Please enter a title for the runebook:
from.Prompt = new InternalPrompt(Book);
}
else
{
Book.Openers.Remove(from);
from.SendLocalizedMessage(502413, null, 0x35); // That cannot be done while the book is locked down.
}
}
else
{
buttonID -= 2;
int index = buttonID / 6;
int type = buttonID % 6;
if (index >= 0 && index < Book.Entries.Count)
{
RunebookEntry e = Book.Entries[index];
switch (type)
{
case 0: // Use charges
{
if (Book.CurCharges <= 0)
{
from.CloseGump<RunebookGump>();
from.SendGump(new RunebookGump(from, Book));
from.SendLocalizedMessage(502412); // There are no charges left on that item.
}
else
{
int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false;
if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast,
ref ySouth))
{
string location =
$"{yLat}<7D> {yMins}'{(ySouth ? "S" : "N")}, {xLong}<7D> {xMins}'{(xEast ? "E" : "W")}";
from.SendMessage(location);
}
Book.OnTravel();
new RecallSpell(from, e, Book, Book).Cast();
Book.Openers.Remove(from);
}
break;
}
case 1: // Drop rune
{
if (!Book.IsLockedDown || from.AccessLevel >= AccessLevel.GameMaster)
{
Book.DropRune(from, e, index);
from.CloseGump<RunebookGump>();
if (!Core.ML)
from.SendGump(new RunebookGump(from, Book));
}
else
{
Book.Openers.Remove(from);
from.SendLocalizedMessage(502413, null,
0x35); // That cannot be done while the book is locked down.
}
break;
}
case 2: // Set default
{
if (Book.CheckAccess(from))
{
Book.Default = e;
from.CloseGump<RunebookGump>();
from.SendGump(new RunebookGump(from, Book));
from.SendLocalizedMessage(502417); // New default location set.
}
break;
}
case 3: // Recall
{
if (HasSpell(from, 31))
{
int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false;
if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast,
ref ySouth))
{
string location =
$"{yLat}<7D> {yMins}'{(ySouth ? "S" : "N")}, {xLong}<7D> {xMins}'{(xEast ? "E" : "W")}";
from.SendMessage(location);
}
Book.OnTravel();
new RecallSpell(from, e).Cast();
}
else
{
from.SendLocalizedMessage(500015); // You do not have that spell!
}
Book.Openers.Remove(from);
break;
}
case 4: // Gate
{
if (HasSpell(from, 51))
{
int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false;
if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins, ref xEast,
ref ySouth))
{
string location =
$"{yLat}<7D> {yMins}'{(ySouth ? "S" : "N")}, {xLong}<7D> {xMins}'{(xEast ? "E" : "W")}";
from.SendMessage(location);
}
Book.OnTravel();
new GateTravelSpell(from, e).Cast();
}
else
{
from.SendLocalizedMessage(500015); // You do not have that spell!
}
Book.Openers.Remove(from);
break;
}
case 5: // Sacred Journey
{
if (Core.AOS)
{
if (HasSpell(from, 209))
{
int xLong = 0, yLat = 0;
int xMins = 0, yMins = 0;
bool xEast = false, ySouth = false;
if (Sextant.Format(e.Location, e.Map, ref xLong, ref yLat, ref xMins, ref yMins,
ref xEast, ref ySouth))
{
string location =
$"{yLat}<7D> {yMins}'{(ySouth ? "S" : "N")}, {xLong}<7D> {xMins}'{(xEast ? "E" : "W")}";
from.SendMessage(location);
}
Book.OnTravel();
new SacredJourneySpell(from, e).Cast();
}
else
{
from.SendLocalizedMessage(500015); // You do not have that spell!
}
}
Book.Openers.Remove(from);
break;
}
}
}
else
{
Book.Openers.Remove(from);
}
}
}
private class InternalPrompt : Prompt
{
private Runebook m_Book;
public InternalPrompt(Runebook book) => m_Book = book;
public override void OnResponse(Mobile from, string text)
{
if (m_Book.Deleted || !from.InRange(m_Book.GetWorldLocation(), Core.ML ? 3 : 1))
return;
if (m_Book.CheckAccess(from))
{
m_Book.Description = Utility.FixHtml(text.Trim());
from.CloseGump<RunebookGump>();
from.SendGump(new RunebookGump(from, m_Book));
from.SendMessage("The book's title has been changed.");
}
else
{
m_Book.Openers.Remove(from);
from.SendLocalizedMessage(502416); // That cannot be done while the book is locked down.
}
}
public override void OnCancel(Mobile from)
{
from.SendLocalizedMessage(502415); // Request cancelled.
if (!m_Book.Deleted && from.InRange(m_Book.GetWorldLocation(), Core.ML ? 3 : 1))
{
from.CloseGump<RunebookGump>();
from.SendGump(new RunebookGump(from, m_Book));
}
}
}
}
}