ModernUO/Projects/UOContent/Engines/Spawners/SpawnerGump.cs
Quick 6601101e2e
fix: Updates spawner gump visuals! Thanks Quick! (#1102)
This update changes the default RunUO SpawnerGump's overall look and feel and expands slightly some functionality. Inspired by the XmlSpawner gump.

![image](https://user-images.githubusercontent.com/577652/176790254-cc1fb6bb-b281-49c9-a7cd-ec5376a69921.png)

![image](https://user-images.githubusercontent.com/577652/176790147-408ef682-9670-4753-872c-db843be1ab05.png)

1. The name of the spawner is displayed
2. This displays the total current spawn with the current allowed max spawn
3. Cleans up the display of the current count and the max count
4. The ability to turn on/off the spawner
5. Several changes to buttons 
   - Simple Save and Cancel instead of Okay, Cancel and Apply.
   - Props button to display spawner properties
   - Goto button to teleport to the spawner
   - Reset button that will clear all the spawned mobs and turn off the spawner
   - Repositioned the buttons to make a little more sense
6. The sum of all the max spawn values per entry, from all pages
2022-06-30 20:48:54 -07:00

447 lines
14 KiB
C#

using Server.Collections;
using Server.Gumps;
using Server.Network;
namespace Server.Engines.Spawners;
public class SpawnerGump : Gump
{
private readonly BaseSpawner _spawner;
private SpawnerEntry _entry;
private int _page;
public SpawnerGump(BaseSpawner spawner, SpawnerEntry focusentry = null, int page = 0) : base(50, 50)
{
_spawner = spawner;
_entry = focusentry;
_page = page;
AddPage(0);
AddBackground(0, 0, 346, 400 + (_entry != null ? 44 : 0), 5054);
AddAlphaRegion(0, 0, 346, 400 + (_entry != null ? 44 : 0));
AddHtml(240, 1, 250, 20, "<BASEFONT COLOR=#F4F4F4>#</BASEFONT>");
AddHtml(271, 1, 250, 20, "<BASEFONT COLOR=#F4F4F4>Max</BASEFONT>");
AddHtml(311, 1, 250, 20, "<BASEFONT COLOR=#F4F4F4>Prb</BASEFONT>");
// AddLabel( 95, 1, 0, "Creatures List" );
var offset = 0;
for (var i = 0; i < 13; i++)
{
var textIndex = i * 5;
var entryIndex = _page * 13 + i;
SpawnerEntry entry = null;
if (entryIndex < spawner.Entries.Count)
{
entry = _spawner.Entries[entryIndex];
}
if (entry == null || _entry != entry)
{
AddButton(
5,
22 * i + 21 + offset,
entry != null ? 0xFBA : 0xFA5,
entry != null ? 0xFBC : 0xFA7,
GetButtonID(2, i * 2)
); // Expand
}
else
{
AddButton(
5,
22 * i + 21 + offset,
0xFBB,
0xFBC,
GetButtonID(2, i * 2)
); // Unexpand
}
AddButton(38, 22 * i + 21 + offset, 0xFA2, 0xFA4, GetButtonID(2, 1 + i * 2)); // Delete
AddImageTiled(71, 22 * i + 20 + offset, 161, 23, 0xA40); // creature text box
AddImageTiled(72, 22 * i + 21 + offset, 159, 21, 0xBBC); // creature text box
AddImageTiled(235, 22 * i + 20 + offset, 35, 23, 0xA40); // count html label
AddImageTiled(236, 22 * i + 21 + offset, 33, 21, 0xE14); // count html label
AddImageTiled(267, 22 * i + 20 + offset, 35, 23, 0xA40); // maxcount text box
AddImageTiled(268, 22 * i + 21 + offset, 33, 21, 0xBBC); // maxcount text box
AddImageTiled(305, 22 * i + 20 + offset, 35, 23, 0xA40); // probability text box
AddImageTiled(306, 22 * i + 21 + offset, 33, 21, 0xBBC); // probability text box
string name;
string probability;
string maxCount;
var flags = EntryFlags.None;
if (entry != null)
{
name = entry.SpawnedName;
probability = entry.SpawnedProbability.ToString();
maxCount = entry.SpawnedMaxCount.ToString();
flags = entry.Valid;
var count = spawner.CountSpawns(entry);
AddHtml(235, 22 * i + 20 + offset + 1, 35, 15, $"<BASEFONT COLOR={GetCountColor(count, entry.SpawnedMaxCount)}><div align=RIGHT>{count}<BASEFONT COLOR=#F4F4F4>/</BASEFONT></div></BASEFONT>");
}
else
{
name = "";
probability = "";
maxCount = "";
}
// creature
AddTextEntry(
75,
22 * i + 21 + offset,
156,
21,
(flags & EntryFlags.InvalidType) != 0 ? 33 : 0,
textIndex,
name
);
AddTextEntry(270, 22 * i + 21 + offset, 30, 21, 0, textIndex + 1, maxCount); // max count
AddTextEntry(308, 22 * i + 21 + offset, 30, 21, 0, textIndex + 2, probability); // probability
if (entry != null && _entry == entry)
{
AddLabel(5, 22 * i + 42, 0x384, "Params");
AddImageTiled(55, 22 * i + 42, 253, 23, 0xA40); // Parameters
AddImageTiled(56, 22 * i + 43, 251, 21, 0xBBC); // Parameters
AddLabel(5, 22 * i + 64, 0x384, "Props");
AddImageTiled(55, 22 * i + 64, 253, 23, 0xA40); // Properties
AddImageTiled(56, 22 * i + 65, 251, 21, 0xBBC); // Properties
AddTextEntry(
59,
22 * i + 42,
248,
21,
(flags & EntryFlags.InvalidParams) != 0 ? 33 : 0,
textIndex + 3,
entry.Parameters
); // parameters
AddTextEntry(
59,
22 * i + 62,
248,
21,
(flags & EntryFlags.InvalidProps) != 0 ? 33 : 0,
textIndex + 4,
entry.Properties
); // properties
offset += 44;
}
}
if (spawner.Running)
{
AddButton(5, 312 + offset, 0x2A4E, 0x2A3A, GetButtonID(1, 6));
AddLabel(38, 317 + offset, 0x384, "On");
}
else
{
AddButton(5, 312 + offset, 0x2A62, 0x2A3A, GetButtonID(1, 7));
AddLabel(38, 317 + offset, 0x384, "Off");
}
var totalSpawned = 0;
var totalSpawns = 0;
var totalWeight = 0;
foreach (SpawnerEntry spawnerEntry in _spawner.Entries)
{
totalSpawns += spawnerEntry.SpawnedMaxCount;
totalSpawned += spawner.CountSpawns(spawnerEntry);
totalWeight += spawnerEntry.SpawnedProbability;
}
AddHtml(270, 308 + offset, 35, 20, $"<BASEFONT COLOR=#F4F4F4><CENTER>{totalSpawns}</CENTER></BASEFONT>");
AddHtml(308, 308 + offset, 35, 20, $"<BASEFONT COLOR=#F4F4F4><CENTER>{totalWeight}</CENTER></BASEFONT>");
AddHtml(5, 1, 161, 20, $"<BASEFONT COLOR=#FFEA00>{spawner.Name}</BASEFONT><BASEFONT COLOR={GetCountColor(totalSpawned, spawner.Count)}> ({totalSpawned}/{spawner.Count})</BASEFONT>");
AddButton(5, 347 + offset, 0xFAB, 0xFAD, GetButtonID(1, 2));
AddLabel(38, 347 + offset, 0x384, "Props");
AddButton(5, 369 + offset, 0xFAE, 0xFAF, GetButtonID(1, 8));
AddLabel(38, 369 + offset, 0x384, "Goto");
AddButton(90, 325 + offset, 0xFA2, 0xFA3, GetButtonID(1, 9));
AddLabel(123, 325 + offset, 0x384, "Reset");
AddButton(90, 347 + offset, 0xFB4, 0xFB6, GetButtonID(1, 3));
AddLabel(123, 347 + offset, 0x384, "Bring Home");
AddButton(90, 369 + offset, 0xFA8, 0xFAA, GetButtonID(1, 4));
AddLabel(123, 369 + offset, 0x384, "Total Respawn");
AddButton(260, 347 + offset, 0xFB7, 0xFB9, GetButtonID(1, 5));
AddLabel(293, 347 + offset, 0x384, "Save");
AddButton(260, 369 + offset, 0xFB1, 0xFB3, 0);
AddLabel(293, 369 + offset, 0x384, "Cancel");
if (_page > 0)
{
AddButton(200, 308 + offset, 0x15E3, 0x15E7, GetButtonID(1, 0));
}
else
{
AddImage(200, 308 + offset, 0x25EA);
}
if ((_page + 1) * 13 <= _spawner.Entries.Count)
{
AddButton(217, 308 + offset, 0x15E1, 0x15E5, GetButtonID(1, 1));
}
else
{
AddImage(217, 308 + offset, 0x25E6);
}
}
public int GetButtonID(int type, int index) => 1 + index * 10 + type;
private static string GetCountColor(int count, int maxCount) =>
((double) count / maxCount) switch
{
<= 0.25 => "#DE3163", // red
<= 0.50 => "#FF7F50", // orange
<= 0.75 => "#DFFF00", // yellow
<= 1 => "#00FF00", // green
_ => "#F4F4F4" // white
};
public void CreateArray(RelayInfo info, Mobile from, BaseSpawner spawner)
{
var ocount = spawner.Entries.Count;
using var queue = PooledRefQueue<SpawnerEntry>.Create();
for (var i = 0; i < 13; i++)
{
var index = i * 5;
var entryindex = _page * 13 + i;
var cte = info.GetTextEntry(index);
var mte = info.GetTextEntry(index + 1);
var poste = info.GetTextEntry(index + 2);
var parmte = info.GetTextEntry(index + 3);
var propte = info.GetTextEntry(index + 4);
if (cte == null)
{
continue;
}
var str = cte.Text.Trim().ToLower();
if (str.Length > 0)
{
var type = AssemblyHandler.FindTypeByName(str);
if (type == null)
{
from.SendMessage("{0} is not a valid type name for entry #{1}.", str, i);
return;
}
SpawnerEntry entry;
if (entryindex < ocount)
{
entry = spawner.Entries[entryindex];
entry.SpawnedName = str;
if (mte != null)
{
entry.SpawnedMaxCount = Utility.ToInt32(mte.Text.Trim());
}
if (poste != null)
{
entry.SpawnedProbability = Utility.ToInt32(poste.Text.Trim());
}
}
else
{
var maxcount = 1;
var probcount = 100;
if (mte != null)
{
maxcount = Utility.ToInt32(mte.Text.Trim());
}
if (poste != null)
{
probcount = Utility.ToInt32(poste.Text.Trim());
}
entry = spawner.AddEntry(str, probcount, maxcount);
}
if (parmte != null)
{
entry.Parameters = parmte.Text.Trim();
}
if (propte != null)
{
entry.Properties = propte.Text.Trim();
}
}
else if (entryindex < ocount && spawner.Entries[entryindex] != null)
{
queue.Enqueue(spawner.Entries[entryindex]);
}
}
while (queue.Count > 0)
{
spawner.RemoveEntry(queue.Dequeue());
}
if (ocount == 0 && spawner.Entries.Count > 0)
{
spawner.Start();
}
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (_spawner.Deleted)
{
return;
}
var val = info.ButtonID - 1;
if (val < 0)
{
return;
}
var type = val % 10;
var index = val / 10;
switch (type)
{
case 0: // Cancel
{
return;
}
case 1:
{
switch (index)
{
case 0:
{
if (_spawner.Entries != null && _page > 0)
{
_page--;
_entry = null;
}
break;
}
case 1:
{
if ((_page + 1) * 13 <= _spawner.Entries?.Count)
{
_page++;
_entry = null;
}
break;
}
case 2: // Props
{
state.Mobile.SendGump(new PropertiesGump(state.Mobile, _spawner));
break;
}
case 3: // Bring Home
{
_spawner.BringToHome();
break;
}
case 4: // Complete respawn
{
_spawner.Respawn();
break;
}
case 5: // Save
{
CreateArray(info, state.Mobile, _spawner);
break;
}
case 6: // On button
{
_spawner.Running = false;
break;
}
case 7: // Off button
{
_spawner.Running = true;
break;
}
case 8: // Goto
{
state.Mobile.MoveToWorld(_spawner.Location, _spawner.Map);
break;
}
case 9: // Reset
{
_spawner.Reset();
break;
}
}
break;
}
case 2:
{
var entryIndex = index / 2 + _page * 13;
var buttonType = index % 2;
if (entryIndex >= 0 && entryIndex < _spawner.Entries.Count)
{
var entry = _spawner.Entries[entryIndex];
if (buttonType == 0) // Spawn creature
{
_entry = _entry != entry ? entry : null;
}
else // Remove creatures
{
_spawner.RemoveSpawn(entryIndex);
}
}
CreateArray(info, state.Mobile, _spawner);
break;
}
}
if (_entry != null && _spawner.Entries?.Contains(_entry) == true)
{
state.Mobile.SendGump(new SpawnerGump(_spawner, _entry, _page));
}
else
{
state.Mobile.SendGump(new SpawnerGump(_spawner, null, _page));
}
}
}