Improve Health system to Use EFT's models and actual Types, also fixed some RequestData not using the base record

This commit is contained in:
CWX
2025-01-28 15:27:45 +00:00
parent ae7042dcc3
commit 078e1b1b36
23 changed files with 324 additions and 340 deletions
+186 -196
View File
@@ -1,34 +1,27 @@
using SptCommon.Annotations;
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(
ISptLogger<HealthHelper> _logger,
TimeUtil _timeUtil,
SaveServer _saveServer,
DatabaseService _databaseService,
ConfigServer _configServer,
ICloner _cloner
ConfigServer _configServer
)
{
protected HealthConfig _healthConfig = _configServer.GetConfig<HealthConfig>();
/// <summary>
/// Resets the profiles vitality/health and vitality/effects properties to their defaults
/// </summary>
@@ -38,34 +31,90 @@ public class HealthHelper(
{
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(),
};
DefaultVitality(profile.VitalityData);
return profile;
}
public void DefaultVitality(Vitality? vitality)
{
vitality ??= new Vitality { Health = null, Energy = 0, Temperature = 0, Hydration = 0 };
vitality.Health = new Dictionary<string, BodyPartHealth>
{
{
"Head", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"Chest", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"Stomach", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"LeftArm", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"RightArm", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"LeftLeg", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"RightLeg", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
}
};
}
/// <summary>
/// Update player profile vitality values with changes from client request object
/// </summary>
@@ -86,10 +135,11 @@ public class HealthHelper(
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 };
_databaseService.GetProfiles()
.GetByJsonProp<ProfileSides>(profileEdition)
.GetByJsonProp<TemplateSide>(profileSide.ToLower())
?.Character?.Health?.Temperature ??
new CurrentMinMax { Current = 36.6 };
StoreHydrationEnergyTempInProfile(
fullProfile,
@@ -99,22 +149,23 @@ public class HealthHelper(
);
// Store limb effects from post-raid in profile
foreach (var bodyPart in postRaidHealth.BodyParts) {
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
if (postRaidHealth.BodyParts[bodyPart.Key].Effects is not null)
{
fullProfile.VitalityData.Health[bodyPart.Key].Effects = postRaidHealth.BodyParts[bodyPart.Key].Effects;
}
// 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;
fullProfile.VitalityData.Health[bodyPart.Key].Health.Current = postRaidHealth.BodyParts[bodyPart.Key].Health.Current ?? 0;
}
else
{
fullProfile.VitalityData.Health[bodyPart.Key].Health.Current = (pmcData.Health.BodyParts[bodyPart.Key].Health.Maximum * _healthConfig.HealthMultipliers.Death) ?? 0;
}
}
@@ -136,9 +187,9 @@ public class HealthHelper(
double energy,
double temprature)
{
fullProfile.VitalityData.Health.Hydration = hydration;
fullProfile.VitalityData.Health.Energy = energy;
fullProfile.VitalityData.Health.Temperature = temprature;
fullProfile.VitalityData.Hydration = hydration;
fullProfile.VitalityData.Energy = energy;
fullProfile.VitalityData.Temperature = temprature;
}
/// <summary>
@@ -150,10 +201,12 @@ public class HealthHelper(
{
// Iterate over each body part
List<string> effectsToIgnore = ["Dehydration", "Exhaustion"];
foreach (var bodyPartId in postRaidBodyParts) {
foreach (var bodyPartId in postRaidBodyParts)
{
// Get effects on body part from profile
var bodyPartEffects = postRaidBodyParts[bodyPartId.Key].Effects;
foreach (var effect in bodyPartEffects) {
foreach (var effect in bodyPartEffects)
{
var effectDetails = bodyPartEffects[effect.Key];
// Null guard
@@ -161,82 +214,33 @@ public class HealthHelper(
// 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)) {
if (profileBodyPartEffects.TryGetValue(effect.Key, out var dictEffect))
{
if (effectsToIgnore.Contains(effect.Key))
{
// Get rid of certain effects we dont want to persist out of raid
profileBodyPartEffects[effect.Key] = null;
dictEffect = null;
}
continue;
}
if (effectsToIgnore.Contains(effect.Key)) {
if (effectsToIgnore.Contains(effect.Key))
{
// Do not pass some effects to out of raid profile
continue;
}
var effectToAdd = new BodyPartEffectProperties { Time = effectDetails.Time ?? -1 };
// Add effect to server profile
profileBodyPartEffects[effect.Key] = new BodyPartEffectProperties { Time = effectDetails.Time ?? -1 };
if (profileBodyPartEffects.TryAdd(effect.Key, effectToAdd))
{
profileBodyPartEffects[effect.Key] = effectToAdd;
}
}
}
}
/// <summary>
/// Update player profile vitality values with changes from client request object
/// </summary>
/// <param name="pmcData">Player profile</param>
/// <param name="request">Heal request</param>
/// <param name="sessionID">Session id</param>
/// <param name="addEffects">Should effects be added to profile (default - true)</param>
/// <param name="deleteExistingEffects">Should all prior effects be removed before apply new ones (default - true)</param>
public void SaveVitality(
PmcData pmcData,
SyncHealthRequestData request,
string sessionID,
bool addEffects = true,
bool deleteExistingEffects = true)
{
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>
/// Adjust hydration/energy/temperate and body part hp values in player profile to values in profile.vitality
/// </summary>
@@ -244,40 +248,45 @@ public class HealthHelper(
/// <param name="sessionID">Session id</param>
protected void SaveHealth(PmcData pmcData, string sessionID)
{
// 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);
// }
// }
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 bodyPart in pmcData.Health.BodyParts)
{
if (profileHealth.Health[bodyPart.Key].Health.Maximum > bodyPart.Value.Health.Maximum)
{
profileHealth.Health[bodyPart.Key].Health.Maximum = bodyPart.Value.Health.Maximum;
}
if (profileHealth.Health[bodyPart.Key].Health.Current == 0)
{
profileHealth.Health[bodyPart.Key].Health.Current = bodyPart.Value.Health.Maximum * _healthConfig.HealthMultipliers.Blacked;
}
bodyPart.Value.Health.Current = Math.Round(profileHealth.Health[bodyPart.Key].Health.Current ?? 0);
}
}
/// <summary>
@@ -292,45 +301,35 @@ public class HealthHelper(
protected void SaveEffects(
PmcData pmcData,
string sessionID,
Effects bodyPartsWithEffects,
Dictionary<string, BodyPartHealth> bodyPartsWithEffects,
bool deleteExistingEffects = true)
{
// 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);
// }
// }
// }
if (!_healthConfig.Save.Effects)
{
return;
}
foreach ( var bodyPart in bodyPartsWithEffects) {
// clear effects from profile bodyPart
if (deleteExistingEffects)
{
pmcData.Health.BodyParts[bodyPart.Key].Effects = new Dictionary<string, BodyPartEffectProperties>();
}
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>
@@ -340,20 +339,11 @@ public class HealthHelper(
/// <param name="effectBodyPart">Body part to edit</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, string effectBodyPart, string effectType, int duration = -1)
protected void AddEffect(PmcData pmcData, KeyValuePair<string, BodyPartEffectProperties> effectType, double? duration = -1)
{
// 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;
// }
var profileBodyPart = pmcData.Health.BodyParts[effectType.Key];
profileBodyPart.Effects ??= new Dictionary<string, BodyPartEffectProperties>();
profileBodyPart.Effects[effectType.Key] = new BodyPartEffectProperties { Time = duration };
}
}
@@ -1,10 +1,11 @@
using System.Text.Json.Serialization;
using Core.Models.Common;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Health;
public record HealthTreatmentRequestData : BaseInteractionRequestData
public record HealthTreatmentRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("trader")]
@@ -28,10 +29,10 @@ public record Difference
public BodyParts? BodyParts { get; set; }
[JsonPropertyName("Energy")]
public int? Energy { get; set; }
public double? Energy { get; set; }
[JsonPropertyName("Hydration")]
public int? Hydration { get; set; }
public double? Hydration { get; set; }
}
public record BodyParts
@@ -1,9 +1,10 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Health;
public record OffraidEatRequestData : BaseInteractionRequestData
public record OffraidEatRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("item")]
public string? Item { get; set; }
@@ -1,12 +1,20 @@
using Core.Models.Eft.Common.Request;
using System.Text.Json.Serialization;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Health;
public record OffraidHealRequestData : BaseInteractionRequestData
public record OffraidHealRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("item")]
public string? Item { get; set; }
public BodyPart? Part { get; set; }
[JsonPropertyName("part")]
public string? Part { get; set; }
[JsonPropertyName("count")]
public int? Count { get; set; }
[JsonPropertyName("time")]
public long? Time { get; set; }
}
@@ -1,9 +1,10 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Hideout;
public record HideoutCircleOfCultistProductionStartRequestData : BaseInteractionRequestData
public record HideoutCircleOfCultistProductionStartRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("timestamp")]
public long? Timestamp { get; set; }
@@ -1,9 +1,10 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Hideout;
public record HideoutContinuousProductionStartRequestData : BaseInteractionRequestData
public record HideoutContinuousProductionStartRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("recipeId")]
public string? RecipeId { get; set; }
@@ -1,9 +1,10 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Hideout;
public record HideoutCustomizationApplyRequestData: BaseInteractionRequestData
public record HideoutCustomizationApplyRequestData : InventoryBaseActionRequestData
{
/// <summary>
@@ -1,9 +1,10 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Hideout;
public record HideoutCustomizationSetMannequinPoseRequest : BaseInteractionRequestData
public record HideoutCustomizationSetMannequinPoseRequest : InventoryBaseActionRequestData
{
[JsonPropertyName("poses")]
public Dictionary<string, string>? Poses { get; set; }
@@ -1,9 +1,10 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Hideout;
public record HideoutDeleteProductionRequestData: BaseInteractionRequestData
public record HideoutDeleteProductionRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("recipeId")]
public string? RecipeId { get; set; }
@@ -1,11 +1,12 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Inventory;
using Core.Models.Enums;
namespace Core.Models.Eft.Hideout;
public record HideoutImproveAreaRequestData : BaseInteractionRequestData
public record HideoutImproveAreaRequestData : InventoryBaseActionRequestData
{
/** Hideout area id from areas.json */
[JsonPropertyName("id")]
@@ -1,11 +1,12 @@
using System.Text.Json.Serialization;
using Core.Models.Common;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
using Core.Models.Enums;
namespace Core.Models.Eft.Hideout;
public record HideoutPutItemInRequestData : BaseInteractionRequestData
public record HideoutPutItemInRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("areaType")]
@@ -1,10 +1,11 @@
using System.Text.Json.Serialization;
using Core.Models.Common;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Hideout;
public record HideoutScavCaseStartRequestData : BaseInteractionRequestData
public record HideoutScavCaseStartRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("recipeId")]
public string? RecipeId { get; set; }
@@ -1,10 +1,11 @@
using System.Text.Json.Serialization;
using Core.Models.Common;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Hideout;
public record HideoutSingleProductionStartRequestData : BaseInteractionRequestData
public record HideoutSingleProductionStartRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("recipeId")]
public string? RecipeId { get; set; }
@@ -1,10 +1,11 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
using Core.Models.Enums;
namespace Core.Models.Eft.Hideout;
public record HideoutTakeItemOutRequestData : BaseInteractionRequestData
public record HideoutTakeItemOutRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("areaType")]
public HideoutAreas? AreaType { get; set; }
@@ -1,9 +1,10 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Hideout;
public record HideoutTakeProductionRequestData : BaseInteractionRequestData
public record HideoutTakeProductionRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("recipeId")]
public string? RecipeId { get; set; }
@@ -1,10 +1,11 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
using Core.Models.Enums;
namespace Core.Models.Eft.Hideout;
public record HideoutToggleAreaRequestData : BaseInteractionRequestData
public record HideoutToggleAreaRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("areaType")]
public HideoutAreas? AreaType { get; set; }
@@ -1,10 +1,11 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
using Core.Models.Enums;
namespace Core.Models.Eft.Hideout;
public record HideoutUpgradeCompleteRequestData : BaseInteractionRequestData
public record HideoutUpgradeCompleteRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("areaType")]
@@ -1,11 +1,12 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Inventory;
using Core.Models.Enums;
namespace Core.Models.Eft.Hideout;
public record HideoutUpgradeRequestData : BaseInteractionRequestData
public record HideoutUpgradeRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("areaType")]
@@ -1,9 +1,10 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Hideout;
public record RecordShootingRangePoints : BaseInteractionRequestData
public record RecordShootingRangePoints : InventoryBaseActionRequestData
{
[JsonPropertyName("points")]
public int? Points { get; set; }
@@ -1,9 +1,10 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common.Request;
using Core.Models.Eft.Inventory;
namespace Core.Models.Eft.Insurance;
public record InsureRequestData : BaseInteractionRequestData
public record InsureRequestData : InventoryBaseActionRequestData
{
[JsonPropertyName("tid")]
public string? TransactionId { get; set; }
@@ -410,105 +410,18 @@ public record ReceivedGift
}
public record Vitality
{
[JsonPropertyName("health")]
public Health? Health { get; set; }
[JsonPropertyName("effects")]
public Effects? Effects { get; set; }
}
public record Health
{
[JsonPropertyName("Hydration")]
public double? Hydration { get; set; }
[JsonPropertyName("Energy")]
public double? Energy { get; set; }
[JsonPropertyName("Temperature")]
public double? Temperature { get; set; }
[JsonPropertyName("Head")]
public double? Head { get; set; }
[JsonPropertyName("Chest")]
public double? Chest { get; set; }
[JsonPropertyName("Stomach")]
public double? Stomach { get; set; }
[JsonPropertyName("LeftArm")]
public double? LeftArm { get; set; }
[JsonPropertyName("RightArm")]
public double? RightArm { get; set; }
[JsonPropertyName("LeftLeg")]
public double? LeftLeg { get; set; }
[JsonPropertyName("RightLeg")]
public double? RightLeg { get; set; }
}
public record Effects
{
[JsonPropertyName("Head")]
public Head? Head { get; set; }
[JsonPropertyName("Chest")]
public Chest? Chest { get; set; }
[JsonPropertyName("Stomach")]
public Stomach? Stomach { get; set; }
[JsonPropertyName("LeftArm")]
public LeftArm? LeftArm { get; set; }
[JsonPropertyName("RightArm")]
public RightArm? RightArm { get; set; }
[JsonPropertyName("LeftLeg")]
public LeftLeg? LeftLeg { get; set; }
[JsonPropertyName("RightLeg")]
public RightLeg? RightLeg { get; set; }
}
public record Head
{
}
public record Chest
{
}
public record Stomach
{
}
public record LeftArm
{
[JsonPropertyName("Fracture")]
public double? Fracture { get; set; }
}
public record RightArm
{
[JsonPropertyName("Fracture")]
public double? Fracture { get; set; }
}
public record LeftLeg
{
[JsonPropertyName("Fracture")]
public double? Fracture { get; set; }
}
public record RightLeg
{
[JsonPropertyName("Fracture")]
public double? Fracture { get; set; }
[JsonPropertyName("Health")] // This now does health and effects to each bodypart
public Dictionary<string, BodyPartHealth>? Health { get; set; }
}
public record Inraid
@@ -1,11 +1,13 @@
using SptCommon.Annotations;
using Core.DI;
using Core.Helpers;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Profile;
namespace Core.Routers.SaveLoad;
[Injectable(InjectableTypeOverride = typeof(SaveLoadRouter))]
public class HealthSaveLoadRouter : SaveLoadRouter
public class HealthSaveLoadRouter() : SaveLoadRouter
{
protected override List<HandledRoute> GetHandledRoutes()
{
@@ -14,34 +16,87 @@ public class HealthSaveLoadRouter : SaveLoadRouter
public override SptProfile HandleLoad(SptProfile profile)
{
if (profile?.VitalityData == null)
profile.VitalityData = new() { Health = null, Effects = null };
profile.VitalityData.Health = new()
{
Hydration = 0,
Energy = 0,
Temperature = 0,
Head = 0,
Chest = 0,
Stomach = 0,
LeftArm = 0,
RightArm = 0,
LeftLeg = 0,
RightLeg = 0
};
profile.VitalityData.Effects = new()
{
Head = new(),
Chest = new(),
Stomach = new(),
LeftArm = new(),
RightArm = new(),
LeftLeg = new(),
RightLeg = new()
};
DefaultVitality(profile.VitalityData);
return profile;
}
public void DefaultVitality(Vitality? vitality)
{
vitality ??= new Vitality { Health = null, Energy = 0, Temperature = 0, Hydration = 0 };
vitality.Health = new Dictionary<string, BodyPartHealth>
{
{
"Head", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"Chest", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"Stomach", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"LeftArm", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"RightArm", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"LeftLeg", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
},
{
"RightLeg", new BodyPartHealth
{
Health = new CurrentMinMax
{
Current = 0,
},
Effects = new Dictionary<string, BodyPartEffectProperties>()
}
}
};
}
}
@@ -365,7 +365,7 @@ public class LocationLifecycleService
/** Handle client/match/local/end */
public void EndLocalRaid(string sessionId, EndLocalRaidRequestData request)
{
// Clear bot loot cache
// Clear bot loot cache
_botLootCacheService.ClearCache();
var fullProfile = _profileHelper.GetFullProfile(sessionId);