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

172 lines
6.2 KiB
TypeScript

import { inject, injectable } from "tsyringe";
import { InventoryHelper } from "@spt/helpers/InventoryHelper";
import { IPmcData } from "@spt/models/eft/common/IPmcData";
import { Item } from "@spt/models/eft/common/tables/IItem";
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
import { ILostOnDeathConfig } from "@spt/models/spt/config/ILostOnDeathConfig";
import { ILogger } from "@spt/models/spt/utils/ILogger";
import { ConfigServer } from "@spt/servers/ConfigServer";
import { ICloner } from "@spt/utils/cloners/ICloner";
@injectable()
export class InRaidHelper
{
protected lostOnDeathConfig: ILostOnDeathConfig;
constructor(
@inject("PrimaryLogger") protected logger: ILogger,
@inject("InventoryHelper") protected inventoryHelper: InventoryHelper,
@inject("ConfigServer") protected configServer: ConfigServer,
@inject("PrimaryCloner") protected cloner: ICloner,
)
{
this.lostOnDeathConfig = this.configServer.getConfig(ConfigTypes.LOST_ON_DEATH);
}
/**
* @deprecated
* Reset the skill points earned in a raid to 0, ready for next raid
* @param profile Profile to update
*/
protected resetSkillPointsEarnedDuringRaid(profile: IPmcData): void
{
for (const skill of profile.Skills.Common)
{
skill.PointsEarnedDuringSession = 0.0;
}
}
/**
* Update a players inventory post-raid
* Remove equipped items from pre-raid
* Add new items found in raid to profile
* Store insurance items in profile
* @param sessionID Session id
* @param serverProfile Profile to update
* @param postRaidProfile Profile returned by client after a raid
*/
public setInventory(sessionID: string, serverProfile: IPmcData, postRaidProfile: IPmcData): void
{
// Store insurance (as removeItem() removes insurance also)
const insured = this.cloner.clone(serverProfile.InsuredItems);
// Remove possible equipped items from before the raid
this.inventoryHelper.removeItem(serverProfile, serverProfile.Inventory.equipment, sessionID);
this.inventoryHelper.removeItem(serverProfile, serverProfile.Inventory.questRaidItems, sessionID);
this.inventoryHelper.removeItem(serverProfile, serverProfile.Inventory.sortingTable, sessionID);
// Add the new items
serverProfile.Inventory.items = [...postRaidProfile.Inventory.items, ...serverProfile.Inventory.items];
serverProfile.Inventory.fastPanel = postRaidProfile.Inventory.fastPanel; // Quick access items bar
serverProfile.InsuredItems = insured;
}
/**
* Clear PMC inventory of all items except those that are exempt
* Used post-raid to remove items after death
* @param pmcData Player profile
* @param sessionId Session id
*/
public deleteInventory(pmcData: IPmcData, sessionId: string): void
{
// Get inventory item ids to remove from players profile
const itemIdsToDeleteFromProfile = this.getInventoryItemsLostOnDeath(pmcData).map((item) => item._id);
for (const itemIdToDelete of itemIdsToDeleteFromProfile)
{
// Items inside containers are handled as part of function
this.inventoryHelper.removeItem(pmcData, itemIdToDelete, sessionId);
}
// Remove contents of fast panel
pmcData.Inventory.fastPanel = {};
}
/**
* Get an array of items from a profile that will be lost on death
* @param pmcProfile Profile to get items from
* @returns Array of items lost on death
*/
protected getInventoryItemsLostOnDeath(pmcProfile: IPmcData): Item[]
{
const inventoryItems = pmcProfile.Inventory.items ?? [];
const equipmentRootId = pmcProfile?.Inventory?.equipment;
const questRaidItemContainerId = pmcProfile?.Inventory?.questRaidItems;
return inventoryItems.filter((item) =>
{
// Keep items flagged as kept after death
if (this.isItemKeptAfterDeath(pmcProfile, item))
{
return false;
}
// Remove normal items or quest raid items
if (item.parentId === equipmentRootId || item.parentId === questRaidItemContainerId)
{
return true;
}
// Pocket items are lost on death
if (item.slotId.startsWith("pocket"))
{
return true;
}
return false;
});
}
/**
* Does the provided items slotId mean its kept on the player after death
* @pmcData Player profile
* @itemToCheck Item to check should be kept
* @returns true if item is kept after death
*/
protected isItemKeptAfterDeath(pmcData: IPmcData, itemToCheck: Item): boolean
{
// Use pocket slotId's otherwise it deletes the root pocket item.
const pocketSlots = ["pocket1", "pocket2", "pocket3", "pocket4"];
// Base inventory items are always kept
if (!itemToCheck.parentId)
{
return true;
}
// Is item equipped on player
if (itemToCheck.parentId === pmcData.Inventory.equipment)
{
// Check slot id against config, true = delete, false = keep, undefined = delete
const discard: boolean = this.lostOnDeathConfig.equipment[itemToCheck.slotId];
if (typeof discard === "boolean" && discard === true)
{
// Lost on death
return false;
}
return true;
}
// Should we keep items in pockets on death
if (!this.lostOnDeathConfig.equipment.PocketItems && pocketSlots.includes(itemToCheck.slotId))
{
return true;
}
// Is quest item + quest item not lost on death
if (itemToCheck.parentId === pmcData.Inventory.questRaidItems && !this.lostOnDeathConfig.questItems)
{
return true;
}
// special slots are always kept after death
if (itemToCheck.slotId?.includes("SpecialSlot") && this.lostOnDeathConfig.specialSlotItems)
{
return true;
}
// All other cases item is lost
return false;
}
}