Skip to content

Commit 8fbf259

Browse files
authored
feat: Firearm new module & Reload Unload methods (#621)
* Update Player.cs * Update Firearm.cs * validation for nre * Add validation for nre * Update Firearm.cs * Update Firearm.cs
1 parent a393c8f commit 8fbf259

File tree

2 files changed

+126
-33
lines changed

2 files changed

+126
-33
lines changed

EXILED/Exiled.API/Features/Items/Firearm.cs

Lines changed: 69 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,15 @@ namespace Exiled.API.Features.Items
2121
using Exiled.API.Interfaces;
2222
using Exiled.API.Structs;
2323
using Extensions;
24-
using InventorySystem;
25-
using InventorySystem.Items;
2624
using InventorySystem.Items.Autosync;
27-
using InventorySystem.Items.Firearms;
2825
using InventorySystem.Items.Firearms.Attachments;
2926
using InventorySystem.Items.Firearms.Attachments.Components;
30-
using InventorySystem.Items.Firearms.BasicMessages;
3127
using InventorySystem.Items.Firearms.Modules;
32-
using InventorySystem.Items.Pickups;
33-
using MEC;
34-
using UnityEngine;
28+
29+
using static InventorySystem.Items.Firearms.Modules.AnimatorReloaderModuleBase;
3530

3631
using BaseFirearm = InventorySystem.Items.Firearms.Firearm;
3732
using FirearmPickup = Pickups.FirearmPickup;
38-
using Object = UnityEngine.Object;
3933

4034
/// <summary>
4135
/// A wrapper class for <see cref="InventorySystem.Items.Firearms.Firearm"/>.
@@ -63,20 +57,26 @@ public Firearm(BaseFirearm itemBase)
6357

6458
foreach (ModuleBase module in Base.Modules)
6559
{
66-
if (module is IPrimaryAmmoContainerModule primaryAmmoModule)
60+
switch (module)
6761
{
68-
PrimaryMagazine ??= (PrimaryMagazine)Magazine.Get(primaryAmmoModule);
69-
continue;
70-
}
62+
case IPrimaryAmmoContainerModule primaryAmmoModule:
63+
PrimaryMagazine ??= (PrimaryMagazine)Magazine.Get(primaryAmmoModule);
64+
break;
7165

72-
if (module is IAmmoContainerModule ammoModule)
73-
{
74-
BarrelMagazine ??= (BarrelMagazine)Magazine.Get(ammoModule);
75-
}
66+
case IAmmoContainerModule ammoModule:
67+
BarrelMagazine ??= (BarrelMagazine)Magazine.Get(ammoModule);
68+
break;
7669

77-
if (module is HitscanHitregModuleBase hitregModule)
78-
{
79-
HitscanHitregModule = hitregModule;
70+
case HitscanHitregModuleBase hitregModule:
71+
HitscanHitregModule = hitregModule;
72+
break;
73+
74+
case AnimatorReloaderModuleBase animatorReloaderModule:
75+
AnimatorReloaderModule = animatorReloaderModule;
76+
break;
77+
78+
default:
79+
break;
8080
}
8181
}
8282
}
@@ -146,6 +146,11 @@ public static IReadOnlyDictionary<Player, Dictionary<FirearmType, AttachmentIden
146146
/// </summary>
147147
public HitscanHitregModuleBase HitscanHitregModule { get; }
148148

149+
/// <summary>
150+
/// Gets an animator reloader module for the current firearm.
151+
/// </summary>
152+
public AnimatorReloaderModuleBase AnimatorReloaderModule { get; }
153+
149154
/// <summary>
150155
/// Gets or sets the amount of ammo in the firearm magazine.
151156
/// </summary>
@@ -713,12 +718,52 @@ public void ClearPreferences()
713718
/// <remarks>
714719
/// For specific reloading logic you also can use <see cref="NormalMagazine"/> for avaible weapons.
715720
/// </remarks>
716-
public void Reload()
721+
public void ForceReload()
717722
{
718-
if (Base.TryGetModule(out AnimatorReloaderModuleBase module))
719-
{
720-
module.StartReloading();
721-
}
723+
if (AnimatorReloaderModule == null)
724+
return;
725+
726+
AnimatorReloaderModule.IsReloading = true;
727+
AnimatorReloaderModule.SendRpcHeaderWithRandomByte(ReloaderMessageHeader.Reload);
728+
}
729+
730+
/// <summary>
731+
/// Attempts to reload the firearm with server-side validation.
732+
/// </summary>
733+
/// <returns><see langword="true"/> if the firearm was successfully reloaded. Otherwise, <see langword="false"/>.</returns>
734+
public bool Reload()
735+
{
736+
if (AnimatorReloaderModule == null)
737+
return false;
738+
739+
return AnimatorReloaderModule.ServerTryReload();
740+
}
741+
742+
/// <summary>
743+
/// Attempts to unload the firearm with server-side validation.
744+
/// </summary>
745+
/// <returns><see langword="true"/> if the firearm was successfully unload. Otherwise, <see langword="false"/>.</returns>
746+
public bool Unload()
747+
{
748+
if (AnimatorReloaderModule == null)
749+
return false;
750+
751+
return AnimatorReloaderModule.ServerTryUnload();
752+
}
753+
754+
/// <summary>
755+
/// Forces the firearm's client-side unload animation, bypassing server-side checks.
756+
/// </summary>
757+
/// <remarks>
758+
/// This only plays the animation and is not guaranteed to result in a successful unload. For server-validated unloading, use <see cref="Unload"/>.
759+
/// </remarks>
760+
public void ForceUnload()
761+
{
762+
if (AnimatorReloaderModule == null)
763+
return;
764+
765+
AnimatorReloaderModule.IsUnloading = true;
766+
AnimatorReloaderModule.SendRpcHeaderWithRandomByte(ReloaderMessageHeader.Unload);
722767
}
723768

