ModernUO/Projects/UOContent/Items/Construction/Doors/HouseDoors.cs
Kamron Batman f58117a877
fix: Moves ContextMenu out of core, streamlines code, fixes bugs (#1873)
## Summary
- Removes allocation of a `List<ContextMenuEntry>` every time a context menu is created.
- Moves packet/context menu creation logic out of the core
- Fixes tame entry

## BREAKING CHANGE
> [!Important]
> **Developer Note**
> ```cs
> public virtual void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
> ```
> and similar functions changed to
> ```cs
> public virtual void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
> ```
2024-07-20 21:33:23 -07:00

220 lines
5.3 KiB
C#

using ModernUO.Serialization;
using Server.Collections;
using Server.ContextMenus;
using Server.Gumps;
using Server.Multis;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class MetalHouseDoor : BaseHouseDoor
{
[Constructible]
public MetalHouseDoor(DoorFacing facing) : base(
facing,
0x675 + 2 * (int)facing,
0x676 + 2 * (int)facing,
0xEC,
0xF3,
GetOffset(facing)
)
{
}
}
[SerializationGenerator(0, false)]
public partial class DarkWoodHouseDoor : BaseHouseDoor
{
[Constructible]
public DarkWoodHouseDoor(DoorFacing facing) : base(
facing,
0x6A5 + 2 * (int)facing,
0x6A6 + 2 * (int)facing,
0xEA,
0xF1,
GetOffset(facing)
)
{
}
}
[SerializationGenerator(0, false)]
public partial class GenericHouseDoor : BaseHouseDoor
{
[Constructible]
public GenericHouseDoor(DoorFacing facing, int baseItemID, int openedSound, int closedSound, bool autoAdjust = true)
: base(
facing,
baseItemID + (autoAdjust ? 2 * (int)facing : 0),
baseItemID + 1 + (autoAdjust ? 2 * (int)facing : 0),
openedSound,
closedSound,
GetOffset(facing)
)
{
}
}
[SerializationGenerator(2, false)]
public abstract partial class BaseHouseDoor : BaseDoor, ISecurable
{
[SerializedIgnoreDupe]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private SecureLevel _level;
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private DoorFacing _facing;
public BaseHouseDoor(DoorFacing facing, int closedID, int openedID, int openedSound, int closedSound, Point3D offset)
: base(closedID, openedID, openedSound, closedSound, offset)
{
_facing = facing;
_level = SecureLevel.Anyone;
}
public override void GetContextMenuEntries(Mobile from, ref PooledRefList<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, ref list);
SetSecureLevelEntry.AddTo(from, this, ref list);
}
public BaseHouse FindHouse()
{
Point3D loc;
if (Open)
{
loc = new Point3D(X - Offset.X, Y - Offset.Y, Z - Offset.Z);
}
else
{
loc = Location;
}
return BaseHouse.FindHouseAt(loc, Map, 20);
}
public bool CheckAccess(Mobile m)
{
var house = FindHouse();
if (house == null)
{
return false;
}
if (!house.IsAosRules)
{
return true;
}
if (house.Public ? house.IsBanned(m) : !house.HasAccess(m))
{
return false;
}
return house.HasSecureAccess(m, Level);
}
public override void OnOpened(Mobile from)
{
var house = FindHouse();
if (house?.IsFriend(from) == true && from.AccessLevel == AccessLevel.Player && house.RefreshDecay())
{
from.SendLocalizedMessage(1043293); // Your house's age and contents have been refreshed.
}
if (house?.Public == true && !house.IsFriend(from))
{
house.Visits++;
}
}
public override bool UseLocks() => FindHouse()?.IsAosRules != true;
public override void Use(Mobile from)
{
if (!CheckAccess(from))
{
from.SendLocalizedMessage(1061637); // You are not allowed to access this.
}
else
{
base.Use(from);
}
}
private void Deserialize(IGenericReader reader, int version)
{
_level = (SecureLevel)reader.ReadInt();
_facing = (DoorFacing)reader.ReadInt();
}
public override bool IsInside(Mobile from)
{
int x, y, w, h;
const int r = 2;
const int bs = r * 2 + 1;
const int ss = r + 1;
switch (Facing)
{
case DoorFacing.WestCW:
case DoorFacing.EastCCW:
{
x = -r;
y = -r;
w = bs;
h = ss;
break;
}
case DoorFacing.EastCW:
case DoorFacing.WestCCW:
{
x = -r;
y = 0;
w = bs;
h = ss;
break;
}
case DoorFacing.SouthCW:
case DoorFacing.NorthCCW:
{
x = -r;
y = -r;
w = ss;
h = bs;
break;
}
case DoorFacing.NorthCW:
case DoorFacing.SouthCCW:
{
x = 0;
y = -r;
w = ss;
h = bs;
break;
}
// No way to test the 'insideness' of SE Sliding doors on OSI, so leaving them default to false until further information gained
default:
{
return false;
}
}
var rx = from.X - X;
var ry = from.Y - Y;
var az = (from.Z - Z).Abs();
return rx >= x && rx < x + w && ry >= y && ry < y + h && az <= 4;
}
}