ModernUO/Projects/UOContent/Misc/DoorGenerator.cs
Kamron Batman 8903028b5f
fix(core): Tightens the network stack (#479)
- [X] Removes network pause/resume
- [X] Adds back packet profiler
- [X] Adds state machine to keep track and trace netstates
- [X] Changes NetState.Running back to using an interlock exchange
- [X] Adds preliminary packet throttling support


### Packet Throttling
- `[GetThrottle <packetId>` to get the delay in milliseconds for that packet
- `[SetThrottle <packetId> <delay>` to set the delay in milliseconds for that packet
The settings are saved to `Configuration/throttles.json`
2021-02-07 23:30:56 -08:00

579 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 Initialize()
{
CommandSystem.Register("DoorGen", AccessLevel.Administrator, 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: {0}; Felucca: {1}; Ilshenar: {2}; Malas: {3};",
trammelCount,
feluccaCount,
ilshenarCount,
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)
{
var tiles = m_Map.Tiles.GetStaticTiles(x, y);
for (var i = 0; i < tiles.Length; ++i)
{
var tile = tiles[i];
if (tile.Z == z && IsEastFrame(tile.ID))
{
return true;
}
}
return false;
}
public static bool IsSouthFrame(int x, int y, int z)
{
var tiles = m_Map.Tiles.GetStaticTiles(x, y);
for (var i = 0; i < tiles.Length; ++i)
{
var tile = tiles[i];
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;
var tiles = m_Map.Tiles.GetStaticTiles(vx, vy);
for (var i = 0; i < tiles.Length; ++i)
{
var tile = tiles[i];
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();
}
}
}
}
}
}
}
}
}