Update mod example types

This commit is contained in:
Dev 2024-03-16 16:22:32 +00:00
parent 393f9d4fc4
commit 61bb4a02f6
936 changed files with 10128 additions and 4608 deletions

View File

@ -1,14 +1,24 @@
import { ClientLogController } from "@spt-aki/controllers/ClientLogController";
import { ModLoadOrder } from "@spt-aki/loaders/ModLoadOrder";
import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData";
import { IClientLogRequest } from "@spt-aki/models/spt/logging/IClientLogRequest";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
/** Handle client logging related events */
export declare class ClientLogCallbacks {
protected httpResponse: HttpResponseUtil;
protected clientLogController: ClientLogController;
constructor(httpResponse: HttpResponseUtil, clientLogController: ClientLogController);
protected configServer: ConfigServer;
protected localisationService: LocalisationService;
protected modLoadOrder: ModLoadOrder;
constructor(httpResponse: HttpResponseUtil, clientLogController: ClientLogController, configServer: ConfigServer, localisationService: LocalisationService, modLoadOrder: ModLoadOrder);
/**
* Handle /singleplayer/log
*/
clientLog(url: string, info: IClientLogRequest, sessionID: string): INullResponseData;
/**
* Handle /singleplayer/release
*/
releaseNotes(): string;
}

View File

@ -9,5 +9,11 @@ export declare class ItemEventCallbacks {
protected itemEventRouter: ItemEventRouter;
constructor(httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter);
handleEvents(url: string, info: IItemEventRouterRequest, sessionID: string): IGetBodyResponseData<IItemEventRouterResponse>;
/**
* Return true if the passed in list of warnings contains critical issues
* @param warnings The list of warnings to check for critical errors
* @returns
*/
private isCriticalError;
protected getErrorCode(warnings: Warning[]): number;
}

View File

