diff --git a/Core/Controllers/GameController.cs b/Core/Controllers/GameController.cs
index ec0d79da..3731442d 100644
--- a/Core/Controllers/GameController.cs
+++ b/Core/Controllers/GameController.cs
@@ -3,6 +3,7 @@ using Core.Context;
using Core.Helpers;
using Core.Models.Eft.Common;
using Core.Models.Eft.Game;
+using Core.Models.Eft.Match;
using Core.Models.Eft.Profile;
using Core.Models.Enums;
using Core.Models.External;
@@ -12,6 +13,8 @@ using Core.Servers;
using Core.Services;
using Core.Utils;
using Core.Utils.Cloners;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+using System.Diagnostics;
namespace Core.Controllers;
@@ -570,7 +573,11 @@ public class GameController
/// Profile to check for dialog in
private void CheckForAndRemoveUndefinedDialogues(SptProfile fullProfile)
{
- throw new NotImplementedException();
+
+ if (fullProfile.DialogueRecords.TryGetValue("undefined", out var undefinedDialog))
+ {
+ fullProfile.DialogueRecords.Remove("undefined");
+ }
}
///
@@ -579,7 +586,12 @@ public class GameController
///
private void LogProfileDetails(SptProfile fullProfile)
{
- throw new NotImplementedException();
+ _logger.Error("NOT IMPLEMENTED LogProfileDetails");
+ _logger.Debug($"Profile made with: ${ fullProfile.SptData.Version}");
+ _logger.Debug($"{fullProfile.SptData.Mods.Count} Mods used");
+ //_logger.Debug($"Server version: ${ ProgramStatics.SPT_VERSION || _coreConfig.SptVersion} ${ ProgramStatics.COMMIT}");
+ //_logger.Debug($"Debug enabled: ${ ProgramStatics.DEBUG}");
+ //_logger.Debug($"Mods enabled: ${ ProgramStatics.MODS}");
}
public void Load()
diff --git a/Core/Helpers/HideoutHelper.cs b/Core/Helpers/HideoutHelper.cs
index fe4f82a8..ea26eac3 100644
--- a/Core/Helpers/HideoutHelper.cs
+++ b/Core/Helpers/HideoutHelper.cs
@@ -1,15 +1,32 @@
-using Core.Annotations;
+using Core.Annotations;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Hideout;
using Core.Models.Eft.ItemEvent;
using Core.Models.Enums;
+using Core.Models.Utils;
+using Core.Services;
+using Core.Utils;
namespace Core.Helpers;
[Injectable]
public class HideoutHelper
{
+ private readonly ISptLogger _logger;
+ protected TimeUtil _timeUtil;
+ private readonly LocalisationService _localisationService;
+
+ public HideoutHelper(
+ ISptLogger logger,
+ TimeUtil timeUtil,
+ LocalisationService localisationService)
+ {
+ _logger = logger;
+ _timeUtil = timeUtil;
+ _localisationService = localisationService;
+ }
+
///
/// Add production to profiles' Hideout.Production array
///
@@ -52,9 +69,41 @@ public class HideoutHelper
///
/// Profile to add bonus to
/// Bonus to add to profile
- public void ApplyPlayerUpgradesBonuses(PmcData profileData, StageBonus bonus)
+ public void ApplyPlayerUpgradesBonuses(PmcData profileData, Bonus bonus)
{
- throw new NotImplementedException();
+ // Handle additional changes some bonuses need before being added
+ var bonusToAdd = new Bonus();
+ switch (bonus.Type)
+ {
+ case BonusType.StashSize:
+ {
+ // Find stash item and adjust tpl to new tpl from bonus
+ var stashItem = profileData.Inventory.Items.FirstOrDefault((x) => x.Id == profileData.Inventory.Stash);
+ if (stashItem is null)
+ {
+ _logger.Warning(_localisationService.GetText("hideout-unable_to_apply_stashsize_bonus_no_stash_found", profileData.Inventory.Stash));
+ }
+
+ stashItem.Template = bonus.TemplateId;
+
+ break;
+ }
+ case BonusType.MaximumEnergyReserve:
+ // Amend max energy in profile
+ profileData.Health.Energy.Maximum += bonus.Value;
+ break;
+ case BonusType.TextBonus:
+ // Delete values before they're added to profile
+ bonus.IsPassive = null;
+ bonus.IsProduction = null;
+ bonus.IsVisible = null;
+ break;
+ }
+
+ // Add bonus to player bonuses array in profile
+ // EnergyRegeneration, HealthRegeneration, RagfairCommission, ScavCooldownTimer, SkillGroupLevelingBoost, ExperienceRate, QuestMoneyReward etc
+ _logger.Debug($"Adding bonus: {bonus.Type} to profile, value: {bonus.Value}");
+ profileData.Bonuses.Add(bonus);
}
///
@@ -420,7 +469,22 @@ public class HideoutHelper
/// Profile to upgrade wall in
public void UnlockHideoutWallInProfile(PmcData profileData)
{
- throw new NotImplementedException();
+ var profileHideoutAreas = profileData.Hideout.Areas;
+ var waterCollector = profileHideoutAreas.FirstOrDefault((x) => x.Type == HideoutAreas.WATER_COLLECTOR);
+ var medStation = profileHideoutAreas.FirstOrDefault((x) => x.Type == HideoutAreas.MEDSTATION);
+ var wall = profileHideoutAreas.FirstOrDefault((x) => x.Type == HideoutAreas.EMERGENCY_WALL);
+
+ // No collector or med station, skip
+ if ((waterCollector is null && medStation is null))
+ {
+ return;
+ }
+
+ // If med-station > level 1 AND water collector > level 1 AND wall is level 0
+ if (waterCollector?.Level >= 1 && medStation?.Level >= 1 && wall?.Level <= 0)
+ {
+ wall.Level = 3;
+ }
}
///
@@ -439,7 +503,20 @@ public class HideoutHelper
/// Profile to adjust
public void SetHideoutImprovementsToCompleted(PmcData profileData)
{
- throw new NotImplementedException();
+ foreach (var improvementId in profileData.Hideout.Improvements)
+ {
+ if (!profileData.Hideout.Improvements.TryGetValue(improvementId.Key, out var improvementDetails))
+ {
+ continue;
+ }
+
+ if (improvementDetails.Completed == false
+ && improvementDetails.ImproveCompleteTimestamp < _timeUtil.GetTimeStamp()
+ )
+ {
+ improvementDetails.Completed = true;
+ }
+ }
}
///
diff --git a/Core/Models/Eft/Hideout/HideoutArea.cs b/Core/Models/Eft/Hideout/HideoutArea.cs
index 04e7fe39..99ea612f 100644
--- a/Core/Models/Eft/Hideout/HideoutArea.cs
+++ b/Core/Models/Eft/Hideout/HideoutArea.cs
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
+using Core.Models.Eft.Common.Tables;
using Core.Models.Enums;
namespace Core.Models.Eft.Hideout;
@@ -9,7 +10,7 @@ public class HideoutArea
public string? Id { get; set; }
[JsonPropertyName("type")]
- public int? Type { get; set; }
+ public HideoutAreas? Type { get; set; }
[JsonPropertyName("enabled")]
public bool? IsEnabled { get; set; }
@@ -57,7 +58,7 @@ public class Stage
public bool? AutoUpgrade { get; set; }
[JsonPropertyName("bonuses")]
- public List? Bonuses { get; set; }
+ public List? Bonuses { get; set; }
[JsonPropertyName("constructionTime")]
public double? ConstructionTime { get; set; }
@@ -181,39 +182,3 @@ public class StageRequirement : RequirementBase
[JsonPropertyName("skillLevel")]
public int? SkillLevel { get; set; }
}
-
-public class StageBonus
-{
- [JsonPropertyName("value")]
- public int? Value { get; set; }
-
- [JsonPropertyName("passive")]
- public bool? Passive { get; set; }
-
- [JsonPropertyName("production")]
- public bool? Production { get; set; }
-
- [JsonPropertyName("visible")]
- public bool? Visible { get; set; }
-
- [JsonPropertyName("skillType")]
- [JsonConverter(typeof(JsonStringEnumConverter))]
- public BonusSkillType? SkillType { get; set; }
-
- [JsonPropertyName("type")]
- [JsonConverter(typeof(JsonStringEnumConverter))]
- public BonusType? Type { get; set; }
-
- [JsonPropertyName("filter")]
- public List? Filter { get; set; }
-
- [JsonPropertyName("icon")]
- public string? Icon { get; set; }
-
- /** CHANGES PER DUMP */
- [JsonPropertyName("id")]
- public string? Id { get; set; }
-
- [JsonPropertyName("templateId")]
- public string? TemplateId { get; set; }
-}
\ No newline at end of file
diff --git a/Core/Services/ProfileFixerService.cs b/Core/Services/ProfileFixerService.cs
index 8e48dcaa..b1af922b 100644
--- a/Core/Services/ProfileFixerService.cs
+++ b/Core/Services/ProfileFixerService.cs
@@ -11,6 +11,10 @@ using Core.Utils;
using System.Text.RegularExpressions;
using Core.Models.Spt.Config;
using Core.Models.Utils;
+using Core.Models.Spt.Bots;
+using static System.Runtime.InteropServices.JavaScript.JSType;
+using System.Reflection.Emit;
+using System.Security.AccessControl;
namespace Core.Services;
@@ -23,6 +27,7 @@ public class ProfileFixerService
protected ItemHelper _itemHelper;
protected QuestRewardHelper _questRewardHelper;
protected TraderHelper _traderHelper;
+ protected HideoutHelper _hideoutHelper;
protected DatabaseService _databaseService;
protected LocalisationService _localisationService;
protected ConfigServer _configServer;
@@ -36,6 +41,7 @@ public class ProfileFixerService
ItemHelper itemHelper,
QuestRewardHelper questRewardHelper,
TraderHelper traderHelper,
+ HideoutHelper hideoutHelper,
DatabaseService databaseService,
LocalisationService localisationService,
ConfigServer configServer,
@@ -48,6 +54,7 @@ public class ProfileFixerService
_itemHelper = itemHelper;
_questRewardHelper = questRewardHelper;
_traderHelper = traderHelper;
+ _hideoutHelper = hideoutHelper;
_databaseService = databaseService;
_localisationService = localisationService;
_configServer = configServer;
@@ -690,7 +697,54 @@ public class ProfileFixerService
*/
public void AddMissingHideoutBonusesToProfile(PmcData pmcProfile)
{
- throw new NotImplementedException();
+ var dbHideoutAreas = _databaseService.GetHideout().Areas;
+
+ foreach (var profileArea in pmcProfile.Hideout.Areas) {
+ var areaType = profileArea.Type;
+ var level = profileArea.Level;
+
+ if (level.GetValueOrDefault(0) == 0)
+ {
+ continue;
+ }
+
+ // Get array of hideout area upgrade levels to check for bonuses
+ // Zero indexed
+ var areaLevelsToCheck = new List();
+ for (var index = 0; index < level + 1; index++)
+ {
+ // Stage key is saved as string in db
+ areaLevelsToCheck.Add(index.ToString());
+ }
+
+ // Iterate over area levels, check for bonuses, add if needed
+ var dbArea = dbHideoutAreas.FirstOrDefault((area) => area.Type == areaType);
+ if (dbArea is null)
+ {
+ continue;
+ }
+
+ foreach (var areaLevel in areaLevelsToCheck) {
+ // Get areas level bonuses from db
+ var levelBonuses = dbArea.Stages[areaLevel]?.Bonuses;
+ if (levelBonuses is null || levelBonuses.Count == 0)
+ {
+ continue;
+ }
+
+ // Iterate over each bonus for the areas level
+ foreach (var bonus in levelBonuses) {
+ // Check if profile has bonus
+ var profileBonus = GetBonusFromProfile(pmcProfile.Bonuses, bonus);
+ if (profileBonus is null)
+ {
+ // no bonus, add to profile
+ _logger.Debug($"Profile has level {level} area {profileArea.Type} but no bonus found, adding { bonus.Type}");
+ _hideoutHelper.ApplyPlayerUpgradesBonuses(pmcProfile, bonus);
+ }
+ }
+ }
+ }
}
/**
@@ -698,9 +752,24 @@ public class ProfileFixerService
* @param bonus bonus to find
* @returns matching bonus
*/
- protected Bonus GetBonusFromProfile(List profileBonuses, StageBonus bonus)
+ protected Bonus? GetBonusFromProfile(List profileBonuses, Bonus bonus)
{
- throw new NotImplementedException();
+ // match by id first, used by "TextBonus" bonuses
+ if (bonus.Id is null)
+ {
+ return profileBonuses.FirstOrDefault((x) => x.Id == bonus.Id);
+ }
+
+ return bonus.Type switch
+ {
+ BonusType.StashSize => profileBonuses.FirstOrDefault(
+ (x) => x.Type == bonus.Type && x.TemplateId == bonus.TemplateId
+ ),
+ BonusType.AdditionalSlots => profileBonuses.FirstOrDefault(
+ (x) => x.Type == bonus.Type && x.Value == bonus.Value && x.IsVisible == bonus.IsVisible
+ ),
+ _ => profileBonuses.FirstOrDefault((x) => x.Type == bonus.Type && x.Value == bonus.Value)
+ };
}
public void CheckForAndRemoveInvalidTraders(SptProfile fullProfile)