Partial implementation of healthHelper, Type fuckery needs to be fixed
This commit is contained in:
@@ -3,14 +3,32 @@ using Core.Models.Eft.Common;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Eft.Health;
|
||||
using Core.Models.Eft.Profile;
|
||||
using Core.Models.Spt.Config;
|
||||
using Core.Models.Utils;
|
||||
using Core.Servers;
|
||||
using Core.Services;
|
||||
using Core.Utils;
|
||||
using Core.Utils.Cloners;
|
||||
using SptCommon.Extensions;
|
||||
using BodyPartHealth = Core.Models.Eft.Common.Tables.BodyPartHealth;
|
||||
using Effects = Core.Models.Eft.Profile.Effects;
|
||||
using Health = Core.Models.Eft.Profile.Health;
|
||||
using Vitality = Core.Models.Eft.Profile.Vitality;
|
||||
|
||||
namespace Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class HealthHelper
|
||||
public class HealthHelper(
|
||||
ISptLogger<HealthHelper> _logger,
|
||||
TimeUtil _timeUtil,
|
||||
SaveServer _saveServer,
|
||||
DatabaseService _databaseService,
|
||||
ConfigServer _configServer,
|
||||
ICloner _cloner
|
||||
)
|
||||
{
|
||||
protected HealthConfig _healthConfig = _configServer.GetConfig<HealthConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Resets the profiles vitality/health and vitality/effects properties to their defaults
|
||||
/// </summary>
|
||||
@@ -18,7 +36,34 @@ public class HealthHelper
|
||||
/// <returns>Updated profile</returns>
|
||||
public SptProfile ResetVitality(string sessionID)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var profile = _saveServer.GetProfile(sessionID);
|
||||
|
||||
profile.VitalityData ??= new Vitality { Health = null, Effects = null };
|
||||
|
||||
profile.VitalityData.Health = new Health {
|
||||
Hydration = 0,
|
||||
Energy = 0,
|
||||
Temperature = 0,
|
||||
Head = 0,
|
||||
Chest = 0,
|
||||
Stomach = 0,
|
||||
LeftArm = 0,
|
||||
RightArm = 0,
|
||||
LeftLeg = 0,
|
||||
RightLeg = 0,
|
||||
};
|
||||
|
||||
profile.VitalityData.Effects = new Effects {
|
||||
Head = new Head(),
|
||||
Chest = new Chest(),
|
||||
Stomach = new Stomach(),
|
||||
LeftArm = new LeftArm(),
|
||||
RightArm = new RightArm(),
|
||||
LeftLeg = new LeftLeg(),
|
||||
RightLeg = new RightLeg(),
|
||||
};
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -36,7 +81,53 @@ public class HealthHelper
|
||||
string sessionID,
|
||||
bool isDead)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var fullProfile = _saveServer.GetProfile(sessionID);
|
||||
var profileEdition = fullProfile.ProfileInfo.Edition;
|
||||
var profileSide = fullProfile.CharacterData.PmcData.Info.Side;
|
||||
|
||||
var defaultTemperature =
|
||||
_databaseService.GetProfiles()
|
||||
.GetByJsonProp<ProfileSides>(profileEdition)
|
||||
.GetByJsonProp<TemplateSide>(profileSide.ToLower())
|
||||
?.Character?.Health?.Temperature ?? new CurrentMinMax { Current = 36.6 };
|
||||
|
||||
StoreHydrationEnergyTempInProfile(
|
||||
fullProfile,
|
||||
postRaidHealth.Hydration.Current ?? 0,
|
||||
postRaidHealth.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 postRaidHealth.BodyParts) {
|
||||
// Effects
|
||||
if (postRaidHealth.BodyParts[bodyPart.Key].Effects is not null) {
|
||||
// fullProfile.VitalityData.Effects[bodyPart.Key] = postRaidHealth.BodyParts[bodyPart.Key].Effects;
|
||||
// TODO: this will need to change, typing is all fucked up
|
||||
}
|
||||
|
||||
// Limb hp
|
||||
if (!isDead)
|
||||
{
|
||||
// Player alive, not is limb alive
|
||||
var byJsonProp = fullProfile.VitalityData.Health.GetByJsonProp<double>(bodyPart.Key);
|
||||
byJsonProp = postRaidHealth.BodyParts[bodyPart.Key].Health.Current ?? 0;
|
||||
} else {
|
||||
var byJsonProp = fullProfile.VitalityData.Health.GetByJsonProp<double>(bodyPart.Key);
|
||||
byJsonProp = (pmcData.Health.BodyParts[bodyPart.Key].Health.Maximum * _healthConfig.HealthMultipliers.Death) ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
TransferPostRaidLimbEffectsToProfile(postRaidHealth.BodyParts, pmcData);
|
||||
|
||||
// Adjust hydration/energy/temp and limb hp using temp storage hydated above
|
||||
SaveHealth(pmcData, sessionID);
|
||||
|
||||
// Reset temp storage
|
||||
ResetVitality(sessionID);
|
||||
|
||||
// Update last edited timestamp
|
||||
pmcData.Health.UpdateTime = _timeUtil.GetTimeStamp();
|
||||
}
|
||||
|
||||
protected void StoreHydrationEnergyTempInProfile(
|
||||
@@ -45,7 +136,9 @@ public class HealthHelper
|
||||
double energy,
|
||||
double temprature)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
fullProfile.VitalityData.Health.Hydration = hydration;
|
||||
fullProfile.VitalityData.Health.Energy = energy;
|
||||
fullProfile.VitalityData.Health.Temperature = temprature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -55,7 +148,37 @@ public class HealthHelper
|
||||
/// <param name="profileData">Player profile on server</param>
|
||||
protected void TransferPostRaidLimbEffectsToProfile(Dictionary<string, BodyPartHealth> postRaidBodyParts, PmcData profileData)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// Iterate over each body part
|
||||
List<string> effectsToIgnore = ["Dehydration", "Exhaustion"];
|
||||
foreach (var bodyPartId in postRaidBodyParts) {
|
||||
// Get effects on body part from profile
|
||||
var bodyPartEffects = postRaidBodyParts[bodyPartId.Key].Effects;
|
||||
foreach (var effect in bodyPartEffects) {
|
||||
var effectDetails = bodyPartEffects[effect.Key];
|
||||
|
||||
// Null guard
|
||||
profileData.Health.BodyParts[bodyPartId.Key].Effects ??= new Dictionary<string, BodyPartEffectProperties>();
|
||||
|
||||
// Effect already exists on limb in server profile, skip
|
||||
var profileBodyPartEffects = profileData.Health.BodyParts[bodyPartId.Key].Effects;
|
||||
if (profileBodyPartEffects[effect.Key] is not null) {
|
||||
if (effectsToIgnore.Contains(effect.Key)) {
|
||||
// Get rid of certain effects we dont want to persist out of raid
|
||||
profileBodyPartEffects[effect.Key] = null;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (effectsToIgnore.Contains(effect.Key)) {
|
||||
// Do not pass some effects to out of raid profile
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add effect to server profile
|
||||
profileBodyPartEffects[effect.Key] = new BodyPartEffectProperties { Time = effectDetails.Time ?? -1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -73,7 +196,45 @@ public class HealthHelper
|
||||
bool addEffects = true,
|
||||
bool deleteExistingEffects = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var postRaidBodyParts = request.Health; // post raid health settings
|
||||
var fullProfile = _saveServer.GetProfile(sessionID);
|
||||
var profileEffects = fullProfile.VitalityData.Effects;
|
||||
|
||||
StoreHydrationEnergyTempInProfile(fullProfile, request.Hydration ?? 0, request.Energy ?? 0, request.Temperature ?? 0);
|
||||
|
||||
// Process request data into profile
|
||||
foreach (var bodyPart in postRaidBodyParts) {
|
||||
// Transfer effects from request to profile
|
||||
if (bodyPart.Effects is not null) {
|
||||
// profileEffects[bodyPart] = postRaidBodyParts[bodyPart].Effects;
|
||||
}
|
||||
|
||||
if (request.IsAlive ?? false) {
|
||||
// Player alive, not is limb alive
|
||||
// fullProfile.VitalityData.Health[bodyPart] = postRaidBodyParts[bodyPart].Current;
|
||||
} else {
|
||||
// fullProfile.VitalityData.Health[bodyPart] =
|
||||
// pmcData.Health.BodyParts[bodyPart].Health.Maximum * _healthConfig.HealthMultipliers.Death;
|
||||
}// TODO: this will need to change, typing is all fucked up
|
||||
}
|
||||
|
||||
// Add effects to body parts if enabled
|
||||
if (addEffects) {
|
||||
SaveEffects(
|
||||
pmcData,
|
||||
sessionID,
|
||||
_cloner.Clone(_saveServer.GetProfile(sessionID).VitalityData.Effects),
|
||||
deleteExistingEffects
|
||||
);
|
||||
}
|
||||
|
||||
// Adjust hydration/energy/temp and limb hp
|
||||
SaveHealth(pmcData, sessionID);
|
||||
|
||||
ResetVitality(sessionID);
|
||||
|
||||
// Update last edited timestamp
|
||||
pmcData.Health.UpdateTime = _timeUtil.GetTimeStamp();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -83,7 +244,40 @@ public class HealthHelper
|
||||
/// <param name="sessionID">Session id</param>
|
||||
protected void SaveHealth(PmcData pmcData, string sessionID)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// TODO: this will need to change, typing is all fucked up
|
||||
// if (!_healthConfig.Save.Health) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// var profileHealth = _saveServer.GetProfile(sessionID).VitalityData.Health;
|
||||
// foreach (var healthModifier in profileHealth) {
|
||||
// let target = profileHealth[healthModifier];
|
||||
//
|
||||
// if (["Hydration", "Energy", "Temperature"].includes(healthModifier)) {
|
||||
// // Set resources
|
||||
// if (target > pmcData.Health[healthModifier].Maximum) {
|
||||
// target = pmcData.Health[healthModifier].Maximum;
|
||||
// }
|
||||
//
|
||||
// pmcData.Health[healthModifier].Current = Math.round(target);
|
||||
// } else {
|
||||
// // Over max, limit
|
||||
// if (target > pmcData.Health.BodyParts[healthModifier].Health.Maximum) {
|
||||
// target = pmcData.Health.BodyParts[healthModifier].Health.Maximum;
|
||||
// }
|
||||
//
|
||||
// // Part was zeroed out in raid
|
||||
// if (target === 0) {
|
||||
// // Blacked body part
|
||||
// target = Math.round(
|
||||
// pmcData.Health.BodyParts[healthModifier].Health.Maximum *
|
||||
// this.healthConfig.healthMultipliers.blacked,
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// pmcData.Health.BodyParts[healthModifier].Health.Current = Math.round(target);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,7 +295,42 @@ public class HealthHelper
|
||||
Effects bodyPartsWithEffects,
|
||||
bool deleteExistingEffects = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// TODO: this will need to change, typing is all fucked up
|
||||
// if (!this.healthConfig.save.effects) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// for (const bodyPart in bodyPartsWithEffects) {
|
||||
// // clear effects from profile bodyPart
|
||||
// if (deleteExistingEffects) {
|
||||
// // biome-ignore lint/performance/noDelete: Delete is fine here as we entirely want to get rid of the effect.
|
||||
// delete pmcData.Health.BodyParts[bodyPart].Effects;
|
||||
// }
|
||||
//
|
||||
// for (const effectType in bodyPartsWithEffects[bodyPart]) {
|
||||
// if (typeof effectType !== "string") {
|
||||
// this.logger.warning(`Effect ${effectType} on body part ${bodyPart} not a string, report this`);
|
||||
// }
|
||||
//
|
||||
// // // data can be index or the effect string (e.g. "Fracture") itself
|
||||
// // const effect = /^-?\d+$/.test(effectValue) // is an int
|
||||
// // ? nodeEffects[bodyPart][effectValue]
|
||||
// // : effectValue;
|
||||
// let time = bodyPartsWithEffects[bodyPart][effectType];
|
||||
// if (time) {
|
||||
// // Sometimes the value can be Infinity instead of -1, blame HealthListener.cs in modules
|
||||
// if (time === "Infinity") {
|
||||
// this.logger.warning(
|
||||
// `Effect ${effectType} found with value of Infinity, changed to -1, this is an issue with HealthListener.cs`,
|
||||
// );
|
||||
// time = -1;
|
||||
// }
|
||||
// this.addEffect(pmcData, bodyPart, effectType, time);
|
||||
// } else {
|
||||
// this.addEffect(pmcData, bodyPart, effectType);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -113,6 +342,18 @@ public class HealthHelper
|
||||
/// <param name="duration">How long the effect has left in seconds (-1 by default, no duration).</param>
|
||||
protected void AddEffect(PmcData pmcData, string effectBodyPart, string effectType, int duration = -1)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// TODO: this will need to change, typing is all fucked up
|
||||
// const profileBodyPart = pmcData.Health.BodyParts[effectBodyPart];
|
||||
// if (!profileBodyPart.Effects) {
|
||||
// profileBodyPart.Effects = {};
|
||||
// }
|
||||
//
|
||||
// profileBodyPart.Effects[effectType] = { Time: duration };
|
||||
//
|
||||
// // Delete empty property to prevent client bugs
|
||||
// if (this.isEmpty(profileBodyPart.Effects)) {
|
||||
// // biome-ignore lint/performance/noDelete: Delete is fine here, we're removing an empty property to prevent game bugs.
|
||||
// delete profileBodyPart.Effects;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user