diff --git a/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/health.json b/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/health.json
index 239dfdcec..1e762a3d5 100644
--- a/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/health.json
+++ b/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/health.json
@@ -1,6 +1,7 @@
{
"healthMultipliers": {
- "blacked": 0.1
+ "blacked": 0.1,
+ "death": 0.3
},
"save": {
"health": true
diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs
index 1f17c7bf4..46b265e21 100644
--- a/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs
+++ b/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs
@@ -254,19 +254,6 @@ public static QuestStatusEnum GetQuestStatus(this PmcData pmcData, MongoId quest
return quest?.Status ?? QuestStatusEnum.Locked;
}
- ///
- /// Use values from the profiles template to reset all body part max values
- ///
- /// Profile to update
- /// Template used to create profile
- public static void ResetMaxLimbHp(this PmcData profile, TemplateSide profileTemplate)
- {
- foreach (var (partKey, bodyPart) in profile.Health.BodyParts)
- {
- bodyPart.Health.Maximum = profileTemplate.Character.Health.BodyParts[partKey].Health.Maximum;
- }
- }
-
///
/// Handle Remove event
/// Remove item from player inventory + insured items array
diff --git a/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs
index 9fbf43a9a..f14b4341b 100644
--- a/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs
+++ b/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs
@@ -3,6 +3,7 @@
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
+using SPTarkov.Server.Core.Models.Eft.Health;
using SPTarkov.Server.Core.Models.Spt.Config;
using SPTarkov.Server.Core.Models.Utils;
using SPTarkov.Server.Core.Servers;
@@ -23,7 +24,7 @@ public class HealthHelper(ISptLogger logger, TimeUtil timeUtil, Co
/// Session id
/// Player profile to apply changes to
/// Changes to apply
- public void ApplyHealthChangesToProfile(MongoId sessionId, PmcData pmcProfileToUpdate, BotBaseHealth healthChanges)
+ public void ApplyHealthChangesToProfile(MongoId sessionId, PmcData pmcProfileToUpdate, BotBaseHealth healthChanges, bool isDead)
{
/* TODO: Not used here, need to check node or a live profile, commented out for now to avoid the potential alloc - Cj
var fullProfile = saveServer.GetProfile(sessionId);
@@ -44,7 +45,7 @@ public void ApplyHealthChangesToProfile(MongoId sessionId, PmcData pmcProfileToU
var playerWasCursed = !PlayerHadGearOnRaidStart(pmcProfileToUpdate.Inventory);
// Alter saved profiles Health with values from post-raid client data
- ModifyProfileHealthProperties(pmcProfileToUpdate, healthChanges.BodyParts, EffectsToSkip, playerWasCursed);
+ ModifyProfileHealthProperties(pmcProfileToUpdate, healthChanges.BodyParts, EffectsToSkip, isDead, playerWasCursed);
// Adjust hydration/energy/temperature
AdjustProfileHydrationEnergyTemperature(pmcProfileToUpdate, healthChanges);
@@ -103,11 +104,13 @@ protected bool PlayerHadGearOnRaidStart(BotBaseInventory inventory)
/// Player profile on server
/// Changes to apply
///
+ ///
/// Did player enter raid with no equipment
protected void ModifyProfileHealthProperties(
PmcData profileToAdjust,
Dictionary bodyPartChanges,
HashSet? effectsToSkip = null,
+ bool isDead = false,
bool playerWasCursed = false
)
{
@@ -131,17 +134,24 @@ protected void ModifyProfileHealthProperties(
if (HealthConfig.Save.Health)
{
// Apply hp changes to profile
- matchingProfilePart.Health.Current =
- partProperties.Health.Current == 0
- ? partProperties.Health.Maximum * HealthConfig.HealthMultipliers.Blacked
- : partProperties.Health.Current;
-
- matchingProfilePart.Health.Maximum = partProperties.Health.Maximum;
-
- // Cursed player + limb was not lost, reset to 20%
- if (playerWasCursed && matchingProfilePart.Health.Current > 20)
+ if (!isDead)
+ {
+ // If the player isn't dead, restore blacked limbs with a penalty
+ matchingProfilePart.Health.Current =
+ partProperties.Health.Current == 0
+ ? matchingProfilePart.Health.Maximum * HealthConfig.HealthMultipliers.Blacked
+ : partProperties.Health.Current;
+ }
+ else
{
- matchingProfilePart.Health.Current = 20;
+ // If the player died, set all limbs with a penalty
+ matchingProfilePart.Health.Current = matchingProfilePart.Health.Maximum * HealthConfig.HealthMultipliers.Death;
+
+ // Cursed player, body part gets set to 1 on death
+ if (playerWasCursed)
+ {
+ matchingProfilePart.Health.Current = 1;
+ }
}
}
diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/HealthConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/HealthConfig.cs
index 069fd882a..6d2551155 100644
--- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/HealthConfig.cs
+++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/HealthConfig.cs
@@ -18,6 +18,9 @@ public record HealthMultipliers
{
[JsonPropertyName("blacked")]
public double Blacked { get; set; }
+
+ [JsonPropertyName("death")]
+ public double Death { get; set; }
}
public record HealthSave
diff --git a/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs b/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs
index 2714f71ff..ba94bcb14 100644
--- a/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs
+++ b/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs
@@ -792,11 +792,7 @@ string locationName
MergePmcAndScavEncyclopedias(serverPmcProfile, scavProfile);
// Handle temp, hydration, limb hp/effects
- healthHelper.ApplyHealthChangesToProfile(sessionId, serverPmcProfile, postRaidProfile.Health);
-
- // Required when player loses limb in-raid and fixes it, max now stuck at 50% or less if lost multiple times
- var profileTemplate = profileHelper.GetProfileTemplateForSide(fullServerProfile.ProfileInfo.Edition, serverPmcProfile.Info.Side);
- serverPmcProfile.ResetMaxLimbHp(profileTemplate);
+ healthHelper.ApplyHealthChangesToProfile(sessionId, serverPmcProfile, postRaidProfile.Health, isDead);
if (isTransfer)
{