using Core.Annotations; using Core.Helpers; using Core.Models.Eft.Common; using Core.Models.Eft.Common.Tables; using Core.Models.Eft.Inventory; using Core.Models.Eft.Prestige; using Core.Models.Eft.Profile; using Core.Models.Utils; using Core.Routers; using Core.Servers; using Core.Services; using Core.Utils; using Core.Utils.Cloners; namespace Core.Controllers; [Injectable] public class PrestigeController { protected ISptLogger _logger; protected TimeUtil _timeUtil; protected InventoryHelper _inventoryHelper; protected ProfileHelper _profileHelper; protected EventOutputHolder _eventOutputHolder; protected CreateProfileService _createProfileService; private DatabaseService _databaseService; private readonly SaveServer _saveServer; protected ICloner _cloner; public PrestigeController ( ISptLogger logger, TimeUtil timeUtil, InventoryHelper inventoryHelper, ProfileHelper profileHelper, EventOutputHolder eventOutputHolder, CreateProfileService createProfileService, DatabaseService databaseService, SaveServer saveServer, ICloner cloner ) { _logger = logger; _timeUtil = timeUtil; _inventoryHelper = inventoryHelper; _profileHelper = profileHelper; _eventOutputHolder = eventOutputHolder; _createProfileService = createProfileService; _databaseService = databaseService; _saveServer = saveServer; _cloner = cloner; } /// /// Handle /client/prestige/list /// /// /// /// public Prestige GetPrestige( string sessionId, EmptyRequestData info) { return _databaseService.GetTemplates().Prestige; } /// /// Handle /client/prestige/obtain /// /// /// /// public void ObtainPrestige( string sessionId, List request) { var prePrestigeProfileClone = _cloner.Clone(_profileHelper.GetFullProfile(sessionId)); var prePrestigePmc = prePrestigeProfileClone.CharacterData.PmcData; var createRequest = new ProfileCreateRequestData { Side = prePrestigePmc.Info.Side, Nickname = prePrestigePmc.Info.Nickname, HeadId = prePrestigePmc.Customization.Head, VoiceId = _databaseService.GetTemplates().Customization.FirstOrDefault( (customisation) => customisation.Value.Name == prePrestigePmc.Info.Voice).Value.Id, SptForcePrestigeLevel = prePrestigeProfileClone.CharacterData.PmcData.Info.PrestigeLevel.GetValueOrDefault(0) + 1, // Current + 1 }; // Reset profile _createProfileService.CreateProfile(sessionId, createRequest); // Get freshly reset profile ready for editing var newProfile = _profileHelper.GetFullProfile(sessionId); // Skill copy // TODO - Find what skills should be prestiged over var commonSkillsToCopy = prePrestigePmc.Skills.Common; foreach (var skillToCopy in commonSkillsToCopy) { // Set progress to max level 20 skillToCopy.Progress = Math.Min(skillToCopy.Progress.Value, 2000); var existingSkill = newProfile.CharacterData.PmcData.Skills.Common.FirstOrDefault((skill) => skill.Id == skillToCopy.Id); if (existingSkill is not null) { existingSkill.Progress = skillToCopy.Progress; } else { newProfile.CharacterData.PmcData.Skills.Common.Add(skillToCopy); } } var masteringSkillsToCopy = prePrestigePmc.Skills.Mastering; foreach (var skillToCopy in masteringSkillsToCopy) { // Set progress to max level 20 skillToCopy.Progress = Math.Min(skillToCopy.Progress.Value, 2000); var existingSkill = newProfile.CharacterData.PmcData.Skills.Mastering.FirstOrDefault( (skill) => skill.Id == skillToCopy.Id); if (existingSkill is not null) { existingSkill.Progress = skillToCopy.Progress; } else { newProfile.CharacterData.PmcData.Skills.Mastering.Add(skillToCopy); } } // Assumes Prestige data is in descending order var indexOfPrestigeObtained = (int)Math.Min(createRequest.SptForcePrestigeLevel.Value - 1, 1); // Index starts at 0 var currentPrestigeData = _databaseService.GetTemplates().Prestige.Elements[indexOfPrestigeObtained]; var prestigeRewards = _databaseService.GetTemplates().Prestige.Elements.Slice(0, indexOfPrestigeObtained + 1) .SelectMany((prestige) => prestige.Rewards); AddPrestigeRewardsToProfile(sessionId, newProfile, prestigeRewards); // Flag profile as having achieved this prestige level newProfile.CharacterData.PmcData.Prestige[currentPrestigeData.Id] = _timeUtil.GetTimeStamp(); // Copy transferred items foreach (var transferRequest in request) { var item = prePrestigePmc.Inventory.Items.FirstOrDefault((item) => item.Id == transferRequest.Id); var addItemRequest = new AddItemDirectRequest { ItemWithModsToAdd = [item], FoundInRaid = item.Upd?.SpawnedInSession, UseSortingTable = false, Callback = null, }; _inventoryHelper.AddItemToStash( sessionId, addItemRequest, newProfile.CharacterData.PmcData, _eventOutputHolder.GetOutput(sessionId)); } // Add "Prestigious" achievement if (!newProfile.PlayerAchievements.ContainsKey("676091c0f457869a94017a23")) { newProfile.PlayerAchievements.Add("676091c0f457869a94017a23", _timeUtil.GetTimeStamp()); } // Force save of above changes to disk _saveServer.SaveProfile(sessionId); } private void AddPrestigeRewardsToProfile(string sessionId, SptProfile newProfile, IEnumerable rewards) { _logger.Error("NOT IMPLEMENTED AddPrestigeRewardsToProfile()"); } }