mirror of
https://github.com/sp-tarkov/server.git
synced 2025-02-12 16:10:43 -05:00
Fixed issue where player dying with a quest item would prevent the quest item from appearing in a raid again due to the profile flagging the quest item as being picked up
This commit is contained in:
parent
d2c0775b90
commit
7ba772d458
@ -1,6 +1,7 @@
|
||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
||||
import { IPmcData } from "@spt/models/eft/common/IPmcData";
|
||||
import { BanType, Common, ICounterKeyValue, IStats } from "@spt/models/eft/common/tables/IBotBase";
|
||||
import { IItem } from "@spt/models/eft/common/tables/IItem";
|
||||
import { ISptProfile } from "@spt/models/eft/profile/ISptProfile";
|
||||
import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData";
|
||||
import { AccountTypes } from "@spt/models/enums/AccountTypes";
|
||||
@ -523,4 +524,13 @@ export class ProfileHelper {
|
||||
pocket._tpl = newPocketTpl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all quest items current in the supplied profile
|
||||
* @param profile Profile to get quest items from
|
||||
* @returns Array of item objects
|
||||
*/
|
||||
public getQuestItemsInProfile(profile: IPmcData): IItem[] {
|
||||
return profile.Inventory.items.filter((item) => item.parentId === profile.Inventory.questRaidItems);
|
||||
}
|
||||
}
|
||||
|
@ -639,6 +639,10 @@ export class LocationLifecycleService {
|
||||
const postRaidProfile = request.results.profile;
|
||||
const preRaidProfileQuestDataClone = this.cloner.clone(pmcProfile.Quests);
|
||||
|
||||
// MUST occur BEFORE inventory actions occur
|
||||
// Player died, quest items presist in the post raid profile
|
||||
const lostQuestItems = this.profileHelper.getQuestItemsInProfile(postRaidProfile);
|
||||
|
||||
// Update inventory
|
||||
this.inRaidHelper.setInventory(sessionId, pmcProfile, postRaidProfile, isSurvived, isTransfer);
|
||||
|
||||
@ -651,6 +655,12 @@ export class LocationLifecycleService {
|
||||
pmcProfile.Achievements = postRaidProfile.Achievements;
|
||||
pmcProfile.Quests = this.processPostRaidQuests(postRaidProfile.Quests);
|
||||
|
||||
if (lostQuestItems.length > 0) {
|
||||
// MUST occur AFTER quests have post raid quest data has been merged
|
||||
// Player is dead + had quest items, check and fix any broken find item quests
|
||||
this.checkForAndFixPickupQuestsAfterDeath(sessionId, lostQuestItems, pmcProfile.Quests);
|
||||
}
|
||||
|
||||
// Handle edge case - must occur AFTER processPostRaidQuests()
|
||||
this.lightkeeperQuestWorkaround(sessionId, postRaidProfile.Quests, preRaidProfileQuestDataClone, pmcProfile);
|
||||
|
||||
@ -672,7 +682,7 @@ export class LocationLifecycleService {
|
||||
// Copy fence values to Scav
|
||||
scavProfile.TradersInfo[fenceId] = pmcProfile.TradersInfo[fenceId];
|
||||
|
||||
// Must occur after encyclopedia updated
|
||||
// MUST occur AFTER encyclopedia updated
|
||||
this.mergePmcAndScavEncyclopedias(pmcProfile, scavProfile);
|
||||
|
||||
// Remove skill fatigue values
|
||||
@ -709,6 +719,58 @@ export class LocationLifecycleService {
|
||||
this.handleInsuredItemLostEvent(sessionId, pmcProfile, request, locationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* On death Quest items are lost, the client does not clean up completed conditions for picking up those quest items,
|
||||
* If the completed conditions remain in the profile the player is unable to pick the item up again
|
||||
* @param sessionId Session id
|
||||
* @param lostQuestItems Quest items lost on player death
|
||||
* @param profileQuests Quest status data from player profile
|
||||
*/
|
||||
protected checkForAndFixPickupQuestsAfterDeath(
|
||||
sessionId: string,
|
||||
lostQuestItems: IItem[],
|
||||
profileQuests: IQuestStatus[],
|
||||
) {
|
||||
// Exclude completed quests
|
||||
const activeQuestIdsInProfile = profileQuests
|
||||
.filter((quest) => quest.status !== QuestStatus.Success)
|
||||
.map((status) => status.qid);
|
||||
|
||||
// Get db details of quests we found above
|
||||
const questDb = Object.values(this.databaseService.getQuests()).filter((x) =>
|
||||
activeQuestIdsInProfile.includes(x._id),
|
||||
);
|
||||
|
||||
for (const lostItem of lostQuestItems) {
|
||||
for (const quest of questDb) {
|
||||
// Find a quest in the db that has the lost item in one of its conditions that is also a 'find' type of condition
|
||||
const matchingCondition = quest.conditions.AvailableForFinish.find(
|
||||
(questCondition) =>
|
||||
questCondition.conditionType === "FindItem" && questCondition.target.includes(lostItem._tpl),
|
||||
);
|
||||
if (!matchingCondition) {
|
||||
// Quest doesnt have a matching condition
|
||||
continue;
|
||||
}
|
||||
|
||||
// We have a match, remove the condition id from profile to reset progress and let player pick item up again
|
||||
const profileQuestToUpdate = profileQuests.find((questStatus) => questStatus.qid === quest._id);
|
||||
if (!profileQuestToUpdate) {
|
||||
// Profile doesnt have a matching quest
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filter out the matching condition we found
|
||||
profileQuestToUpdate.completedConditions = profileQuestToUpdate.completedConditions.filter(
|
||||
(conditionId) => conditionId !== matchingCondition.id,
|
||||
);
|
||||
|
||||
// We found and updated the relevant quest, no more work to do with this lost item
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In 0.15 Lightkeeper quests do not give rewards in PvE, this issue also occurs in spt
|
||||
* We check for newly completed Lk quests and run them through the servers `CompleteQuest` process
|
||||
|
Loading…
x
Reference in New Issue
Block a user