diff --git a/EXILED/Exiled.API/Enums/AdminToyType.cs b/EXILED/Exiled.API/Enums/AdminToyType.cs index 1ca81b5e01..1ddad225ed 100644 --- a/EXILED/Exiled.API/Enums/AdminToyType.cs +++ b/EXILED/Exiled.API/Enums/AdminToyType.cs @@ -37,5 +37,15 @@ public enum AdminToyType /// Capybara toy. /// Capybara, + + /// + /// InvisibleInteractable toy. + /// + InvisibleInteractableToy, + + /// + /// Camera Object toy. + /// + CameraToy, } } \ No newline at end of file diff --git a/EXILED/Exiled.API/Enums/CameraType.cs b/EXILED/Exiled.API/Enums/CameraType.cs index 80c1b7cb89..8b064b045f 100644 --- a/EXILED/Exiled.API/Enums/CameraType.cs +++ b/EXILED/Exiled.API/Enums/CameraType.cs @@ -123,6 +123,7 @@ public enum CameraType Hcz173ContChamber, [System.Obsolete("This Camera no longer exist.")] Hcz173Hallway, + [System.Obsolete("This Camera no longer exist.")] HczCurve, HczJunkMain, HczJunkHallway, @@ -137,6 +138,19 @@ public enum CameraType HczWarheadPortElevator, HczMicroHIDLab, HczPipesMain, + HczScp127Lab, + HczScp127Containment, + HczServersUpperStorage, + HczLowerServerStorage, + HczServerStaircase, + #endregion + + #region custom + EzArmCameraToy, + EzCameraToy, + HczCameraToy, + LczCameraToy, + SzCameraToy, #endregion } } diff --git a/EXILED/Exiled.API/Enums/DamageType.cs b/EXILED/Exiled.API/Enums/DamageType.cs index 602ad2f740..ae93c5c020 100644 --- a/EXILED/Exiled.API/Enums/DamageType.cs +++ b/EXILED/Exiled.API/Enums/DamageType.cs @@ -269,5 +269,10 @@ public enum DamageType /// Damage caused by . /// SnowBall, + + /// + /// Damage caused by . + /// + Scp127, } } \ No newline at end of file diff --git a/EXILED/Exiled.API/Enums/DoorType.cs b/EXILED/Exiled.API/Enums/DoorType.cs index ee5655f77e..4e3cb644f5 100644 --- a/EXILED/Exiled.API/Enums/DoorType.cs +++ b/EXILED/Exiled.API/Enums/DoorType.cs @@ -167,11 +167,20 @@ public enum DoorType /// /// Represents the HID_UPPER door. /// + [Obsolete("This Door has been renamed too HID_LAB.")] HIDUpper, + /// + /// Represents the HID_LAB door. + /// +#pragma warning disable CS0618 + HIDLab = HIDUpper, +#pragma warning restore CS0618 + /// /// Represents the HID_LOWER door. /// + [Obsolete("This Door has been removed from the game.")] HIDLower, /// @@ -320,5 +329,15 @@ public enum DoorType /// Represents the ESCAPE_FINAL door. /// EscapeFinal, + + /// + /// Represents the Elevator door for . + /// + ElevatorServerRoom, + + /// + /// Represents the HCZ_127_LAB door. + /// + Hcz127Lab, } } \ No newline at end of file diff --git a/EXILED/Exiled.API/Enums/ElevatorType.cs b/EXILED/Exiled.API/Enums/ElevatorType.cs index 02783b7180..ebccf5b356 100644 --- a/EXILED/Exiled.API/Enums/ElevatorType.cs +++ b/EXILED/Exiled.API/Enums/ElevatorType.cs @@ -48,5 +48,10 @@ public enum ElevatorType : byte /// Light Containment Zone checkpoint B elevator. /// LczB, + + /// + /// Heavy Containment Zone ServerRoom elevator. + /// + ServerRoom, } } \ No newline at end of file diff --git a/EXILED/Exiled.API/Enums/FirearmType.cs b/EXILED/Exiled.API/Enums/FirearmType.cs index aa814136fa..05cccf2388 100644 --- a/EXILED/Exiled.API/Enums/FirearmType.cs +++ b/EXILED/Exiled.API/Enums/FirearmType.cs @@ -89,5 +89,10 @@ public enum FirearmType /// Represents the . /// A7, + + /// + /// Represents the . + /// + Scp127, } } diff --git a/EXILED/Exiled.API/Enums/GeneratorState.cs b/EXILED/Exiled.API/Enums/GeneratorState.cs index 1b434908b0..4f0a9b7111 100644 --- a/EXILED/Exiled.API/Enums/GeneratorState.cs +++ b/EXILED/Exiled.API/Enums/GeneratorState.cs @@ -20,9 +20,9 @@ namespace Exiled.API.Enums public enum GeneratorState : byte { /// - /// Generator is locked. + /// Generator is doing nothing. /// - None = 1, + None = 0, /// /// Generator is unlocked. diff --git a/EXILED/Exiled.API/Enums/GlassType.cs b/EXILED/Exiled.API/Enums/GlassType.cs index 9857ed2a82..4144c7fd98 100644 --- a/EXILED/Exiled.API/Enums/GlassType.cs +++ b/EXILED/Exiled.API/Enums/GlassType.cs @@ -69,5 +69,10 @@ public enum GlassType /// Represents the window in . /// TestRoom, + + /// + /// Represents the window in . + /// + Scp127, } } \ No newline at end of file diff --git a/EXILED/Exiled.API/Enums/LockerType.cs b/EXILED/Exiled.API/Enums/LockerType.cs index af62a06cb3..14c2f365df 100644 --- a/EXILED/Exiled.API/Enums/LockerType.cs +++ b/EXILED/Exiled.API/Enums/LockerType.cs @@ -115,5 +115,10 @@ public enum LockerType /// SCP-1853 pedestal. /// Scp1853Pedestal, + + /// + /// SCP-127 pedestal. + /// + Scp127Pedestal, } } diff --git a/EXILED/Exiled.API/Enums/PrefabType.cs b/EXILED/Exiled.API/Enums/PrefabType.cs index 4296de63db..000773a6c3 100644 --- a/EXILED/Exiled.API/Enums/PrefabType.cs +++ b/EXILED/Exiled.API/Enums/PrefabType.cs @@ -345,5 +345,29 @@ public enum PrefabType [Prefab(1548138668, "AutoRagdoll")] AutoRagdoll, + + [Prefab(1323017091, "ElevatorChamberCargo")] + ElevatorChamberCargo, + + [Prefab(359728307, "InvisibleInteractableToy")] + InvisibleInteractableToy, + + [Prefab(1824808402, "EzArmCameraToy")] + EzArmCameraToy, + + [Prefab(3375932423, "EzCameraToy")] + EzCameraToy, + + [Prefab(144958943, "HczCameraToy")] + HczCameraToy, + + [Prefab(2026969629, "LczCameraToy")] + LczCameraToy, + + [Prefab(1548138668, "SzCameraToy")] + SzCameraToy, + + [Prefab(2842703865, "KeycardPickup_Chaos")] + KeycardPickupChaos, } } \ No newline at end of file diff --git a/EXILED/Exiled.API/Enums/RoomType.cs b/EXILED/Exiled.API/Enums/RoomType.cs index 3cb78e53f2..6e236c25d1 100644 --- a/EXILED/Exiled.API/Enums/RoomType.cs +++ b/EXILED/Exiled.API/Enums/RoomType.cs @@ -328,5 +328,15 @@ public enum RoomType /// Entrance Zone's straight hall with Dr.L's and conference room 9b locked room. /// EzSmallrooms, + + /// + /// Heavy Containment Zone's SCP-330 room. + /// + Hcz127, + + /// + /// Heavy Containment Zone's storage / server room. + /// + HczServerRoom, } } \ No newline at end of file diff --git a/EXILED/Exiled.API/Extensions/DamageTypeExtensions.cs b/EXILED/Exiled.API/Extensions/DamageTypeExtensions.cs index 7e496e77ac..6abeea8a2f 100644 --- a/EXILED/Exiled.API/Extensions/DamageTypeExtensions.cs +++ b/EXILED/Exiled.API/Extensions/DamageTypeExtensions.cs @@ -102,6 +102,7 @@ public static class DamageTypeExtensions { ItemType.Jailbird, DamageType.Jailbird }, { ItemType.GunFRMG0, DamageType.Frmg0 }, { ItemType.GunA7, DamageType.A7 }, + { ItemType.GunSCP127, DamageType.Scp127 }, }; /// diff --git a/EXILED/Exiled.API/Extensions/DoorTypeExtensions.cs b/EXILED/Exiled.API/Extensions/DoorTypeExtensions.cs index 79164df2b3..a4380d81cf 100644 --- a/EXILED/Exiled.API/Extensions/DoorTypeExtensions.cs +++ b/EXILED/Exiled.API/Extensions/DoorTypeExtensions.cs @@ -35,6 +35,6 @@ public static bool IsGate(this DoorType door) => door is DoorType.GateA or DoorT /// The door to be checked. /// Returns whether the is an elevator. public static bool IsElevator(this DoorType door) => door is DoorType.ElevatorGateA or DoorType.ElevatorGateB - or DoorType.ElevatorLczA or DoorType.ElevatorLczB or DoorType.ElevatorNuke or DoorType.ElevatorScp049; + or DoorType.ElevatorLczA or DoorType.ElevatorLczB or DoorType.ElevatorNuke or DoorType.ElevatorScp049 or DoorType.ElevatorServerRoom; } } \ No newline at end of file diff --git a/EXILED/Exiled.API/Extensions/ItemExtensions.cs b/EXILED/Exiled.API/Extensions/ItemExtensions.cs index c169f03011..458fd10bc4 100644 --- a/EXILED/Exiled.API/Extensions/ItemExtensions.cs +++ b/EXILED/Exiled.API/Extensions/ItemExtensions.cs @@ -182,6 +182,7 @@ public static int GetMaxAmmo(this FirearmType item) ItemType.GunCom45 => FirearmType.Com45, ItemType.GunFRMG0 => FirearmType.FRMG0, ItemType.ParticleDisruptor => FirearmType.ParticleDisruptor, + ItemType.GunSCP127 => FirearmType.Scp127, _ => FirearmType.None, }; @@ -220,6 +221,7 @@ public static int GetMaxAmmo(this FirearmType item) FirearmType.Com45 => ItemType.GunCom45, FirearmType.FRMG0 => ItemType.GunFRMG0, FirearmType.ParticleDisruptor => ItemType.ParticleDisruptor, + FirearmType.Scp127 => ItemType.GunSCP127, _ => ItemType.None, }; diff --git a/EXILED/Exiled.API/Extensions/LockerExtensions.cs b/EXILED/Exiled.API/Extensions/LockerExtensions.cs index 4a6466f636..da8b915794 100644 --- a/EXILED/Exiled.API/Extensions/LockerExtensions.cs +++ b/EXILED/Exiled.API/Extensions/LockerExtensions.cs @@ -48,6 +48,7 @@ public static class LockerExtensions "RegularMedkitStructure" => LockerType.Medkit, "AdrenalineMedkitStructure" => LockerType.Adrenaline, "MicroHIDpedestal" => LockerType.MicroHid, + "SCP_127_Container" => LockerType.Scp127Pedestal, _ => LockerType.Unknown, }; } diff --git a/EXILED/Exiled.API/Extensions/RoomExtensions.cs b/EXILED/Exiled.API/Extensions/RoomExtensions.cs index 14141a4422..8d36486505 100644 --- a/EXILED/Exiled.API/Extensions/RoomExtensions.cs +++ b/EXILED/Exiled.API/Extensions/RoomExtensions.cs @@ -52,7 +52,7 @@ public static bool IsCheckpoint(this RoomType room) => room is RoomType.LczCheck /// Returns whether the contains any SCP. public static bool IsScp(this RoomType room) => room is RoomType.Lcz173 or RoomType.Lcz330 or RoomType.Lcz914 or RoomType.Hcz049 or RoomType.Hcz079 or - RoomType.Hcz096 or RoomType.Hcz106 or RoomType.Hcz939; + RoomType.Hcz096 or RoomType.Hcz106 or RoomType.Hcz939 or RoomType.Hcz127; /// /// Converts the provided into the corresponding . diff --git a/EXILED/Exiled.API/Features/Camera.cs b/EXILED/Exiled.API/Features/Camera.cs index 208b4c672f..da3f73e27b 100644 --- a/EXILED/Exiled.API/Features/Camera.cs +++ b/EXILED/Exiled.API/Features/Camera.cs @@ -70,7 +70,6 @@ public class Camera : IWrapper, IWorldSpace ["HCZ ARMORY"] = CameraType.HczArmory, ["HCZ ARMORY INTERIOR"] = CameraType.HczArmoryInterior, ["HCZ CROSSING"] = CameraType.HczCrossing, - ["HCZ CURVE"] = CameraType.HczCurve, ["HCZ ELEV SYS A"] = CameraType.HczElevSysA, ["HCZ ELEV SYS B"] = CameraType.HczElevSysB, ["HCZ HALLWAY"] = CameraType.HczHallway, @@ -134,6 +133,18 @@ public class Camera : IWrapper, IWorldSpace ["WARHEAD TOP ELEVATORS"] = CameraType.HczWarheadTopElevators, ["WARHEAD CONNECTOR"] = CameraType.HczWarheadConnector, ["WARHEAD PORT ELEVATOR"] = CameraType.HczWarheadPortElevator, + ["HCZ SCP-127 LAB"] = CameraType.HczScp127Lab, + ["HCZ SCP-127 CONTAINMENT"] = CameraType.HczScp127Containment, + ["HCZ SERVERS UPPER STORAGE"] = CameraType.HczServersUpperStorage, + ["HCZ LOWER SERVER STORAGE"] = CameraType.HczLowerServerStorage, + ["HCZ SERVERS STAIRCASE"] = CameraType.HczServerStaircase, + + // CustomCamera + ["EZ ARM CAMERA TOY"] = CameraType.EzArmCameraToy, + ["EZ CAMERA TOY"] = CameraType.EzCameraToy, + ["HCZ CAMERA TOY"] = CameraType.HczCameraToy, + ["LCZ CAMERA TOY"] = CameraType.LczCameraToy, + ["SZ CAMERA TOY"] = CameraType.SzCameraToy, }; private Room room; @@ -147,10 +158,6 @@ internal Camera(Scp079Camera camera079) Base = camera079; Camera079ToCamera.Add(camera079, this); Type = GetCameraType(); -#if DEBUG - if (Type is CameraType.Unknown) - Log.Error($"[CAMERATYPE UNKNOWN] {this} BASE = {Base}"); -#endif } /// diff --git a/EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs b/EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs index b4c4d8d739..e19ce970f5 100644 --- a/EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs +++ b/EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs @@ -23,7 +23,14 @@ public class CustomHumeShieldStat : HumeShieldStat /// public float ShieldRegenerationMultiplier { get; set; } = 1; - private float ShieldRegeneration => TryGetHsModule(out HumeShieldModuleBase controller) ? controller.HsRegeneration * ShieldRegenerationMultiplier : 0; + private float ShieldRegeneration + { + get + { + IHumeShieldProvider.GetForHub(Hub, out _, out _, out float hsRegen, out _); + return hsRegen * ShieldRegenerationMultiplier; + } + } /// public override void Update() diff --git a/EXILED/Exiled.API/Features/DamageHandlers/GenericDamageHandler.cs b/EXILED/Exiled.API/Features/DamageHandlers/GenericDamageHandler.cs index 2008936bea..bd858b3447 100644 --- a/EXILED/Exiled.API/Features/DamageHandlers/GenericDamageHandler.cs +++ b/EXILED/Exiled.API/Features/DamageHandlers/GenericDamageHandler.cs @@ -155,6 +155,9 @@ public GenericDamageHandler(Player player, Player attacker, float damage, Damage case DamageType.A7: GenericFirearm(player, attacker, damage, damageType, ItemType.GunA7); break; + case DamageType.Scp127: + GenericFirearm(player, attacker, damage, damageType, ItemType.GunSCP127); + break; case DamageType.ParticleDisruptor: Base = new DisruptorDamageHandler(new (Item.Create(ItemType.ParticleDisruptor, attacker).Base as InventorySystem.Items.Firearms.Firearm, InventorySystem.Items.Firearms.Modules.DisruptorActionModule.FiringState.FiringSingle), Vector3.up, damage); break; diff --git a/EXILED/Exiled.API/Features/Doors/BasicDoor.cs b/EXILED/Exiled.API/Features/Doors/BasicDoor.cs index 39316fdd37..5a53caa738 100644 --- a/EXILED/Exiled.API/Features/Doors/BasicDoor.cs +++ b/EXILED/Exiled.API/Features/Doors/BasicDoor.cs @@ -9,6 +9,8 @@ namespace Exiled.API.Features.Doors { using System.Collections.Generic; + using Exiled.API.Enums; + using PlayerRoles; using UnityEngine; using Basegame = Interactables.Interobjects.BasicDoor; @@ -35,9 +37,9 @@ public BasicDoor(Basegame door, List room) public new Basegame Base { get; } /// - /// Gets the list with all SCP-106's colliders. + /// Gets the list with all Ignored's colliders for or . /// - public IEnumerable Scp106Colliders => Base.Scp106Colliders; + public IEnumerable Scp106Colliders => Base.IgnoredColliders; /// /// Gets or sets the total cooldown before door can be triggered again. diff --git a/EXILED/Exiled.API/Features/Doors/Door.cs b/EXILED/Exiled.API/Features/Doors/Door.cs index 3085f6fb4a..c2cea9a761 100644 --- a/EXILED/Exiled.API/Features/Doors/Door.cs +++ b/EXILED/Exiled.API/Features/Doors/Door.cs @@ -25,7 +25,7 @@ namespace Exiled.API.Features.Doors using Breakable = BreakableDoor; using Checkpoint = CheckpointDoor; using Elevator = ElevatorDoor; - using KeycardPermissions = Enums.KeycardPermissions; + using KeycardPermissions = Exiled.API.Enums.KeycardPermissions; /// /// A wrapper class for . @@ -54,10 +54,6 @@ internal Door(DoorVariant door, List rooms) } Type = GetDoorType(); -#if DEBUG - if (Type is DoorType.UnknownDoor or DoorType.UnknownGate or DoorType.UnknownElevator) - Log.Error($"[DOORTYPE UNKNOWN] {this} BASE = {Base}"); -#endif } /// @@ -180,8 +176,8 @@ public bool IsOpen /// public KeycardPermissions KeycardPermissions { - get => (KeycardPermissions)Base.RequiredPermissions.RequiredPermissions; - set => Base.RequiredPermissions = new((DoorPermissionFlags)value, Base.RequiredPermissions.RequireAll, Base.RequiredPermissions.Bypass2176); + get => (KeycardPermissions)RequiredPermissions; + set => RequiredPermissions = (DoorPermissionFlags)value; } /// @@ -240,6 +236,15 @@ public DoorLockType DoorLockType /// public string Name => Nametag == null ? GameObject.name.GetBefore(' ') : Nametag.GetName.RemoveBracketsOnEndOfName(); + /// + /// Gets or sets the required permissions to open the door. + /// + public DoorPermissionFlags RequiredPermissions + { + get => Base.RequiredPermissions.RequiredPermissions; + set => Base.RequiredPermissions.RequiredPermissions = value; + } + /// /// Gets or sets the door's rotation. /// @@ -603,6 +608,7 @@ private DoorType GetDoorType() ElevatorGroup.Scp049 => DoorType.ElevatorScp049, ElevatorGroup.GateB => DoorType.ElevatorGateB, ElevatorGroup.GateA => DoorType.ElevatorGateA, + ElevatorGroup.ServerRoom => DoorType.ElevatorServerRoom, ElevatorGroup.LczA01 or ElevatorGroup.LczA02 => DoorType.ElevatorLczA, ElevatorGroup.LczB01 or ElevatorGroup.LczB02 => DoorType.ElevatorLczB, ElevatorGroup.Nuke01 or ElevatorGroup.Nuke02 => DoorType.ElevatorNuke, @@ -644,8 +650,8 @@ private DoorType GetDoorType() "173_CONNECTOR" => DoorType.Scp173Connector, "LCZ_WC" => DoorType.LczWc, "HID_CHAMBER" => DoorType.HIDChamber, - "HID_UPPER" => DoorType.HIDUpper, - "HID_LOWER" => DoorType.HIDLower, + "HID_LAB" => DoorType.HIDLab, + "HCZ_127_LAB" => DoorType.Hcz127Lab, "173_ARMORY" => DoorType.Scp173Armory, "173_GATE" => DoorType.Scp173Gate, "GR18" => DoorType.GR18Gate, diff --git a/EXILED/Exiled.API/Features/Doors/ElevatorDoor.cs b/EXILED/Exiled.API/Features/Doors/ElevatorDoor.cs index 797378312a..0145e53f84 100644 --- a/EXILED/Exiled.API/Features/Doors/ElevatorDoor.cs +++ b/EXILED/Exiled.API/Features/Doors/ElevatorDoor.cs @@ -30,7 +30,7 @@ internal ElevatorDoor(Interactables.Interobjects.ElevatorDoor door, List r Base = door; Lift = Lift.Get(x => x.Group == Group).FirstOrDefault(); - Panel = Object.FindObjectsOfType().FirstOrDefault(x => x._door == door); + Panel = Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None).FirstOrDefault(x => x._door == door); } /// @@ -56,6 +56,7 @@ internal ElevatorDoor(Interactables.Interobjects.ElevatorDoor door, List r ElevatorGroup.Scp049 => ElevatorType.Scp049, ElevatorGroup.GateA => ElevatorType.GateA, ElevatorGroup.GateB => ElevatorType.GateB, + ElevatorGroup.ServerRoom => ElevatorType.ServerRoom, ElevatorGroup.LczA01 or ElevatorGroup.LczA02 => ElevatorType.LczA, ElevatorGroup.LczB01 or ElevatorGroup.LczB02 => ElevatorType.LczB, ElevatorGroup.Nuke01 or ElevatorGroup.Nuke02 => ElevatorType.Nuke, diff --git a/EXILED/Exiled.API/Features/Generator.cs b/EXILED/Exiled.API/Features/Generator.cs index ae989736f5..b19369208d 100644 --- a/EXILED/Exiled.API/Features/Generator.cs +++ b/EXILED/Exiled.API/Features/Generator.cs @@ -281,9 +281,7 @@ public static bool TryGet(Func predicate, out IEnumerable /// Denies the unlock. /// - public void DenyUnlock() => Base.RpcDenied(Interactables.Interobjects.DoorUtils.DoorPermissionFlags.None); - - // TODO: Documentation + public void DenyUnlock() => Base.RpcDenied(DoorPermissionFlags.None); /// /// Denies the unlock. diff --git a/EXILED/Exiled.API/Features/Items/Armor.cs b/EXILED/Exiled.API/Features/Items/Armor.cs index 238de555ec..344b7a0118 100644 --- a/EXILED/Exiled.API/Features/Items/Armor.cs +++ b/EXILED/Exiled.API/Features/Items/Armor.cs @@ -65,21 +65,22 @@ internal Armor(ItemType type) public bool IsWorn => Base.IsWorn; /// - /// Gets or sets the Weight of the armor. + /// Gets or sets a value indicating whether excess ammo should be removed when the armor is dropped. /// - public new float Weight + [Obsolete("Not functional anymore", true)] + public bool RemoveExcessOnDrop { - get => Base.Weight; - set => Base._weight = value; + get => false; + set => _ = value; } /// - /// Gets or sets a value indicating whether excess ammo should be removed when the armor is dropped. + /// Gets or sets the Weight of the armor. /// - public bool RemoveExcessOnDrop + public new float Weight { - get => !Base.DontRemoveExcessOnDrop; - set => Base.DontRemoveExcessOnDrop = !value; + get => Base.Weight; + set => Base._weight = value; } /// diff --git a/EXILED/Exiled.API/Features/Items/Keycard.cs b/EXILED/Exiled.API/Features/Items/Keycard.cs index 97adf63067..4e68dd60a5 100644 --- a/EXILED/Exiled.API/Features/Items/Keycard.cs +++ b/EXILED/Exiled.API/Features/Items/Keycard.cs @@ -7,14 +7,12 @@ namespace Exiled.API.Features.Items { + using System; + using Exiled.API.Enums; - using Exiled.API.Features.Pickups; using Exiled.API.Interfaces; - using InventorySystem.Items.Keycards; - using KeycardPickup = Pickups.KeycardPickup; - /// /// A wrapper class for . /// @@ -49,33 +47,30 @@ internal Keycard(ItemType type) /// public KeycardPermissions Permissions { - get => (KeycardPermissions)Base.GetPermissions(new()); - set => Base.Permissions = (Interactables.Interobjects.DoorUtils.KeycardPermissions)value; - } + get + { + foreach (DetailBase detail in Base.Details) + { + switch (detail) + { + case PredefinedPermsDetail predefinedPermsDetail: + return (KeycardPermissions)predefinedPermsDetail.Levels.Permissions; + case CustomPermsDetail customPermsDetail: + return (KeycardPermissions)customPermsDetail.GetPermissions(null); + } + } - /// - /// Clones current object. - /// - /// New object. - public override Item Clone() => new Keycard(Type) - { - Permissions = Permissions, - }; + return KeycardPermissions.None; + } + + [Obsolete("Not functional anymore", true)] + set => _ = value; + } /// /// Returns the Keycard in a human readable format. /// /// A string containing Keycard-related data. public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* |{Permissions}|"; - - /// - internal override void ReadPickupInfoBefore(Pickup pickup) - { - base.ReadPickupInfoBefore(pickup); - if (pickup is KeycardPickup keycardPickup) - { - Permissions = keycardPickup.Permissions; - } - } } } \ No newline at end of file diff --git a/EXILED/Exiled.API/Features/Items/Scp1344.cs b/EXILED/Exiled.API/Features/Items/Scp1344.cs index 460aeb8c06..7f96da8903 100644 --- a/EXILED/Exiled.API/Features/Items/Scp1344.cs +++ b/EXILED/Exiled.API/Features/Items/Scp1344.cs @@ -11,7 +11,7 @@ namespace Exiled.API.Features.Items using InventorySystem.Items.Usables; using InventorySystem.Items.Usables.Scp1344; - using PlayerRoles.FirstPersonControl.Thirdperson.Subcontrollers; + using PlayerRoles.FirstPersonControl.Thirdperson.Subcontrollers.Wearables; /// /// A wrapper class for . diff --git a/EXILED/Exiled.API/Features/Lockers/Chamber.cs b/EXILED/Exiled.API/Features/Lockers/Chamber.cs index 4c05213cc3..e98281ed5c 100644 --- a/EXILED/Exiled.API/Features/Lockers/Chamber.cs +++ b/EXILED/Exiled.API/Features/Lockers/Chamber.cs @@ -115,7 +115,7 @@ public IEnumerable AcceptableTypes public KeycardPermissions RequiredPermissions { get => (KeycardPermissions)Base.RequiredPermissions; - set => Base.RequiredPermissions = (Interactables.Interobjects.DoorUtils.KeycardPermissions)value; + set => Base.RequiredPermissions = (Interactables.Interobjects.DoorUtils.DoorPermissionFlags)value; } /// @@ -235,7 +235,7 @@ public void AddItem(Pickup item) Base.Content.Add(item.Base); item.Spawn(); - if (Base._wasEverOpened) + if (Base.WasEverOpened) item.IsLocked = false; } diff --git a/EXILED/Exiled.API/Features/Npc.cs b/EXILED/Exiled.API/Features/Npc.cs index 127ec1c629..7791218042 100644 --- a/EXILED/Exiled.API/Features/Npc.cs +++ b/EXILED/Exiled.API/Features/Npc.cs @@ -11,25 +11,20 @@ namespace Exiled.API.Features using System; using System.Collections.Generic; using System.Linq; - using System.Reflection; - using CentralAuth; using CommandSystem; using CommandSystem.Commands.RemoteAdmin.Dummies; using Exiled.API.Enums; - using Exiled.API.Features.Components; using Exiled.API.Features.CustomStats; using Exiled.API.Features.Roles; using Footprinting; - using GameCore; using MEC; using Mirror; + using NetworkManagerUtils.Dummies; using PlayerRoles; using PlayerStatsSystem; using UnityEngine; - using Object = UnityEngine.Object; - /// /// Wrapper class for handling NPC players. /// @@ -287,7 +282,7 @@ public static Npc Spawn(string name, RoleTypeId role = RoleTypeId.None, bool ign Timing.CallDelayed(SpawnSetRoleDelay, () => { npc.Role.Set(role, SpawnReason.ForceClass, position is null ? RoleSpawnFlags.All : RoleSpawnFlags.AssignInventory); - npc.ReferenceHub.playerStats._dictionarizedTypes[typeof(HealthStat)] = npc.ReferenceHub.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(HealthStat))] = npc.CustomHealthStat = new CustomHealthStat { Hub = npc.ReferenceHub }; + npc.ReferenceHub.playerStats._dictionarizedTypes[typeof(HealthStat)] = npc.ReferenceHub.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(HealthStat))] = npc.CustomHealthStat = new HealthStat { Hub = npc.ReferenceHub }; npc.Health = npc.MaxHealth; // otherwise the npc will spawn with 0 health npc.ReferenceHub.playerStats._dictionarizedTypes[typeof(HumeShieldStat)] = npc.ReferenceHub.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(HumeShieldStat))] = npc.CustomHumeShieldStat = new CustomHumeShieldStat { Hub = npc.ReferenceHub }; diff --git a/EXILED/Exiled.API/Features/Pickups/KeycardPickup.cs b/EXILED/Exiled.API/Features/Pickups/KeycardPickup.cs index 49115119b9..e7e29ff13e 100644 --- a/EXILED/Exiled.API/Features/Pickups/KeycardPickup.cs +++ b/EXILED/Exiled.API/Features/Pickups/KeycardPickup.cs @@ -42,9 +42,9 @@ internal KeycardPickup(ItemType type) } /// - /// Gets or sets the of the keycard. + /// Gets the of the keycard. /// - public KeycardPermissions Permissions { get; set; } + public KeycardPermissions Permissions { get; private set; } /// /// Gets the that this class is encapsulating. @@ -67,7 +67,18 @@ protected override void InitializeProperties(ItemBase itemBase) base.InitializeProperties(itemBase); if (itemBase is KeycardItem keycardItem) { - Permissions = (KeycardPermissions)keycardItem.Permissions; + foreach (DetailBase detail in keycardItem.Details) + { + switch (detail) + { + case PredefinedPermsDetail predefinedPermsDetail: + Permissions = (KeycardPermissions)predefinedPermsDetail.Levels.Permissions; + return; + case CustomPermsDetail customPermsDetail: + Permissions = (KeycardPermissions)customPermsDetail.GetPermissions(null); + return; + } + } } } } diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs index 4b2c5ae261..4dfcf09409 100644 --- a/EXILED/Exiled.API/Features/Player.cs +++ b/EXILED/Exiled.API/Features/Player.cs @@ -351,7 +351,7 @@ public string CustomInfo get => ReferenceHub.nicknameSync.Network_customPlayerInfoString; set { - if (NicknameSync.ValidateCustomInfo(value, out string rejectionText)) + if (!NicknameSync.ValidateCustomInfo(value, out string rejectionText)) { Log.Error($"Could not set CustomInfo for {Nickname}. Reason: {rejectionText}"); } @@ -2962,9 +2962,6 @@ public void ClearInventory(bool destroy = true) /// public void ClearItems(bool destroy = true) { - if (CurrentArmor is Armor armor) - armor.RemoveExcessOnDrop = false; - while (Items.Count > 0) RemoveItem(Items.ElementAt(0), destroy); } diff --git a/EXILED/Exiled.API/Features/Roles/FpcRole.cs b/EXILED/Exiled.API/Features/Roles/FpcRole.cs index 6a0c0fa49a..d1c0a12591 100644 --- a/EXILED/Exiled.API/Features/Roles/FpcRole.cs +++ b/EXILED/Exiled.API/Features/Roles/FpcRole.cs @@ -27,7 +27,6 @@ namespace Exiled.API.Features.Roles /// public abstract class FpcRole : Role, IVoiceRole { - private static FieldInfo enableFallDamageSettings; private bool isUsingStamina = true; /// diff --git a/EXILED/Exiled.API/Features/Roles/Scp079Role.cs b/EXILED/Exiled.API/Features/Roles/Scp079Role.cs index d46d069cdf..c2b8cb70ce 100644 --- a/EXILED/Exiled.API/Features/Roles/Scp079Role.cs +++ b/EXILED/Exiled.API/Features/Roles/Scp079Role.cs @@ -593,7 +593,7 @@ public void ActivateTesla(bool consumeEnergy = true) Scp079Camera cam = CurrentCameraSync.CurrentCamera; RewardManager.MarkRoom(cam.Room); - if (!global::TeslaGate.AllGates.TryGetFirst(x => RoomUtils.IsTheSameRoom(cam.Position, x.transform.position), out global::TeslaGate teslaGate)) + if (!global::TeslaGate.AllGates.TryGetFirst(x => cam.Position.TryGetRoom(out RoomIdentifier camRoom) && x.transform.position.TryGetRoom(out RoomIdentifier teslaRoom) && camRoom == teslaRoom, out global::TeslaGate teslaGate)) return; if (consumeEnergy) diff --git a/EXILED/Exiled.API/Features/Room.cs b/EXILED/Exiled.API/Features/Room.cs index f2f7c802a9..e5bcc9c0d5 100644 --- a/EXILED/Exiled.API/Features/Room.cs +++ b/EXILED/Exiled.API/Features/Room.cs @@ -246,7 +246,7 @@ public static Room Get(RoomIdentifier roomIdentifier) => roomIdentifier == null /// /// The to search for. /// The with the given or if not found. - public static Room Get(Vector3 position) => RoomUtils.RoomAtPositionRaycasts(position, false) is RoomIdentifier identifier ? Get(identifier) : null; + public static Room Get(Vector3 position) => position.TryGetRoom(out RoomIdentifier room) ? Get(room) : null; /// /// Gets a given the specified . @@ -421,7 +421,7 @@ internal void InternalCreate() Identifier = gameObject.GetComponent(); RoomIdentifierToRoom.Add(Identifier, this); - Zone = FindZone(gameObject); + Zone = Identifier.Zone.GetZone(); #if DEBUG if (Zone is ZoneType.Unspecified) Log.Error($"[ZONETYPE UNKNOWN] {this} Zone : {Identifier?.Zone}"); @@ -496,6 +496,8 @@ private static RoomType FindType(GameObject gameObject) "HCZ_Straight Variant" => RoomType.HczStraightVariant, "HCZ_ChkpA" => RoomType.HczElevatorA, "HCZ_ChkpB" => RoomType.HczElevatorB, + "HCZ_127" => RoomType.Hcz127, + "HCZ_ServerRoom" => RoomType.HczServerRoom, "EZ_GateA" => RoomType.EzGateA, "EZ_GateB" => RoomType.EzGateB, "EZ_ThreeWay" => RoomType.EzTCross, @@ -527,22 +529,5 @@ private static RoomType FindType(GameObject gameObject) _ => RoomType.Unknown, }; } - - private static ZoneType FindZone(GameObject gameObject) - { - Transform transform = gameObject.transform; - - if (gameObject.name == "PocketWorld") - return ZoneType.Pocket; - - return transform.parent?.name.RemoveBracketsOnEndOfName() switch - { - "HeavyRooms" => ZoneType.HeavyContainment, - "LightRooms" => ZoneType.LightContainment, - "EntranceRooms" => ZoneType.Entrance, - "HCZ_EZ_Checkpoint" => ZoneType.HeavyContainment | ZoneType.Entrance, - _ => transform.position.y > 900 ? ZoneType.Surface : ZoneType.Unspecified, - }; - } } } diff --git a/EXILED/Exiled.API/Features/Round.cs b/EXILED/Exiled.API/Features/Round.cs index b6ee2b35fc..a278e169dc 100644 --- a/EXILED/Exiled.API/Features/Round.cs +++ b/EXILED/Exiled.API/Features/Round.cs @@ -54,7 +54,7 @@ public static class Round /// /// Gets a value indicating whether the round is ended. /// - public static bool IsEnded => RoundSummary._singletonSet && RoundSummary.singleton._roundEnded; + public static bool IsEnded => RoundSummary._singletonSet && RoundSummary.singleton.IsRoundEnded; /// /// Gets a value indicating whether the round is lobby. diff --git a/EXILED/Exiled.API/Features/Server.cs b/EXILED/Exiled.API/Features/Server.cs index 202d026112..5de5dd5655 100644 --- a/EXILED/Exiled.API/Features/Server.cs +++ b/EXILED/Exiled.API/Features/Server.cs @@ -64,7 +64,7 @@ public static string Name set { ServerConsole.ServerName = value; - ServerConsole.singleton.RefreshServerNameSafe(); + ServerConsole.Singleton.RefreshServerNameSafe(); } } diff --git a/EXILED/Exiled.API/Features/Toys/AdminToy.cs b/EXILED/Exiled.API/Features/Toys/AdminToy.cs index 19fd51f9ca..79c5bfc17d 100644 --- a/EXILED/Exiled.API/Features/Toys/AdminToy.cs +++ b/EXILED/Exiled.API/Features/Toys/AdminToy.cs @@ -167,6 +167,8 @@ public static AdminToy Get(AdminToyBase adminToyBase) ShootingTarget shootingTarget => new ShootingTargetToy(shootingTarget), SpeakerToy speakerToy => new Speaker(speakerToy), CapybaraToy capybaraToy => new Capybara(capybaraToy), + Scp079CameraToy scp079CameraToy => new CameraToy(scp079CameraToy), + InvisibleInteractableToy invisibleInteractableToy => new InteractableToy(invisibleInteractableToy), _ => throw new System.NotImplementedException() }; } diff --git a/EXILED/Exiled.API/Features/Toys/CameraToy.cs b/EXILED/Exiled.API/Features/Toys/CameraToy.cs new file mode 100644 index 0000000000..518c4d789a --- /dev/null +++ b/EXILED/Exiled.API/Features/Toys/CameraToy.cs @@ -0,0 +1,83 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.API.Features.Toys +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + using AdminToys; + using Exiled.API.Enums; + using Exiled.API.Interfaces; + using UnityEngine; + + /// + /// A wrapper class for . + /// + internal class CameraToy : AdminToy, IWrapper + { + /// + /// Initializes a new instance of the class. + /// + /// The of the toy. + internal CameraToy(Scp079CameraToy scp079CameraToy) + : base(scp079CameraToy, AdminToyType.CameraToy) => Base = scp079CameraToy; + + /// + /// Gets the base . + /// + public Scp079CameraToy Base { get; } + + /// + /// Gets or sets the Vertical Restriction. + /// + public Vector2 VerticalConstraint + { + get => Base.NetworkVerticalConstraint; + set => Base.NetworkVerticalConstraint = value; + } + + /// + /// Gets or sets the Horizontal restriction. + /// + public Vector2 HorizontalConstraint + { + get => Base.NetworkHorizontalConstraint; + set => Base.NetworkHorizontalConstraint = value; + } + + /// + /// Gets or sets the Zoom restriction. + /// + public Vector2 ZoomConstraint + { + get => Base.NetworkZoomConstraint; + set => Base.NetworkZoomConstraint = value; + } + + /// + /// Gets or sets the Room where the Camera is associated with. + /// + public Room Room + { + get => Room.Get(Base.NetworkRoom); + set => Base.NetworkRoom = value.Identifier; + } + + /// + /// Gets or sets the Name of the Camera. + /// + public string Name + { + get => Base.NetworkLabel; + set => Base.NetworkLabel = value; + } + } +} diff --git a/EXILED/Exiled.API/Features/Toys/InteractableToy.cs b/EXILED/Exiled.API/Features/Toys/InteractableToy.cs new file mode 100644 index 0000000000..c6c73936cd --- /dev/null +++ b/EXILED/Exiled.API/Features/Toys/InteractableToy.cs @@ -0,0 +1,61 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.API.Features.Toys +{ + using AdminToys; + using Exiled.API.Enums; + using Exiled.API.Interfaces; + using UnityEngine; + + using static AdminToys.InvisibleInteractableToy; + + /// + /// A wrapper class for . + /// + internal class InteractableToy : AdminToy, IWrapper + { + /// + /// Initializes a new instance of the class. + /// + /// The of the toy. + internal InteractableToy(InvisibleInteractableToy invisibleInteractableToy) + : base(invisibleInteractableToy, AdminToyType.InvisibleInteractableToy) => Base = invisibleInteractableToy; + + /// + /// Gets the base . + /// + public InvisibleInteractableToy Base { get; } + + /// + /// Gets or sets the Shape of the Interactable. + /// + public ColliderShape Shape + { + get => Base.NetworkShape; + set => Base.NetworkShape = value; + } + + /// + /// Gets or sets the time to interact with the Interactable. + /// + public float InteractionDuration + { + get => Base.NetworkInteractionDuration; + set => Base.NetworkInteractionDuration = value; + } + + /// + /// Gets or sets a value indicating whether the interactable is locked. + /// + public bool IsLocked + { + get => Base.NetworkIsLocked; + set => Base.NetworkIsLocked = value; + } + } +} diff --git a/EXILED/Exiled.API/Features/Toys/Light.cs b/EXILED/Exiled.API/Features/Toys/Light.cs index 9496f6b833..9e167d1bb5 100644 --- a/EXILED/Exiled.API/Features/Toys/Light.cs +++ b/EXILED/Exiled.API/Features/Toys/Light.cs @@ -7,6 +7,7 @@ namespace Exiled.API.Features.Toys { + using System; using System.Linq; using AdminToys; @@ -98,6 +99,7 @@ public Color Color /// /// Gets or sets the shape that the Light emits. /// + [Obsolete("This property has been deprecated. Use LightType.Spot, LightType.Pyramid, or LightType.Box instead.")] public LightShape LightShape { get => Base.NetworkLightShape; diff --git a/EXILED/Exiled.API/Features/Warhead.cs b/EXILED/Exiled.API/Features/Warhead.cs index 682c63e8c4..97ce5a9cfe 100644 --- a/EXILED/Exiled.API/Features/Warhead.cs +++ b/EXILED/Exiled.API/Features/Warhead.cs @@ -35,7 +35,7 @@ public static class Warhead /// /// Gets the cached component. /// - public static AlphaWarheadOutsitePanel OutsitePanel => alphaWarheadOutsitePanel != null ? alphaWarheadOutsitePanel : (alphaWarheadOutsitePanel = UnityEngine.Object.FindObjectOfType()); + public static AlphaWarheadOutsitePanel OutsitePanel => alphaWarheadOutsitePanel != null ? alphaWarheadOutsitePanel : (alphaWarheadOutsitePanel = UnityEngine.Object.FindFirstObjectByType()); /// /// Gets the of the warhead lever. @@ -84,8 +84,8 @@ public static bool LeverStatus /// public static bool IsKeycardActivated { - get => OutsitePanel.NetworkkeycardEntered; - set => OutsitePanel.NetworkkeycardEntered = value; + get => AlphaWarheadActivationPanel.IsUnlocked; + set => AlphaWarheadActivationPanel.IsUnlocked = value; } /// diff --git a/EXILED/Exiled.API/Features/Window.cs b/EXILED/Exiled.API/Features/Window.cs index d11fe275ef..892733246b 100644 --- a/EXILED/Exiled.API/Features/Window.cs +++ b/EXILED/Exiled.API/Features/Window.cs @@ -45,7 +45,7 @@ internal Window(BreakableWindow window, Room room) } /// - /// Gets a of which contains all the instances. + /// Gets a of which contains all the instances. /// public static IReadOnlyCollection List => BreakableWindowToWindow.Values; @@ -225,6 +225,7 @@ public void DamageWindow(float amount, DamageHandlerBase handler) RoomType.HczTestRoom => GlassType.TestRoom, RoomType.HczEzCheckpointA => GlassType.HczEzCheckpointA, RoomType.HczEzCheckpointB => GlassType.HczEzCheckpointB, + RoomType.Hcz127 => GlassType.Scp127, _ => GlassType.Unknown, }; } diff --git a/EXILED/Exiled.CustomItems/API/Features/CustomKeycard.cs b/EXILED/Exiled.CustomItems/API/Features/CustomKeycard.cs index e28f1ea3d3..d53846cbb0 100644 --- a/EXILED/Exiled.CustomItems/API/Features/CustomKeycard.cs +++ b/EXILED/Exiled.CustomItems/API/Features/CustomKeycard.cs @@ -8,6 +8,7 @@ namespace Exiled.CustomItems.API.Features { using System; + using System.Linq; using Exiled.API.Enums; using Exiled.API.Extensions; @@ -18,6 +19,8 @@ namespace Exiled.CustomItems.API.Features using Exiled.API.Features.Pickups; using Exiled.Events.EventArgs.Item; using Exiled.Events.EventArgs.Player; + using Interactables.Interobjects.DoorUtils; + using InventorySystem.Items.Keycards; using UnityEngine; /// @@ -33,16 +36,41 @@ public override ItemType Type set { if (!value.IsKeycard()) - throw new ArgumentOutOfRangeException("Type", value, "Invalid keycard type."); + throw new ArgumentOutOfRangeException(nameof(Type), value, "Invalid keycard type."); base.Type = value; } } + /// + /// Gets or sets name of keycard holder. + /// + public virtual string KeycardName { get; set; } = string.Empty; + + /// + /// Gets or sets a label for keycard. + /// + public virtual string KeycardLabel { get; set; } = string.Empty; + + /// + /// Gets or sets a color of keycard label. + /// + public virtual Color32? KeycardLabelColor { get; set; } + + /// + /// Gets or sets a tint color. + /// + public virtual Color32? TintColor { get; set; } + /// /// Gets or sets the permissions for custom keycard. /// - public virtual KeycardPermissions Permissions { get; set; } + public virtual KeycardPermissions Permissions { get; set; } = KeycardPermissions.None; + + /// + /// Gets or sets a color of keycard permissions. + /// + public virtual Color32? KeycardPermissionsColor { get; set; } /// public override void Give(Player player, Item item, bool displayMessage = true) @@ -50,18 +78,66 @@ public override void Give(Player player, Item item, bool displayMessage = true) base.Give(player, item, displayMessage); if (item.Is(out Keycard card)) - card.Permissions = Permissions; + SetupKeycard(card); } /// public override Pickup? Spawn(Vector3 position, Item item, Player? previousOwner = null) { if (item.Is(out Keycard card)) - card.Permissions = Permissions; + SetupKeycard(card); return base.Spawn(position, item, previousOwner); } + /// + /// Setups keycard according to this class. + /// + /// Item instance. + protected virtual void SetupKeycard(Keycard keycard) + { + if (!keycard.Base.Customizable) + return; + + DetailBase[] details = keycard.Base.Details; + + NametagDetail? nameDetail = details.OfType().FirstOrDefault(); + + if (nameDetail != null && !string.IsNullOrEmpty(KeycardName)) + NametagDetail._customNametag = KeycardName; + + CustomItemNameDetail? raNameDetail = details.OfType().FirstOrDefault(); + + if (raNameDetail != null) + raNameDetail.Name = Name; + + CustomLabelDetail? labelDetail = details.OfType().FirstOrDefault(); + + if (labelDetail != null) + { + if (!string.IsNullOrEmpty(KeycardLabel)) + CustomLabelDetail._customText = KeycardLabel; + + if (KeycardLabelColor.HasValue) + CustomLabelDetail._customColor = KeycardLabelColor.Value; + } + + CustomPermsDetail? permsDetail = details.OfType().FirstOrDefault(); + + if (permsDetail != null) + { + CustomPermsDetail._customLevels = new((DoorPermissionFlags)Permissions); + CustomPermsDetail._customColor = KeycardPermissionsColor; + } + + CustomTintDetail? tintDetail = details.OfType().FirstOrDefault(); + + if (tintDetail != null && TintColor.HasValue) + { + CustomTintDetail._customColor = TintColor.Value; + } + } + /// /// Called when custom keycard interacts with a door. /// diff --git a/EXILED/Exiled.Events/EventArgs/Map/AnnouncingScpTerminationEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Map/AnnouncingScpTerminationEventArgs.cs index a083ac1fa1..4c43eb1df8 100644 --- a/EXILED/Exiled.Events/EventArgs/Map/AnnouncingScpTerminationEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Map/AnnouncingScpTerminationEventArgs.cs @@ -30,17 +30,14 @@ public class AnnouncingScpTerminationEventArgs : IAttackerEvent, IDeniableEvent /// /// /// - /// - /// - /// - public AnnouncingScpTerminationEventArgs(Player scp, DamageHandlerBase damageHandlerBase, bool isAllowed = true) + public AnnouncingScpTerminationEventArgs(Player scp, DamageHandlerBase damageHandlerBase) { Player = scp; Role = scp.Role; DamageHandler = new CustomDamageHandler(scp, damageHandlerBase); Attacker = DamageHandler.BaseIs(out CustomAttackerHandler customAttackerHandler) ? customAttackerHandler.Attacker : null; TerminationCause = damageHandlerBase.CassieDeathAnnouncement.Announcement; - IsAllowed = isAllowed; + IsAllowed = true; } /// @@ -71,6 +68,6 @@ public AnnouncingScpTerminationEventArgs(Player scp, DamageHandlerBase damageHan /// /// Gets or sets a value indicating whether the SCP termination will be announced by C.A.S.S.I.E. /// - public bool IsAllowed { get; set; } = true; + public bool IsAllowed { get; set; } } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/EventArgs/Player/ActivatingGeneratorEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ActivatingGeneratorEventArgs.cs index 33a6e87ee5..8050e534bf 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/ActivatingGeneratorEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/ActivatingGeneratorEventArgs.cs @@ -27,14 +27,11 @@ public class ActivatingGeneratorEventArgs : IPlayerEvent, IGeneratorEvent, IDeni /// /// /// - /// - /// - /// - public ActivatingGeneratorEventArgs(Player player, Scp079Generator generator, bool isAllowed = true) + public ActivatingGeneratorEventArgs(Player player, Scp079Generator generator) { Player = player; Generator = Generator.Get(generator); - IsAllowed = isAllowed; + IsAllowed = true; } /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/ActivatingWarheadPanelEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ActivatingWarheadPanelEventArgs.cs index f31eded385..65504085ed 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/ActivatingWarheadPanelEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/ActivatingWarheadPanelEventArgs.cs @@ -25,7 +25,7 @@ public class ActivatingWarheadPanelEventArgs : IPlayerEvent, IDeniableEvent /// /// /// - public ActivatingWarheadPanelEventArgs(Player player, bool isAllowed = true) + public ActivatingWarheadPanelEventArgs(Player player, bool isAllowed) { Player = player; IsAllowed = isAllowed; diff --git a/EXILED/Exiled.Events/EventArgs/Player/ClosingGeneratorEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ClosingGeneratorEventArgs.cs index 9218db494b..c33b0bcc0f 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/ClosingGeneratorEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/ClosingGeneratorEventArgs.cs @@ -21,12 +21,11 @@ public class ClosingGeneratorEventArgs : IPlayerEvent, IDeniableEvent, IGenerato /// /// The player who's closing the generator. /// The instance. - /// Indicates whether the generator can be closed. - public ClosingGeneratorEventArgs(Player player, Scp079Generator generator, bool isAllowed = true) + public ClosingGeneratorEventArgs(Player player, Scp079Generator generator) { Player = player; Generator = Generator.Get(generator); - IsAllowed = isAllowed; + IsAllowed = true; } /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/FailingEscapePocketDimensionEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/FailingEscapePocketDimensionEventArgs.cs index 490ebfa1a9..620178368c 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/FailingEscapePocketDimensionEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/FailingEscapePocketDimensionEventArgs.cs @@ -24,16 +24,16 @@ public class FailingEscapePocketDimensionEventArgs : IPlayerEvent, IDeniableEven /// /// /// - /// + /// /// /// /// /// /// - public FailingEscapePocketDimensionEventArgs(PocketDimensionTeleport pocketDimensionTeleport, Player player, bool isAllowed = true) + public FailingEscapePocketDimensionEventArgs(PocketDimensionTeleport pocketDimensionTeleport, ReferenceHub hub, bool isAllowed = true) { + Player = Player.Get(hub); Teleporter = pocketDimensionTeleport; - Player = player; IsAllowed = isAllowed; } diff --git a/EXILED/Exiled.Events/EventArgs/Player/InteractingDoorEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/InteractingDoorEventArgs.cs index 75eb562f39..c93656d6fc 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/InteractingDoorEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/InteractingDoorEventArgs.cs @@ -33,17 +33,14 @@ public class InteractingDoorEventArgs : IPlayerEvent, IDoorEvent, IDeniableEvent /// /// /// - /// - /// - /// - public InteractingDoorEventArgs(Player player, DoorVariant door, byte colliderId, bool isAllowed = true, bool canInteract = true) + public InteractingDoorEventArgs(Player player, DoorVariant door, byte colliderId, bool isAllowed) { Player = player; Door = Door.Get(door); ColliderId = colliderId; Collider = InteractableCollider.TryGetCollider(door, colliderId, out InteractableCollider interactableCollider) ? interactableCollider : null; IsAllowed = isAllowed; - CanInteract = canInteract; + CanInteract = true; } /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/OpeningGeneratorEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/OpeningGeneratorEventArgs.cs index f69507e355..13dc43febf 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/OpeningGeneratorEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/OpeningGeneratorEventArgs.cs @@ -27,14 +27,11 @@ public class OpeningGeneratorEventArgs : IPlayerEvent, IDeniableEvent, IGenerato /// /// /// - /// - /// - /// - public OpeningGeneratorEventArgs(Player player, Scp079Generator generator, bool isAllowed = true) + public OpeningGeneratorEventArgs(Player player, Scp079Generator generator) { Player = player; Generator = Generator.Get(generator); - IsAllowed = isAllowed; + IsAllowed = true; } /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs index 0eb6a5c69d..18d2303353 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs @@ -25,15 +25,16 @@ public class ShotEventArgs : IPlayerEvent, IFirearmEvent /// Raycast hit info. /// The firearm used. /// The IDestructible that was hit. Can be null. - public ShotEventArgs(HitscanHitregModuleBase hitregModule, RaycastHit hitInfo, InventorySystem.Items.Firearms.Firearm firearm, IDestructible destructible) + /// + public ShotEventArgs(HitscanHitregModuleBase hitregModule, RaycastHit hitInfo, InventorySystem.Items.Firearms.Firearm firearm, IDestructible destructible, float damage) { HitregModule = hitregModule; RaycastHit = hitInfo; Destructible = destructible; Firearm = Item.Get(firearm); + Damage = damage; Player = Firearm.Owner; - Damage = Destructible is not null ? HitregModule.DamageAtDistance(hitInfo.distance) : 0f; if (Destructible is HitboxIdentity hitboxIdentity) { diff --git a/EXILED/Exiled.Events/EventArgs/Player/StoppingGeneratorEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/StoppingGeneratorEventArgs.cs index 53f0d9ecf5..6462c655d8 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/StoppingGeneratorEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/StoppingGeneratorEventArgs.cs @@ -21,12 +21,11 @@ public class StoppingGeneratorEventArgs : IPlayerEvent, IGeneratorEvent, IDeniab /// /// The player who's flipping the switch. /// The instance. - /// Indicates whether the switch of the generator can be flipped. - public StoppingGeneratorEventArgs(Player player, Scp079Generator generator, bool isAllowed = true) + public StoppingGeneratorEventArgs(Player player, Scp079Generator generator) { Player = player; Generator = Generator.Get(generator); - IsAllowed = isAllowed; + IsAllowed = true; } /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/UnlockingGeneratorEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/UnlockingGeneratorEventArgs.cs index 422def506f..77541732d0 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/UnlockingGeneratorEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/UnlockingGeneratorEventArgs.cs @@ -30,7 +30,7 @@ public class UnlockingGeneratorEventArgs : IPlayerEvent, IGeneratorEvent, IDenia /// /// /// - public UnlockingGeneratorEventArgs(Player player, Scp079Generator generator, bool isAllowed = true) + public UnlockingGeneratorEventArgs(Player player, Scp079Generator generator, bool isAllowed) { Player = player; Generator = Generator.Get(generator); diff --git a/EXILED/Exiled.Events/Events.cs b/EXILED/Exiled.Events/Events.cs index 4815c2492c..103ba58829 100644 --- a/EXILED/Exiled.Events/Events.cs +++ b/EXILED/Exiled.Events/Events.cs @@ -81,9 +81,13 @@ public override void OnEnabled() RagdollManager.OnRagdollRemoved += Handlers.Internal.RagdollList.OnRemovedRagdoll; ItemPickupBase.OnPickupAdded += Handlers.Internal.PickupEvent.OnSpawnedPickup; ItemPickupBase.OnPickupDestroyed += Handlers.Internal.PickupEvent.OnRemovedPickup; - ServerConsole.ReloadServerName(); + + AdminToys.AdminToyBase.OnAdded += Handlers.Internal.AdminToyList.OnAddedAdminToys; + AdminToys.AdminToyBase.OnRemoved += Handlers.Internal.AdminToyList.OnRemovedAdminToys; ServerSpecificSettingsSync.ServerOnSettingValueReceived += SettingBase.OnSettingUpdated; + + ServerConsole.ReloadServerName(); } /// diff --git a/EXILED/Exiled.Events/Handlers/Internal/AdminToyList.cs b/EXILED/Exiled.Events/Handlers/Internal/AdminToyList.cs new file mode 100644 index 0000000000..2d4ebf971e --- /dev/null +++ b/EXILED/Exiled.Events/Handlers/Internal/AdminToyList.cs @@ -0,0 +1,27 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Handlers.Internal +{ + /// + /// Handles adding and removing from . + /// + internal static class AdminToyList + { + /// + /// Called after a ragdoll is spawned. Hooked to . + /// + /// The spawned ragdoll. + public static void OnAddedAdminToys(AdminToys.AdminToyBase adminToy) => API.Features.Toys.AdminToy.Get(adminToy); + + /// + /// Called before a ragdoll is destroyed. Hooked to . + /// + /// The destroyed ragdoll. + public static void OnRemovedAdminToys(AdminToys.AdminToyBase adminToy) => API.Features.Toys.AdminToy.BaseToAdminToy.Remove(adminToy); + } +} diff --git a/EXILED/Exiled.Events/Handlers/Internal/SceneUnloaded.cs b/EXILED/Exiled.Events/Handlers/Internal/SceneUnloaded.cs index 63bb70267e..55b9d0738b 100644 --- a/EXILED/Exiled.Events/Handlers/Internal/SceneUnloaded.cs +++ b/EXILED/Exiled.Events/Handlers/Internal/SceneUnloaded.cs @@ -35,7 +35,6 @@ public static void OnSceneUnloaded(Scene _) { Player.UserIdsCache.Clear(); Player.Dictionary.Clear(); - AdminToy.BaseToAdminToy.Clear(); } } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Cassie/SendingCassieMessage.cs b/EXILED/Exiled.Events/Patches/Events/Cassie/SendingCassieMessage.cs index 2c138e305e..0cb378ac02 100644 --- a/EXILED/Exiled.Events/Patches/Events/Cassie/SendingCassieMessage.cs +++ b/EXILED/Exiled.Events/Patches/Events/Cassie/SendingCassieMessage.cs @@ -35,40 +35,62 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions); LocalBuilder isUnlocked = generator.DeclareLocal(typeof(bool)); - LocalBuilder notEmptyPermissions = generator.DeclareLocal(typeof(bool)); - LocalBuilder havePermissions = generator.DeclareLocal(typeof(bool)); + LocalBuilder hasPermission = generator.DeclareLocal(typeof(bool)); - Label skip = generator.DefineLabel(); Label ret = generator.DefineLabel(); int offset = 1; int index = newInstructions.FindIndex(i => i.LoadsField(Field(typeof(DoorVariant), nameof(DoorVariant.ActiveLocks)))) + offset; + Label continueLabel = (Label)newInstructions[index].operand; + newInstructions.RemoveAt(index); newInstructions.InsertRange( index, - new[] + new CodeInstruction[] { // check and write door lock state (isUnlocked) new(OpCodes.Ldc_I4_0), new(OpCodes.Ceq), - new CodeInstruction(OpCodes.Stloc_S, isUnlocked.LocalIndex), - }); - - index = newInstructions.FindIndex(i => i.LoadsField(Field(typeof(DoorPermissions), nameof(DoorPermissions.RequiredPermissions)))) + offset; - - newInstructions.InsertRange( - index, - new[] - { - // checking empty permissions - new(OpCodes.Ldc_I4_0), - new(OpCodes.Cgt), - - new(OpCodes.Stloc_S, notEmptyPermissions.LocalIndex), - new(OpCodes.Br_S, skip), - - // save original return - new CodeInstruction(OpCodes.Ret).MoveLabelsFrom(newInstructions[index + 1]), - new CodeInstruction(OpCodes.Nop).WithLabels(skip), - }); - - // 6 new instructions - offset = 6; - index += offset; - - newInstructions.RemoveRange(index, 14); - - newInstructions.InsertRange( - index, - new[] - { - // override permissions check, to implement KeycardPickup::Permissions - new(OpCodes.Ldarg_0), - new(OpCodes.Ldloc_1), - new CodeInstruction(OpCodes.Call, Method(typeof(KeycardInteracting), nameof(KeycardInteracting.CheckPermissions))), - new CodeInstruction(OpCodes.Stloc_S, havePermissions.LocalIndex), + new(OpCodes.Stloc_S, isUnlocked.LocalIndex), + new(OpCodes.Br, continueLabel), }); - // 4 new instructions - offset = 4; - index += offset; - - newInstructions.RemoveRange(index, 2); - - offset = -5; - index = newInstructions.FindIndex(i => i.Calls(PropertySetter(typeof(DoorVariant), nameof(DoorVariant.NetworkTargetState)))) + offset; + offset = 1; + index = newInstructions.FindIndex(i => i.Calls(Method( + typeof(DoorPermissionsPolicyExtensions), + nameof(DoorPermissionsPolicyExtensions.CheckPermissions), + new[] { typeof(IDoorPermissionRequester), typeof(IDoorPermissionProvider), typeof(PermissionUsed).MakeByRefType() }))) + offset; newInstructions.InsertRange( index, - new[] - { - // pickup - new(OpCodes.Ldarg_0), - - // PreviousOwner.Hub - new CodeInstruction(OpCodes.Ldarg_0), - new(OpCodes.Ldflda, Field(typeof(BaseKeycardPickup), nameof(BaseKeycardPickup.PreviousOwner))), - new(OpCodes.Ldfld, Field(typeof(Footprint), nameof(Footprint.Hub))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - - // door - new(OpCodes.Ldloc_1), - - // allowed calculate - new(OpCodes.Ldloc_S, isUnlocked), - - new(OpCodes.Ldloc_S, havePermissions), - - new(OpCodes.Ldloc_S, notEmptyPermissions), - new(OpCodes.Call, PropertyGetter(typeof(Events), nameof(Events.Instance))), - new(OpCodes.Callvirt, PropertyGetter(typeof(Events), nameof(Events.Config))), - new(OpCodes.Callvirt, PropertyGetter(typeof(Config), nameof(Config.CanKeycardThrowAffectDoors))), - new(OpCodes.Or), - - new(OpCodes.And), - new(OpCodes.And), - - // ThrowKeycardInteractingEventArgs ev = new(pickup, player, door, isAllowed); - // - // Item.OnThrowKeycardInteracting(ev); - // - // if (!ev.IsAllowed) - // return; - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(KeycardInteractingEventArgs))[0]), - new(OpCodes.Dup), - new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnKeycardInteracting))), - new(OpCodes.Callvirt, PropertyGetter(typeof(KeycardInteractingEventArgs), nameof(KeycardInteractingEventArgs.IsAllowed))), - new(OpCodes.Brfalse_S, ret), - }); + new CodeInstruction[] + { + // hasPermission + new(OpCodes.Stloc_S, hasPermission.LocalIndex), + + // pickup + new(OpCodes.Ldarg_0), + + // PreviousOwner.Hub + new(OpCodes.Ldarg_0), + new(OpCodes.Ldflda, Field(typeof(BaseKeycardPickup), nameof(BaseKeycardPickup.PreviousOwner))), + new(OpCodes.Ldfld, Field(typeof(Footprint), nameof(Footprint.Hub))), + new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), + + // door + new(OpCodes.Ldloc_1), + + // isAllowed = isUnlocked && hasPermission && Events.Instance.Config.CanKeycardThrowAffectDoors + new(OpCodes.Ldloc_S, isUnlocked.LocalIndex), + new(OpCodes.Ldloc_S, hasPermission.LocalIndex), + new(OpCodes.And), + new(OpCodes.Call, PropertyGetter(typeof(Events), nameof(Events.Instance))), + new(OpCodes.Callvirt, PropertyGetter(typeof(Events), nameof(Events.Config))), + new(OpCodes.Callvirt, PropertyGetter(typeof(Config), nameof(Config.CanKeycardThrowAffectDoors))), + new(OpCodes.And), + + // ev = new KeycardInteractingEventArgs(pickup, player, door, isAllowed) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(KeycardInteractingEventArgs))[0]), + new(OpCodes.Dup), + new(OpCodes.Call, Method(typeof(Handlers.Item), nameof(Handlers.Item.OnKeycardInteracting))), + + new(OpCodes.Callvirt, PropertyGetter(typeof(KeycardInteractingEventArgs), nameof(KeycardInteractingEventArgs.IsAllowed))), + }); newInstructions.InsertRange( newInstructions.Count - 1, @@ -167,26 +123,5 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } - - private static bool CheckPermissions(BaseKeycardPickup keycard, DoorVariant door) - { - DoorPermissions permissions = door.RequiredPermissions; - if (permissions.RequiredPermissions == KeycardPermissions.None) - { - return true; - } - - if (Pickup.Get(keycard) is KeycardPickup keycardPickup) - { - if (!permissions.RequireAll) - { - return ((KeycardPermissions)keycardPickup.Permissions & permissions.RequiredPermissions) != 0; - } - - return ((KeycardPermissions)keycardPickup.Permissions & permissions.RequiredPermissions) == permissions.RequiredPermissions; - } - - return InventorySystem.InventoryItemLoader.AvailableItems.TryGetValue(keycard.Info.ItemId, out ItemBase itemBase) && permissions.CheckPermissions(itemBase, null); - } } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Map/AnnouncingChaosEntrance.cs b/EXILED/Exiled.Events/Patches/Events/Map/AnnouncingChaosEntrance.cs index 1bf2c9c02d..0d53ebeefb 100644 --- a/EXILED/Exiled.Events/Patches/Events/Map/AnnouncingChaosEntrance.cs +++ b/EXILED/Exiled.Events/Patches/Events/Map/AnnouncingChaosEntrance.cs @@ -42,7 +42,7 @@ private static IEnumerable Transpiler(IEnumerable i.opcode == OpCodes.Ldloca_S); + int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Pop) + 1; newInstructions.InsertRange(index, new[] { diff --git a/EXILED/Exiled.Events/Patches/Events/Map/AnnouncingNtfEntrance.cs b/EXILED/Exiled.Events/Patches/Events/Map/AnnouncingNtfEntrance.cs index f9663ecc7e..4d169bf050 100644 --- a/EXILED/Exiled.Events/Patches/Events/Map/AnnouncingNtfEntrance.cs +++ b/EXILED/Exiled.Events/Patches/Events/Map/AnnouncingNtfEntrance.cs @@ -55,8 +55,8 @@ private static IEnumerable Transpiler(IEnumerable x.characterClassManager.CurRole.team == Team.SCP && x.characterClassManager.CurClass != RoleTypeId.Scp0492); - new(OpCodes.Ldloc_3), + // scpsLeft + new(OpCodes.Ldloc_2), // string[] unitInformation = unitNameClear.Split('-'); new(OpCodes.Ldloc_1), @@ -111,7 +111,7 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable i.opcode == OpCodes.Ldloc_0) + offset; + int offset = -3; + int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.ServerEvents.CassieQueuingScpTerminationEventArgs))[0]) + offset; newInstructions.InsertRange( index, @@ -53,10 +54,7 @@ private static IEnumerable Transpiler(IEnumerable - /// Patches . + /// Patches . /// Adds the event. /// [EventPatch(typeof(Map), nameof(Map.SpawningItem))] - [HarmonyPatch(typeof(ItemDistributor), nameof(ItemDistributor.CreatePickup))] + [HarmonyPatch(typeof(ItemDistributor), nameof(ItemDistributor.ServerRegisterPickup))] internal static class SpawningItem { private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) diff --git a/EXILED/Exiled.Events/Patches/Events/Map/SpawningRoomConnector.cs b/EXILED/Exiled.Events/Patches/Events/Map/SpawningRoomConnector.cs index e1cfcc367c..b379bdec1a 100644 --- a/EXILED/Exiled.Events/Patches/Events/Map/SpawningRoomConnector.cs +++ b/EXILED/Exiled.Events/Patches/Events/Map/SpawningRoomConnector.cs @@ -75,4 +75,32 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } } + + /// + /// Patches . + /// Adds the event. + /// + [EventPatch(typeof(Handlers.Map), nameof(Handlers.Map.SpawningRoomConnector))] + [HarmonyPatch(typeof(SeedSynchronizer), nameof(SeedSynchronizer.GenerateLevel))] + internal static class SpawningRoomConnectorFix + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int index = newInstructions.FindIndex(i => i.Calls(Method(typeof(RoomConnectorSpawnpointBase), nameof(RoomConnectorSpawnpointBase.SetupAllRoomConnectors)))); + List - [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.InteractingDoor))] + [EventPatch(typeof(Handlers.Player), nameof(Player.InteractingDoor))] [HarmonyPatch(typeof(DoorVariant), nameof(DoorVariant.ServerInteract), typeof(ReferenceHub), typeof(byte))] internal static class InteractingDoor { @@ -32,55 +33,166 @@ private static IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions); - Label retLabel = generator.DefineLabel(); - LocalBuilder ev = generator.DeclareLocal(typeof(InteractingDoorEventArgs)); + LocalBuilder labEvent = generator.DeclareLocal(typeof(PlayerInteractedDoorEventArgs)); + + Label exiledEvContinue = generator.DefineLabel(); + Label labEvContinue = generator.DefineLabel(); + + int offset = -3; + int index = newInstructions.FindIndex(i => i.Calls(Method(typeof(DoorVariant), nameof(DoorVariant.AllowInteracting)))) + offset; + + Label elseStatement = newInstructions[index].labels[0]; + + offset = -1; + index = newInstructions.FindIndex(i => i.LoadsField(Field(typeof(DoorVariant), nameof(DoorVariant._remainingDeniedCooldown)))) + offset; + + Label bypassLock = generator.DefineLabel(); + Label continueLabel = generator.DefineLabel(); + + newInstructions[index].labels.Add(bypassLock); + + newInstructions.InsertRange( + index, + new[] + { + // pluginRequestSent = true (which prevent the second event call) + new(OpCodes.Ldc_I4_1), + new(OpCodes.Stloc_2), + + // Player.Get(ply) + new(OpCodes.Ldarg_1), + new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), + + // doorVariant + new(OpCodes.Ldarg_0), + + // colliderId + new(OpCodes.Ldarg_2), + + // false (canOpen is false because the door is locked, but still calling the event) + new(OpCodes.Ldc_I4_0), + + // ev = new InteractingDoorEventArgs(Player, DoorVariant, byte) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InteractingDoorEventArgs))[0]), + new(OpCodes.Dup), + new(OpCodes.Dup), + + // Player.OnInteractingDoor(ev); + new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnInteractingDoor))), + + // if (ev.CanInteract) goto continueLabel + // else return + new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.CanInteract))), + new(OpCodes.Brtrue_S, exiledEvContinue), + new(OpCodes.Pop), + new(OpCodes.Ret), + + // canOpen = ev.IsAllowed + new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.IsAllowed))).WithLabels(exiledEvContinue), + new(OpCodes.Stloc_0), + + // hub + new(OpCodes.Ldarg_1), - CodeInstruction[] interactingEvent = new CodeInstruction[] - { - // Player.Get(ply) - new(OpCodes.Ldarg_1), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), + // doorVariant + new(OpCodes.Ldarg_0), - // this - new(OpCodes.Ldarg_0), + // canOpen + new(OpCodes.Ldloc_0), - // colliderId - new(OpCodes.Ldarg_2), + // labEvent = new PlayerInteractingDoorEventArgs(ReferenceHub, DoorVariant, bool) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(PlayerInteractingDoorEventArgs))[0]), + new(OpCodes.Dup), + new(OpCodes.Dup), + new(OpCodes.Stloc_S, labEvent.LocalIndex), - // IsAllowed - new(OpCodes.Ldloc_1), + // PlayerEvents.OnInteractingDoor(labEvent) + new(OpCodes.Call, Method(typeof(PlayerEvents), nameof(PlayerEvents.OnInteractingDoor))), - // CanInteract - new(OpCodes.Ldc_I4_1), + // if (!labEvent.IsAllowed) goto bypassLock + new(OpCodes.Callvirt, PropertyGetter(typeof(PlayerInteractingDoorEventArgs), nameof(PlayerInteractingDoorEventArgs.IsAllowed))), + new(OpCodes.Brfalse_S, bypassLock), - // InteractingDoorEventArgs ev = new(Player.Get(ply), __instance, colliderId, bool, true); - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InteractingDoorEventArgs))[0]), - new(OpCodes.Dup), - new(OpCodes.Dup), + // canOpen = ev.CanOpen + new(OpCodes.Ldloc_S, labEvent.LocalIndex), + new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(PlayerInteractingDoorEventArgs), nameof(PlayerInteractingDoorEventArgs.CanOpen))).WithLabels(labEvContinue), + new(OpCodes.Stloc_0), + new(OpCodes.Br_S, elseStatement), + }); - // Handlers.Player.OnInteractingDoor(ev); - new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnInteractingDoor))), - new(OpCodes.Stloc_S, ev.LocalIndex), + offset = -3; + index = newInstructions.FindLastIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerInteractingDoorEventArgs))[0]) + offset; - // if (!ev.CanInteract) return; - new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.CanInteract))), - new(OpCodes.Brfalse_S, retLabel), + newInstructions.InsertRange( + index, + new[] + { + // Player.Get(ply) + new(OpCodes.Ldarg_1), + new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), - // CanInteract = ev.IsAllowed (Reminder this is done on purpose because we prefer than IDeniableEvent when cancel use CanInteract and not Interacting) - new(OpCodes.Ldloc_S, ev.LocalIndex), - new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.IsAllowed))), - new(OpCodes.Stloc_1), - }; + // doorVariant + new(OpCodes.Ldarg_0), + + // colliderId + new(OpCodes.Ldarg_2), + + // canOpen + new(OpCodes.Ldloc_0), + + // ev = new InteractingDoorEventArgs(Player, DoorVariant, byte) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InteractingDoorEventArgs))[0]), + new(OpCodes.Dup), + new(OpCodes.Dup), + + // Player.OnInteractingDoor(ev); + new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnInteractingDoor))), + + // if (ev.CanInteract) goto continueLabel + // else return + new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.CanInteract))), + new(OpCodes.Brtrue_S, continueLabel), + new(OpCodes.Pop), + new(OpCodes.Ret), + + // canOpen = ev.IsAllowed + new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(InteractingDoorEventArgs), nameof(InteractingDoorEventArgs.IsAllowed))).WithLabels(continueLabel), + new(OpCodes.Stloc_0), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } + + /// + /// Patches . + /// + [EventPatch(typeof(Handlers.Player), nameof(Player.InteractingDoor))] + [HarmonyPatch(typeof(DoorVariant), nameof(DoorVariant.TryResolveLock))] +#pragma warning disable SA1402 + internal static class ChangeNWLogic + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); - int offset = 4; - int index = newInstructions.FindLastIndex(x => x.Calls(Method(typeof(DoorLockUtils), nameof(DoorLockUtils.HasFlagFast), new System.Type[] { typeof(DoorLockMode), typeof(DoorLockMode) }))) + offset; - newInstructions.InsertRange(index, interactingEvent); + int offset = -3; + int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerInteractingDoorEventArgs))[0]) + offset; - offset = 2; - index = newInstructions.FindIndex(x => x.opcode == OpCodes.Ldloc_0) + offset; - newInstructions.InsertRange(index, interactingEvent); + newInstructions.InsertRange( + index, + new[] + { + new CodeInstruction(OpCodes.Ldc_I4_0).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Ret), + }); - newInstructions[newInstructions.Count - 1].labels.Add(retLabel); + // placing index after new added instructions + index += 2; + newInstructions.RemoveRange(index, newInstructions.Count - index); for (int z = 0; z < newInstructions.Count; z++) yield return newInstructions[z]; diff --git a/EXILED/Exiled.Events/Patches/Events/Player/InteractingGenerator.cs b/EXILED/Exiled.Events/Patches/Events/Player/InteractingGenerator.cs index 796e588b8e..ade2d45a67 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/InteractingGenerator.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/InteractingGenerator.cs @@ -9,6 +9,7 @@ namespace Exiled.Events.Patches.Events.Player { using System.Collections.Generic; using System.Diagnostics; + using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -41,19 +42,14 @@ private static IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions); LocalBuilder player = generator.DeclareLocal(typeof(API.Features.Player)); - LocalBuilder isAllowedUnlocking = generator.DeclareLocal(typeof(bool)); - Label isOpening = generator.DefineLabel(); - Label isActivating = generator.DefineLabel(); - Label check = generator.DefineLabel(); - Label check2 = generator.DefineLabel(); - Label notAllowed = generator.DefineLabel(); - Label skip = generator.DefineLabel(); - Label skip2 = generator.DefineLabel(); - Label @break = (Label)newInstructions.FindLast(instruction => instruction.opcode == OpCodes.Br_S).operand; + int offset = -1; + int index = newInstructions.FindLastIndex(i => i.LoadsField(Field(typeof(Scp079Generator), nameof(Scp079Generator._cooldownStopwatch)))) + offset; - int offset = 1; - int index = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(Stopwatch), nameof(Stopwatch.Stop)))) + offset; + Label breakLabel = newInstructions[index].labels.First(); + + offset = 1; + index = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(Stopwatch), nameof(Stopwatch.Stop)))) + offset; newInstructions.InsertRange( index, @@ -65,121 +61,74 @@ private static IEnumerable Transpiler(IEnumerable instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerClosingGeneratorEventArgs))[0]) + offset; - - // if (this.HasFlag(_flags, GeneratorFlags.Open)) - // { - // ClosingGeneratorEventArgs ev = new(player, this, true); - // - // Player.OnClosingGenerator(ev); - // - // if (!ev.IsAllowed) - // { - // this._targetCooldown = this._unlockCooldownTime; - // this.RpcDenied(); - // break; - // } - // } - // else - // { - // OpeningGeneratorEventArgs ev = new(player, this, true); - // - // Player.OnOpeningGenerator(ev); - // - // if (!ev.IsAllowed) - // { - // this._targetCooldown = this._unlockCooldownTime; - // this.RpcDenied(); - // break; - // } - // } + // closing generator index + offset = -2; + index = newInstructions.FindIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerClosingGeneratorEventArgs))[0]) + offset; + newInstructions.InsertRange( index, - new[] + new CodeInstruction[] { // player - new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex), - - // this - new(OpCodes.Ldarg_0), - - // true - new(OpCodes.Ldc_I4_1), + new(OpCodes.Ldloc_S, player.LocalIndex), - // if (!this.HasFlag(_flags, GeneratorFlags.Open)) - // goto isOpening; + // Scp079Generator new(OpCodes.Ldarg_0), - new(OpCodes.Ldarg_0), - new(OpCodes.Ldfld, Field(typeof(Scp079Generator), nameof(Scp079Generator._flags))), - new(OpCodes.Ldc_I4_4), // GeneratorFlags.Open - new(OpCodes.Callvirt, Method(typeof(Scp079Generator), nameof(Scp079Generator.HasFlag))), - new(OpCodes.Brfalse_S, isOpening), - // ClosingGeneratorEventArgs ev = new(Player, Scp079Generator, bool) + // ClosingGeneratorEventArgs ev = new(Player, Scp079Generator) new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ClosingGeneratorEventArgs))[0]), new(OpCodes.Dup), // Player.OnClosingGenerator(ev) new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnClosingGenerator))), - // ev.IsAllowed - // - // goto check + // if (!ev.IsAllowed) goto break; new(OpCodes.Callvirt, PropertyGetter(typeof(ClosingGeneratorEventArgs), nameof(ClosingGeneratorEventArgs.IsAllowed))), - new(OpCodes.Br_S, check), - - // OpeningGeneratorEventArgs ev = new(Player, Scp079Generator, bool) - new CodeInstruction(OpCodes.Newobj, GetDeclaredConstructors(typeof(OpeningGeneratorEventArgs))[0]).WithLabels(isOpening), - new(OpCodes.Dup), + new(OpCodes.Brfalse_S, breakLabel), + }); - // Player.OnOpeningGenerator(ev) - new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnOpeningGenerator))), + // opening generator index + offset = -2; + index = newInstructions.FindIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerOpeningGeneratorEventArgs))[0]) + offset; - // loads ev.isAllowed - // - // if (ev.IsAllowed) - // goto skip; - new(OpCodes.Callvirt, PropertyGetter(typeof(OpeningGeneratorEventArgs), nameof(OpeningGeneratorEventArgs.IsAllowed))), - new CodeInstruction(OpCodes.Brtrue_S, skip).WithLabels(check), + newInstructions.InsertRange( + index, + new[] + { + // player + new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]), - // notAllowed: - // - // this._targetCooldown = this._unlockCooldownTime; - new CodeInstruction(OpCodes.Ldarg_0).WithLabels(notAllowed), + // Scp079Generator new(OpCodes.Ldarg_0), - new(OpCodes.Ldfld, Field(typeof(Scp079Generator), nameof(Scp079Generator._unlockCooldownTime))), - new(OpCodes.Stfld, Field(typeof(Scp079Generator), nameof(Scp079Generator._targetCooldown))), - // this.RpcDenied() - new(OpCodes.Ldarg_0), - new(OpCodes.Callvirt, Method(typeof(Scp079Generator), nameof(Scp079Generator.RpcDenied))), + // OpeningGeneratorEventArgs ev = new(Player, Scp079Generator) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(OpeningGeneratorEventArgs))[0]), + new(OpCodes.Dup), - // goto @break - new(OpCodes.Br_S, @break), + // Player.OnOpeningGenerator(ev) + new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnOpeningGenerator))), - // skip: - new CodeInstruction(OpCodes.Nop).WithLabels(skip), + // if (!ev.IsAllowed) goto break; + new(OpCodes.Callvirt, PropertyGetter(typeof(OpeningGeneratorEventArgs), nameof(OpeningGeneratorEventArgs.IsAllowed))), + new(OpCodes.Brfalse_S, breakLabel), }); - offset = -6; - index = newInstructions.FindLastIndex(instruction => instruction.Calls(Method(typeof(Scp079Generator), nameof(Scp079Generator.RpcDenied)))) + offset; + // unlocking generator index + offset = -2; + index = newInstructions.FindIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerUnlockingGeneratorEventArgs))[0]) + offset; newInstructions.InsertRange( index, new[] { - // save the value of IsAllowed - new CodeInstruction(OpCodes.Stloc_S, isAllowedUnlocking.LocalIndex).MoveLabelsFrom(newInstructions[index]), - // player - new(OpCodes.Ldloc_S, player.LocalIndex), + new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex), - // this + // Scp079Generator new(OpCodes.Ldarg_0), - // isAllowed - new(OpCodes.Ldloc_S, isAllowedUnlocking.LocalIndex), + // flag + new(OpCodes.Ldloc_2), // UnlockingGeneratorEventArgs ev = new(Player, Scp079Generator, bool) new(OpCodes.Newobj, GetDeclaredConstructors(typeof(UnlockingGeneratorEventArgs))[0]), @@ -188,113 +137,69 @@ private static IEnumerable Transpiler(IEnumerable i.Calls(PropertySetter(typeof(Scp079Generator), nameof(Scp079Generator.Activating)))) + offset; - - // if (this.Activating) - // { - // StoppingGeneratorEventArgs ev = new(player, this, true); - // - // Player.OnStoppingGenerator(ev); - // - // if (!ev.IsAllowed) - // { - // this._targetCooldown = this._unlockCooldownTime; - // this.RpcDenied(); - // break; - // } - // } - // else - // { - // ActivatingGeneratorEventArgs ev = new(player, this, true); - // - // Player.OnActivatingGenerator(ev); - // - // if (!ev.IsAllowed) - // { - // this._targetCooldown = this._unlockCooldownTime; - // this.RpcDenied(); - // break; - // } - // } + // activating generator index + offset = -2; + index = newInstructions.FindIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerActivatingGeneratorEventArgs))[0]) + offset; + newInstructions.InsertRange( index, new[] { // player - new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]), - - // this - new(OpCodes.Ldarg_0), - - // true - new(OpCodes.Ldc_I4_1), + new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex), - // if (!this.Activating) - // goto isActivating; + // Scp079Generator new(OpCodes.Ldarg_0), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079Generator), nameof(Scp079Generator.Activating))), - new(OpCodes.Brfalse_S, isActivating), - // StoppingGeneratorEventArgs ev = new(Player, Scp079Generator, bool) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(StoppingGeneratorEventArgs))[0]), - new(OpCodes.Dup), - - // Player.OnStoppingGenerator(ev) - new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnStoppingGenerator))), - - // ev.IsAllowed - new(OpCodes.Callvirt, PropertyGetter(typeof(StoppingGeneratorEventArgs), nameof(StoppingGeneratorEventArgs.IsAllowed))), - new(OpCodes.Br_S, check2), - - // isActivating: - // - // ActivatingGeneratorEventArgs ev = new(Player, Scp079Generator, bool) - new CodeInstruction(OpCodes.Newobj, GetDeclaredConstructors(typeof(ActivatingGeneratorEventArgs))[0]).WithLabels(isActivating), + // ActivatingGeneratorEventArgs ev = new(Player, Scp079Generator) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ActivatingGeneratorEventArgs))[0]), new(OpCodes.Dup), // Player.OnActivatingGenerator(ev) new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnActivatingGenerator))), - // if (!ev.IsAllowed) - // goto notAllowed; + // if (!ev.IsAllowed) goto break; new(OpCodes.Callvirt, PropertyGetter(typeof(ActivatingGeneratorEventArgs), nameof(ActivatingGeneratorEventArgs.IsAllowed))), - new CodeInstruction(OpCodes.Brfalse_S, notAllowed).WithLabels(check2), + new(OpCodes.Brfalse_S, breakLabel), }); - offset = 1; - index = newInstructions.FindLastIndex(i => i.opcode == OpCodes.Brfalse_S) + offset; - - newInstructions.InsertRange( - index, - new[] - { - // player - new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex), - - // this - new(OpCodes.Ldarg_0), - - // true - new(OpCodes.Ldc_I4_1), - - // StoppingGeneratorEventArgs ev = new(Player, Scp079Generator, bool) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(StoppingGeneratorEventArgs))[0]), - new(OpCodes.Dup), - - // Player.OnStoppingGenerator(ev) - new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnStoppingGenerator))), - - // if (!ev.IsAllowed) - // return notAllowed; - new(OpCodes.Callvirt, PropertyGetter(typeof(StoppingGeneratorEventArgs), nameof(StoppingGeneratorEventArgs.IsAllowed))), - new(OpCodes.Brfalse_S, notAllowed), - }); + // deactivating generator instructions + CodeInstruction[] deactivatingGeneratorEvent = + { + // Scp079Generator + new(OpCodes.Ldarg_0), + + // StoppingGeneratorEventArgs ev = new(Player, Scp079Generator) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(StoppingGeneratorEventArgs))[0]), + new(OpCodes.Dup), + + // Player.OnStoppingGenerator(ev) + new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnStoppingGenerator))), + + // if (!ev.IsAllowed) goto break; + new(OpCodes.Callvirt, PropertyGetter(typeof(StoppingGeneratorEventArgs), nameof(StoppingGeneratorEventArgs.IsAllowed))), + new(OpCodes.Brfalse_S, breakLabel), + }; + + // deactivating generator index + offset = -2; + index = newInstructions.FindIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerDeactivatingGeneratorEventArgs))[0]) + offset; + newInstructions.InsertRange(index, new[] + { + new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]), + }.AddRangeToArray(deactivatingGeneratorEvent)); + + // second deactivating generator index + index = newInstructions.FindLastIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerDeactivatingGeneratorEventArgs))[0]) + offset; + newInstructions.InsertRange(index, new[] + { + new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex), + }.AddRangeToArray(deactivatingGeneratorEvent)); for (int z = 0; z < newInstructions.Count; z++) yield return newInstructions[z]; diff --git a/EXILED/Exiled.Events/Patches/Events/Player/InteractingLocker.cs b/EXILED/Exiled.Events/Patches/Events/Player/InteractingLocker.cs index 21f3ef2d23..3ce7b9aeee 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/InteractingLocker.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/InteractingLocker.cs @@ -8,6 +8,7 @@ namespace Exiled.Events.Patches.Events.Player { using System.Collections.Generic; + using System.Reflection; using System.Reflection.Emit; using API.Features; @@ -32,14 +33,15 @@ private static IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions); - int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldloc_1); + int offset = -9; + int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerInteractingLockerEventArgs))[0]) + offset; newInstructions.InsertRange( index, - new[] + new CodeInstruction[] { // Player.Get(ply); - new CodeInstruction(OpCodes.Ldarg_1).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Ldarg_1), new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), // this @@ -54,7 +56,7 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable instruction.opcode == OpCodes.Stloc_2) + offset; + int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldloc_1); + newInstructions[index].labels.Add(continueLabel); newInstructions.InsertRange( index, @@ -43,7 +43,7 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerPickingUpArmorEventArgs))[0]) + offset; newInstructions.InsertRange( index, @@ -43,7 +45,7 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerPickingUpItemEventArgs))[0]) + offset; newInstructions[index].WithLabels(continueLabel); @@ -50,7 +52,7 @@ private static IEnumerable Transpiler(IEnumerable /// Patches to add missing event handler to the /// . @@ -36,8 +35,8 @@ private static IEnumerable Transpiler(IEnumerable instruction.opcode == OpCodes.Ret) + offset; + int offset = -4; + int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Newobj && (ConstructorInfo)i.operand == GetDeclaredConstructors(typeof(LabApi.Events.Arguments.PlayerEvents.PlayerPickingUpItemEventArgs))[0]) + offset; newInstructions.InsertRange( index, @@ -45,7 +44,7 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable - /// Patches . + /// Patches . /// Adds the event. /// [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Shot))] - [HarmonyPatch(typeof(HitscanHitregModuleBase), nameof(HitscanHitregModuleBase.ServerPerformHitscan))] - internal static class Shot + [HarmonyPatch(typeof(HitscanHitregModuleBase), nameof(HitscanHitregModuleBase.ServerApplyDestructibleDamage))] + internal static class ShotTarget { - private static void ProcessRaycastMiss(HitscanHitregModuleBase hitregModule, Ray ray, float maxDistance) - { - RaycastHit hit = new() - { - distance = maxDistance, - point = ray.GetPoint(maxDistance), - normal = -ray.direction, - }; - - ShotEventArgs ev = new(hitregModule, hit, hitregModule.Firearm, null); - Handlers.Player.OnShot(ev); - } - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { List newInstructions = ListPool.Pool.Get(instructions); - /* - IL_0020: ldarg.1 // targetRay - IL_0021: ldloca.s hitInfo - IL_0023: ldloc.0 // maxDistance - IL_0024: ldsfld class CachedLayerMask InventorySystem.Items.Firearms.Modules.HitscanHitregModuleBase::HitregMask - IL_0029: call int32 CachedLayerMask::op_Implicit(class CachedLayerMask) - IL_002e: call bool [UnityEngine.PhysicsModule]UnityEngine.Physics::Raycast(valuetype [UnityEngine.CoreModule]UnityEngine.Ray, valuetype [UnityEngine.PhysicsModule]UnityEngine.RaycastHit&, float32, int32) - IL_0033: brtrue.s IL_0037 - [] <= Here - */ - MethodInfo raycastMethod = Method(typeof(Physics), nameof(Physics.Raycast), new[] { typeof(Ray), typeof(RaycastHit).MakeByRefType(), typeof(float), typeof(int) }); - int raycastFailIndex = newInstructions.FindIndex(i => i.Calls(raycastMethod)) + 2; - - newInstructions.InsertRange( - raycastFailIndex, - new CodeInstruction[] - { - // ProcessRaycastMiss(this, targetRay, maxDistance); - new(OpCodes.Ldarg_0), - new(OpCodes.Ldarg_1), - new(OpCodes.Ldloc_0), - new(OpCodes.Call, Method(typeof(Shot), nameof(ProcessRaycastMiss))), - }); - - /* - IL_0037: ldloca.s hitInfo - IL_0039: call instance class [UnityEngine.PhysicsModule]UnityEngine.Collider [UnityEngine.PhysicsModule]UnityEngine.RaycastHit::get_collider() - IL_003e: ldloca.s component - IL_0040: callvirt instance bool [UnityEngine.CoreModule]UnityEngine.Component::TryGetComponent(!!0/*class IDestructible* /&) - [] <= Here // This position is reached whether IDestructible is found or not. - IL_0045: brfalse.s IL_005e - */ - int destructibleGetIndex = newInstructions.FindIndex(i => i.operand is MethodInfo { Name: nameof(Component.TryGetComponent) }) + 1; + int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Ldloc_2); Label continueLabel = generator.DefineLabel(); LocalBuilder ev = generator.DeclareLocal(typeof(ShotEventArgs)); newInstructions.InsertRange( - destructibleGetIndex, + index, new[] { - // var ev = new ShotEventArgs(this, hitInfo, firearm, component); - new(OpCodes.Ldarg_0), // this - new(OpCodes.Ldloc_1), // hitInfo - new(OpCodes.Ldarg_0), // this.Firearm + // this + new(OpCodes.Ldarg_0), + + // target.Raycast.Hit + new(OpCodes.Ldarg_1), + new(OpCodes.Ldfld, Field(typeof(DestructibleHitPair), nameof(DestructibleHitPair.Raycast))), + new(OpCodes.Ldfld, Field(typeof(HitRayPair), nameof(HitRayPair.Hit))), + + // this.Firearm + new(OpCodes.Ldarg_0), new(OpCodes.Callvirt, PropertyGetter(typeof(HitscanHitregModuleBase), nameof(HitscanHitregModuleBase.Firearm))), - new(OpCodes.Ldloc_2), // component + + // destructible + new(OpCodes.Ldloc_2), + + // damage + new(OpCodes.Ldloc_0), + + // ShotEventArgs ev = new ShotEventArgs(this, hitInfo, firearm, component, damage); new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ShotEventArgs))[0]), - new(OpCodes.Dup), // Leave ShotEventArgs on the stack + new(OpCodes.Dup), + new(OpCodes.Dup), new(OpCodes.Stloc_S, ev.LocalIndex), - new(OpCodes.Dup), // Leave ShotEventArgs on the stack new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnShot))), - // if (!ev.CanHurt) hitInfo.distance = maxDistance; + // if (!ev.CanHurt) num = 0; new(OpCodes.Callvirt, PropertyGetter(typeof(ShotEventArgs), nameof(ShotEventArgs.CanHurt))), new(OpCodes.Brtrue, continueLabel), - new(OpCodes.Ldloca_S, 1), // hitInfo address - new(OpCodes.Ldloc_0), // maxDistance - new(OpCodes.Call, PropertySetter(typeof(RaycastHit), nameof(RaycastHit.distance))), // hitInfo.distance = maxDistance + new(OpCodes.Ldc_I4_0), + new(OpCodes.Stloc_0), new CodeInstruction(OpCodes.Nop).WithLabels(continueLabel), }); - /* - [] <= Here - IL_0067: ldarg.0 // this - IL_0068: call instance class InventorySystem.Items.Firearms.Firearm InventorySystem.Items.Firearms.FirearmSubcomponentBase::get_Firearm() - IL_006d: ldloca.s module - IL_006f: ldc.i4.1 - IL_0070: call bool InventorySystem.Items.Firearms.Modules.ModulesUtils::TryGetModule(class InventorySystem.Items.Firearms.Firearm, !!0/*class InventorySystem.Items.Firearms.Modules.ImpactEffectsModule* /&, bool) - IL_0075: brtrue.s IL_0079 - */ - int impactEffectsIndex = newInstructions.FindIndex(i => i.operand is MethodInfo { Name: nameof(ModulesUtils.TryGetModule) }) - 4; - List - [HarmonyPatch(typeof(BodyArmorUtils), nameof(BodyArmorUtils.RemoveEverythingExceedingLimits), typeof(Inventory), typeof(BodyArmor), typeof(bool), typeof(bool))] + [HarmonyPatch(typeof(BodyArmorUtils), nameof(BodyArmorUtils.RemoveEverythingExceedingLimits), typeof(InventorySystem.Inventory))] internal static class ArmorDropPatch { private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) diff --git a/EXILED/Exiled.Events/Patches/Fixes/LockerFixes.cs b/EXILED/Exiled.Events/Patches/Fixes/LockerFixes.cs index 97cbb98577..2538e90ca2 100644 --- a/EXILED/Exiled.Events/Patches/Fixes/LockerFixes.cs +++ b/EXILED/Exiled.Events/Patches/Fixes/LockerFixes.cs @@ -23,7 +23,7 @@ namespace Exiled.Events.Patches.Fixes /// /// Fix for chamber lists weren't cleared. /// - [HarmonyPatch(typeof(LockerChamber), nameof(LockerChamber.SetDoor))] + [HarmonyPatch(typeof(LockerChamber), nameof(LockerChamber.OnFirstTimeOpen))] internal class LockerFixes { private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) diff --git a/EXILED/Exiled.Events/Patches/Fixes/RemoteAdminNpcCommandAddToDictionaryFix.cs b/EXILED/Exiled.Events/Patches/Fixes/RemoteAdminNpcCommandAddToDictionaryFix.cs index cb7b867f77..ec70f756bc 100644 --- a/EXILED/Exiled.Events/Patches/Fixes/RemoteAdminNpcCommandAddToDictionaryFix.cs +++ b/EXILED/Exiled.Events/Patches/Fixes/RemoteAdminNpcCommandAddToDictionaryFix.cs @@ -16,6 +16,7 @@ namespace Exiled.Events.Patches.Fixes using Exiled.API.Features.Pools; using GameCore; using HarmonyLib; + using NetworkManagerUtils.Dummies; using UnityEngine; using static HarmonyLib.AccessTools; diff --git a/EXILED/Exiled.Events/Patches/Fixes/Scp3114FriendlyFireFix.cs b/EXILED/Exiled.Events/Patches/Fixes/Scp3114FriendlyFireFix.cs index e2d309ced2..6d0f4accf4 100644 --- a/EXILED/Exiled.Events/Patches/Fixes/Scp3114FriendlyFireFix.cs +++ b/EXILED/Exiled.Events/Patches/Fixes/Scp3114FriendlyFireFix.cs @@ -94,6 +94,10 @@ public Scp3114FriendlyFireFix2(Footprint attacker, float damage) public override float Damage { get; set; } + public override string RagdollInspectText { get; } + + public override string DeathScreenText { get; } + public override string ServerLogsText { get; } #pragma warning restore SA1600 // Elements should be documented diff --git a/EXILED/Exiled.Events/Patches/Generic/CameraList.cs b/EXILED/Exiled.Events/Patches/Generic/CameraList.cs index c0981eb87f..db02509a4f 100644 --- a/EXILED/Exiled.Events/Patches/Generic/CameraList.cs +++ b/EXILED/Exiled.Events/Patches/Generic/CameraList.cs @@ -37,10 +37,13 @@ private static IEnumerable Transpiler(IEnumerable i.Calls(PropertySetter(typeof(Scp079InteractableBase), nameof(Scp079InteractableBase.Room)))) + offset; + // if (this is Scp079Camera camera) // Room.RoomIdentifierToRoom[Room].CamerasValue.Add(new Camera(camera)); newInstructions.InsertRange( - newInstructions.Count - 1, + index, new CodeInstruction[] { new(OpCodes.Ldarg_0), diff --git a/EXILED/Exiled.Events/Patches/Generic/RoomList.cs b/EXILED/Exiled.Events/Patches/Generic/RoomList.cs index c61c7bc3f6..88c24aa6c7 100644 --- a/EXILED/Exiled.Events/Patches/Generic/RoomList.cs +++ b/EXILED/Exiled.Events/Patches/Generic/RoomList.cs @@ -27,22 +27,19 @@ namespace Exiled.Events.Patches.Generic /// /// Patches . /// - [HarmonyPatch(typeof(RoomIdentifier), nameof(RoomIdentifier.TryAssignId))] + [HarmonyPatch(typeof(RoomIdentifier), nameof(RoomIdentifier.RegisterCoords))] internal class RoomList { private static IEnumerable Transpiler(IEnumerable codeInstructions) { List newInstructions = ListPool.Pool.Get(codeInstructions); - int offset = -3; - int index = newInstructions.FindIndex(i => i.Calls(Method(typeof(RoomUtils), nameof(RoomUtils.PositionToCoords)))) + offset; - // Room.Get(gameObject).InternalCreate(); newInstructions.InsertRange( - index, + 0, new CodeInstruction[] { - new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Ldarg_0), new(OpCodes.Callvirt, PropertyGetter(typeof(Component), nameof(Component.gameObject))), new(OpCodes.Callvirt, Method(typeof(Room), nameof(Room.CreateComponent))), }); diff --git a/EXILED/Exiled.Loader/AutoUpdateFiles.cs b/EXILED/Exiled.Loader/AutoUpdateFiles.cs index 18d49995ef..8490d01eea 100644 --- a/EXILED/Exiled.Loader/AutoUpdateFiles.cs +++ b/EXILED/Exiled.Loader/AutoUpdateFiles.cs @@ -17,6 +17,6 @@ public static class AutoUpdateFiles /// /// Gets which SCP: SL version generated Exiled. /// - public static readonly Version RequiredSCPSLVersion = new(14, 0, 0, 3); + public static readonly Version RequiredSCPSLVersion = new(14, 1, 0, 0); } } \ No newline at end of file diff --git a/EXILED/docs/articles/SCPSLRessources/NW_Documentation.md b/EXILED/docs/articles/SCPSLRessources/NW_Documentation.md index d192c18231..31ee11803d 100644 --- a/EXILED/docs/articles/SCPSLRessources/NW_Documentation.md +++ b/EXILED/docs/articles/SCPSLRessources/NW_Documentation.md @@ -17,7 +17,7 @@ title: NW Documentation --- -Last Update (14.0.0.3) +Last Update (14.1.0.0) ### Index @@ -61,8 +61,7 @@ Last Update (14.0.0.3) - [ChallengeState](#challengestate) - [ChallengeType](#challengetype) - [ChamberState](#chamberstate) -- [CheckpointErrorType](#checkpointerrortype) -- [CheckpointSequenceStage](#checkpointsequencestage) +- [ChaosMsgType](#chaosmsgtype) - [ClientFlags](#clientflags) - [ClientInstanceMode](#clientinstancemode) - [ClientReceivedContentType](#clientreceivedcontenttype) @@ -72,6 +71,7 @@ Last Update (14.0.0.3) - [CmdTeleportData](#cmdteleportdata) - [CoffeeTranslation](#coffeetranslation) - [CollectionDeserializeToBehaviour](#collectiondeserializetobehaviour) +- [ColliderShape](#collidershape) - [CollisionsDisablingReasons](#collisionsdisablingreasons) - [ColorMode](#colormode) - [CommandOperationMode](#commandoperationmode) @@ -89,6 +89,7 @@ Last Update (14.0.0.3) - [DecalPoolType](#decalpooltype) - [DecontaminationStatus](#decontaminationstatus) - [DeliveryMethod](#deliverymethod) +- [DetectionStatus](#detectionstatus) - [DiodeType](#diodetype) - [DisconnectReason](#disconnectreason) - [DisconnectResult](#disconnectresult) @@ -101,6 +102,7 @@ Last Update (14.0.0.3) - [DoorDamageType](#doordamagetype) - [DoorLockMode](#doorlockmode) - [DoorLockReason](#doorlockreason) +- [DoorPermissionFlags](#doorpermissionflags) - [DropdownEntryType](#dropdownentrytype) - [DtoaMode](#dtoamode) - [EffectClassification](#effectclassification) @@ -133,6 +135,8 @@ Last Update (14.0.0.3) - [FoldoutMode](#foldoutmode) - [FootprintsTranslation](#footprintstranslation) - [FootstepLoudness](#footsteploudness) +- [ForceCondition](#forcecondition) +- [ForceResult](#forceresult) - [FpcViewMode](#fpcviewmode) - [FreezingMode](#freezingmode) - [FriendlyFireAction](#friendlyfireaction) @@ -171,7 +175,8 @@ Last Update (14.0.0.3) - [JailbirdMessageType](#jailbirdmessagetype) - [JailbirdWearState](#jailbirdwearstate) - [JsonToken](#jsontoken) -- [KeycardPermissions](#keycardpermissions) +- [KeycardLabelTranslation](#keycardlabeltranslation) +- [KeyCodeTranslations](#keycodetranslations) - [LcdElementType](#lcdelementtype) - [LeadingTeam](#leadingteam) - [LegacyInterfaces](#legacyinterfaces) @@ -196,6 +201,7 @@ Last Update (14.0.0.3) - [Mode](#mode) - [ModifierMode](#modifiermode) - [Modules](#modules) +- [MsgType](#msgtype) - [NatAddressType](#nataddresstype) - [NetLogLevel](#netloglevel) - [NetworkProtocolType](#networkprotocoltype) @@ -231,12 +237,14 @@ Last Update (14.0.0.3) - [RadioCommand](#radiocommand) - [RadioRangeLevel](#radiorangelevel) - [RejectionReason](#rejectionreason) +- [RejectionReason](#rejectionreason) - [ReloaderMessageHeader](#reloadermessageheader) - [RemoteAdminResponseFlags](#remoteadminresponseflags) - [RemovalMode](#removalmode) - [ReproProjectAssetType](#reproprojectassettype) - [RequestType](#requesttype) - [RespawnSetting](#respawnsetting) +- [RespawnTooltipTranslation](#respawntooltiptranslation) - [ResurrectError](#resurrecterror) - [RoleChangeReason](#rolechangereason) - [RoleSpawnFlags](#rolespawnflags) @@ -257,6 +265,7 @@ Last Update (14.0.0.3) - [RpcType](#rpctype) - [RpcType](#rpctype) - [RpcType](#rpctype) +- [RpcType](#rpctype) - [ScanSequenceStep](#scansequencestep) - [Scp0492SoundId](#scp0492soundid) - [Scp079HudTranslation](#scp079hudtranslation) @@ -264,6 +273,8 @@ Last Update (14.0.0.3) - [Scp096HitResult](#scp096hitresult) - [Scp096HudTranslation](#scp096hudtranslation) - [Scp096RageState](#scp096ragestate) +- [Scp127Tier](#scp127tier) +- [Scp127VoiceLinesTranslation](#scp127voicelinestranslation) - [Scp1344Status](#scp1344status) - [Scp173SoundId](#scp173soundid) - [Scp244State](#scp244state) @@ -275,8 +286,10 @@ Last Update (14.0.0.3) - [Scp939DamageType](#scp939damagetype) - [Scp939HudTranslation](#scp939hudtranslation) - [Scp939LungeState](#scp939lungestate) +- [ScpSetting](#scpsetting) - [SecurityLevel](#securitylevel) - [SensitivitySetting](#sensitivitysetting) +- [SequenceState](#sequencestate) - [ServerLogType](#serverlogtype) - [ServerOperativeSystem](#serveroperativesystem) - [ServerRateLimit](#serverratelimit) @@ -319,6 +332,7 @@ Last Update (14.0.0.3) - [VersionType](#versiontype) - [VoiceChatChannel](#voicechatchannel) - [VoiceChatSupportMode](#voicechatsupportmode) +- [VoiceLinePriority](#voicelinepriority) - [VoiceLinesName](#voicelinesname) - [VolumeSliderSetting](#volumeslidersetting) - [WarheadScenarioType](#warheadscenariotype) @@ -383,6 +397,7 @@ Last Update (14.0.0.3) [48] = UndeadSpaceProgram [49] = ArizonaRanger [50] = Matador + [51] = ToothAndNail ``` @@ -987,27 +1002,15 @@ Last Update (14.0.0.3) -### CheckpointErrorType - -
Interactables.Interobjects.CheckpointDoor+CheckpointErrorType - -``` - [0] = Denied - [1] = LockedDown - [2] = Destroyed -``` - -
- -### CheckpointSequenceStage +### ChaosMsgType -
Interactables.Interobjects.CheckpointDoor+CheckpointSequenceStage +
InventorySystem.Items.Keycards.ChaosKeycardItem+ChaosMsgType ``` - [0] = Idle - [1] = Granted - [2] = Open - [3] = Closing + [0] = SnakeMsgSync + [1] = NewConnectionFullSync + [2] = MovementSwitch + [3] = UseDetails ```
@@ -1162,6 +1165,18 @@ Last Update (14.0.0.3)
+### ColliderShape + +
AdminToys.InvisibleInteractableToy+ColliderShape + +``` + [0] = Box + [1] = Sphere + [2] = Capsule +``` + +
+ ### CollisionsDisablingReasons
Interactables.Interobjects.DoorUtils.DoorVariant+CollisionsDisablingReasons @@ -1414,6 +1429,18 @@ Last Update (14.0.0.3)
+### DetectionStatus + +
InventorySystem.Items.Firearms.Modules.Scp127.Scp127CassieBasedVoiceTriggerBase+DetectionStatus + +``` + [0] = Idle + [1] = WaitingForTrigger + [2] = AnnouncementStartedPlaying +``` + +
+ ### DiodeType
AlphaWarheadNukesitePanel+DiodeType @@ -1586,6 +1613,28 @@ Last Update (14.0.0.3)
+### DoorPermissionFlags + +
Interactables.Interobjects.DoorUtils.DoorPermissionFlags + +``` + [0] = None + [1] = Checkpoints + [2] = ExitGates + [4] = Intercom + [8] = AlphaWarhead + [16] = ContainmentLevelOne + [32] = ContainmentLevelTwo + [64] = ContainmentLevelThree + [128] = ArmoryLevelOne + [256] = ArmoryLevelTwo + [512] = ArmoryLevelThree + [1024] = ScpOverride + [65535] = All +``` + +
+ ### DropdownEntryType
UserSettings.ServerSpecific.SSDropdownSetting+DropdownEntryType @@ -1650,6 +1699,7 @@ Last Update (14.0.0.3) [6] = Nuke01 [7] = Scp049 [8] = Nuke02 + [9] = ServerRoom ```
@@ -1659,11 +1709,12 @@ Last Update (14.0.0.3)
Interactables.Interobjects.ElevatorChamber+ElevatorSequence ``` - [0] = DoorClosing - [1] = MovingAway - [2] = Arriving - [3] = DoorOpening - [4] = Ready + [0] = StartingSequence + [1] = DoorClosing + [2] = MovingAway + [3] = Arriving + [4] = DoorOpening + [5] = Ready ```
@@ -2024,6 +2075,7 @@ Last Update (14.0.0.3) [9] = HalloweenOutside [10] = ChristmasInside [11] = ChristmasOutside + [12] = PocketDimension ``` @@ -2073,6 +2125,29 @@ Last Update (14.0.0.3) +### ForceCondition + +
PlayerRoles.FirstPersonControl.Thirdperson.Subcontrollers.GlowInTheDarkSubcontroller+ForceCondition + +``` + [0] = NeverForce + [1] = ForceWhenFriendly + [2] = ForceWhenEnemy +``` + +
+ +### ForceResult + +
PlayerRoles.FirstPersonControl.Thirdperson.Subcontrollers.GlowInTheDarkSubcontroller+ForceResult + +``` + [0] = ForceDarkened + [1] = ForceNormal +``` + +
+ ### FpcViewMode
PlayerRoles.FirstPersonControl.FpcMotor+FpcViewMode @@ -2270,6 +2345,7 @@ Last Update (14.0.0.3) [15] = PackedLong [16] = PackedULong [17] = Scp330Hint + [18] = SSKeybind ```
@@ -2500,6 +2576,8 @@ Last Update (14.0.0.3) [24] = JailbirdChargeHint [25] = MicroHidReadyToDischarge [26] = MicroHidDamaged + [27] = Scp127OnEquip + [28] = SnakeHint ``` @@ -2660,6 +2738,13 @@ Last Update (14.0.0.3) [57] = Coal [58] = SpecialCoal [59] = SCP1507Tape + [60] = DebugRagdollMover + [61] = SurfaceAccessPass + [62] = GunSCP127 + [63] = KeycardCustomTaskForce + [64] = KeycardCustomSite02 + [65] = KeycardCustomManagement + [66] = KeycardCustomMetalCase [-1] = None ``` @@ -2719,23 +2804,48 @@ Last Update (14.0.0.3) -### KeycardPermissions +### KeycardLabelTranslation -
Interactables.Interobjects.DoorUtils.KeycardPermissions +
InventorySystem.Items.Keycards.TranslatedLabelDetail+KeycardLabelTranslation ``` - [0] = None - [1] = Checkpoints - [2] = ExitGates - [4] = Intercom - [8] = AlphaWarhead - [16] = ContainmentLevelOne - [32] = ContainmentLevelTwo - [64] = ContainmentLevelThree - [128] = ArmoryLevelOne - [256] = ArmoryLevelTwo - [512] = ArmoryLevelThree - [1024] = ScpOverride + [0] = Scientist + [1] = Janitor + [2] = ResearchSupervisor + [3] = ContEngineer + [4] = SecurityGuard + [5] = ZoneManager + [6] = FacilityManager + [7] = SurfaceAccessPassNormal + [8] = SurfaceAccessPassUsed +``` + +
+ +### KeyCodeTranslations + +
Hints.KeyCodeTranslations + +``` + [0] = ServerSettingNotFound + [1] = KeyNotAssigned + [2] = ArrowUp + [3] = ArrowDown + [4] = ArrowLeft + [5] = ArrowRight + [6] = LeftShift + [7] = RightShift + [8] = LeftControl + [9] = RightControl + [10] = LeftAlt + [11] = RightAlt + [12] = Tab + [13] = Space + [14] = Enter + [15] = MousePrimary + [16] = MouseSecondary + [17] = MouseMiddle + [18] = MouseN ```
@@ -2853,12 +2963,14 @@ Last Update (14.0.0.3)
MapGeneration.MapGenerationPhase ``` - [0] = ParentRoomRegistration - [1] = RelativePositioningWaypoints - [2] = ComplexDecorationsAndClutter - [3] = SimpleDecorations - [4] = CullingCaching - [5] = SpawnableStructures + [0] = RoomCoordsRegistrations + [1] = ParentRoomRegistration + [2] = RelativePositioningWaypoints + [3] = ComplexDecorationsAndClutter + [4] = SimpleDecorations + [5] = CullingCaching + [6] = SpawnableStructures + [7] = StaticBatching ```
@@ -2887,6 +2999,7 @@ Last Update (14.0.0.3) [3] = RpcFire [4] = RpcDryFire [5] = RpcNewPlayerSync + [6] = RpcRejectionReason ```
@@ -2925,9 +3038,10 @@ Last Update (14.0.0.3) [1] = RpcRequireReloadFalse [2] = RpcRequireReloadFullResync [3] = RpcStartFiring - [4] = RpcOnShot - [5] = CmdRequestStartFiring - [6] = CmdConfirmDischarge + [4] = RpcStopFiring + [5] = RpcOnShot + [6] = CmdRequestStartFiring + [7] = CmdConfirmDischarge ``` @@ -2989,6 +3103,7 @@ Last Update (14.0.0.3) [5] = RightClickToDrop [6] = InventoryToggle [7] = Scp079KeybindZoneSwitching + [8] = AutomaticSpectatorSwitch ``` @@ -3019,6 +3134,7 @@ Last Update (14.0.0.3) [2] = HeadBobbing [3] = FlashbangDarkMode [4] = ShowNeedles + [5] = Scp939VisionBlur ``` @@ -3033,6 +3149,7 @@ Last Update (14.0.0.3) [2] = Weapons [3] = VoiceChat [4] = NoDucking + [5] = Scp127VoiceViewmodel ``` @@ -3093,6 +3210,19 @@ Last Update (14.0.0.3) +### MsgType + +
InventorySystem.Items.Keycards.KeycardItem+MsgType + +``` + [0] = Custom + [1] = OnKeycardUsed + [2] = Inspect + [3] = NewPlayerFullResync +``` + +
+ ### NatAddressType
LiteNetLib.NatAddressType @@ -3659,6 +3789,19 @@ Last Update (14.0.0.3)
+### RejectionReason + +
InventorySystem.Items.Firearms.Modules.AutomaticActionModule+RejectionReason + +``` + [1] = TimedOut + [2] = ModuleBusy + [3] = NotCocked + [4] = BoltLocked +``` + +
+ ### ReloaderMessageHeader
InventorySystem.Items.Firearms.Modules.AnimatorReloaderModuleBase+ReloaderMessageHeader @@ -3732,6 +3875,18 @@ Last Update (14.0.0.3)
+### RespawnTooltipTranslation + +
Respawning.Graphics.RespawnTooltipTranslation + +``` + [0] = TimerBarTranslation + [1] = InfluenceTranslation + [2] = RespawnsTokensTranslation +``` + +
+ ### ResurrectError
PlayerRoles.PlayableScps.Scp049.Scp049ResurrectAbility+ResurrectError @@ -3861,6 +4016,7 @@ Last Update (14.0.0.3) [35] = Outside [36] = Pocket [37] = HczTestroom + [38] = Hcz127 ```
@@ -4042,6 +4198,17 @@ Last Update (14.0.0.3) ### RpcType +
InventorySystem.Items.Firearms.Modules.Scp127.Scp127VoiceLineManagerModule+RpcType + +``` + [0] = OwnerRegistered + [1] = PlayLine +``` + +
+ +### RpcType +
InventorySystem.Items.Firearms.Attachments.FlashlightAttachment+RpcType ``` @@ -4236,6 +4403,181 @@ Last Update (14.0.0.3)
+### Scp127Tier + +
InventorySystem.Items.Firearms.Modules.Scp127.Scp127Tier + +``` + [0] = Tier1 + [1] = Tier2 + [2] = Tier3 +``` + +
+ +### Scp127VoiceLinesTranslation + +
InventorySystem.Items.Firearms.Modules.Scp127.Scp127VoiceLinesTranslation + +``` + [0] = ChamberingDammitThatHurts + [1] = ChamberingFeelThatTmrw + [2] = ChamberingGrunt1 + [3] = ChamberingGrunt2 + [4] = ChamberingGrunt3 + [5] = ChamberingGrunt4 + [6] = ChamberingHateThatPart + [7] = ChamberingNopeNeverGettinBetter + [8] = ChamberingThatStings + [9] = ChaosSpawnDrowningConstantly + [10] = ChaosSpawnIDontTrustEm + [11] = ChaosSpawnNotHereNotAgain + [12] = ChaosSpawnNotJustMe + [13] = ChaosSpawnThemAgain + [14] = ChaosSpawnThisIsntGonnaEndWell + [15] = DrawGoodToSeeYa + [16] = DrawHelloAgain + [17] = DrawHelloThere + [18] = DrawHello + [19] = DrawHeyHey + [20] = DrawHowsItGoin + [21] = DroppedDontForgetAboutMe + [22] = DroppedGuessIllWaitHere + [23] = DroppedIllCatchUp + [24] = DroppedSeeyaLaterBoss + [25] = DroppedTakeCareBoss + [26] = DroppedWatchThePaint + [27] = HolsterBeHereIfYouNeedMe + [28] = HolsterByeBye + [29] = HolsterFairEnough + [30] = HolsterGoodbye + [31] = HolsterIsTheSafetyOn2 + [32] = HolsterIsTheSafetyOn + [33] = HolsterOffIGo + [34] = HolsterYouKnowWhereToFindMeBoss + [35] = IdleChatterBarDownInQueens + [36] = IdleChatterDifferentFacility + [37] = IdleChatterGettingPaidForThisRight + [38] = IdleChatterSoundedLikeDeath + [39] = IdleChatterThoughtIHeardSomething + [40] = IdleChatterWhatWentWrong + [41] = IdleChatterYouGotAnyPlans + [42] = IdleChatterYouKnowWhereYoureGoin + [43] = MissedAlmostHitSomething + [44] = MissedILikeYourStyleBoss + [45] = MissedInvisHatFellaAround + [46] = MissedUhYouGoodBoss + [47] = MtfSpawnAhaReinforcements + [48] = MtfSpawnDontLetEmTakeMeAgain + [49] = MtfSpawnDontSayAnything + [50] = MtfSpawnFriendsOfYours + [51] = MtfSpawnGotAPlan + [52] = MtfSpawnThatsNotGood + [53] = MtfSpawnThingsAreGettingInterestingNow + [54] = MtfSpawnWereGettingBackup + [55] = OnKillBang + [56] = OnKillBeatItBopIt + [57] = OnKillGoodOneBoss + [58] = OnKillGoodStuff + [59] = OnKillGoodWorkBoss + [60] = OnKillNiceOneBoss + [61] = OnKillNiceShot + [62] = OnKillOooNice + [63] = OnKillRattleHim + [64] = OnKillScram + [65] = OnKillWhamo + [66] = PickupChamberNecksnapMcgee + [67] = PickupChamberPleasedToMeetYa + [68] = PickupChamberRoomForOneMore + [69] = PickupChamberSayWhatYearIsIt + [70] = PickupChamberSweetOxygen + [71] = PickupChamberWaterboarding + [72] = PickupChaosGasMask + [73] = PickupChaosSickGladRagsBoss + [74] = PickupChaosYouFellasFromOuttaTown + [75] = PickupDclassCouplaCorpses + [76] = PickupDclassNeedAHand + [77] = PickupDclassPartnersInCrime + [78] = PickupDclassTagEmBoss + [79] = PickupDclassUsedToOwnAJumpsuit + [80] = PickupDclassWooBreakout + [81] = PickupGenericEasyOnTheGrip + [82] = PickupGenericHeyBossHowsItGoin + [83] = PickupGenericSobbing + [84] = PickupGenericTakeMeWith + [85] = PickupMtfAnyChanceICanGo + [86] = PickupMtfAwJeezRick + [87] = PickupScientistDidntYouStickMeInThatTank + [88] = PickupScientistThoseGlassesBetterBe + [89] = PickupScientistYouDoKnowHowToShootRight + [90] = PickupTutorialHereToRescueMe + [91] = PickupTutorialOutOfPlaceHereBoss + [92] = RankupBetterThanExpected + [93] = RankupDoinPrettyGood + [94] = RankupFeelsGoodToBeBack + [95] = RankupIThinkWereWinning + [96] = RankupManicLaughter + [97] = RankupPartnersInCrimeOrJustice + [98] = ScpKilled049AppleADay + [99] = ScpKilled049BehindThatBeak + [100] = ScpKilled049IAmTheBlackDeath + [101] = ScpKilled049MsBirdface + [102] = ScpKilled049OverdosedOnShells + [103] = ScpKilled049ResurrectThis + [104] = ScpKilled049TakeGoodCareOfTheKids + [105] = ScpKilled0790101Moron + [106] = ScpKilled079AintDyinToAMinifridge + [107] = ScpKilled079KeepTheCamera + [108] = ScpKilled079NeverLikedThatToaster + [109] = ScpKilled079WarrantyRunOut + [110] = ScpKilled0967FeetTall + [111] = ScpKilled096AllTheRage + [112] = ScpKilled096IMayNotHaveEyes2 + [113] = ScpKilled096IMayNotHaveEyes + [114] = ScpKilled096LikedTheStatue + [115] = ScpKilled096ThoughtHedNeverShutUp + [116] = ScpKilled106HaveFunInTheCage + [117] = ScpKilled106OldDudesGone + [118] = ScpKilled106PocketThisDimension + [119] = ScpKilled106SinkingFeeling + [120] = ScpKilled106StayForABit + [121] = ScpKilled106SunkIntoTheFloor + [122] = ScpKilled173EyeOpener + [123] = ScpKilled173PeiceThatBackTogether + [124] = ScpKilled173ScrapingWasGettingOnMyNerves + [125] = ScpKilled173ShatteredLikeGlass + [126] = ScpKilled939NothingToSayNow + [127] = ScpKilled939StayDownFreakshow + [128] = ScpKilled939YouAintTheFirst2 + [129] = ScpKilled939YouAintTheFirst + [130] = ScpKilled3114NoMoreBones + [131] = ScpKilled3114OneLessSkeleton + [132] = ScpKilled3114WeGotTheSkinwalker + [133] = ScpKilledAllThoseFreakyPowers + [134] = ScpKilledCoupleOfRounds + [135] = ScpKilledGunBeatsWhateverYouAre2 + [136] = ScpKilledGunBeatsWhateverYouAre + [137] = ScpKilledNotSoTough + [138] = ScpKilledWhyBuildAContainer + [139] = ScpKilledZombieAintNoPill + [140] = ScpKilledZombieGetHisGoons + [141] = ScpKilledZombieMr12FeetUnder + [142] = ScpKilledZombieSayGoodbyeToUrGoons + [143] = ScpKilledZombieStayDown + [144] = ScpKilledZombieTwoLivesTooMany + [145] = ScpKilledZombieWhatGetsUp + [146] = UserKilledAttacthmentIssues + [147] = UserKilledBooooosss + [148] = UserKilledHeyHeyGetUp + [149] = UserKilledJustStartingToLikeYou + [150] = UserKilledNoNotNow2 + [151] = UserKilledNoNotNow + [152] = UserKilledNotAgain2 + [153] = UserKilledNotAgain +``` + +
+ ### Scp1344Status
InventorySystem.Items.Usables.Scp1344.Scp1344Status @@ -4438,6 +4780,16 @@ Last Update (14.0.0.3)
+### ScpSetting + +
UserSettings.OtherSettings.ScpSetting + +``` + [0] = ScpOptOut +``` + +
+ ### SecurityLevel
EncryptedChannelManager+SecurityLevel @@ -4461,6 +4813,19 @@ Last Update (14.0.0.3)
+### SequenceState + +
Interactables.Interobjects.CheckpointDoor+SequenceState + +``` + [0] = Idle + [1] = Granted + [2] = OpenLoop + [3] = ClosingWarning +``` + +
+ ### ServerLogType
ServerLogs+ServerLogType @@ -4894,6 +5259,7 @@ Last Update (14.0.0.3) [4] = Trigger [8] = Tokens [11] = All + [16] = Spawn ```
@@ -5067,6 +5433,19 @@ Last Update (14.0.0.3) +### VoiceLinePriority + +
InventorySystem.Items.Firearms.Modules.Scp127.Scp127VoiceTriggerBase+VoiceLinePriority + +``` + [0] = Low + [1] = Normal + [2] = High + [3] = VeryHigh +``` + +
+ ### VoiceLinesName
PlayerRoles.PlayableScps.Scp3114.Scp3114VoiceLines+VoiceLinesName @@ -5093,6 +5472,8 @@ Last Update (14.0.0.3) [2] = SoundEffects [3] = MenuMusic [4] = MenuUI + [5] = Scp127Voice + [6] = Scp3114Voice ```
@@ -5124,12 +5505,13 @@ Last Update (14.0.0.3) ### WearableElements -
PlayerRoles.FirstPersonControl.Thirdperson.Subcontrollers.WearableElements +
PlayerRoles.FirstPersonControl.Thirdperson.Subcontrollers.Wearables.WearableElements ``` [0] = None [1] = Scp268Hat [2] = Scp1344Goggles + [4] = Armor ```
@@ -5213,7 +5595,7 @@ Last Update (14.0.0.3)
Damage Handlers -```md title="Latest Updated: 14.0.0.3" +```md title="Latest Updated: 14.1.0.0" All available DamageHandlers + Symbol ':' literally means "inherits from" @@ -5223,6 +5605,7 @@ All available DamageHandlers Scp956DamageHandler : StandardDamageHandler SnowballDamageHandler : AttackerDamageHandler PlayerStatsSystem.CustomReasonDamageHandler : StandardDamageHandler +PlayerStatsSystem.CustomReasonFirearmDamageHandler : FirearmDamageHandler PlayerStatsSystem.DisruptorDamageHandler : AttackerDamageHandler PlayerStatsSystem.ExplosionDamageHandler : AttackerDamageHandler PlayerStatsSystem.FirearmDamageHandler : AttackerDamageHandler