Reduced complexity of post-raid health transfer
Likely fixed issue with effects not transferring over correctly out of raid
This commit is contained in:
@@ -6,18 +6,6 @@ namespace SPTarkov.Server.Core.Extensions
|
||||
{
|
||||
public static class FullProfileExtensions
|
||||
{
|
||||
public static void StoreHydrationEnergyTempInProfile(
|
||||
this SptProfile fullProfile,
|
||||
double hydration,
|
||||
double energy,
|
||||
double temperature
|
||||
)
|
||||
{
|
||||
fullProfile.VitalityData.Hydration = hydration;
|
||||
fullProfile.VitalityData.Energy = energy;
|
||||
fullProfile.VitalityData.Temperature = temperature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a list of suit ids to a profiles suit list, no duplicates
|
||||
/// </summary>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Eft.Profile;
|
||||
using SPTarkov.Server.Core.Models.Spt.Config;
|
||||
using SPTarkov.Server.Core.Servers;
|
||||
using SPTarkov.Server.Core.Utils;
|
||||
@@ -20,20 +18,6 @@ public class HealthHelper(
|
||||
{
|
||||
protected readonly HealthConfig _healthConfig = _configServer.GetConfig<HealthConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Resets the profiles vitality/health and vitality/effects properties to their defaults
|
||||
/// </summary>
|
||||
/// <param name="sessionID">Session Id</param>
|
||||
/// <returns>Updated profile</returns>
|
||||
public SptProfile ResetVitality(string sessionID)
|
||||
{
|
||||
var profile = _saveServer.GetProfile(sessionID);
|
||||
|
||||
profile.VitalityData.SetDefaults();
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update player profile vitality values with changes from client request object
|
||||
/// </summary>
|
||||
@@ -58,50 +42,15 @@ public class HealthHelper(
|
||||
var defaultTemperature =
|
||||
matchingSide?.Character?.Health?.Temperature ?? new CurrentMinMax { Current = 36.6 };
|
||||
|
||||
fullProfile.StoreHydrationEnergyTempInProfile(
|
||||
healthChanges.Hydration.Current ?? 0,
|
||||
healthChanges.Energy.Current ?? 0,
|
||||
defaultTemperature.Current ?? 0 // Reset profile temp to the default to prevent very cold/hot temps persisting into next raid
|
||||
);
|
||||
|
||||
// Store limb effects from post-raid in profile
|
||||
foreach (var bodyPart in healthChanges.BodyParts)
|
||||
{
|
||||
// Effects
|
||||
if (healthChanges.BodyParts[bodyPart.Key].Effects is not null)
|
||||
{
|
||||
fullProfile.VitalityData.Health[bodyPart.Key].Effects = healthChanges
|
||||
.BodyParts[bodyPart.Key]
|
||||
.Effects;
|
||||
}
|
||||
|
||||
// Limb hp
|
||||
if (!isDead)
|
||||
// Player alive, not is limb alive
|
||||
{
|
||||
fullProfile.VitalityData.Health[bodyPart.Key].Health.Current =
|
||||
healthChanges.BodyParts[bodyPart.Key].Health.Current ?? 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fullProfile.VitalityData.Health[bodyPart.Key].Health.Current =
|
||||
pmcProfileToUpdate.Health.BodyParts[bodyPart.Key].Health.Maximum
|
||||
* _healthConfig.HealthMultipliers.Death
|
||||
?? 0;
|
||||
}
|
||||
}
|
||||
// Alter saved profiles Health with values from post-raid client data
|
||||
ModifyProfileHeathProperties(
|
||||
healthChanges.BodyParts,
|
||||
ModifyProfileHealthProperties(
|
||||
pmcProfileToUpdate,
|
||||
healthChanges.BodyParts,
|
||||
["Dehydration", "Exhaustion"]
|
||||
);
|
||||
|
||||
// Adjust hydration/energy/temp and limb hp using temp storage hydrated above
|
||||
SaveHealth(pmcProfileToUpdate, sessionID);
|
||||
|
||||
// Reset temp storage
|
||||
ResetVitality(sessionID);
|
||||
// Adjust hydration/energy/temperature
|
||||
AdjustProfileHydrationEnergyTemperature(pmcProfileToUpdate, healthChanges);
|
||||
|
||||
// Update last edited timestamp
|
||||
pmcProfileToUpdate.Health.UpdateTime = _timeUtil.GetTimeStamp();
|
||||
@@ -110,22 +59,39 @@ public class HealthHelper(
|
||||
/// <summary>
|
||||
/// Apply Health values to profile
|
||||
/// </summary>
|
||||
/// <param name="bodyPartChanges">Changes to apply</param>
|
||||
/// <param name="profileToAdjust">Player profile on server</param>
|
||||
/// <param name="bodyPartChanges">Changes to apply</param>
|
||||
/// <param name="effectsToSkip"></param>
|
||||
protected void ModifyProfileHeathProperties(
|
||||
Dictionary<string, BodyPartHealth> bodyPartChanges,
|
||||
protected void ModifyProfileHealthProperties(
|
||||
PmcData profileToAdjust,
|
||||
Dictionary<string, BodyPartHealth> bodyPartChanges,
|
||||
HashSet<string>? effectsToSkip = null
|
||||
)
|
||||
{
|
||||
foreach (var (partName, partProperties) in bodyPartChanges)
|
||||
{
|
||||
if (
|
||||
!profileToAdjust.Health.BodyParts.TryGetValue(partName, out var matchingProfilePart)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Process each effect for each part
|
||||
foreach (var (key, effectDetails) in partProperties.Effects)
|
||||
{
|
||||
// Null guard
|
||||
var matchingProfilePart = profileToAdjust.Health.BodyParts[partName];
|
||||
matchingProfilePart.Effects ??= new Dictionary<string, BodyPartEffectProperties>();
|
||||
|
||||
// Effect already exists on limb in server profile, skip
|
||||
@@ -157,117 +123,30 @@ public class HealthHelper(
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjust hydration/energy/temperate and body part hp values in player profile to values in `profile.vitality`
|
||||
/// Adjust hydration/energy/temperate
|
||||
/// </summary>
|
||||
/// <param name="pmcData">Profile to update</param>
|
||||
/// <param name="sessionID">Session id</param>
|
||||
protected void SaveHealth(PmcData pmcData, string sessionID)
|
||||
{
|
||||
if (!_healthConfig.Save.Health)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var profileHealth = _saveServer.GetProfile(sessionID).VitalityData;
|
||||
|
||||
if (profileHealth.Hydration > pmcData.Health.Hydration.Maximum)
|
||||
{
|
||||
profileHealth.Hydration = pmcData.Health.Hydration.Maximum;
|
||||
}
|
||||
|
||||
if (profileHealth.Energy > pmcData.Health.Energy.Maximum)
|
||||
{
|
||||
profileHealth.Energy = pmcData.Health.Energy.Maximum;
|
||||
}
|
||||
|
||||
if (profileHealth.Temperature > pmcData.Health.Temperature.Maximum)
|
||||
{
|
||||
profileHealth.Temperature = pmcData.Health.Temperature.Maximum;
|
||||
}
|
||||
|
||||
pmcData.Health.Hydration.Current = Math.Round(profileHealth.Hydration ?? 0);
|
||||
pmcData.Health.Energy.Current = Math.Round(profileHealth.Energy ?? 0);
|
||||
pmcData.Health.Temperature.Current = Math.Round(profileHealth.Temperature ?? 0);
|
||||
|
||||
foreach (var (partName, partProperties) in pmcData.Health.BodyParts)
|
||||
{
|
||||
var matchingProfilePart = profileHealth.Health[partName];
|
||||
if (matchingProfilePart.Health.Maximum > partProperties.Health.Maximum)
|
||||
{
|
||||
matchingProfilePart.Health.Maximum = partProperties.Health.Maximum;
|
||||
}
|
||||
|
||||
if (matchingProfilePart.Health.Current == 0)
|
||||
{
|
||||
matchingProfilePart.Health.Current =
|
||||
partProperties.Health.Maximum * _healthConfig.HealthMultipliers.Blacked;
|
||||
}
|
||||
|
||||
partProperties.Health.Current = Math.Round(matchingProfilePart.Health.Current ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save effects to profile
|
||||
/// Works by removing all effects and adding them back from profile
|
||||
/// Removes empty 'Effects' objects if found
|
||||
/// </summary>
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <param name="sessionID">Session id</param>
|
||||
/// <param name="bodyPartsWithEffects">Dictionary of body parts with effects that should be added to profile</param>
|
||||
/// <param name="deleteExistingEffects">Should effects be added back to profile</param>
|
||||
protected void SaveEffects(
|
||||
PmcData pmcData,
|
||||
string sessionID,
|
||||
Dictionary<string, BodyPartHealth> bodyPartsWithEffects,
|
||||
bool deleteExistingEffects = true
|
||||
/// <param name="profileToUpdate">Profile to update</param>
|
||||
/// <param name="healthChanges"></param>
|
||||
protected void AdjustProfileHydrationEnergyTemperature(
|
||||
PmcData profileToUpdate,
|
||||
BotBaseHealth healthChanges
|
||||
)
|
||||
{
|
||||
// TODO: this will need to change, typing is all fucked up
|
||||
if (!_healthConfig.Save.Effects)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Ensure current hydration/energy/temp are copied over and don't exceed maximum
|
||||
var profileHealth = profileToUpdate.Health;
|
||||
profileHealth.Hydration.Current =
|
||||
profileHealth.Hydration.Current > healthChanges.Hydration.Maximum
|
||||
? healthChanges.Hydration.Maximum
|
||||
: Math.Round(healthChanges.Hydration.Current ?? 0);
|
||||
|
||||
foreach (var bodyPart in bodyPartsWithEffects)
|
||||
{
|
||||
// clear effects from profile bodyPart
|
||||
if (deleteExistingEffects)
|
||||
{
|
||||
pmcData.Health.BodyParts[bodyPart.Key].Effects =
|
||||
new Dictionary<string, BodyPartEffectProperties>();
|
||||
}
|
||||
profileHealth.Energy.Current =
|
||||
profileHealth.Energy.Current > healthChanges.Energy.Maximum
|
||||
? healthChanges.Energy.Maximum
|
||||
: Math.Round(healthChanges.Energy.Current ?? 0);
|
||||
|
||||
foreach (var effectType in bodyPartsWithEffects[bodyPart.Key].Effects)
|
||||
{
|
||||
var time = effectType.Value.Time;
|
||||
if (time is not null && time > 0)
|
||||
{
|
||||
AddEffect(pmcData, effectType, time);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddEffect(pmcData, effectType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add effect to body part in profile
|
||||
/// </summary>
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
/// <param name="effectType">Effect to add to body part</param>
|
||||
/// <param name="duration">How long the effect has left in seconds (-1 by default, no duration).</param>
|
||||
protected void AddEffect(
|
||||
PmcData pmcData,
|
||||
KeyValuePair<string, BodyPartEffectProperties> effectType,
|
||||
double? duration = -1
|
||||
)
|
||||
{
|
||||
var profileBodyPart = pmcData.Health.BodyParts[effectType.Key];
|
||||
profileBodyPart.Effects ??= new Dictionary<string, BodyPartEffectProperties>();
|
||||
|
||||
profileBodyPart.Effects[effectType.Key] = new BodyPartEffectProperties { Time = duration };
|
||||
profileHealth.Temperature.Current =
|
||||
profileHealth.Temperature.Current > healthChanges.Temperature.Maximum
|
||||
? healthChanges.Temperature.Maximum
|
||||
: Math.Round(healthChanges.Temperature.Current ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user