diff --git a/Exiled.API/Enums/AdminToyType.cs b/Exiled.API/Enums/AdminToyType.cs index 6a4f1324a4..0eb3e1884f 100644 --- a/Exiled.API/Enums/AdminToyType.cs +++ b/Exiled.API/Enums/AdminToyType.cs @@ -27,5 +27,10 @@ public enum AdminToyType /// ShootingTarget toy. /// ShootingTarget, + + /// + /// Speaker toy. + /// + Speaker, } } \ No newline at end of file diff --git a/Exiled.API/Enums/BloodType.cs b/Exiled.API/Enums/BloodType.cs index 18a27255b2..d4066ccce4 100644 --- a/Exiled.API/Enums/BloodType.cs +++ b/Exiled.API/Enums/BloodType.cs @@ -10,8 +10,6 @@ namespace Exiled.API.Enums /// /// Unique identifier for the different types of blood decals. /// - /// - /// public enum BloodType { /// diff --git a/Exiled.API/Enums/CameraType.cs b/Exiled.API/Enums/CameraType.cs index c72624b009..6a6fedfff5 100644 --- a/Exiled.API/Enums/CameraType.cs +++ b/Exiled.API/Enums/CameraType.cs @@ -124,6 +124,19 @@ public enum CameraType Hcz173ContChamber, Hcz173Hallway, HczCurve, + HczJunkMain, + HczJunkHallway, + HczCornerDeep, + HczDss08, + HczMicroHidStairs, + HczPipesHallway, + HczWarheadStarboardElevator, + HczMicroHidMain, + HczWarheadTopElevators, + HczWarheadConnector, + HczWarheadPortElevator, + HczMicroHidLab, + HczPipesMain, #endregion } } diff --git a/Exiled.API/Enums/DamageType.cs b/Exiled.API/Enums/DamageType.cs index 9aec9fc647..9f522246d1 100644 --- a/Exiled.API/Enums/DamageType.cs +++ b/Exiled.API/Enums/DamageType.cs @@ -249,5 +249,10 @@ public enum DamageType /// Damage caused by the marshmallow man. /// Marshmallow, + + /// + /// Damage caused by . + /// + Scp1344, } } diff --git a/Exiled.API/Enums/DoorType.cs b/Exiled.API/Enums/DoorType.cs index 0feb0ffa7f..2404d09837 100644 --- a/Exiled.API/Enums/DoorType.cs +++ b/Exiled.API/Enums/DoorType.cs @@ -7,9 +7,8 @@ namespace Exiled.API.Enums { - using Exiled.API.Features.Doors; - - using static Interactables.Interobjects.ElevatorManager; + using Features.Doors; + using Interactables.Interobjects; /// /// Unique identifier for the different types of doors. @@ -158,20 +157,25 @@ public enum DoorType /// HeavyContainmentDoor, + /// + /// Represents the new door style introduced in 14.0 (Bulk Doors in Heavy). + /// + HeavyBulkDoor, + /// /// Represents the HID door. /// - HID, + HidChamber, /// - /// Represents the HID_LEFT door. + /// Represents the HID_UPPER door. /// - HIDLeft, + HidUpper, /// - /// Represents the HID_RIGHT door. + /// Represents the HID_LOWER door. /// - HIDRight, + HidLower, /// /// Represents the INTERCOM door. @@ -229,9 +233,14 @@ public enum DoorType Scp330Chamber, /// - /// Represents the Gate in the Checkpoint between EZ and HCZ. + /// Represents the Gate in the Checkpoint between EZ and HCZ (Checkpoint A). + /// + CheckpointGateA, + + /// + /// Represents the Gate in the Checkpoint between EZ and HCZ (Checkpoint B). /// - CheckpointGate, + CheckpointGateB, /// /// Represents the Gate in the Checkpoint between EZ and HCZ. @@ -269,9 +278,14 @@ public enum DoorType ElevatorGateB, /// - /// Represents the Elevator door for . + /// Represents the Elevator door for . + /// + ElevatorNuke1, + + /// + /// Represents the Elevator door for . /// - ElevatorNuke, + ElevatorNuke2, /// /// Represents the Elevator door for . @@ -307,5 +321,10 @@ public enum DoorType /// Represents the New Gate where Scp173 spawn in the . /// Scp173NewGate, + + /// + /// Represents the ESCAPE_FINAL door. + /// + EscapeFinal, } } \ No newline at end of file diff --git a/Exiled.API/Enums/EffectType.cs b/Exiled.API/Enums/EffectType.cs index bfd2278d2a..858d535c27 100644 --- a/Exiled.API/Enums/EffectType.cs +++ b/Exiled.API/Enums/EffectType.cs @@ -9,7 +9,7 @@ namespace Exiled.API.Enums { using System; - using Exiled.API.Extensions; + using Extensions; /// /// Status effects as enum. @@ -239,5 +239,25 @@ public enum EffectType /// . /// Slowness, + + /// + /// . + /// + Scp1344, + + /// + /// . + /// + SeveredEyes, + + /// + /// . + /// + PitDeath, + + /// + /// . + /// + Blurred, } } diff --git a/Exiled.API/Enums/ElevatorType.cs b/Exiled.API/Enums/ElevatorType.cs index 3c2518ea69..b257a23304 100644 --- a/Exiled.API/Enums/ElevatorType.cs +++ b/Exiled.API/Enums/ElevatorType.cs @@ -30,9 +30,14 @@ public enum ElevatorType : byte GateB, /// - /// Heavy Containment Zone Nuke elevator. + /// Heavy Containment Zone Nuke 1 elevator. /// - Nuke, + Nuke1, + + /// + /// Heavy Containment Zone Nuke 2 elevator. + /// + Nuke2, /// /// Heavy Containment Zone SCP-049 elevator. diff --git a/Exiled.API/Enums/RespawnEffectType.cs b/Exiled.API/Enums/RespawnEffectType.cs index 77c0b26c61..b6edfcaf2b 100644 --- a/Exiled.API/Enums/RespawnEffectType.cs +++ b/Exiled.API/Enums/RespawnEffectType.cs @@ -7,30 +7,19 @@ namespace Exiled.API.Enums { - using Features; - - using PlayerRoles; - /// /// Layers game respawn effects. /// - /// - /// - public enum RespawnEffectType : byte + public enum RespawnEffectType { - /// - /// Plays the music to alive and . - /// - PlayChaosInsurgencyMusic = 0, - /// /// Summons the van. /// - SummonChaosInsurgencyVan = 128, + SummonChaosInsurgencyVan, /// /// Summons the NTF chopper. /// - SummonNtfChopper = 129, + SummonNtfChopper, } } \ No newline at end of file diff --git a/Exiled.API/Enums/RoomType.cs b/Exiled.API/Enums/RoomType.cs index e74f07ecff..9b1d7b8e3f 100644 --- a/Exiled.API/Enums/RoomType.cs +++ b/Exiled.API/Enums/RoomType.cs @@ -235,10 +235,15 @@ public enum RoomType EzGateB, /// - /// Entrance Zone's Shelter rfoom. + /// Entrance Zone's Shelter room. /// EzShelter, + /// + /// Entrance Zone's straight hall with Chef's locked room. + /// + EzChef, + /// /// The Pocket Dimension. /// @@ -265,9 +270,14 @@ public enum RoomType Lcz330, /// - /// Entrance Zone's straight hall before the entrance/heavy checkpoint. + /// Entrance Zone's straight hall before the entrance/heavy checkpoint (Checkpoint Hallway A). /// - EzCheckpointHallway, + EzCheckpointHallwayA, + + /// + /// Entrance Zone's straight hall before the entrance/heavy checkpoint (Checkpoint Hallway B). + /// + EzCheckpointHallwayB, /// /// Heavy Containment Zone's test room's straight hall. @@ -283,5 +293,40 @@ public enum RoomType /// Heavy Containment Elevator Zone's System B room. /// HczElevatorB, + + /// + /// Waterfall Room. + /// + HczCrossRoomWater, + + /// + /// Heavy Containment Corner Room. + /// + HczCornerDeep, + + /// + /// Heavy Containment Junk Intersection. + /// + HczIntersectionJunk, + + /// + /// Intersection in Heavy Containment. + /// + HczIntersection, + + /// + /// Straight Hallway variant in Heavy Containment. + /// + HczStraightC, + + /// + /// Straight Hallway with Pipes in Heavy Containment. + /// + HczStraightPipeRoom, + + /// + /// Straight Hallway variant in Heavy Containment. + /// + HczStraightVariant, } } \ No newline at end of file diff --git a/Exiled.API/Enums/SpawnableWave.cs b/Exiled.API/Enums/SpawnableWave.cs new file mode 100644 index 0000000000..1904461b70 --- /dev/null +++ b/Exiled.API/Enums/SpawnableWave.cs @@ -0,0 +1,35 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.API.Enums +{ + /// + /// All spawnable factions and mini-waves available. + /// + public enum SpawnableWave + { + /// + /// Represents a normal spawnable Ntf wave. + /// + NtfWave, + + /// + /// Represents a spawnable smaller Ntf wave. + /// + NtfMiniWave, + + /// + /// Represents a normal spawnable Chaos wave. + /// + ChaosWave, + + /// + /// Represents a spawnable smaller Chaos wave. + /// + ChaosMiniWave, + } +} \ No newline at end of file diff --git a/Exiled.API/Enums/ZoneType.cs b/Exiled.API/Enums/ZoneType.cs index 126757de9f..7e478c95c5 100644 --- a/Exiled.API/Enums/ZoneType.cs +++ b/Exiled.API/Enums/ZoneType.cs @@ -51,9 +51,14 @@ public enum ZoneType /// Surface = 8, + /// + /// The Pocket Dimension. + /// + Pocket = 16, + /// /// An unknown type of zone. /// - Other = 16, + Other = 32, } } \ No newline at end of file diff --git a/Exiled.API/Extensions/DamageTypeExtensions.cs b/Exiled.API/Extensions/DamageTypeExtensions.cs index 0d2816efbd..f158624f36 100644 --- a/Exiled.API/Extensions/DamageTypeExtensions.cs +++ b/Exiled.API/Extensions/DamageTypeExtensions.cs @@ -51,6 +51,7 @@ public static class DamageTypeExtensions { DeathTranslations.MicroHID, DamageType.MicroHid }, { DeathTranslations.Hypothermia, DamageType.Hypothermia }, { DeathTranslations.MarshmallowMan, DamageType.Marshmallow }, + { DeathTranslations.Scp1344, DamageType.Scp1344 }, }; private static readonly Dictionary ItemConversionInternal = new() diff --git a/Exiled.API/Extensions/DoorTypeExtensions.cs b/Exiled.API/Extensions/DoorTypeExtensions.cs index c4b512dd13..be863707a8 100644 --- a/Exiled.API/Extensions/DoorTypeExtensions.cs +++ b/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 or not. 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.ElevatorNuke1 or DoorType.ElevatorNuke2 or DoorType.ElevatorScp049; } } \ No newline at end of file diff --git a/Exiled.API/Extensions/EffectTypeExtension.cs b/Exiled.API/Extensions/EffectTypeExtension.cs index bb9d1d00a9..58ec69610e 100644 --- a/Exiled.API/Extensions/EffectTypeExtension.cs +++ b/Exiled.API/Extensions/EffectTypeExtension.cs @@ -15,7 +15,7 @@ namespace Exiled.API.Extensions using CustomPlayerEffects; using CustomRendering; using Enums; - using Exiled.API.Features; + using Features; using InventorySystem.Items.MarshmallowMan; using InventorySystem.Items.Usables.Scp244.Hypothermia; using PlayerRoles.FirstPersonControl; @@ -34,7 +34,7 @@ public static class EffectTypeExtension { EffectType.AmnesiaVision, typeof(AmnesiaVision) }, { EffectType.Asphyxiated, typeof(Asphyxiated) }, { EffectType.Bleeding, typeof(Bleeding) }, - { EffectType.Blinded, typeof(Blinded) }, + { EffectType.Blinded, typeof(Blindness) }, { EffectType.BodyshotReduction, typeof(BodyshotReduction) }, { EffectType.Burned, typeof(Burned) }, { EffectType.CardiacArrest, typeof(CardiacArrest) }, @@ -75,6 +75,10 @@ public static class EffectTypeExtension { EffectType.Ghostly, typeof(Ghostly) }, { EffectType.FogControl, typeof(FogControl) }, { EffectType.Slowness, typeof(Slowness) }, + { EffectType.Scp1344, typeof(Scp1344) }, + { EffectType.SeveredEyes, typeof(SeveredEyes) }, + { EffectType.PitDeath, typeof(PitDeath) }, + { EffectType.Blurred, typeof(Blurred) }, }); /// @@ -147,7 +151,7 @@ or EffectType.Corroding or EffectType.Decontaminating or EffectType.Hemorrhage o /// The . /// Whether or not the effect heals. /// - public static bool IsHealing(this EffectType effect) => effect.TryGetType(out Type type) && typeof(IHealablePlayerEffect).IsAssignableFrom(type); + public static bool IsHealing(this EffectType effect) => effect.TryGetType(out Type type) && typeof(IHealableEffect).IsAssignableFrom(type); /// /// Returns whether or not the provided is a negative effect. diff --git a/Exiled.API/Extensions/ItemExtensions.cs b/Exiled.API/Extensions/ItemExtensions.cs index ef96fe510b..0e7f7af1f1 100644 --- a/Exiled.API/Extensions/ItemExtensions.cs +++ b/Exiled.API/Extensions/ItemExtensions.cs @@ -15,8 +15,8 @@ namespace Exiled.API.Extensions using Features.Items; using InventorySystem; using InventorySystem.Items; - using InventorySystem.Items.Firearms; using InventorySystem.Items.Firearms.Attachments; + using InventorySystem.Items.Firearms.Modules; using InventorySystem.Items.Pickups; using InventorySystem.Items.ThrowableProjectiles; using Structs; @@ -125,10 +125,11 @@ public static T GetItemBase(this ItemType type) /// /// The weapon that you want to get maximum of. /// Returns the maximum. - public static byte GetMaxAmmo(this FirearmType type) + public static int GetMaxAmmo(this FirearmType type) { InventorySystem.Items.Firearms.Firearm firearm = GetItemBase(type.GetItemType()); - return firearm is null ? (byte)0 : firearm.AmmoManagerModule.MaxAmmo; + IAmmoContainerModule ammoModule = firearm.Modules.OfType().FirstOrDefault(); + return ammoModule?.AmmoMax ?? 0; } /// diff --git a/Exiled.API/Extensions/MirrorExtensions.cs b/Exiled.API/Extensions/MirrorExtensions.cs index aa38b362e9..a4c5eced93 100644 --- a/Exiled.API/Extensions/MirrorExtensions.cs +++ b/Exiled.API/Extensions/MirrorExtensions.cs @@ -13,22 +13,11 @@ namespace Exiled.API.Extensions using System.Linq; using System.Reflection; using System.Reflection.Emit; - using System.Text; using Features; - using Features.Core.Generic.Pools; - using InventorySystem.Items.Firearms; using Mirror; using PlayerRoles; - using PlayerRoles.FirstPersonControl; - using PlayerRoles.PlayableScps.Scp049.Zombies; using PlayerRoles.Subroutines; - using PlayerRoles.Voice; - using RelativePositioning; - using Respawning; - using UnityEngine; - - using EIntercom = Exiled.API.Features.Intercom; /// /// A set of extensions for Networking. diff --git a/Exiled.API/Features/Camera.cs b/Exiled.API/Features/Camera.cs index 6b0017ab05..ceedbc375a 100644 --- a/Exiled.API/Features/Camera.cs +++ b/Exiled.API/Features/Camera.cs @@ -125,6 +125,21 @@ public class Camera : GameEntity, IWrapper ["SURFACE AIRLOCK"] = CameraType.SurfaceAirlock, ["SURFACE BRIDGE"] = CameraType.SurfaceBridge, ["TUNNEL ENTRANCE"] = CameraType.TunnelEntrance, + + // 14.0 + ["JUNK MAIN"] = CameraType.HczJunkMain, + ["JUNK HALLWAY"] = CameraType.HczJunkHallway, + ["CORNER DEEP"] = CameraType.HczCornerDeep, + ["DSS-08"] = CameraType.HczDss08, + ["MICROHID STAIRS"] = CameraType.HczMicroHidStairs, + ["PIPES HALLWAY"] = CameraType.HczPipesHallway, + ["PIPES MAIN"] = CameraType.HczPipesMain, + ["WARHEAD STARBOARD ELEVATOR"] = CameraType.HczWarheadStarboardElevator, + ["MICROHID MAIN"] = CameraType.HczMicroHidMain, + ["MICROHID LAB"] = CameraType.HczMicroHidLab, + ["WARHEAD TOP ELEVATORS"] = CameraType.HczWarheadTopElevators, + ["WARHEAD CONNECTOR"] = CameraType.HczWarheadConnector, + ["WARHEAD PORT ELEVATOR"] = CameraType.HczWarheadPortElevator, }; private Room room; diff --git a/Exiled.API/Features/DamageHandlers/CustomDamageHandler.cs b/Exiled.API/Features/DamageHandlers/CustomDamageHandler.cs index cf7e5c5e2e..374e47c8b5 100644 --- a/Exiled.API/Features/DamageHandlers/CustomDamageHandler.cs +++ b/Exiled.API/Features/DamageHandlers/CustomDamageHandler.cs @@ -11,7 +11,7 @@ namespace Exiled.API.Features.DamageHandlers using CustomPlayerEffects; using Enums; - using Exiled.API.Extensions; + using Extensions; using Items; using PlayerStatsSystem; using UnityEngine; @@ -102,7 +102,7 @@ public CustomDamageHandler(Player target, Player attacker, float damage, DamageT Base = { Owner = attacker.ReferenceHub }, }; - CustomBase = new FirearmDamageHandler(firearm, target, new BaseFirearmHandler(firearm.Base, damage)); + CustomBase = new FirearmDamageHandler(firearm, target, new BaseFirearmHandler { Firearm = firearm.Base, Damage = damage }); return; } @@ -126,7 +126,7 @@ public CustomDamageHandler(Player target, Player attacker, float damage, Firearm if (firearm.Owner != attacker) firearm.ChangeOwner(firearm.Owner, attacker); - CustomBase = new FirearmDamageHandler(firearm, target, new BaseFirearmHandler(firearm.Base, damage)); + CustomBase = new FirearmDamageHandler(firearm, target, new BaseFirearmHandler { Firearm = firearm.Base, Damage = damage }); } /// diff --git a/Exiled.API/Features/DamageHandlers/GenericDamageHandler.cs b/Exiled.API/Features/DamageHandlers/GenericDamageHandler.cs index 027365a174..9fabceec27 100644 --- a/Exiled.API/Features/DamageHandlers/GenericDamageHandler.cs +++ b/Exiled.API/Features/DamageHandlers/GenericDamageHandler.cs @@ -10,11 +10,13 @@ namespace Exiled.API.Features.DamageHandlers using System.Collections.Generic; using Enums; - using Exiled.API.Extensions; - using Exiled.API.Features.Pickups; + using Extensions; using Footprinting; + using InventorySystem.Items.Firearms.Modules; + using InventorySystem.Items.Firearms.ShotEvents; using InventorySystem.Items.MicroHID; using Items; + using Pickups; using PlayerRoles.PlayableScps.Scp096; using PlayerRoles.PlayableScps.Scp3114; using PlayerRoles.PlayableScps.Scp939; @@ -50,6 +52,7 @@ public class GenericDamageHandler : CustomReasonDamageHandler [DamageType.Scp0492] = DeathTranslations.Zombie, [DamageType.Scp106] = DeathTranslations.PocketDecay, [DamageType.Scp3114] = DeathTranslations.Scp3114Slap, + [DamageType.Scp1344] = DeathTranslations.Scp1344, }; private static readonly Dictionary DamageToItemType = new() @@ -133,10 +136,10 @@ public GenericDamageHandler(Player player, Player attacker, float damage, Damage Base = new MicroHidDamageHandler(microHidOwner, damage); break; case DamageType.Explosion: - Base = new ExplosionDamageHandler(attacker.Footprint, UnityEngine.Vector3.zero, damage, 0); + Base = new ExplosionDamageHandler(attacker.Footprint, Vector3.zero, damage, 0, ExplosionType.Grenade); break; case DamageType.ParticleDisruptor: - Base = new DisruptorDamageHandler(Attacker, damage); + Base = new DisruptorDamageHandler(new DisruptorShotEvent(Item.Create(ItemType.ParticleDisruptor, attacker).Base as InventorySystem.Items.Firearms.Firearm, DisruptorActionModule.FiringState.FiringSingle), Vector3.up, damage); break; case DamageType.Scp096: Scp096Role curr096 = attacker.Role.Is(out Roles.Scp096Role scp096) ? scp096.Base : new GameObject().AddComponent(); @@ -222,7 +225,7 @@ private void GenericFirearm(Player player, Player attacker, float amount, Damage Owner = attacker.ReferenceHub, }, }; - Base = new PlayerStatsSystem.FirearmDamageHandler(firearm.Base, amount); + Base = new PlayerStatsSystem.FirearmDamageHandler { Firearm = firearm.Base, Damage = amount }; } } } diff --git a/Exiled.API/Features/Doors/Door.cs b/Exiled.API/Features/Doors/Door.cs index a411925ff4..93a5bbadd0 100644 --- a/Exiled.API/Features/Doors/Door.cs +++ b/Exiled.API/Features/Doors/Door.cs @@ -20,8 +20,6 @@ namespace Exiled.API.Features.Doors using Mirror; using UnityEngine; - using static Interactables.Interobjects.ElevatorManager; - using BaseBreakableDoor = Interactables.Interobjects.BreakableDoor; using BaseKeycardPermissions = Interactables.Interobjects.DoorUtils.KeycardPermissions; using Breakable = BreakableDoor; @@ -700,6 +698,7 @@ private DoorType GetDoorType() _ => DoorType.LightContainmentDoor, }, "HCZ" => DoorType.HeavyContainmentDoor, + "BulkDoor" => DoorType.HeavyBulkDoor, "EZ" => DoorType.EntranceDoor, "Prison" => DoorType.PrisonDoor, "914" => DoorType.Scp914Door, @@ -711,13 +710,15 @@ private DoorType GetDoorType() }, "Unsecured" => Room switch { - { Type: RoomType.EzCheckpointHallway } => DoorType.CheckpointGate, + { Type: RoomType.EzCheckpointHallwayA } => DoorType.CheckpointGateA, + { Type: RoomType.EzCheckpointHallwayB } => DoorType.CheckpointGateB, { Type: RoomType.Hcz049 } => Position.y < -805 ? DoorType.Scp049Gate : DoorType.Scp173NewGate, _ => DoorType.UnknownGate, }, "Elevator" => (Base as Interactables.Interobjects.ElevatorDoor) switch { - { Group: ElevatorGroup.Nuke } => DoorType.ElevatorNuke, + { Group: ElevatorGroup.Nuke01 } => DoorType.ElevatorNuke1, + { Group: ElevatorGroup.Nuke02 } => DoorType.ElevatorNuke2, { Group: ElevatorGroup.Scp049 } => DoorType.ElevatorScp049, { Group: ElevatorGroup.GateB } => DoorType.ElevatorGateB, { Group: ElevatorGroup.GateA } => DoorType.ElevatorGateA, @@ -744,7 +745,7 @@ private DoorType GetDoorType() "NUKE_ARMORY" => DoorType.NukeArmory, "LCZ_ARMORY" => DoorType.LczArmory, "SURFACE_NUKE" => DoorType.NukeSurface, - "HID" => DoorType.HID, + "HID_CHAMBER" => DoorType.HidChamber, "HCZ_ARMORY" => DoorType.HczArmory, "096" => DoorType.Scp096, "049_ARMORY" => DoorType.Scp049Armory, @@ -757,8 +758,8 @@ private DoorType GetDoorType() "SERVERS_BOTTOM" => DoorType.ServersBottom, "173_CONNECTOR" => DoorType.Scp173Connector, "LCZ_WC" => DoorType.LczWc, - "HID_RIGHT" => DoorType.HIDRight, - "HID_LEFT" => DoorType.HIDLeft, + "HID_UPPER" => DoorType.HidUpper, + "HID_LOWER" => DoorType.HidLower, "173_ARMORY" => DoorType.Scp173Armory, "173_GATE" => DoorType.Scp173Gate, "GR18" => DoorType.GR18Gate, @@ -767,6 +768,7 @@ private DoorType GetDoorType() "330_CHAMBER" => DoorType.Scp330Chamber, "GR18_INNER" => DoorType.GR18Inner, "939_CRYO" => DoorType.Scp939Cryo, + "ESCAPE_FINAL" => DoorType.EscapeFinal, // Doors spawned by the DoorSpawnPoint component "LCZ_CAFE" => DoorType.LczCafe, diff --git a/Exiled.API/Features/Doors/ElevatorDoor.cs b/Exiled.API/Features/Doors/ElevatorDoor.cs index d5d303d103..404cb3058d 100644 --- a/Exiled.API/Features/Doors/ElevatorDoor.cs +++ b/Exiled.API/Features/Doors/ElevatorDoor.cs @@ -10,8 +10,9 @@ namespace Exiled.API.Features.Doors using System.Collections.Generic; using System.Linq; - using Exiled.API.Enums; + using Enums; using Interactables.Interobjects; + using UnityEngine; /// /// Represents an elevator door. @@ -28,6 +29,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); } /// @@ -36,28 +38,29 @@ internal ElevatorDoor(Interactables.Interobjects.ElevatorDoor door, List r public new Interactables.Interobjects.ElevatorDoor Base { get; } /// - /// Gets the that this door's belongs to. + /// Gets the that this door's belongs to. /// - public ElevatorManager.ElevatorGroup Group => Base.Group; + public ElevatorGroup Group => Base.Group; /// /// Gets the type according to . /// public ElevatorType ElevatorType => Group switch { - ElevatorManager.ElevatorGroup.Scp049 => ElevatorType.Scp049, - ElevatorManager.ElevatorGroup.GateA => ElevatorType.GateA, - ElevatorManager.ElevatorGroup.GateB => ElevatorType.GateB, - ElevatorManager.ElevatorGroup.LczA01 or ElevatorManager.ElevatorGroup.LczA02 => ElevatorType.LczA, - ElevatorManager.ElevatorGroup.LczB01 or ElevatorManager.ElevatorGroup.LczB02 => ElevatorType.LczB, - ElevatorManager.ElevatorGroup.Nuke => ElevatorType.Nuke, + ElevatorGroup.Scp049 => ElevatorType.Scp049, + ElevatorGroup.GateA => ElevatorType.GateA, + ElevatorGroup.GateB => ElevatorType.GateB, + ElevatorGroup.LczA01 or ElevatorGroup.LczA02 => ElevatorType.LczA, + ElevatorGroup.LczB01 or ElevatorGroup.LczB02 => ElevatorType.LczB, + ElevatorGroup.Nuke01 => ElevatorType.Nuke1, + ElevatorGroup.Nuke02 => ElevatorType.Nuke2, _ => ElevatorType.Unknown, }; /// /// Gets the target panel for this lift. /// - public ElevatorPanel Panel => Base.TargetPanel; + public ElevatorPanel Panel { get; } /// /// Gets the associated with this elevator door. diff --git a/Exiled.API/Features/Items/Firearm.cs b/Exiled.API/Features/Items/Firearm.cs index 41a48341a1..8706ca5cb4 100644 --- a/Exiled.API/Features/Items/Firearm.cs +++ b/Exiled.API/Features/Items/Firearm.cs @@ -7,7 +7,6 @@ namespace Exiled.API.Features.Items { - using System; using System.Collections.Generic; using System.Linq; @@ -18,12 +17,11 @@ namespace Exiled.API.Features.Items using Exiled.API.Interfaces; using Exiled.API.Structs; using Extensions; + using InventorySystem.Items; using InventorySystem.Items.Firearms; using InventorySystem.Items.Firearms.Attachments; using InventorySystem.Items.Firearms.Attachments.Components; - using InventorySystem.Items.Firearms.BasicMessages; using InventorySystem.Items.Firearms.Modules; - using UnityEngine; using BaseFirearm = InventorySystem.Items.Firearms.Firearm; @@ -52,13 +50,12 @@ public Firearm(BaseFirearm itemBase) /// /// The of the firearm. internal Firearm(ItemType type) - : this((BaseFirearm)Server.Host.Inventory.CreateItemInstance(new(type, 0), false)) + : this((BaseFirearm)Server.Host.Inventory.CreateItemInstance(new ItemIdentifier(type, 0), false)) { - FirearmStatusFlags firearmStatusFlags = FirearmStatusFlags.MagazineInserted; - if (Base.HasAdvantageFlag(AttachmentDescriptiveAdvantages.Flashlight)) - firearmStatusFlags = firearmStatusFlags.AddFlags(FirearmStatusFlags.FlashlightEnabled); + FlashlightAttachment flashlightAttachment = Attachments.OfType().FirstOrDefault(); - Base.Status = new(MaxAmmo, firearmStatusFlags, Base.GetCurrentAttachmentsCode()); + if (flashlightAttachment is not null && flashlightAttachment.IsEnabled) + flashlightAttachment.ServerSendStatus(true); } /// . @@ -95,14 +92,19 @@ public static IReadOnlyDictionary public new BaseFirearm Base { get; } + /// + /// Gets the modules associated with this firearm. + /// + public IEnumerable Modules => Base.Modules; + /// /// Gets or sets the amount of ammo in the firearm. /// [EProperty(category: nameof(Firearm))] - public byte Ammo + public int Ammo { - get => Base.Status.Ammo; - set => Base.Status = new FirearmStatus(value, Base.Status.Flags, Base.Status.Attachments); + get => (Modules.FirstOrDefault(module => module is MagazineModule) as MagazineModule)?.AmmoStored ?? 0; + set => ((MagazineModule)Modules.FirstOrDefault(module => module is MagazineModule))!.AmmoStored = value; } /// @@ -110,27 +112,10 @@ public byte Ammo /// /// Disruptor can't be used for MaxAmmo. [EProperty(category: nameof(Firearm))] - public byte MaxAmmo + public int MaxAmmo { - get => Base.AmmoManagerModule?.MaxAmmo ?? 0; - set - { - switch (Base.AmmoManagerModule) - { - case TubularMagazineAmmoManager tubularMagazineAmmoManager: - tubularMagazineAmmoManager.MaxAmmo = (byte)(value - Base.AttachmentsValue(AttachmentParam.MagazineCapacityModifier) - (Base.Status.Flags.HasFlagFast(FirearmStatusFlags.Cocked) ? tubularMagazineAmmoManager.ChamberedRounds : 0)); - break; - case ClipLoadedInternalMagAmmoManager clipLoadedInternalMagAmmoManager: - clipLoadedInternalMagAmmoManager.MaxAmmo = (byte)(value - Base.AttachmentsValue(AttachmentParam.MagazineCapacityModifier)); - break; - case AutomaticAmmoManager automaticAmmoManager: - automaticAmmoManager.MaxAmmo = (byte)(value - Base.AttachmentsValue(AttachmentParam.MagazineCapacityModifier) - automaticAmmoManager.ChamberedAmount); - break; - default: - Log.Warn($"MaxAmmo can't be used for this Item: {Type} ({Base.AmmoManagerModule})"); - return; - } - } + get => (Modules.FirstOrDefault(module => module is MagazineModule) as MagazineModule)?.AmmoMax ?? 0; + set => ((MagazineModule)Modules.FirstOrDefault(module => module is MagazineModule))!._defaultCapacity = value; } /// @@ -140,24 +125,16 @@ public byte MaxAmmo public FirearmType FirearmType => Type.GetFirearmType(); /// - /// Gets or sets the of the firearm. + /// Gets the of the firearm. /// [EProperty(category: nameof(Firearm))] - public AmmoType AmmoType - { - get => Base.AmmoType.GetAmmoType(); - set - { - if (Base is AutomaticFirearm automaticFirearm) - automaticFirearm._ammoType = value.GetItemType(); - } - } + public AmmoType AmmoType => (Modules.OfType().FirstOrDefault()?.AmmoType ?? ItemType.None).GetAmmoType(); /// /// Gets a value indicating whether the firearm is being aimed. /// [EProperty(readOnly: true, category: nameof(Firearm))] - public bool Aiming => Base.AdsModule.ServerAds; + public bool Aiming => Modules.OfType().FirstOrDefault()?.AdsTarget ?? false; /// /// Gets a value indicating whether the firearm Flashlight. @@ -169,7 +146,7 @@ public AmmoType AmmoType /// Gets a value indicating whether the firearm's flashlight module is enabled. /// [EProperty(readOnly: true, category: nameof(Firearm))] - public bool FlashlightEnabled => Base.Status.Flags.HasFlagFast(FirearmStatusFlags.FlashlightEnabled); + public bool FlashlightEnabled => Base.IsEmittingLight; /// /// Gets a value indicating whether the firearm's NightVision is being used. @@ -187,7 +164,7 @@ public AmmoType AmmoType /// Gets a value indicating whether or not the firearm is automatic. /// [EProperty(readOnly: true, category: nameof(Firearm))] - public bool IsAutomatic => Base is AutomaticFirearm; + public bool IsAutomatic => Modules.Any(module => module is AutomaticActionModule); /// /// Gets the s of the firearm. @@ -214,11 +191,23 @@ public IEnumerable AttachmentIdentifiers public uint BaseCode => BaseCodesValue[FirearmType]; /// - /// Gets the fire rate of the firearm, if it is an automatic weapon. + /// Gets or sets the fire rate of the firearm, if it is an automatic weapon. /// /// [EProperty(readOnly: true, category: nameof(Firearm))] - public float FireRate => Base is AutomaticFirearm auto ? auto._fireRate : 1f; + public float FireRate + { + get => Modules.OfType().FirstOrDefault()?.BaseFireRate ?? 0f; + set + { + AutomaticActionModule module = Modules.OfType().FirstOrDefault(); + + if (module is null) + return; + + module.BaseFireRate = value; + } + } /// /// Gets or sets the recoil settings of the firearm, if it's an automatic weapon. @@ -228,39 +217,19 @@ public IEnumerable AttachmentIdentifiers [EProperty(category: nameof(Firearm))] public RecoilSettings Recoil { - get => Base is AutomaticFirearm auto ? auto._recoil : default; + get => Base.Modules.OfType().FirstOrDefault()?.BaseRecoil ?? default; set { - if (Base is not AutomaticFirearm auto) + RecoilPatternModule module = Base.Modules.OfType().FirstOrDefault(); + + if (module is null) return; - auto.ActionModule = new AutomaticAction( - Base, - auto._semiAutomatic, - auto._boltTravelTime, - 1f / auto._fireRate, - auto._dryfireClipId, - auto._triggerClipId, - auto._gunshotPitchRandomization, - value, - auto._recoilPattern, - false, - Mathf.Max(1, auto._chamberSize)); + module.BaseRecoil = value; } } - /// - /// Gets the firearm's . Will be for non-automatic weapons. - /// - [EProperty(readOnly: true, category: nameof(Firearm))] - public FirearmRecoilPattern RecoilPattern => Base is AutomaticFirearm auto ? auto._recoilPattern : null; - - /// - /// Gets the . - /// - [EProperty(readOnly: true, category: nameof(Firearm))] - public FirearmBaseStats Stats => Base.BaseStats; - + /* TODO /// /// Gets the base damage. /// @@ -272,6 +241,7 @@ public RecoilSettings Recoil /// [EProperty(readOnly: true, category: nameof(Firearm))] public float MaxRange => Stats.MaxDistance(); + */ /// /// Gets a of and [] which contains all available attachments for all firearms. @@ -473,7 +443,9 @@ public void AddAttachment(AttachmentIdentifier identifier) : identifier.Code; Base.ApplyAttachmentsCode((Base.GetCurrentAttachmentsCode() & ~toRemove) | newCode, true); - Base.Status = new FirearmStatus(Math.Min(Ammo, MaxAmmo), Base.Status.Flags, Base.GetCurrentAttachmentsCode()); + + // TODO + // Base.Status = new FirearmStatus(Math.Min(Ammo, MaxAmmo), Base.Status.Flags, Base.GetCurrentAttachmentsCode()); } /// @@ -515,10 +487,12 @@ public void RemoveAttachment(AttachmentIdentifier identifier) Base.ApplyAttachmentsCode(Base.GetCurrentAttachmentsCode() & ~code, true); + /* TODO if (identifier.Name == AttachmentName.Flashlight) Base.Status = new FirearmStatus(Math.Min(Ammo, MaxAmmo), Base.Status.Flags & ~FirearmStatusFlags.FlashlightEnabled, Base.GetCurrentAttachmentsCode()); else Base.Status = new FirearmStatus(Math.Min(Ammo, MaxAmmo), Base.Status.Flags, Base.GetCurrentAttachmentsCode()); + */ } /// @@ -531,10 +505,12 @@ public void RemoveAttachment(AttachmentName attachmentName) Base.ApplyAttachmentsCode(Base.GetCurrentAttachmentsCode() & ~code, true); + /* TODO if (attachmentName == AttachmentName.Flashlight) Base.Status = new FirearmStatus(Math.Min(Ammo, MaxAmmo), Base.Status.Flags & ~FirearmStatusFlags.FlashlightEnabled, Base.GetCurrentAttachmentsCode()); else Base.Status = new FirearmStatus(Math.Min(Ammo, MaxAmmo), Base.Status.Flags, Base.GetCurrentAttachmentsCode()); + */ } /// @@ -552,10 +528,12 @@ public void RemoveAttachment(AttachmentSlot attachmentSlot) Base.ApplyAttachmentsCode(Base.GetCurrentAttachmentsCode() & ~code, true); + /* TODO if (firearmAttachment.Name == AttachmentName.Flashlight) Base.Status = new FirearmStatus(Math.Min(Ammo, MaxAmmo), Base.Status.Flags & ~FirearmStatusFlags.FlashlightEnabled, Base.GetCurrentAttachmentsCode()); else Base.Status = new FirearmStatus(Math.Min(Ammo, MaxAmmo), Base.Status.Flags, Base.GetCurrentAttachmentsCode()); + */ } /// @@ -636,12 +614,14 @@ public bool TryGetAttachment(AttachmentName attachmentName, out Attachment firea return true; } + /* TODO /// /// Gets the damage based on the specified distance. /// /// The distance to evaluate. /// The corresponding damage based on the specified distance. public float GetDamageAtDistance(float distance) => Stats.DamageAtDistance(Base, distance); + */ /// /// Clones current object. @@ -668,22 +648,7 @@ public override Item Clone() internal override void ChangeOwner(Player oldOwner, Player newOwner) { Base.Owner = newOwner.ReferenceHub; - - Base.HitregModule = Base switch - { - AutomaticFirearm automaticFirearm => - new SingleBulletHitreg(automaticFirearm, automaticFirearm.Owner, automaticFirearm._recoilPattern), - Shotgun shotgun => - new BuckshotHitreg(shotgun, shotgun.Owner, shotgun.GetBuckshotPattern), - ParticleDisruptor particleDisruptor => - new DisruptorHitreg(particleDisruptor, particleDisruptor.Owner, particleDisruptor._explosionSettings), - Revolver revolver => - new SingleBulletHitreg(revolver, revolver.Owner), - _ => throw new NotImplementedException("Should never happend"), - }; - - Base._sendStatusNextFrame = true; - Base._footprintValid = false; + Base._footprintCacheSet = false; } /// @@ -695,7 +660,6 @@ internal override void ReadPickupInfo(Pickup pickup) return; Base.OnAdded(firearm.Base); - AmmoType = firearm.AmmoType; if (Base is not ParticleDisruptor) MaxAmmo = firearm.MaxAmmo; diff --git a/Exiled.API/Features/Items/Item.cs b/Exiled.API/Features/Items/Item.cs index d21666d07f..e4d490513c 100644 --- a/Exiled.API/Features/Items/Item.cs +++ b/Exiled.API/Features/Items/Item.cs @@ -7,11 +7,10 @@ namespace Exiled.API.Features.Items { - using System; using System.Collections.Generic; using System.Linq; - using Exiled.API.Features.Core; + using Core; using Exiled.API.Features.Core.Attributes; using Exiled.API.Features.Pickups; using Exiled.API.Interfaces; @@ -199,6 +198,16 @@ public ushort Serial /// public Player Owner => Player.Get(Base.Owner) ?? Server.Host; + /// + /// Gets or sets a reason for adding this item to the inventory. + /// + [EProperty(category: nameof(Item))] + public ItemAddReason AddReason + { + get => Base.ServerAddReason; + set => Base.ServerAddReason = value; + } + /// /// Gets an existing or creates a new instance of one. /// diff --git a/Exiled.API/Features/Lift.cs b/Exiled.API/Features/Lift.cs index df6ed6f8fd..3a0938a2f2 100644 --- a/Exiled.API/Features/Lift.cs +++ b/Exiled.API/Features/Lift.cs @@ -22,7 +22,6 @@ namespace Exiled.API.Features using UnityEngine; using static Interactables.Interobjects.ElevatorChamber; - using static Interactables.Interobjects.ElevatorManager; using BaseElevatorDoor = Interactables.Interobjects.ElevatorDoor; using ElevatorDoor = Doors.ElevatorDoor; @@ -94,8 +93,8 @@ internal Lift(ElevatorChamber elevator) [EProperty(category: nameof(Lift))] public ElevatorSequence Status { - get => Base._curSequence; - set => Base._curSequence = value; + get => Base.CurSequence; + set => Base.CurSequence = value; } /// @@ -115,7 +114,8 @@ public ElevatorSequence Status ElevatorGroup.GateB => ElevatorType.GateB, ElevatorGroup.LczA01 or ElevatorGroup.LczA02 => ElevatorType.LczA, ElevatorGroup.LczB01 or ElevatorGroup.LczB02 => ElevatorType.LczB, - ElevatorGroup.Nuke => ElevatorType.Nuke, + ElevatorGroup.Nuke01 => ElevatorType.Nuke1, + ElevatorGroup.Nuke02 => ElevatorType.Nuke2, _ => ElevatorType.Unknown, }; @@ -141,7 +141,7 @@ public ElevatorSequence Status /// Gets a value indicating whether the lift is locked. /// [EProperty(readOnly: true, category: nameof(Lift))] - public bool IsLocked => Base.ActiveLocks > 0; + public bool IsLocked => Base.ActiveLocksAllDoors > 0; /// /// Gets or sets the . @@ -178,15 +178,15 @@ public float AnimationTime public float MoveTime => AnimationTime + RotationTime + DoorOpenTime + DoorCloseTime; /// - /// Gets the . + /// Gets the . /// [EProperty(readOnly: true, category: nameof(Lift))] - public int CurrentLevel => Base.CurrentLevel; + public int NextLevel => Base.NextLevel; /// /// Gets the . /// - public ElevatorDoor CurrentDestination => Door.Get(Base.CurrentDestination).As(); + public ElevatorDoor CurrentDestination => Door.Get(Base.DestinationDoor).As(); /// /// Gets the base . @@ -338,8 +338,7 @@ public float AnimationTime /// /// The destination level. /// Indicates whether the start will be forced or not. - /// if the lift was started successfully; otherwise, . - public bool TryStart(int level, bool isForced = false) => TrySetDestination(Group, level, isForced); + public void Start(int level, bool isForced = false) => Base.ServerSetDestination(level, isForced); /// /// Locks the lift. @@ -388,6 +387,6 @@ public void Lock(DoorLockType lockReason = DoorLockType.Isolation) /// Returns the Lift in a human-readable format. /// /// A string containing Lift-related data. - public override string ToString() => $"{Type} {Status} [{CurrentLevel}] *{IsLocked}*"; + public override string ToString() => $"{Type} {Status} [{NextLevel}] *{IsLocked}*"; } } \ No newline at end of file diff --git a/Exiled.API/Features/Map.cs b/Exiled.API/Features/Map.cs index 22be75d24c..ee75923721 100644 --- a/Exiled.API/Features/Map.cs +++ b/Exiled.API/Features/Map.cs @@ -12,7 +12,6 @@ namespace Exiled.API.Features using System.Collections.ObjectModel; using System.Linq; - using Decals; using Enums; using Exiled.API.Extensions; using Exiled.API.Features.Lockers; @@ -20,18 +19,14 @@ namespace Exiled.API.Features using Exiled.API.Features.Scp914Processors; using Exiled.API.Features.Toys; using InventorySystem; - using InventorySystem.Items.Firearms; - using InventorySystem.Items.Firearms.BasicMessages; using InventorySystem.Items.Pickups; using InventorySystem.Items.ThrowableProjectiles; using Items; using LightContainmentZoneDecontamination; using MapGeneration; using PlayerRoles.Ragdolls; - using RelativePositioning; using UnityEngine; using Utils; - using Utils.Networking; using Object = UnityEngine.Object; @@ -91,14 +86,14 @@ public static int Seed set { if (!SeedSynchronizer.MapGenerated) - SeedSynchronizer._singleton.Network_syncSeed = value; + SeedSynchronizer.Seed = value; } } /// /// Gets the . /// - public static AmbientSoundPlayer AmbientSoundPlayer => ambientSoundPlayer ??= ReferenceHub.HostHub.GetComponent(); + public static AmbientSoundPlayer AmbientSoundPlayer => ambientSoundPlayer ??= ReferenceHub._hostHub.GetComponent(); /// /// Gets the . @@ -274,21 +269,6 @@ public static void CleanAllRagdolls(IEnumerable ragDolls) ragDoll.Destroy(); } - /// - /// Places a decal. - /// - /// The position of the blood decal. - /// The direction of the blood decal. - /// The type of decal to place. - public static void PlaceDecal(Vector3 position, Vector3 direction, DecalPoolType type) => new GunDecalMessage(position, direction, type).SendToAuthenticated(0); - - /// - /// Places a blood decal. - /// - /// The position of the blood decal. - /// The direction of the blood decal. - public static void PlaceBlood(Vector3 position, Vector3 direction) => PlaceDecal(position, direction, DecalPoolType.Blood); - /// /// Gets all the near cameras. /// @@ -339,26 +319,6 @@ public static void ExplodeEffect(Vector3 position, ProjectileType projectileType ExplosionUtils.ServerSpawnEffect(position, item); } - /// - /// Plays a gun sound at the specified position. - /// - /// Position to play the sound at. - /// The type of firearm to play the sound of. - /// The maximum distance the sound can be heard from. - /// The audio clip ID to play. - public static void PlayGunSound(Vector3 position, ItemType firearmType, byte maxDistance = 45, byte audioClipId = 0) - { - GunAudioMessage msg = new() - { - Weapon = firearmType, - AudioClipId = audioClipId, - MaxDistance = maxDistance, - ShooterHub = ReferenceHub.HostHub, - ShooterPosition = new RelativePosition(position), - }; - msg.SendToAuthenticated(); - } - /// /// Spawns mice inside the . /// diff --git a/Exiled.API/Features/Npc.cs b/Exiled.API/Features/Npc.cs index 99c13ee5d1..d68e82fa79 100644 --- a/Exiled.API/Features/Npc.cs +++ b/Exiled.API/Features/Npc.cs @@ -257,61 +257,5 @@ public bool UseJailbird() jailbird.Base.ServerAttack(null); return true; } - - /// - /// Forces the NPC to shoot their current . - /// - /// if the weapon shot request is received. Returns otherwise, or if the player is not an or is not holding a . - public bool ShootWeapon() - { - if (CurrentItem is not Firearm firearm) - return false; - - if (!firearm.Base.ActionModule.ServerAuthorizeShot()) - return false; - - ShotMessage message = new() - { - ShooterCameraRotation = CameraTransform.rotation, - ShooterPosition = new RelativePosition(Transform.position), - ShooterWeaponSerial = CurrentItem.Serial, - TargetNetId = 0, - TargetPosition = default, - TargetRotation = Quaternion.identity, - }; - - Physics.Raycast(CameraTransform.position, CameraTransform.forward, out RaycastHit hit, firearm.Base.BaseStats.MaxDistance(), StandardHitregBase.HitregMask); - - if (hit.transform && hit.collider.TryGetComponent(out IDestructible destructible) && destructible != null) - { - message.TargetNetId = destructible.NetworkId; - message.TargetPosition = new RelativePosition(hit.transform.position); - message.TargetRotation = hit.transform.rotation; - } - else if (hit.transform) - { - message.TargetPosition = new RelativePosition(hit.transform.position); - message.TargetRotation = hit.transform.rotation; - } - - FirearmBasicMessagesHandler.ServerShotReceived(ReferenceHub.connectionToClient, message); - return true; - } - - /// - /// Sets the NPC's current status for Aiming Down Sights. - /// - /// Should the player be aiming down sights. - /// if the weapon Aim Down Sights request is received. Returns otherwise, or if the player is not an or is not holding a . - public bool SetAimDownSight(bool shouldADS) - { - if (CurrentItem is Firearm firearm) - { - FirearmBasicMessagesHandler.ServerRequestReceived(ReferenceHub.connectionToClient, new RequestMessage(firearm.Serial, shouldADS ? RequestType.AdsIn : RequestType.AdsOut)); - return true; - } - - return false; - } } } diff --git a/Exiled.API/Features/Pickups/FirearmPickup.cs b/Exiled.API/Features/Pickups/FirearmPickup.cs index 8068abd422..fbeea23486 100644 --- a/Exiled.API/Features/Pickups/FirearmPickup.cs +++ b/Exiled.API/Features/Pickups/FirearmPickup.cs @@ -7,13 +7,15 @@ namespace Exiled.API.Features.Pickups { + using System.Linq; + using Exiled.API.Enums; using Exiled.API.Extensions; using Exiled.API.Features.Core.Attributes; using Exiled.API.Features.Items; using Exiled.API.Interfaces; using InventorySystem.Items; - using InventorySystem.Items.Firearms; + using InventorySystem.Items.Firearms.Modules; using BaseFirearm = InventorySystem.Items.Firearms.FirearmPickup; using FirearmItem = InventorySystem.Items.Firearms.Firearm; @@ -41,10 +43,10 @@ internal FirearmPickup(ItemType type) : base(type) { Base = (BaseFirearm)((Pickup)this).Base; - IsDistributed = true; + Base.OnDistributed(); - if (type is ItemType.ParticleDisruptor && Status.Ammo <= 0) - Status = new FirearmStatus(5, FirearmStatusFlags.MagazineInserted, 0); + if (type is ItemType.ParticleDisruptor && Base.Template.Modules.OfType().FirstOrDefault()!.AmmoStored <= 0) + Base.Template.Modules.OfType().FirstOrDefault()!.AmmoStored = 5; } /// @@ -59,56 +61,26 @@ internal FirearmPickup(ItemType type) public FirearmType FirearmType => Type.GetFirearmType(); /// - /// Gets or sets the of the firearm. - /// - [EProperty(category: nameof(FirearmPickup))] - public AmmoType AmmoType { get; set; } - - /// - /// Gets or sets a value indicating whether the pickup is already distributed. + /// Gets the of the firearm. /// [EProperty(category: nameof(FirearmPickup))] - public bool IsDistributed - { - get => Base.Distributed; - set => Base.Distributed = value; - } - - /// - /// Gets or sets the . - /// - [EProperty(category: nameof(FirearmPickup))] - public FirearmStatus Status - { - get => Base.NetworkStatus; - set => Base.NetworkStatus = value; - } + public AmmoType AmmoType { get; private set; } /// /// Gets or sets a value indicating how many ammo have this . /// [EProperty(category: nameof(FirearmPickup))] - public byte Ammo + public int Ammo { - get => Base.NetworkStatus.Ammo; - set => Base.NetworkStatus = new(value, Base.NetworkStatus.Flags, Base.NetworkStatus.Attachments); + get => Base.Template.Modules.OfType().FirstOrDefault()?.AmmoStored ?? 0; + set => Base.Template.Modules.OfType().FirstOrDefault()!.AmmoStored = value; } /// /// Gets or sets the max ammo the Firearm can have. /// [EProperty(category: nameof(FirearmPickup))] - public byte MaxAmmo { get; set; } - - /// - /// Gets or sets the . - /// - [EProperty(category: nameof(FirearmPickup))] - public FirearmStatusFlags Flags - { - get => Base.NetworkStatus.Flags; - set => Base.NetworkStatus = new(Base.NetworkStatus.Ammo, value, Base.NetworkStatus.Attachments); - } + public int MaxAmmo { get; set; } /// /// Gets or sets a value indicating whether the attachment code have this . @@ -116,25 +88,24 @@ public FirearmStatusFlags Flags [EProperty(category: nameof(FirearmPickup))] public uint Attachments { - get => Base.NetworkStatus.Attachments; - set => Base.NetworkStatus = new(Base.NetworkStatus.Ammo, Base.NetworkStatus.Flags, value); + get => Base.Worldmodel.AttachmentCode; + set => Base.Worldmodel.AttachmentCode = value; } /// /// Returns the FirearmPickup in a human readable format. /// /// A string containing FirearmPickup related data. - public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* |{IsDistributed}| -{Ammo}-"; + public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* -{Ammo}-"; /// internal override void ReadItemInfo(Item item) { base.ReadItemInfo(item); - if (item is Items.Firearm firearm) + if (item is Firearm firearm) { MaxAmmo = firearm.MaxAmmo; - AmmoType = firearm.AmmoType; } } @@ -145,14 +116,8 @@ protected override void InitializeProperties(ItemBase itemBase) if (itemBase is FirearmItem firearm) { - MaxAmmo = firearm switch - { - AutomaticFirearm autoFirearm => autoFirearm._baseMaxAmmo, - Revolver => 6, - Shotgun shotgun => shotgun._ammoCapacity, - _ => 0 - }; - AmmoType = firearm is AutomaticFirearm automaticFirearm ? automaticFirearm._ammoType.GetAmmoType() : firearm.ItemTypeId.GetAmmoType(); + MaxAmmo = firearm.GetTotalMaxAmmo(); + AmmoType = (firearm.Modules.OfType().FirstOrDefault()?.AmmoType ?? ItemType.None).GetAmmoType(); } } } diff --git a/Exiled.API/Features/Player.cs b/Exiled.API/Features/Player.cs index 62b1d2375c..56a0bc51b1 100644 --- a/Exiled.API/Features/Player.cs +++ b/Exiled.API/Features/Player.cs @@ -40,9 +40,9 @@ namespace Exiled.API.Features using InventorySystem.Disarming; using InventorySystem.Items; using InventorySystem.Items.Armor; - using InventorySystem.Items.Firearms; using InventorySystem.Items.Firearms.Attachments; - using InventorySystem.Items.Firearms.BasicMessages; + using InventorySystem.Items.Firearms.Modules; + using InventorySystem.Items.Firearms.ShotEvents; using InventorySystem.Items.Usables; using InventorySystem.Items.Usables.Scp330; using MEC; @@ -51,6 +51,7 @@ namespace Exiled.API.Features using NorthwoodLib; using PlayerRoles; using PlayerRoles.FirstPersonControl; + using PlayerRoles.FirstPersonControl.Thirdperson.Subcontrollers; using PlayerRoles.PlayableScps; using PlayerRoles.PlayableScps.Scp049.Zombies; using PlayerRoles.RoleAssign; @@ -679,7 +680,7 @@ public Role Role get => role ??= Role.Create(RoleManager.CurrentRole); internal set { - PreviousRole = role; + PreviousRole = role?.Type ?? RoleTypeId.None; role = value; } } @@ -688,7 +689,7 @@ internal set /// Gets the previous player's role. /// [EProperty(readOnly: true, category: ROLES_CATEGORY)] - public Role PreviousRole { get; private set; } + public RoleTypeId PreviousRole { get; private set; } /// /// Gets or sets the player's SCP preferences. @@ -712,11 +713,6 @@ public ScpSpawnPreferences.SpawnPreferences ScpPreferences /// Players can be cuffed without another player being the cuffer. public bool IsCuffed => Inventory.IsDisarmed(); - /// - /// Gets a value indicating whether or not the player is reloading a weapon. - /// - public bool IsReloading => CurrentItem is Firearm firearm && !firearm.Base.AmmoManagerModule.Standby; - /// /// Gets a value indicating whether or not the player is aiming with a weapon. /// @@ -1059,6 +1055,15 @@ public float HumeShieldRegenerationMultiplier /// public CustomHumeShieldStat HumeShieldStat => humeShieldStat; + /// + /// Gets or sets the player's emotion. + /// + public EmotionPresetType Emotion + { + get => EmotionSync.GetEmotionPreset(ReferenceHub); + set => ReferenceHub.ServerSetEmotionPreset(value); + } + /// /// Gets or sets the item in the player's hand. Value will be if the player is not holding anything. /// @@ -2025,54 +2030,6 @@ public void TrySetCustomRoleFriendlyFire(string roleTypeId, Dictionary Whether or not the item was able to be added. public bool TryRemoveCustomRoleFriendlyFire(string role) => CustomRoleFriendlyFireMultiplier.Remove(role); - /// - /// Forces the player to reload their current . - /// - /// if firearm was successfully reloaded. Otherwise, . - public bool ReloadWeapon() - { - if (CurrentItem is Firearm firearm) - { - bool result = firearm.Base.AmmoManagerModule.ServerTryReload(); - if (result) - Connection.Send(new RequestMessage(firearm.Serial, RequestType.Reload)); - return result; - } - - return false; - } - - /// - /// Forces the player to unload their current . - /// - /// if the weapon unload request is received. Returns otherwise, or if the player is not an or is not holding a . - public bool UnloadWeapon() - { - if (CurrentItem is Firearm firearm) - { - bool result = firearm.Base.AmmoManagerModule.ServerTryUnload(); - if (result) - Connection.Send(new RequestMessage(firearm.Serial, RequestType.Unload)); - return result; - } - - return true; - } - - /// - /// Forces the player to toggle the Flashlight Attachment on their current . - /// - /// if the weapon flashlight toggle request is received. Returns otherwise, or if the player is not an or is not holding a . - public bool ToggleWeaponFlashlight() - { - if (RoleManager.CurrentRole is not IFpcRole || CurrentItem is not Firearm firearm) - return false; - - bool oldCheck = firearm.FlashlightEnabled; // Temporary Solution - FirearmBasicMessagesHandler.ServerRequestReceived(ReferenceHub.connectionToClient, new RequestMessage(firearm.Serial, RequestType.ToggleFlashlight)); - return oldCheck != firearm.FlashlightEnabled; - } - /// /// Tries to get an item from a player's inventory. /// @@ -2413,7 +2370,7 @@ public void Hurt(Player attacker, float amount, DamageType damageType = DamageTy /// The throw force. /// The armor penetration amount. public void Hurt(Player attacker, float damage, Vector3 force = default, int armorPenetration = 0) => - Hurt(new ExplosionDamageHandler(attacker.Footprint, force, damage, armorPenetration)); + Hurt(new ExplosionDamageHandler(attacker.Footprint, force, damage, armorPenetration, ExplosionType.Grenade)); /// /// Hurts the player. @@ -2511,7 +2468,7 @@ public void Vaporize(Player attacker = null, string cassieAnnouncement = "") if ((Role.Side != Side.Scp) && !string.IsNullOrEmpty(cassieAnnouncement)) Cassie.Message(cassieAnnouncement); - Kill(new DisruptorDamageHandler(attacker?.Footprint ?? Footprint, -1)); + Kill(new DisruptorDamageHandler(new DisruptorShotEvent(Item.Create(ItemType.ParticleDisruptor, attacker).Base as InventorySystem.Items.Firearms.Firearm, DisruptorActionModule.FiringState.FiringSingle), Vector3.up, -1)); } /// @@ -2897,12 +2854,13 @@ public Item AddItem(FirearmType firearmType, IEnumerable i else if (Preferences is not null && Preferences.TryGetValue(firearmType, out AttachmentIdentifier[] attachments)) firearm.Base.ApplyAttachmentsCode(attachments.GetAttachmentsCode(), true); - FirearmStatusFlags flags = FirearmStatusFlags.MagazineInserted; + // TODO: + /*FirearmStatusFlags flags = FirearmStatusFlags.MagazineInserted; if (firearm.Attachments.Any(a => a.Name == AttachmentName.Flashlight)) flags = flags.AddFlags(FirearmStatusFlags.FlashlightEnabled); - firearm.Base.Status = new FirearmStatus(firearm.MaxAmmo, flags, firearm.Base.GetCurrentAttachmentsCode()); + firearm.Base.Status = new FirearmStatus(firearm.MaxAmmo, flags, firearm.Base.GetCurrentAttachmentsCode());*/ } AddItem(item); @@ -3023,7 +2981,7 @@ public void AddItem(Firearm item, IEnumerable identifiers) /// /// The of the item to be added. /// The that was added. - public Item AddItem(Pickup pickup) => Item.Get(Inventory.ServerAddItem(pickup.Type, pickup.Serial, pickup.Base)); + public Item AddItem(Pickup pickup) => Item.Get(Inventory.ServerAddItem(pickup.Type, ItemAddReason.AdminCommand, pickup.Serial, pickup.Base)); /// /// Adds an item to the player's inventory. @@ -3033,7 +2991,7 @@ public void AddItem(Firearm item, IEnumerable identifiers) /// The that was added. public Item AddItem(FirearmPickup pickup, IEnumerable identifiers) { - Firearm firearm = (Firearm)Item.Get(Inventory.ServerAddItem(pickup.Type, pickup.Serial, pickup.Base)); + Firearm firearm = (Firearm)Item.Get(Inventory.ServerAddItem(pickup.Type, ItemAddReason.AdminCommand, pickup.Serial, pickup.Base)); if (identifiers is not null) firearm.AddAttachment(identifiers); @@ -3046,12 +3004,14 @@ public Item AddItem(FirearmPickup pickup, IEnumerable iden /// /// The item to be added. /// The object of the item. + /// The reason the item was added. /// The that was added. - public Item AddItem(ItemBase itemBase, Item item = null) + public Item AddItem(ItemBase itemBase, Item item = null, ItemAddReason addReason = ItemAddReason.AdminCommand) { try { item ??= Item.Get(itemBase); + item.AddReason = addReason; Inventory.UserInventory.Items[item.Serial] = itemBase; @@ -3744,13 +3704,6 @@ public void Reconnect(ushort newPort = 0, float delay = 5, bool reconnect = true Connection.Send(new RoundRestartMessage(roundRestartType, delay, newPort, reconnect, false)); } - /// - public void PlayGunSound(ItemType type, byte volume, byte audioClipId = 0) => - PlayGunSound(Position, type, volume, audioClipId); - - /// - public void PlaceBlood(Vector3 direction) => Map.PlaceBlood(Position, direction); - /// public IEnumerable GetNearCameras(float toleration = 15f) => Map.GetNearCameras(Position, toleration); @@ -3908,7 +3861,7 @@ public void SetCooldownItem(float time, ItemType itemType) /// /// Triggers an explosion for the player. /// - public void Explode() => ExplosionUtils.ServerExplode(ReferenceHub); + public void Explode() => ExplosionUtils.ServerExplode(ReferenceHub, ExplosionType.Grenade); /// /// Triggers an explosion for the player. @@ -3937,28 +3890,7 @@ public void SetRank(string rankName, string rankColor) /// /// Plays a beep sound that only the player can hear. /// - public void PlayBeepSound() => MirrorExtensions.SendFakeTargetRpc(ReferenceHub, ReferenceHub.HostHub.networkIdentity, typeof(AmbientSoundPlayer), nameof(AmbientSoundPlayer.RpcPlaySound), 7); - - /// - /// Plays a gun sound that only the target can hear. - /// - /// Position to play on. - /// Weapon' sound to play. - /// Sound's volume to set. - /// GunAudioMessage's audioClipId to set (default = 0). - public void PlayGunSound(Vector3 position, ItemType itemType, byte volume, byte audioClipId = 0) - { - GunAudioMessage message = new() - { - Weapon = itemType, - AudioClipId = audioClipId, - MaxDistance = volume, - ShooterHub = ReferenceHub, - ShooterPosition = new RelativePosition(position), - }; - - Connection.Send(message); - } + public void PlayBeepSound() => MirrorExtensions.SendFakeTargetRpc(ReferenceHub, ReferenceHub._hostHub.networkIdentity, typeof(AmbientSoundPlayer), nameof(AmbientSoundPlayer.RpcPlaySound), 7); /// /// Set to the player that only can see. diff --git a/Exiled.API/Features/Ragdoll.cs b/Exiled.API/Features/Ragdoll.cs index 11c852c667..bb80aa2cd1 100644 --- a/Exiled.API/Features/Ragdoll.cs +++ b/Exiled.API/Features/Ragdoll.cs @@ -110,10 +110,14 @@ public DamageHandlerBase DamageHandler public DeathAnimation[] DeathAnimations => Base.AllDeathAnimations; /// - /// Gets a value indicating whether or not the ragdoll has been already cleaned up. + /// Gets or sets a value indicating whether or not the ragdoll has freeze or not. /// - [EProperty(readOnly: true, category: nameof(Ragdoll))] - public bool IsFrozen => Base._frozen; + [EProperty(category: nameof(Ragdoll))] + public bool IsFrozen + { + get => Base.Frozen; + set => Base.Frozen = value; + } /// /// Gets or sets a value indicating whether or not the ragdoll can be cleaned up. @@ -420,6 +424,11 @@ public static Ragdoll Get(BasicRagdoll ragdoll) => ragdoll == null ? null : /// public void UnSpawn() => NetworkServer.UnSpawn(GameObject); + /// + /// Freeze the ragdoll. + /// + public void Freeze() => Base.FreezeRagdoll(); + /// /// Returns the Ragdoll in a human-readable format. /// diff --git a/Exiled.API/Features/Respawn.cs b/Exiled.API/Features/Respawn.cs index 59f4e0207b..413cb821f0 100644 --- a/Exiled.API/Features/Respawn.cs +++ b/Exiled.API/Features/Respawn.cs @@ -9,13 +9,14 @@ namespace Exiled.API.Features { using System; using System.Collections.Generic; - using System.Linq; using CustomPlayerEffects; using Enums; using PlayerRoles; using Respawning; using Respawning.NamingRules; + using Respawning.Waves; + using Respawning.Waves.Generic; using UnityEngine; /// @@ -55,57 +56,28 @@ public static GameObject ChaosVan } /// - /// Gets or sets the next known that will spawn. + /// Gets or sets the next known that will spawn. /// - public static SpawnableTeamType NextKnownTeam + public static Faction NextKnownFaction { - get => RespawnManager.Singleton.NextKnownTeam; - set => RespawnManager.Singleton.NextKnownTeam = value; + get => WaveManager._nextWave.TargetFaction; + set => WaveManager._nextWave = WaveManager.Waves.Find(x => x.TargetFaction == value); } /// - /// Gets or sets the amount of seconds before the next respawn phase will occur. + /// Gets the next known that will spawn. /// - public static float TimeUntilNextPhase - { - get => RespawnManager.Singleton._timeForNextSequence - (float)RespawnManager.Singleton._stopwatch.Elapsed.TotalSeconds; - set => RespawnManager.Singleton._timeForNextSequence = (float)RespawnManager.Singleton._stopwatch.Elapsed.TotalSeconds + value; - } - - /// - /// Gets a indicating the amount of time before the next respawn wave will occur. - /// - public static TimeSpan TimeUntilSpawnWave => TimeSpan.FromSeconds(TimeUntilNextPhase); - - /// - /// Gets a indicating the moment in UTC time the next respawn wave will occur. - /// - public static DateTime NextTeamTime => DateTime.UtcNow.AddSeconds(TimeUntilSpawnWave.TotalSeconds); - - /// - /// Gets a value indicating whether or not a team is currently being spawned or the animations are playing for a team. - /// - public static bool IsSpawning => RespawnManager.Singleton._curSequence is RespawnManager.RespawnSequencePhase.PlayingEntryAnimations or RespawnManager.RespawnSequencePhase.SpawningSelectedTeam; + public static SpawnableTeamType NextKnownTeam => NextKnownFaction.GetSpawnableTeam(); /// - /// Gets or sets the amount of spawn tickets belonging to the Chaos Insurgency. + /// Gets the current queue state of the . /// - /// - public static float ChaosTickets - { - get => RespawnTokensManager.Counters[0].Amount; - set => RespawnTokensManager.ModifyTokens(SpawnableTeamType.ChaosInsurgency, value); - } + public static WaveManager.WaveQueueState QueueState => WaveManager.State; /// - /// Gets or sets the amount of spawn tickets belonging to the NTF. + /// Gets a value indicating whether a wave is spawning or not. /// - /// - public static float NtfTickets - { - get => RespawnTokensManager.Counters[1].Amount; - set => RespawnTokensManager.ModifyTokens(SpawnableTeamType.NineTailedFox, value); - } + public static bool IsSpawning => QueueState == WaveManager.WaveQueueState.WaveSpawning; /// /// Gets or sets a value indicating whether or not spawn protection is enabled. @@ -145,110 +117,124 @@ public static bool ProtectedCanShoot public static string[] NtfNamingCodes => NineTailedFoxNamingRule.PossibleCodes; /// - /// Generates a queue. + /// Play effects when a certain class spawns. /// - /// The team to get queue of. - /// Amount to get. - /// A queue of . - public static Queue GenerateQueue(SpawnableTeamType team, int amount) + /// The for which effects should be played. + public static void PlayEffect(SpawnableWaveBase wave) { - Queue queue = new(); - - if (!RespawnManager.SpawnableTeams.TryGetValue(team, out SpawnableTeamHandlerBase handler)) - return queue; - - handler.GenerateQueue(queue, amount); - - return queue; + WaveUpdateMessage.ServerSendUpdate(wave, UpdateMessageFlags.Trigger); } /// - /// Play an effect when a certain class spawns. + /// Tries to get a . /// - /// The effect to be played. - public static void PlayEffect(byte effect) => PlayEffects(new[] { effect }); + /// Found . + /// Type of . + /// if was successfully found, true, if not, false. + public static bool TryGetWave(out T wave) + where T : SpawnableWaveBase => WaveManager.TryGet(out wave); /// - /// Play an effect when a certain class spawns. + /// Tries to get a from a . /// - /// The effect to be played. - public static void PlayEffect(RespawnEffectType effect) => PlayEffects(new[] { effect }); + /// Team's . + /// Found . + /// if was successfully found, true, if not, false. + public static bool TryGetWave(Faction faction, out SpawnableWaveBase wave) + => WaveManager.TryGet(faction, out wave); /// - /// Play effects when a certain class spawns. + /// Tries to get a from a . /// - /// The effects to be played. - public static void PlayEffects(byte[] effects) + /// Team's . + /// Found . + /// if was successfully found, true, if not, false. + public static bool TryGetWave(SpawnableWave spawnableWave, out SpawnableWaveBase wave) { - foreach (RespawnEffectsController controller in RespawnEffectsController.AllControllers) + wave = spawnableWave switch { - if (!controller) - continue; + SpawnableWave.NtfWave => TryGetWave(out NtfSpawnWave ntfWave) ? ntfWave : null, + SpawnableWave.NtfMiniWave => TryGetWave(out NtfMiniWave ntfMiniWave) ? ntfMiniWave : null, + SpawnableWave.ChaosWave => TryGetWave(out ChaosSpawnWave chaosWave) ? chaosWave : null, + SpawnableWave.ChaosMiniWave => TryGetWave(out ChaosMiniWave chaosMiniWave) ? chaosMiniWave : null, + _ => null + }; + + return wave != null; + } - controller.RpcPlayEffects(effects); - } + /// + /// Spawns the specified . + /// + /// The spawnable wave to spawn. + public static void ForceWave(SpawnableWaveBase wave) => WaveManager.Spawn(wave); + + /// + /// Spawns a wave based of a . + /// + /// The faction to spawn. + public static void ForceWave(Faction faction) + { + if (TryGetWave(faction, out SpawnableWaveBase wave)) + ForceWave(wave); } /// - /// Play effects when a certain class spawns. + /// Advance the timer from the specified faction. /// - /// The effects to be played. - public static void PlayEffects(RespawnEffectType[] effects) => PlayEffects(effects.Select(effect => (byte)effect).ToArray()); + /// The faction of the spawn wave. + /// The time to advance. + public static void AdvanceTimer(Faction faction, float time) => WaveManager.AdvanceTimer(faction, time); /// /// Summons the NTF chopper. /// - public static void SummonNtfChopper() => PlayEffects(new[] { RespawnEffectType.SummonNtfChopper }); + public static void SummonNtfChopper() + { + if (TryGetWave(Faction.FoundationStaff, out SpawnableWaveBase wave)) + PlayEffect(wave); + } /// /// Summons the van. /// - /// Whether or not to play the Chaos Insurgency spawn music. - public static void SummonChaosInsurgencyVan(bool playMusic = true) + public static void SummonChaosInsurgencyVan() { - PlayEffects(playMusic ? new[] - { - RespawnEffectType.PlayChaosInsurgencyMusic, - RespawnEffectType.SummonChaosInsurgencyVan, - } - : new[] - { - RespawnEffectType.SummonChaosInsurgencyVan, - }); + if (TryGetWave(Faction.FoundationEnemy, out SpawnableWaveBase wave)) + PlayEffect(wave); } /// - /// Grants tickets to a . + /// Grants tickets to a . /// - /// The to grant tickets to. + /// The to grant tickets to. /// The amount of tickets to grant. - public static void GrantTickets(SpawnableTeamType team, float amount) => RespawnTokensManager.GrantTokens(team, Math.Max(0, amount)); + public static void GrantTickets(Faction team, int amount) + { + if (TryGetWave(team, out SpawnableWaveBase wave) && wave is ILimitedWave limitedWave) + limitedWave.RespawnTokens += Math.Max(0, limitedWave.RespawnTokens - amount); + } /// - /// Removes tickets from a . + /// Removes tickets from a . /// - /// The to remove tickets from. + /// The to remove tickets from. /// The amount of tickets to remove. - public static void RemoveTickets(SpawnableTeamType team, float amount) => RespawnTokensManager.RemoveTokens(team, Math.Max(0, amount)); + public static void RemoveTickets(Faction team, int amount) + { + if (TryGetWave(team, out SpawnableWaveBase wave) && wave is ILimitedWave limitedWave) + limitedWave.RespawnTokens = Math.Max(0, limitedWave.RespawnTokens - amount); + } /// - /// Modify tickets from a . + /// Modify tickets from a . /// - /// The to modify tickets from. + /// The to modify tickets from. /// The amount of tickets to modify. - public static void ModifyTickets(SpawnableTeamType team, float amount) => RespawnTokensManager.ModifyTokens(team, amount); - - /// - /// Forces a spawn of the given . - /// - /// The to spawn. - /// Whether or not effects will be played with the spawn. - public static void ForceWave(SpawnableTeamType team, bool playEffects = false) + public static void ModifyTickets(Faction team, int amount) { - if (playEffects) - RespawnEffectsController.ExecuteAllEffects(RespawnEffectsController.EffectType.Selection, team); - - RespawnManager.Singleton.ForceSpawnTeam(team); + if (TryGetWave(team, out SpawnableWaveBase wave) && wave is ILimitedWave limitedWave) + limitedWave.RespawnTokens = amount; } } } \ No newline at end of file diff --git a/Exiled.API/Features/Roles/DestroyedRole.cs b/Exiled.API/Features/Roles/DestroyedRole.cs new file mode 100644 index 0000000000..39fba9e8e4 --- /dev/null +++ b/Exiled.API/Features/Roles/DestroyedRole.cs @@ -0,0 +1,31 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.API.Features.Roles +{ + using PlayerRoles; + + using BaseDestroyedRole = PlayerRoles.DestroyedRole; + + /// + /// Defines a role that represents the Destroyed Role. + /// + public class DestroyedRole : Role + { + /// + /// Initializes a new instance of the class. + /// + /// the base . + internal DestroyedRole(BaseDestroyedRole baseRole) + : base(baseRole) + { + } + + /// + public override RoleTypeId Type { get; } = RoleTypeId.Destroyed; + } +} \ No newline at end of file diff --git a/Exiled.API/Features/Roles/Role.cs b/Exiled.API/Features/Roles/Role.cs index ecfbc9bc5b..fef83ae6f0 100644 --- a/Exiled.API/Features/Roles/Role.cs +++ b/Exiled.API/Features/Roles/Role.cs @@ -24,6 +24,7 @@ namespace Exiled.API.Features.Roles using PlayerRoles.RoleAssign; using UnityEngine; + using DestroyedGameRole = PlayerRoles.DestroyedRole; using FilmmakerGameRole = PlayerRoles.Filmmaker.FilmmakerRole; using HumanGameRole = PlayerRoles.HumanRole; using OverwatchGameRole = PlayerRoles.Spectating.OverwatchRole; @@ -299,6 +300,7 @@ public virtual void Set(RoleTypeId newRole, RoleChangeReason reason, RoleSpawnFl SpectatorGameRole spectatorRole => new SpectatorRole(spectatorRole), HumanGameRole humanRole => new HumanRole(humanRole), FilmmakerGameRole filmmakerRole => new FilmMakerRole(filmmakerRole), + DestroyedGameRole destroyedRole => new DestroyedRole(destroyedRole), _ => new NoneRole(role), }; } diff --git a/Exiled.API/Features/Roles/Scp079Role.cs b/Exiled.API/Features/Roles/Scp079Role.cs index ee81c6c801..b18d344267 100644 --- a/Exiled.API/Features/Roles/Scp079Role.cs +++ b/Exiled.API/Features/Roles/Scp079Role.cs @@ -716,7 +716,7 @@ public void ActivateTesla(bool consumeEnergy = true) Scp079Camera cam = CurrentCameraSync.CurrentCamera; RewardManager.MarkRoom(cam.Room); - if (!TeslaGateController.Singleton.TeslaGates.TryGetFirst(x => RoomIdUtils.IsTheSameRoom(cam.Position, x.transform.position), out global::TeslaGate teslaGate)) + if (!global::TeslaGate.AllGates.TryGetFirst(x => RoomIdUtils.IsTheSameRoom(cam.Position, x.transform.position), out global::TeslaGate teslaGate)) return; if (consumeEnergy) diff --git a/Exiled.API/Features/Roles/Scp106Role.cs b/Exiled.API/Features/Roles/Scp106Role.cs index 6e5797bbba..c101c73c74 100644 --- a/Exiled.API/Features/Roles/Scp106Role.cs +++ b/Exiled.API/Features/Roles/Scp106Role.cs @@ -33,7 +33,7 @@ public class Scp106Role : FpcRole, ISubroutinedScpRole, IHumeShieldRole, ISpawna private readonly ConstProperty corrodingTime = new(Scp106Attack.CorrodingTime, new[] { typeof(Scp106Attack) }); private readonly ConstProperty vigorCaptureReward = new(Scp106Attack.VigorCaptureReward, new[] { typeof(Scp106Attack) }); private readonly ConstProperty cooldownReductionReward = new(Scp106Attack.CooldownReductionReward, new[] { typeof(Scp106Attack) }); - private readonly ConstProperty sinkholeCooldownDuration = new(Scp106SinkholeController.CooldownDuration, new[] { typeof(Scp106SinkholeController) }); + private readonly ConstProperty sinkholeCooldownDuration = new(Scp106SinkholeController.EmergeCooldownDuration, new[] { typeof(Scp106SinkholeController) }); private readonly ConstProperty huntersAtlasCostPerMeter = new(Scp106HuntersAtlasAbility.CostPerMeter, new[] { typeof(Scp106HuntersAtlasAbility) }); /// @@ -137,8 +137,12 @@ public float Vigor [EProperty(category: nameof(Scp106Role))] public bool IsSubmerged { - get => Base.IsSubmerged; - set => HuntersAtlasAbility.SetSubmerged(value); + get => HuntersAtlasAbility._syncSubmerged; + set + { + HuntersAtlasAbility._syncSubmerged = value; + HuntersAtlasAbility.ServerSendRpc(true); + } } /// @@ -165,12 +169,6 @@ public bool IsSubmerged [EProperty(readOnly: true, category: nameof(Scp106Role))] public float SinkholeCurrentTime => SinkholeController.ElapsedToggle; - /// - /// Gets a value indicating the normalized state of the sinkhole. - /// - [EProperty(readOnly: true, category: nameof(Scp106Role))] - public float SinkholeNormalizedState => SinkholeController.NormalizedState; - /// /// Gets a value indicating whether or not SCP-106 is currently in the middle of an animation. /// @@ -183,26 +181,11 @@ public bool IsSubmerged [EProperty(readOnly: true, category: nameof(Scp106Role))] public bool IsSinkholeHidden => SinkholeController.IsHidden; - /// - /// Gets or sets a value indicating whether the current sinkhole state. - /// - [EProperty(category: nameof(Scp106Role))] - public bool SinkholeState - { - get => SinkholeController.State; - set => SinkholeController.State = value; - } - /// /// Gets the sinkhole target duration. /// [EProperty(readOnly: true, category: nameof(Scp106Role))] - public float SinkholeTargetDuration => SinkholeController.TargetDuration; - - /// - /// Gets the speed multiplier of the sinkhole. - /// - public float SinkholeSpeedMultiplier => SinkholeController.SpeedMultiplier; + public float SinkholeTargetDuration => SinkholeController.TargetTransitionDuration; /// /// Gets or sets how mush cost the Ability Stalk will cost per tick when being stationary. @@ -306,10 +289,10 @@ public float CaptureCooldown [EProperty(category: nameof(Scp106Role))] public float RemainingSinkholeCooldown { - get => SinkholeController.Cooldown.Remaining; + get => SinkholeController._submergeCooldown.Remaining; set { - SinkholeController.Cooldown.Remaining = value; + SinkholeController._submergeCooldown.Remaining = value; SinkholeController.ServerSendRpc(true); } } @@ -320,8 +303,8 @@ public float RemainingSinkholeCooldown [EProperty(category: nameof(Scp106Role))] public bool IsStalking { - get => StalkAbility.IsActive; - set => StalkAbility.IsActive = value; + get => StalkAbility.StalkActive; + set => StalkAbility.ServerSetStalk(value); } /// @@ -347,7 +330,7 @@ public bool UsePortal(Vector3 position, float cost = 0f) return false; HuntersAtlasAbility._estimatedCost = cost; - HuntersAtlasAbility.SetSubmerged(true); + HuntersAtlasAbility._syncSubmerged = true; return true; } @@ -361,6 +344,7 @@ public bool CapturePlayer(Player player) { if (player is null) return false; + Attack._targetHub = player.ReferenceHub; DamageHandlerBase handler = new ScpDamageHandler(Attack.Owner, AttackDamage, DeathTranslations.PocketDecay); diff --git a/Exiled.API/Features/Room.cs b/Exiled.API/Features/Room.cs index 0fb949f77f..68c7a4ec9e 100644 --- a/Exiled.API/Features/Room.cs +++ b/Exiled.API/Features/Room.cs @@ -466,19 +466,26 @@ private static RoomType FindType(GameObject gameObject) "LCZ_372" => RoomType.LczGlassBox, "LCZ_ChkpA" => RoomType.LczCheckpointA, "HCZ_079" => RoomType.Hcz079, - "HCZ_Room3ar" => RoomType.HczArmory, + "HCZ_TArmory" => RoomType.HczArmory, + "HCZ_Crossroom_Water" => RoomType.HczCrossRoomWater, "HCZ_Testroom" => RoomType.HczTestRoom, - "HCZ_Hid" => RoomType.HczHid, + "HCZ_MicroHID_New" => RoomType.HczHid, "HCZ_049" => RoomType.Hcz049, "HCZ_Crossing" => RoomType.HczCrossing, - "HCZ_106" => RoomType.Hcz106, + "HCZ_106_Rework" => RoomType.Hcz106, "HCZ_Nuke" => RoomType.HczNuke, - "HCZ_Tesla" => RoomType.HczTesla, + "HCZ_Tesla_Rework" => RoomType.HczTesla, "HCZ_Servers" => RoomType.HczServers, "HCZ_Room3" => RoomType.HczTCross, - "HCZ_457" => RoomType.Hcz096, + "HCZ_Intersection_Junk" => RoomType.HczIntersectionJunk, + "HCZ_Intersection" => RoomType.HczIntersection, + "HCZ_096" => RoomType.Hcz096, "HCZ_Curve" => RoomType.HczCurve, + "HCZ_Corner_Deep" => RoomType.HczCornerDeep, + "HCZ_Straight_C" => RoomType.HczStraightC, "HCZ_Straight" => RoomType.HczStraight, + "HCZ_Straight_PipeRoom"=> RoomType.HczStraightPipeRoom, + "HCZ_Straight Variant" => RoomType.HczStraightVariant, "EZ_Endoof" => RoomType.EzVent, "EZ_Intercom" => RoomType.EzIntercom, "EZ_GateA" => RoomType.EzGateA, @@ -487,7 +494,8 @@ private static RoomType FindType(GameObject gameObject) "EZ_PCs" => RoomType.EzPcs, "EZ_Crossing" => RoomType.EzCrossing, "EZ_CollapsedTunnel" => RoomType.EzCollapsedTunnel, - "EZ_Smallrooms2" => RoomType.EzConference, + "EZ_Smallrooms2" or "EZ_Smallrooms1" => RoomType.EzConference, + "EZ_Chef" => RoomType.EzChef, "EZ_Straight" => RoomType.EzStraight, "EZ_Cafeteria" => RoomType.EzCafeteria, "EZ_upstairs" => RoomType.EzUpstairsPcs, @@ -497,14 +505,17 @@ private static RoomType FindType(GameObject gameObject) "PocketWorld" => RoomType.Pocket, "Outside" => RoomType.Surface, "HCZ_939" => RoomType.Hcz939, - "EZ Part" => RoomType.EzCheckpointHallway, + "EZ_HCZ_Checkpoint Part" => gameObject.transform.position.z switch + { + > 80 => RoomType.EzCheckpointHallwayA, + _ => RoomType.EzCheckpointHallwayB, + }, "HCZ_ChkpA" => RoomType.HczElevatorA, "HCZ_ChkpB" => RoomType.HczElevatorB, - "HCZ Part" => gameObject.transform.parent.name switch + "HCZ_EZ_Checkpoint Part" => gameObject.transform.position.z switch { - "HCZ_EZ_Checkpoint (A)" => RoomType.HczEzCheckpointA, - "HCZ_EZ_Checkpoint (B)" => RoomType.HczEzCheckpointB, - _ => RoomType.Unknown + > 80 => RoomType.HczEzCheckpointA, + _ => RoomType.HczEzCheckpointB }, _ => RoomType.Unknown, }; @@ -512,6 +523,9 @@ private static RoomType FindType(GameObject gameObject) private static ZoneType FindZone(GameObject gameObject) { + if (gameObject.name == "PocketWorld") + return ZoneType.Pocket; + Transform transform = gameObject.transform; if (transform && transform.parent) diff --git a/Exiled.API/Features/Round.cs b/Exiled.API/Features/Round.cs index 071625019b..42022555ad 100644 --- a/Exiled.API/Features/Round.cs +++ b/Exiled.API/Features/Round.cs @@ -11,7 +11,7 @@ namespace Exiled.API.Features using System.Collections.Generic; using Enums; - using Exiled.API.Extensions; + using Extensions; using GameCore; using PlayerRoles; @@ -46,12 +46,12 @@ public static class Round /// /// Gets a value indicating whether the round is started or not. /// - public static bool IsStarted => ReferenceHub.LocalHub && ReferenceHub.LocalHub.characterClassManager.RoundStarted; + public static bool IsStarted => ReferenceHub._localHub != null && ReferenceHub._localHub.characterClassManager.RoundStarted; /// /// Gets a value indicating whether the round in progress or not. /// - public static bool InProgress => ReferenceHub.LocalHub != null && RoundSummary.RoundInProgress(); + public static bool InProgress => ReferenceHub._localHub != null && RoundSummary.RoundInProgress(); /// /// Gets a value indicating whether the round is ended or not. @@ -64,12 +64,12 @@ public static class Round public static bool IsLobby => !(IsEnded || IsStarted); /// - /// Gets or sets a value indicating the amount of Chaos Targets remaining. + /// Gets or sets a value indicating the amount of Extra Targets remaining. /// - public static int ChaosTargetCount + public static int ExtraTargetsCount { - get => RoundSummary.singleton.Network_chaosTargetCount; - set => RoundSummary.singleton.Network_chaosTargetCount = value; + get => RoundSummary.singleton.Network_extraTargets; + set => RoundSummary.singleton.Network_extraTargets = value; } /// @@ -196,7 +196,7 @@ public static int TargetOffset targetOffset = value; foreach (Player player in Player.List) { - player.SendFakeSyncVar(RoundSummary.singleton.netIdentity, typeof(RoundSummary), nameof(RoundSummary.Network_chaosTargetCount), RoundSummary.singleton._chaosTargetCount + TargetOffset); + player.SendFakeSyncVar(RoundSummary.singleton.netIdentity, typeof(RoundSummary), nameof(RoundSummary.Network_extraTargets), RoundSummary.singleton._extraTargets + TargetOffset); } } } diff --git a/Exiled.API/Features/Scp914Processors/FirearmProcessor.cs b/Exiled.API/Features/Scp914Processors/FirearmProcessor.cs index 58d71f9dd1..56b82e87e2 100644 --- a/Exiled.API/Features/Scp914Processors/FirearmProcessor.cs +++ b/Exiled.API/Features/Scp914Processors/FirearmProcessor.cs @@ -33,15 +33,6 @@ public FirearmProcessor(FirearmItemProcessor scp914ItemProcessor) /// public new FirearmItemProcessor Base { get; } - /// - /// Gets or sets a value indicating whether or not magazine should be refilled. - /// - public bool RefillAmmo - { - get => Base._refillAmmo; - set => Base._refillAmmo = value; - } - /// /// Gets or sets a list of items that replace upgrading item when is . /// diff --git a/Exiled.API/Features/Scp914Processors/Scp914Processor.cs b/Exiled.API/Features/Scp914Processors/Scp914Processor.cs index f6c7dea43b..f3964b461c 100644 --- a/Exiled.API/Features/Scp914Processors/Scp914Processor.cs +++ b/Exiled.API/Features/Scp914Processors/Scp914Processor.cs @@ -57,19 +57,18 @@ public Scp914Processor(Scp914ItemProcessor scp914ItemProcessor) /// /// Upgrades an item from player's inventory. /// - /// Player from whose inventory item will be chosen. /// Item to update. /// Setting to use. /// A new upgraded item. - public Item UpgradeInventoryItem(Player player, Item item, Scp914KnobSetting scp914KnobSetting) => Item.Get(Base.OnInventoryItemUpgraded(scp914KnobSetting, player.ReferenceHub, item.Serial)); + public Scp914Result UpgradeInventoryItem(Item item, Scp914KnobSetting scp914KnobSetting) => Base.UpgradeInventoryItem(scp914KnobSetting, item.Base); /// - /// Upgrades an pickup from player's inventory. + /// Upgrades a pickup from player's inventory. /// /// Pickup to update. /// Setting to use. /// A new upgraded pickup. - public Pickup UpgradePickup(Pickup pickup, Scp914KnobSetting scp914KnobSetting) => Pickup.Get(Base.OnPickupUpgraded(scp914KnobSetting, pickup.Base, Scp914.MovingVector)); + public Scp914Result UpgradePickup(Pickup pickup, Scp914KnobSetting scp914KnobSetting) => Base.UpgradePickup(scp914KnobSetting, pickup.Base); /// /// Gets a random output item. diff --git a/Exiled.API/Features/Toys/AdminToy.cs b/Exiled.API/Features/Toys/AdminToy.cs index df20f5544e..ce6b79ff50 100644 --- a/Exiled.API/Features/Toys/AdminToy.cs +++ b/Exiled.API/Features/Toys/AdminToy.cs @@ -98,7 +98,7 @@ public Quaternion Rotation set { Transform.rotation = value; - AdminToyBase.NetworkRotation = new(value); + AdminToyBase.NetworkRotation = value; } } diff --git a/Exiled.API/Features/Toys/Light.cs b/Exiled.API/Features/Toys/Light.cs index e0e8e7215b..da3fe37abc 100644 --- a/Exiled.API/Features/Toys/Light.cs +++ b/Exiled.API/Features/Toys/Light.cs @@ -12,7 +12,7 @@ namespace Exiled.API.Features.Toys using AdminToys; using Enums; - using Exiled.API.Interfaces; + using Exiled.API.Interfaces; using Exiled.API.Structs; using UnityEngine; @@ -62,7 +62,7 @@ public float Range } /// - /// Gets or sets the color of the primitive. + /// Gets or sets the color of the light. /// public Color Color { @@ -73,24 +73,69 @@ public Color Color /// /// Gets or sets a value indicating whether the light should cause shadows from other objects. /// - public bool ShadowEmission + public LightShadows Shadow { - get => Base.NetworkLightShadows; - set => Base.NetworkLightShadows = value; - } - + get => Base.NetworkShadowType; + set => Base.NetworkShadowType = value; + } + + /// + /// Gets or sets the light shape. + /// + public LightShape Shape + { + get => Base.NetworkLightShape; + set => Base.NetworkLightShape = value; + } + + /// + /// Gets or sets the shadow strength. + /// + public float ShadowStrength + { + get => Base.NetworkShadowStrength; + set => Base.NetworkShadowStrength = value; + } + + /// + /// Gets or sets the Light Type of this light. + /// + public LightType LightType + { + get => Base.NetworkLightType; + set => Base.NetworkLightType = value; + } + + /// + /// Gets or sets the spot angle of this light. + /// + public float SpotAngle + { + get => Base.NetworkSpotAngle; + set => Base.NetworkSpotAngle = value; + } + + /// + /// Gets or sets the inner spot angle of this light. + /// + public float InnerSpotAngle + { + get => Base.NetworkInnerSpotAngle; + set => Base.NetworkInnerSpotAngle = value; + } + /// /// Creates a new . /// /// The position of the . /// The rotation of the . - /// The scale of the . - /// The color of the . + /// The scale of the . + /// The color of the . /// Whether or not the should be initially spawned. /// The newly created . - public static Light Create(Vector3? position = null, Quaternion? rotation = null, Vector3? scale = null, Color? color = null, bool spawn = true) - => Create(new(position, rotation, scale, color, spawn)); - + public static Light Create(Vector3? position = null, Quaternion? rotation = null, Vector3? scale = null, Color? color = null, bool spawn = true) + => Create(new(position, rotation, scale, color, spawn)); + /// /// Creates a new . /// @@ -98,12 +143,12 @@ public static Light Create(Vector3? position = null, Quaternion? rotation = null /// The new . public static Light Create(LightSettings lightSettings) { - Light light = new(Object.Instantiate(PrefabObject.GetComponent())) - { - Position = lightSettings.Position, - Rotation = lightSettings.Rotation, - Scale = lightSettings.Scale, - Color = lightSettings.Color, + Light light = new(Object.Instantiate(PrefabObject.GetComponent())) + { + Position = lightSettings.Position, + Rotation = lightSettings.Rotation, + Scale = lightSettings.Scale, + Color = lightSettings.Color, }; if (lightSettings.ShouldSpawn) diff --git a/Exiled.API/Features/Toys/Speaker.cs b/Exiled.API/Features/Toys/Speaker.cs new file mode 100644 index 0000000000..12afc66edb --- /dev/null +++ b/Exiled.API/Features/Toys/Speaker.cs @@ -0,0 +1,91 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.API.Features.Toys +{ + using System.Linq; + + using AdminToys; + using Enums; + using Interfaces; + + /// + /// A wrapper class for . + /// + public class Speaker : AdminToy, IWrapper + { + /// + /// Initializes a new instance of the class. + /// + /// The of the toy. + internal Speaker(SpeakerToy speakerToy) + : base(speakerToy, AdminToyType.Speaker) => Base = speakerToy; + + /// + /// Gets the base . + /// + public SpeakerToy Base { get; } + + /// + /// Gets or sets the controller Id of the SpeakerToy. + /// + public byte ControllerId + { + get => Base.NetworkControllerId; + set => Base.NetworkControllerId = value; + } + + /// + /// Gets or sets the volume of the audio source. + /// + /// 0.0 is silent and 1.0 is full volume. + public float Volume + { + get => Base.NetworkVolume; + set => Base.NetworkVolume = value; + } + + /// + /// Gets or sets a value indicating whether the audio source is spatialize. + /// + /// If true, the audio source will become spatial, which will become 3D relative to the position of the player listening to it. + public bool IsSpatial + { + get => Base.NetworkIsSpatial; + set => Base.NetworkIsSpatial = value; + } + + /// + /// Gets or sets the minimum distance the audio source can be heard. + /// + public float MinDistance + { + get => Base.NetworkMinDistance; + set => Base.NetworkMinDistance = value; + } + + /// + /// Gets or sets the maximum distance the audio source can be heard. + /// + public float MaxDistance + { + get => Base.NetworkMaxDistance; + set => Base.NetworkMaxDistance = value; + } + + /// + /// Gets the belonging to the . + /// + /// The instance. + /// The corresponding instance. + public static Speaker Get(SpeakerToy speakerToy) + { + AdminToy adminToy = Map.Toys.FirstOrDefault(x => x.AdminToyBase == speakerToy); + return adminToy is not null ? adminToy as Speaker : new Speaker(speakerToy); + } + } +} \ No newline at end of file diff --git a/Exiled.API/Features/Warhead.cs b/Exiled.API/Features/Warhead.cs index 2438f223a7..44222d833b 100644 --- a/Exiled.API/Features/Warhead.cs +++ b/Exiled.API/Features/Warhead.cs @@ -122,7 +122,7 @@ public static WarheadStatus Status /// /// Gets a value indicating whether or not the warhead has already been detonated. /// - public static bool IsDetonated => Controller._alreadyDetonated; + public static bool IsDetonated => Controller.AlreadyDetonated; /// /// Gets a value indicating whether or not the warhead detonation is in progress. diff --git a/Exiled.API/Features/Window.cs b/Exiled.API/Features/Window.cs index 896de4e148..6a3718ebe7 100644 --- a/Exiled.API/Features/Window.cs +++ b/Exiled.API/Features/Window.cs @@ -86,15 +86,15 @@ internal Window(BreakableWindow window, Room room) /// /// Gets a value indicating whether or not this window is breakable. /// - public bool IsBreakable => !Base.isBroken; + public bool IsBreakable => !Base.NetworkisBroken; /// /// Gets or sets a value indicating whether or not this window is broken. /// public bool IsBroken { - get => Base.isBroken; - set => Base.isBroken = value; + get => Base.NetworkisBroken; + set => Base.NetworkisBroken = value; } /// @@ -115,15 +115,6 @@ public bool DisableScpDamage set => Base._preventScpDamage = value; } - /// - /// Gets or sets a value indicating whether or not this window is broken. - /// - public BreakableWindow.BreakableWindowStatus SyncStatus - { - get => Base.NetworksyncStatus; - set => Base.NetworksyncStatus = value; - } - /// /// Gets or sets a value indicating who is the LastAttacker. /// diff --git a/Exiled.CustomModules/API/Features/CustomItems/Items/Firearms/FirearmBehaviour.cs b/Exiled.CustomModules/API/Features/CustomItems/Items/Firearms/FirearmBehaviour.cs index f7d625690f..5af9554c85 100644 --- a/Exiled.CustomModules/API/Features/CustomItems/Items/Firearms/FirearmBehaviour.cs +++ b/Exiled.CustomModules/API/Features/CustomItems/Items/Firearms/FirearmBehaviour.cs @@ -56,12 +56,12 @@ public abstract class FirearmBehaviour : ItemBehaviour /// /// Gets or sets the replicated clip. /// - public ReplicatedProperty ReplicatedClip { get; set; } + public ReplicatedProperty ReplicatedClip { get; set; } /// /// Gets or sets the replicated max ammo. /// - public ReplicatedProperty ReplicatedMaxAmmo { get; set; } + public ReplicatedProperty ReplicatedMaxAmmo { get; set; } /// protected override void PostInitialize() @@ -123,7 +123,7 @@ protected override void PostInitialize() Firearm.Recoil = FirearmSettings.RecoilSettings; - ReplicatedMaxAmmo = new ReplicatedProperty( + ReplicatedMaxAmmo = new ReplicatedProperty( firearm => firearm.MaxAmmo, (firearm, value) => firearm.MaxAmmo = value, Firearm); @@ -133,7 +133,7 @@ protected override void PostInitialize() if (overrideReload) { - ReplicatedClip = new ReplicatedProperty( + ReplicatedClip = new ReplicatedProperty( firearm => firearm.Ammo, (firearm, value) => firearm.Ammo = value, Firearm); @@ -233,7 +233,7 @@ private protected virtual void OnInternalReloading(ReloadingWeaponEventArgs ev) return; byte clipSize = FirearmSettings.ClipSize; - byte remainingClip = ReplicatedClip.ReplicatedValue; + int remainingClip = ReplicatedClip.ReplicatedValue; if (remainingClip >= clipSize) return; diff --git a/Exiled.CustomModules/API/Features/CustomItems/Items/Firearms/SemiAutomaticFirearmBehaviour.cs b/Exiled.CustomModules/API/Features/CustomItems/Items/Firearms/SemiAutomaticFirearmBehaviour.cs index a9814cb051..0cc985d9e3 100644 --- a/Exiled.CustomModules/API/Features/CustomItems/Items/Firearms/SemiAutomaticFirearmBehaviour.cs +++ b/Exiled.CustomModules/API/Features/CustomItems/Items/Firearms/SemiAutomaticFirearmBehaviour.cs @@ -49,7 +49,7 @@ protected override void PostInitialize() FiringMode = FirearmSettings.FiringMode; - ReplicatedClip = new ReplicatedProperty( + ReplicatedClip = new ReplicatedProperty( firearm => firearm.Ammo, (firearm, value) => firearm.Ammo = value, Firearm); @@ -84,7 +84,7 @@ private protected override void OnInternalShooting(ShootingEventArgs ev) } else if (FiringMode is FiringMode.Burst) { - byte burstLength = ReplicatedClip.ReplicatedValue >= FirearmSettings.BurstLength ? FirearmSettings.BurstLength : ReplicatedClip.Value; + int burstLength = ReplicatedClip.ReplicatedValue >= FirearmSettings.BurstLength ? FirearmSettings.BurstLength : ReplicatedClip.Value; ReplicatedClip.Send((byte)(ReplicatedClip.ReplicatedValue - burstLength)); ReplicatedClip.Replicate(burstLength); } diff --git a/Exiled.Events/EventArgs/Map/PlacingBulletHoleEventArgs.cs b/Exiled.Events/EventArgs/Map/PlacingBulletHoleEventArgs.cs index 8e237af27e..b6e5254630 100644 --- a/Exiled.Events/EventArgs/Map/PlacingBulletHoleEventArgs.cs +++ b/Exiled.Events/EventArgs/Map/PlacingBulletHoleEventArgs.cs @@ -8,9 +8,8 @@ namespace Exiled.Events.EventArgs.Map { using API.Features; - + using Exiled.API.Features.Items; using Interfaces; - using UnityEngine; /// @@ -27,11 +26,15 @@ public class PlacingBulletHoleEventArgs : IPlayerEvent, IDeniableEvent /// /// /// - public PlacingBulletHoleEventArgs(Player owner, RaycastHit hit) + /// + /// + /// + public PlacingBulletHoleEventArgs(Player owner, RaycastHit hit, InventorySystem.Items.Firearms.Firearm firearm) { Player = owner; Position = hit.point; Rotation = Quaternion.LookRotation(hit.normal); + Firearm = Item.Get(firearm).As(); } /// @@ -53,5 +56,10 @@ public PlacingBulletHoleEventArgs(Player owner, RaycastHit hit) /// Gets the decal owner. /// public Player Player { get; } + + /// + /// Gets the firearm that triggered the event. + /// + public Firearm Firearm { get; } } } \ No newline at end of file diff --git a/Exiled.Events/EventArgs/Player/AddingItemEventArgs.cs b/Exiled.Events/EventArgs/Player/AddingItemEventArgs.cs index 6fa3c24b28..5e0db7400d 100644 --- a/Exiled.Events/EventArgs/Player/AddingItemEventArgs.cs +++ b/Exiled.Events/EventArgs/Player/AddingItemEventArgs.cs @@ -10,7 +10,8 @@ namespace Exiled.Events.EventArgs.Player using Exiled.API.Features; using Exiled.API.Features.Items; using Exiled.API.Features.Pickups; - using Exiled.Events.EventArgs.Interfaces; + using Interfaces; + using InventorySystem.Items; /// /// Contains all information before adding an item to a player's inventory. @@ -23,12 +24,14 @@ public class AddingItemEventArgs : IPlayerEvent, IDeniableEvent, IItemEvent, IPi /// /// /// + /// /// - public AddingItemEventArgs(Player player, Item item, Pickup pickup, bool isAllowed = true) + public AddingItemEventArgs(Player player, Item item, Pickup pickup, ItemAddReason addReason, bool isAllowed = true) { Player = player; Item = item; Pickup = pickup; + AddReason = addReason; IsAllowed = isAllowed; } @@ -45,6 +48,11 @@ public AddingItemEventArgs(Player player, Item item, Pickup pickup, bool isAllow /// public Pickup Pickup { get; } + /// + /// Gets or sets the reason of why the item was added to the player inventory. + /// + public ItemAddReason AddReason { get; set; } + /// public bool IsAllowed { get; set; } } diff --git a/Exiled.Events/EventArgs/Player/AimingDownSightEventArgs.cs b/Exiled.Events/EventArgs/Player/AimingDownSightEventArgs.cs index 9370ba42b5..5ca76161cf 100644 --- a/Exiled.Events/EventArgs/Player/AimingDownSightEventArgs.cs +++ b/Exiled.Events/EventArgs/Player/AimingDownSightEventArgs.cs @@ -26,25 +26,20 @@ public class AimingDownSightEventArgs : IPlayerEvent, IFirearmEvent /// /// /// - /// - /// + /// + /// /// - public AimingDownSightEventArgs(Player player, Firearm firearm, bool adsIn) + public AimingDownSightEventArgs(Player player, Firearm firearm, bool aiming) { Firearm = firearm; Player = player; - AdsIn = adsIn; + Aiming = aiming; } /// - /// Gets a value indicating whether or not the player is aiming down sight in. + /// Gets a value indicating whether the player starts aiming or stops aiming. /// - public bool AdsIn { get; } - - /// - /// Gets a value indicating whether or not the player is aiming down sight out. - /// - public bool AdsOut => !AdsIn; + public bool Aiming { get; } /// /// Gets the used to trigger the aim action. diff --git a/Exiled.Events/EventArgs/Player/TogglingWeaponFlashlightEventArgs.cs b/Exiled.Events/EventArgs/Player/TogglingWeaponFlashlightEventArgs.cs index a49e64a653..5b0e2cbf7d 100644 --- a/Exiled.Events/EventArgs/Player/TogglingWeaponFlashlightEventArgs.cs +++ b/Exiled.Events/EventArgs/Player/TogglingWeaponFlashlightEventArgs.cs @@ -41,9 +41,9 @@ public TogglingWeaponFlashlightEventArgs(Player player, Firearm firearm, bool ne } /// - /// Gets a value indicating whether the new weapon's flashlight state will be enabled. + /// Gets or sets a value indicating whether the weapon's flashlight will turn on or off. /// - public bool NewState { get; } + public bool NewState { get; set; } /// /// Gets or sets a value indicating whether or not the weapon's flashlight can be toggled. diff --git a/Exiled.Events/EventArgs/Server/RespawnedTeamEventArgs.cs b/Exiled.Events/EventArgs/Server/RespawnedTeamEventArgs.cs index 6af48698ec..b48f565d4b 100644 --- a/Exiled.Events/EventArgs/Server/RespawnedTeamEventArgs.cs +++ b/Exiled.Events/EventArgs/Server/RespawnedTeamEventArgs.cs @@ -13,6 +13,7 @@ namespace Exiled.Events.EventArgs.Server using Exiled.API.Features; using Exiled.Events.EventArgs.Interfaces; using Respawning; + using Respawning.Waves; /// /// Contains all information after a team has spawned. @@ -24,7 +25,7 @@ public class RespawnedTeamEventArgs : IExiledEvent /// /// /// - public RespawnedTeamEventArgs(SpawnableTeamType team, IEnumerable hubs) + public RespawnedTeamEventArgs(SpawnableWaveBase team, IEnumerable hubs) { Players = hubs.Select(Player.Get); Team = team; @@ -38,6 +39,6 @@ public RespawnedTeamEventArgs(SpawnableTeamType team, IEnumerable /// /// Gets the spawned team. /// - public SpawnableTeamType Team { get; } + public SpawnableWaveBase Team { get; } } } \ No newline at end of file diff --git a/Exiled.Events/Events.cs b/Exiled.Events/Events.cs index ed5b939b28..ba61519c7f 100644 --- a/Exiled.Events/Events.cs +++ b/Exiled.Events/Events.cs @@ -17,7 +17,6 @@ namespace Exiled.Events using CentralAuth; using Exiled.API.Interfaces; using Exiled.Events.Features; - using HarmonyLib; using InventorySystem.Items.Pickups; using InventorySystem.Items.Usables; using PlayerRoles.Ragdolls; @@ -62,7 +61,7 @@ public override void OnEnabled() PlayerAuthenticationManager.OnInstanceModeChanged -= RoleAssigner.CheckLateJoin; SceneManager.sceneUnloaded += Handlers.Internal.SceneUnloaded.OnSceneUnloaded; - MapGeneration.SeedSynchronizer.OnMapGenerated += Handlers.Internal.MapGenerated.OnMapGenerated; + MapGeneration.SeedSynchronizer.OnGenerationFinished += Handlers.Internal.MapGenerated.OnMapGenerated; UsableItemsController.ServerOnUsingCompleted += Handlers.Internal.Round.OnServerOnUsingCompleted; Handlers.Server.WaitingForPlayers += Handlers.Internal.Round.OnWaitingForPlayers; Handlers.Server.RestartingRound += Handlers.Internal.Round.OnRestartingRound; @@ -77,7 +76,7 @@ public override void OnEnabled() InventorySystem.InventoryExtensions.OnItemAdded += Handlers.Player.OnItemAdded; InventorySystem.InventoryExtensions.OnItemRemoved += Handlers.Player.OnItemRemoved; - RespawnManager.ServerOnRespawned += Handlers.Server.OnRespawnedTeam; + WaveManager.OnWaveSpawned += Handlers.Server.OnRespawnedTeam; RagdollManager.OnRagdollSpawned += Handlers.Internal.RagdollList.OnSpawnedRagdoll; RagdollManager.OnRagdollRemoved += Handlers.Internal.RagdollList.OnRemovedRagdoll; @@ -110,7 +109,7 @@ public override void OnDisabled() Unpatch(); SceneManager.sceneUnloaded -= Handlers.Internal.SceneUnloaded.OnSceneUnloaded; - MapGeneration.SeedSynchronizer.OnMapGenerated -= Handlers.Internal.MapGenerated.OnMapGenerated; + MapGeneration.SeedSynchronizer.OnGenerationFinished -= Handlers.Internal.MapGenerated.OnMapGenerated; UsableItemsController.ServerOnUsingCompleted -= Handlers.Internal.Round.OnServerOnUsingCompleted; Handlers.Server.WaitingForPlayers -= Handlers.Internal.Round.OnWaitingForPlayers; @@ -126,7 +125,7 @@ public override void OnDisabled() InventorySystem.InventoryExtensions.OnItemAdded -= Handlers.Player.OnItemAdded; InventorySystem.InventoryExtensions.OnItemRemoved -= Handlers.Player.OnItemRemoved; - RespawnManager.ServerOnRespawned -= Handlers.Server.OnRespawnedTeam; + WaveManager.OnWaveSpawned -= Handlers.Server.OnRespawnedTeam; RagdollManager.OnRagdollSpawned -= Handlers.Internal.RagdollList.OnSpawnedRagdoll; RagdollManager.OnRagdollRemoved -= Handlers.Internal.RagdollList.OnRemovedRagdoll; diff --git a/Exiled.Events/Handlers/Server.cs b/Exiled.Events/Handlers/Server.cs index 9d97876290..14bd3cb5c6 100644 --- a/Exiled.Events/Handlers/Server.cs +++ b/Exiled.Events/Handlers/Server.cs @@ -10,10 +10,10 @@ namespace Exiled.Events.Handlers using System.Collections.Generic; using Respawning; + using Respawning.Waves; #pragma warning disable SA1623 // Property summary documentation should match accessors - using Exiled.Events.EventArgs.Player; using Exiled.Events.EventArgs.Server; using Exiled.Events.Features; @@ -197,7 +197,7 @@ public static class Server /// /// /// - public static void OnRespawnedTeam(SpawnableTeamType teamType, List hubs) => RespawnedTeam.InvokeSafely(new RespawnedTeamEventArgs(teamType, hubs)); + public static void OnRespawnedTeam(SpawnableWaveBase teamType, List hubs) => RespawnedTeam.InvokeSafely(new RespawnedTeamEventArgs(teamType, hubs)); /// /// Called before adding an unit name. diff --git a/Exiled.Events/Patches/Events/Map/ExplodingFragGrenade.cs b/Exiled.Events/Patches/Events/Map/ExplodingFragGrenade.cs index 2ef6e17001..cbd59e6733 100644 --- a/Exiled.Events/Patches/Events/Map/ExplodingFragGrenade.cs +++ b/Exiled.Events/Patches/Events/Map/ExplodingFragGrenade.cs @@ -26,7 +26,7 @@ namespace Exiled.Events.Patches.Events.Map using static HarmonyLib.AccessTools; /// - /// Patches . + /// Patches . /// Adds the event. /// [EventPatch(typeof(Handlers.Map), nameof(Handlers.Map.ExplodingGrenade))] diff --git a/Exiled.Events/Patches/Events/Map/PlacingBulletHole.cs b/Exiled.Events/Patches/Events/Map/PlacingBulletHole.cs index 772916b751..29160cd165 100644 --- a/Exiled.Events/Patches/Events/Map/PlacingBulletHole.cs +++ b/Exiled.Events/Patches/Events/Map/PlacingBulletHole.cs @@ -11,16 +11,12 @@ namespace Exiled.Events.Patches.Events.Map using System.Reflection.Emit; using API.Features.Core.Generic.Pools; - using Exiled.Events.Attributes; using Exiled.Events.EventArgs.Map; - using Handlers; - using HarmonyLib; - + using InventorySystem.Items.Firearms; using InventorySystem.Items.Firearms.Modules; - using UnityEngine; using static HarmonyLib.AccessTools; @@ -28,11 +24,11 @@ namespace Exiled.Events.Patches.Events.Map using Player = API.Features.Player; /// - /// Patches . + /// Patches . /// Adds the event. /// [EventPatch(typeof(Map), nameof(Map.PlacingBulletHole))] - [HarmonyPatch(typeof(StandardHitregBase), nameof(StandardHitregBase.PlaceBulletholeDecal))] + [HarmonyPatch(typeof(ImpactEffectsModule), nameof(ImpactEffectsModule.ServerSendImpactDecal))] internal static class PlacingBulletHole { private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) @@ -50,11 +46,16 @@ private static IEnumerable Transpiler(IEnumerable - /// Patches . + /// Patches . /// Adds the event. /// [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.AddingItem))] @@ -40,28 +40,34 @@ private static IEnumerable Transpiler(IEnumerable i.opcode == OpCodes.Ldarg_3) + offset; Label ret = generator.DefineLabel(); + LocalBuilder ev = generator.DeclareLocal(typeof(AddingItemEventArgs)); - newInstructions.InsertRange(index, new CodeInstruction[] + newInstructions.InsertRange(index, new[] { new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), new(OpCodes.Ldfld, Field(typeof(Inventory), nameof(Inventory._hub))), new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), new(OpCodes.Ldloc_1), new(OpCodes.Call, Method(typeof(Item), nameof(Item.Get), new[] { typeof(ItemBase) })), - new(OpCodes.Ldarg_3), + new(OpCodes.Ldarg_S, 4), new(OpCodes.Call, Method(typeof(Pickup), nameof(Pickup.Get), new[] { typeof(ItemPickupBase) })), new(OpCodes.Ldc_I4_1), new(OpCodes.Newobj, GetDeclaredConstructors(typeof(AddingItemEventArgs))[0]), new(OpCodes.Dup), + new(OpCodes.Dup), + new(OpCodes.Stloc_S, ev.LocalIndex), new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnAddingItem))), new(OpCodes.Callvirt, PropertyGetter(typeof(AddingItemEventArgs), nameof(AddingItemEventArgs.IsAllowed))), new(OpCodes.Brfalse_S, ret), + new(OpCodes.Ldloc_S, ev.LocalIndex), + new(OpCodes.Callvirt, PropertyGetter(typeof(AddingItemEventArgs), nameof(AddingItemEventArgs.AddReason))), + new(OpCodes.Starg_S, 3), }); newInstructions[newInstructions.Count - 1].labels.Add(ret); - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; + foreach (CodeInstruction instruction in newInstructions) + yield return instruction; ListPool.Pool.Return(newInstructions); } diff --git a/Exiled.Events/Patches/Events/Player/EnteringKillerCollision.cs b/Exiled.Events/Patches/Events/Player/EnteringKillerCollision.cs index 842e3890cd..854f33e0b8 100644 --- a/Exiled.Events/Patches/Events/Player/EnteringKillerCollision.cs +++ b/Exiled.Events/Patches/Events/Player/EnteringKillerCollision.cs @@ -19,11 +19,11 @@ namespace Exiled.Events.Patches.Events.Player using static HarmonyLib.AccessTools; /// - /// Patches . + /// Patches . /// Adds the event. /// [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.EnteringKillerCollision))] - [HarmonyPatch(typeof(CheckpointKiller), nameof(CheckpointKiller.OnTriggerEnter))] + [HarmonyPatch(typeof(PitKiller), nameof(PitKiller.OnTriggerEnter))] internal static class EnteringKillerCollision { private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) @@ -32,8 +32,8 @@ private static IEnumerable Transpiler(IEnumerable instruction.opcode == OpCodes.Newobj) + offset; + const int offset = -1; + int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldfld) + offset; newInstructions.InsertRange( index, @@ -61,8 +61,8 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } diff --git a/Exiled.Events/Patches/Events/Player/FirearmActionEvents/Aiming.cs b/Exiled.Events/Patches/Events/Player/FirearmActionEvents/Aiming.cs new file mode 100644 index 0000000000..d2954c2b54 --- /dev/null +++ b/Exiled.Events/Patches/Events/Player/FirearmActionEvents/Aiming.cs @@ -0,0 +1,71 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Player.FirearmActionEvents +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + using Exiled.API.Features.Core.Generic.Pools; + using Exiled.API.Features.Items; + using Exiled.Events.Attributes; + using Exiled.Events.EventArgs.Player; + using HarmonyLib; + using InventorySystem.Items.Firearms.Modules; + + using static HarmonyLib.AccessTools; + + /// + /// Patches . + /// Adds event. + /// + [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.AimingDownSight))] + [HarmonyPatch(typeof(LinearAdsModule), nameof(LinearAdsModule.ServerProcessCmd))] + internal static class Aiming + { + [HarmonyTranspiler] + private static IEnumerable OnAimStatusChanged(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + Label returnLabel = generator.DefineLabel(); + + int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ret); + + newInstructions.InsertRange(index, new[] + { + // Player.Get(this.Firearm.Owner) + new CodeInstruction(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(LinearAdsModule), nameof(LinearAdsModule.Firearm))), + new(OpCodes.Callvirt, PropertyGetter(typeof(InventorySystem.Items.Firearms.Firearm), nameof(InventorySystem.Items.Firearms.Firearm.Owner))), + new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), + + // (Firearm)Item.Get(this.Firearm) + new(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(LinearAdsModule), nameof(LinearAdsModule.Firearm))), + new(OpCodes.Call, Method(typeof(Item), nameof(Item.Get), new[] { typeof(InventorySystem.Items.Firearms.Firearm) })), + new(OpCodes.Castclass, typeof(Firearm)), + + // this._userInput + new(OpCodes.Ldfld, Field(typeof(LinearAdsModule), nameof(LinearAdsModule._userInput))), + + // AimingDownSightEventArgs args = new(Player, Firearm, bool) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(AimingDownSightEventArgs))[0]), + + // Player.OnAimingDownSight(args) + new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnAimingDownSight))), + }); + + newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); + + foreach (CodeInstruction instruction in newInstructions) + yield return instruction; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file diff --git a/Exiled.Events/Patches/Events/Player/FirearmActionEvents/ToggleWeaponFlashlight.cs b/Exiled.Events/Patches/Events/Player/FirearmActionEvents/ToggleWeaponFlashlight.cs new file mode 100644 index 0000000000..e943ce967e --- /dev/null +++ b/Exiled.Events/Patches/Events/Player/FirearmActionEvents/ToggleWeaponFlashlight.cs @@ -0,0 +1,107 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Player.FirearmActionEvents +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + using Exiled.API.Features.Core.Generic.Pools; + using Exiled.API.Features.Items; + using Exiled.Events.Attributes; + using Exiled.Events.EventArgs.Player; + using HarmonyLib; + using InventorySystem.Items.Firearms.Attachments; + + using static HarmonyLib.AccessTools; + + /// + /// Patches . + /// Adds & event. + /// + [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.TogglingWeaponFlashlight))] + [HarmonyPatch(typeof(FlashlightAttachment), nameof(FlashlightAttachment.ServerSendStatus))] + internal static class ToggleWeaponFlashlight + { + [HarmonyTranspiler] + private static IEnumerable OnToggleWeaponFlashlight(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + Label returnLabel = generator.DefineLabel(); + LocalBuilder ev = generator.DeclareLocal(typeof(TogglingWeaponFlashlightEventArgs)); + LocalBuilder firearm = generator.DeclareLocal(typeof(Firearm)); + LocalBuilder player = generator.DeclareLocal(typeof(API.Features.Player)); + LocalBuilder status = generator.DeclareLocal(typeof(bool)); + + newInstructions.InsertRange(0, new CodeInstruction[] + { + // Player.Get(this.Firearm.Owner) + new(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(FlashlightAttachment), nameof(FlashlightAttachment.Firearm))), + new(OpCodes.Callvirt, PropertyGetter(typeof(InventorySystem.Items.Firearms.Firearm), nameof(InventorySystem.Items.Firearms.Firearm.Owner))), + new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), + new(OpCodes.Stloc_S, player.LocalIndex), + + // (Firearm)Item.Get(this.Firearm) + new(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(FlashlightAttachment), nameof(FlashlightAttachment.Firearm))), + new(OpCodes.Call, Method(typeof(Item), nameof(Item.Get), new[] { typeof(InventorySystem.Items.Firearms.Firearm) })), + new(OpCodes.Castclass, typeof(Firearm)), + new(OpCodes.Stloc_S, firearm.LocalIndex), + + // status + new(OpCodes.Ldarg_1), + + // true + new(OpCodes.Ldc_I4_1), + + // TogglingWeaponFlashlightEventArgs args = new(Player, Firearm, bool, bool) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(TogglingWeaponFlashlightEventArgs))[0]), + new(OpCodes.Dup), + new(OpCodes.Dup), + new(OpCodes.Stloc_S, ev.LocalIndex), + + new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnTogglingWeaponFlashlight))), + + // if (!args.IsAllowed) + // return; + new(OpCodes.Callvirt, PropertyGetter(typeof(TogglingWeaponFlashlightEventArgs), nameof(TogglingWeaponFlashlightEventArgs.IsAllowed))), + new(OpCodes.Brfalse_S, returnLabel), + + // status = NewState + new(OpCodes.Ldloc_S, ev.LocalIndex), + new(OpCodes.Callvirt, PropertyGetter(typeof(TogglingWeaponFlashlightEventArgs), nameof(TogglingWeaponFlashlightEventArgs.NewState))), + new(OpCodes.Starg_S, 1), + new(OpCodes.Ldarg_1), + new(OpCodes.Stloc_S, status.LocalIndex), + }); + + newInstructions.InsertRange(newInstructions.Count - 1, new CodeInstruction[] + { + // Player + new(OpCodes.Ldloc_S, player.LocalIndex), + + // Firearm + new(OpCodes.Ldloc_S, firearm.LocalIndex), + + // status + new(OpCodes.Ldloc_S, status.LocalIndex), + + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ToggledWeaponFlashlightEventArgs))[0]), + new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnToggledWeaponFlashlight))), + }); + + newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); + + foreach (CodeInstruction instruction in newInstructions) + yield return instruction; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file diff --git a/Exiled.Events/Patches/Events/Player/FirearmRequestReceived.cs b/Exiled.Events/Patches/Events/Player/FirearmRequestReceived.cs index 823679eac4..bee9dd37ee 100644 --- a/Exiled.Events/Patches/Events/Player/FirearmRequestReceived.cs +++ b/Exiled.Events/Patches/Events/Player/FirearmRequestReceived.cs @@ -28,6 +28,7 @@ namespace Exiled.Events.Patches.Events.Player using static HarmonyLib.AccessTools; + /* /// /// Patches . /// Adds , , @@ -329,4 +330,5 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } } + */ } \ No newline at end of file diff --git a/Exiled.Events/Patches/Events/Player/InteractingElevator.cs b/Exiled.Events/Patches/Events/Player/InteractingElevator.cs index 801cdfbad7..9c8f3d4748 100644 --- a/Exiled.Events/Patches/Events/Player/InteractingElevator.cs +++ b/Exiled.Events/Patches/Events/Player/InteractingElevator.cs @@ -24,21 +24,21 @@ namespace Exiled.Events.Patches.Events.Player using static HarmonyLib.AccessTools; /// - /// Patches . + /// Patches . /// Adds the event. /// [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.InteractingElevator))] - [HarmonyPatch(typeof(ElevatorManager), nameof(ElevatorManager.ServerReceiveMessage))] + [HarmonyPatch(typeof(ElevatorChamber), nameof(ElevatorChamber.ServerInteract))] internal class InteractingElevator { private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { List newInstructions = ListPool.Pool.Get(instructions); - Label @break = (Label)newInstructions.FindLast(i => i.opcode == OpCodes.Leave_S).operand; + Label retLabel = generator.DefineLabel(); - int offset = -2; - int index = newInstructions.FindLastIndex(i => i.opcode == OpCodes.Newobj) + offset; + const int offset = -1; + int index = newInstructions.FindLastIndex(i => i.opcode == OpCodes.Ldarg_0) + offset; // InteractingElevatorEventArgs ev = new(Player.Get(referenceHub), elevatorChamber, true); // @@ -51,11 +51,11 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } diff --git a/Exiled.Events/Patches/Events/Player/Joined.cs b/Exiled.Events/Patches/Events/Player/Joined.cs index d152e5c9ab..115df866dd 100644 --- a/Exiled.Events/Patches/Events/Player/Joined.cs +++ b/Exiled.Events/Patches/Events/Player/Joined.cs @@ -39,7 +39,7 @@ internal static void CallEvent(ReferenceHub hub, out Player player) #endif Player.UnverifiedPlayers.Add(hub.gameObject, player); - if (ReferenceHub.HostHub == null) + if (ReferenceHub._hostHub == null) { Server.Host = player; } diff --git a/Exiled.Events/Patches/Events/Scp106/ExitStalking.cs b/Exiled.Events/Patches/Events/Scp106/ExitStalking.cs index d1951ce3f7..e52988856f 100644 --- a/Exiled.Events/Patches/Events/Scp106/ExitStalking.cs +++ b/Exiled.Events/Patches/Events/Scp106/ExitStalking.cs @@ -21,11 +21,11 @@ namespace Exiled.Events.Patches.Events.Scp106 using static HarmonyLib.AccessTools; /// - /// Patches . + /// Patches . /// To add the event. /// [EventPatch(typeof(Handlers.Scp106), nameof(Handlers.Scp106.ExitStalking))] - [HarmonyPatch(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.IsActive), MethodType.Setter)] + [HarmonyPatch(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.UpdateServerside))] public class ExitStalking { private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) @@ -34,22 +34,17 @@ private static IEnumerable Transpiler(IEnumerable instruction.opcode == OpCodes.Newobj) + offset; + + const int offset = -2; + int index = newInstructions.FindIndex(instruction => instruction.OperandIs(Method(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.ServerSetStalk), new[] { typeof(bool) }))) + offset; newInstructions.InsertRange( index, - new CodeInstruction[] + new[] { - // if (value is false) continue; - new CodeInstruction(OpCodes.Ldarg_1).MoveLabelsFrom(newInstructions[index]), - new(OpCodes.Ldc_I4_0), - new(OpCodes.Beq_S, continueLabel), - // Player.Get(this.Owner); - new(OpCodes.Ldarg_0), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106HuntersAtlasAbility), nameof(Scp106HuntersAtlasAbility.Owner))), + new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.Owner))), new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), // true @@ -70,14 +65,10 @@ private static IEnumerable Transpiler(IEnumerable instruction.opcode == OpCodes.Newobj) + offset; - newInstructions[index].labels.Add(continueLabel); - newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; + foreach (CodeInstruction instruction in newInstructions) + yield return instruction; ListPool.Pool.Return(newInstructions); } diff --git a/Exiled.Events/Patches/Events/Scp106/Stalking.cs b/Exiled.Events/Patches/Events/Scp106/Stalking.cs index 9098fd65e3..63bdc1c90b 100644 --- a/Exiled.Events/Patches/Events/Scp106/Stalking.cs +++ b/Exiled.Events/Patches/Events/Scp106/Stalking.cs @@ -35,15 +35,15 @@ private static IEnumerable Transpiler(IEnumerable instruction.operand == (object)PropertyGetter(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.IsActive))) + offset; + const int offset = -1; + int index = newInstructions.FindIndex(instruction => instruction.Calls(PropertyGetter(typeof(Scp106VigorAbilityBase), nameof(Scp106VigorAbilityBase.VigorAmount)))) + offset; newInstructions.InsertRange( index, - new CodeInstruction[] + new[] { // Player.Get(this.Owner); new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106HuntersAtlasAbility), nameof(Scp106HuntersAtlasAbility.Owner))), + new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.Owner))), new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), // true @@ -64,38 +64,8 @@ private static IEnumerable Transpiler(IEnumerable instruction.operand == (object)PropertySetter(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.IsActive))) + offset; - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(this.Owner); - new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106HuntersAtlasAbility), nameof(Scp106HuntersAtlasAbility.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - - // true - new(OpCodes.Ldc_I4_1), - - // StalkingEventArgs ev = new(Player, isAllowed) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(StalkingEventArgs))[0]), - new(OpCodes.Dup), - new(OpCodes.Dup), - new(OpCodes.Stloc_S, ev.LocalIndex), - - // Handlers.Scp106.OnStalking(ev) - new(OpCodes.Call, Method(typeof(Handlers.Scp106), nameof(Handlers.Scp106.OnStalking))), - - // if (!ev.IsAllowed) - // return; - new(OpCodes.Callvirt, PropertyGetter(typeof(StalkingEventArgs), nameof(StalkingEventArgs.IsAllowed))), - new(OpCodes.Brfalse_S, returnLabel), - }); - // replace "base.Vigor.VigorAmount < 0.25f" with "base.Vigor.VigorAmount < ev.MinimumVigor" - offset = 0; - index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; + index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldc_R4); newInstructions.RemoveAt(index); newInstructions.InsertRange( @@ -109,8 +79,8 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } diff --git a/Exiled.Events/Patches/Fixes/FixOnAddedBeingCallAfterOnRemoved.cs b/Exiled.Events/Patches/Fixes/FixOnAddedBeingCallAfterOnRemoved.cs index 6a59cc7ad1..b039cfd279 100644 --- a/Exiled.Events/Patches/Fixes/FixOnAddedBeingCallAfterOnRemoved.cs +++ b/Exiled.Events/Patches/Fixes/FixOnAddedBeingCallAfterOnRemoved.cs @@ -20,7 +20,7 @@ namespace Exiled.Events.Patches.Fixes using static HarmonyLib.AccessTools; /// - /// Patches . + /// Patches . /// Fix than NW call before for AmmoItem. /// [HarmonyPatch(typeof(InventoryExtensions), nameof(InventoryExtensions.ServerAddItem))] diff --git a/Exiled.Events/Patches/Fixes/FixPickupPreviousOwner.cs b/Exiled.Events/Patches/Fixes/FixPickupPreviousOwner.cs index 4e6ceecb96..56c907e325 100644 --- a/Exiled.Events/Patches/Fixes/FixPickupPreviousOwner.cs +++ b/Exiled.Events/Patches/Fixes/FixPickupPreviousOwner.cs @@ -37,7 +37,7 @@ private static IEnumerable Transpiler(IEnumerable Math.Abs(d.TimeToDetonate - ConfigFile.ServerConfig.GetInt("warhead_tminus_start_duration", 90))).First()); + networkInfo.ScenarioId = (byte)Array.IndexOf(AlphaWarheadController.Singleton._startScenarios, AlphaWarheadController.Singleton._startScenarios.OrderBy(d => Math.Abs(d.TimeToDetonate - ConfigFile.ServerConfig.GetInt("warhead_tminus_start_duration", 90))).First()); AlphaWarheadController.Singleton.NetworkInfo = networkInfo; return; diff --git a/Exiled.Events/Patches/Fixes/NWFixScp096BreakingDoor.cs b/Exiled.Events/Patches/Fixes/NWFixScp096BreakingDoor.cs index 366a531d74..df02235c2e 100644 --- a/Exiled.Events/Patches/Fixes/NWFixScp096BreakingDoor.cs +++ b/Exiled.Events/Patches/Fixes/NWFixScp096BreakingDoor.cs @@ -11,6 +11,7 @@ namespace Exiled.Events.Patches.Fixes using System.Reflection.Emit; using API.Features.Core.Generic.Pools; + using Footprinting; using HarmonyLib; using Interactables.Interobjects; using Interactables.Interobjects.DoorUtils; @@ -20,7 +21,7 @@ namespace Exiled.Events.Patches.Fixes using static HarmonyLib.AccessTools; /// - /// Patches the delegate. + /// Patches the delegate. /// Fixes open doors getting easily broke. /// Bug reported to NW (https://trello.com/c/6Nz7Isjm/4637-scp096-easily-breaking-opened-doors). /// @@ -32,7 +33,7 @@ private static IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions); Label ret = generator.DefineLabel(); - int offset = -4; + const int offset = -5; int index = newInstructions.FindIndex(x => x.operand == (object)Method(typeof(IDamageableDoor), nameof(IDamageableDoor.ServerDamage))) + offset; newInstructions.InsertRange(index, new[] @@ -44,8 +45,8 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } diff --git a/Exiled.Events/Patches/Fixes/WeaponAttachmentDesyncFix.cs b/Exiled.Events/Patches/Fixes/WeaponAttachmentDesyncFix.cs deleted file mode 100644 index dfd304d2a5..0000000000 --- a/Exiled.Events/Patches/Fixes/WeaponAttachmentDesyncFix.cs +++ /dev/null @@ -1,102 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Fixes -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Core.Generic.Pools; - - using HarmonyLib; - - using InventorySystem.Items.Firearms.Attachments; - - using static HarmonyLib.AccessTools; - - /// - /// Patches . - /// Fixes if a plugin gives you an weapon that you do not have ammo for, your attachments will not correctly appear on said weapon. - /// - [HarmonyPatch(typeof(AttachmentsServerHandler), nameof(AttachmentsServerHandler.SetupProvidedWeapon))] - internal static class WeaponAttachmentDesyncFix - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - Label skipLabel = generator.DefineLabel(); - Label skipLabel2 = generator.DefineLabel(); - Label insertLabel = generator.DefineLabel(); - - LocalBuilder flagLocal = generator.DeclareLocal(typeof(bool)); - - const int offset = -1; - int ifIndex = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldloc_3) + offset; - - newInstructions[ifIndex].operand = insertLabel; - - // if (ply.inventory.UserInventory.ReserveAmmo.TryGetValue(firearm.AmmoType, out num2)) - // { - // Execute base game code - // } - // else - // { - // bool isFlaghLightEnabled = firearm.CombinedAttachments.AdditionalPros.HasFlagFast(AttachmentDescriptiveAdvantages.Flashlight); - // firearm.Status = new FirearmStatus(0, isFlaghLightEnabled ? (FirearmStatusFlags.MagazineInserted | FirearmStatusFlags.FlashlightEnabled) : FirearmStatusFlags.MagazineInserted, num); - // } - newInstructions.AddRange( - new[] - { - // bool isFlaghLightEnabled = firearm.CombinedAttachments.AdditionalPros.HasFlagFast(AttachmentDescriptiveAdvantages.Flashlight) - new CodeInstruction(OpCodes.Ldloc_0).WithLabels(insertLabel), - new(OpCodes.Ldfld, Field(typeof(InventorySystem.Items.Firearms.Firearm), nameof(InventorySystem.Items.Firearms.Firearm.Attachments))), - new(OpCodes.Ldfld, Field(typeof(AttachmentSettings), nameof(AttachmentSettings.AdditionalPros))), - new(OpCodes.Ldc_I4_2), - new(OpCodes.Call, Method(typeof(AttachmentsUtils), nameof(AttachmentsUtils.HasFlagFast), new[] { typeof(AttachmentDescriptiveAdvantages), typeof(AttachmentDescriptiveAdvantages) })), - new(OpCodes.Stloc_S, flagLocal.LocalIndex), - - // firearm - new(OpCodes.Ldloc_0), - - // 0 (ammo) - new(OpCodes.Ldc_I4_0), - - // if (flagLocal) - // goto skipLabel; - new(OpCodes.Ldloc_S, flagLocal.LocalIndex), - new(OpCodes.Brtrue_S, skipLabel), - - // FirearmStatusFlags.MagazineInserted - // - // goto skipLabel2 - new(OpCodes.Ldc_I4_4), - new(OpCodes.Br_S, skipLabel2), - - // skipLabel: - // - // FirearmStatusFlags.MagazineInserted | FirearmStatusFlags.FlashlightEnabled - new CodeInstruction(OpCodes.Ldc_I4_S, 12).WithLabels(skipLabel), - - // skiplabel2: - // - // num (attachments) - new CodeInstruction(OpCodes.Ldloc_2).WithLabels(skipLabel2), - - // firearm.Status = new FirearmStatus(byte, FirearmStatusFlags, uint) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InventorySystem.Items.Firearms.FirearmStatus))[0]), - new(OpCodes.Call, PropertySetter(typeof(InventorySystem.Items.Firearms.Firearm), nameof(InventorySystem.Items.Firearms.Firearm.Status))), - new(OpCodes.Ret), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} \ No newline at end of file diff --git a/Exiled.Events/Patches/Generic/AddRespawnTargetMultiplierConfig.cs b/Exiled.Events/Patches/Generic/AddRespawnTargetMultiplierConfig.cs deleted file mode 100644 index 0054fd3a30..0000000000 --- a/Exiled.Events/Patches/Generic/AddRespawnTargetMultiplierConfig.cs +++ /dev/null @@ -1,54 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp079API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Core.Generic.Pools; - using HarmonyLib; - - using static HarmonyLib.AccessTools; - - using Scp049Role = API.Features.Roles.Scp049Role; - - /// - /// Patches . - /// Adds the as NW config. - /// - [HarmonyPatch(typeof(RoundSummary), nameof(RoundSummary.ServerOnRespawned))] - internal class AddRespawnTargetMultiplierConfig - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - // replace "this.ChaosTargetCount += (int)((double)respawnedPlayers.Count * 0.75);" - // with " this.ChaosTargetCount += (int)((double)respawnedPlayers.Count * ConfigFile.ServerConfig.GetDouble("respawn_target_multiplier", 0.75);" - int offset = 0; - int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldc_R8) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // ConfigFile.ServerConfig.GetDouble("respawn_target_multiplier", 0.75); - new(OpCodes.Ldsfld, Field(typeof(GameCore.ConfigFile), nameof(GameCore.ConfigFile.ServerConfig))), - new(OpCodes.Ldstr, "respawn_target_multiplier"), - new(OpCodes.Ldc_R8, RoundSummary.RespawnTargetMultiplier), - new(OpCodes.Call, Method(typeof(YamlConfig), nameof(YamlConfig.GetDouble))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} \ No newline at end of file diff --git a/Exiled.Events/Patches/Generic/LiftList.cs b/Exiled.Events/Patches/Generic/LiftList.cs index 397a305c40..b23bfd6455 100644 --- a/Exiled.Events/Patches/Generic/LiftList.cs +++ b/Exiled.Events/Patches/Generic/LiftList.cs @@ -7,27 +7,53 @@ namespace Exiled.Events.Patches.Generic { +#pragma warning disable SA1313 +#pragma warning disable SA1402 using System.Collections.Generic; + using System.Reflection.Emit; using API.Features; - + using Exiled.API.Features.Core.Generic.Pools; using HarmonyLib; using Interactables.Interobjects; + using static HarmonyLib.AccessTools; + + // TODO: CHECK IF THIS WORKS AS ISTENDED. + /// - /// Patches . + /// Patches to register all ElevatorChambers inside the Lift wrapper. /// - [HarmonyPatch(typeof(ElevatorManager), nameof(ElevatorManager.RefreshChambers))] - internal class LiftList + [HarmonyPatch(typeof(ElevatorManager), nameof(ElevatorManager.SpawnChamber))] + internal static class LiftList { - private static void Postfix() + [HarmonyTranspiler] + private static IEnumerable OnSpawnChamber(IEnumerable instructions, ILGenerator generator) { - Lift.ElevatorChamberToLift.Clear(); + List newInstructions = ListPool.Pool.Get(instructions); - foreach (KeyValuePair lift in ElevatorManager.SpawnedChambers) + int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ldarg_1); + + newInstructions.InsertRange(index, new CodeInstruction[] { - Lift.Get(lift.Value); - } + new(OpCodes.Ldloc_0), + new(OpCodes.Call, Method(typeof(Lift), nameof(Lift.Get), new[] { typeof(ElevatorChamber) })), + }); + + foreach (CodeInstruction instruction in newInstructions) + yield return instruction; + + ListPool.Pool.Return(newInstructions); } } + + /// + /// Patches to remove the destroyed ElevatorChambers from the Lift wrapper list. + /// + [HarmonyPatch(typeof(ElevatorChamber), nameof(ElevatorChamber.OnDestroy))] + internal static class LiftListRemove + { + [HarmonyPrefix] + private static void OnDestroy(ElevatorChamber __instance) => Lift.ElevatorChamberToLift.Remove(__instance); + } } \ No newline at end of file diff --git a/Exiled.Events/Patches/Generic/PickupControlPatch.cs b/Exiled.Events/Patches/Generic/PickupControlPatch.cs index bcb689f8ab..7a97064497 100644 --- a/Exiled.Events/Patches/Generic/PickupControlPatch.cs +++ b/Exiled.Events/Patches/Generic/PickupControlPatch.cs @@ -30,9 +30,9 @@ namespace Exiled.Events.Patches.Generic #pragma warning disable SA1402 /// File may only contain a single type. /// - /// Patches to save scale for pickups and control property. + /// Patches to save scale for pickups and control property. /// - [HarmonyPatch(typeof(InventoryExtensions), nameof(InventoryExtensions.ServerCreatePickup), typeof(ItemBase), typeof(PickupSyncInfo), typeof(Vector3), typeof(Quaternion), typeof(bool), typeof(Action))] + [HarmonyPatch(typeof(InventoryExtensions), nameof(InventoryExtensions.ServerCreatePickup), typeof(ItemBase), typeof(PickupSyncInfo?), typeof(Vector3), typeof(Quaternion), typeof(bool), typeof(Action))] internal static class PickupControlPatch { private static IEnumerable Transpiler( diff --git a/Exiled.Events/Patches/Generic/TargetOffset.cs b/Exiled.Events/Patches/Generic/TargetOffset.cs index a3435ff42e..41931cb586 100644 --- a/Exiled.Events/Patches/Generic/TargetOffset.cs +++ b/Exiled.Events/Patches/Generic/TargetOffset.cs @@ -28,7 +28,7 @@ internal static class TargetOffset private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { static bool IsField(CodeInstruction instruction) => instruction.opcode == OpCodes.Ldfld - && (FieldInfo)instruction.operand == Field(typeof(RoundSummary), nameof(RoundSummary._chaosTargetCount)); + && (FieldInfo)instruction.operand == Field(typeof(RoundSummary), nameof(RoundSummary._extraTargets)); List newInstructions = ListPool.Pool.Get(instructions); diff --git a/Exiled.Events/Patches/Generic/TeleportList.cs b/Exiled.Events/Patches/Generic/TeleportList.cs index d15d9d2673..22fa479102 100644 --- a/Exiled.Events/Patches/Generic/TeleportList.cs +++ b/Exiled.Events/Patches/Generic/TeleportList.cs @@ -7,20 +7,26 @@ namespace Exiled.Events.Patches.Generic { +#pragma warning disable SA1313 +#pragma warning disable SA1402 using API.Features; using HarmonyLib; - using MapGeneration; /// - /// Patches . + /// Patches . /// - [HarmonyPatch(typeof(ImageGenerator), nameof(ImageGenerator.GenerateMap))] + [HarmonyPatch(typeof(PocketDimensionTeleport), nameof(PocketDimensionTeleport.Awake))] internal class TeleportList { - private static void Prefix() - { - Map.TeleportsValue.Clear(); - Map.TeleportsValue.AddRange(UnityEngine.Object.FindObjectsOfType()); - } + private static void Postfix(PocketDimensionTeleport __instance) => Map.TeleportsValue.Add(__instance); + } + + /// + /// Patches . + /// + [HarmonyPatch(typeof(PocketDimensionTeleport), nameof(PocketDimensionTeleport.OnDestroy))] + internal class TeleportListRemove + { + private static void Postfix(PocketDimensionTeleport __instance) => Map.TeleportsValue.Remove(__instance); } } \ No newline at end of file diff --git a/Exiled.Loader/AutoUpdateFiles.cs b/Exiled.Loader/AutoUpdateFiles.cs index c083b2eb6e..be1f08fc74 100644 --- a/Exiled.Loader/AutoUpdateFiles.cs +++ b/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(13, 5, 0, 1); + public static readonly Version RequiredSCPSLVersion = new(14, 0, 0, 0); } } \ No newline at end of file diff --git a/Exiled.Permissions/Extensions/Permissions.cs b/Exiled.Permissions/Extensions/Permissions.cs index d8860ab527..58e5ac0544 100644 --- a/Exiled.Permissions/Extensions/Permissions.cs +++ b/Exiled.Permissions/Extensions/Permissions.cs @@ -14,16 +14,13 @@ namespace Exiled.Permissions.Extensions using System.Text; using CommandSystem; - using Exiled.API.Extensions; using Exiled.API.Features; using Exiled.API.Features.Core.Generic.Pools; using Features; - using Properties; - + using Query; using RemoteAdmin; - using YamlDotNet.Core; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; @@ -183,12 +180,9 @@ public static bool CheckPermission(this CommandSender sender, string permission) { return true; } - else if (sender is PlayerCommandSender || sender is UserPrint) + else if (sender is PlayerCommandSender || sender is QueryCommandSender) { - if (Player.Get(sender.SenderId) is not Player player) - return false; - - return player.CheckPermission(permission); + return Player.Get(sender.SenderId) is Player player && player.CheckPermission(permission); } return false;