0
0
mirror of https://github.com/sp-tarkov/server.git synced 2025-02-13 09:50:43 -05:00

On quest completion, store hideout customisation unlocks inside profile json

Append the unlock customisations to results of `client/customization/storage` call

Added `hideoutCustomisationUnlocks` to profile on creation
This commit is contained in:
Chomp 2025-01-07 12:47:32 +00:00
parent 4d039bf869
commit 9b16af7cb6
5 changed files with 59 additions and 3 deletions

View File

@ -230,8 +230,12 @@ export class CustomizationController {
public getCustomisationStorage(sessionID: string, info: IEmptyRequestData): ICustomisationStorage[] { public getCustomisationStorage(sessionID: string, info: IEmptyRequestData): ICustomisationStorage[] {
const customisationResultsClone = this.cloner.clone(this.databaseService.getTemplates().customisationStorage); const customisationResultsClone = this.cloner.clone(this.databaseService.getTemplates().customisationStorage);
// Some game versions have additional dogtag variants, add them
const profile = this.profileHelper.getFullProfile(sessionID); const profile = this.profileHelper.getFullProfile(sessionID);
if (!profile) {
return customisationResultsClone;
}
// Some game versions have additional dogtag variants, add them
switch (this.getGameEdition(profile)) { switch (this.getGameEdition(profile)) {
case GameEditions.EDGE_OF_DARKNESS: case GameEditions.EDGE_OF_DARKNESS:
// Gets EoD tags // Gets EoD tags
@ -295,6 +299,9 @@ export class CustomizationController {
} }
} }
// Append on customisations unlocked by player to results
customisationResultsClone.push(...(profile.hideoutCustomisationUnlocks ?? []));
return customisationResultsClone; return customisationResultsClone;
} }

View File

@ -1,7 +1,9 @@
import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper";
import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IPmcData } from "@spt/models/eft/common/IPmcData";
import { BanType, Common, ICounterKeyValue, IStats } from "@spt/models/eft/common/tables/IBotBase"; import { BanType, Common, ICounterKeyValue, IStats } from "@spt/models/eft/common/tables/IBotBase";
import { ICustomisationStorage } from "@spt/models/eft/common/tables/ICustomisationStorage";
import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IItem } from "@spt/models/eft/common/tables/IItem";
import { IQuestReward } from "@spt/models/eft/common/tables/IQuest";
import { ISearchFriendResponse } from "@spt/models/eft/profile/ISearchFriendResponse"; import { ISearchFriendResponse } from "@spt/models/eft/profile/ISearchFriendResponse";
import { ISpt, ISptProfile } from "@spt/models/eft/profile/ISptProfile"; import { ISpt, ISptProfile } from "@spt/models/eft/profile/ISptProfile";
import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData"; import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData";
@ -607,4 +609,40 @@ export class ProfileHelper {
return fullFavorites; return fullFavorites;
} }
/**
* Store a hideout customisation unlock inside a profile
* @param fullProfile Profile to add unlock to
* @param reward reward given to player with customisation data
* @param source Source of reward, e.g. "unlockedInGame" for quests and "achievement" for achievements
*/
public addHideoutCustomisationUnlock(fullProfile: ISptProfile, reward: IQuestReward, source: string): void {
// Get matching db data for reward
const hideoutCustomisationDb = this.databaseService
.getHideout()
.customisation.globals.find((customisation) => customisation.itemId === reward.target);
if (!hideoutCustomisationDb) {
this.logger.warning(
`Unable to add hideout customisaiton reward: ${reward.target} to profile: ${fullProfile.info.id} as matching object cannot be found in hideout/customisation.json`,
);
return;
}
fullProfile.hideoutCustomisationUnlocks ||= [];
if (fullProfile.hideoutCustomisationUnlocks?.some((unlock) => unlock.id === hideoutCustomisationDb.id)) {
this.logger.warning(
`Profile: ${fullProfile.info.id} already has hideout customisaiton reward: ${reward.target}, skipping`,
);
return;
}
const rewardToStore: ICustomisationStorage = {
id: hideoutCustomisationDb.id,
source: source,
type: hideoutCustomisationDb.type,
};
fullProfile.hideoutCustomisationUnlocks.push(rewardToStore);
}
} }

View File

@ -919,7 +919,13 @@ export class QuestHelper {
): IItem[] { ): IItem[] {
// Repeatable quest base data is always in PMCProfile, `profileData` may be scav profile // Repeatable quest base data is always in PMCProfile, `profileData` may be scav profile
// TODO: consider moving repeatable quest data to profile-agnostic location // TODO: consider moving repeatable quest data to profile-agnostic location
const pmcProfile = this.profileHelper.getPmcProfile(sessionId); const fullProfile = this.profileHelper.getFullProfile(sessionId);
const pmcProfile = fullProfile?.characters.pmc;
if (!pmcProfile) {
this.logger.error(`Unable to get pmc profile for: ${sessionId}, no rewards given`);
return [];
}
let questDetails = this.getQuestFromDb(questId, pmcProfile); let questDetails = this.getQuestFromDb(questId, pmcProfile);
if (!questDetails) { if (!questDetails) {
this.logger.warning( this.logger.warning(
@ -990,6 +996,9 @@ export class QuestHelper {
case QuestRewardType.POCKETS: case QuestRewardType.POCKETS:
this.profileHelper.replaceProfilePocketTpl(pmcProfile, reward.target); this.profileHelper.replaceProfilePocketTpl(pmcProfile, reward.target);
break; break;
case QuestRewardType.CUSTOMIZATION_DIRECT:
this.profileHelper.addHideoutCustomisationUnlock(fullProfile, reward, "unlockedInGame");
break;
default: default:
this.logger.error( this.logger.error(
this.localisationService.getText("quest-reward_type_not_handled", { this.localisationService.getText("quest-reward_type_not_handled", {

View File

@ -1,5 +1,5 @@
export interface ICustomisationStorage { export interface ICustomisationStorage {
id: string; id: string; // Customiastion.json/itemId
source: string; source: string;
type: string; type: string;
} }

View File

@ -1,4 +1,5 @@
import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IPmcData } from "@spt/models/eft/common/IPmcData";
import { ICustomisationStorage } from "@spt/models/eft/common/tables/ICustomisationStorage";
import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IItem } from "@spt/models/eft/common/tables/IItem";
import { EquipmentBuildType } from "@spt/models/enums/EquipmentBuildType"; import { EquipmentBuildType } from "@spt/models/enums/EquipmentBuildType";
import { MemberCategory } from "@spt/models/enums/MemberCategory"; import { MemberCategory } from "@spt/models/enums/MemberCategory";
@ -24,6 +25,7 @@ export interface ISptProfile {
achievements: Record<string, number>; achievements: Record<string, number>;
/** List of friend profile IDs */ /** List of friend profile IDs */
friends: string[]; friends: string[];
hideoutCustomisationUnlocks: ICustomisationStorage[];
} }
export class ITraderPurchaseData { export class ITraderPurchaseData {