@ -1,16 +1,14 @@
import { MatchController } from "@spt-aki/controllers/MatchController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { IGetBodyResponseData } from "@spt-aki/models/eft/httpResponse/IGetBodyResponseData";
import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData";
import { IAcceptGroupInviteRequest } from "@spt-aki/models/eft/match/IAcceptGroupInviteRequest";
import { IAcceptGroupInviteResponse } from "@spt-aki/models/eft/match/IAcceptGroupInviteResponse";
import { ICancelGroupInviteRequest } from "@spt-aki/models/eft/match/ICancelGroupInviteRequest";
import { ICreateGroupRequestData } from "@spt-aki/models/eft/match/ICreateGroupRequestData";
import { IDeclineGroupInviteRequest } from "@spt-aki/models/eft/match/IDeclineGroupInviteRequest";
import { IEndOfflineRaidRequestData } from "@spt-aki/models/eft/match/IEndOfflineRaidRequestData";
import { IGetGroupStatusRequestData } from "@spt-aki/models/eft/match/IGetGroupStatusRequestData";
import { IGetGroupStatusResponse } from "@spt-aki/models/eft/match/IGetGroupStatusResponse";
import { IGetProfileRequestData } from "@spt-aki/models/eft/match/IGetProfileRequestData";
import { IGetRaidConfigurationRequestData } from "@spt-aki/models/eft/match/IGetRaidConfigurationRequestData";
import { IJoinMatchRequestData } from "@spt-aki/models/eft/match/IJoinMatchRequestData";
import { IJoinMatchResult } from "@spt-aki/models/eft/match/IJoinMatchResult";
@ -39,6 +37,8 @@ export declare class MatchCallbacks {
sendGroupInvite(url: string, info: ISendGroupInviteRequest, sessionID: string): IGetBodyResponseData<string>;
/** Handle client/match/group/invite/accept */
acceptGroupInvite(url: string, info: IAcceptGroupInviteRequest, sessionID: string): IGetBodyResponseData<IAcceptGroupInviteResponse[]>;
/** Handle client/match/group/invite/decline */
declineGroupInvite(url: string, info: IDeclineGroupInviteRequest, sessionID: string): IGetBodyResponseData<any>;
/** Handle client/match/group/invite/cancel */
cancelGroupInvite(url: string, info: ICancelGroupInviteRequest, sessionID: string): IGetBodyResponseData<boolean>;
/** Handle client/match/group/transfer */
@ -47,8 +47,6 @@ export declare class MatchCallbacks {
cancelAllGroupInvite(url: string, info: any, sessionID: string): INullResponseData;
/** @deprecated - not called on raid start/end or game start/exit */
putMetrics(url: string, info: IPutMetricsRequestData, sessionID: string): INullResponseData;
/** Handle raid/profile/list */
getProfile(url: string, info: IGetProfileRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
serverAvailable(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<boolean>;
/** Handle match/group/start_game */
joinMatch(url: string, info: IJoinMatchRequestData, sessionID: string): IGetBodyResponseData<IJoinMatchResult>;
@ -60,8 +58,6 @@ export declare class MatchCallbacks {
* @returns
*/
getGroupStatus(url: string, info: IGetGroupStatusRequestData, sessionID: string): IGetBodyResponseData<IGetGroupStatusResponse>;
/** Handle client/match/group/create */
createGroup(url: string, info: ICreateGroupRequestData, sessionID: string): IGetBodyResponseData<any>;
/** Handle client/match/group/delete */
deleteGroup(url: string, info: any, sessionID: string): INullResponseData;
leaveGroup(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<boolean>;

View File

@ -3,11 +3,9 @@ import { LootGenerator } from "@spt-aki/generators/LootGenerator";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { ICreateGroupRequestData } from "@spt-aki/models/eft/match/ICreateGroupRequestData";
import { IEndOfflineRaidRequestData } from "@spt-aki/models/eft/match/IEndOfflineRaidRequestData";
import { IGetGroupStatusRequestData } from "@spt-aki/models/eft/match/IGetGroupStatusRequestData";
import { IGetGroupStatusResponse } from "@spt-aki/models/eft/match/IGetGroupStatusResponse";
import { IGetProfileRequestData } from "@spt-aki/models/eft/match/IGetProfileRequestData";
import { IGetRaidConfigurationRequestData } from "@spt-aki/models/eft/match/IGetRaidConfigurationRequestData";
import { IJoinMatchRequestData } from "@spt-aki/models/eft/match/IJoinMatchRequestData";
import { IJoinMatchResult } from "@spt-aki/models/eft/match/IJoinMatchResult";
@ -48,10 +46,6 @@ export declare class MatchController {
protected pmcConfig: IPmcConfig;
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, randomUtil: RandomUtil, hashUtil: HashUtil, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, botGenerationCacheService: BotGenerationCacheService, mailSendService: MailSendService, lootGenerator: LootGenerator, applicationContext: ApplicationContext);
getEnabled(): boolean;
/** Handle raid/profile/list */
getProfile(info: IGetProfileRequestData): IPmcData[];
/** Handle client/match/group/create */
createGroup(sessionID: string, info: ICreateGroupRequestData): any;
/** Handle client/match/group/delete */
deleteGroup(info: any): void;
/** Handle match/group/start_game */

View File

@ -1,3 +1,4 @@
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
import { RepairHelper } from "@spt-aki/helpers/RepairHelper";
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
@ -20,8 +21,9 @@ export declare class RepairController {
protected paymentService: PaymentService;
protected repairHelper: RepairHelper;
protected repairService: RepairService;
protected profileHelper: ProfileHelper;
protected repairConfig: IRepairConfig;
constructor(logger: ILogger, eventOutputHolder: EventOutputHolder, databaseServer: DatabaseServer, questHelper: QuestHelper, traderHelper: TraderHelper, paymentService: PaymentService, repairHelper: RepairHelper, repairService: RepairService);
constructor(logger: ILogger, eventOutputHolder: EventOutputHolder, databaseServer: DatabaseServer, questHelper: QuestHelper, traderHelper: TraderHelper, paymentService: PaymentService, repairHelper: RepairHelper, repairService: RepairService, profileHelper: ProfileHelper);
/**
* Handle TraderRepair event
* Repair with trader

View File

@ -1,7 +1,6 @@
import { RepeatableQuestGenerator } from "@spt-aki/generators/RepeatableQuestGenerator";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
import { RagfairServerHelper } from "@spt-aki/helpers/RagfairServerHelper";
import { RepeatableQuestHelper } from "@spt-aki/helpers/RepeatableQuestHelper";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
@ -31,7 +30,6 @@ export declare class RepeatableQuestController {
protected jsonUtil: JsonUtil;
protected profileHelper: ProfileHelper;
protected profileFixerService: ProfileFixerService;
protected ragfairServerHelper: RagfairServerHelper;
protected eventOutputHolder: EventOutputHolder;
protected paymentService: PaymentService;
protected objectId: ObjectId;
@ -40,7 +38,7 @@ export declare class RepeatableQuestController {
protected questHelper: QuestHelper;
protected configServer: ConfigServer;
protected questConfig: IQuestConfig;
constructor(logger: ILogger, databaseServer: DatabaseServer, timeUtil: TimeUtil, randomUtil: RandomUtil, httpResponse: HttpResponseUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, paymentService: PaymentService, objectId: ObjectId, repeatableQuestGenerator: RepeatableQuestGenerator, repeatableQuestHelper: RepeatableQuestHelper, questHelper: QuestHelper, configServer: ConfigServer);
constructor(logger: ILogger, databaseServer: DatabaseServer, timeUtil: TimeUtil, randomUtil: RandomUtil, httpResponse: HttpResponseUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, eventOutputHolder: EventOutputHolder, paymentService: PaymentService, objectId: ObjectId, repeatableQuestGenerator: RepeatableQuestGenerator, repeatableQuestHelper: RepeatableQuestHelper, questHelper: QuestHelper, configServer: ConfigServer);
/**
* Handle client/repeatalbeQuests/activityPeriods
* Returns an array of objects in the format of repeatable quests to the client.

View File

@ -3,14 +3,18 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { TraderAssortHelper } from "@spt-aki/helpers/TraderAssortHelper";
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
import { ITraderAssort, ITraderBase } from "@spt-aki/models/eft/common/tables/ITrader";
import { ITraderConfig } from "@spt-aki/models/spt/config/ITraderConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { FenceService } from "@spt-aki/services/FenceService";
import { TraderAssortService } from "@spt-aki/services/TraderAssortService";
import { TraderPurchasePersisterService } from "@spt-aki/services/TraderPurchasePersisterService";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class TraderController {
protected logger: ILogger;
protected timeUtil: TimeUtil;
protected databaseServer: DatabaseServer;
protected traderAssortHelper: TraderAssortHelper;
protected profileHelper: ProfileHelper;
@ -20,10 +24,12 @@ export declare class TraderController {
protected fenceService: FenceService;
protected fenceBaseAssortGenerator: FenceBaseAssortGenerator;
protected jsonUtil: JsonUtil;
constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, traderAssortService: TraderAssortService, traderPurchasePersisterService: TraderPurchasePersisterService, fenceService: FenceService, fenceBaseAssortGenerator: FenceBaseAssortGenerator, jsonUtil: JsonUtil);
protected configServer: ConfigServer;
protected traderConfig: ITraderConfig;
constructor(logger: ILogger, timeUtil: TimeUtil, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, traderAssortService: TraderAssortService, traderPurchasePersisterService: TraderPurchasePersisterService, fenceService: FenceService, fenceBaseAssortGenerator: FenceBaseAssortGenerator, jsonUtil: JsonUtil, configServer: ConfigServer);
/**
* Runs when onLoad event is fired
* Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
* Iterate over traders, ensure a pristine copy of their assorts is stored in traderAssortService
* Store timestamp of next assort refresh in nextResupply property of traders .base object
*/
load(): void;

View File

@ -89,8 +89,9 @@ export declare class BotLootGenerator {
* @param itemToAddTemplate Db template of item to check
* @param itemToAddChildrenTo Item to add children to
* @param isPmc Is the item being generated for a pmc (affects money/ammo stack sizes)
* @param botRole role bot has that owns item
*/
protected addRequiredChildItemsToParent(itemToAddTemplate: ITemplateItem, itemToAddChildrenTo: Item[], isPmc: boolean): void;
protected addRequiredChildItemsToParent(itemToAddTemplate: ITemplateItem, itemToAddChildrenTo: Item[], isPmc: boolean, botRole: string): void;
/**
* Add generated weapons to inventory as loot
* @param botInventory inventory to add preset to
@ -118,11 +119,11 @@ export declare class BotLootGenerator {
protected itemHasReachedSpawnLimit(itemTemplate: ITemplateItem, botRole: string, itemSpawnLimits: IItemSpawnLimitSettings): boolean;
/**
* Randomise the stack size of a money object, uses different values for pmc or scavs
* @param isPmc Is money on a PMC bot
* @param botRole Role bot has that has money stack
* @param itemTemplate item details from db
* @param moneyItem Money item to randomise
*/
protected randomiseMoneyStackSize(isPmc: boolean, itemTemplate: ITemplateItem, moneyItem: Item): void;
protected randomiseMoneyStackSize(botRole: string, itemTemplate: ITemplateItem, moneyItem: Item): void;
/**
* Randomise the size of an ammo stack
* @param isPmc Is ammo on a PMC bot

View File

@ -1,54 +1,34 @@
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { RepeatableQuestRewardGenerator } from "@spt-aki/generators/RepeatableQuestRewardGenerator";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { RagfairServerHelper } from "@spt-aki/helpers/RagfairServerHelper";
import { RepeatableQuestHelper } from "@spt-aki/helpers/RepeatableQuestHelper";
import { Exit } from "@spt-aki/models/eft/common/ILocationBase";
import { TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase";
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
import { IQuestCondition, IQuestConditionCounterCondition, IQuestReward, IQuestRewards } from "@spt-aki/models/eft/common/tables/IQuest";
import { IQuestCondition, IQuestConditionCounterCondition } from "@spt-aki/models/eft/common/tables/IQuest";
import { IRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests";
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
import { IBaseQuestConfig, IBossInfo, IEliminationConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig";
import { IBossInfo, IEliminationConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig";
import { IQuestTypePool } from "@spt-aki/models/spt/repeatable/IQuestTypePool";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { EventOutputHolder } from "@spt-aki/routers/EventOutputHolder";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemFilterService } from "@spt-aki/services/ItemFilterService";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { PaymentService } from "@spt-aki/services/PaymentService";
import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { MathUtil } from "@spt-aki/utils/MathUtil";
import { ObjectId } from "@spt-aki/utils/ObjectId";
import { ProbabilityObjectArray, RandomUtil } from "@spt-aki/utils/RandomUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class RepeatableQuestGenerator {
protected timeUtil: TimeUtil;
protected logger: ILogger;
protected randomUtil: RandomUtil;
protected httpResponse: HttpResponseUtil;
protected mathUtil: MathUtil;
protected jsonUtil: JsonUtil;
protected databaseServer: DatabaseServer;
protected itemHelper: ItemHelper;
protected presetHelper: PresetHelper;
protected profileHelper: ProfileHelper;
protected profileFixerService: ProfileFixerService;
protected handbookHelper: HandbookHelper;
protected ragfairServerHelper: RagfairServerHelper;
protected eventOutputHolder: EventOutputHolder;
protected localisationService: LocalisationService;
protected paymentService: PaymentService;
protected objectId: ObjectId;
protected itemFilterService: ItemFilterService;
protected repeatableQuestHelper: RepeatableQuestHelper;
protected repeatableQuestRewardGenerator: RepeatableQuestRewardGenerator;
protected configServer: ConfigServer;
protected questConfig: IQuestConfig;
constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, httpResponse: HttpResponseUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, handbookHelper: HandbookHelper, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, localisationService: LocalisationService, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, repeatableQuestHelper: RepeatableQuestHelper, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, localisationService: LocalisationService, objectId: ObjectId, repeatableQuestHelper: RepeatableQuestHelper, repeatableQuestRewardGenerator: RepeatableQuestRewardGenerator, configServer: ConfigServer);
/**
* This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json).
* It randomly draws a quest type (currently Elimination, Completion or Exploration) as well as a trader who is providing the quest
@ -144,71 +124,6 @@ export declare class RepeatableQuestGenerator {
* @returns {object} Exit condition
*/
protected generateExplorationExitCondition(exit: Exit): IQuestConditionCounterCondition;
/**
* Generate the reward for a mission. A reward can consist of
* - Experience
* - Money
* - Items
* - Trader Reputation
*
* The reward is dependent on the player level as given by the wiki. The exact mapping of pmcLevel to
* experience / money / items / trader reputation can be defined in QuestConfig.js
*
* There's also a random variation of the reward the spread of which can be also defined in the config.
*
* Additionally, a scaling factor w.r.t. quest difficulty going from 0.2...1 can be used
*
* @param {integer} pmcLevel player's level
* @param {number} difficulty a reward scaling factor from 0.2 to 1
* @param {string} traderId the trader for reputation gain (and possible in the future filtering of reward item type based on trader)
* @param {object} repeatableConfig The configuration for the repeatable kind (daily, weekly) as configured in QuestConfig for the requested quest
* @returns {object} object of "Reward"-type that can be given for a repeatable mission
*/
protected generateReward(pmcLevel: number, difficulty: number, traderId: string, repeatableConfig: IRepeatableQuestConfig, questConfig: IBaseQuestConfig): IQuestRewards;
protected addMoneyReward(traderId: string, rewards: IQuestRewards, rewardRoubles: number, rewardIndex: number): void;
protected calculateAmmoStackSizeThatFitsBudget(itemSelected: ITemplateItem, roublesBudget: number, rewardNumItems: number): number;
/**
* Should reward item have stack size increased (25% chance)
* @param item Item to possibly increase stack size of
* @param maxRoublePriceToStack Maximum rouble price an item can be to still be chosen for stacking
* @returns True if it should
*/
protected canIncreaseRewardItemStackSize(item: ITemplateItem, maxRoublePriceToStack: number): boolean;
/**
* Get a randomised number a reward items stack size should be based on its handbook price
* @param item Reward item to get stack size for
* @returns Stack size value
*/
protected getRandomisedRewardItemStackSizeByPrice(item: ITemplateItem): number;
/**
* Select a number of items that have a colelctive value of the passed in parameter
* @param repeatableConfig Config
* @param roublesBudget Total value of items to return
* @returns Array of reward items that fit budget
*/
protected chooseRewardItemsWithinBudget(repeatableConfig: IRepeatableQuestConfig, roublesBudget: number, traderId: string): ITemplateItem[];
/**
* Helper to create a reward item structured as required by the client
*
* @param {string} tpl ItemId of the rewarded item
* @param {integer} value Amount of items to give
* @param {integer} index All rewards will be appended to a list, for unknown reasons the client wants the index
* @returns {object} Object of "Reward"-item-type
*/
protected generateRewardItem(tpl: string, value: number, index: number, preset?: Item[]): IQuestReward;
/**
* Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
* @param repeatableQuestConfig Config file
* @returns List of rewardable items [[_tpl, itemTemplate],...]
*/
protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig, traderId: string): [string, ITemplateItem][];
/**
* Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
* or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
* @param {string} tpl template id of item to check
* @returns True if item is valid reward
*/
protected isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig, itemBaseWhitelist: string[]): boolean;
/**
* Generates the base object of quest type format given as templates in assets/database/templates/repeatableQuests.json
* The templates include Elimination, Completion and Extraction quest types

View File

@ -0,0 +1,106 @@
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
import { IQuestReward, IQuestRewards } from "@spt-aki/models/eft/common/tables/IQuest";
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
import { IBaseQuestConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemFilterService } from "@spt-aki/services/ItemFilterService";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { MathUtil } from "@spt-aki/utils/MathUtil";
import { ObjectId } from "@spt-aki/utils/ObjectId";
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
export declare class RepeatableQuestRewardGenerator {
protected logger: ILogger;
protected randomUtil: RandomUtil;
protected mathUtil: MathUtil;
protected jsonUtil: JsonUtil;
protected databaseServer: DatabaseServer;
protected itemHelper: ItemHelper;
protected presetHelper: PresetHelper;
protected handbookHelper: HandbookHelper;
protected localisationService: LocalisationService;
protected objectId: ObjectId;
protected itemFilterService: ItemFilterService;
protected seasonalEventService: SeasonalEventService;
protected configServer: ConfigServer;
protected questConfig: IQuestConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer);
/**
* Generate the reward for a mission. A reward can consist of
* - Experience
* - Money
* - Items
* - Trader Reputation
*
* The reward is dependent on the player level as given by the wiki. The exact mapping of pmcLevel to
* experience / money / items / trader reputation can be defined in QuestConfig.js
*
* There's also a random variation of the reward the spread of which can be also defined in the config.
*
* Additionally, a scaling factor w.r.t. quest difficulty going from 0.2...1 can be used
*
* @param {integer} pmcLevel player's level
* @param {number} difficulty a reward scaling factor from 0.2 to 1
* @param {string} traderId the trader for reputation gain (and possible in the future filtering of reward item type based on trader)
* @param {object} repeatableConfig The configuration for the repeatable kind (daily, weekly) as configured in QuestConfig for the requested quest
* @returns {object} object of "Reward"-type that can be given for a repeatable mission
*/
generateReward(pmcLevel: number, difficulty: number, traderId: string, repeatableConfig: IRepeatableQuestConfig, questConfig: IBaseQuestConfig): IQuestRewards;
/**
* @param rewardItems List of reward items to filter
* @param roublesBudget The budget remaining for rewards
* @param minPrice The minimum priced item to include
* @returns True if any items remain in `rewardItems`, false otherwise
*/
protected filterRewardPoolWithinBudget(rewardItems: ITemplateItem[], roublesBudget: number, minPrice: number): boolean;
/**
* Get a randomised number a reward items stack size should be based on its handbook price
* @param item Reward item to get stack size for
* @returns Stack size value
*/
protected getRandomisedRewardItemStackSizeByPrice(item: ITemplateItem): number;
/**
* Should reward item have stack size increased (25% chance)
* @param item Item to possibly increase stack size of
* @param maxRoublePriceToStack Maximum rouble price an item can be to still be chosen for stacking
* @returns True if it should
*/
protected canIncreaseRewardItemStackSize(item: ITemplateItem, maxRoublePriceToStack: number): boolean;
protected calculateAmmoStackSizeThatFitsBudget(itemSelected: ITemplateItem, roublesBudget: number, rewardNumItems: number): number;
/**
* Select a number of items that have a colelctive value of the passed in parameter
* @param repeatableConfig Config
* @param roublesBudget Total value of items to return
* @returns Array of reward items that fit budget
*/
protected chooseRewardItemsWithinBudget(repeatableConfig: IRepeatableQuestConfig, roublesBudget: number, traderId: string): ITemplateItem[];
/**
* Helper to create a reward item structured as required by the client
*
* @param {string} tpl ItemId of the rewarded item
* @param {integer} value Amount of items to give
* @param {integer} index All rewards will be appended to a list, for unknown reasons the client wants the index
* @returns {object} Object of "Reward"-item-type
*/
protected generateRewardItem(tpl: string, value: number, index: number, preset?: Item[]): IQuestReward;
/**
* Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
* @param repeatableQuestConfig Config file
* @returns List of rewardable items [[_tpl, itemTemplate],...]
*/
getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig, traderId: string): [string, ITemplateItem][];
/**
* Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
* or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
* @param {string} tpl template id of item to check
* @returns True if item is valid reward
*/
protected isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig, itemBaseWhitelist: string[]): boolean;
protected addMoneyReward(traderId: string, rewards: IQuestRewards, rewardRoubles: number, rewardIndex: number): void;
}

View File

@ -10,6 +10,7 @@ import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemFilterService } from "@spt-aki/services/ItemFilterService";
import { RagfairPriceService } from "@spt-aki/services/RagfairPriceService";
import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
@ -25,12 +26,13 @@ export declare class ScavCaseRewardGenerator {
protected presetHelper: PresetHelper;
protected databaseServer: DatabaseServer;
protected ragfairPriceService: RagfairPriceService;
protected seasonalEventService: SeasonalEventService;
protected itemFilterService: ItemFilterService;
protected configServer: ConfigServer;
protected scavCaseConfig: IScavCaseConfig;
protected dbItemsCache: ITemplateItem[];
protected dbAmmoItemsCache: ITemplateItem[];
constructor(logger: ILogger, randomUtil: RandomUtil, jsonUtil: JsonUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, jsonUtil: JsonUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, seasonalEventService: SeasonalEventService, itemFilterService: ItemFilterService, configServer: ConfigServer);
/**
* Create an array of rewards that will be given to the player upon completing their scav case build
* @param recipeId recipe of the scav case craft

View File

@ -3,6 +3,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig";
import { IWeatherConfig } from "@spt-aki/models/spt/config/IWeatherConfig";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { GiftService } from "@spt-aki/services/GiftService";
import { MailSendService } from "@spt-aki/services/MailSendService";
@ -14,6 +15,7 @@ export declare class SptDialogueChatBot implements IDialogueChatBot {
protected giftService: GiftService;
protected configServer: ConfigServer;
protected coreConfig: ICoreConfig;
protected weatherConfig: IWeatherConfig;
constructor(profileHelper: ProfileHelper, randomUtil: RandomUtil, mailSendService: MailSendService, giftService: GiftService, configServer: ConfigServer);
getChatBot(): IUserDialogInfo;
/**

View File

@ -19,6 +19,7 @@ import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { PlayerService } from "@spt-aki/services/PlayerService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class HideoutHelper {
protected logger: ILogger;
@ -33,6 +34,7 @@ export declare class HideoutHelper {
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected configServer: ConfigServer;
protected jsonUtil: JsonUtil;
static bitcoinFarm: string;
static bitcoinProductionId: string;
static waterCollector: string;
@ -40,7 +42,7 @@ export declare class HideoutHelper {
static expeditionaryFuelTank: string;
static maxSkillPoint: number;
protected hideoutConfig: IHideoutConfig;
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, localisationService: LocalisationService, itemHelper: ItemHelper, configServer: ConfigServer);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, localisationService: LocalisationService, itemHelper: ItemHelper, configServer: ConfigServer, jsonUtil: JsonUtil);
/**
* Add production to profiles' Hideout.Production array
* @param pmcData Profile to add production to
@ -82,6 +84,16 @@ export declare class HideoutHelper {
waterCollectorHasFilter: boolean;
};
protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
/**
* Iterate over productions and update their progress timers
* @param pmcData Profile to check for productions and update
* @param hideoutProperties Hideout properties
*/
protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
btcFarmCGs: number;
isGeneratorOn: boolean;
waterCollectorHasFilter: boolean;
}): void;
/**
* Update progress timer for water collector
* @param pmcData profile to update
@ -93,16 +105,6 @@ export declare class HideoutHelper {
isGeneratorOn: boolean;
waterCollectorHasFilter: boolean;
}): void;
/**
* Iterate over productions and update their progress timers
* @param pmcData Profile to check for productions and update
* @param hideoutProperties Hideout properties
*/
protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
btcFarmCGs: number;
isGeneratorOn: boolean;
waterCollectorHasFilter: boolean;
}): void;
/**
* Update a productions progress value based on the amount of time that has passed
* @param pmcData Player profile
@ -148,6 +150,13 @@ export declare class HideoutHelper {
*/
protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData, isGeneratorOn: boolean): void;
protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
/**
* Get craft time and make adjustments to account for dev profile + crafting skill level
* @param pmcData Player profile making craft
* @param recipeId Recipe being crafted
* @returns
*/
protected getAdjustedCraftTimeWithSkills(pmcData: IPmcData, recipeId: string): number;
/**
* Adjust water filter objects resourceValue or delete when they reach 0 resource
* @param waterFilterArea water filter area to update
@ -163,9 +172,9 @@ export declare class HideoutHelper {
* @param totalProductionTime Total time collecting water
* @param productionProgress how far water collector has progressed
* @param baseFilterDrainRate Base drain rate
* @returns
* @returns drain rate (adjusted)
*/
protected adjustWaterFilterDrainRate(secondsSinceServerTick: number, totalProductionTime: number, productionProgress: number, baseFilterDrainRate: number): number;
protected getAdjustWaterFilterDrainRate(secondsSinceServerTick: number, totalProductionTime: number, productionProgress: number, baseFilterDrainRate: number): number;
/**
* Get the water filter drain rate based on hideout bonues player has
* @param pmcData Player profile
@ -185,7 +194,7 @@ export declare class HideoutHelper {
* @param resourceUnitsConsumed
* @returns Upd
*/
protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number, isFoundInRaid: boolean): Upd;
protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData, isGeneratorOn: boolean): void;
protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
/**
@ -225,7 +234,7 @@ export declare class HideoutHelper {
* @param productionTime Time to complete hideout craft in seconds
* @returns Adjusted craft time in seconds
*/
protected getCraftingSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number): number;
getCraftingSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number): number;
isProduction(productive: Productive): productive is Production;
/**
* Gather crafted BTC from hideout area and add to inventory

View File

@ -74,9 +74,9 @@ export declare class InventoryHelper {
* @param itemWithChildren An item
* @param foundInRaid Item was found in raid
*/
private setFindInRaidStatusForItem;
protected setFindInRaidStatusForItem(itemWithChildren: Item[], foundInRaid: boolean): void;
/**
* Remove properties from a Upd object used by a trader/ragfair
* Remove properties from a Upd object used by a trader/ragfair that are unnecessary to a player
* @param upd Object to update
*/
protected removeTraderRagfairRelatedUpdProperties(upd: Upd): void;
@ -106,8 +106,9 @@ export declare class InventoryHelper {
* @param containerFS2D Container grid to add item to
* @param itemWithChildren Item to add to grid
* @param containerId Id of the container we're fitting item into
* @param desiredSlotId slot id value to use, default is "hideout"
*/
placeItemInContainer(containerFS2D: number[][], itemWithChildren: Item[], containerId: string): void;
placeItemInContainer(containerFS2D: number[][], itemWithChildren: Item[], containerId: string, desiredSlotId?: string): void;
/**
* Find a location to place an item into inventory and place it
* @param stashFS2D 2-dimensional representation of the container slots
@ -119,9 +120,10 @@ export declare class InventoryHelper {
*/
protected placeItemInInventory(stashFS2D: number[][], sortingTableFS2D: number[][], itemWithChildren: Item[], playerInventory: Inventory, useSortingTable: boolean, output: IItemEventRouterResponse): void;
/**
* Split an items stack size based on its StackMaxSize value
* @param assortItems Items to add to inventory
* @param requestItem Details of purchased item to add to inventory
* @param result Array split stacks are added to
* @param result Array split stacks are appended to
*/
protected splitStackIntoSmallerChildStacks(assortItems: Item[], requestItem: AddItem, result: IAddItemTempObject[]): void;
/**
@ -134,13 +136,48 @@ export declare class InventoryHelper {
* @param output OPTIONAL - IItemEventRouterResponse
*/
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): void;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): void;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
/**
* Delete desired item from a player profiles mail
* @param sessionId Session id
* @param removeRequest Remove request
* @param output OPTIONAL - IItemEventRouterResponse
*/
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output?: IItemEventRouterResponse): void;
/**
* Find item by id in player inventory and remove x of its count
* @param pmcData player profile
* @param itemId Item id to decrement StackObjectsCount of
* @param countToRemove Number of item to remove
* @param sessionID Session id
* @param output IItemEventRouterResponse
* @returns IItemEventRouterResponse
*/
removeItemByCount(pmcData: IPmcData, itemId: string, countToRemove: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
/**
* Get the height and width of an item - can have children that alter size
* @param itemTpl Item to get size of
* @param itemID Items id to get size of
* @param inventoryItems
* @returns [width, height]
*/
getItemSize(itemTpl: string, itemID: string, inventoryItems: Item[]): number[];
protected getSizeByInventoryItemHash(itemTpl: string, itemID: string, inventoryItemHash: InventoryHelper.InventoryItemHash): number[];
protected getInventoryItemHash(inventoryItem: Item[]): InventoryHelper.InventoryItemHash;
/**
* Get a blank two-dimentional representation of a container
* @param containerH Horizontal size of container
* @param containerY Vertical size of container
* @returns Two-dimensional representation of container
*/
protected getBlankContainerMap(containerH: number, containerY: number): number[][];
/**
* @param containerH Horizontal size of container
* @param containerV Vertical size of container
* @param itemList
* @param containerId Id of the container
* @returns Two-dimensional representation of container
*/
getContainerMap(containerH: number, containerV: number, itemList: Item[], containerId: string): number[][];
protected getInventoryItemHash(inventoryItem: Item[]): InventoryHelper.InventoryItemHash;
/**
* Return the inventory that needs to be modified (scav/pmc etc)
* Changes made to result apply to character inventory
@ -151,18 +188,29 @@ export declare class InventoryHelper {
*/
getOwnerInventoryItems(request: IInventoryMoveRequestData | IInventorySplitRequestData | IInventoryMergeRequestData | IInventoryTransferRequestData, sessionId: string): IOwnerInventoryItems;
/**
* Made a 2d array table with 0 - free slot and 1 - used slot
* @param {Object} pmcData
* @param {string} sessionID
* @returns Array
* Get a two dimensional array to represent stash slots
* 0 value = free, 1 = taken
* @param pmcData Player profile
* @param sessionID session id
* @returns 2-dimensional array
*/
protected getStashSlotMap(pmcData: IPmcData, sessionID: string): number[][];
/**
* Get a blank two-dimensional array representation of a container
* @param containerTpl Container to get data for
* @returns blank two-dimensional array
*/
getContainerSlotMap(containerTpl: string): number[][];
/**
* Get a two-dimensional array representation of the players sorting table
* @param pmcData Player profile
* @returns two-dimensional array
*/
protected getSortingTableSlotMap(pmcData: IPmcData): number[][];
/**
* Get Player Stash Proper Size
* @param sessionID Playerid
* @returns Array of 2 values, x and y stash size
* Get Players Stash Size
* @param sessionID Players id
* @returns Array of 2 values, horizontal and vertical stash size
*/
protected getPlayerStashSize(sessionID: string): Record<number, number>;
/**

View File

@ -71,6 +71,10 @@ export declare class ItemHelper {
* @returns True if it needs armor inserts
*/
itemRequiresSoftInserts(itemTpl: string): boolean;
/**
* Get all soft insert slot ids
* @returns An array of soft insert ids (e.g. soft_armor_back, helmet_top)
*/
getSoftInsertSlotIds(): string[];
/**
* Returns the items total price based on the handbook or as a fallback from the prices.json if the item is not
@ -221,6 +225,12 @@ export declare class ItemHelper {
* @returns Item[]
*/
replaceIDs(originalItems: Item[], pmcData?: IPmcData | null, insuredItems?: InsuredItem[] | null, fastPanel?: any): Item[];
/**
* Mark the passed in array of items as found in raid.
* Modifies passed in items
* @param items The list of items to mark as FiR
*/
setFoundInRaid(items: Item[]): void;
/**
* WARNING, SLOW. Recursively loop down through an items hierarchy to see if any of the ids match the supplied list, return true if any do
* @param {string} tpl Items tpl to check parents of
@ -432,6 +442,13 @@ export declare class ItemHelper {
* @returns A Map where the keys are the item IDs and the values are the corresponding Item objects.
*/
generateItemsMap(items: Item[]): Map<string, Item>;
/**
* Add a blank upd object to passed in item if it does not exist already
* @param item item to add upd to
* @param warningMessageWhenMissing text to write to log when upd object was not found
* @returns True when upd object was added
*/
addUpdObjectToItem(item: Item, warningMessageWhenMissing?: string): boolean;
}
declare namespace ItemHelper {
interface ItemSize {

View File

@ -38,4 +38,10 @@ export declare class PresetHelper {
*/
getDefaultPreset(templateId: string): IPreset;
getBaseItemTpl(presetId: string): string;
/**
* Return the price of the preset for the given item tpl, or for the tpl itself if no preset exists
* @param tpl The item template to get the price of
* @returns The price of the given item preset, or base item if no preset exists
*/
getDefaultPresetOrItemPrice(tpl: string): number;
}

View File

@ -4,17 +4,21 @@ import { Common, CounterKeyValue, Stats } from "@spt-aki/models/eft/common/table
import { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile";
import { IValidateNicknameRequestData } from "@spt-aki/models/eft/profile/IValidateNicknameRequestData";
import { SkillTypes } from "@spt-aki/models/enums/SkillTypes";
import { IInventoryConfig } from "@spt-aki/models/spt/config/IInventoryConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { SaveServer } from "@spt-aki/servers/SaveServer";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { ProfileSnapshotService } from "@spt-aki/services/ProfileSnapshotService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
import { Watermark } from "@spt-aki/utils/Watermark";
export declare class ProfileHelper {
protected logger: ILogger;
protected jsonUtil: JsonUtil;
protected hashUtil: HashUtil;
protected watermark: Watermark;
protected timeUtil: TimeUtil;
protected saveServer: SaveServer;
@ -22,7 +26,9 @@ export declare class ProfileHelper {
protected itemHelper: ItemHelper;
protected profileSnapshotService: ProfileSnapshotService;
protected localisationService: LocalisationService;
constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, localisationService: LocalisationService);
protected configServer: ConfigServer;
protected inventoryConfig: IInventoryConfig;
constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, localisationService: LocalisationService, configServer: ConfigServer);
/**
* Remove/reset a completed quest condtion from players profile quest data
* @param sessionID Session id
@ -34,6 +40,11 @@ export declare class ProfileHelper {
* @returns Dictionary of profiles
*/
getProfiles(): Record<string, IAkiProfile>;
/**
* Get the pmc and scav profiles as an array by profile id
* @param sessionID
* @returns Array of IPmcData objects
*/
getCompleteProfile(sessionID: string): IPmcData[];
/**
* Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
@ -45,37 +56,70 @@ export declare class ProfileHelper {
* @param output pmc and scav profiles array
* @param pmcProfile post-raid pmc profile
* @param scavProfile post-raid scav profile
* @returns updated profile array
* @returns Updated profile array
*/
protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
/**
* Check if a nickname is used by another profile loaded by the server
* @param nicknameRequest
* @param nicknameRequest nickname request object
* @param sessionID Session id
* @returns True if already used
*/
isNicknameTaken(nicknameRequest: IValidateNicknameRequestData, sessionID: string): boolean;
protected profileHasInfoProperty(profile: IAkiProfile): boolean;
protected nicknameMatches(profileName: string, nicknameRequest: string): boolean;
protected sessionIdMatchesProfileId(profileId: string, sessionId: string): boolean;
protected stringsMatch(stringA: string, stringB: string): boolean;
/**
* Add experience to a PMC inside the players profile
* @param sessionID Session id
* @param experienceToAdd Experience to add to PMC character
*/
addExperienceToPmc(sessionID: string, experienceToAdd: number): void;
/**
* Iterate all profiles and find matching pmc profile by provided id
* @param pmcId Profile id to find
* @returns IPmcData
*/
getProfileByPmcId(pmcId: string): IPmcData;
/**
* Get the experiecne for the given level
* @param level level to get xp for
* @returns Number of xp points for level
*/
getExperience(level: number): number;
/**
* Get the max level a player can be
* @returns Max level
*/
getMaxLevel(): number;
getDefaultAkiDataObject(): any;
/**
* Get full representation of a players profile json
* @param sessionID Profile id to get
* @returns IAkiProfile object
*/
getFullProfile(sessionID: string): IAkiProfile;
/**
* Get a PMC profile by its session id
* @param sessionID Profile id to return
* @returns IPmcData object
*/
getPmcProfile(sessionID: string): IPmcData;
/**
* Get a full profiles scav-specific sub-profile
* @param sessionID Profiles id
* @returns IPmcData object
*/
getScavProfile(sessionID: string): IPmcData;
/**
* Get baseline counter values for a fresh profile
* @returns Stats
* @returns Default profile Stats object
*/
getDefaultCounters(): Stats;
/**
* is this profile flagged for data removal
* @param sessionID Profile id
* @returns True if profile is to be wiped of data/progress
*/
protected isWiped(sessionID: string): boolean;
protected getServerVersion(): string;
/**
@ -120,6 +164,23 @@ export declare class ProfileHelper {
* @returns
*/
addSkillPointsToPlayer(pmcProfile: IPmcData, skill: SkillTypes, pointsToAdd: number, useSkillProgressRateMultipler?: boolean): void;
/**
* Get a speciic common skill from supplied profile
* @param pmcData Player profile
* @param skill Skill get get
* @returns Common skill object from desired profile
*/
getSkillFromProfile(pmcData: IPmcData, skill: SkillTypes): Common;
/**
* Is the provided session id for a developer account
* @param sessionID Profile id ot check
* @returns True if account is developer
*/
isDeveloperAccount(sessionID: string): boolean;
/**
* Add stash row bonus to profile or increments rows given count if it already exists
* @param sessionId Profile id to give rows to
* @param rowsToAdd How many rows to give profile
*/
addStashRowsBonusToProfile(sessionId: string, rowsToAdd: number): void;
}

View File

@ -178,9 +178,8 @@ export declare class QuestHelper {
* @param failRequest Fail quest request data
* @param sessionID Session id
* @param output Client output
* @returns Item event router response
*/
failQuest(pmcData: IPmcData, failRequest: IFailQuestRequestData, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
failQuest(pmcData: IPmcData, failRequest: IFailQuestRequestData, sessionID: string, output?: IItemEventRouterResponse): void;
/**
* Get List of All Quests from db
* NOT CLONED

View File

@ -53,6 +53,12 @@ export declare class RagfairServerHelper {
* @returns True if its blacklsited
*/
protected isItemOnCustomFleaBlacklist(itemTemplateId: string): boolean;
/**
* Is supplied parent id on the ragfair custom item category blacklist
* @param parentId Parent Id to check is blacklisted
* @returns true if blacklisted
*/
protected isItemCategoryOnCustomFleaBlacklist(itemParentId: string): boolean;
/**
* is supplied id a trader
* @param traderId

View File

@ -54,6 +54,7 @@ export interface Info {
LowerNickname: string;
Side: string;
SquadInviteRestriction: boolean;
HasCoopExtension: boolean;
Voice: string;
Level: number;
Experience: number;
@ -314,8 +315,8 @@ export interface Productive {
sptIsComplete?: boolean;
/** Is the craft a Continuous, e.g bitcoins/water collector */
sptIsContinuous?: boolean;
/** Stores a list of tools used in this craft, to give back once the craft is done */
sptRequiredTools?: string[];
/** Stores a list of tools used in this craft and whether they're FiR, to give back once the craft is done */
sptRequiredTools?: Item[];
}
export interface Production extends Productive {
RecipeId: string;

View File

@ -0,0 +1,2 @@
export interface IDeclineGroupInviteRequest {
}

View File

@ -62,6 +62,7 @@ export declare enum BackendErrorCodes {
BANNEDERRORCODE = 1513,
INSUFFICIENTNUMBERINSTOCK = 1516,
TOOMANYITEMSTOSELL = 1517,
INCORRECTCLIENTPRICE = 1519,
EXAMINATIONFAILED = 22001,
ITEMALREADYEXAMINED = 22002,
UNKNOWNNGINXERROR = 9000,
@ -81,5 +82,6 @@ export declare enum BackendErrorCodes {
PLAYERISNOTSEARCHINGFORGROUP = 502018,
PLAYERALREADYLOOKINGFORGAME = 503001,
PLAYERINRAID = 503002,
LIMITFORPRESETSREACHED = 504001
LIMITFORPRESETSREACHED = 504001,
PLAYERPROFILENOTFOUND = 505001
}

View File

@ -28,5 +28,6 @@ export declare enum BonusType {
STASH_SIZE = "StashSize",
MAXIMUM_ENERGY_RESERVE = "MaximumEnergyReserve",
TEXT_BONUS = "TextBonus",
SKILL_GROUP_LEVELING_BOOST = "SkillGroupLevelingBoost"
SKILL_GROUP_LEVELING_BOOST = "SkillGroupLevelingBoost",
STASH_ROWS = "StashRows"
}

View File

@ -1,6 +0,0 @@
export declare enum AddItemToContainerResult {
UNKONWN_FAILURE = 0,
HIT_SPAWN_LIMIT = 1,
HIT_ROUBLE_LIMIT = 2,
SUCCESS = 3
}

View File

@ -37,6 +37,8 @@ export interface IBotConfig extends IBaseConfig {
botRolesWithDogTags: string[];
/** Settings to control the items that get added into wallets on bots */
walletLoot: IWalletLootSettings;
/** Currency weights, Keyed by botrole / currency */
currencyStackSize: Record<string, Record<string, Record<string, number>>>;
}
/** Number of bots to generate and store in cache on raid start per bot type */
export interface PresetBatch {
@ -78,8 +80,13 @@ export interface PresetBatch {
sptBear: number;
}
export interface IWalletLootSettings {
itemCount: number;
/** Chance wallets have loot in them */
chancePercent: number;
itemCount: MinMax;
stackSizeWeight: Record<string, number>;
currencyWeight: Record<string, number>;
/** What wallets will have money in them */
walletTplPool: string[];
}
export interface EquipmentFilters {
/** Limits for mod types per weapon .e.g. scopes */

View File

@ -7,6 +7,7 @@ export interface ICoreConfig extends IBaseConfig {
serverName: string;
profileSaveIntervalSeconds: number;
sptFriendNickname: string;
release: IRelease;
fixes: IGameFixes;
features: IServerFeatures;
/** Commit hash build server was created from */
@ -14,6 +15,21 @@ export interface ICoreConfig extends IBaseConfig {
/** Timestamp of server build */
buildTime?: string;
}
export interface IRelease {
betaDisclaimerText?: string;
betaDisclaimerAcceptText: string;
serverModsLoadedText: string;
serverModsLoadedDebugText: string;
clientModsLoadedText: string;
clientModsLoadedDebugText: string;
illegalPluginsLoadedText: string;
illegalPluginsExceptionText: string;
releaseSummaryText?: string;
isBeta?: boolean;
isModdable?: boolean;
isModded: boolean;
betaDisclaimerTimeoutDelay: number;
}
export interface IGameFixes {
/** Shotguns use a different value than normal guns causing huge pellet dispersion */
fixShotgunDispersion: boolean;

View File

@ -8,6 +8,8 @@ export interface IInventoryConfig extends IBaseConfig {
sealedAirdropContainer: ISealedAirdropContainerSettings;
/** Contains item tpls that the server should consider money and treat the same as roubles/euros/dollars */
customMoneyTpls: string[];
/** Multipliers for skill gain when inside menus, NOT in-game */
skillGainMultiplers: Record<string, number>;
}
export interface RewardDetails {
rewardCount: number;

View File

@ -16,6 +16,7 @@ export interface Equipment {
ArmorVest: boolean;
Eyewear: boolean;
TacticalVest: boolean;
PocketItems: boolean;
Backpack: boolean;
Holster: boolean;
FirstPrimaryWeapon: boolean;

View File

@ -13,7 +13,6 @@ export interface IPmcConfig extends IBaseConfig {
pocketLoot: SlotLootSettings;
/** Global whitelist/blacklist of backpack loot for PMCs */
backpackLoot: SlotLootSettings;
dynamicLoot: DynamicLoot;
/** Use difficulty defined in config/bot.json/difficulty instead of chosen difficulty dropdown value */
useDifficultyOverride: boolean;
/** Difficulty override e.g. "AsOnline/Hard" */
@ -55,8 +54,4 @@ export interface PmcTypes {
export interface SlotLootSettings {
whitelist: string[];
blacklist: string[];
moneyStackLimits: Record<string, number>;
}
export interface DynamicLoot {
moneyStackLimits: Record<string, number>;
}

View File

@ -16,9 +16,7 @@ export interface Sell {
/** Settings to control chances of offer being sold */
chance: Chance;
/** Settings to control how long it takes for a player offer to sell */
time: Time;
/** Player offer reputation gain/loss settings */
reputation: Reputation;
time: MinMax;
/**Seconds from clicking remove to remove offer from market */
expireSeconds: number;
}
@ -32,13 +30,6 @@ export interface Chance {
/** Min possible sell chance % for a player listed offer */
minSellChancePercent: number;
}
export interface Time extends MinMax {
base: number;
}
export interface Reputation {
gain: number;
loss: number;
}
export interface Dynamic {
purchasesAreFoundInRaid: boolean;
/** Use the highest trader price for an offer if its greater than the price in templates/prices.json */
@ -138,6 +129,10 @@ export interface Blacklist {
traderItems: boolean;
/** Maximum level an armor plate can be found in a flea-listed armor item */
armorPlate: IArmorPlateBlacklistSettings;
/** Should specific categories be blacklisted from the flea, true = use blacklist */
enableCustomItemCategoryList: boolean;
/** Custom category blacklist for parent Ids */
customItemCategoryList: string[];
}
export interface IArmorPlateBlacklistSettings {
/** Max level of plates an armor can have without being removed */

View File

@ -5,6 +5,8 @@ export interface ITraderConfig extends IBaseConfig {
kind: "aki-trader";
updateTime: UpdateTime[];
purchasesAreFoundInRaid: boolean;
/** Should trader reset times be set based on server start time (false = bsg time - on the hour) */
tradersResetFromServerStart: boolean;
updateTimeDefault: number;
traderPriceMultipler: number;
/** Keep track of purchased trader-limited items beyond server restarts to prevent server-restart item scumming */
@ -13,6 +15,7 @@ export interface ITraderConfig extends IBaseConfig {
}
export interface UpdateTime {
traderId: string;
/** Seconds between trader resets */
seconds: number;
}
export interface FenceConfig {
@ -30,6 +33,8 @@ export interface FenceConfig {
/** Key: item tpl */
itemStackSizeOverrideMinMax: Record<string, MinMax>;
itemTypeLimits: Record<string, number>;
/** Prevent duplicate offers of items of specific categories by parentId*/
preventDuplicateOffersOfCategory: string[];
regenerateAssortsOnRefresh: boolean;
/** Max rouble price before item is not listed on flea */
itemCategoryRoublePriceLimit: Record<string, number>;

View File

@ -8,4 +8,11 @@ export interface ITraderServiceModel {
subServices?: {
[key: string]: number;
};
requirements?: ITraderServiceRequirementsModel;
}
export interface ITraderServiceRequirementsModel {
completedQuests?: string[];
standings?: {
[key: string]: number;
};
}

View File

@ -39,8 +39,6 @@ export declare class FenceService {
protected fenceDiscountAssort: ITraderAssort;
/** Hydrated on initial assort generation as part of generateFenceAssorts() */
protected desiredAssortCounts: IFenceAssortGenerationValues;
/** Items that have a multi-stack */
protected multiStackItems: Record<string, boolean>;
constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, localisationService: LocalisationService, configServer: ConfigServer);
/**
* Replace main fence assort with new assort
@ -162,6 +160,22 @@ export declare class FenceService {
current: number;
max: number;
}>, loyaltyLevel: number): void;
/**
* Find an assort item that matches the first parameter, also matches based on upd properties
* e.g. salewa hp resource units left
* @param rootItemBeingAdded item to look for a match against
* @param itemDbDetails Db details of matching item
* @param fenceItemAssorts Items to search through
* @returns Matching assort item
*/
protected getMatchingItem(rootItemBeingAdded: Item, itemDbDetails: ITemplateItem, fenceItemAssorts: Item[]): Item;
/**
* Should this item be forced into only 1 stack on fence
* @param existingItem Existing item from fence assort
* @param itemDbDetails Item we want to add db details
* @returns True item should be force stacked
*/
protected itemShouldBeForceStacked(existingItem: Item, itemDbDetails: ITemplateItem): boolean;
/**
* Adjust price of item based on what is left to buy (resource/uses left)
* @param barterSchemes All barter scheme for item having price adjusted

View File

@ -70,12 +70,6 @@ export declare class InsuranceService {
* @param mapId Id of the map player died/exited that caused the insurance to be issued on
*/
sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
/**
* Send a message to player informing them gear was completely lost
* @param sessionId Session id
* @param locationName name of map insurance was lost on
*/
sendLostInsuranceMessage(sessionId: string, locationName?: string): void;
/**
* Check all root insured items and remove location property + set slotId to 'hideout'
* @param sessionId Session id

View File

@ -1,4 +1,3 @@
import { ICreateGroupRequestData } from "@spt-aki/models/eft/match/ICreateGroupRequestData";
import { SaveServer } from "@spt-aki/servers/SaveServer";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class MatchLocationService {
@ -6,6 +5,5 @@ export declare class MatchLocationService {
protected saveServer: SaveServer;
protected locations: {};
constructor(timeUtil: TimeUtil, saveServer: SaveServer);
createGroup(sessionID: string, info: ICreateGroupRequestData): any;
deleteGroup(info: any): void;
}

View File

@ -1,9 +1,13 @@
import { ITraderServiceModel } from "@spt-aki/models/spt/services/ITraderServiceModel";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
export declare class TraderServicesService {
protected profileHelper: ProfileHelper;
protected jsonUtil: JsonUtil;
protected logger: ILogger;
protected databaseServer: DatabaseServer;
constructor(logger: ILogger, databaseServer: DatabaseServer);
getTraderServices(traderId: string): ITraderServiceModel[];
constructor(profileHelper: ProfileHelper, jsonUtil: JsonUtil, logger: ILogger, databaseServer: DatabaseServer);
getTraderServices(sessionId: string, traderId: string): ITraderServiceModel[];
}

View File

@ -4,6 +4,7 @@ import { CreateItemResult, LocaleDetails, NewItemDetails, NewItemFromCloneDetail
import { IDatabaseTables } from "@spt-aki/models/spt/server/IDatabaseTables";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
export declare class CustomItemService {
@ -12,8 +13,9 @@ export declare class CustomItemService {
protected jsonUtil: JsonUtil;
protected databaseServer: DatabaseServer;
protected itemHelper: ItemHelper;
protected itemBaseClassService: ItemBaseClassService;
protected tables: IDatabaseTables;
constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, itemBaseClassService: ItemBaseClassService);
/**
* Create a new item from a cloned item base
* WARNING - If no item id is supplied, an id will be generated, this id will be random every time you add an item and will not be the same on each subsequent server start
@ -79,6 +81,11 @@ export declare class CustomItemService {
* @param fleaPriceRoubles Price of the new item
*/
protected addToFleaPriceDb(newItemId: string, fleaPriceRoubles: number): void;
/**
* Add a weapon to the hideout weapon shelf whitelist
* @param newItemId Weapon id to add
*/
protected addToWeaponShelf(newItemId: string): void;
/**
* Add a custom weapon to PMCs loadout
* @param weaponTpl Custom weapon tpl to add to PMCs

View File

@ -61,4 +61,5 @@ export declare class TimeUtil {
* @returns {number} The equivalent number of seconds.
*/
getHoursAsSeconds(hours: number): number;
getTimestampOfNextHour(): number;
}

View File

@ -46,8 +46,8 @@ export declare class VFS {
removeDirAsync(filepath: string): Promise<void>;
rename(oldPath: string, newPath: string): void;
renameAsync(oldPath: string, newPath: string): Promise<void>;
protected lockFileSync(filepath: any): void;
protected checkFileSync(filepath: any): any;
protected lockFileSync(filepath: any): () => void;
protected checkFileSync(filepath: any): boolean;
protected unlockFileSync(filepath: any): void;
getFileExtension(filepath: string): string;
stripExtension(filepath: string): string;

View File

@ -1,14 +1,24 @@
import { ClientLogController } from "@spt-aki/controllers/ClientLogController";
import { ModLoadOrder } from "@spt-aki/loaders/ModLoadOrder";
import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData";
import { IClientLogRequest } from "@spt-aki/models/spt/logging/IClientLogRequest";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
/** Handle client logging related events */
export declare class ClientLogCallbacks {
protected httpResponse: HttpResponseUtil;
protected clientLogController: ClientLogController;
constructor(httpResponse: HttpResponseUtil, clientLogController: ClientLogController);
protected configServer: ConfigServer;
protected localisationService: LocalisationService;
protected modLoadOrder: ModLoadOrder;
constructor(httpResponse: HttpResponseUtil, clientLogController: ClientLogController, configServer: ConfigServer, localisationService: LocalisationService, modLoadOrder: ModLoadOrder);
/**
* Handle /singleplayer/log
*/
clientLog(url: string, info: IClientLogRequest, sessionID: string): INullResponseData;
/**
* Handle /singleplayer/release
*/
releaseNotes(): string;
}

View File

@ -9,5 +9,11 @@ export declare class ItemEventCallbacks {
protected itemEventRouter: ItemEventRouter;
constructor(httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter);
handleEvents(url: string, info: IItemEventRouterRequest, sessionID: string): IGetBodyResponseData<IItemEventRouterResponse>;
/**
* Return true if the passed in list of warnings contains critical issues
* @param warnings The list of warnings to check for critical errors
* @returns
*/
private isCriticalError;
protected getErrorCode(warnings: Warning[]): number;
}

View File

@ -1,16 +1,14 @@
import { MatchController } from "@spt-aki/controllers/MatchController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { IGetBodyResponseData } from "@spt-aki/models/eft/httpResponse/IGetBodyResponseData";
import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData";
import { IAcceptGroupInviteRequest } from "@spt-aki/models/eft/match/IAcceptGroupInviteRequest";
import { IAcceptGroupInviteResponse } from "@spt-aki/models/eft/match/IAcceptGroupInviteResponse";
import { ICancelGroupInviteRequest } from "@spt-aki/models/eft/match/ICancelGroupInviteRequest";
import { ICreateGroupRequestData } from "@spt-aki/models/eft/match/ICreateGroupRequestData";
import { IDeclineGroupInviteRequest } from "@spt-aki/models/eft/match/IDeclineGroupInviteRequest";
import { IEndOfflineRaidRequestData } from "@spt-aki/models/eft/match/IEndOfflineRaidRequestData";
import { IGetGroupStatusRequestData } from "@spt-aki/models/eft/match/IGetGroupStatusRequestData";
import { IGetGroupStatusResponse } from "@spt-aki/models/eft/match/IGetGroupStatusResponse";
import { IGetProfileRequestData } from "@spt-aki/models/eft/match/IGetProfileRequestData";
import { IGetRaidConfigurationRequestData } from "@spt-aki/models/eft/match/IGetRaidConfigurationRequestData";
import { IJoinMatchRequestData } from "@spt-aki/models/eft/match/IJoinMatchRequestData";
import { IJoinMatchResult } from "@spt-aki/models/eft/match/IJoinMatchResult";
@ -39,6 +37,8 @@ export declare class MatchCallbacks {
sendGroupInvite(url: string, info: ISendGroupInviteRequest, sessionID: string): IGetBodyResponseData<string>;
/** Handle client/match/group/invite/accept */
acceptGroupInvite(url: string, info: IAcceptGroupInviteRequest, sessionID: string): IGetBodyResponseData<IAcceptGroupInviteResponse[]>;
/** Handle client/match/group/invite/decline */
declineGroupInvite(url: string, info: IDeclineGroupInviteRequest, sessionID: string): IGetBodyResponseData<any>;
/** Handle client/match/group/invite/cancel */
cancelGroupInvite(url: string, info: ICancelGroupInviteRequest, sessionID: string): IGetBodyResponseData<boolean>;
/** Handle client/match/group/transfer */
@ -47,8 +47,6 @@ export declare class MatchCallbacks {
cancelAllGroupInvite(url: string, info: any, sessionID: string): INullResponseData;
/** @deprecated - not called on raid start/end or game start/exit */
putMetrics(url: string, info: IPutMetricsRequestData, sessionID: string): INullResponseData;
/** Handle raid/profile/list */
getProfile(url: string, info: IGetProfileRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
serverAvailable(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<boolean>;
/** Handle match/group/start_game */
joinMatch(url: string, info: IJoinMatchRequestData, sessionID: string): IGetBodyResponseData<IJoinMatchResult>;
@ -60,8 +58,6 @@ export declare class MatchCallbacks {
* @returns
*/
getGroupStatus(url: string, info: IGetGroupStatusRequestData, sessionID: string): IGetBodyResponseData<IGetGroupStatusResponse>;
/** Handle client/match/group/create */
createGroup(url: string, info: ICreateGroupRequestData, sessionID: string): IGetBodyResponseData<any>;
/** Handle client/match/group/delete */
deleteGroup(url: string, info: any, sessionID: string): INullResponseData;
leaveGroup(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<boolean>;

View File

@ -3,11 +3,9 @@ import { LootGenerator } from "@spt-aki/generators/LootGenerator";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { ICreateGroupRequestData } from "@spt-aki/models/eft/match/ICreateGroupRequestData";
import { IEndOfflineRaidRequestData } from "@spt-aki/models/eft/match/IEndOfflineRaidRequestData";
import { IGetGroupStatusRequestData } from "@spt-aki/models/eft/match/IGetGroupStatusRequestData";
import { IGetGroupStatusResponse } from "@spt-aki/models/eft/match/IGetGroupStatusResponse";
import { IGetProfileRequestData } from "@spt-aki/models/eft/match/IGetProfileRequestData";
import { IGetRaidConfigurationRequestData } from "@spt-aki/models/eft/match/IGetRaidConfigurationRequestData";
import { IJoinMatchRequestData } from "@spt-aki/models/eft/match/IJoinMatchRequestData";
import { IJoinMatchResult } from "@spt-aki/models/eft/match/IJoinMatchResult";
@ -48,10 +46,6 @@ export declare class MatchController {
protected pmcConfig: IPmcConfig;
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, randomUtil: RandomUtil, hashUtil: HashUtil, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, botGenerationCacheService: BotGenerationCacheService, mailSendService: MailSendService, lootGenerator: LootGenerator, applicationContext: ApplicationContext);
getEnabled(): boolean;
/** Handle raid/profile/list */
getProfile(info: IGetProfileRequestData): IPmcData[];
/** Handle client/match/group/create */
createGroup(sessionID: string, info: ICreateGroupRequestData): any;
/** Handle client/match/group/delete */
deleteGroup(info: any): void;
/** Handle match/group/start_game */

View File

@ -1,3 +1,4 @@
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
import { RepairHelper } from "@spt-aki/helpers/RepairHelper";
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
@ -20,8 +21,9 @@ export declare class RepairController {
protected paymentService: PaymentService;
protected repairHelper: RepairHelper;
protected repairService: RepairService;
protected profileHelper: ProfileHelper;
protected repairConfig: IRepairConfig;
constructor(logger: ILogger, eventOutputHolder: EventOutputHolder, databaseServer: DatabaseServer, questHelper: QuestHelper, traderHelper: TraderHelper, paymentService: PaymentService, repairHelper: RepairHelper, repairService: RepairService);
constructor(logger: ILogger, eventOutputHolder: EventOutputHolder, databaseServer: DatabaseServer, questHelper: QuestHelper, traderHelper: TraderHelper, paymentService: PaymentService, repairHelper: RepairHelper, repairService: RepairService, profileHelper: ProfileHelper);
/**
* Handle TraderRepair event
* Repair with trader

View File

@ -1,7 +1,6 @@
import { RepeatableQuestGenerator } from "@spt-aki/generators/RepeatableQuestGenerator";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
import { RagfairServerHelper } from "@spt-aki/helpers/RagfairServerHelper";
import { RepeatableQuestHelper } from "@spt-aki/helpers/RepeatableQuestHelper";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
@ -31,7 +30,6 @@ export declare class RepeatableQuestController {
protected jsonUtil: JsonUtil;
protected profileHelper: ProfileHelper;
protected profileFixerService: ProfileFixerService;
protected ragfairServerHelper: RagfairServerHelper;
protected eventOutputHolder: EventOutputHolder;
protected paymentService: PaymentService;
protected objectId: ObjectId;
@ -40,7 +38,7 @@ export declare class RepeatableQuestController {
protected questHelper: QuestHelper;
protected configServer: ConfigServer;
protected questConfig: IQuestConfig;
constructor(logger: ILogger, databaseServer: DatabaseServer, timeUtil: TimeUtil, randomUtil: RandomUtil, httpResponse: HttpResponseUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, paymentService: PaymentService, objectId: ObjectId, repeatableQuestGenerator: RepeatableQuestGenerator, repeatableQuestHelper: RepeatableQuestHelper, questHelper: QuestHelper, configServer: ConfigServer);
constructor(logger: ILogger, databaseServer: DatabaseServer, timeUtil: TimeUtil, randomUtil: RandomUtil, httpResponse: HttpResponseUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, eventOutputHolder: EventOutputHolder, paymentService: PaymentService, objectId: ObjectId, repeatableQuestGenerator: RepeatableQuestGenerator, repeatableQuestHelper: RepeatableQuestHelper, questHelper: QuestHelper, configServer: ConfigServer);
/**
* Handle client/repeatalbeQuests/activityPeriods
* Returns an array of objects in the format of repeatable quests to the client.

View File

@ -3,14 +3,18 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { TraderAssortHelper } from "@spt-aki/helpers/TraderAssortHelper";
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
import { ITraderAssort, ITraderBase } from "@spt-aki/models/eft/common/tables/ITrader";
import { ITraderConfig } from "@spt-aki/models/spt/config/ITraderConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { FenceService } from "@spt-aki/services/FenceService";
import { TraderAssortService } from "@spt-aki/services/TraderAssortService";
import { TraderPurchasePersisterService } from "@spt-aki/services/TraderPurchasePersisterService";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class TraderController {
protected logger: ILogger;
protected timeUtil: TimeUtil;
protected databaseServer: DatabaseServer;
protected traderAssortHelper: TraderAssortHelper;
protected profileHelper: ProfileHelper;
@ -20,10 +24,12 @@ export declare class TraderController {
protected fenceService: FenceService;
protected fenceBaseAssortGenerator: FenceBaseAssortGenerator;
protected jsonUtil: JsonUtil;
constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, traderAssortService: TraderAssortService, traderPurchasePersisterService: TraderPurchasePersisterService, fenceService: FenceService, fenceBaseAssortGenerator: FenceBaseAssortGenerator, jsonUtil: JsonUtil);
protected configServer: ConfigServer;
protected traderConfig: ITraderConfig;
constructor(logger: ILogger, timeUtil: TimeUtil, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, traderAssortService: TraderAssortService, traderPurchasePersisterService: TraderPurchasePersisterService, fenceService: FenceService, fenceBaseAssortGenerator: FenceBaseAssortGenerator, jsonUtil: JsonUtil, configServer: ConfigServer);
/**
* Runs when onLoad event is fired
* Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
* Iterate over traders, ensure a pristine copy of their assorts is stored in traderAssortService
* Store timestamp of next assort refresh in nextResupply property of traders .base object
*/
load(): void;

View File

@ -89,8 +89,9 @@ export declare class BotLootGenerator {
* @param itemToAddTemplate Db template of item to check
* @param itemToAddChildrenTo Item to add children to
* @param isPmc Is the item being generated for a pmc (affects money/ammo stack sizes)
* @param botRole role bot has that owns item
*/
protected addRequiredChildItemsToParent(itemToAddTemplate: ITemplateItem, itemToAddChildrenTo: Item[], isPmc: boolean): void;
protected addRequiredChildItemsToParent(itemToAddTemplate: ITemplateItem, itemToAddChildrenTo: Item[], isPmc: boolean, botRole: string): void;
/**
* Add generated weapons to inventory as loot
* @param botInventory inventory to add preset to
@ -118,11 +119,11 @@ export declare class BotLootGenerator {
protected itemHasReachedSpawnLimit(itemTemplate: ITemplateItem, botRole: string, itemSpawnLimits: IItemSpawnLimitSettings): boolean;
/**
* Randomise the stack size of a money object, uses different values for pmc or scavs
* @param isPmc Is money on a PMC bot
* @param botRole Role bot has that has money stack
* @param itemTemplate item details from db
* @param moneyItem Money item to randomise
*/
protected randomiseMoneyStackSize(isPmc: boolean, itemTemplate: ITemplateItem, moneyItem: Item): void;
protected randomiseMoneyStackSize(botRole: string, itemTemplate: ITemplateItem, moneyItem: Item): void;
/**
* Randomise the size of an ammo stack
* @param isPmc Is ammo on a PMC bot

View File

@ -1,54 +1,34 @@
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { RepeatableQuestRewardGenerator } from "@spt-aki/generators/RepeatableQuestRewardGenerator";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { RagfairServerHelper } from "@spt-aki/helpers/RagfairServerHelper";
import { RepeatableQuestHelper } from "@spt-aki/helpers/RepeatableQuestHelper";
import { Exit } from "@spt-aki/models/eft/common/ILocationBase";
import { TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase";
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
import { IQuestCondition, IQuestConditionCounterCondition, IQuestReward, IQuestRewards } from "@spt-aki/models/eft/common/tables/IQuest";
import { IQuestCondition, IQuestConditionCounterCondition } from "@spt-aki/models/eft/common/tables/IQuest";
import { IRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests";
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
import { IBaseQuestConfig, IBossInfo, IEliminationConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig";
import { IBossInfo, IEliminationConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig";
import { IQuestTypePool } from "@spt-aki/models/spt/repeatable/IQuestTypePool";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { EventOutputHolder } from "@spt-aki/routers/EventOutputHolder";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemFilterService } from "@spt-aki/services/ItemFilterService";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { PaymentService } from "@spt-aki/services/PaymentService";
import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { MathUtil } from "@spt-aki/utils/MathUtil";
import { ObjectId } from "@spt-aki/utils/ObjectId";
import { ProbabilityObjectArray, RandomUtil } from "@spt-aki/utils/RandomUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class RepeatableQuestGenerator {
protected timeUtil: TimeUtil;
protected logger: ILogger;
protected randomUtil: RandomUtil;
protected httpResponse: HttpResponseUtil;
protected mathUtil: MathUtil;
protected jsonUtil: JsonUtil;
protected databaseServer: DatabaseServer;
protected itemHelper: ItemHelper;
protected presetHelper: PresetHelper;
protected profileHelper: ProfileHelper;
protected profileFixerService: ProfileFixerService;
protected handbookHelper: HandbookHelper;
protected ragfairServerHelper: RagfairServerHelper;
protected eventOutputHolder: EventOutputHolder;
protected localisationService: LocalisationService;
protected paymentService: PaymentService;
protected objectId: ObjectId;
protected itemFilterService: ItemFilterService;
protected repeatableQuestHelper: RepeatableQuestHelper;
protected repeatableQuestRewardGenerator: RepeatableQuestRewardGenerator;
protected configServer: ConfigServer;
protected questConfig: IQuestConfig;
constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, httpResponse: HttpResponseUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, handbookHelper: HandbookHelper, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, localisationService: LocalisationService, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, repeatableQuestHelper: RepeatableQuestHelper, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, localisationService: LocalisationService, objectId: ObjectId, repeatableQuestHelper: RepeatableQuestHelper, repeatableQuestRewardGenerator: RepeatableQuestRewardGenerator, configServer: ConfigServer);
/**
* This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json).
* It randomly draws a quest type (currently Elimination, Completion or Exploration) as well as a trader who is providing the quest
@ -144,71 +124,6 @@ export declare class RepeatableQuestGenerator {
* @returns {object} Exit condition
*/
protected generateExplorationExitCondition(exit: Exit): IQuestConditionCounterCondition;
/**
* Generate the reward for a mission. A reward can consist of
* - Experience
* - Money
* - Items
* - Trader Reputation
*
* The reward is dependent on the player level as given by the wiki. The exact mapping of pmcLevel to
* experience / money / items / trader reputation can be defined in QuestConfig.js
*
* There's also a random variation of the reward the spread of which can be also defined in the config.
*
* Additionally, a scaling factor w.r.t. quest difficulty going from 0.2...1 can be used
*
* @param {integer} pmcLevel player's level
* @param {number} difficulty a reward scaling factor from 0.2 to 1
* @param {string} traderId the trader for reputation gain (and possible in the future filtering of reward item type based on trader)
* @param {object} repeatableConfig The configuration for the repeatable kind (daily, weekly) as configured in QuestConfig for the requested quest
* @returns {object} object of "Reward"-type that can be given for a repeatable mission
*/
protected generateReward(pmcLevel: number, difficulty: number, traderId: string, repeatableConfig: IRepeatableQuestConfig, questConfig: IBaseQuestConfig): IQuestRewards;
protected addMoneyReward(traderId: string, rewards: IQuestRewards, rewardRoubles: number, rewardIndex: number): void;
protected calculateAmmoStackSizeThatFitsBudget(itemSelected: ITemplateItem, roublesBudget: number, rewardNumItems: number): number;
/**
* Should reward item have stack size increased (25% chance)
* @param item Item to possibly increase stack size of
* @param maxRoublePriceToStack Maximum rouble price an item can be to still be chosen for stacking
* @returns True if it should
*/
protected canIncreaseRewardItemStackSize(item: ITemplateItem, maxRoublePriceToStack: number): boolean;
/**
* Get a randomised number a reward items stack size should be based on its handbook price
* @param item Reward item to get stack size for
* @returns Stack size value
*/
protected getRandomisedRewardItemStackSizeByPrice(item: ITemplateItem): number;
/**
* Select a number of items that have a colelctive value of the passed in parameter
* @param repeatableConfig Config
* @param roublesBudget Total value of items to return
* @returns Array of reward items that fit budget
*/
protected chooseRewardItemsWithinBudget(repeatableConfig: IRepeatableQuestConfig, roublesBudget: number, traderId: string): ITemplateItem[];
/**
* Helper to create a reward item structured as required by the client
*
* @param {string} tpl ItemId of the rewarded item
* @param {integer} value Amount of items to give
* @param {integer} index All rewards will be appended to a list, for unknown reasons the client wants the index
* @returns {object} Object of "Reward"-item-type
*/
protected generateRewardItem(tpl: string, value: number, index: number, preset?: Item[]): IQuestReward;
/**
* Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
* @param repeatableQuestConfig Config file
* @returns List of rewardable items [[_tpl, itemTemplate],...]
*/
protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig, traderId: string): [string, ITemplateItem][];
/**
* Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
* or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
* @param {string} tpl template id of item to check
* @returns True if item is valid reward
*/
protected isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig, itemBaseWhitelist: string[]): boolean;
/**
* Generates the base object of quest type format given as templates in assets/database/templates/repeatableQuests.json
* The templates include Elimination, Completion and Extraction quest types

View File

@ -0,0 +1,106 @@
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
import { IQuestReward, IQuestRewards } from "@spt-aki/models/eft/common/tables/IQuest";
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
import { IBaseQuestConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemFilterService } from "@spt-aki/services/ItemFilterService";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { MathUtil } from "@spt-aki/utils/MathUtil";
import { ObjectId } from "@spt-aki/utils/ObjectId";
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
export declare class RepeatableQuestRewardGenerator {
protected logger: ILogger;
protected randomUtil: RandomUtil;
protected mathUtil: MathUtil;
protected jsonUtil: JsonUtil;
protected databaseServer: DatabaseServer;
protected itemHelper: ItemHelper;
protected presetHelper: PresetHelper;
protected handbookHelper: HandbookHelper;
protected localisationService: LocalisationService;
protected objectId: ObjectId;
protected itemFilterService: ItemFilterService;
protected seasonalEventService: SeasonalEventService;
protected configServer: ConfigServer;
protected questConfig: IQuestConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer);
/**
* Generate the reward for a mission. A reward can consist of
* - Experience
* - Money
* - Items
* - Trader Reputation
*
* The reward is dependent on the player level as given by the wiki. The exact mapping of pmcLevel to
* experience / money / items / trader reputation can be defined in QuestConfig.js
*
* There's also a random variation of the reward the spread of which can be also defined in the config.
*
* Additionally, a scaling factor w.r.t. quest difficulty going from 0.2...1 can be used
*
* @param {integer} pmcLevel player's level
* @param {number} difficulty a reward scaling factor from 0.2 to 1
* @param {string} traderId the trader for reputation gain (and possible in the future filtering of reward item type based on trader)
* @param {object} repeatableConfig The configuration for the repeatable kind (daily, weekly) as configured in QuestConfig for the requested quest
* @returns {object} object of "Reward"-type that can be given for a repeatable mission
*/
generateReward(pmcLevel: number, difficulty: number, traderId: string, repeatableConfig: IRepeatableQuestConfig, questConfig: IBaseQuestConfig): IQuestRewards;
/**
* @param rewardItems List of reward items to filter
* @param roublesBudget The budget remaining for rewards
* @param minPrice The minimum priced item to include
* @returns True if any items remain in `rewardItems`, false otherwise
*/
protected filterRewardPoolWithinBudget(rewardItems: ITemplateItem[], roublesBudget: number, minPrice: number): boolean;
/**
* Get a randomised number a reward items stack size should be based on its handbook price
* @param item Reward item to get stack size for
* @returns Stack size value
*/
protected getRandomisedRewardItemStackSizeByPrice(item: ITemplateItem): number;
/**
* Should reward item have stack size increased (25% chance)
* @param item Item to possibly increase stack size of
* @param maxRoublePriceToStack Maximum rouble price an item can be to still be chosen for stacking
* @returns True if it should
*/
protected canIncreaseRewardItemStackSize(item: ITemplateItem, maxRoublePriceToStack: number): boolean;
protected calculateAmmoStackSizeThatFitsBudget(itemSelected: ITemplateItem, roublesBudget: number, rewardNumItems: number): number;
/**
* Select a number of items that have a colelctive value of the passed in parameter
* @param repeatableConfig Config
* @param roublesBudget Total value of items to return
* @returns Array of reward items that fit budget
*/
protected chooseRewardItemsWithinBudget(repeatableConfig: IRepeatableQuestConfig, roublesBudget: number, traderId: string): ITemplateItem[];
/**
* Helper to create a reward item structured as required by the client
*
* @param {string} tpl ItemId of the rewarded item
* @param {integer} value Amount of items to give
* @param {integer} index All rewards will be appended to a list, for unknown reasons the client wants the index
* @returns {object} Object of "Reward"-item-type
*/
protected generateRewardItem(tpl: string, value: number, index: number, preset?: Item[]): IQuestReward;
/**
* Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
* @param repeatableQuestConfig Config file
* @returns List of rewardable items [[_tpl, itemTemplate],...]
*/
getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig, traderId: string): [string, ITemplateItem][];
/**
* Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
* or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
* @param {string} tpl template id of item to check
* @returns True if item is valid reward
*/
protected isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig, itemBaseWhitelist: string[]): boolean;
protected addMoneyReward(traderId: string, rewards: IQuestRewards, rewardRoubles: number, rewardIndex: number): void;
}

View File

@ -10,6 +10,7 @@ import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemFilterService } from "@spt-aki/services/ItemFilterService";
import { RagfairPriceService } from "@spt-aki/services/RagfairPriceService";
import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
@ -25,12 +26,13 @@ export declare class ScavCaseRewardGenerator {
protected presetHelper: PresetHelper;
protected databaseServer: DatabaseServer;
protected ragfairPriceService: RagfairPriceService;
protected seasonalEventService: SeasonalEventService;
protected itemFilterService: ItemFilterService;
protected configServer: ConfigServer;
protected scavCaseConfig: IScavCaseConfig;
protected dbItemsCache: ITemplateItem[];
protected dbAmmoItemsCache: ITemplateItem[];
constructor(logger: ILogger, randomUtil: RandomUtil, jsonUtil: JsonUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, jsonUtil: JsonUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, seasonalEventService: SeasonalEventService, itemFilterService: ItemFilterService, configServer: ConfigServer);
/**
* Create an array of rewards that will be given to the player upon completing their scav case build
* @param recipeId recipe of the scav case craft

View File

@ -3,6 +3,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig";
import { IWeatherConfig } from "@spt-aki/models/spt/config/IWeatherConfig";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { GiftService } from "@spt-aki/services/GiftService";
import { MailSendService } from "@spt-aki/services/MailSendService";
@ -14,6 +15,7 @@ export declare class SptDialogueChatBot implements IDialogueChatBot {
protected giftService: GiftService;
protected configServer: ConfigServer;
protected coreConfig: ICoreConfig;
protected weatherConfig: IWeatherConfig;
constructor(profileHelper: ProfileHelper, randomUtil: RandomUtil, mailSendService: MailSendService, giftService: GiftService, configServer: ConfigServer);
getChatBot(): IUserDialogInfo;
/**

View File

@ -19,6 +19,7 @@ import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { PlayerService } from "@spt-aki/services/PlayerService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class HideoutHelper {
protected logger: ILogger;
@ -33,6 +34,7 @@ export declare class HideoutHelper {
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected configServer: ConfigServer;
protected jsonUtil: JsonUtil;
static bitcoinFarm: string;
static bitcoinProductionId: string;
static waterCollector: string;
@ -40,7 +42,7 @@ export declare class HideoutHelper {
static expeditionaryFuelTank: string;
static maxSkillPoint: number;
protected hideoutConfig: IHideoutConfig;
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, localisationService: LocalisationService, itemHelper: ItemHelper, configServer: ConfigServer);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, localisationService: LocalisationService, itemHelper: ItemHelper, configServer: ConfigServer, jsonUtil: JsonUtil);
/**
* Add production to profiles' Hideout.Production array
* @param pmcData Profile to add production to
@ -82,6 +84,16 @@ export declare class HideoutHelper {
waterCollectorHasFilter: boolean;
};
protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
/**
* Iterate over productions and update their progress timers
* @param pmcData Profile to check for productions and update
* @param hideoutProperties Hideout properties
*/
protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
btcFarmCGs: number;
isGeneratorOn: boolean;
waterCollectorHasFilter: boolean;
}): void;
/**
* Update progress timer for water collector
* @param pmcData profile to update
@ -93,16 +105,6 @@ export declare class HideoutHelper {
isGeneratorOn: boolean;
waterCollectorHasFilter: boolean;
}): void;
/**
* Iterate over productions and update their progress timers
* @param pmcData Profile to check for productions and update
* @param hideoutProperties Hideout properties
*/
protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
btcFarmCGs: number;
isGeneratorOn: boolean;
waterCollectorHasFilter: boolean;
}): void;
/**
* Update a productions progress value based on the amount of time that has passed
* @param pmcData Player profile
@ -148,6 +150,13 @@ export declare class HideoutHelper {
*/
protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData, isGeneratorOn: boolean): void;
protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
/**
* Get craft time and make adjustments to account for dev profile + crafting skill level
* @param pmcData Player profile making craft
* @param recipeId Recipe being crafted
* @returns
*/
protected getAdjustedCraftTimeWithSkills(pmcData: IPmcData, recipeId: string): number;
/**
* Adjust water filter objects resourceValue or delete when they reach 0 resource
* @param waterFilterArea water filter area to update
@ -163,9 +172,9 @@ export declare class HideoutHelper {
* @param totalProductionTime Total time collecting water
* @param productionProgress how far water collector has progressed
* @param baseFilterDrainRate Base drain rate
* @returns
* @returns drain rate (adjusted)
*/
protected adjustWaterFilterDrainRate(secondsSinceServerTick: number, totalProductionTime: number, productionProgress: number, baseFilterDrainRate: number): number;
protected getAdjustWaterFilterDrainRate(secondsSinceServerTick: number, totalProductionTime: number, productionProgress: number, baseFilterDrainRate: number): number;
/**
* Get the water filter drain rate based on hideout bonues player has
* @param pmcData Player profile
@ -185,7 +194,7 @@ export declare class HideoutHelper {
* @param resourceUnitsConsumed
* @returns Upd
*/
protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number, isFoundInRaid: boolean): Upd;
protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData, isGeneratorOn: boolean): void;
protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
/**
@ -225,7 +234,7 @@ export declare class HideoutHelper {
* @param productionTime Time to complete hideout craft in seconds
* @returns Adjusted craft time in seconds
*/
protected getCraftingSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number): number;
getCraftingSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number): number;
isProduction(productive: Productive): productive is Production;
/**
* Gather crafted BTC from hideout area and add to inventory

View File

@ -74,9 +74,9 @@ export declare class InventoryHelper {
* @param itemWithChildren An item
* @param foundInRaid Item was found in raid
*/
private setFindInRaidStatusForItem;
protected setFindInRaidStatusForItem(itemWithChildren: Item[], foundInRaid: boolean): void;
/**
* Remove properties from a Upd object used by a trader/ragfair
* Remove properties from a Upd object used by a trader/ragfair that are unnecessary to a player
* @param upd Object to update
*/
protected removeTraderRagfairRelatedUpdProperties(upd: Upd): void;
@ -106,8 +106,9 @@ export declare class InventoryHelper {
* @param containerFS2D Container grid to add item to
* @param itemWithChildren Item to add to grid
* @param containerId Id of the container we're fitting item into
* @param desiredSlotId slot id value to use, default is "hideout"
*/
placeItemInContainer(containerFS2D: number[][], itemWithChildren: Item[], containerId: string): void;
placeItemInContainer(containerFS2D: number[][], itemWithChildren: Item[], containerId: string, desiredSlotId?: string): void;
/**
* Find a location to place an item into inventory and place it
* @param stashFS2D 2-dimensional representation of the container slots
@ -119,9 +120,10 @@ export declare class InventoryHelper {
*/
protected placeItemInInventory(stashFS2D: number[][], sortingTableFS2D: number[][], itemWithChildren: Item[], playerInventory: Inventory, useSortingTable: boolean, output: IItemEventRouterResponse): void;
/**
* Split an items stack size based on its StackMaxSize value
* @param assortItems Items to add to inventory
* @param requestItem Details of purchased item to add to inventory
* @param result Array split stacks are added to
* @param result Array split stacks are appended to
*/
protected splitStackIntoSmallerChildStacks(assortItems: Item[], requestItem: AddItem, result: IAddItemTempObject[]): void;
/**
@ -134,13 +136,48 @@ export declare class InventoryHelper {
* @param output OPTIONAL - IItemEventRouterResponse
*/
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): void;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): void;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
/**
* Delete desired item from a player profiles mail
* @param sessionId Session id
* @param removeRequest Remove request
* @param output OPTIONAL - IItemEventRouterResponse
*/
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output?: IItemEventRouterResponse): void;
/**
* Find item by id in player inventory and remove x of its count
* @param pmcData player profile
* @param itemId Item id to decrement StackObjectsCount of
* @param countToRemove Number of item to remove
* @param sessionID Session id
* @param output IItemEventRouterResponse
* @returns IItemEventRouterResponse
*/
removeItemByCount(pmcData: IPmcData, itemId: string, countToRemove: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
/**
* Get the height and width of an item - can have children that alter size
* @param itemTpl Item to get size of
* @param itemID Items id to get size of
* @param inventoryItems
* @returns [width, height]
*/
getItemSize(itemTpl: string, itemID: string, inventoryItems: Item[]): number[];
protected getSizeByInventoryItemHash(itemTpl: string, itemID: string, inventoryItemHash: InventoryHelper.InventoryItemHash): number[];
protected getInventoryItemHash(inventoryItem: Item[]): InventoryHelper.InventoryItemHash;
/**
* Get a blank two-dimentional representation of a container
* @param containerH Horizontal size of container
* @param containerY Vertical size of container
* @returns Two-dimensional representation of container
*/
protected getBlankContainerMap(containerH: number, containerY: number): number[][];
/**
* @param containerH Horizontal size of container
* @param containerV Vertical size of container
* @param itemList
* @param containerId Id of the container
* @returns Two-dimensional representation of container
*/
getContainerMap(containerH: number, containerV: number, itemList: Item[], containerId: string): number[][];
protected getInventoryItemHash(inventoryItem: Item[]): InventoryHelper.InventoryItemHash;
/**
* Return the inventory that needs to be modified (scav/pmc etc)
* Changes made to result apply to character inventory
@ -151,18 +188,29 @@ export declare class InventoryHelper {
*/
getOwnerInventoryItems(request: IInventoryMoveRequestData | IInventorySplitRequestData | IInventoryMergeRequestData | IInventoryTransferRequestData, sessionId: string): IOwnerInventoryItems;
/**
* Made a 2d array table with 0 - free slot and 1 - used slot
* @param {Object} pmcData
* @param {string} sessionID
* @returns Array
* Get a two dimensional array to represent stash slots
* 0 value = free, 1 = taken
* @param pmcData Player profile
* @param sessionID session id
* @returns 2-dimensional array
*/
protected getStashSlotMap(pmcData: IPmcData, sessionID: string): number[][];
/**
* Get a blank two-dimensional array representation of a container
* @param containerTpl Container to get data for
* @returns blank two-dimensional array
*/
getContainerSlotMap(containerTpl: string): number[][];
/**
* Get a two-dimensional array representation of the players sorting table
* @param pmcData Player profile
* @returns two-dimensional array
*/
protected getSortingTableSlotMap(pmcData: IPmcData): number[][];
/**
* Get Player Stash Proper Size
* @param sessionID Playerid
* @returns Array of 2 values, x and y stash size
* Get Players Stash Size
* @param sessionID Players id
* @returns Array of 2 values, horizontal and vertical stash size
*/
protected getPlayerStashSize(sessionID: string): Record<number, number>;
/**

View File

@ -71,6 +71,10 @@ export declare class ItemHelper {
* @returns True if it needs armor inserts
*/
itemRequiresSoftInserts(itemTpl: string): boolean;
/**
* Get all soft insert slot ids
* @returns An array of soft insert ids (e.g. soft_armor_back, helmet_top)
*/
getSoftInsertSlotIds(): string[];
/**
* Returns the items total price based on the handbook or as a fallback from the prices.json if the item is not
@ -221,6 +225,12 @@ export declare class ItemHelper {
* @returns Item[]
*/
replaceIDs(originalItems: Item[], pmcData?: IPmcData | null, insuredItems?: InsuredItem[] | null, fastPanel?: any): Item[];
/**
* Mark the passed in array of items as found in raid.
* Modifies passed in items
* @param items The list of items to mark as FiR
*/
setFoundInRaid(items: Item[]): void;
/**
* WARNING, SLOW. Recursively loop down through an items hierarchy to see if any of the ids match the supplied list, return true if any do
* @param {string} tpl Items tpl to check parents of
@ -432,6 +442,13 @@ export declare class ItemHelper {
* @returns A Map where the keys are the item IDs and the values are the corresponding Item objects.
*/
generateItemsMap(items: Item[]): Map<string, Item>;
/**
* Add a blank upd object to passed in item if it does not exist already
* @param item item to add upd to
* @param warningMessageWhenMissing text to write to log when upd object was not found
* @returns True when upd object was added
*/
addUpdObjectToItem(item: Item, warningMessageWhenMissing?: string): boolean;
}
declare namespace ItemHelper {
interface ItemSize {

View File

@ -38,4 +38,10 @@ export declare class PresetHelper {
*/
getDefaultPreset(templateId: string): IPreset;
getBaseItemTpl(presetId: string): string;
/**
* Return the price of the preset for the given item tpl, or for the tpl itself if no preset exists
* @param tpl The item template to get the price of
* @returns The price of the given item preset, or base item if no preset exists
*/
getDefaultPresetOrItemPrice(tpl: string): number;
}

View File

@ -4,17 +4,21 @@ import { Common, CounterKeyValue, Stats } from "@spt-aki/models/eft/common/table
import { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile";
import { IValidateNicknameRequestData } from "@spt-aki/models/eft/profile/IValidateNicknameRequestData";
import { SkillTypes } from "@spt-aki/models/enums/SkillTypes";
import { IInventoryConfig } from "@spt-aki/models/spt/config/IInventoryConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { SaveServer } from "@spt-aki/servers/SaveServer";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { ProfileSnapshotService } from "@spt-aki/services/ProfileSnapshotService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
import { Watermark } from "@spt-aki/utils/Watermark";
export declare class ProfileHelper {
protected logger: ILogger;
protected jsonUtil: JsonUtil;
protected hashUtil: HashUtil;
protected watermark: Watermark;
protected timeUtil: TimeUtil;
protected saveServer: SaveServer;
@ -22,7 +26,9 @@ export declare class ProfileHelper {
protected itemHelper: ItemHelper;
protected profileSnapshotService: ProfileSnapshotService;
protected localisationService: LocalisationService;
constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, localisationService: LocalisationService);
protected configServer: ConfigServer;
protected inventoryConfig: IInventoryConfig;
constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, localisationService: LocalisationService, configServer: ConfigServer);
/**
* Remove/reset a completed quest condtion from players profile quest data
* @param sessionID Session id
@ -34,6 +40,11 @@ export declare class ProfileHelper {
* @returns Dictionary of profiles
*/
getProfiles(): Record<string, IAkiProfile>;
/**
* Get the pmc and scav profiles as an array by profile id
* @param sessionID
* @returns Array of IPmcData objects
*/
getCompleteProfile(sessionID: string): IPmcData[];
/**
* Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
@ -45,37 +56,70 @@ export declare class ProfileHelper {
* @param output pmc and scav profiles array
* @param pmcProfile post-raid pmc profile
* @param scavProfile post-raid scav profile
* @returns updated profile array
* @returns Updated profile array
*/
protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
/**
* Check if a nickname is used by another profile loaded by the server
* @param nicknameRequest
* @param nicknameRequest nickname request object
* @param sessionID Session id
* @returns True if already used
*/
isNicknameTaken(nicknameRequest: IValidateNicknameRequestData, sessionID: string): boolean;
protected profileHasInfoProperty(profile: IAkiProfile): boolean;
protected nicknameMatches(profileName: string, nicknameRequest: string): boolean;
protected sessionIdMatchesProfileId(profileId: string, sessionId: string): boolean;
protected stringsMatch(stringA: string, stringB: string): boolean;
/**
* Add experience to a PMC inside the players profile
* @param sessionID Session id
* @param experienceToAdd Experience to add to PMC character
*/
addExperienceToPmc(sessionID: string, experienceToAdd: number): void;
/**
* Iterate all profiles and find matching pmc profile by provided id
* @param pmcId Profile id to find
* @returns IPmcData
*/
getProfileByPmcId(pmcId: string): IPmcData;
/**
* Get the experiecne for the given level
* @param level level to get xp for
* @returns Number of xp points for level
*/
getExperience(level: number): number;
/**
* Get the max level a player can be
* @returns Max level
*/
getMaxLevel(): number;
getDefaultAkiDataObject(): any;
/**
* Get full representation of a players profile json
* @param sessionID Profile id to get
* @returns IAkiProfile object
*/
getFullProfile(sessionID: string): IAkiProfile;
/**
* Get a PMC profile by its session id
* @param sessionID Profile id to return
* @returns IPmcData object
*/
getPmcProfile(sessionID: string): IPmcData;
/**
* Get a full profiles scav-specific sub-profile
* @param sessionID Profiles id
* @returns IPmcData object
*/
getScavProfile(sessionID: string): IPmcData;
/**
* Get baseline counter values for a fresh profile
* @returns Stats
* @returns Default profile Stats object
*/
getDefaultCounters(): Stats;
/**
* is this profile flagged for data removal
* @param sessionID Profile id
* @returns True if profile is to be wiped of data/progress
*/
protected isWiped(sessionID: string): boolean;
protected getServerVersion(): string;
/**
@ -120,6 +164,23 @@ export declare class ProfileHelper {
* @returns
*/
addSkillPointsToPlayer(pmcProfile: IPmcData, skill: SkillTypes, pointsToAdd: number, useSkillProgressRateMultipler?: boolean): void;
/**
* Get a speciic common skill from supplied profile
* @param pmcData Player profile
* @param skill Skill get get
* @returns Common skill object from desired profile
*/
getSkillFromProfile(pmcData: IPmcData, skill: SkillTypes): Common;
/**
* Is the provided session id for a developer account
* @param sessionID Profile id ot check
* @returns True if account is developer
*/
isDeveloperAccount(sessionID: string): boolean;
/**
* Add stash row bonus to profile or increments rows given count if it already exists
* @param sessionId Profile id to give rows to
* @param rowsToAdd How many rows to give profile
*/
addStashRowsBonusToProfile(sessionId: string, rowsToAdd: number): void;
}

View File

@ -178,9 +178,8 @@ export declare class QuestHelper {
* @param failRequest Fail quest request data
* @param sessionID Session id
* @param output Client output
* @returns Item event router response
*/
failQuest(pmcData: IPmcData, failRequest: IFailQuestRequestData, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
failQuest(pmcData: IPmcData, failRequest: IFailQuestRequestData, sessionID: string, output?: IItemEventRouterResponse): void;
/**
* Get List of All Quests from db
* NOT CLONED

View File

@ -53,6 +53,12 @@ export declare class RagfairServerHelper {
* @returns True if its blacklsited
*/
protected isItemOnCustomFleaBlacklist(itemTemplateId: string): boolean;
/**
* Is supplied parent id on the ragfair custom item category blacklist
* @param parentId Parent Id to check is blacklisted
* @returns true if blacklisted
*/
protected isItemCategoryOnCustomFleaBlacklist(itemParentId: string): boolean;
/**
* is supplied id a trader
* @param traderId

View File

@ -54,6 +54,7 @@ export interface Info {
LowerNickname: string;
Side: string;
SquadInviteRestriction: boolean;
HasCoopExtension: boolean;
Voice: string;
Level: number;
Experience: number;
@ -314,8 +315,8 @@ export interface Productive {
sptIsComplete?: boolean;
/** Is the craft a Continuous, e.g bitcoins/water collector */
sptIsContinuous?: boolean;
/** Stores a list of tools used in this craft, to give back once the craft is done */
sptRequiredTools?: string[];
/** Stores a list of tools used in this craft and whether they're FiR, to give back once the craft is done */
sptRequiredTools?: Item[];
}
export interface Production extends Productive {
RecipeId: string;

View File

@ -0,0 +1,2 @@
export interface IDeclineGroupInviteRequest {
}

View File

@ -62,6 +62,7 @@ export declare enum BackendErrorCodes {
BANNEDERRORCODE = 1513,
INSUFFICIENTNUMBERINSTOCK = 1516,
TOOMANYITEMSTOSELL = 1517,
INCORRECTCLIENTPRICE = 1519,
EXAMINATIONFAILED = 22001,
ITEMALREADYEXAMINED = 22002,
UNKNOWNNGINXERROR = 9000,
@ -81,5 +82,6 @@ export declare enum BackendErrorCodes {
PLAYERISNOTSEARCHINGFORGROUP = 502018,
PLAYERALREADYLOOKINGFORGAME = 503001,
PLAYERINRAID = 503002,
LIMITFORPRESETSREACHED = 504001
LIMITFORPRESETSREACHED = 504001,
PLAYERPROFILENOTFOUND = 505001
}

View File

@ -28,5 +28,6 @@ export declare enum BonusType {
STASH_SIZE = "StashSize",
MAXIMUM_ENERGY_RESERVE = "MaximumEnergyReserve",
TEXT_BONUS = "TextBonus",
SKILL_GROUP_LEVELING_BOOST = "SkillGroupLevelingBoost"
SKILL_GROUP_LEVELING_BOOST = "SkillGroupLevelingBoost",
STASH_ROWS = "StashRows"
}

View File

@ -1,6 +0,0 @@
export declare enum AddItemToContainerResult {
UNKONWN_FAILURE = 0,
HIT_SPAWN_LIMIT = 1,
HIT_ROUBLE_LIMIT = 2,
SUCCESS = 3
}

View File

@ -37,6 +37,8 @@ export interface IBotConfig extends IBaseConfig {
botRolesWithDogTags: string[];
/** Settings to control the items that get added into wallets on bots */
walletLoot: IWalletLootSettings;
/** Currency weights, Keyed by botrole / currency */
currencyStackSize: Record<string, Record<string, Record<string, number>>>;
}
/** Number of bots to generate and store in cache on raid start per bot type */
export interface PresetBatch {
@ -78,8 +80,13 @@ export interface PresetBatch {
sptBear: number;
}
export interface IWalletLootSettings {
itemCount: number;
/** Chance wallets have loot in them */
chancePercent: number;
itemCount: MinMax;
stackSizeWeight: Record<string, number>;
currencyWeight: Record<string, number>;
/** What wallets will have money in them */
walletTplPool: string[];
}
export interface EquipmentFilters {
/** Limits for mod types per weapon .e.g. scopes */

View File

@ -7,6 +7,7 @@ export interface ICoreConfig extends IBaseConfig {
serverName: string;
profileSaveIntervalSeconds: number;
sptFriendNickname: string;
release: IRelease;
fixes: IGameFixes;
features: IServerFeatures;
/** Commit hash build server was created from */
@ -14,6 +15,21 @@ export interface ICoreConfig extends IBaseConfig {
/** Timestamp of server build */
buildTime?: string;
}
export interface IRelease {
betaDisclaimerText?: string;
betaDisclaimerAcceptText: string;
serverModsLoadedText: string;
serverModsLoadedDebugText: string;
clientModsLoadedText: string;
clientModsLoadedDebugText: string;
illegalPluginsLoadedText: string;
illegalPluginsExceptionText: string;
releaseSummaryText?: string;
isBeta?: boolean;
isModdable?: boolean;
isModded: boolean;
betaDisclaimerTimeoutDelay: number;
}
export interface IGameFixes {
/** Shotguns use a different value than normal guns causing huge pellet dispersion */
fixShotgunDispersion: boolean;

View File

@ -8,6 +8,8 @@ export interface IInventoryConfig extends IBaseConfig {
sealedAirdropContainer: ISealedAirdropContainerSettings;
/** Contains item tpls that the server should consider money and treat the same as roubles/euros/dollars */
customMoneyTpls: string[];
/** Multipliers for skill gain when inside menus, NOT in-game */
skillGainMultiplers: Record<string, number>;
}
export interface RewardDetails {
rewardCount: number;

View File

@ -16,6 +16,7 @@ export interface Equipment {
ArmorVest: boolean;
Eyewear: boolean;
TacticalVest: boolean;
PocketItems: boolean;
Backpack: boolean;
Holster: boolean;
FirstPrimaryWeapon: boolean;

View File

@ -13,7 +13,6 @@ export interface IPmcConfig extends IBaseConfig {
pocketLoot: SlotLootSettings;
/** Global whitelist/blacklist of backpack loot for PMCs */
backpackLoot: SlotLootSettings;
dynamicLoot: DynamicLoot;
/** Use difficulty defined in config/bot.json/difficulty instead of chosen difficulty dropdown value */
useDifficultyOverride: boolean;
/** Difficulty override e.g. "AsOnline/Hard" */
@ -55,8 +54,4 @@ export interface PmcTypes {
export interface SlotLootSettings {
whitelist: string[];
blacklist: string[];
moneyStackLimits: Record<string, number>;
}
export interface DynamicLoot {
moneyStackLimits: Record<string, number>;
}

View File

@ -16,9 +16,7 @@ export interface Sell {
/** Settings to control chances of offer being sold */
chance: Chance;
/** Settings to control how long it takes for a player offer to sell */
time: Time;
/** Player offer reputation gain/loss settings */
reputation: Reputation;
time: MinMax;
/**Seconds from clicking remove to remove offer from market */
expireSeconds: number;
}
@ -32,13 +30,6 @@ export interface Chance {
/** Min possible sell chance % for a player listed offer */
minSellChancePercent: number;
}
export interface Time extends MinMax {
base: number;
}
export interface Reputation {
gain: number;
loss: number;
}
export interface Dynamic {
purchasesAreFoundInRaid: boolean;
/** Use the highest trader price for an offer if its greater than the price in templates/prices.json */
@ -138,6 +129,10 @@ export interface Blacklist {
traderItems: boolean;
/** Maximum level an armor plate can be found in a flea-listed armor item */
armorPlate: IArmorPlateBlacklistSettings;
/** Should specific categories be blacklisted from the flea, true = use blacklist */
enableCustomItemCategoryList: boolean;
/** Custom category blacklist for parent Ids */
customItemCategoryList: string[];
}
export interface IArmorPlateBlacklistSettings {
/** Max level of plates an armor can have without being removed */

View File

@ -5,6 +5,8 @@ export interface ITraderConfig extends IBaseConfig {
kind: "aki-trader";
updateTime: UpdateTime[];
purchasesAreFoundInRaid: boolean;
/** Should trader reset times be set based on server start time (false = bsg time - on the hour) */
tradersResetFromServerStart: boolean;
updateTimeDefault: number;
traderPriceMultipler: number;
/** Keep track of purchased trader-limited items beyond server restarts to prevent server-restart item scumming */
@ -13,6 +15,7 @@ export interface ITraderConfig extends IBaseConfig {
}
export interface UpdateTime {
traderId: string;
/** Seconds between trader resets */
seconds: number;
}
export interface FenceConfig {
@ -30,6 +33,8 @@ export interface FenceConfig {
/** Key: item tpl */
itemStackSizeOverrideMinMax: Record<string, MinMax>;
itemTypeLimits: Record<string, number>;
/** Prevent duplicate offers of items of specific categories by parentId*/
preventDuplicateOffersOfCategory: string[];
regenerateAssortsOnRefresh: boolean;
/** Max rouble price before item is not listed on flea */
itemCategoryRoublePriceLimit: Record<string, number>;

View File

@ -8,4 +8,11 @@ export interface ITraderServiceModel {
subServices?: {
[key: string]: number;
};
requirements?: ITraderServiceRequirementsModel;
}
export interface ITraderServiceRequirementsModel {
completedQuests?: string[];
standings?: {
[key: string]: number;
};
}

View File

@ -39,8 +39,6 @@ export declare class FenceService {
protected fenceDiscountAssort: ITraderAssort;
/** Hydrated on initial assort generation as part of generateFenceAssorts() */
protected desiredAssortCounts: IFenceAssortGenerationValues;
/** Items that have a multi-stack */
protected multiStackItems: Record<string, boolean>;
constructor(logger: ILogger, jsonUtil: JsonUtil, timeUtil: TimeUtil, randomUtil: RandomUtil, databaseServer: DatabaseServer, handbookHelper: HandbookHelper, itemHelper: ItemHelper, presetHelper: PresetHelper, localisationService: LocalisationService, configServer: ConfigServer);
/**
* Replace main fence assort with new assort
@ -162,6 +160,22 @@ export declare class FenceService {
current: number;
max: number;
}>, loyaltyLevel: number): void;
/**
* Find an assort item that matches the first parameter, also matches based on upd properties
* e.g. salewa hp resource units left
* @param rootItemBeingAdded item to look for a match against
* @param itemDbDetails Db details of matching item
* @param fenceItemAssorts Items to search through
* @returns Matching assort item
*/
protected getMatchingItem(rootItemBeingAdded: Item, itemDbDetails: ITemplateItem, fenceItemAssorts: Item[]): Item;
/**
* Should this item be forced into only 1 stack on fence
* @param existingItem Existing item from fence assort
* @param itemDbDetails Item we want to add db details
* @returns True item should be force stacked
*/
protected itemShouldBeForceStacked(existingItem: Item, itemDbDetails: ITemplateItem): boolean;
/**
* Adjust price of item based on what is left to buy (resource/uses left)
* @param barterSchemes All barter scheme for item having price adjusted

View File

@ -70,12 +70,6 @@ export declare class InsuranceService {
* @param mapId Id of the map player died/exited that caused the insurance to be issued on
*/
sendInsuredItems(pmcData: IPmcData, sessionID: string, mapId: string): void;
/**
* Send a message to player informing them gear was completely lost
* @param sessionId Session id
* @param locationName name of map insurance was lost on
*/
sendLostInsuranceMessage(sessionId: string, locationName?: string): void;
/**
* Check all root insured items and remove location property + set slotId to 'hideout'
* @param sessionId Session id

View File

@ -1,4 +1,3 @@
import { ICreateGroupRequestData } from "@spt-aki/models/eft/match/ICreateGroupRequestData";
import { SaveServer } from "@spt-aki/servers/SaveServer";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class MatchLocationService {
@ -6,6 +5,5 @@ export declare class MatchLocationService {
protected saveServer: SaveServer;
protected locations: {};
constructor(timeUtil: TimeUtil, saveServer: SaveServer);
createGroup(sessionID: string, info: ICreateGroupRequestData): any;
deleteGroup(info: any): void;
}

View File

@ -1,9 +1,13 @@
import { ITraderServiceModel } from "@spt-aki/models/spt/services/ITraderServiceModel";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
export declare class TraderServicesService {
protected profileHelper: ProfileHelper;
protected jsonUtil: JsonUtil;
protected logger: ILogger;
protected databaseServer: DatabaseServer;
constructor(logger: ILogger, databaseServer: DatabaseServer);
getTraderServices(traderId: string): ITraderServiceModel[];
constructor(profileHelper: ProfileHelper, jsonUtil: JsonUtil, logger: ILogger, databaseServer: DatabaseServer);
getTraderServices(sessionId: string, traderId: string): ITraderServiceModel[];
}

View File

@ -4,6 +4,7 @@ import { CreateItemResult, LocaleDetails, NewItemDetails, NewItemFromCloneDetail
import { IDatabaseTables } from "@spt-aki/models/spt/server/IDatabaseTables";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemBaseClassService } from "@spt-aki/services/ItemBaseClassService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
export declare class CustomItemService {
@ -12,8 +13,9 @@ export declare class CustomItemService {
protected jsonUtil: JsonUtil;
protected databaseServer: DatabaseServer;
protected itemHelper: ItemHelper;
protected itemBaseClassService: ItemBaseClassService;
protected tables: IDatabaseTables;
constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper);
constructor(logger: ILogger, hashUtil: HashUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, itemBaseClassService: ItemBaseClassService);
/**
* Create a new item from a cloned item base
* WARNING - If no item id is supplied, an id will be generated, this id will be random every time you add an item and will not be the same on each subsequent server start
@ -79,6 +81,11 @@ export declare class CustomItemService {
* @param fleaPriceRoubles Price of the new item
*/
protected addToFleaPriceDb(newItemId: string, fleaPriceRoubles: number): void;
/**
* Add a weapon to the hideout weapon shelf whitelist
* @param newItemId Weapon id to add
*/
protected addToWeaponShelf(newItemId: string): void;
/**
* Add a custom weapon to PMCs loadout
* @param weaponTpl Custom weapon tpl to add to PMCs

View File

@ -61,4 +61,5 @@ export declare class TimeUtil {
* @returns {number} The equivalent number of seconds.
*/
getHoursAsSeconds(hours: number): number;
getTimestampOfNextHour(): number;
}

View File

@ -46,8 +46,8 @@ export declare class VFS {
removeDirAsync(filepath: string): Promise<void>;
rename(oldPath: string, newPath: string): void;
renameAsync(oldPath: string, newPath: string): Promise<void>;
protected lockFileSync(filepath: any): void;
protected checkFileSync(filepath: any): any;
protected lockFileSync(filepath: any): () => void;
protected checkFileSync(filepath: any): boolean;
protected unlockFileSync(filepath: any): void;
getFileExtension(filepath: string): string;
stripExtension(filepath: string): string;

View File

@ -1,14 +1,24 @@
import { ClientLogController } from "@spt-aki/controllers/ClientLogController";
import { ModLoadOrder } from "@spt-aki/loaders/ModLoadOrder";
import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData";
import { IClientLogRequest } from "@spt-aki/models/spt/logging/IClientLogRequest";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
/** Handle client logging related events */
export declare class ClientLogCallbacks {
protected httpResponse: HttpResponseUtil;
protected clientLogController: ClientLogController;
constructor(httpResponse: HttpResponseUtil, clientLogController: ClientLogController);
protected configServer: ConfigServer;
protected localisationService: LocalisationService;
protected modLoadOrder: ModLoadOrder;
constructor(httpResponse: HttpResponseUtil, clientLogController: ClientLogController, configServer: ConfigServer, localisationService: LocalisationService, modLoadOrder: ModLoadOrder);
/**
* Handle /singleplayer/log
*/
clientLog(url: string, info: IClientLogRequest, sessionID: string): INullResponseData;
/**
* Handle /singleplayer/release
*/
releaseNotes(): string;
}

View File

@ -9,5 +9,11 @@ export declare class ItemEventCallbacks {
protected itemEventRouter: ItemEventRouter;
constructor(httpResponse: HttpResponseUtil, itemEventRouter: ItemEventRouter);
handleEvents(url: string, info: IItemEventRouterRequest, sessionID: string): IGetBodyResponseData<IItemEventRouterResponse>;
/**
* Return true if the passed in list of warnings contains critical issues
* @param warnings The list of warnings to check for critical errors
* @returns
*/
private isCriticalError;
protected getErrorCode(warnings: Warning[]): number;
}

View File

@ -1,16 +1,14 @@
import { MatchController } from "@spt-aki/controllers/MatchController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { IGetBodyResponseData } from "@spt-aki/models/eft/httpResponse/IGetBodyResponseData";
import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData";
import { IAcceptGroupInviteRequest } from "@spt-aki/models/eft/match/IAcceptGroupInviteRequest";
import { IAcceptGroupInviteResponse } from "@spt-aki/models/eft/match/IAcceptGroupInviteResponse";
import { ICancelGroupInviteRequest } from "@spt-aki/models/eft/match/ICancelGroupInviteRequest";
import { ICreateGroupRequestData } from "@spt-aki/models/eft/match/ICreateGroupRequestData";
import { IDeclineGroupInviteRequest } from "@spt-aki/models/eft/match/IDeclineGroupInviteRequest";
import { IEndOfflineRaidRequestData } from "@spt-aki/models/eft/match/IEndOfflineRaidRequestData";
import { IGetGroupStatusRequestData } from "@spt-aki/models/eft/match/IGetGroupStatusRequestData";
import { IGetGroupStatusResponse } from "@spt-aki/models/eft/match/IGetGroupStatusResponse";
import { IGetProfileRequestData } from "@spt-aki/models/eft/match/IGetProfileRequestData";
import { IGetRaidConfigurationRequestData } from "@spt-aki/models/eft/match/IGetRaidConfigurationRequestData";
import { IJoinMatchRequestData } from "@spt-aki/models/eft/match/IJoinMatchRequestData";
import { IJoinMatchResult } from "@spt-aki/models/eft/match/IJoinMatchResult";
@ -39,6 +37,8 @@ export declare class MatchCallbacks {
sendGroupInvite(url: string, info: ISendGroupInviteRequest, sessionID: string): IGetBodyResponseData<string>;
/** Handle client/match/group/invite/accept */
acceptGroupInvite(url: string, info: IAcceptGroupInviteRequest, sessionID: string): IGetBodyResponseData<IAcceptGroupInviteResponse[]>;
/** Handle client/match/group/invite/decline */
declineGroupInvite(url: string, info: IDeclineGroupInviteRequest, sessionID: string): IGetBodyResponseData<any>;
/** Handle client/match/group/invite/cancel */
cancelGroupInvite(url: string, info: ICancelGroupInviteRequest, sessionID: string): IGetBodyResponseData<boolean>;
/** Handle client/match/group/transfer */
@ -47,8 +47,6 @@ export declare class MatchCallbacks {
cancelAllGroupInvite(url: string, info: any, sessionID: string): INullResponseData;
/** @deprecated - not called on raid start/end or game start/exit */
putMetrics(url: string, info: IPutMetricsRequestData, sessionID: string): INullResponseData;
/** Handle raid/profile/list */
getProfile(url: string, info: IGetProfileRequestData, sessionID: string): IGetBodyResponseData<IPmcData[]>;
serverAvailable(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<boolean>;
/** Handle match/group/start_game */
joinMatch(url: string, info: IJoinMatchRequestData, sessionID: string): IGetBodyResponseData<IJoinMatchResult>;
@ -60,8 +58,6 @@ export declare class MatchCallbacks {
* @returns
*/
getGroupStatus(url: string, info: IGetGroupStatusRequestData, sessionID: string): IGetBodyResponseData<IGetGroupStatusResponse>;
/** Handle client/match/group/create */
createGroup(url: string, info: ICreateGroupRequestData, sessionID: string): IGetBodyResponseData<any>;
/** Handle client/match/group/delete */
deleteGroup(url: string, info: any, sessionID: string): INullResponseData;
leaveGroup(url: string, info: IEmptyRequestData, sessionID: string): IGetBodyResponseData<boolean>;

View File

@ -3,11 +3,9 @@ import { LootGenerator } from "@spt-aki/generators/LootGenerator";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { ICreateGroupRequestData } from "@spt-aki/models/eft/match/ICreateGroupRequestData";
import { IEndOfflineRaidRequestData } from "@spt-aki/models/eft/match/IEndOfflineRaidRequestData";
import { IGetGroupStatusRequestData } from "@spt-aki/models/eft/match/IGetGroupStatusRequestData";
import { IGetGroupStatusResponse } from "@spt-aki/models/eft/match/IGetGroupStatusResponse";
import { IGetProfileRequestData } from "@spt-aki/models/eft/match/IGetProfileRequestData";
import { IGetRaidConfigurationRequestData } from "@spt-aki/models/eft/match/IGetRaidConfigurationRequestData";
import { IJoinMatchRequestData } from "@spt-aki/models/eft/match/IJoinMatchRequestData";
import { IJoinMatchResult } from "@spt-aki/models/eft/match/IJoinMatchResult";
@ -48,10 +46,6 @@ export declare class MatchController {
protected pmcConfig: IPmcConfig;
constructor(logger: ILogger, saveServer: SaveServer, timeUtil: TimeUtil, randomUtil: RandomUtil, hashUtil: HashUtil, profileHelper: ProfileHelper, matchLocationService: MatchLocationService, traderHelper: TraderHelper, botLootCacheService: BotLootCacheService, configServer: ConfigServer, profileSnapshotService: ProfileSnapshotService, botGenerationCacheService: BotGenerationCacheService, mailSendService: MailSendService, lootGenerator: LootGenerator, applicationContext: ApplicationContext);
getEnabled(): boolean;
/** Handle raid/profile/list */
getProfile(info: IGetProfileRequestData): IPmcData[];
/** Handle client/match/group/create */
createGroup(sessionID: string, info: ICreateGroupRequestData): any;
/** Handle client/match/group/delete */
deleteGroup(info: any): void;
/** Handle match/group/start_game */

View File

@ -1,3 +1,4 @@
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
import { RepairHelper } from "@spt-aki/helpers/RepairHelper";
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
@ -20,8 +21,9 @@ export declare class RepairController {
protected paymentService: PaymentService;
protected repairHelper: RepairHelper;
protected repairService: RepairService;
protected profileHelper: ProfileHelper;
protected repairConfig: IRepairConfig;
constructor(logger: ILogger, eventOutputHolder: EventOutputHolder, databaseServer: DatabaseServer, questHelper: QuestHelper, traderHelper: TraderHelper, paymentService: PaymentService, repairHelper: RepairHelper, repairService: RepairService);
constructor(logger: ILogger, eventOutputHolder: EventOutputHolder, databaseServer: DatabaseServer, questHelper: QuestHelper, traderHelper: TraderHelper, paymentService: PaymentService, repairHelper: RepairHelper, repairService: RepairService, profileHelper: ProfileHelper);
/**
* Handle TraderRepair event
* Repair with trader

View File

@ -1,7 +1,6 @@
import { RepeatableQuestGenerator } from "@spt-aki/generators/RepeatableQuestGenerator";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
import { RagfairServerHelper } from "@spt-aki/helpers/RagfairServerHelper";
import { RepeatableQuestHelper } from "@spt-aki/helpers/RepeatableQuestHelper";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
@ -31,7 +30,6 @@ export declare class RepeatableQuestController {
protected jsonUtil: JsonUtil;
protected profileHelper: ProfileHelper;
protected profileFixerService: ProfileFixerService;
protected ragfairServerHelper: RagfairServerHelper;
protected eventOutputHolder: EventOutputHolder;
protected paymentService: PaymentService;
protected objectId: ObjectId;
@ -40,7 +38,7 @@ export declare class RepeatableQuestController {
protected questHelper: QuestHelper;
protected configServer: ConfigServer;
protected questConfig: IQuestConfig;
constructor(logger: ILogger, databaseServer: DatabaseServer, timeUtil: TimeUtil, randomUtil: RandomUtil, httpResponse: HttpResponseUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, paymentService: PaymentService, objectId: ObjectId, repeatableQuestGenerator: RepeatableQuestGenerator, repeatableQuestHelper: RepeatableQuestHelper, questHelper: QuestHelper, configServer: ConfigServer);
constructor(logger: ILogger, databaseServer: DatabaseServer, timeUtil: TimeUtil, randomUtil: RandomUtil, httpResponse: HttpResponseUtil, jsonUtil: JsonUtil, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, eventOutputHolder: EventOutputHolder, paymentService: PaymentService, objectId: ObjectId, repeatableQuestGenerator: RepeatableQuestGenerator, repeatableQuestHelper: RepeatableQuestHelper, questHelper: QuestHelper, configServer: ConfigServer);
/**
* Handle client/repeatalbeQuests/activityPeriods
* Returns an array of objects in the format of repeatable quests to the client.

View File

@ -3,14 +3,18 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { TraderAssortHelper } from "@spt-aki/helpers/TraderAssortHelper";
import { TraderHelper } from "@spt-aki/helpers/TraderHelper";
import { ITraderAssort, ITraderBase } from "@spt-aki/models/eft/common/tables/ITrader";
import { ITraderConfig } from "@spt-aki/models/spt/config/ITraderConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { FenceService } from "@spt-aki/services/FenceService";
import { TraderAssortService } from "@spt-aki/services/TraderAssortService";
import { TraderPurchasePersisterService } from "@spt-aki/services/TraderPurchasePersisterService";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class TraderController {
protected logger: ILogger;
protected timeUtil: TimeUtil;
protected databaseServer: DatabaseServer;
protected traderAssortHelper: TraderAssortHelper;
protected profileHelper: ProfileHelper;
@ -20,10 +24,12 @@ export declare class TraderController {
protected fenceService: FenceService;
protected fenceBaseAssortGenerator: FenceBaseAssortGenerator;
protected jsonUtil: JsonUtil;
constructor(logger: ILogger, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, traderAssortService: TraderAssortService, traderPurchasePersisterService: TraderPurchasePersisterService, fenceService: FenceService, fenceBaseAssortGenerator: FenceBaseAssortGenerator, jsonUtil: JsonUtil);
protected configServer: ConfigServer;
protected traderConfig: ITraderConfig;
constructor(logger: ILogger, timeUtil: TimeUtil, databaseServer: DatabaseServer, traderAssortHelper: TraderAssortHelper, profileHelper: ProfileHelper, traderHelper: TraderHelper, traderAssortService: TraderAssortService, traderPurchasePersisterService: TraderPurchasePersisterService, fenceService: FenceService, fenceBaseAssortGenerator: FenceBaseAssortGenerator, jsonUtil: JsonUtil, configServer: ConfigServer);
/**
* Runs when onLoad event is fired
* Iterate over traders, ensure an unmolested copy of their assorts is stored in traderAssortService
* Iterate over traders, ensure a pristine copy of their assorts is stored in traderAssortService
* Store timestamp of next assort refresh in nextResupply property of traders .base object
*/
load(): void;

View File

@ -89,8 +89,9 @@ export declare class BotLootGenerator {
* @param itemToAddTemplate Db template of item to check
* @param itemToAddChildrenTo Item to add children to
* @param isPmc Is the item being generated for a pmc (affects money/ammo stack sizes)
* @param botRole role bot has that owns item
*/
protected addRequiredChildItemsToParent(itemToAddTemplate: ITemplateItem, itemToAddChildrenTo: Item[], isPmc: boolean): void;
protected addRequiredChildItemsToParent(itemToAddTemplate: ITemplateItem, itemToAddChildrenTo: Item[], isPmc: boolean, botRole: string): void;
/**
* Add generated weapons to inventory as loot
* @param botInventory inventory to add preset to
@ -118,11 +119,11 @@ export declare class BotLootGenerator {
protected itemHasReachedSpawnLimit(itemTemplate: ITemplateItem, botRole: string, itemSpawnLimits: IItemSpawnLimitSettings): boolean;
/**
* Randomise the stack size of a money object, uses different values for pmc or scavs
* @param isPmc Is money on a PMC bot
* @param botRole Role bot has that has money stack
* @param itemTemplate item details from db
* @param moneyItem Money item to randomise
*/
protected randomiseMoneyStackSize(isPmc: boolean, itemTemplate: ITemplateItem, moneyItem: Item): void;
protected randomiseMoneyStackSize(botRole: string, itemTemplate: ITemplateItem, moneyItem: Item): void;
/**
* Randomise the size of an ammo stack
* @param isPmc Is ammo on a PMC bot

View File

@ -1,54 +1,34 @@
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { RepeatableQuestRewardGenerator } from "@spt-aki/generators/RepeatableQuestRewardGenerator";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { RagfairServerHelper } from "@spt-aki/helpers/RagfairServerHelper";
import { RepeatableQuestHelper } from "@spt-aki/helpers/RepeatableQuestHelper";
import { Exit } from "@spt-aki/models/eft/common/ILocationBase";
import { TraderInfo } from "@spt-aki/models/eft/common/tables/IBotBase";
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
import { IQuestCondition, IQuestConditionCounterCondition, IQuestReward, IQuestRewards } from "@spt-aki/models/eft/common/tables/IQuest";
import { IQuestCondition, IQuestConditionCounterCondition } from "@spt-aki/models/eft/common/tables/IQuest";
import { IRepeatableQuest } from "@spt-aki/models/eft/common/tables/IRepeatableQuests";
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
import { IBaseQuestConfig, IBossInfo, IEliminationConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig";
import { IBossInfo, IEliminationConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig";
import { IQuestTypePool } from "@spt-aki/models/spt/repeatable/IQuestTypePool";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { EventOutputHolder } from "@spt-aki/routers/EventOutputHolder";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemFilterService } from "@spt-aki/services/ItemFilterService";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { PaymentService } from "@spt-aki/services/PaymentService";
import { ProfileFixerService } from "@spt-aki/services/ProfileFixerService";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { MathUtil } from "@spt-aki/utils/MathUtil";
import { ObjectId } from "@spt-aki/utils/ObjectId";
import { ProbabilityObjectArray, RandomUtil } from "@spt-aki/utils/RandomUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class RepeatableQuestGenerator {
protected timeUtil: TimeUtil;
protected logger: ILogger;
protected randomUtil: RandomUtil;
protected httpResponse: HttpResponseUtil;
protected mathUtil: MathUtil;
protected jsonUtil: JsonUtil;
protected databaseServer: DatabaseServer;
protected itemHelper: ItemHelper;
protected presetHelper: PresetHelper;
protected profileHelper: ProfileHelper;
protected profileFixerService: ProfileFixerService;
protected handbookHelper: HandbookHelper;
protected ragfairServerHelper: RagfairServerHelper;
protected eventOutputHolder: EventOutputHolder;
protected localisationService: LocalisationService;
protected paymentService: PaymentService;
protected objectId: ObjectId;
protected itemFilterService: ItemFilterService;
protected repeatableQuestHelper: RepeatableQuestHelper;
protected repeatableQuestRewardGenerator: RepeatableQuestRewardGenerator;
protected configServer: ConfigServer;
protected questConfig: IQuestConfig;
constructor(timeUtil: TimeUtil, logger: ILogger, randomUtil: RandomUtil, httpResponse: HttpResponseUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, profileFixerService: ProfileFixerService, handbookHelper: HandbookHelper, ragfairServerHelper: RagfairServerHelper, eventOutputHolder: EventOutputHolder, localisationService: LocalisationService, paymentService: PaymentService, objectId: ObjectId, itemFilterService: ItemFilterService, repeatableQuestHelper: RepeatableQuestHelper, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, localisationService: LocalisationService, objectId: ObjectId, repeatableQuestHelper: RepeatableQuestHelper, repeatableQuestRewardGenerator: RepeatableQuestRewardGenerator, configServer: ConfigServer);
/**
* This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json).
* It randomly draws a quest type (currently Elimination, Completion or Exploration) as well as a trader who is providing the quest
@ -144,71 +124,6 @@ export declare class RepeatableQuestGenerator {
* @returns {object} Exit condition
*/
protected generateExplorationExitCondition(exit: Exit): IQuestConditionCounterCondition;
/**
* Generate the reward for a mission. A reward can consist of
* - Experience
* - Money
* - Items
* - Trader Reputation
*
* The reward is dependent on the player level as given by the wiki. The exact mapping of pmcLevel to
* experience / money / items / trader reputation can be defined in QuestConfig.js
*
* There's also a random variation of the reward the spread of which can be also defined in the config.
*
* Additionally, a scaling factor w.r.t. quest difficulty going from 0.2...1 can be used
*
* @param {integer} pmcLevel player's level
* @param {number} difficulty a reward scaling factor from 0.2 to 1
* @param {string} traderId the trader for reputation gain (and possible in the future filtering of reward item type based on trader)
* @param {object} repeatableConfig The configuration for the repeatable kind (daily, weekly) as configured in QuestConfig for the requested quest
* @returns {object} object of "Reward"-type that can be given for a repeatable mission
*/
protected generateReward(pmcLevel: number, difficulty: number, traderId: string, repeatableConfig: IRepeatableQuestConfig, questConfig: IBaseQuestConfig): IQuestRewards;
protected addMoneyReward(traderId: string, rewards: IQuestRewards, rewardRoubles: number, rewardIndex: number): void;
protected calculateAmmoStackSizeThatFitsBudget(itemSelected: ITemplateItem, roublesBudget: number, rewardNumItems: number): number;
/**
* Should reward item have stack size increased (25% chance)
* @param item Item to possibly increase stack size of
* @param maxRoublePriceToStack Maximum rouble price an item can be to still be chosen for stacking
* @returns True if it should
*/
protected canIncreaseRewardItemStackSize(item: ITemplateItem, maxRoublePriceToStack: number): boolean;
/**
* Get a randomised number a reward items stack size should be based on its handbook price
* @param item Reward item to get stack size for
* @returns Stack size value
*/
protected getRandomisedRewardItemStackSizeByPrice(item: ITemplateItem): number;
/**
* Select a number of items that have a colelctive value of the passed in parameter
* @param repeatableConfig Config
* @param roublesBudget Total value of items to return
* @returns Array of reward items that fit budget
*/
protected chooseRewardItemsWithinBudget(repeatableConfig: IRepeatableQuestConfig, roublesBudget: number, traderId: string): ITemplateItem[];
/**
* Helper to create a reward item structured as required by the client
*
* @param {string} tpl ItemId of the rewarded item
* @param {integer} value Amount of items to give
* @param {integer} index All rewards will be appended to a list, for unknown reasons the client wants the index
* @returns {object} Object of "Reward"-item-type
*/
protected generateRewardItem(tpl: string, value: number, index: number, preset?: Item[]): IQuestReward;
/**
* Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
* @param repeatableQuestConfig Config file
* @returns List of rewardable items [[_tpl, itemTemplate],...]
*/
protected getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig, traderId: string): [string, ITemplateItem][];
/**
* Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
* or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
* @param {string} tpl template id of item to check
* @returns True if item is valid reward
*/
protected isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig, itemBaseWhitelist: string[]): boolean;
/**
* Generates the base object of quest type format given as templates in assets/database/templates/repeatableQuests.json
* The templates include Elimination, Completion and Extraction quest types

View File

@ -0,0 +1,106 @@
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { Item } from "@spt-aki/models/eft/common/tables/IItem";
import { IQuestReward, IQuestRewards } from "@spt-aki/models/eft/common/tables/IQuest";
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
import { IBaseQuestConfig, IQuestConfig, IRepeatableQuestConfig } from "@spt-aki/models/spt/config/IQuestConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemFilterService } from "@spt-aki/services/ItemFilterService";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { MathUtil } from "@spt-aki/utils/MathUtil";
import { ObjectId } from "@spt-aki/utils/ObjectId";
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
export declare class RepeatableQuestRewardGenerator {
protected logger: ILogger;
protected randomUtil: RandomUtil;
protected mathUtil: MathUtil;
protected jsonUtil: JsonUtil;
protected databaseServer: DatabaseServer;
protected itemHelper: ItemHelper;
protected presetHelper: PresetHelper;
protected handbookHelper: HandbookHelper;
protected localisationService: LocalisationService;
protected objectId: ObjectId;
protected itemFilterService: ItemFilterService;
protected seasonalEventService: SeasonalEventService;
protected configServer: ConfigServer;
protected questConfig: IQuestConfig;
constructor(logger: ILogger, randomUtil: RandomUtil, mathUtil: MathUtil, jsonUtil: JsonUtil, databaseServer: DatabaseServer, itemHelper: ItemHelper, presetHelper: PresetHelper, handbookHelper: HandbookHelper, localisationService: LocalisationService, objectId: ObjectId, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer);
/**
* Generate the reward for a mission. A reward can consist of
* - Experience
* - Money
* - Items
* - Trader Reputation
*
* The reward is dependent on the player level as given by the wiki. The exact mapping of pmcLevel to
* experience / money / items / trader reputation can be defined in QuestConfig.js
*
* There's also a random variation of the reward the spread of which can be also defined in the config.
*
* Additionally, a scaling factor w.r.t. quest difficulty going from 0.2...1 can be used
*
* @param {integer} pmcLevel player's level
* @param {number} difficulty a reward scaling factor from 0.2 to 1
* @param {string} traderId the trader for reputation gain (and possible in the future filtering of reward item type based on trader)
* @param {object} repeatableConfig The configuration for the repeatable kind (daily, weekly) as configured in QuestConfig for the requested quest
* @returns {object} object of "Reward"-type that can be given for a repeatable mission
*/
generateReward(pmcLevel: number, difficulty: number, traderId: string, repeatableConfig: IRepeatableQuestConfig, questConfig: IBaseQuestConfig): IQuestRewards;
/**
* @param rewardItems List of reward items to filter
* @param roublesBudget The budget remaining for rewards
* @param minPrice The minimum priced item to include
* @returns True if any items remain in `rewardItems`, false otherwise
*/
protected filterRewardPoolWithinBudget(rewardItems: ITemplateItem[], roublesBudget: number, minPrice: number): boolean;
/**
* Get a randomised number a reward items stack size should be based on its handbook price
* @param item Reward item to get stack size for
* @returns Stack size value
*/
protected getRandomisedRewardItemStackSizeByPrice(item: ITemplateItem): number;
/**
* Should reward item have stack size increased (25% chance)
* @param item Item to possibly increase stack size of
* @param maxRoublePriceToStack Maximum rouble price an item can be to still be chosen for stacking
* @returns True if it should
*/
protected canIncreaseRewardItemStackSize(item: ITemplateItem, maxRoublePriceToStack: number): boolean;
protected calculateAmmoStackSizeThatFitsBudget(itemSelected: ITemplateItem, roublesBudget: number, rewardNumItems: number): number;
/**
* Select a number of items that have a colelctive value of the passed in parameter
* @param repeatableConfig Config
* @param roublesBudget Total value of items to return
* @returns Array of reward items that fit budget
*/
protected chooseRewardItemsWithinBudget(repeatableConfig: IRepeatableQuestConfig, roublesBudget: number, traderId: string): ITemplateItem[];
/**
* Helper to create a reward item structured as required by the client
*
* @param {string} tpl ItemId of the rewarded item
* @param {integer} value Amount of items to give
* @param {integer} index All rewards will be appended to a list, for unknown reasons the client wants the index
* @returns {object} Object of "Reward"-item-type
*/
protected generateRewardItem(tpl: string, value: number, index: number, preset?: Item[]): IQuestReward;
/**
* Picks rewardable items from items.json. This means they need to fit into the inventory and they shouldn't be keys (debatable)
* @param repeatableQuestConfig Config file
* @returns List of rewardable items [[_tpl, itemTemplate],...]
*/
getRewardableItems(repeatableQuestConfig: IRepeatableQuestConfig, traderId: string): [string, ITemplateItem][];
/**
* Checks if an id is a valid item. Valid meaning that it's an item that may be a reward
* or content of bot loot. Items that are tested as valid may be in a player backpack or stash.
* @param {string} tpl template id of item to check
* @returns True if item is valid reward
*/
protected isValidRewardItem(tpl: string, repeatableQuestConfig: IRepeatableQuestConfig, itemBaseWhitelist: string[]): boolean;
protected addMoneyReward(traderId: string, rewards: IQuestRewards, rewardRoubles: number, rewardIndex: number): void;
}

View File

@ -10,6 +10,7 @@ import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ItemFilterService } from "@spt-aki/services/ItemFilterService";
import { RagfairPriceService } from "@spt-aki/services/RagfairPriceService";
import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
@ -25,12 +26,13 @@ export declare class ScavCaseRewardGenerator {
protected presetHelper: PresetHelper;
protected databaseServer: DatabaseServer;
protected ragfairPriceService: RagfairPriceService;
protected seasonalEventService: SeasonalEventService;
protected itemFilterService: ItemFilterService;
protected configServer: ConfigServer;
protected scavCaseConfig: IScavCaseConfig;
protected dbItemsCache: ITemplateItem[];
protected dbAmmoItemsCache: ITemplateItem[];
constructor(logger: ILogger, randomUtil: RandomUtil, jsonUtil: JsonUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, itemFilterService: ItemFilterService, configServer: ConfigServer);
constructor(logger: ILogger, randomUtil: RandomUtil, jsonUtil: JsonUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, databaseServer: DatabaseServer, ragfairPriceService: RagfairPriceService, seasonalEventService: SeasonalEventService, itemFilterService: ItemFilterService, configServer: ConfigServer);
/**
* Create an array of rewards that will be given to the player upon completing their scav case build
* @param recipeId recipe of the scav case craft

View File

@ -3,6 +3,7 @@ import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig";
import { IWeatherConfig } from "@spt-aki/models/spt/config/IWeatherConfig";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { GiftService } from "@spt-aki/services/GiftService";
import { MailSendService } from "@spt-aki/services/MailSendService";
@ -14,6 +15,7 @@ export declare class SptDialogueChatBot implements IDialogueChatBot {
protected giftService: GiftService;
protected configServer: ConfigServer;
protected coreConfig: ICoreConfig;
protected weatherConfig: IWeatherConfig;
constructor(profileHelper: ProfileHelper, randomUtil: RandomUtil, mailSendService: MailSendService, giftService: GiftService, configServer: ConfigServer);
getChatBot(): IUserDialogInfo;
/**

View File

@ -19,6 +19,7 @@ import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { PlayerService } from "@spt-aki/services/PlayerService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export declare class HideoutHelper {
protected logger: ILogger;
@ -33,6 +34,7 @@ export declare class HideoutHelper {
protected localisationService: LocalisationService;
protected itemHelper: ItemHelper;
protected configServer: ConfigServer;
protected jsonUtil: JsonUtil;
static bitcoinFarm: string;
static bitcoinProductionId: string;
static waterCollector: string;
@ -40,7 +42,7 @@ export declare class HideoutHelper {
static expeditionaryFuelTank: string;
static maxSkillPoint: number;
protected hideoutConfig: IHideoutConfig;
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, localisationService: LocalisationService, itemHelper: ItemHelper, configServer: ConfigServer);
constructor(logger: ILogger, hashUtil: HashUtil, timeUtil: TimeUtil, databaseServer: DatabaseServer, eventOutputHolder: EventOutputHolder, httpResponse: HttpResponseUtil, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, playerService: PlayerService, localisationService: LocalisationService, itemHelper: ItemHelper, configServer: ConfigServer, jsonUtil: JsonUtil);
/**
* Add production to profiles' Hideout.Production array
* @param pmcData Profile to add production to
@ -82,6 +84,16 @@ export declare class HideoutHelper {
waterCollectorHasFilter: boolean;
};
protected doesWaterCollectorHaveFilter(waterCollector: HideoutArea): boolean;
/**
* Iterate over productions and update their progress timers
* @param pmcData Profile to check for productions and update
* @param hideoutProperties Hideout properties
*/
protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
btcFarmCGs: number;
isGeneratorOn: boolean;
waterCollectorHasFilter: boolean;
}): void;
/**
* Update progress timer for water collector
* @param pmcData profile to update
@ -93,16 +105,6 @@ export declare class HideoutHelper {
isGeneratorOn: boolean;
waterCollectorHasFilter: boolean;
}): void;
/**
* Iterate over productions and update their progress timers
* @param pmcData Profile to check for productions and update
* @param hideoutProperties Hideout properties
*/
protected updateProductionTimers(pmcData: IPmcData, hideoutProperties: {
btcFarmCGs: number;
isGeneratorOn: boolean;
waterCollectorHasFilter: boolean;
}): void;
/**
* Update a productions progress value based on the amount of time that has passed
* @param pmcData Player profile
@ -148,6 +150,13 @@ export declare class HideoutHelper {
*/
protected updateFuel(generatorArea: HideoutArea, pmcData: IPmcData, isGeneratorOn: boolean): void;
protected updateWaterCollector(sessionId: string, pmcData: IPmcData, area: HideoutArea, isGeneratorOn: boolean): void;
/**
* Get craft time and make adjustments to account for dev profile + crafting skill level
* @param pmcData Player profile making craft
* @param recipeId Recipe being crafted
* @returns
*/
protected getAdjustedCraftTimeWithSkills(pmcData: IPmcData, recipeId: string): number;
/**
* Adjust water filter objects resourceValue or delete when they reach 0 resource
* @param waterFilterArea water filter area to update
@ -163,9 +172,9 @@ export declare class HideoutHelper {
* @param totalProductionTime Total time collecting water
* @param productionProgress how far water collector has progressed
* @param baseFilterDrainRate Base drain rate
* @returns
* @returns drain rate (adjusted)
*/
protected adjustWaterFilterDrainRate(secondsSinceServerTick: number, totalProductionTime: number, productionProgress: number, baseFilterDrainRate: number): number;
protected getAdjustWaterFilterDrainRate(secondsSinceServerTick: number, totalProductionTime: number, productionProgress: number, baseFilterDrainRate: number): number;
/**
* Get the water filter drain rate based on hideout bonues player has
* @param pmcData Player profile
@ -185,7 +194,7 @@ export declare class HideoutHelper {
* @param resourceUnitsConsumed
* @returns Upd
*/
protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number): Upd;
protected getAreaUpdObject(stackCount: number, resourceValue: number, resourceUnitsConsumed: number, isFoundInRaid: boolean): Upd;
protected updateAirFilters(airFilterArea: HideoutArea, pmcData: IPmcData, isGeneratorOn: boolean): void;
protected updateBitcoinFarm(pmcData: IPmcData, btcFarmCGs: number, isGeneratorOn: boolean): Production;
/**
@ -225,7 +234,7 @@ export declare class HideoutHelper {
* @param productionTime Time to complete hideout craft in seconds
* @returns Adjusted craft time in seconds
*/
protected getCraftingSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number): number;
getCraftingSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number): number;
isProduction(productive: Productive): productive is Production;
/**
* Gather crafted BTC from hideout area and add to inventory

View File

@ -74,9 +74,9 @@ export declare class InventoryHelper {
* @param itemWithChildren An item
* @param foundInRaid Item was found in raid
*/
private setFindInRaidStatusForItem;
protected setFindInRaidStatusForItem(itemWithChildren: Item[], foundInRaid: boolean): void;
/**
* Remove properties from a Upd object used by a trader/ragfair
* Remove properties from a Upd object used by a trader/ragfair that are unnecessary to a player
* @param upd Object to update
*/
protected removeTraderRagfairRelatedUpdProperties(upd: Upd): void;
@ -106,8 +106,9 @@ export declare class InventoryHelper {
* @param containerFS2D Container grid to add item to
* @param itemWithChildren Item to add to grid
* @param containerId Id of the container we're fitting item into
* @param desiredSlotId slot id value to use, default is "hideout"
*/
placeItemInContainer(containerFS2D: number[][], itemWithChildren: Item[], containerId: string): void;
placeItemInContainer(containerFS2D: number[][], itemWithChildren: Item[], containerId: string, desiredSlotId?: string): void;
/**
* Find a location to place an item into inventory and place it
* @param stashFS2D 2-dimensional representation of the container slots
@ -119,9 +120,10 @@ export declare class InventoryHelper {
*/
protected placeItemInInventory(stashFS2D: number[][], sortingTableFS2D: number[][], itemWithChildren: Item[], playerInventory: Inventory, useSortingTable: boolean, output: IItemEventRouterResponse): void;
/**
* Split an items stack size based on its StackMaxSize value
* @param assortItems Items to add to inventory
* @param requestItem Details of purchased item to add to inventory
* @param result Array split stacks are added to
* @param result Array split stacks are appended to
*/
protected splitStackIntoSmallerChildStacks(assortItems: Item[], requestItem: AddItem, result: IAddItemTempObject[]): void;
/**
@ -134,13 +136,48 @@ export declare class InventoryHelper {
* @param output OPTIONAL - IItemEventRouterResponse
*/
removeItem(profile: IPmcData, itemId: string, sessionID: string, output?: IItemEventRouterResponse): void;
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output: IItemEventRouterResponse): void;
removeItemByCount(pmcData: IPmcData, itemId: string, count: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
/**
* Delete desired item from a player profiles mail
* @param sessionId Session id
* @param removeRequest Remove request
* @param output OPTIONAL - IItemEventRouterResponse
*/
removeItemAndChildrenFromMailRewards(sessionId: string, removeRequest: IInventoryRemoveRequestData, output?: IItemEventRouterResponse): void;
/**
* Find item by id in player inventory and remove x of its count
* @param pmcData player profile
* @param itemId Item id to decrement StackObjectsCount of
* @param countToRemove Number of item to remove
* @param sessionID Session id
* @param output IItemEventRouterResponse
* @returns IItemEventRouterResponse
*/
removeItemByCount(pmcData: IPmcData, itemId: string, countToRemove: number, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
/**
* Get the height and width of an item - can have children that alter size
* @param itemTpl Item to get size of
* @param itemID Items id to get size of
* @param inventoryItems
* @returns [width, height]
*/
getItemSize(itemTpl: string, itemID: string, inventoryItems: Item[]): number[];
protected getSizeByInventoryItemHash(itemTpl: string, itemID: string, inventoryItemHash: InventoryHelper.InventoryItemHash): number[];
protected getInventoryItemHash(inventoryItem: Item[]): InventoryHelper.InventoryItemHash;
/**
* Get a blank two-dimentional representation of a container
* @param containerH Horizontal size of container
* @param containerY Vertical size of container
* @returns Two-dimensional representation of container
*/
protected getBlankContainerMap(containerH: number, containerY: number): number[][];
/**
* @param containerH Horizontal size of container
* @param containerV Vertical size of container
* @param itemList
* @param containerId Id of the container
* @returns Two-dimensional representation of container
*/
getContainerMap(containerH: number, containerV: number, itemList: Item[], containerId: string): number[][];
protected getInventoryItemHash(inventoryItem: Item[]): InventoryHelper.InventoryItemHash;
/**
* Return the inventory that needs to be modified (scav/pmc etc)
* Changes made to result apply to character inventory
@ -151,18 +188,29 @@ export declare class InventoryHelper {
*/
getOwnerInventoryItems(request: IInventoryMoveRequestData | IInventorySplitRequestData | IInventoryMergeRequestData | IInventoryTransferRequestData, sessionId: string): IOwnerInventoryItems;
/**
* Made a 2d array table with 0 - free slot and 1 - used slot
* @param {Object} pmcData
* @param {string} sessionID
* @returns Array
* Get a two dimensional array to represent stash slots
* 0 value = free, 1 = taken
* @param pmcData Player profile
* @param sessionID session id
* @returns 2-dimensional array
*/
protected getStashSlotMap(pmcData: IPmcData, sessionID: string): number[][];
/**
* Get a blank two-dimensional array representation of a container
* @param containerTpl Container to get data for
* @returns blank two-dimensional array
*/
getContainerSlotMap(containerTpl: string): number[][];
/**
* Get a two-dimensional array representation of the players sorting table
* @param pmcData Player profile
* @returns two-dimensional array
*/
protected getSortingTableSlotMap(pmcData: IPmcData): number[][];
/**
* Get Player Stash Proper Size
* @param sessionID Playerid
* @returns Array of 2 values, x and y stash size
* Get Players Stash Size
* @param sessionID Players id
* @returns Array of 2 values, horizontal and vertical stash size
*/
protected getPlayerStashSize(sessionID: string): Record<number, number>;
/**

View File

@ -71,6 +71,10 @@ export declare class ItemHelper {
* @returns True if it needs armor inserts
*/
itemRequiresSoftInserts(itemTpl: string): boolean;
/**
* Get all soft insert slot ids
* @returns An array of soft insert ids (e.g. soft_armor_back, helmet_top)
*/
getSoftInsertSlotIds(): string[];
/**
* Returns the items total price based on the handbook or as a fallback from the prices.json if the item is not
@ -221,6 +225,12 @@ export declare class ItemHelper {
* @returns Item[]
*/
replaceIDs(originalItems: Item[], pmcData?: IPmcData | null, insuredItems?: InsuredItem[] | null, fastPanel?: any): Item[];
/**
* Mark the passed in array of items as found in raid.
* Modifies passed in items
* @param items The list of items to mark as FiR
*/
setFoundInRaid(items: Item[]): void;
/**
* WARNING, SLOW. Recursively loop down through an items hierarchy to see if any of the ids match the supplied list, return true if any do
* @param {string} tpl Items tpl to check parents of
@ -432,6 +442,13 @@ export declare class ItemHelper {
* @returns A Map where the keys are the item IDs and the values are the corresponding Item objects.
*/
generateItemsMap(items: Item[]): Map<string, Item>;
/**
* Add a blank upd object to passed in item if it does not exist already
* @param item item to add upd to
* @param warningMessageWhenMissing text to write to log when upd object was not found
* @returns True when upd object was added
*/
addUpdObjectToItem(item: Item, warningMessageWhenMissing?: string): boolean;
}
declare namespace ItemHelper {
interface ItemSize {

View File

@ -38,4 +38,10 @@ export declare class PresetHelper {
*/
getDefaultPreset(templateId: string): IPreset;
getBaseItemTpl(presetId: string): string;
/**
* Return the price of the preset for the given item tpl, or for the tpl itself if no preset exists
* @param tpl The item template to get the price of
* @returns The price of the given item preset, or base item if no preset exists
*/
getDefaultPresetOrItemPrice(tpl: string): number;
}

View File

@ -4,17 +4,21 @@ import { Common, CounterKeyValue, Stats } from "@spt-aki/models/eft/common/table
import { IAkiProfile } from "@spt-aki/models/eft/profile/IAkiProfile";
import { IValidateNicknameRequestData } from "@spt-aki/models/eft/profile/IValidateNicknameRequestData";
import { SkillTypes } from "@spt-aki/models/enums/SkillTypes";
import { IInventoryConfig } from "@spt-aki/models/spt/config/IInventoryConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { SaveServer } from "@spt-aki/servers/SaveServer";
import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { ProfileSnapshotService } from "@spt-aki/services/ProfileSnapshotService";
import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
import { Watermark } from "@spt-aki/utils/Watermark";
export declare class ProfileHelper {
protected logger: ILogger;
protected jsonUtil: JsonUtil;
protected hashUtil: HashUtil;
protected watermark: Watermark;
protected timeUtil: TimeUtil;
protected saveServer: SaveServer;
@ -22,7 +26,9 @@ export declare class ProfileHelper {
protected itemHelper: ItemHelper;
protected profileSnapshotService: ProfileSnapshotService;
protected localisationService: LocalisationService;
constructor(logger: ILogger, jsonUtil: JsonUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, localisationService: LocalisationService);
protected configServer: ConfigServer;
protected inventoryConfig: IInventoryConfig;
constructor(logger: ILogger, jsonUtil: JsonUtil, hashUtil: HashUtil, watermark: Watermark, timeUtil: TimeUtil, saveServer: SaveServer, databaseServer: DatabaseServer, itemHelper: ItemHelper, profileSnapshotService: ProfileSnapshotService, localisationService: LocalisationService, configServer: ConfigServer);
/**
* Remove/reset a completed quest condtion from players profile quest data
* @param sessionID Session id
@ -34,6 +40,11 @@ export declare class ProfileHelper {
* @returns Dictionary of profiles
*/
getProfiles(): Record<string, IAkiProfile>;
/**
* Get the pmc and scav profiles as an array by profile id
* @param sessionID
* @returns Array of IPmcData objects
*/
getCompleteProfile(sessionID: string): IPmcData[];
/**
* Fix xp doubling on post-raid xp reward screen by sending a 'dummy' profile to the post-raid screen
@ -45,37 +56,70 @@ export declare class ProfileHelper {
* @param output pmc and scav profiles array
* @param pmcProfile post-raid pmc profile
* @param scavProfile post-raid scav profile
* @returns updated profile array
* @returns Updated profile array
*/
protected postRaidXpWorkaroundFix(sessionId: string, output: IPmcData[], pmcProfile: IPmcData, scavProfile: IPmcData): IPmcData[];
/**
* Check if a nickname is used by another profile loaded by the server
* @param nicknameRequest
* @param nicknameRequest nickname request object
* @param sessionID Session id
* @returns True if already used
*/
isNicknameTaken(nicknameRequest: IValidateNicknameRequestData, sessionID: string): boolean;
protected profileHasInfoProperty(profile: IAkiProfile): boolean;
protected nicknameMatches(profileName: string, nicknameRequest: string): boolean;
protected sessionIdMatchesProfileId(profileId: string, sessionId: string): boolean;
protected stringsMatch(stringA: string, stringB: string): boolean;
/**
* Add experience to a PMC inside the players profile
* @param sessionID Session id
* @param experienceToAdd Experience to add to PMC character
*/
addExperienceToPmc(sessionID: string, experienceToAdd: number): void;
/**
* Iterate all profiles and find matching pmc profile by provided id
* @param pmcId Profile id to find
* @returns IPmcData
*/
getProfileByPmcId(pmcId: string): IPmcData;
/**
* Get the experiecne for the given level
* @param level level to get xp for
* @returns Number of xp points for level
*/
getExperience(level: number): number;
/**
* Get the max level a player can be
* @returns Max level
*/
getMaxLevel(): number;
getDefaultAkiDataObject(): any;
/**
* Get full representation of a players profile json
* @param sessionID Profile id to get
* @returns IAkiProfile object
*/
getFullProfile(sessionID: string): IAkiProfile;
/**
* Get a PMC profile by its session id
* @param sessionID Profile id to return
* @returns IPmcData object
*/
getPmcProfile(sessionID: string): IPmcData;
/**
* Get a full profiles scav-specific sub-profile
* @param sessionID Profiles id
* @returns IPmcData object
*/
getScavProfile(sessionID: string): IPmcData;
/**
* Get baseline counter values for a fresh profile
* @returns Stats
* @returns Default profile Stats object
*/
getDefaultCounters(): Stats;
/**
* is this profile flagged for data removal
* @param sessionID Profile id
* @returns True if profile is to be wiped of data/progress
*/
protected isWiped(sessionID: string): boolean;
protected getServerVersion(): string;
/**
@ -120,6 +164,23 @@ export declare class ProfileHelper {
* @returns
*/
addSkillPointsToPlayer(pmcProfile: IPmcData, skill: SkillTypes, pointsToAdd: number, useSkillProgressRateMultipler?: boolean): void;
/**
* Get a speciic common skill from supplied profile
* @param pmcData Player profile
* @param skill Skill get get
* @returns Common skill object from desired profile
*/
getSkillFromProfile(pmcData: IPmcData, skill: SkillTypes): Common;
/**
* Is the provided session id for a developer account
* @param sessionID Profile id ot check
* @returns True if account is developer
*/
isDeveloperAccount(sessionID: string): boolean;
/**
* Add stash row bonus to profile or increments rows given count if it already exists
* @param sessionId Profile id to give rows to
* @param rowsToAdd How many rows to give profile
*/
addStashRowsBonusToProfile(sessionId: string, rowsToAdd: number): void;
}

View File

@ -178,9 +178,8 @@ export declare class QuestHelper {
* @param failRequest Fail quest request data
* @param sessionID Session id
* @param output Client output
* @returns Item event router response
*/
failQuest(pmcData: IPmcData, failRequest: IFailQuestRequestData, sessionID: string, output?: IItemEventRouterResponse): IItemEventRouterResponse;
failQuest(pmcData: IPmcData, failRequest: IFailQuestRequestData, sessionID: string, output?: IItemEventRouterResponse): void;
/**
* Get List of All Quests from db
* NOT CLONED

View File

@ -53,6 +53,12 @@ export declare class RagfairServerHelper {
* @returns True if its blacklsited
*/
protected isItemOnCustomFleaBlacklist(itemTemplateId: string): boolean;
/**
* Is supplied parent id on the ragfair custom item category blacklist
* @param parentId Parent Id to check is blacklisted
* @returns true if blacklisted
*/
protected isItemCategoryOnCustomFleaBlacklist(itemParentId: string): boolean;
/**
* is supplied id a trader
* @param traderId

View File

@ -54,6 +54,7 @@ export interface Info {
LowerNickname: string;
Side: string;
SquadInviteRestriction: boolean;
HasCoopExtension: boolean;
Voice: string;
Level: number;
Experience: number;
@ -314,8 +315,8 @@ export interface Productive {
sptIsComplete?: boolean;
/** Is the craft a Continuous, e.g bitcoins/water collector */
sptIsContinuous?: boolean;
/** Stores a list of tools used in this craft, to give back once the craft is done */
sptRequiredTools?: string[];
/** Stores a list of tools used in this craft and whether they're FiR, to give back once the craft is done */
sptRequiredTools?: Item[];
}
export interface Production extends Productive {
RecipeId: string;

View File

@ -0,0 +1,2 @@
export interface IDeclineGroupInviteRequest {
}

View File

@ -62,6 +62,7 @@ export declare enum BackendErrorCodes {
BANNEDERRORCODE = 1513,
INSUFFICIENTNUMBERINSTOCK = 1516,
TOOMANYITEMSTOSELL = 1517,
INCORRECTCLIENTPRICE = 1519,
EXAMINATIONFAILED = 22001,
ITEMALREADYEXAMINED = 22002,
UNKNOWNNGINXERROR = 9000,
@ -81,5 +82,6 @@ export declare enum BackendErrorCodes {
PLAYERISNOTSEARCHINGFORGROUP = 502018,
PLAYERALREADYLOOKINGFORGAME = 503001,
PLAYERINRAID = 503002,
LIMITFORPRESETSREACHED = 504001
LIMITFORPRESETSREACHED = 504001,
PLAYERPROFILENOTFOUND = 505001
}

Some files were not shown because too many files have changed in this diff Show More