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) {