diff --git a/EXILED/EXILED.props b/EXILED/EXILED.props
index a949e45c5..e11ce67c2 100644
--- a/EXILED/EXILED.props
+++ b/EXILED/EXILED.props
@@ -22,6 +22,7 @@
2.2.2
1.1.118
2.0.2
+ disable
Copyright © $(Authors) 2020 - $([System.DateTime]::Now.ToString("yyyy"))
Git
diff --git a/EXILED/Exiled.API/Features/Items/Firearm.cs b/EXILED/Exiled.API/Features/Items/Firearm.cs
index fb83411f2..6bfa9d237 100644
--- a/EXILED/Exiled.API/Features/Items/Firearm.cs
+++ b/EXILED/Exiled.API/Features/Items/Firearm.cs
@@ -13,24 +13,18 @@ namespace Exiled.API.Features.Items
using CameraShaking;
using Enums;
- using Exiled.API.Features.Pickups;
- using Exiled.API.Interfaces;
- using Exiled.API.Structs;
using Extensions;
- using InventorySystem;
- using InventorySystem.Items;
- using InventorySystem.Items.Firearms;
+ using Interfaces;
+ using InventorySystem.Items.Autosync;
using InventorySystem.Items.Firearms.Attachments;
using InventorySystem.Items.Firearms.Attachments.Components;
- using InventorySystem.Items.Firearms.BasicMessages;
using InventorySystem.Items.Firearms.Modules;
- using InventorySystem.Items.Pickups;
using MEC;
- using UnityEngine;
+ using Pickups;
+ using Structs;
using BaseFirearm = InventorySystem.Items.Firearms.Firearm;
using FirearmPickup = Pickups.FirearmPickup;
- using Object = UnityEngine.Object;
///
/// A wrapper class for .
@@ -47,6 +41,8 @@ public class Firearm : Item, IWrapper
///
internal static readonly Dictionary BaseCodesValue = new();
+ private readonly IPrimaryAmmoContainerModule ammoModule;
+
///
/// Initializes a new instance of the class.
///
@@ -55,6 +51,11 @@ public Firearm(BaseFirearm itemBase)
: base(itemBase)
{
Base = itemBase;
+ foreach (ModuleBase mod in itemBase.Modules)
+ {
+ if (mod is IPrimaryAmmoContainerModule primary)
+ ammoModule = primary;
+ }
}
///
@@ -86,7 +87,7 @@ public static IReadOnlyDictionary>> playerPreferences =
AttachmentsServerHandler.PlayerPreferences.Where(
kvp => kvp.Key is not null).Select(
- (KeyValuePair> keyValuePair) =>
+ keyValuePair =>
{
return new KeyValuePair>(
Player.Get(keyValuePair.Key),
@@ -109,8 +110,8 @@ public static IReadOnlyDictionary
public int Ammo
{
- get => (Base.Modules[Array.IndexOf(Base.Modules, typeof(MagazineModule))] as MagazineModule).AmmoStored;
- set => (Base.Modules[Array.IndexOf(Base.Modules, typeof(MagazineModule))] as MagazineModule).AmmoStored = value;
+ get => ammoModule?.AmmoStored ?? 0;
+ set => ammoModule?.ServerModifyAmmo(value);
}
///
@@ -119,8 +120,21 @@ public int Ammo
/// Disruptor can't be used for MaxAmmo.
public int MaxAmmo
{
- get => (Base.Modules[Array.IndexOf(Base.Modules, typeof(MagazineModule))] as MagazineModule).AmmoMax;
- set => (Base.Modules[Array.IndexOf(Base.Modules, typeof(MagazineModule))] as MagazineModule)._defaultCapacity = value; // Synced?
+ get => ammoModule?.AmmoMax ?? 0;
+ set
+ {
+ switch (ammoModule)
+ {
+ case null:
+ throw new InvalidOperationException("Cannot change max ammo for non-ammo weapons.");
+ case MagazineModule mag:
+ mag._defaultCapacity = value;
+ break;
+ case CylinderAmmoModule:
+ CylinderAmmoModule.ServerPrepareNewChambers(Serial, value);
+ break;
+ }
+ }
}
///
@@ -131,7 +145,7 @@ public int MaxAmmo
///
/// Gets the of the firearm.
///
- public AmmoType AmmoType => (Base.Modules.OfType().FirstOrDefault()?.AmmoType ?? ItemType.None).GetAmmoType();
+ public AmmoType AmmoType => ammoModule?.AmmoType.GetAmmoType() ?? AmmoType.None;
///
/// Gets a value indicating whether the firearm is being aimed.
@@ -406,7 +420,7 @@ public bool TryGetAttachment(AttachmentIdentifier identifier, out Attachment fir
{
firearmAttachment = default;
- if (!Attachments.Any(attachment => attachment.Name == identifier.Name))
+ if (Attachments.All(attachment => attachment.Name != identifier.Name))
return false;
firearmAttachment = GetAttachment(identifier);
@@ -558,11 +572,10 @@ public void RemovePreference(IEnumerable players, IEnumerableThe of which must be cleared.
public void ClearPreferences(Player player)
{
- if (AttachmentsServerHandler.PlayerPreferences.TryGetValue(player.ReferenceHub, out Dictionary dictionary))
- {
- foreach (KeyValuePair kvp in dictionary)
- dictionary[kvp.Key] = kvp.Key.GetFirearmType().GetBaseCode();
- }
+ if (!AttachmentsServerHandler.PlayerPreferences.TryGetValue(player.ReferenceHub, out Dictionary dictionary))
+ return;
+ foreach (KeyValuePair kvp in dictionary)
+ dictionary[kvp.Key] = kvp.Key.GetFirearmType().GetBaseCode();
}
///
@@ -590,20 +603,22 @@ public void ClearPreferences()
/// Whether empty magazine should be loaded.
public void Reload(bool emptyMagazine = false)
{
- MagazineModule magazineModule = Base.Modules.OfType().FirstOrDefault();
-
- if (magazineModule == null)
- return;
-
- magazineModule.ServerRemoveMagazine();
+ if (ammoModule is MagazineModule magazineModule)
+ {
+ magazineModule.ServerRemoveMagazine();
- Timing.CallDelayed(0.1f, () =>
+ Timing.CallDelayed(0.1f, () =>
+ {
+ if (emptyMagazine)
+ magazineModule.ServerInsertEmptyMagazine();
+ else
+ magazineModule.ServerInsertMagazine();
+ });
+ }
+ else if (Base.TryGetModule(out AnimatorReloaderModuleBase animatorModule))
{
- if (emptyMagazine)
- magazineModule.ServerInsertEmptyMagazine();
- else
- magazineModule.ServerInsertMagazine();
- });
+ animatorModule.StartReloading();
+ }
}
///
@@ -639,6 +654,8 @@ internal override void ChangeOwner(Player oldOwner, Player newOwner)
{
Base.Owner = newOwner.ReferenceHub;
Base._footprintCacheSet = false;
+ foreach (SubcomponentBase component in Base.AllSubcomponents)
+ component.OnAdded();
}
///
@@ -648,8 +665,7 @@ internal override void ReadPickupInfo(Pickup pickup)
if (pickup is FirearmPickup firearmPickup)
{
- // TODO If synced
- // MaxAmmo = firearmPickup.MaxAmmo;
+ Timing.CallDelayed(0.1f, () => Ammo = firearmPickup.Ammo);
}
}
}
diff --git a/EXILED/Exiled.API/Features/Lockers/Locker.cs b/EXILED/Exiled.API/Features/Lockers/Locker.cs
index 0e04382fc..997cf525f 100644
--- a/EXILED/Exiled.API/Features/Lockers/Locker.cs
+++ b/EXILED/Exiled.API/Features/Lockers/Locker.cs
@@ -10,20 +10,18 @@ namespace Exiled.API.Features.Lockers
using System.Collections.Generic;
using System.Linq;
- using Exiled.API.Enums;
- using Exiled.API.Extensions;
- using Exiled.API.Features;
- using Exiled.API.Features.Pickups;
- using Exiled.API.Interfaces;
-
+ using Enums;
+ using Extensions;
+ using Features;
+ using Interfaces;
using InventorySystem.Items.Pickups;
using MapGeneration.Distributors;
-
using Mirror;
+ using Pickups;
using UnityEngine;
using BaseLocker = MapGeneration.Distributors.Locker;
-#nullable enable
+
///
/// The in-game Locker.
///
@@ -79,7 +77,7 @@ public Locker(BaseLocker locker)
///
/// Gets the in which the is located.
///
- public Room? Room => Room.Get(Position);
+ public Room Room => Room.Get(Position);
///
/// Gets the in which the locker is located.
@@ -126,7 +124,7 @@ public Vector3 RandomChamberPosition
///
/// The to get.
/// A or if not found.
- public static Locker? Get(BaseLocker locker) => locker == null ? null :
+ public static Locker Get(BaseLocker locker) => locker == null ? null :
BaseToExiledLockers.TryGetValue(locker, out Locker supply) ? supply : new Locker(locker);
///
@@ -149,7 +147,7 @@ public Vector3 RandomChamberPosition
/// The to filter by. If unspecified, all zones are considered.
/// The to filter by. If unspecified, all locker types are considered.
/// A random object, or if no matching locker is found.
- public static Locker? Random(ZoneType zone = ZoneType.Unspecified, LockerType lockerType = LockerType.Unknow)
+ public static Locker Random(ZoneType zone = ZoneType.Unspecified, LockerType lockerType = LockerType.Unknow)
{
IEnumerable filteredLockers = List;
diff --git a/EXILED/Exiled.API/Features/Npc.cs b/EXILED/Exiled.API/Features/Npc.cs
index 4055dfa6a..717dd0202 100644
--- a/EXILED/Exiled.API/Features/Npc.cs
+++ b/EXILED/Exiled.API/Features/Npc.cs
@@ -7,17 +7,13 @@
namespace Exiled.API.Features
{
-#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
- using System.Reflection;
- using CentralAuth;
using CommandSystem;
using CommandSystem.Commands.RemoteAdmin.Dummies;
using Exiled.API.Enums;
- using Exiled.API.Features.Components;
using Exiled.API.Features.Roles;
using Footprinting;
using GameCore;
@@ -26,8 +22,6 @@ namespace Exiled.API.Features
using PlayerRoles;
using UnityEngine;
- using Object = UnityEngine.Object;
-
///
/// Wrapper class for handling NPC players.
///
@@ -68,7 +62,7 @@ public override Vector3 Position
/// Gets or sets the player being followed.
///
/// The npc must have .
- public Player? FollowedPlayer
+ public Player FollowedPlayer
{
get => !GameObject.TryGetComponent(out PlayerFollower follower) ? null : Player.Get(follower._hubToFollow);
@@ -176,70 +170,70 @@ public float? Speed
///
/// The ReferenceHub to retrieve the NPC for.
/// The NPC associated with the ReferenceHub, or null if not found.
- public static new Npc? Get(ReferenceHub rHub) => Player.Get(rHub) as Npc;
+ public static new Npc Get(ReferenceHub rHub) => Player.Get(rHub) as Npc;
///
/// Retrieves the NPC associated with the specified GameObject.
///
/// The GameObject to retrieve the NPC for.
/// The NPC associated with the GameObject, or null if not found.
- public static new Npc? Get(GameObject gameObject) => Player.Get(gameObject) as Npc;
+ public static new Npc Get(GameObject gameObject) => Player.Get(gameObject) as Npc;
///
/// Retrieves the NPC associated with the specified user ID.
///
/// The user ID to retrieve the NPC for.
/// The NPC associated with the user ID, or null if not found.
- public static new Npc? Get(string userId) => Player.Get(userId) as Npc;
+ public static new Npc Get(string userId) => Player.Get(userId) as Npc;
///
/// Retrieves the NPC associated with the specified ID.
///
/// The ID to retrieve the NPC for.
/// The NPC associated with the ID, or null if not found.
- public static new Npc? Get(int id) => Player.Get(id) as Npc;
+ public static new Npc Get(int id) => Player.Get(id) as Npc;
///
/// Retrieves the NPC associated with the specified ICommandSender.
///
/// The ICommandSender to retrieve the NPC for.
/// The NPC associated with the ICommandSender, or null if not found.
- public static new Npc? Get(ICommandSender sender) => Player.Get(sender) as Npc;
+ public static new Npc Get(ICommandSender sender) => Player.Get(sender) as Npc;
///
/// Retrieves the NPC associated with the specified Footprint.
///
/// The Footprint to retrieve the NPC for.
/// The NPC associated with the Footprint, or null if not found.
- public static new Npc? Get(Footprint footprint) => Player.Get(footprint) as Npc;
+ public static new Npc Get(Footprint footprint) => Player.Get(footprint) as Npc;
///
/// Retrieves the NPC associated with the specified CommandSender.
///
/// The CommandSender to retrieve the NPC for.
/// The NPC associated with the CommandSender, or null if not found.
- public static new Npc? Get(CommandSender sender) => Player.Get(sender) as Npc;
+ public static new Npc Get(CommandSender sender) => Player.Get(sender) as Npc;
///
/// Retrieves the NPC associated with the specified Collider.
///
/// The Collider to retrieve the NPC for.
/// The NPC associated with the Collider, or null if not found.
- public static new Npc? Get(Collider collider) => Player.Get(collider) as Npc;
+ public static new Npc Get(Collider collider) => Player.Get(collider) as Npc;
///
/// Retrieves the NPC associated with the specified net ID.
///
/// The net ID to retrieve the NPC for.
/// The NPC associated with the net ID, or null if not found.
- public static new Npc? Get(uint netId) => Player.Get(netId) as Npc;
+ public static new Npc Get(uint netId) => Player.Get(netId) as Npc;
///
/// Retrieves the NPC associated with the specified NetworkConnection.
///
/// The NetworkConnection to retrieve the NPC for.
/// The NPC associated with the NetworkConnection, or null if not found.
- public static new Npc? Get(NetworkConnection conn) => Player.Get(conn) as Npc;
+ public static new Npc Get(NetworkConnection conn) => Player.Get(conn) as Npc;
///
/// Spawns an NPC based on the given parameters.
@@ -348,4 +342,4 @@ public void LateDestroy(float time)
});
}
}
-}
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs b/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs
index 936ac1d2c..b78043db6 100644
--- a/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs
+++ b/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs
@@ -7,9 +7,13 @@
namespace Exiled.API.Features.Pickups
{
- using Exiled.API.Interfaces;
+ using System;
+ using Interfaces;
using InventorySystem.Items.Firearms;
+ using InventorySystem.Items.Firearms.Attachments;
+ using InventorySystem.Items.Firearms.Modules;
+ using UnityEngine;
using BaseFirearm = InventorySystem.Items.Firearms.FirearmPickup;
@@ -18,6 +22,8 @@ namespace Exiled.API.Features.Pickups
///
public class FirearmPickup : Pickup, IWrapper
{
+ private IPrimaryAmmoContainerModule module;
+
///
/// Initializes a new instance of the class.
///
@@ -26,6 +32,7 @@ internal FirearmPickup(BaseFirearm pickupBase)
: base(pickupBase)
{
Base = pickupBase;
+ module = AttachmentPreview.TryGet(Base.CurId, false, out Firearm firearm) ? firearm.TryGetModule(out CylinderAmmoModule cylinder) ? cylinder : firearm.TryGetModule(out MagazineModule magazine) ? magazine : null : null;
}
///
@@ -36,12 +43,7 @@ internal FirearmPickup(ItemType type)
: base(type)
{
Base = (BaseFirearm)((Pickup)this).Base;
- IsDistributed = true;
-
- // TODO not finish
- /*
- if (type is ItemType.ParticleDisruptor && Status.Ammo == 0)
- Status = new FirearmStatus(5, FirearmStatusFlags.MagazineInserted, 0);*/
+ module = AttachmentPreview.TryGet(Base.CurId, false, out Firearm firearm) ? firearm.TryGetModule(out CylinderAmmoModule cylinder) ? cylinder : firearm.TryGetModule(out MagazineModule magazine) ? magazine : null : null;
}
///
@@ -49,46 +51,20 @@ internal FirearmPickup(ItemType type)
///
public new BaseFirearm Base { get; }
- ///
- /// Gets or sets a value indicating whether the pickup is already distributed.
- ///
- public bool IsDistributed { get; set; }
-
- // TODO NOT FINISH
- /*{
- get => Base.Distributed;
- set => Base.Distributed = value;
- }*/
-
- // TODO not finish
-
- /*
- ///
- /// Gets or sets the .
- ///
- public FirearmStatus Status
- {
- get => Base.NetworkStatus;
- set => Base.NetworkStatus = value;
- }
- */
-
///
/// Gets or sets a value indicating how many ammo have this .
///
/// This will be updated only when item will be picked up.
- public int Ammo { get; set; }
-
- /*
- ///
- /// Gets or sets the .
- ///
- public FirearmStatusFlags Flags
+ public int Ammo
{
- get => Base.NetworkStatus.Flags;
- set => Base.NetworkStatus = new(Base.NetworkStatus.Ammo, value, Base.NetworkStatus.Attachments);
+ get => module?.AmmoStored ?? 0;
+ set
+ {
+ if (module is null)
+ throw new InvalidOperationException("Cannot set ammo for non-ammo using weapons.");
+ module.ServerModifyAmmo(value);
+ }
}
- */
///
/// Gets or sets a value indicating whether the attachment code have this .
@@ -96,13 +72,40 @@ public FirearmStatusFlags Flags
public uint Attachments
{
get => Base.Worldmodel.AttachmentCode;
- set => Base.Worldmodel.AttachmentCode = value;
+ set => Base.Worldmodel.Setup(Base.CurId, Base.Worldmodel.WorldmodelType, value);
}
+ ///
+ /// Gets a value indicating whether the item has been distributed.
+ ///
+ public bool IsDistributed { get; internal set; }
+
///
/// Returns the FirearmPickup in a human readable format.
///
/// A string containing FirearmPickup related data.
- public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* |{IsDistributed}| -{/*Ammo*/0}-";
+ public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* -{Ammo}-";
+
+ ///
+ public override void Spawn()
+ {
+ base.Spawn();
+ Base.OnDistributed();
+ }
+
+ ///
+ public override Pickup Spawn(Vector3 position, Quaternion? rotation = null, Player previousOwner = null)
+ {
+ Pickup pickup = base.Spawn(position, rotation, previousOwner);
+ Base.OnDistributed();
+ return pickup;
+ }
+
+ ///
+ public override void UnSpawn()
+ {
+ base.UnSpawn();
+ IsDistributed = false;
+ }
}
}
diff --git a/EXILED/Exiled.API/Features/Pickups/Pickup.cs b/EXILED/Exiled.API/Features/Pickups/Pickup.cs
index 047958be7..4939b78f1 100644
--- a/EXILED/Exiled.API/Features/Pickups/Pickup.cs
+++ b/EXILED/Exiled.API/Features/Pickups/Pickup.cs
@@ -7,22 +7,19 @@
namespace Exiled.API.Features.Pickups
{
- using System;
using System.Collections.Generic;
using System.Linq;
- using Exiled.API.Extensions;
- using Exiled.API.Features.Core;
- using Exiled.API.Features.Pickups.Projectiles;
- using Exiled.API.Interfaces;
-
+ using Core;
+ using Extensions;
+ using Interfaces;
using InventorySystem;
using InventorySystem.Items;
using InventorySystem.Items.Pickups;
using InventorySystem.Items.ThrowableProjectiles;
using InventorySystem.Items.Usables.Scp244;
-
using Mirror;
+ using Projectiles;
using RelativePositioning;
using UnityEngine;
@@ -37,7 +34,6 @@ namespace Exiled.API.Features.Pickups
using BaseScp1576Pickup = InventorySystem.Items.Usables.Scp1576.Scp1576Pickup;
using BaseScp2176Projectile = InventorySystem.Items.ThrowableProjectiles.Scp2176Projectile;
using BaseScp330Pickup = InventorySystem.Items.Usables.Scp330.Scp330Pickup;
-
using Object = UnityEngine.Object;
///
@@ -563,11 +559,17 @@ public float PickupTimeForPlayer(Player player)
return Base.SearchTimeForPlayer(player.ReferenceHub);
}
+ ///
+ /// Destroys the already spawned pickup.
+ ///
+ ///
+ public void Destroy() => Base.DestroySelf();
+
///
/// Spawns pickup on a server.
///
///
- public void Spawn()
+ public virtual void Spawn()
{
// condition for projectiles
if (!GameObject.activeSelf)
@@ -589,7 +591,7 @@ public void Spawn()
/// An optional previous owner of the item.
/// The spawned .
///
- public Pickup Spawn(Vector3 position, Quaternion? rotation = null, Player previousOwner = null)
+ public virtual Pickup Spawn(Vector3 position, Quaternion? rotation = null, Player previousOwner = null)
{
Position = position;
Rotation = rotation ?? Quaternion.identity;
@@ -604,7 +606,7 @@ public Pickup Spawn(Vector3 position, Quaternion? rotation = null, Player previo
///
///
///
- public void UnSpawn()
+ public virtual void UnSpawn()
{
if (IsSpawned)
{
@@ -612,12 +614,6 @@ public void UnSpawn()
}
}
- ///
- /// Destroys the already spawned pickup.
- ///
- ///
- public void Destroy() => Base.DestroySelf();
-
///
/// Clones the current pickup with a different serial.
///
diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs
index b76a88753..94de341bf 100644
--- a/EXILED/Exiled.API/Features/Player.cs
+++ b/EXILED/Exiled.API/Features/Player.cs
@@ -17,21 +17,16 @@ namespace Exiled.API.Features
using CustomPlayerEffects;
using CustomPlayerEffects.Danger;
using DamageHandlers;
+ using Doors;
using Enums;
using Exiled.API.Features.Core.Interfaces;
- using Exiled.API.Features.Doors;
- using Exiled.API.Features.Hazards;
- using Exiled.API.Features.Items;
- using Exiled.API.Features.Pickups;
- using Exiled.API.Features.Pools;
- using Exiled.API.Features.Roles;
- using Exiled.API.Interfaces;
- using Exiled.API.Structs;
using Extensions;
using Footprinting;
using global::Scp914;
+ using Hazards;
using Hints;
using Interactables.Interobjects;
+ using Interfaces;
using InventorySystem;
using InventorySystem.Disarming;
using InventorySystem.Items;
@@ -41,10 +36,12 @@ namespace Exiled.API.Features
using InventorySystem.Items.Firearms.ShotEvents;
using InventorySystem.Items.Usables;
using InventorySystem.Items.Usables.Scp330;
+ using Items;
using MapGeneration.Distributors;
using MEC;
using Mirror;
using Mirror.LiteNetLib4Mirror;
+ using Pickups;
using PlayerRoles;
using PlayerRoles.FirstPersonControl;
using PlayerRoles.FirstPersonControl.Thirdperson.Subcontrollers;
@@ -53,10 +50,13 @@ namespace Exiled.API.Features
using PlayerRoles.Voice;
using PlayerStatsSystem;
using PluginAPI.Core;
+ using Pools;
using RelativePositioning;
using RemoteAdmin;
using Respawning.NamingRules;
+ using Roles;
using RoundRestarting;
+ using Structs;
using UnityEngine;
using Utils;
using Utils.Networking;
@@ -2654,6 +2654,12 @@ 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);
+ foreach (ModuleBase module in firearm.Base.Modules)
+ {
+ if (module is IPrimaryAmmoContainerModule primaryAmmo)
+ primaryAmmo.ServerModifyAmmo(primaryAmmo.AmmoMax);
+ }
+
// TODO Not finish
/*
FirearmStatusFlags flags = FirearmStatusFlags.MagazineInserted;
diff --git a/EXILED/Exiled.Events/EventArgs/Player/ReloadingWeaponEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ReloadingWeaponEventArgs.cs
index 0dde302a9..29feac45b 100644
--- a/EXILED/Exiled.Events/EventArgs/Player/ReloadingWeaponEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Player/ReloadingWeaponEventArgs.cs
@@ -26,20 +26,16 @@ public class ReloadingWeaponEventArgs : IPlayerEvent, IFirearmEvent, IDeniableEv
///
///
///
- ///
- ///
- ///
- public ReloadingWeaponEventArgs(Player player, Firearm firearm, bool isAllowed = true)
+ public ReloadingWeaponEventArgs(Player player, Firearm firearm)
{
Firearm = firearm;
Player = player;
- IsAllowed = isAllowed;
}
///
/// Gets or sets a value indicating whether the weapon can be reloaded.
///
- public bool IsAllowed { get; set; }
+ public bool IsAllowed { get; set; } = true;
///
/// Gets the being reloaded.
diff --git a/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs
index 0eb6a5c69..f2e6daf7c 100644
--- a/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs
@@ -28,12 +28,19 @@ public class ShotEventArgs : IPlayerEvent, IFirearmEvent
public ShotEventArgs(HitscanHitregModuleBase hitregModule, RaycastHit hitInfo, InventorySystem.Items.Firearms.Firearm firearm, IDestructible destructible)
{
HitregModule = hitregModule;
+ Firearm = Item.Get(firearm);
+ Player = Firearm.Owner;
+ Distance = hitInfo.distance;
+ Position = hitInfo.point;
RaycastHit = hitInfo;
Destructible = destructible;
- Firearm = Item.Get(firearm);
+ if (Destructible is null)
+ {
+ hitInfo.distance = float.PositiveInfinity;
+ return;
+ }
- Player = Firearm.Owner;
- Damage = Destructible is not null ? HitregModule.DamageAtDistance(hitInfo.distance) : 0f;
+ Damage = HitregModule.DamageAtDistance(hitInfo.distance);
if (Destructible is HitboxIdentity hitboxIdentity)
{
@@ -61,19 +68,24 @@ public ShotEventArgs(HitscanHitregModuleBase hitregModule, RaycastHit hitInfo, I
public HitscanHitregModuleBase HitregModule { get; }
///
- /// Gets the raycast info.
+ /// Gets the shot distance. Can be 0.0f if the raycast doesn't hit collider.
///
- public RaycastHit RaycastHit { get; }
+ public float Distance { get; }
+
+ ///
+ /// Gets the shot position. Can be if the raycast doesn't hit collider.
+ ///
+ public Vector3 Position { get; }
///
- /// Gets the bullet travel distance.
+ /// Gets the component of the hit collider. Can be .
///
- public float Distance => RaycastHit.distance;
+ public IDestructible Destructible { get; }
///
- /// Gets the position of the hit.
+ /// Gets the raycast result.
///
- public Vector3 Position => RaycastHit.point;
+ public RaycastHit RaycastHit { get; }
///
/// Gets the firearm base damage at the hit distance. Actual inflicted damage may vary.
@@ -86,15 +98,10 @@ public ShotEventArgs(HitscanHitregModuleBase hitregModule, RaycastHit hitInfo, I
public Player Target { get; }
///
- /// Gets the component of the target player that was hit. Can be null.
+ /// Gets the component of the target player that was hit. Can be .
///
public HitboxIdentity Hitbox { get; }
- ///
- /// Gets the component of the hit collider. Can be null.
- ///
- public IDestructible Destructible { get; }
-
///
/// Gets or sets a value indicating whether the shot can deal damage.
///
diff --git a/EXILED/Exiled.Events/EventArgs/Player/UnloadingWeaponEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/UnloadingWeaponEventArgs.cs
index a5c8df5f0..ee0ed4f65 100644
--- a/EXILED/Exiled.Events/EventArgs/Player/UnloadingWeaponEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Player/UnloadingWeaponEventArgs.cs
@@ -26,20 +26,16 @@ public class UnloadingWeaponEventArgs : IPlayerEvent, IFirearmEvent, IDeniableEv
///
///
///
- ///
- ///
- ///
- public UnloadingWeaponEventArgs(Player player, Firearm firearm, bool isAllowed = true)
+ public UnloadingWeaponEventArgs(Player player, Firearm firearm)
{
Firearm = firearm;
Player = player;
- IsAllowed = isAllowed;
}
///
/// Gets or sets a value indicating whether the weapon can be unloaded.
///
- public bool IsAllowed { get; set; }
+ public bool IsAllowed { get; set; } = true;
///
/// Gets the being unloaded.
diff --git a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs
index 47f1ede44..c9b92a2f5 100644
--- a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs
@@ -151,8 +151,18 @@ private static IEnumerable Transpiler(IEnumerable
-// Copyright (c) ExMod Team. All rights reserved.
-// Licensed under the CC BY-SA 3.0 license.
-//
-// -----------------------------------------------------------------------
-
-namespace Exiled.Events.Patches.Events.Player
-{
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
-
- using API.Features.Pools;
- using Exiled.API.Features.Items;
- using Exiled.Events.Attributes;
- using Exiled.Events.EventArgs.Player;
- using Handlers;
- using HarmonyLib;
- using InventorySystem.Items;
- using InventorySystem.Items.Firearms;
- using InventorySystem.Items.Firearms.BasicMessages;
- using PluginAPI.Events;
-
- using static HarmonyLib.AccessTools;
-
- /* TODO
- ///
- /// Patches .
- /// Adds , ,
- /// , and
- /// events.
- ///
- [EventPatch(typeof(Player), nameof(Player.ReloadingWeapon))]
- [EventPatch(typeof(Player), nameof(Player.UnloadingWeapon))]
- [EventPatch(typeof(Player), nameof(Player.DryfiringWeapon))]
- [EventPatch(typeof(Player), nameof(Player.AimingDownSight))]
- [EventPatch(typeof(Player), nameof(Player.TogglingWeaponFlashlight))]
- [HarmonyPatch(typeof(FirearmUtils), nameof())]
- internal static class FirearmRequestReceived
- {
- private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator)
- {
- List newInstructions = ListPool.Pool.Get(instructions);
-
- LocalBuilder ev = generator.DeclareLocal(typeof(TogglingWeaponFlashlightEventArgs));
- LocalBuilder player = generator.DeclareLocal(typeof(API.Features.Player));
- LocalBuilder firearm = generator.DeclareLocal(typeof(Firearm));
-
- Label returnLabel = generator.DefineLabel();
-
- int offset = -1;
- int index = newInstructions.FindLastIndex(instruction => instruction.LoadsField(Field(typeof(RequestMessage), nameof(RequestMessage.Request)))) + offset;
-
- newInstructions.InsertRange(index, new[]
- {
- // Player player = Player.Get(hub);
- // if (player == null)
- // return;
- new CodeInstruction(OpCodes.Ldloc_0).MoveLabelsFrom(newInstructions[index]),
- new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })),
- new(OpCodes.Dup),
- new(OpCodes.Stloc_S, player.LocalIndex),
- new(OpCodes.Brfalse_S, returnLabel),
-
- // Firearm firearm = (Firearm)Item.Get(hub);
- // if (Firearm == null)
- // return;
- new CodeInstruction(OpCodes.Ldloc_1),
- new(OpCodes.Call, GetDeclaredMethods(typeof(API.Features.Items.Item)).First(x => !x.IsGenericMethod && x.Name is nameof(API.Features.Items.Item.Get) && x.GetParameters().Length is 1 && x.GetParameters()[0].ParameterType == typeof(ItemBase))),
- new(OpCodes.Isinst, typeof(Firearm)),
- new(OpCodes.Dup),
- new(OpCodes.Stloc_S, firearm.LocalIndex),
- new(OpCodes.Brfalse_S, returnLabel),
- });
-
- offset = -2;
- index = newInstructions.FindIndex(
- instruction => instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(PlayerReloadWeaponEvent))[0]) + offset;
-
- newInstructions.InsertRange(
- index,
- new[]
- {
- // player
- new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]),
-
- // firearm
- new(OpCodes.Ldloc_S, firearm.LocalIndex),
-
- // true
- new(OpCodes.Ldc_I4_1),
-
- // ReloadingWeaponEventArgs ev = new(Player, firearm, bool)
- new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ReloadingWeaponEventArgs))[0]),
- new(OpCodes.Dup),
-
- // Player.OnReloadingWeapon(ev)
- new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnReloadingWeapon))),
-
- // if (!ev.IsAllowed)
- // return;
- new(OpCodes.Callvirt, PropertyGetter(typeof(ReloadingWeaponEventArgs), nameof(ReloadingWeaponEventArgs.IsAllowed))),
- new(OpCodes.Brfalse, returnLabel),
- });
-
- offset = -2;
- index = newInstructions.FindIndex(
- instruction => instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(PlayerUnloadWeaponEvent))[0]) + offset;
-
- newInstructions.InsertRange(
- index,
- new[]
- {
- // player
- new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]),
-
- // firearm
- new(OpCodes.Ldloc_S, firearm.LocalIndex),
-
- // true
- new(OpCodes.Ldc_I4_1),
-
- // UnloadingWeaponEventArgs ev = new(Player, firearm, bool)
- new(OpCodes.Newobj, GetDeclaredConstructors(typeof(UnloadingWeaponEventArgs))[0]),
- new(OpCodes.Dup),
-
- // Player.OnUnloadingWeapon(ev)
- new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnUnloadingWeapon))),
-
- // if (!ev.IsAllowed)
- // return;
- new(OpCodes.Callvirt, PropertyGetter(typeof(UnloadingWeaponEventArgs), nameof(UnloadingWeaponEventArgs.IsAllowed))),
- new(OpCodes.Brfalse, returnLabel),
- });
-
- offset = -2;
- index = newInstructions.FindIndex(
- instruction => instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(PlayerDryfireWeaponEvent))[0]) + offset;
-
- newInstructions.InsertRange(
- index,
- new[]
- {
- // player
- new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]),
-
- // firearm
- new(OpCodes.Ldloc_S, firearm.LocalIndex),
-
- // true
- new(OpCodes.Ldc_I4_1),
-
- // DryfiringWeaponEventArgs ev = new(Player, firearm, bool)
- new(OpCodes.Newobj, GetDeclaredConstructors(typeof(DryfiringWeaponEventArgs))[0]),
- new(OpCodes.Dup),
-
- // Player.OnDryfiringWeapon(ev)
- new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnDryfiringWeapon))),
-
- // if (!ev.IsAllowed)
- // return;
- new(OpCodes.Callvirt, PropertyGetter(typeof(DryfiringWeaponEventArgs), nameof(DryfiringWeaponEventArgs.IsAllowed))),
- new(OpCodes.Brfalse, returnLabel),
- });
-
- offset = -3;
- index = newInstructions.FindIndex(
- instruction => instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(PlayerAimWeaponEvent))[0]) + offset;
-
- newInstructions.InsertRange(
- index,
- new[]
- {
- // player
- new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]),
-
- // firearm
- new(OpCodes.Ldloc_S, firearm.LocalIndex),
-
- // true (adsIn)
- new(OpCodes.Ldc_I4_1),
-
- // false (adsOut)
- new(OpCodes.Ldc_I4_0),
-
- // AimingDownSightEventArgs ev = new(Player, firearm, bool, bool)
- new(OpCodes.Newobj, GetDeclaredConstructors(typeof(AimingDownSightEventArgs))[0]),
-
- // Player.OnAimingDownSight(ev)
- new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnAimingDownSight))),
- });
-
- offset = -3;
- index = newInstructions.FindLastIndex(
- instruction => instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(PlayerAimWeaponEvent))[0]) + offset;
-
- newInstructions.InsertRange(
- index,
- new[]
- {
- // player
- new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]),
-
- // firearm
- new(OpCodes.Ldloc_S, firearm.LocalIndex),
-
- // false (adsIn)
- new(OpCodes.Ldc_I4_0),
-
- // true (adsOut)
- new(OpCodes.Ldc_I4_1),
-
- // AimingDownSightEventArgs ev = new(Player, firearm, bool, bool)
- new(OpCodes.Newobj, GetDeclaredConstructors(typeof(AimingDownSightEventArgs))[0]),
-
- // Player.OnAimingDownSight(ev)
- new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnAimingDownSight))),
- });
-
- offset = -7;
- index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ceq) + offset;
-
- newInstructions.InsertRange(
- index,
- new[]
- {
- // player
- new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex),
-
- // firearm
- new(OpCodes.Ldloc_S, firearm.LocalIndex),
-
- // !flag
- new(OpCodes.Ldloc_S, 8),
- new(OpCodes.Ldc_I4_0),
- new(OpCodes.Ceq),
-
- // true
- new(OpCodes.Ldc_I4_1),
-
- // TogglingWeaponFlashlightEventArgs ev = new(Player, firearm, bool, bool)
- new(OpCodes.Newobj, GetDeclaredConstructors(typeof(TogglingWeaponFlashlightEventArgs))[0]),
- new(OpCodes.Dup),
- new(OpCodes.Dup),
- new(OpCodes.Stloc_S, ev.LocalIndex),
-
- // Player.OnTogglingWeaponFlashlight(ev)
- new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnTogglingWeaponFlashlight))),
-
- // if (!ev.IsAllowed)
- // return;
- new(OpCodes.Callvirt, PropertyGetter(typeof(TogglingWeaponFlashlightEventArgs), nameof(TogglingWeaponFlashlightEventArgs.IsAllowed))),
- new(OpCodes.Brfalse_S, returnLabel),
-
- // flag = !ev.NewState
- new(OpCodes.Ldloc_S, ev.LocalIndex),
- new(OpCodes.Callvirt, PropertyGetter(typeof(TogglingWeaponFlashlightEventArgs), nameof(TogglingWeaponFlashlightEventArgs.NewState))),
- new(OpCodes.Ldc_I4_0),
- new(OpCodes.Ceq),
- new(OpCodes.Stloc_S, 6),
- });
-
- newInstructions[newInstructions.Count - 1].WithLabels(returnLabel);
-
- 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/Exiled.Events/Patches/Events/Player/ReloaderProcessCommand.cs b/EXILED/Exiled.Events/Patches/Events/Player/ReloaderProcessCommand.cs
new file mode 100644
index 000000000..b11f5573f
--- /dev/null
+++ b/EXILED/Exiled.Events/Patches/Events/Player/ReloaderProcessCommand.cs
@@ -0,0 +1,115 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.Patches.Events.Player
+{
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Reflection.Emit;
+
+ using Attributes;
+ using Exiled.API.Features.Items;
+ using Exiled.API.Features.Pools;
+ using Exiled.Events.EventArgs.Player;
+ using HarmonyLib;
+ using InventorySystem.Items.Autosync;
+ using InventorySystem.Items.Firearms.Modules;
+
+ using static HarmonyLib.AccessTools;
+
+ using Player = Exiled.Events.Handlers.Player;
+
+ ///
+ /// Patches the method to add the and events.
+ ///
+ [EventPatch(typeof(Player), nameof(Player.ReloadingWeapon))]
+ [HarmonyPatch(typeof(AnimatorReloaderModuleBase), nameof(AnimatorReloaderModuleBase.ServerProcessCmd))]
+ internal static class ReloaderProcessCommand
+ {
+ private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator)
+ {
+ List newInstructions = ListPool.Pool.Get(instructions);
+
+ LocalBuilder player = generator.DeclareLocal(typeof(API.Features.Player));
+ LocalBuilder firearm = generator.DeclareLocal(typeof(Firearm));
+
+ Label ret = generator.DefineLabel();
+ Label cont = generator.DefineLabel();
+ Label unloadCheck = generator.DefineLabel();
+
+ int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Ldloc_1);
+
+ // Index is correct, player and firearm exist, skips reload and continues to no action.
+ newInstructions.InsertRange(index, new[]
+ {
+ // player = Player.Get(this.Item.Owner);
+ new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(AnimatorReloaderModuleBase), nameof(AnimatorReloaderModuleBase.Item))),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(ModularAutosyncItem), nameof(ModularAutosyncItem.Owner))),
+ new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })),
+ new(OpCodes.Isinst, typeof(API.Features.Player)),
+ new(OpCodes.Dup),
+ new(OpCodes.Stloc_S, player.LocalIndex),
+ new(OpCodes.Brfalse_S, cont),
+
+ // firearm = Firearm.Get(this.ItemSerial);
+ new(OpCodes.Ldarg_0),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(AnimatorReloaderModuleBase), nameof(AnimatorReloaderModuleBase.ItemSerial))),
+ new(OpCodes.Call, GetDeclaredMethods(typeof(API.Features.Items.Item)).First(x => !x.IsGenericMethod && x.Name is nameof(API.Features.Items.Item.Get) && x.GetParameters().Length is 1 && x.GetParameters()[0].ParameterType == typeof(ushort))),
+ new(OpCodes.Isinst, typeof(Firearm)),
+ new(OpCodes.Dup),
+ new(OpCodes.Stloc_S, firearm.LocalIndex),
+ new(OpCodes.Brfalse_S, cont),
+
+ // if (header == Reloading) ...
+ new(OpCodes.Ldloc_2),
+ new(OpCodes.Ldc_I4_1),
+ new(OpCodes.Ceq),
+ new(OpCodes.Brfalse_S, unloadCheck),
+
+ // ReloadingWeaponEventArgs ev = new(player, firearm);
+ // Player.OnReloadingWeapon(ev);
+ // if (!ev.IsAllowed)
+ // return;
+ new(OpCodes.Ldloc_S, player.LocalIndex),
+ new(OpCodes.Ldloc_S, firearm.LocalIndex),
+ new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ReloadingWeaponEventArgs))[0]),
+ new(OpCodes.Dup),
+ new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnReloadingWeapon))),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(ReloadingWeaponEventArgs), nameof(ReloadingWeaponEventArgs.IsAllowed))),
+ new(OpCodes.Brfalse_S, ret),
+ new(OpCodes.Br_S, cont),
+
+ // else if (header == Unloading) ...
+ new CodeInstruction(OpCodes.Ldloc_2).WithLabels(unloadCheck),
+ new(OpCodes.Ldc_I4_2),
+ new(OpCodes.Ceq),
+ new(OpCodes.Brfalse_S, cont),
+
+ // UnloadingWeaponEventArgs ev = new(player, firearm);
+ // Player.OnUnloadingWeapon(ev);
+ // if (!ev.IsAllowed)
+ // return;
+ new(OpCodes.Ldloc_S, player.LocalIndex),
+ new(OpCodes.Ldloc_S, firearm.LocalIndex),
+ new(OpCodes.Newobj, GetDeclaredConstructors(typeof(UnloadingWeaponEventArgs))[0]),
+ new(OpCodes.Dup),
+ new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnUnloadingWeapon))),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(UnloadingWeaponEventArgs), nameof(UnloadingWeaponEventArgs.IsAllowed))),
+ new(OpCodes.Brfalse_S, ret),
+
+ new CodeInstruction(OpCodes.Nop).WithLabels(cont),
+ });
+
+ newInstructions[newInstructions.Count - 1].labels.Add(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/Exiled.Events/Patches/Events/Player/Shooting.cs b/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs
index 501c1f812..0de58f557 100644
--- a/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs
@@ -25,7 +25,6 @@ namespace Exiled.Events.Patches.Events.Player
/// Adds the events.
///
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Shooting))]
-
[HarmonyPatch(typeof(ShotBacktrackData), nameof(ShotBacktrackData.ProcessShot))]
internal static class Shooting
{
diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Shot.cs b/EXILED/Exiled.Events/Patches/Events/Player/Shot.cs
index 317a694ae..8338de2c3 100644
--- a/EXILED/Exiled.Events/Patches/Events/Player/Shot.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Player/Shot.cs
@@ -87,26 +87,36 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions);
Label returnLabel = generator.DefineLabel();
- LocalBuilder ev = generator.DeclareLocal(typeof(ElevatorTeleportingEventArgs));
- int offset = -3;
- int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldloc_2) + offset;
-
- newInstructions.InsertRange(index, new[]
- {
- // Player.Get(base.Owner)
- new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]),
- new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))),
- new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),
-
- // base.CurrentCamSync.CurrentCamera.Room
- new(OpCodes.Ldarg_0),
- new(OpCodes.Call, PropertyGetter(typeof(Scp079AbilityBase), nameof(Scp079AbilityBase.CurrentCamSync))),
- new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079CurrentCameraSync), nameof(Scp079CurrentCameraSync.CurrentCamera))),
- new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079Camera), nameof(Scp079Camera.Room))),
-
- // chamber
- new(OpCodes.Ldloc_2),
-
- // (float)this._cost
- new(OpCodes.Ldarg_0),
- new(OpCodes.Ldfld, Field(typeof(Scp079ElevatorStateChanger), nameof(Scp079ElevatorStateChanger._cost))),
- new(OpCodes.Conv_R4),
-
- // ElevatorTeleportingEventArgs ev = new(Player, RoomIdentifier, ElevatorChamber, float)
- new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ElevatorTeleportingEventArgs))[0]),
- new(OpCodes.Dup),
- new(OpCodes.Dup),
- new(OpCodes.Stloc_S, ev.LocalIndex),
-
- // Scp079.OnElevatorTeleporting(ev);
- new(OpCodes.Call, Method(typeof(Scp079), nameof(Scp079.OnElevatorTeleporting))),
-
- // if (!ev.IsAllowed)
- // return;
- new(OpCodes.Callvirt, PropertyGetter(typeof(ElevatorTeleportingEventArgs), nameof(ElevatorTeleportingEventArgs.IsAllowed))),
- new(OpCodes.Brfalse, returnLabel),
- });
+ LocalBuilder ev = generator.DeclareLocal(typeof(ElevatorTeleportingEventArgs));
+ int offset = 0;
+ int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldloc_3) + offset;
+
+ // ElevatorTeleportingEventArgs ev = new(Player.Get(base.Owner), base.CurrentCamSync.CurrentCamera.Room, elevatorDoor, (float)this._cost);
+ //
+ // Handlers.Scp079.OnElevatorTeleporting(ev);
+ //
+ // if (!ev.IsAllowed)
+ // return;
+ newInstructions.InsertRange(
+ index,
+ new CodeInstruction[]
+ {
+ // Player.Get(base.Owner)
+ new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]),
+ new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))),
+ new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),
+
+ // base.CurrentCamSync.CurrentCamera.Room
+ new(OpCodes.Ldarg_0),
+ new(OpCodes.Call, PropertyGetter(typeof(Scp079AbilityBase), nameof(Scp079AbilityBase.CurrentCamSync))),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079CurrentCameraSync), nameof(Scp079CurrentCameraSync.CurrentCamera))),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079Camera), nameof(Scp079Camera.Room))),
+
+ // elevatorDoor
+ new(OpCodes.Ldloc_3),
+
+ // (float)this._cost
+ new(OpCodes.Ldarg_0),
+ new(OpCodes.Ldfld, Field(typeof(Scp079ElevatorStateChanger), nameof(Scp079ElevatorStateChanger._cost))),
+ new(OpCodes.Conv_R4),
+
+ // ElevatorTeleportingEventArgs ev = new(Player, RoomIdentifier, ElevatorDoor, float)
+ new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ElevatorTeleportingEventArgs))[0]),
+ new(OpCodes.Dup),
+ new(OpCodes.Dup),
+ new(OpCodes.Stloc_S, ev.LocalIndex),
+
+ // Scp079.OnElevatorTeleporting(ev);
+ new(OpCodes.Call, Method(typeof(Scp079), nameof(Scp079.OnElevatorTeleporting))),
+
+ // if (!ev.IsAllowed)
+ // return;
+ new(OpCodes.Callvirt, PropertyGetter(typeof(ElevatorTeleportingEventArgs), nameof(ElevatorTeleportingEventArgs.IsAllowed))),
+ new(OpCodes.Brfalse, returnLabel),
+ });
+
+ // Replace "(float)this._cost" with "ev.AuxiliaryPowerCost"
offset = -1;
- index = newInstructions.FindLastIndex(instruction => instruction.LoadsField(Field(typeof(Scp079ElevatorStateChanger), nameof(Scp079ElevatorStateChanger._cost)))) + offset;
+ index = newInstructions.FindLastIndex(
+ instruction => instruction.LoadsField(Field(typeof(Scp079ElevatorStateChanger), nameof(Scp079ElevatorStateChanger._cost)))) + offset;
newInstructions.RemoveRange(index, 3);
- newInstructions.InsertRange(index, new CodeInstruction[]
- {
- // ev.AuxiliaryPowerCost
- new(OpCodes.Ldloc, ev.LocalIndex),
- new(OpCodes.Callvirt, PropertyGetter(typeof(ElevatorTeleportingEventArgs), nameof(ElevatorTeleportingEventArgs.AuxiliaryPowerCost))),
- });
+ newInstructions.InsertRange(
+ index,
+ new CodeInstruction[]
+ {
+ // ev.AuxiliaryPowerCost
+ new(OpCodes.Ldloc, ev.LocalIndex),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(ElevatorTeleportingEventArgs), nameof(ElevatorTeleportingEventArgs.AuxiliaryPowerCost))),
+ });
newInstructions[newInstructions.Count - 1].WithLabels(returnLabel);
diff --git a/EXILED/Exiled.Installer/CommandSettings.cs b/EXILED/Exiled.Installer/CommandSettings.cs
index 55f5b226d..b9bb94db0 100644
--- a/EXILED/Exiled.Installer/CommandSettings.cs
+++ b/EXILED/Exiled.Installer/CommandSettings.cs
@@ -21,7 +21,7 @@ internal sealed class CommandSettings
///
public static readonly RootCommand RootCommand = new()
{
- new Option(
+ new Option(
new[] { "-p", "--path" },
(parsed) =>
{
@@ -44,7 +44,7 @@ internal sealed class CommandSettings
"Path to the folder with the SL server")
{ IsRequired = true },
- new Option(
+ new Option(
"--appdata",
(parsed) =>
{
@@ -67,7 +67,7 @@ internal sealed class CommandSettings
"Forces the folder to be the AppData folder (useful for containers when pterodactyl runs as root)")
{ IsRequired = true },
- new Option(
+ new Option(
"--exiled",
(parsed) =>
{
@@ -96,17 +96,17 @@ internal sealed class CommandSettings
"Includes pre-releases")
{ IsRequired = false },
- new Option(
+ new Option(
"--target-port",
"Target port for ExiledLoader installation")
{ IsRequired = false },
- new Option(
+ new Option(
"--target-version",
"Target version for installation")
{ IsRequired = false },
- new Option(
+ new Option(
"--github-token",
"Uses a token for auth in case the rate limit is exceeded (no permissions required)")
{ IsRequired = false },
@@ -122,7 +122,6 @@ internal sealed class CommandSettings
{ IsRequired = false },
};
-#nullable disable
///
/// Gets or sets the directory path.
///
@@ -137,7 +136,7 @@ internal sealed class CommandSettings
/// Gets or sets the Exiled directory path.
///
public DirectoryInfo Exiled { get; set; }
-#nullable restore
+
///
/// Gets or sets if it is a prerelease.
///
@@ -146,17 +145,17 @@ internal sealed class CommandSettings
///
/// Gets or sets the target port.
///
- public string? TargetPort { get; set; }
+ public string TargetPort { get; set; }
///
/// Gets or sets the target version.
///
- public string? TargetVersion { get; set; }
+ public string TargetVersion { get; set; }
///
/// Gets or sets the GitHub token.
///
- public string? GitHubToken { get; set; }
+ public string GitHubToken { get; set; }
///
/// Gets or sets the version of Exiled available.
diff --git a/EXILED/Exiled.Installer/Program.cs b/EXILED/Exiled.Installer/Program.cs
index c7a43a2dc..e95a665b6 100644
--- a/EXILED/Exiled.Installer/Program.cs
+++ b/EXILED/Exiled.Installer/Program.cs
@@ -15,14 +15,10 @@ namespace Exiled.Installer
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
-
- using Exiled.Installer.Properties;
-
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
-
using Octokit;
-
+ using Properties;
using Version = SemanticVersioning.Version;
internal enum PathResolution
@@ -101,7 +97,7 @@ internal static async Task MainSafe(CommandSettings args)
Console.WriteLine(Resources.Program_MainSafe_Release_found_);
Console.WriteLine(FormatRelease(targetRelease!));
- ReleaseAsset? exiledAsset = targetRelease!.Assets.FirstOrDefault(a => a.Name.Equals(ExiledAssetName, StringComparison.OrdinalIgnoreCase));
+ ReleaseAsset exiledAsset = targetRelease!.Assets.FirstOrDefault(a => a.Name.Equals(ExiledAssetName, StringComparison.OrdinalIgnoreCase));
if (exiledAsset is null)
{
Console.WriteLine(Resources.Program_MainSafe_____ASSETS____);
@@ -220,7 +216,7 @@ private static void ExtractEntry(TarInputStream tarInputStream, TarEntry entry,
EnsureDirExists(Path.GetDirectoryName(path)!);
- FileStream? fs = null;
+ FileStream fs = null;
try
{
fs = new FileStream(path, System.IO.FileMode.Create, FileAccess.Write, FileShare.None);
@@ -280,7 +276,7 @@ static PathResolution TryParse(string s)
private static Release FindRelease(CommandSettings args, IEnumerable releases)
{
Console.WriteLine(Resources.Program_TryFindRelease_Trying_to_find_release__);
- Version? targetVersion = args.TargetVersion is not null ? new Version(args.TargetVersion) : null;
+ Version targetVersion = args.TargetVersion is not null ? new Version(args.TargetVersion) : null;
List enumerable = releases.ToList();