ModernUO/Projects/UOContent/Misc/DoorGenerator.cs
Kamron Batman fffda53263
fix: Adds command help, webpage, and fixes issues with other commands (#1669)
### Summary

- Fixes `[AdvancedSearch` being accessible by players 😱 
- Adds `[GenCommands` to generate the same commands html page on https://muo.gg/commands.
- Fixes `[helpinfo` so all commands properly show up!

> [!WARNING]  
> ### Developer Warning:
> Commands must now be registered in the `Configure` bootup phase.
> If a command is not registered early enough, it may not be available to systems like [helpinfo
> that cache their information.

> [!NOTE]  
> ### Developer Note:
> Various commands related to generating content have been changed to _Developer_ and above access level.

### Screenshots
<img width="673" alt="image" src="https://github.com/modernuo/ModernUO/assets/3953314/b105b5c9-5eb4-4ace-93ff-1bfb31e7132f">

<img width="547" alt="image" src="https://github.com/modernuo/ModernUO/assets/3953314/e97487e8-47a5-4aa7-89cc-9fe3deda584d">
2024-02-10 00:19:19 -08:00

563 lines
14 KiB
C#

using Server.Items;
using Server.Network;
namespace Server
{
public static class DoorGenerator
{
private static readonly Rectangle2D[] m_BritRegions =
{
new(new Point2D(250, 750), new Point2D(775, 1330)),
new(new Point2D(525, 2095), new Point2D(925, 2430)),
new(new Point2D(1025, 2155), new Point2D(1265, 2310)),
new(new Point2D(1635, 2430), new Point2D(1705, 2508)),
new(new Point2D(1775, 2605), new Point2D(2165, 2975)),
new(new Point2D(1055, 3520), new Point2D(1570, 4075)),
new(new Point2D(2860, 3310), new Point2D(3120, 3630)),
new(new Point2D(2470, 1855), new Point2D(3950, 3045)),
new(new Point2D(3425, 990), new Point2D(3900, 1455)),
new(new Point2D(4175, 735), new Point2D(4840, 1600)),
new(new Point2D(2375, 330), new Point2D(3100, 1045)),
new(new Point2D(2100, 1090), new Point2D(2310, 1450)),
new(new Point2D(1495, 1400), new Point2D(1550, 1475)),
new(new Point2D(1085, 1520), new Point2D(1415, 1910)),
new(new Point2D(1410, 1500), new Point2D(1745, 1795)),
new(new Point2D(5120, 2300), new Point2D(6143, 4095))
};
private static readonly Rectangle2D[] m_IlshRegions =
{
new(new Point2D(0, 0), new Point2D(288 * 8, 200 * 8))
};
private static readonly Rectangle2D[] m_MalasRegions =
{
new(new Point2D(0, 0), new Point2D(320 * 8, 256 * 8))
};
private static readonly int[] m_SouthFrames =
{
0x0006,
0x0008,
0x000B,
0x001A,
0x001B,
0x001F,
0x0038,
0x0057,
0x0059,
0x005B,
0x005D,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0091,
0x0094,
0x0096,
0x0099,
0x00A6,
0x00A7,
0x00AA,
0x00AE,
0x00B0,
0x00B3,
0x00C7,
0x00C9,
0x00F8,
0x00FA,
0x00FD,
0x00FE,
0x0100,
0x0103,
0x0104,
0x0106,
0x0109,
0x0127,
0x0129,
0x012B,
0x012D,
0x012F,
0x0131,
0x0132,
0x0134,
0x0135,
0x0137,
0x0139,
0x013B,
0x014C,
0x014E,
0x014F,
0x0151,
0x0153,
0x0155,
0x0157,
0x0158,
0x015A,
0x015D,
0x015E,
0x015F,
0x0162,
0x01CF,
0x01D1,
0x01D4,
0x01FF,
0x0204,
0x0206,
0x0208,
0x020A
};
private static readonly int[] m_NorthFrames =
{
0x0006,
0x0008,
0x000D,
0x001A,
0x001B,
0x0020,
0x003A,
0x0057,
0x0059,
0x005B,
0x005D,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0091,
0x0094,
0x0096,
0x0099,
0x00A6,
0x00A7,
0x00AC,
0x00AE,
0x00B0,
0x00C7,
0x00C9,
0x00F8,
0x00FA,
0x00FD,
0x00FE,
0x0100,
0x0103,
0x0104,
0x0106,
0x0109,
0x0127,
0x0129,
0x012B,
0x012D,
0x012F,
0x0131,
0x0132,
0x0134,
0x0135,
0x0137,
0x0139,
0x013B,
0x014C,
0x014E,
0x014F,
0x0151,
0x0153,
0x0155,
0x0157,
0x0158,
0x015A,
0x015D,
0x015E,
0x015F,
0x0162,
0x01CF,
0x01D1,
0x01D4,
0x01FF,
0x0201,
0x0204,
0x0208,
0x020A
};
private static readonly int[] m_EastFrames =
{
0x0007,
0x000A,
0x001A,
0x001C,
0x001E,
0x0037,
0x0058,
0x0059,
0x005C,
0x005E,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0092,
0x0095,
0x0097,
0x0098,
0x00A6,
0x00A8,
0x00AB,
0x00AE,
0x00AF,
0x00B2,
0x00C7,
0x00C8,
0x00EA,
0x00F8,
0x00F9,
0x00FC,
0x00FE,
0x00FF,
0x0102,
0x0104,
0x0105,
0x0108,
0x0127,
0x0128,
0x012B,
0x012C,
0x012E,
0x0130,
0x0132,
0x0133,
0x0135,
0x0136,
0x0138,
0x013A,
0x014C,
0x014D,
0x014F,
0x0150,
0x0152,
0x0154,
0x0156,
0x0158,
0x0159,
0x015C,
0x015E,
0x0160,
0x0163,
0x01CF,
0x01D0,
0x01D3,
0x01FF,
0x0203,
0x0205,
0x0207,
0x0209
};
private static readonly int[] m_WestFrames =
{
0x0007,
0x000C,
0x001A,
0x001C,
0x0021,
0x0039,
0x0058,
0x0059,
0x005C,
0x005E,
0x0080,
0x0081,
0x0082,
0x0084,
0x0090,
0x0092,
0x0095,
0x0097,
0x0098,
0x00A6,
0x00A8,
0x00AD,
0x00AE,
0x00AF,
0x00B5,
0x00C7,
0x00C8,
0x00EA,
0x00F8,
0x00F9,
0x00FC,
0x00FE,
0x00FF,
0x0102,
0x0104,
0x0105,
0x0108,
0x0127,
0x0128,
0x012C,
0x012E,
0x0130,
0x0132,
0x0133,
0x0135,
0x0136,
0x0138,
0x013A,
0x014C,
0x014D,
0x014F,
0x0150,
0x0152,
0x0154,
0x0156,
0x0158,
0x0159,
0x015C,
0x015E,
0x0160,
0x0163,
0x01CF,
0x01D0,
0x01D3,
0x01FF,
0x0200,
0x0203,
0x0207,
0x0209
};
private static Map m_Map;
private static int m_Count;
public static void Configure()
{
CommandSystem.Register("DoorGen", AccessLevel.Developer, DoorGen_OnCommand);
}
[Usage("DoorGen"), Description("Generates doors by analyzing the map. Slow.")]
public static void DoorGen_OnCommand(CommandEventArgs e)
{
Generate();
}
public static void Generate()
{
World.Broadcast(0x35, true, "Generating doors, please wait.");
NetState.FlushAll();
m_Map = Map.Trammel;
m_Count = 0;
for (var i = 0; i < m_BritRegions.Length; ++i)
{
Generate(m_BritRegions[i]);
}
var trammelCount = m_Count;
m_Map = Map.Felucca;
m_Count = 0;
for (var i = 0; i < m_BritRegions.Length; ++i)
{
Generate(m_BritRegions[i]);
}
var feluccaCount = m_Count;
m_Map = Map.Ilshenar;
m_Count = 0;
for (var i = 0; i < m_IlshRegions.Length; ++i)
{
Generate(m_IlshRegions[i]);
}
var ilshenarCount = m_Count;
m_Map = Map.Malas;
m_Count = 0;
for (var i = 0; i < m_MalasRegions.Length; ++i)
{
Generate(m_MalasRegions[i]);
}
var malasCount = m_Count;
World.Broadcast(
0x35,
true,
$"Door generation complete. Trammel: {trammelCount}; Felucca: {feluccaCount}; Ilshenar: {ilshenarCount}; Malas: {malasCount};"
);
}
public static bool IsFrame(int id, int[] list)
{
if (id > list[^1])
{
return false;
}
for (var i = 0; i < list.Length; ++i)
{
var delta = id - list[i];
if (delta < 0)
{
return false;
}
if (delta == 0)
{
return true;
}
}
return false;
}
public static bool IsNorthFrame(int id) => IsFrame(id, m_NorthFrames);
public static bool IsSouthFrame(int id) => IsFrame(id, m_SouthFrames);
public static bool IsWestFrame(int id) => IsFrame(id, m_WestFrames);
public static bool IsEastFrame(int id) => IsFrame(id, m_EastFrames);
public static bool IsEastFrame(int x, int y, int z)
{
foreach (var tile in m_Map.Tiles.GetStaticTiles(x, y))
{
if (tile.Z == z && IsEastFrame(tile.ID))
{
return true;
}
}
return false;
}
public static bool IsSouthFrame(int x, int y, int z)
{
foreach (var tile in m_Map.Tiles.GetStaticTiles(x, y))
{
if (tile.Z == z && IsSouthFrame(tile.ID))
{
return true;
}
}
return false;
}
public static BaseDoor AddDoor(int x, int y, int z, DoorFacing facing)
{
var doorZ = z;
var doorTop = doorZ + 20;
if (!m_Map.CanFit(x, y, z, 16, false, false))
{
return null;
}
if (y == 1743 && x >= 1343 && x <= 1344)
{
return null;
}
if (y == 1679 && x >= 1392 && x <= 1393)
{
return null;
}
if (x == 1320 && y >= 1618 && y <= 1640)
{
return null;
}
if (x == 1383 && y >= 1642 && y <= 1643)
{
return null;
}
BaseDoor door = new DarkWoodDoor(facing);
door.MoveToWorld(new Point3D(x, y, z), m_Map);
++m_Count;
return door;
}
public static void Generate(Rectangle2D region)
{
for (var rx = 0; rx < region.Width; ++rx)
{
for (var ry = 0; ry < region.Height; ++ry)
{
var vx = rx + region.X;
var vy = ry + region.Y;
foreach (var tile in m_Map.Tiles.GetStaticTiles(vx, vy))
{
var id = tile.ID;
var z = tile.Z;
if (IsWestFrame(id))
{
if (IsEastFrame(vx + 2, vy, z))
{
AddDoor(vx + 1, vy, z, DoorFacing.WestCW);
}
else if (IsEastFrame(vx + 3, vy, z))
{
var first = AddDoor(vx + 1, vy, z, DoorFacing.WestCW);
var second = AddDoor(vx + 2, vy, z, DoorFacing.EastCCW);
if (first != null && second != null)
{
first.Link = second;
second.Link = first;
}
else
{
first?.Delete();
second?.Delete();
}
}
}
else if (IsNorthFrame(id))
{
if (IsSouthFrame(vx, vy + 2, z))
{
AddDoor(vx, vy + 1, z, DoorFacing.SouthCW);
}
else if (IsSouthFrame(vx, vy + 3, z))
{
var first = AddDoor(vx, vy + 1, z, DoorFacing.NorthCCW);
var second = AddDoor(vx, vy + 2, z, DoorFacing.SouthCW);
if (first != null && second != null)
{
first.Link = second;
second.Link = first;
}
else
{
first?.Delete();
second?.Delete();
}
}
}
}
}
}
}
}
}