From d39b877cba0157e2d8f2226ef269ea96424781ee Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 22 Jan 2025 14:10:06 +0000 Subject: [PATCH 1/2] Implemented Eat endpoint --- .../Core/Controllers/HealthController.cs | 104 +++++++++++++++++- .../Models/Eft/Common/Tables/TemplateItem.cs | 3 +- 2 files changed, 103 insertions(+), 4 deletions(-) diff --git a/Libraries/Core/Controllers/HealthController.cs b/Libraries/Core/Controllers/HealthController.cs index 7e7495b2..b5292146 100644 --- a/Libraries/Core/Controllers/HealthController.cs +++ b/Libraries/Core/Controllers/HealthController.cs @@ -2,11 +2,28 @@ using SptCommon.Annotations; using Core.Models.Eft.Common; using Core.Models.Eft.Health; using Core.Models.Eft.ItemEvent; +using Core.Models.Eft.Common.Tables; +using Core.Helpers; +using Core.Models.Utils; +using Core.Routers; +using Core.Services; +using Core.Utils; +using Core.Utils.Cloners; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace Core.Controllers; [Injectable] -public class HealthController +public class HealthController( + ISptLogger _logger, + EventOutputHolder _eventOutputHolder, + ItemHelper _itemHelper, + PaymentService _paymentService, + InventoryHelper _inventoryHelper, + LocalisationService _localisationService, + HttpResponseUtil _httpResponseUtil, + HealthHelper _healthHelper, + ICloner cloner) { /// /// When healing in menu @@ -34,9 +51,90 @@ public class HealthController public ItemEventRouterResponse OffRaidEat( PmcData pmcData, OffraidEatRequestData request, - string sessionId) + string sessionID) { - throw new NotImplementedException(); + var output = _eventOutputHolder.GetOutput(sessionID); + var resourceLeft = 0d; + + var itemToConsume = pmcData.Inventory.Items.FirstOrDefault((item) => item.Id == request.Item); + if (itemToConsume is null) + { + // Item not found, very bad + return _httpResponseUtil.AppendErrorToOutput(output, _localisationService.GetText("health-unable_to_find_item_to_consume", request.Item)); + } + + var consumedItemMaxResource = _itemHelper.GetItem(itemToConsume.Template).Value.Properties.MaxResource; + if (consumedItemMaxResource > 1) + { + // Ensure item has a upd object + _itemHelper.AddUpdObjectToItem(itemToConsume); + + if (itemToConsume.Upd.FoodDrink is null) + { + itemToConsume.Upd.FoodDrink = new UpdFoodDrink{ HpPercent = consumedItemMaxResource - request.Count }; + } + else + { + itemToConsume.Upd.FoodDrink.HpPercent -= request.Count; + } + + resourceLeft = itemToConsume.Upd.FoodDrink.HpPercent.Value; + } + + // Remove item from inventory if resource has dropped below threshold + if (consumedItemMaxResource == 1 || resourceLeft < 1) + { + _inventoryHelper.RemoveItem(pmcData, request.Item, sessionID, output); + } + + // Check what effect eating item has and handle + var foodItemDbDetails = _itemHelper.GetItem(itemToConsume.Template).Value; + var foodItemEffectDetails = foodItemDbDetails.Properties.EffectsHealth; + var foodIsSingleUse = foodItemDbDetails.Properties.MaxResource == 1; + + foreach (var (key, effectProps) in foodItemEffectDetails) { + switch (key) + { + case "Hydration": + ApplyEdibleEffect(pmcData.Health.Hydration, effectProps, foodIsSingleUse, request); + break; + case "Energy": + ApplyEdibleEffect(pmcData.Health.Energy, effectProps, foodIsSingleUse, request); + break; + + default: + _logger.Warning($"Unhandled effect after consuming: ${ itemToConsume.Template}, ${key}"); + break; + } + } + return output; + } + + protected void ApplyEdibleEffect(CurrentMax bodyValue, EffectsHealthProps consumptionDetails, bool foodIsSingleUse, OffraidEatRequestData request) + { + if (foodIsSingleUse) + { + // Apply whole value from passed in parameter + bodyValue.Current += consumptionDetails.Value; + } + else + { + bodyValue.Current += request.Count; + } + + // Ensure current never goes over max + if (bodyValue.Current > bodyValue.Maximum) + { + bodyValue.Current = bodyValue.Maximum; + + return; + } + + // Same as above but for the lower bound + if (bodyValue.Current < 0) + { + bodyValue.Current = 0; + } } /// diff --git a/Libraries/Core/Models/Eft/Common/Tables/TemplateItem.cs b/Libraries/Core/Models/Eft/Common/Tables/TemplateItem.cs index 79d368da..7e5060ee 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/TemplateItem.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/TemplateItem.cs @@ -977,7 +977,8 @@ public record Props public string? StimulatorBuffs { get; set; } [JsonPropertyName("effects_health")] - public object? EffectsHealth { get; set; } // TODO: object here + [JsonConverter(typeof(ArrayToObjectFactoryConverter))] + public Dictionary? EffectsHealth { get; set; } [JsonPropertyName("effects_damage")] [JsonConverter(typeof(ArrayToObjectFactoryConverter))] From e7d5fda4d8a24fa128da9b89b16c4b96edefe024 Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 22 Jan 2025 14:29:57 +0000 Subject: [PATCH 2/2] Fixed inaccuracies on profile creation --- Libraries/Core/Helpers/ProfileHelper.cs | 9 +++++++-- Libraries/Core/Models/Eft/Common/Tables/BotBase.cs | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Libraries/Core/Helpers/ProfileHelper.cs b/Libraries/Core/Helpers/ProfileHelper.cs index 9e0bf86b..6ef80282 100644 --- a/Libraries/Core/Helpers/ProfileHelper.cs +++ b/Libraries/Core/Helpers/ProfileHelper.cs @@ -303,8 +303,13 @@ public class ProfileHelper( FoundInRaidItems = new(), LastPlayerState = null, LastSessionDate = 0, - OverallCounters = new(), - SessionCounters = new(), + OverallCounters = new() + { + Items = [] + }, + SessionCounters = new(){ + Items = [] + }, SessionExperienceMult = 0, SurvivorClass = "Unknown", TotalInGameTime = 0, diff --git a/Libraries/Core/Models/Eft/Common/Tables/BotBase.cs b/Libraries/Core/Models/Eft/Common/Tables/BotBase.cs index 5828618e..fd14daec 100644 --- a/Libraries/Core/Models/Eft/Common/Tables/BotBase.cs +++ b/Libraries/Core/Models/Eft/Common/Tables/BotBase.cs @@ -231,6 +231,9 @@ public record BotBaseHealth public CurrentMax? Hydration { get; set; } public CurrentMax? Energy { get; set; } public CurrentMax? Temperature { get; set; } + + [JsonConverter(typeof(ArrayToObjectFactoryConverter))] + [JsonPropertyName("BodyParts")] public Dictionary? BodyParts { get; set; } public double? UpdateTime { get; set; } public bool? Immortal { get; set; }