724769
/// <summary>

EXILED/Exiled.API/Features/Player.cs

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ namespace Exiled.API.Features
6464
using VoiceChat.Playbacks;
6565

6666
using static DamageHandlers.DamageHandlerBase;
67+
using static InventorySystem.Items.Firearms.Modules.AnimatorReloaderModuleBase;
6768

6869
using DamageHandlerBase = PlayerStatsSystem.DamageHandlerBase;
6970
using Firearm = Items.Firearm;
@@ -1803,23 +1804,70 @@ public void TrySetCustomRoleFriendlyFire(string roleTypeId, Dictionary<RoleTypeI
18031804
/// <returns> Whether the item was able to be added. </returns>
18041805
public bool TryRemoveCustomeRoleFriendlyFire(string role) => CustomRoleFriendlyFireMultiplier.Remove(role);
18051806

1807+
/// <summary>
1808+
/// Forces the player's client to play the weapon reload animation, bypassing server-side checks.
1809+
/// </summary>
1810+
/// <returns><see langword="true"/> if the command to start reloading was sent. Otherwise, <see langword="false"/>.</returns>
1811+
/// <remarks>
1812+
/// This method does not check if the weapon can actually be reloaded. It only forces the animation and is not guaranteed to result in a successful reload.
1813+
/// </remarks>
1814+
public bool ForceReloadWeapon()
1815+
{
1816+
if (CurrentItem is not Firearm firearm || firearm.AnimatorReloaderModule == null)
1817+
{
1818+
return false;
1819+
}
1820+
1821+
firearm.AnimatorReloaderModule.IsReloading = true;
1822+
firearm.AnimatorReloaderModule.SendRpcHeaderWithRandomByte(ReloaderMessageHeader.Reload);
1823+
return true;
1824+
}
1825+
18061826
/// <summary>
18071827
/// Forces the player to reload their current weapon.
18081828
/// </summary>
1809-
/// <returns><see langword="true"/> if firearm was successfully reloaded. Otherwise, <see langword="false"/>.</returns>
1829+
/// <returns><see langword="true"/> if the firearm was successfully reloaded. Otherwise, <see langword="false"/>.</returns>
18101830
public bool ReloadWeapon()
18111831
{
1812-
if (CurrentItem is Firearm firearm)
1832+
if (CurrentItem is not Firearm firearm || firearm.AnimatorReloaderModule == null)
18131833
{
1814-
// TODO not finish
1815-
/*
1816-
bool result = firearm.Base.Ammo.ServerTryReload();
1817-
Connection.Send(new RequestMessage(firearm.Serial, RequestType.Reload));
1818-
return result;
1819-
*/
1834+
return false;
18201835
}
18211836

1822-
return false;
1837+
return firearm.AnimatorReloaderModule.ServerTryReload();
1838+
}
1839+
1840+
/// <summary>
1841+
/// Forces the player's client to play the weapon unload animation, bypassing server-side checks.
1842+
/// </summary>
1843+
/// <returns><see langword="true"/> if the command to start unloading was sent. Otherwise, <see langword="false"/>.</returns>
1844+
/// <remarks>
1845+
/// This method does not check if the weapon can actually be unloaded. It only forces the animation and is not guaranteed to result in a successful unload.
1846+
/// </remarks>
1847+
public bool ForceUnloadWeapon()
1848+
{
1849+
if (CurrentItem is not Firearm firearm || firearm.AnimatorReloaderModule == null)
1850+
{
1851+
return false;
1852+
}
1853+
1854+
firearm.AnimatorReloaderModule.IsUnloading = true;
1855+
firearm.AnimatorReloaderModule.SendRpcHeaderWithRandomByte(ReloaderMessageHeader.Unload);
1856+
return true;
1857+
}
1858+
1859+
/// <summary>
1860+
/// Forces the player to unload their current weapon.
1861+
/// </summary>
1862+
/// <returns><see langword="true"/> if the firearm was successfully unloaded. Otherwise, <see langword="false"/>.</returns>
1863+
public bool UnloadWeapon()
1864+
{
1865+
if (CurrentItem is not Firearm firearm || firearm.AnimatorReloaderModule == null)
1866+
{
1867+
return false;
1868+
}
1869+
1870+
return firearm.AnimatorReloaderModule.ServerTryUnload();
18231871
}
18241872

18251873
/// <summary>

0 commit comments

Comments
 (0)