mirror of
https://github.com/sp-tarkov/server.git
synced 2025-02-12 21:50: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 { 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 { IItem } from "@spt/models/eft/common/tables/IItem";
|
||||||
import { ISptProfile } from "@spt/models/eft/profile/ISptProfile";
|
import { ISptProfile } from "@spt/models/eft/profile/ISptProfile";
|
||||||
import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData";
|
import { IValidateNicknameRequestData } from "@spt/models/eft/profile/IValidateNicknameRequestData";
|
||||||
import { AccountTypes } from "@spt/models/enums/AccountTypes";
|
import { AccountTypes } from "@spt/models/enums/AccountTypes";
|
||||||
@ -523,4 +524,13 @@ export class ProfileHelper {
|
|||||||
pocket._tpl = newPocketTpl;
|
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 postRaidProfile = request.results.profile;
|
||||||
const preRaidProfileQuestDataClone = this.cloner.clone(pmcProfile.Quests);
|
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
|
// Update inventory
|
||||||
this.inRaidHelper.setInventory(sessionId, pmcProfile, postRaidProfile, isSurvived, isTransfer);
|
this.inRaidHelper.setInventory(sessionId, pmcProfile, postRaidProfile, isSurvived, isTransfer);
|
||||||
|
|
||||||
@ -651,6 +655,12 @@ export class LocationLifecycleService {
|
|||||||
pmcProfile.Achievements = postRaidProfile.Achievements;
|
pmcProfile.Achievements = postRaidProfile.Achievements;
|
||||||
pmcProfile.Quests = this.processPostRaidQuests(postRaidProfile.Quests);
|
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()
|
// Handle edge case - must occur AFTER processPostRaidQuests()
|
||||||
this.lightkeeperQuestWorkaround(sessionId, postRaidProfile.Quests, preRaidProfileQuestDataClone, pmcProfile);
|
this.lightkeeperQuestWorkaround(sessionId, postRaidProfile.Quests, preRaidProfileQuestDataClone, pmcProfile);
|
||||||
|
|
||||||
@ -672,7 +682,7 @@ export class LocationLifecycleService {
|
|||||||
// Copy fence values to Scav
|
// Copy fence values to Scav
|
||||||
scavProfile.TradersInfo[fenceId] = pmcProfile.TradersInfo[fenceId];
|
scavProfile.TradersInfo[fenceId] = pmcProfile.TradersInfo[fenceId];
|
||||||
|
|
||||||
// Must occur after encyclopedia updated
|
// MUST occur AFTER encyclopedia updated
|
||||||
this.mergePmcAndScavEncyclopedias(pmcProfile, scavProfile);
|
this.mergePmcAndScavEncyclopedias(pmcProfile, scavProfile);
|
||||||
|
|
||||||
// Remove skill fatigue values
|
// Remove skill fatigue values
|
||||||
@ -709,6 +719,58 @@ export class LocationLifecycleService {
|
|||||||
this.handleInsuredItemLostEvent(sessionId, pmcProfile, request, locationName);
|
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
|
* 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
|
* We check for newly completed Lk quests and run them through the servers `CompleteQuest` process
|
||||||
|
Loading…
x
Reference in New Issue
Block a user