mirror of
https://github.com/sp-tarkov/server.git
synced 2025-02-12 16:10:43 -05:00
Add quest production unlocks to the PMC Profile fixer service
This commit is contained in:
parent
063d1eaea8
commit
8b1a3158cb
@ -10,6 +10,7 @@ import { IPmcData } from "@spt/models/eft/common/IPmcData";
|
||||
import { Common, IQuestStatus } from "@spt/models/eft/common/tables/IBotBase";
|
||||
import { IItem } from "@spt/models/eft/common/tables/IItem";
|
||||
import { IQuest, IQuestCondition, IQuestReward } from "@spt/models/eft/common/tables/IQuest";
|
||||
import { IHideoutProduction } from "@spt/models/eft/hideout/IHideoutProduction";
|
||||
import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse";
|
||||
import { IAcceptQuestRequestData } from "@spt/models/eft/quests/IAcceptQuestRequestData";
|
||||
import { ICompleteQuestRequestData } from "@spt/models/eft/quests/ICompleteQuestRequestData";
|
||||
@ -1034,6 +1035,34 @@ export class QuestHelper {
|
||||
sessionID: string,
|
||||
response: IItemEventRouterResponse,
|
||||
): void {
|
||||
const matchingProductions = this.getRewardProductionMatch(craftUnlockReward, questDetails);
|
||||
if (matchingProductions.length !== 1) {
|
||||
this.logger.error(
|
||||
this.localisationService.getText("quest-unable_to_find_matching_hideout_production", {
|
||||
questName: questDetails.QuestName,
|
||||
matchCount: matchingProductions.length,
|
||||
}),
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Add above match to pmc profile + client response
|
||||
const matchingCraftId = matchingProductions[0]._id;
|
||||
pmcData.UnlockedInfo.unlockedProductionRecipe.push(matchingCraftId);
|
||||
response.profileChanges[sessionID].recipeUnlocked[matchingCraftId] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find hideout craft id for the specified quest reward
|
||||
* @param craftUnlockReward
|
||||
* @param questDetails
|
||||
* @returns
|
||||
*/
|
||||
public getRewardProductionMatch(
|
||||
craftUnlockReward: IQuestReward,
|
||||
questDetails: IQuest,
|
||||
): IHideoutProduction[] {
|
||||
// Get hideout crafts and find those that match by areatype/required level/end product tpl - hope for just one match
|
||||
const craftingRecipes = this.databaseService.getHideout().production.recipes;
|
||||
|
||||
@ -1055,23 +1084,9 @@ export class QuestHelper {
|
||||
matchingProductions = matchingProductions.filter((prod) =>
|
||||
prod.requirements.some((requirement) => requirement.questId === questDetails._id),
|
||||
);
|
||||
|
||||
if (matchingProductions.length !== 1) {
|
||||
this.logger.error(
|
||||
this.localisationService.getText("quest-unable_to_find_matching_hideout_production", {
|
||||
questName: questDetails.QuestName,
|
||||
matchCount: matchingProductions.length,
|
||||
}),
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add above match to pmc profile + client response
|
||||
const matchingCraftId = matchingProductions[0]._id;
|
||||
pmcData.UnlockedInfo.unlockedProductionRecipe.push(matchingCraftId);
|
||||
response.profileChanges[sessionID].recipeUnlocked[matchingCraftId] = true;
|
||||
return matchingProductions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,9 +2,11 @@ import { HideoutHelper } from "@spt/helpers/HideoutHelper";
|
||||
import { InventoryHelper } from "@spt/helpers/InventoryHelper";
|
||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
||||
import { QuestHelper } from "@spt/helpers/QuestHelper";
|
||||
import { TraderHelper } from "@spt/helpers/TraderHelper";
|
||||
import { IPmcData } from "@spt/models/eft/common/IPmcData";
|
||||
import { IBonus, IHideoutSlot } from "@spt/models/eft/common/tables/IBotBase";
|
||||
import { IQuest, IQuestReward } from "@spt/models/eft/common/tables/IQuest";
|
||||
import { IPmcDataRepeatableQuest, IRepeatableQuest } from "@spt/models/eft/common/tables/IRepeatableQuests";
|
||||
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
||||
import { IStageBonus } from "@spt/models/eft/hideout/IHideoutArea";
|
||||
@ -12,6 +14,8 @@ import { IEquipmentBuild, IMagazineBuild, ISptProfile, IWeaponBuild } from "@spt
|
||||
import { BonusType } from "@spt/models/enums/BonusType";
|
||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||
import { HideoutAreas } from "@spt/models/enums/HideoutAreas";
|
||||
import { QuestRewardType } from "@spt/models/enums/QuestRewardType";
|
||||
import { QuestStatus } from "@spt/models/enums/QuestStatus";
|
||||
import { ICoreConfig } from "@spt/models/spt/config/ICoreConfig";
|
||||
import { IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
@ -45,6 +49,7 @@ export class ProfileFixerService {
|
||||
@inject("HashUtil") protected hashUtil: HashUtil,
|
||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||
@inject("PrimaryCloner") protected cloner: ICloner,
|
||||
@inject("QuestHelper") protected questHelper: QuestHelper,
|
||||
) {
|
||||
this.coreConfig = this.configServer.getConfig(ConfigTypes.CORE);
|
||||
this.ragfairConfig = this.configServer.getConfig(ConfigTypes.RAGFAIR);
|
||||
@ -58,6 +63,7 @@ export class ProfileFixerService {
|
||||
this.removeDanglingConditionCounters(pmcProfile);
|
||||
this.removeDanglingTaskConditionCounters(pmcProfile);
|
||||
this.removeOrphanedQuests(pmcProfile);
|
||||
this.verifyQuestProductionUnlocks(pmcProfile);
|
||||
|
||||
if (pmcProfile.Hideout) {
|
||||
this.addHideoutEliteSlots(pmcProfile);
|
||||
@ -264,6 +270,72 @@ export class ProfileFixerService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that all quest production unlocks have been applied to the PMC Profile
|
||||
* @param pmcProfile The profile to validate quest productions for
|
||||
*/
|
||||
protected verifyQuestProductionUnlocks(pmcProfile: IPmcData): void {
|
||||
const start = performance.now();
|
||||
|
||||
const quests = this.databaseService.getQuests();
|
||||
const profileQuests = pmcProfile.Quests;
|
||||
|
||||
for (const profileQuest of profileQuests)
|
||||
{
|
||||
const quest = quests[profileQuest.qid];
|
||||
|
||||
// For started or successful quests, check for unlocks in the `Started` rewards
|
||||
if (profileQuest.status == QuestStatus.Started || profileQuest.status == QuestStatus.Success)
|
||||
{
|
||||
const productionRewards = quest.rewards.Started?.filter(reward => reward.type == QuestRewardType.PRODUCTIONS_SCHEME);
|
||||
productionRewards?.forEach(reward => this.verifyQuestProductionUnlock(pmcProfile, reward, quest));
|
||||
}
|
||||
|
||||
// For successful quests, check for unlocks in the `Success` rewards
|
||||
if (profileQuest.status == QuestStatus.Success)
|
||||
{
|
||||
const productionRewards = quest.rewards.Success?.filter(reward => reward.type == QuestRewardType.PRODUCTIONS_SCHEME);
|
||||
productionRewards?.forEach(reward => this.verifyQuestProductionUnlock(pmcProfile, reward, quest));
|
||||
}
|
||||
}
|
||||
|
||||
const validateTime = performance.now() - start
|
||||
this.logger.debug(`Quest Production Unlock validation took: ${validateTime.toFixed(2)}ms`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the given profile has the given quest reward production scheme unlocked, and add it if not
|
||||
* @param pmcProfile Profile to check
|
||||
* @param productionUnlockReward The quest reward to validate
|
||||
* @param questDetails The quest the reward belongs to
|
||||
* @returns
|
||||
*/
|
||||
protected verifyQuestProductionUnlock(
|
||||
pmcProfile: IPmcData,
|
||||
productionUnlockReward: IQuestReward,
|
||||
questDetails: IQuest
|
||||
): void {
|
||||
const matchingProductions = this.questHelper.getRewardProductionMatch(productionUnlockReward, questDetails);
|
||||
if (matchingProductions.length !== 1) {
|
||||
this.logger.error(
|
||||
this.localisationService.getText("quest-unable_to_find_matching_hideout_production", {
|
||||
questName: questDetails.QuestName,
|
||||
matchCount: matchingProductions.length,
|
||||
}),
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Add above match to pmc profile
|
||||
const matchingProductionId = matchingProductions[0]._id;
|
||||
if (!pmcProfile.UnlockedInfo.unlockedProductionRecipe.includes(matchingProductionId))
|
||||
{
|
||||
pmcProfile.UnlockedInfo.unlockedProductionRecipe.push(matchingProductionId);
|
||||
this.logger.debug(`Added production ${matchingProductionId} to unlocked production recipes for ${questDetails.QuestName}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the profile has elite Hideout Managment skill, add the additional slots from globals
|
||||
* NOTE: This seems redundant, but we will leave it here just incase.
|
||||
|
Loading…
x
Reference in New Issue
Block a user