using Microsoft.Extensions.Logging;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Prestige;
using SPTarkov.Server.Core.Models.Eft.Profile;
using SPTarkov.Server.Core.Servers;
using SPTarkov.Server.Core.Services;
namespace SPTarkov.Server.Core.Controllers;
[Injectable]
public class PrestigeController(ProfileHelper profileHelper, DatabaseService databaseService, SaveServer saveServer)
{
///
/// Handle /client/prestige/list
/// Get a collection of all possible prestiges
///
/// Session/Player id
/// Prestige
public Prestige GetPrestige(MongoId sessionId)
{
return databaseService.GetTemplates().Prestige;
}
///
/// Handle /client/prestige/obtain
/// Going to Prestige 1 grants the below
///
/// - 5% of skills should be transferred over
/// - 5% of mastering should be transferred over
/// - Earned achievements should be transferred over
/// - Profile stats should be transferred over
/// - Prestige progress should be transferred over
/// - Items and rewards for Prestige 1
///
/// Going to Prestige 2 grants the below
///
/// - 10% of skills should be transfered over
/// - 10% of mastering should be transfered over
/// - Earned achievements should be transfered over
/// - Profile stats should be transfered over
/// - Prestige progress should be transfered over
/// - Items and rewards for Prestige 2
///
/// Each time resetting the below
///
/// - Trader standing
/// - Task progress
/// - Character level
/// - Stash
/// - Hideout progress
///
///
///
public async Task ObtainPrestige(MongoId sessionId, ObtainPrestigeRequestList request)
{
var profile = profileHelper.GetFullProfile(sessionId);
if (profile is not null)
{
var pendingPrestige = new PendingPrestige
{
PrestigeLevel = (profile.CharacterData?.PmcData?.Info?.PrestigeLevel ?? 0) + 1,
Items = request,
};
profile.SptData.PendingPrestige = pendingPrestige;
profile.ProfileInfo.IsWiped = true;
var prestigeLevels = databaseService.GetTemplates().Prestige?.Elements ?? [];
var prestigeRewards = prestigeLevels
.Slice(0, pendingPrestige.PrestigeLevel.Value)
.SelectMany(prestigeInner => prestigeInner.Rewards);
var customisationTemplateDb = databaseService.GetTemplates().Customization;
foreach (var reward in prestigeRewards)
{
if (!MongoId.IsValidMongoId(reward.Target))
{
continue;
}
if (!customisationTemplateDb.TryGetValue(reward.Target, out var template))
{
continue;
}
// This has to be done before the profile is wiped, as the user can only select a new head during the wipe
if (template.Parent == CustomisationTypeId.HEAD)
{
profileHelper.AddHideoutCustomisationUnlock(profile, reward, CustomisationSource.PRESTIGE);
}
}
await saveServer.SaveProfileAsync(sessionId);
}
}
}