Files
SPT-Server-Build/Libraries/SPTarkov.Server.Core/Helpers/PrestigeHelper.cs
T
Chomp 0ea5269756 Updated profile SkillTypes property to use string to enum converter
Updated surrounding properties to not be null
Updated related code to reflect nullability change
2025-08-03 09:52:18 +01:00

168 lines
6.6 KiB
C#

using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Extensions;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Profile;
using SPTarkov.Server.Core.Models.Enums;
using SPTarkov.Server.Core.Models.Utils;
using SPTarkov.Server.Core.Services;
using SPTarkov.Server.Core.Utils;
namespace SPTarkov.Server.Core.Helpers;
[Injectable]
public class PrestigeHelper(
ISptLogger<PrestigeHelper> logger,
TimeUtil timeUtil,
DatabaseService databaseService,
MailSendService mailSendService,
ProfileHelper profileHelper,
RewardHelper rewardHelper
)
{
public void ProcessPendingPrestige(SptProfile oldProfile, SptProfile newProfile, PendingPrestige prestige)
{
var prePrestigePmc = oldProfile.CharacterData.PmcData;
var sessionId = newProfile.ProfileInfo.ProfileId;
var prestigeLevels = databaseService.GetTemplates().Prestige.Elements;
var indexOfPrestigeObtained = Math.Clamp((prestige.PrestigeLevel ?? 1) - 1, 0, prestigeLevels.Count - 1); // Levels are 1 to 4, Index is 0 to 3
// Skill copy
var skillProgressCopyAmount = (float)(1 - prestigeLevels[indexOfPrestigeObtained].TransferConfigs.SkillConfig.TransferMultiplier);
var masteringProgressCopyAmount = (float)(
1 - prestigeLevels[indexOfPrestigeObtained].TransferConfigs.MasteringConfig.TransferMultiplier
);
if (prePrestigePmc.Skills.Common is not null)
{
var commonSKillsToCopy = prePrestigePmc.Skills.Common;
foreach (var skillToCopy in commonSKillsToCopy)
{
// Set progress for 5% of what it was, multiplied by prestige level
skillToCopy.Progress *= skillProgressCopyAmount;
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 = newProfile.CharacterData.PmcData.Skills.Common.Union([skillToCopy]);
}
}
var masteringSkillsToCopy = prePrestigePmc.Skills.Mastering;
foreach (var skillToCopy in masteringSkillsToCopy)
{
// Set progress 5% of what it was, multiplied by prestige level
skillToCopy.Progress *= masteringProgressCopyAmount;
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 = newProfile.CharacterData.PmcData.Skills.Mastering.Union(
[skillToCopy]
);
}
}
}
// Add "Prestigious" achievement
var prestigiousAchievement = new MongoId("676091c0f457869a94017a23");
if (!newProfile.CharacterData.PmcData.Achievements.ContainsKey(prestigiousAchievement))
{
rewardHelper.AddAchievementToProfile(newProfile, prestigiousAchievement);
}
// Assumes Prestige data is in descending order
var currentPrestigeData = databaseService.GetTemplates().Prestige.Elements[indexOfPrestigeObtained];
// Get all prestige rewards from prestige 1 up to desired prestige
var prestigeRewards = prestigeLevels
.Slice(0, indexOfPrestigeObtained + 1) // Index back to PrestigeLevel
.SelectMany(prestige => prestige.Rewards);
AddPrestigeRewardsToProfile(sessionId.Value, newProfile, prestigeRewards);
// Flag profile as having achieved this prestige level
newProfile.CharacterData.PmcData.Prestige.TryAdd(currentPrestigeData.Id, timeUtil.GetTimeStamp());
var itemsToTransfer = new List<Item>();
// Copy transferred items
foreach (var transferRequest in prestige.Items ?? [])
{
var item = prePrestigePmc.Inventory.Items.FirstOrDefault(item => item.Id == transferRequest.Id);
if (item is null)
{
logger.Error($"Unable to find item with id: {transferRequest.Id} in profile: {sessionId}, skipping");
continue;
}
itemsToTransfer.Add(item);
}
if (itemsToTransfer.Count > 0)
{
mailSendService.SendSystemMessageToPlayer(
sessionId.Value,
"",
itemsToTransfer,
timeUtil.GetHoursAsSeconds(8760) // Year
);
}
newProfile.CharacterData.PmcData.Info.PrestigeLevel = prestige.PrestigeLevel;
}
private void AddPrestigeRewardsToProfile(MongoId sessionId, SptProfile newProfile, IEnumerable<Reward> rewards)
{
var itemsToSend = new List<Item>();
foreach (var reward in rewards)
{
switch (reward.Type)
{
case RewardType.CustomizationDirect:
{
profileHelper.AddHideoutCustomisationUnlock(newProfile, reward, CustomisationSource.PRESTIGE);
break;
}
case RewardType.Skill:
if (Enum.TryParse(reward.Target, out SkillTypes result))
{
profileHelper.AddSkillPointsToPlayer(newProfile.CharacterData.PmcData, result, reward.Value.GetValueOrDefault(0));
}
else
{
logger.Error($"Unable to parse reward Target to Enum: {reward.Target}");
}
break;
case RewardType.Item:
{
itemsToSend.AddRange(reward.Items);
break;
}
case RewardType.ExtraDailyQuest:
{
newProfile.AddExtraRepeatableQuest(new MongoId(reward.Target), (double)reward.Value);
break;
}
default:
logger.Error($"Unhandled prestige reward type: {reward.Type} Id: {reward.Id}");
break;
}
}
if (itemsToSend.Count > 0)
{
mailSendService.SendSystemMessageToPlayer(sessionId, "", itemsToSend, 31536000);
}
}
}