using System.Collections.Generic;
namespace AcDream.Core.Items;
///
/// AP-129 (Campaign P Slice P4 review fix, 2026-07-30). Retail
/// RestrictionDB — the access-control list carried on a house/dwelling
/// object's PublicWeenieDesc (WeenieHeaderFlag.HouseRestrictions,
/// 0x04000000) and refreshed live via House_UpdateRestrictions (0x0248).
/// Wire shape confirmed verbatim against
/// references/Chorizite.ACProtocol/Chorizite.ACProtocol/Types/RestrictionDB.generated.cs
/// and protocol.xml:6270-6275: uint Version, uint Flags (0=private,
/// 1=open), ObjectId MonarchId, PHashTable<ObjectId,uint> Permissions.
///
/// Wire Flags != 0 — retail's _bitmask
/// & 1. When true, every mover is admitted regardless of the guest
/// list.
/// Wire MonarchId — retail
/// _monarch_iid. A mover whose own monarch matches this id is admitted
/// (allegiance-wide access), independent of the guest list.
/// Wire Permissions — guid to permission value
/// (0 = dwelling access only, 1 = storage access also). Retail's
/// IsAllowedIn only consults key membership for entry; the permission
/// value is preserved for wire fidelity but not consulted here.
public sealed record HouseRestrictionRecord(
bool OpenToPublic,
uint AllegianceMonarchId,
IReadOnlyDictionary Guests)
{
///
/// Verbatim port of retail RestrictionDB::IsAllowedIn
/// (named-retail pc:444493-444516, 0x005ae8f0):
/// if ((_bitmask & 1) == 0) { if (_monarch_iid == 0 || arg3 !=
/// _monarch_iid) { if (arg2 == 0) return 0; if (!table.find(arg2)) return
/// 0; } } return 1; — open bit set, OR mover shares the house's
/// allegiance monarch, OR mover's own guid is a table member.
///
public bool IsAllowedIn(uint moverId, uint moverMonarchId)
{
if (OpenToPublic) return true;
if (AllegianceMonarchId != 0 && moverMonarchId == AllegianceMonarchId) return true;
return moverId != 0 && Guests.ContainsKey(moverId);
}
}