From 353b8f54bbc08287346e6172b38512ee29013d01 Mon Sep 17 00:00:00 2001 From: Chomp Date: Mon, 20 Oct 2025 11:06:29 +0100 Subject: [PATCH] Added functionality to reduce non-damaged limb hp to 20% on pmc death when player is 'cursed' #640 --- .../Helpers/HealthHelper.cs | 51 ++++++++++++++++++- .../Helpers/InRaidHelper.cs | 2 +- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs index 40472934..9fbf43a9 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs @@ -41,8 +41,10 @@ public class HealthHelper(ISptLogger logger, TimeUtil timeUtil, Co throw new HealthHelperException(message); } + var playerWasCursed = !PlayerHadGearOnRaidStart(pmcProfileToUpdate.Inventory); + // Alter saved profiles Health with values from post-raid client data - ModifyProfileHealthProperties(pmcProfileToUpdate, healthChanges.BodyParts, EffectsToSkip); + ModifyProfileHealthProperties(pmcProfileToUpdate, healthChanges.BodyParts, EffectsToSkip, playerWasCursed); // Adjust hydration/energy/temperature AdjustProfileHydrationEnergyTemperature(pmcProfileToUpdate, healthChanges); @@ -58,16 +60,55 @@ public class HealthHelper(ISptLogger logger, TimeUtil timeUtil, Co pmcProfileToUpdate.Health.UpdateTime = timeUtil.GetTimeStamp(); } + /// + /// Did the player start raid with gear, if false, they are 'cursed' + /// + /// Players inventory at start of raid + /// True = they had enough gear to not be classed as 'cursed' + protected bool PlayerHadGearOnRaidStart(BotBaseInventory inventory) + { + if (inventory?.Items == null) + { + return false; + } + + var hasWeapon = false; + var hasVestRigOrBackpack = false; + foreach (var item in inventory.Items) + { + // Possible early escape + if (hasWeapon && hasVestRigOrBackpack) + { + return true; + } + + if (item.SlotId is "FirstPrimaryWeapon" or "SecondPrimaryWeapon" or "Holster") + { + hasWeapon = true; + continue; + } + + if (item.SlotId is "Backpack" or "ArmorVest" or "TacticalVest") + { + hasVestRigOrBackpack = true; + } + } + + return hasWeapon && hasVestRigOrBackpack; + } + /// /// Apply Health values to profile /// /// Player profile on server /// Changes to apply /// + /// Did player enter raid with no equipment protected void ModifyProfileHealthProperties( PmcData profileToAdjust, Dictionary bodyPartChanges, - HashSet? effectsToSkip = null + HashSet? effectsToSkip = null, + bool playerWasCursed = false ) { foreach (var (partName, partProperties) in bodyPartChanges) @@ -96,6 +137,12 @@ public class HealthHelper(ISptLogger logger, TimeUtil timeUtil, Co : partProperties.Health.Current; matchingProfilePart.Health.Maximum = partProperties.Health.Maximum; + + // Cursed player + limb was not lost, reset to 20% + if (playerWasCursed && matchingProfilePart.Health.Current > 20) + { + matchingProfilePart.Health.Current = 20; + } } // Process each effect for each part diff --git a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs index bed3d87c..ac9f10bc 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs @@ -179,7 +179,7 @@ public class InRaidHelper( } // Remove contents of fast panel - pmcData.Inventory.FastPanel = new Dictionary(); + pmcData.Inventory.FastPanel = []; } ///