diff --git a/EXILED/Exiled.API/Features/CustomHealthStat.cs b/EXILED/Exiled.API/Features/CustomStats/CustomHealthStat.cs
similarity index 95%
rename from EXILED/Exiled.API/Features/CustomHealthStat.cs
rename to EXILED/Exiled.API/Features/CustomStats/CustomHealthStat.cs
index af351bf7ab..f0d71fc665 100644
--- a/EXILED/Exiled.API/Features/CustomHealthStat.cs
+++ b/EXILED/Exiled.API/Features/CustomStats/CustomHealthStat.cs
@@ -5,7 +5,7 @@
//
// -----------------------------------------------------------------------
-namespace Exiled.API.Features
+namespace Exiled.API.Features.CustomStats
{
using PlayerStatsSystem;
diff --git a/EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs b/EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs
new file mode 100644
index 0000000000..590c664ecf
--- /dev/null
+++ b/EXILED/Exiled.API/Features/CustomStats/CustomHumeShieldStat.cs
@@ -0,0 +1,74 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.API.Features.CustomStats
+{
+ using Mirror;
+ using PlayerRoles.PlayableScps.HumeShield;
+ using PlayerStatsSystem;
+ using UnityEngine;
+ using Utils.Networking;
+
+ ///
+ /// A custom version of which allows the player's max amount of HumeShield to be changed.
+ ///
+ public class CustomHumeShieldStat : HumeShieldStat
+ {
+ private const float DefaultCustomValue = -1;
+
+ ///
+ public override float MaxValue => CustomMaxValue == DefaultCustomValue ? base.MaxValue : CustomMaxValue;
+
+ ///
+ /// Gets or sets the multiplier for gaining HumeShield.
+ ///
+ public float ShieldRegenerationMultiplier { get; set; } = 1;
+
+ ///
+ /// Gets or sets the maximum amount of HumeShield the player can have.
+ ///
+ public float CustomMaxValue { get; set; }
+
+ private float ShieldRegeneration => TryGetHsModule(out HumeShieldModuleBase controller) ? controller.HsRegeneration * ShieldRegenerationMultiplier : 0;
+
+ ///
+ public override void Update()
+ {
+ if (MaxValue == DefaultCustomValue)
+ {
+ base.Update();
+ return;
+ }
+
+ if (!NetworkServer.active)
+ return;
+
+ if (_valueDirty)
+ {
+ new SyncedStatMessages.StatMessage()
+ {
+ Stat = this,
+ SyncedValue = CurValue,
+ }.SendToHubsConditionally(CanReceive);
+ _lastSent = CurValue;
+ _valueDirty = false;
+ }
+
+ if (ShieldRegeneration == 0)
+ return;
+
+ float delta = ShieldRegeneration * Time.deltaTime;
+
+ if (delta > 0)
+ {
+ if (CurValue >= MaxValue)
+ return;
+ CurValue = Mathf.MoveTowards(CurValue, MaxValue, delta);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs
index 788493ca98..3012a9d39b 100644
--- a/EXILED/Exiled.API/Features/Player.cs
+++ b/EXILED/Exiled.API/Features/Player.cs
@@ -19,6 +19,7 @@ namespace Exiled.API.Features
using DamageHandlers;
using Enums;
using Exiled.API.Features.Core.Interfaces;
+ using Exiled.API.Features.CustomStats;
using Exiled.API.Features.Doors;
using Exiled.API.Features.Hazards;
using Exiled.API.Features.Items;
@@ -95,6 +96,7 @@ public class Player : TypeCastObject, IEntity, IWorldSpace
private ReferenceHub referenceHub;
private CustomHealthStat healthStat;
+ private CustomHumeShieldStat humeShieldStat;
private Role role;
///
@@ -176,6 +178,7 @@ private set
CameraTransform = value.PlayerCameraReference;
value.playerStats._dictionarizedTypes[typeof(HealthStat)] = value.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(HealthStat))] = healthStat = new CustomHealthStat { Hub = value };
+ value.playerStats._dictionarizedTypes[typeof(HumeShieldStat)] = value.playerStats.StatModules[Array.IndexOf(PlayerStats.DefinedModules, typeof(HumeShieldStat))] = humeShieldStat = new CustomHumeShieldStat { Hub = value };
}
}
@@ -914,6 +917,16 @@ public float MaxArtificialHealth
}
}
+ ///
+ /// Gets the of the Player.
+ ///
+ public AhpStat AhpStat => ReferenceHub.playerStats.GetModule();
+
+ ///
+ /// Gets a of all active Artificial Health processes on the player.
+ ///
+ public List ActiveArtificialHealthProcesses => AhpStat._activeProcesses;
+
///
/// Gets or sets the player's Hume Shield.
///
@@ -925,14 +938,27 @@ public float HumeShield
}
///
- /// Gets a of all active Artificial Health processes on the player.
+ /// Gets or sets the players maximum Hume Shield.
///
- public IEnumerable ActiveArtificialHealthProcesses => ReferenceHub.playerStats.GetModule()._activeProcesses;
+ public float MaxHumeShield
+ {
+ get => HumeShieldStat.MaxValue;
+ set => HumeShieldStat.CustomMaxValue = value;
+ }
+
+ ///
+ /// Gets or sets the players multiplier for gaining HumeShield.
+ ///
+ public float HumeShieldRegenerationMultiplier
+ {
+ get => HumeShieldStat.ShieldRegenerationMultiplier;
+ set => HumeShieldStat.ShieldRegenerationMultiplier = value;
+ }
///
/// Gets the player's .
///
- public HumeShieldStat HumeShieldStat => ReferenceHub.playerStats.GetModule();
+ public CustomHumeShieldStat HumeShieldStat => humeShieldStat;
///
/// Gets or sets the item in the player's hand. Value will be if the player is not holding anything.
@@ -3441,10 +3467,7 @@ public void ChangeEffectIntensity(string effectName, byte intensity, float durat
/// The number of seconds to delay the start of the decay.
/// Whether the process is removed when the value hits 0.
public void AddAhp(float amount, float limit = 75f, float decay = 1.2f, float efficacy = 0.7f, float sustain = 0f, bool persistant = false)
- {
- ReferenceHub.playerStats.GetModule()
- .ServerAddProcess(amount, limit, decay, efficacy, sustain, persistant);
- }
+ => AhpStat.ServerAddProcess(amount, limit, decay, efficacy, sustain, persistant);
///
/// Reconnects the player to the server. Can be used to redirect them to another server on a different port but same IP.
diff --git a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs
index ad159f736c..0e0470d928 100644
--- a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs
@@ -179,6 +179,7 @@ private static void UpdatePlayerRole(RoleTypeId newRole, API.Features.Player pla
if (newRole is RoleTypeId.Scp173)
Scp173Role.TurnedPlayers.Remove(player);
+ player.MaxHumeShield = -1;
player.MaxHealth = default;
}
@@ -192,10 +193,9 @@ private static void ChangeInventory(ChangingRoleEventArgs ev)
}
Inventory inventory = ev.Player.Inventory;
- bool flag = InventoryItemProvider.KeepItemsAfterEscaping && ev.Reason == API.Enums.SpawnReason.Escaped;
- if (flag)
+ if (InventoryItemProvider.KeepItemsAfterEscaping && ev.Reason == API.Enums.SpawnReason.Escaped)
{
- List list = new List();
+ List list = new();
if (inventory.TryGetBodyArmor(out BodyArmor bodyArmor))
{
bodyArmor.DontRemoveExcessOnDrop = true;
@@ -222,8 +222,7 @@ private static void ChangeInventory(ChangingRoleEventArgs ev)
HashSetPool.Pool.Return(hashSet);
InventoryItemProvider.PreviousInventoryPickups[ev.Player.ReferenceHub] = list;
}
-
- if (!flag)
+ else
{
while (inventory.UserInventory.Items.Count > 0)
{