0
0
mirror of https://github.com/sp-tarkov/server.git synced 2025-02-13 02:50:44 -05:00

ESLint Pass

This is the first pass of ESLint on the codebase.

ESLint formatting is less strict when it comes to line-length and line-breaks then dprint/biome, so if you see formatting that you don't like... fix it! It shouldn't require a configuration change.

- This should merge clean into master (when the time comes).
- This will not merge clean into `3.9.0-DEV`, but the conflicts aren't that bad.
This commit is contained in:
Refringe 2024-05-07 23:57:08 -04:00
parent 45bf159bb8
commit 50c7a26a58
Signed by: Refringe
GPG Key ID: 7715B85B4A6306ED
569 changed files with 6490 additions and 6706 deletions

View File

@ -1,5 +1,4 @@
import readline from "node:readline"; import readline from "node:readline";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { AsyncQueue } from "@spt-aki/utils/AsyncQueue"; import { AsyncQueue } from "@spt-aki/utils/AsyncQueue";
import { WinstonMainLogger } from "@spt-aki/utils/logging/WinstonMainLogger"; import { WinstonMainLogger } from "@spt-aki/utils/logging/WinstonMainLogger";
@ -24,7 +23,7 @@ export class ErrorHandler
this.logger.error(`\nStacktrace:\n${err.stack}`); this.logger.error(`\nStacktrace:\n${err.stack}`);
} }
this.readLine.question("Press Enter to close the window", (_ans) => this.readLine.close()); this.readLine.question("Press Enter to close the window", _ans => this.readLine.close());
this.readLine.on("close", () => process.exit(1)); this.readLine.on("close", () => process.exit(1));
} }
} }

View File

@ -1,7 +1,6 @@
import { container } from "tsyringe"; import { container } from "tsyringe";
import { ErrorHandler } from "@spt-aki/ErrorHandler";
import { Container } from "@spt-aki/di/Container"; import { Container } from "@spt-aki/di/Container";
import { ErrorHandler } from "@spt-aki/ErrorHandler";
import type { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader"; import type { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";
import { App } from "@spt-aki/utils/App"; import { App } from "@spt-aki/utils/App";
import { Watermark } from "@spt-aki/utils/Watermark"; import { Watermark } from "@spt-aki/utils/Watermark";

View File

@ -1,3 +1,4 @@
import { inject, injectable } from "tsyringe";
import { AchievementController } from "@spt-aki/controllers/AchievementController"; import { AchievementController } from "@spt-aki/controllers/AchievementController";
import { ProfileController } from "@spt-aki/controllers/ProfileController"; import { ProfileController } from "@spt-aki/controllers/ProfileController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
@ -6,7 +7,6 @@ import { IGetBodyResponseData } from "@spt-aki/models/eft/httpResponse/IGetBodyR
import { ICompletedAchievementsResponse } from "@spt-aki/models/eft/profile/ICompletedAchievementsResponse"; import { ICompletedAchievementsResponse } from "@spt-aki/models/eft/profile/ICompletedAchievementsResponse";
import { IGetAchievementsResponse } from "@spt-aki/models/eft/profile/IGetAchievementsResponse"; import { IGetAchievementsResponse } from "@spt-aki/models/eft/profile/IGetAchievementsResponse";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil"; import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { inject, injectable } from "tsyringe";
@injectable() @injectable()
export class AchievementCallbacks export class AchievementCallbacks

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { BotController } from "@spt-aki/controllers/BotController"; import { BotController } from "@spt-aki/controllers/BotController";
import { IGenerateBotsRequestData } from "@spt-aki/models/eft/bot/IGenerateBotsRequestData"; import { IGenerateBotsRequestData } from "@spt-aki/models/eft/bot/IGenerateBotsRequestData";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";

View File

@ -1,3 +1,4 @@
import { inject, injectable } from "tsyringe";
import { BuildController } from "@spt-aki/controllers/BuildController"; import { BuildController } from "@spt-aki/controllers/BuildController";
import { ISetMagazineRequest } from "@spt-aki/models/eft/builds/ISetMagazineRequest"; import { ISetMagazineRequest } from "@spt-aki/models/eft/builds/ISetMagazineRequest";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
@ -7,7 +8,6 @@ import { IPresetBuildActionRequestData } from "@spt-aki/models/eft/presetBuild/I
import { IRemoveBuildRequestData } from "@spt-aki/models/eft/presetBuild/IRemoveBuildRequestData"; import { IRemoveBuildRequestData } from "@spt-aki/models/eft/presetBuild/IRemoveBuildRequestData";
import { IUserBuilds } from "@spt-aki/models/eft/profile/IAkiProfile"; import { IUserBuilds } from "@spt-aki/models/eft/profile/IAkiProfile";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil"; import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { inject, injectable } from "tsyringe";
@injectable() @injectable()
export class BuildsCallbacks export class BuildsCallbacks

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { BundleLoader } from "@spt-aki/loaders/BundleLoader"; import { BundleLoader } from "@spt-aki/loaders/BundleLoader";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes"; import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
import { IHttpConfig } from "@spt-aki/models/spt/config/IHttpConfig"; import { IHttpConfig } from "@spt-aki/models/spt/config/IHttpConfig";

View File

@ -1,3 +1,4 @@
import { inject, injectable } from "tsyringe";
import { ClientLogController } from "@spt-aki/controllers/ClientLogController"; import { ClientLogController } from "@spt-aki/controllers/ClientLogController";
import { ModLoadOrder } from "@spt-aki/loaders/ModLoadOrder"; import { ModLoadOrder } from "@spt-aki/loaders/ModLoadOrder";
import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData"; import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData";
@ -7,7 +8,6 @@ import { IClientLogRequest } from "@spt-aki/models/spt/logging/IClientLogRequest
import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { LocalisationService } from "@spt-aki/services/LocalisationService"; import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil"; import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { inject, injectable } from "tsyringe";
/** Handle client logging related events */ /** Handle client logging related events */
@injectable() @injectable()

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { CustomizationController } from "@spt-aki/controllers/CustomizationController"; import { CustomizationController } from "@spt-aki/controllers/CustomizationController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { HideoutController } from "@spt-aki/controllers/HideoutController"; import { HideoutController } from "@spt-aki/controllers/HideoutController";
import { RagfairController } from "@spt-aki/controllers/RagfairController"; import { RagfairController } from "@spt-aki/controllers/RagfairController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { DialogueController } from "@spt-aki/controllers/DialogueController"; import { DialogueController } from "@spt-aki/controllers/DialogueController";
import { OnUpdate } from "@spt-aki/di/OnUpdate"; import { OnUpdate } from "@spt-aki/di/OnUpdate";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { GameController } from "@spt-aki/controllers/GameController"; import { GameController } from "@spt-aki/controllers/GameController";
import { OnLoad } from "@spt-aki/di/OnLoad"; import { OnLoad } from "@spt-aki/di/OnLoad";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { HandbookController } from "@spt-aki/controllers/HandbookController"; import { HandbookController } from "@spt-aki/controllers/HandbookController";
import { OnLoad } from "@spt-aki/di/OnLoad"; import { OnLoad } from "@spt-aki/di/OnLoad";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { HealthController } from "@spt-aki/controllers/HealthController"; import { HealthController } from "@spt-aki/controllers/HealthController";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { HideoutController } from "@spt-aki/controllers/HideoutController"; import { HideoutController } from "@spt-aki/controllers/HideoutController";
import { OnUpdate } from "@spt-aki/di/OnUpdate"; import { OnUpdate } from "@spt-aki/di/OnUpdate";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { OnLoad } from "@spt-aki/di/OnLoad"; import { OnLoad } from "@spt-aki/di/OnLoad";
import { HttpServer } from "@spt-aki/servers/HttpServer"; import { HttpServer } from "@spt-aki/servers/HttpServer";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { InraidController } from "@spt-aki/controllers/InraidController"; import { InraidController } from "@spt-aki/controllers/InraidController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData"; import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { InsuranceController } from "@spt-aki/controllers/InsuranceController"; import { InsuranceController } from "@spt-aki/controllers/InsuranceController";
import { OnUpdate } from "@spt-aki/di/OnUpdate"; import { OnUpdate } from "@spt-aki/di/OnUpdate";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { InventoryController } from "@spt-aki/controllers/InventoryController"; import { InventoryController } from "@spt-aki/controllers/InventoryController";
import { QuestController } from "@spt-aki/controllers/QuestController"; import { QuestController } from "@spt-aki/controllers/QuestController";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { IGetBodyResponseData } from "@spt-aki/models/eft/httpResponse/IGetBodyResponseData"; import { IGetBodyResponseData } from "@spt-aki/models/eft/httpResponse/IGetBodyResponseData";
import { Warning } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase"; import { Warning } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase";
import { IItemEventRouterRequest } from "@spt-aki/models/eft/itemEvent/IItemEventRouterRequest"; import { IItemEventRouterRequest } from "@spt-aki/models/eft/itemEvent/IItemEventRouterRequest";
@ -24,7 +23,7 @@ export class ItemEventCallbacks
): IGetBodyResponseData<IItemEventRouterResponse> ): IGetBodyResponseData<IItemEventRouterResponse>
{ {
const eventResponse = this.itemEventRouter.handleEvents(info, sessionID); const eventResponse = this.itemEventRouter.handleEvents(info, sessionID);
const result = (this.isCriticalError(eventResponse.warnings)) const result = this.isCriticalError(eventResponse.warnings)
? this.httpResponse.getBody( ? this.httpResponse.getBody(
eventResponse, eventResponse,
this.getErrorCode(eventResponse.warnings), this.getErrorCode(eventResponse.warnings),

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { LauncherController } from "@spt-aki/controllers/LauncherController"; import { LauncherController } from "@spt-aki/controllers/LauncherController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { IChangeRequestData } from "@spt-aki/models/eft/launcher/IChangeRequestData"; import { IChangeRequestData } from "@spt-aki/models/eft/launcher/IChangeRequestData";
@ -29,13 +28,13 @@ export class LauncherCallbacks
public login(url: string, info: ILoginRequestData, sessionID: string): string public login(url: string, info: ILoginRequestData, sessionID: string): string
{ {
const output = this.launcherController.login(info); const output = this.launcherController.login(info);
return (!output) ? "FAILED" : output; return !output ? "FAILED" : output;
} }
public register(url: string, info: IRegisterData, sessionID: string): "FAILED" | "OK" public register(url: string, info: IRegisterData, sessionID: string): "FAILED" | "OK"
{ {
const output = this.launcherController.register(info); const output = this.launcherController.register(info);
return (!output) ? "FAILED" : "OK"; return !output ? "FAILED" : "OK";
} }
public get(url: string, info: ILoginRequestData, sessionID: string): string public get(url: string, info: ILoginRequestData, sessionID: string): string
@ -47,19 +46,19 @@ export class LauncherCallbacks
public changeUsername(url: string, info: IChangeRequestData, sessionID: string): "FAILED" | "OK" public changeUsername(url: string, info: IChangeRequestData, sessionID: string): "FAILED" | "OK"
{ {
const output = this.launcherController.changeUsername(info); const output = this.launcherController.changeUsername(info);
return (!output) ? "FAILED" : "OK"; return !output ? "FAILED" : "OK";
} }
public changePassword(url: string, info: IChangeRequestData, sessionID: string): "FAILED" | "OK" public changePassword(url: string, info: IChangeRequestData, sessionID: string): "FAILED" | "OK"
{ {
const output = this.launcherController.changePassword(info); const output = this.launcherController.changePassword(info);
return (!output) ? "FAILED" : "OK"; return !output ? "FAILED" : "OK";
} }
public wipe(url: string, info: IRegisterData, sessionID: string): "FAILED" | "OK" public wipe(url: string, info: IRegisterData, sessionID: string): "FAILED" | "OK"
{ {
const output = this.launcherController.wipe(info); const output = this.launcherController.wipe(info);
return (!output) ? "FAILED" : "OK"; return !output ? "FAILED" : "OK";
} }
public getServerVersion(): string public getServerVersion(): string

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { LocationController } from "@spt-aki/controllers/LocationController"; import { LocationController } from "@spt-aki/controllers/LocationController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase"; import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { MatchController } from "@spt-aki/controllers/MatchController"; import { MatchController } from "@spt-aki/controllers/MatchController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
@ -112,6 +111,7 @@ export class MatchCallbacks
{ {
return this.httpResponse.getBody(true); return this.httpResponse.getBody(true);
} }
/** Handle client/match/group/transfer */ /** Handle client/match/group/transfer */
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
public transferGroup(url: string, info: ITransferGroupRequest, sessionID: string): IGetBodyResponseData<boolean> public transferGroup(url: string, info: ITransferGroupRequest, sessionID: string): IGetBodyResponseData<boolean>

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { OnLoad } from "@spt-aki/di/OnLoad"; import { OnLoad } from "@spt-aki/di/OnLoad";
import { PostAkiModLoader } from "@spt-aki/loaders/PostAkiModLoader"; import { PostAkiModLoader } from "@spt-aki/loaders/PostAkiModLoader";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes"; import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { NoteController } from "@spt-aki/controllers/NoteController"; import { NoteController } from "@spt-aki/controllers/NoteController";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { NotifierController } from "@spt-aki/controllers/NotifierController"; import { NotifierController } from "@spt-aki/controllers/NotifierController";
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper"; import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
@ -38,8 +37,8 @@ export class NotifierCallbacks
* be sent to client as NEWLINE separated strings... yup. * be sent to client as NEWLINE separated strings... yup.
*/ */
this.notifierController.notifyAsync(tmpSessionID).then((messages: any) => this.notifierController.notifyAsync(tmpSessionID).then((messages: any) =>
messages.map((message: any) => this.jsonUtil.serialize(message)).join("\n") messages.map((message: any) => this.jsonUtil.serialize(message)).join("\n"),
).then((text) => this.httpServerHelper.sendTextJson(resp, text)); ).then(text => this.httpServerHelper.sendTextJson(resp, text));
} }
/** Handle push/notifier/get */ /** Handle push/notifier/get */

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { PresetController } from "@spt-aki/controllers/PresetController"; import { PresetController } from "@spt-aki/controllers/PresetController";
import { OnLoad } from "@spt-aki/di/OnLoad"; import { OnLoad } from "@spt-aki/di/OnLoad";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ProfileController } from "@spt-aki/controllers/ProfileController"; import { ProfileController } from "@spt-aki/controllers/ProfileController";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { QuestController } from "@spt-aki/controllers/QuestController"; import { QuestController } from "@spt-aki/controllers/QuestController";
import { RepeatableQuestController } from "@spt-aki/controllers/RepeatableQuestController"; import { RepeatableQuestController } from "@spt-aki/controllers/RepeatableQuestController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { RagfairController } from "@spt-aki/controllers/RagfairController"; import { RagfairController } from "@spt-aki/controllers/RagfairController";
import { OnLoad } from "@spt-aki/di/OnLoad"; import { OnLoad } from "@spt-aki/di/OnLoad";
import { OnUpdate } from "@spt-aki/di/OnUpdate"; import { OnUpdate } from "@spt-aki/di/OnUpdate";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { RepairController } from "@spt-aki/controllers/RepairController"; import { RepairController } from "@spt-aki/controllers/RepairController";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { OnLoad } from "@spt-aki/di/OnLoad"; import { OnLoad } from "@spt-aki/di/OnLoad";
import { OnUpdate } from "@spt-aki/di/OnUpdate"; import { OnUpdate } from "@spt-aki/di/OnUpdate";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes"; import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { TradeController } from "@spt-aki/controllers/TradeController"; import { TradeController } from "@spt-aki/controllers/TradeController";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { TraderController } from "@spt-aki/controllers/TraderController"; import { TraderController } from "@spt-aki/controllers/TraderController";
import { OnLoad } from "@spt-aki/di/OnLoad"; import { OnLoad } from "@spt-aki/di/OnLoad";
import { OnUpdate } from "@spt-aki/di/OnUpdate"; import { OnUpdate } from "@spt-aki/di/OnUpdate";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { WeatherController } from "@spt-aki/controllers/WeatherController"; import { WeatherController } from "@spt-aki/controllers/WeatherController";
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData"; import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
import { IGetBodyResponseData } from "@spt-aki/models/eft/httpResponse/IGetBodyResponseData"; import { IGetBodyResponseData } from "@spt-aki/models/eft/httpResponse/IGetBodyResponseData";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { WishlistController } from "@spt-aki/controllers/WishlistController"; import { WishlistController } from "@spt-aki/controllers/WishlistController";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";

View File

@ -1,5 +1,4 @@
import { injectable } from "tsyringe"; import { injectable } from "tsyringe";
import { ContextVariable } from "@spt-aki/context/ContextVariable"; import { ContextVariable } from "@spt-aki/context/ContextVariable";
import { ContextVariableType } from "@spt-aki/context/ContextVariableType"; import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
import { LinkedList } from "@spt-aki/utils/collections/lists/LinkedList"; import { LinkedList } from "@spt-aki/utils/collections/lists/LinkedList";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ICompletedAchievementsResponse } from "@spt-aki/models/eft/profile/ICompletedAchievementsResponse"; import { ICompletedAchievementsResponse } from "@spt-aki/models/eft/profile/ICompletedAchievementsResponse";
import { IGetAchievementsResponse } from "@spt-aki/models/eft/profile/IGetAchievementsResponse"; import { IGetAchievementsResponse } from "@spt-aki/models/eft/profile/IGetAchievementsResponse";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
import { ContextVariableType } from "@spt-aki/context/ContextVariableType"; import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
import { BotGenerator } from "@spt-aki/generators/BotGenerator"; import { BotGenerator } from "@spt-aki/generators/BotGenerator";
@ -61,7 +60,7 @@ export class BotController
*/ */
public getBotPresetGenerationLimit(type: string): number public getBotPresetGenerationLimit(type: string): number
{ {
const value = this.botConfig.presetBatch[(type === "assaultGroup") ? "assault" : type]; const value = this.botConfig.presetBatch[type === "assaultGroup" ? "assault" : type];
if (!value) if (!value)
{ {
@ -147,7 +146,7 @@ export class BotController
const result = {}; const result = {};
const botDb = this.databaseServer.getTables().bots.types; const botDb = this.databaseServer.getTables().bots.types;
const botTypes = Object.keys(WildSpawnTypeNumber).filter((v) => Number.isNaN(Number(v))); const botTypes = Object.keys(WildSpawnTypeNumber).filter(v => Number.isNaN(Number(v)));
for (let botType of botTypes) for (let botType of botTypes)
{ {
const enumType = botType.toLowerCase(); const enumType = botType.toLowerCase();

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { ISetMagazineRequest } from "@spt-aki/models/eft/builds/ISetMagazineRequest"; import { ISetMagazineRequest } from "@spt-aki/models/eft/builds/ISetMagazineRequest";
@ -43,11 +42,11 @@ export class BuildController
const defaultEquipmentPresetsClone = this.jsonUtil.clone( const defaultEquipmentPresetsClone = this.jsonUtil.clone(
this.databaseServer.getTables().templates.defaultEquipmentPresets, this.databaseServer.getTables().templates.defaultEquipmentPresets,
); );
const playerSecureContainer = profile.characters.pmc.Inventory.items?.find((x) => const playerSecureContainer = profile.characters.pmc.Inventory.items?.find(x =>
x.slotId === secureContainerSlotId x.slotId === secureContainerSlotId,
); );
const firstDefaultItemsSecureContainer = defaultEquipmentPresetsClone[0]?.Items?.find((x) => const firstDefaultItemsSecureContainer = defaultEquipmentPresetsClone[0]?.Items?.find(x =>
x.slotId === secureContainerSlotId x.slotId === secureContainerSlotId,
); );
if (playerSecureContainer && playerSecureContainer?._tpl !== firstDefaultItemsSecureContainer?._tpl) if (playerSecureContainer && playerSecureContainer?._tpl !== firstDefaultItemsSecureContainer?._tpl)
{ {
@ -55,7 +54,7 @@ export class BuildController
for (const defaultPreset of defaultEquipmentPresetsClone) for (const defaultPreset of defaultEquipmentPresetsClone)
{ {
// Find presets secure container // Find presets secure container
const secureContainer = defaultPreset.Items.find((item) => item.slotId === secureContainerSlotId); const secureContainer = defaultPreset.Items.find(item => item.slotId === secureContainerSlotId);
if (secureContainer) if (secureContainer)
{ {
secureContainer._tpl = playerSecureContainer._tpl; secureContainer._tpl = playerSecureContainer._tpl;
@ -84,7 +83,7 @@ export class BuildController
const newBuild: IWeaponBuild = { Id: body.Id, Name: body.Name, Root: body.Root, Items: body.Items }; const newBuild: IWeaponBuild = { Id: body.Id, Name: body.Name, Root: body.Root, Items: body.Items };
const savedWeaponBuilds = this.saveServer.getProfile(sessionId).userbuilds.weaponBuilds; const savedWeaponBuilds = this.saveServer.getProfile(sessionId).userbuilds.weaponBuilds;
const existingBuild = savedWeaponBuilds.find((x) => x.Id === body.Id); const existingBuild = savedWeaponBuilds.find(x => x.Id === body.Id);
if (existingBuild) if (existingBuild)
{ {
// exists, replace // exists, replace
@ -107,8 +106,8 @@ export class BuildController
const buildType = "equipmentBuilds"; const buildType = "equipmentBuilds";
const pmcData = this.profileHelper.getPmcProfile(sessionID); const pmcData = this.profileHelper.getPmcProfile(sessionID);
const existingSavedEquipmentBuilds: IEquipmentBuild[] = const existingSavedEquipmentBuilds: IEquipmentBuild[] = this.saveServer.getProfile(sessionID)
this.saveServer.getProfile(sessionID).userbuilds[buildType]; .userbuilds[buildType];
// Replace duplicate ID's. The first item is the base item. // Replace duplicate ID's. The first item is the base item.
// Root ID and the base item ID need to match. // Root ID and the base item ID need to match.
@ -122,8 +121,8 @@ export class BuildController
Items: request.Items, Items: request.Items,
}; };
const existingBuild = existingSavedEquipmentBuilds.find((build) => const existingBuild = existingSavedEquipmentBuilds.find(build =>
build.Name === request.Name || build.Id === request.Id build.Name === request.Name || build.Id === request.Id,
); );
if (existingBuild) if (existingBuild)
{ {
@ -141,7 +140,7 @@ export class BuildController
} }
} }
/** Handle client/builds/delete*/ /** Handle client/builds/delete */
public removeBuild(sessionID: string, request: IRemoveBuildRequestData): void public removeBuild(sessionID: string, request: IRemoveBuildRequestData): void
{ {
this.removePlayerBuild(request.id, sessionID); this.removePlayerBuild(request.id, sessionID);
@ -155,7 +154,7 @@ export class BuildController
const magazineBuilds = profile.userbuilds.magazineBuilds; const magazineBuilds = profile.userbuilds.magazineBuilds;
// Check for id in weapon array first // Check for id in weapon array first
const matchingWeaponBuild = weaponBuilds.find((weaponBuild) => weaponBuild.Id === idToRemove); const matchingWeaponBuild = weaponBuilds.find(weaponBuild => weaponBuild.Id === idToRemove);
if (matchingWeaponBuild) if (matchingWeaponBuild)
{ {
weaponBuilds.splice(weaponBuilds.indexOf(matchingWeaponBuild), 1); weaponBuilds.splice(weaponBuilds.indexOf(matchingWeaponBuild), 1);
@ -164,7 +163,7 @@ export class BuildController
} }
// Id not found in weapons, try equipment // Id not found in weapons, try equipment
const matchingEquipmentBuild = equipmentBuilds.find((equipmentBuild) => equipmentBuild.Id === idToRemove); const matchingEquipmentBuild = equipmentBuilds.find(equipmentBuild => equipmentBuild.Id === idToRemove);
if (matchingEquipmentBuild) if (matchingEquipmentBuild)
{ {
equipmentBuilds.splice(equipmentBuilds.indexOf(matchingEquipmentBuild), 1); equipmentBuilds.splice(equipmentBuilds.indexOf(matchingEquipmentBuild), 1);
@ -173,7 +172,7 @@ export class BuildController
} }
// Id not found in weapons/equipment, try mags // Id not found in weapons/equipment, try mags
const matchingMagazineBuild = magazineBuilds.find((magBuild) => magBuild.Id === idToRemove); const matchingMagazineBuild = magazineBuilds.find(magBuild => magBuild.Id === idToRemove);
if (matchingMagazineBuild) if (matchingMagazineBuild)
{ {
magazineBuilds.splice(magazineBuilds.indexOf(matchingMagazineBuild), 1); magazineBuilds.splice(magazineBuilds.indexOf(matchingMagazineBuild), 1);
@ -208,7 +207,7 @@ export class BuildController
profile.userbuilds.magazineBuilds = []; profile.userbuilds.magazineBuilds = [];
} }
const existingArrayId = profile.userbuilds.magazineBuilds.findIndex((item) => item.Name === request.Name); const existingArrayId = profile.userbuilds.magazineBuilds.findIndex(item => item.Name === request.Name);
if (existingArrayId === -1) if (existingArrayId === -1)
{ {

View File

@ -1,9 +1,9 @@
import { inject, injectable } from "tsyringe";
import { IClientLogRequest } from "@spt-aki/models/spt/logging/IClientLogRequest"; import { IClientLogRequest } from "@spt-aki/models/spt/logging/IClientLogRequest";
import { LogBackgroundColor } from "@spt-aki/models/spt/logging/LogBackgroundColor"; import { LogBackgroundColor } from "@spt-aki/models/spt/logging/LogBackgroundColor";
import { LogLevel } from "@spt-aki/models/spt/logging/LogLevel"; import { LogLevel } from "@spt-aki/models/spt/logging/LogLevel";
import { LogTextColor } from "@spt-aki/models/spt/logging/LogTextColor"; import { LogTextColor } from "@spt-aki/models/spt/logging/LogTextColor";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { inject, injectable } from "tsyringe";
@injectable() @injectable()
export class ClientLogController export class ClientLogController

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { ISuit } from "@spt-aki/models/eft/common/tables/ITrader"; import { ISuit } from "@spt-aki/models/eft/common/tables/ITrader";
@ -43,10 +42,10 @@ export class CustomizationController
const suits = this.databaseServer.getTables().traders[traderID].suits; const suits = this.databaseServer.getTables().traders[traderID].suits;
// Get an inner join of clothing from templates.customization and Ragman's suits array // Get an inner join of clothing from templates.customization and Ragman's suits array
const matchingSuits = suits.filter((x) => x.suiteId in templates); const matchingSuits = suits.filter(x => x.suiteId in templates);
// Return all suits that have a side array containing the players side (usec/bear) // Return all suits that have a side array containing the players side (usec/bear)
return matchingSuits.filter((x) => templates[x.suiteId]._props.Side.includes(pmcData.Info.Side)); return matchingSuits.filter(x => templates[x.suiteId]._props.Side.includes(pmcData.Info.Side));
} }
/** /**
@ -133,7 +132,7 @@ export class CustomizationController
protected getTraderClothingOffer(sessionId: string, offerId: string): ISuit protected getTraderClothingOffer(sessionId: string, offerId: string): ISuit
{ {
return this.getAllTraderSuits(sessionId).find((x) => x._id === offerId); return this.getAllTraderSuits(sessionId).find(x => x._id === offerId);
} }
/** /**
@ -181,7 +180,7 @@ export class CustomizationController
output: IItemEventRouterResponse, output: IItemEventRouterResponse,
): void ): void
{ {
const relatedItem = pmcData.Inventory.items.find((x) => x._id === clothingItem.id); const relatedItem = pmcData.Inventory.items.find(x => x._id === clothingItem.id);
if (!relatedItem) if (!relatedItem)
{ {
this.logger.error( this.logger.error(

View File

@ -1,5 +1,4 @@
import { inject, injectAll, injectable } from "tsyringe"; import { inject, injectAll, injectable } from "tsyringe";
import { IDialogueChatBot } from "@spt-aki/helpers/Dialogue/IDialogueChatBot"; import { IDialogueChatBot } from "@spt-aki/helpers/Dialogue/IDialogueChatBot";
import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper"; import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper";
import { IGetAllAttachmentsResponse } from "@spt-aki/models/eft/dialog/IGetAllAttachmentsResponse"; import { IGetAllAttachmentsResponse } from "@spt-aki/models/eft/dialog/IGetAllAttachmentsResponse";
@ -34,21 +33,21 @@ export class DialogueController
// if give command is disabled or commando commands are disabled // if give command is disabled or commando commands are disabled
if (!coreConfigs.features?.chatbotFeatures?.commandoEnabled) if (!coreConfigs.features?.chatbotFeatures?.commandoEnabled)
{ {
const sptCommando = this.dialogueChatBots.find((c) => const sptCommando = this.dialogueChatBots.find(c =>
c.getChatBot()._id.toLocaleLowerCase() === "sptcommando" c.getChatBot()._id.toLocaleLowerCase() === "sptcommando",
); );
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptCommando), 1); this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptCommando), 1);
} }
if (!coreConfigs.features?.chatbotFeatures?.sptFriendEnabled) if (!coreConfigs.features?.chatbotFeatures?.sptFriendEnabled)
{ {
const sptFriend = this.dialogueChatBots.find((c) => c.getChatBot()._id.toLocaleLowerCase() === "sptFriend"); const sptFriend = this.dialogueChatBots.find(c => c.getChatBot()._id.toLocaleLowerCase() === "sptFriend");
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptFriend), 1); this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptFriend), 1);
} }
} }
public registerChatBot(chatBot: IDialogueChatBot): void public registerChatBot(chatBot: IDialogueChatBot): void
{ {
if (this.dialogueChatBots.some((cb) => cb.getChatBot()._id === chatBot.getChatBot()._id)) if (this.dialogueChatBots.some(cb => cb.getChatBot()._id === chatBot.getChatBot()._id))
{ {
throw new Error(`The chat bot ${chatBot.getChatBot()._id} being registered already exists!`); throw new Error(`The chat bot ${chatBot.getChatBot()._id} being registered already exists!`);
} }
@ -73,7 +72,7 @@ export class DialogueController
public getFriendList(sessionID: string): IGetFriendListDataResponse public getFriendList(sessionID: string): IGetFriendListDataResponse
{ {
// Force a fake friend called SPT into friend list // Force a fake friend called SPT into friend list
return { Friends: this.dialogueChatBots.map((v) => v.getChatBot()), Ignore: [], InIgnoreList: [] }; return { Friends: this.dialogueChatBots.map(v => v.getChatBot()), Ignore: [], InIgnoreList: [] };
} }
/** /**
@ -117,6 +116,7 @@ export class DialogueController
return result; return result;
} }
/** /**
* Get the users involved in a dialog (player + other party) * Get the users involved in a dialog (player + other party)
* @param dialog The dialog to check for users * @param dialog The dialog to check for users
@ -131,7 +131,7 @@ export class DialogueController
// User to user messages are special in that they need the player to exist in them, add if they don't // User to user messages are special in that they need the player to exist in them, add if they don't
if ( if (
messageType === MessageType.USER_MESSAGE messageType === MessageType.USER_MESSAGE
&& !dialog.Users?.find((userDialog) => userDialog._id === profile.characters.pmc.sessionId) && !dialog.Users?.find(userDialog => userDialog._id === profile.characters.pmc.sessionId)
) )
{ {
if (!dialog.Users) if (!dialog.Users)
@ -207,7 +207,7 @@ export class DialogueController
if (request.type === MessageType.USER_MESSAGE) if (request.type === MessageType.USER_MESSAGE)
{ {
profile.dialogues[request.dialogId].Users = []; profile.dialogues[request.dialogId].Users = [];
const chatBot = this.dialogueChatBots.find((cb) => cb.getChatBot()._id === request.dialogId); const chatBot = this.dialogueChatBots.find(cb => cb.getChatBot()._id === request.dialogId);
if (chatBot) if (chatBot)
{ {
profile.dialogues[request.dialogId].Users.push(chatBot.getChatBot()); profile.dialogues[request.dialogId].Users.push(chatBot.getChatBot());
@ -217,6 +217,7 @@ export class DialogueController
return profile.dialogues[request.dialogId]; return profile.dialogues[request.dialogId];
} }
/** /**
* Get the users involved in a mail between two entities * Get the users involved in a mail between two entities
* @param fullProfile Player profile * @param fullProfile Player profile
@ -230,7 +231,7 @@ export class DialogueController
{ {
result.push(...dialogUsers); result.push(...dialogUsers);
if (!result.find((userDialog) => userDialog._id === fullProfile.info.id)) if (!result.find(userDialog => userDialog._id === fullProfile.info.id))
{ {
// Player doesnt exist, add them in before returning // Player doesnt exist, add them in before returning
const pmcProfile = fullProfile.characters.pmc; const pmcProfile = fullProfile.characters.pmc;
@ -278,7 +279,7 @@ export class DialogueController
*/ */
protected messagesHaveUncollectedRewards(messages: Message[]): boolean protected messagesHaveUncollectedRewards(messages: Message[]): boolean
{ {
return messages.some((message) => message.items?.data?.length > 0); return messages.some(message => message.items?.data?.length > 0);
} }
/** /**
@ -375,7 +376,7 @@ export class DialogueController
{ {
this.mailSendService.sendPlayerMessageToNpc(sessionId, request.dialogId, request.text); this.mailSendService.sendPlayerMessageToNpc(sessionId, request.dialogId, request.text);
return this.dialogueChatBots.find((cb) => cb.getChatBot()._id === request.dialogId)?.handleMessage( return this.dialogueChatBots.find(cb => cb.getChatBot()._id === request.dialogId)?.handleMessage(
sessionId, sessionId,
request, request,
) ?? request.dialogId; ) ?? request.dialogId;
@ -391,7 +392,7 @@ export class DialogueController
{ {
const timeNow = this.timeUtil.getTimestamp(); const timeNow = this.timeUtil.getTimestamp();
const dialogs = this.dialogueHelper.getDialogsForProfile(sessionId); const dialogs = this.dialogueHelper.getDialogsForProfile(sessionId);
return dialogs[dialogueId].messages.filter((message) => timeNow < (message.dt + message.maxStorageTime)); return dialogs[dialogueId].messages.filter(message => timeNow < message.dt + message.maxStorageTime);
} }
/** /**
@ -401,7 +402,7 @@ export class DialogueController
*/ */
protected getMessagesWithAttachments(messages: Message[]): Message[] protected getMessagesWithAttachments(messages: Message[]): Message[]
{ {
return messages.filter((message) => message.items?.data?.length > 0); return messages.filter(message => message.items?.data?.length > 0);
} }
/** /**
@ -446,6 +447,6 @@ export class DialogueController
*/ */
protected messageHasExpired(message: Message): boolean protected messageHasExpired(message: Message): boolean
{ {
return (this.timeUtil.getTimestamp()) > (message.dt + message.maxStorageTime); return this.timeUtil.getTimestamp() > message.dt + message.maxStorageTime;
} }
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
import { ContextVariableType } from "@spt-aki/context/ContextVariableType"; import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
import { HideoutHelper } from "@spt-aki/helpers/HideoutHelper"; import { HideoutHelper } from "@spt-aki/helpers/HideoutHelper";
@ -358,8 +357,8 @@ export class GameController
for (const positionToAdd of positionsToAdd) for (const positionToAdd of positionsToAdd)
{ {
// Exists already, add new items to existing positions pool // Exists already, add new items to existing positions pool
const existingLootPosition = mapLooseLoot.spawnpoints.find((x) => const existingLootPosition = mapLooseLoot.spawnpoints.find(x =>
x.template.Id === positionToAdd.template.Id x.template.Id === positionToAdd.template.Id,
); );
if (existingLootPosition) if (existingLootPosition)
{ {
@ -389,7 +388,7 @@ export class GameController
const mapLootAdjustmentsDict = adjustments[mapId]; const mapLootAdjustmentsDict = adjustments[mapId];
for (const lootKey in mapLootAdjustmentsDict) for (const lootKey in mapLootAdjustmentsDict)
{ {
const lootPostionToAdjust = mapLooseLootData.spawnpoints.find((x) => x.template.Id === lootKey); const lootPostionToAdjust = mapLooseLootData.spawnpoints.find(x => x.template.Id === lootKey);
if (!lootPostionToAdjust) if (!lootPostionToAdjust)
{ {
this.logger.warning(`Unable to adjust loot position: ${lootKey} on map: ${mapId}`); this.logger.warning(`Unable to adjust loot position: ${lootKey} on map: ${mapId}`);
@ -422,7 +421,7 @@ export class GameController
for (const botToLimit of this.locationConfig.botTypeLimits[mapId]) for (const botToLimit of this.locationConfig.botTypeLimits[mapId])
{ {
const index = map.base.MinMaxBots.findIndex((x) => x.WildSpawnType === botToLimit.type); const index = map.base.MinMaxBots.findIndex(x => x.WildSpawnType === botToLimit.type);
if (index !== -1) if (index !== -1)
{ {
// Existing bot type found in MinMaxBots array, edit // Existing bot type found in MinMaxBots array, edit
@ -450,9 +449,9 @@ export class GameController
public getGameConfig(sessionID: string): IGameConfigResponse public getGameConfig(sessionID: string): IGameConfigResponse
{ {
const profile = this.profileHelper.getPmcProfile(sessionID); const profile = this.profileHelper.getPmcProfile(sessionID);
const gameTime = const gameTime
profile.Stats?.Eft.OverallCounters.Items?.find((counter) => = profile.Stats?.Eft.OverallCounters.Items?.find(counter =>
counter.Key.includes("LifeTime") && counter.Key.includes("Pmc") counter.Key.includes("LifeTime") && counter.Key.includes("Pmc"),
)?.Value ?? 0; )?.Value ?? 0;
const config: IGameConfigResponse = { const config: IGameConfigResponse = {
@ -589,12 +588,12 @@ export class GameController
let hpRegenPerHour = 456.6; let hpRegenPerHour = 456.6;
// Set new values, whatever is smallest // Set new values, whatever is smallest
energyRegenPerHour += pmcProfile.Bonuses.filter((bonus) => bonus.type === BonusType.ENERGY_REGENERATION) energyRegenPerHour += pmcProfile.Bonuses.filter(bonus => bonus.type === BonusType.ENERGY_REGENERATION)
.reduce((sum, curr) => sum + curr.value, 0); .reduce((sum, curr) => sum + curr.value, 0);
hydrationRegenPerHour += pmcProfile.Bonuses.filter((bonus) => hydrationRegenPerHour += pmcProfile.Bonuses.filter(bonus =>
bonus.type === BonusType.HYDRATION_REGENERATION bonus.type === BonusType.HYDRATION_REGENERATION,
).reduce((sum, curr) => sum + curr.value, 0); ).reduce((sum, curr) => sum + curr.value, 0);
hpRegenPerHour += pmcProfile.Bonuses.filter((bonus) => bonus.type === BonusType.HEALTH_REGENERATION).reduce( hpRegenPerHour += pmcProfile.Bonuses.filter(bonus => bonus.type === BonusType.HEALTH_REGENERATION).reduce(
(sum, curr) => sum + curr.value, (sum, curr) => sum + curr.value,
0, 0,
); );
@ -691,7 +690,7 @@ export class GameController
for (const wave of location.base.waves ?? []) for (const wave of location.base.waves ?? [])
{ {
if ((wave.slots_max - wave.slots_min === 0)) if (wave.slots_max - wave.slots_min === 0)
{ {
this.logger.debug( this.logger.debug(
`Fixed ${wave.WildSpawnType} Spawn: ${locationKey} wave: ${wave.number} of type: ${wave.WildSpawnType} in zone: ${wave.SpawnPoints} with Max Slots of ${wave.slots_max}`, `Fixed ${wave.WildSpawnType} Spawn: ${locationKey} wave: ${wave.number} of type: ${wave.WildSpawnType} in zone: ${wave.SpawnPoints} with Max Slots of ${wave.slots_max}`,
@ -729,13 +728,13 @@ export class GameController
const currentTimeStamp = this.timeUtil.getTimestamp(); const currentTimeStamp = this.timeUtil.getTimestamp();
// One day post-profile creation // One day post-profile creation
if (currentTimeStamp > (timeStampProfileCreated + oneDaySeconds)) if (currentTimeStamp > timeStampProfileCreated + oneDaySeconds)
{ {
this.giftService.sendPraporStartingGift(pmcProfile.sessionId, 1); this.giftService.sendPraporStartingGift(pmcProfile.sessionId, 1);
} }
// Two day post-profile creation // Two day post-profile creation
if (currentTimeStamp > (timeStampProfileCreated + (oneDaySeconds * 2))) if (currentTimeStamp > timeStampProfileCreated + oneDaySeconds * 2)
{ {
this.giftService.sendPraporStartingGift(pmcProfile.sessionId, 2); this.giftService.sendPraporStartingGift(pmcProfile.sessionId, 2);
} }
@ -761,7 +760,7 @@ export class GameController
// Wave has size that makes it candidate for splitting // Wave has size that makes it candidate for splitting
if ( if (
wave.slots_max - wave.slots_min wave.slots_max - wave.slots_min
>= this.locationConfig.splitWaveIntoSingleSpawnsSettings.waveSizeThreshold >= this.locationConfig.splitWaveIntoSingleSpawnsSettings.waveSizeThreshold
) )
{ {
// Get count of bots to be spawned in wave // Get count of bots to be spawned in wave
@ -832,8 +831,8 @@ export class GameController
{ {
const modDetails = activeMods[modKey]; const modDetails = activeMods[modKey];
if ( if (
fullProfile.aki.mods.some((x) => fullProfile.aki.mods.some(x =>
x.author === modDetails.author && x.name === modDetails.name && x.version === modDetails.version x.author === modDetails.author && x.name === modDetails.name && x.version === modDetails.version,
) )
) )
{ {
@ -948,8 +947,8 @@ export class GameController
protected adjustLabsRaiderSpawnRate(): void protected adjustLabsRaiderSpawnRate(): void
{ {
const labsBase = this.databaseServer.getTables().locations.laboratory.base; const labsBase = this.databaseServer.getTables().locations.laboratory.base;
const nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.filter((x) => const nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.filter(x =>
x.TriggerId === "" && x.TriggerName === "" x.TriggerId === "" && x.TriggerName === "",
); );
if (nonTriggerLabsBossSpawns) if (nonTriggerLabsBossSpawns)
{ {

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper"; import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { HealthHelper } from "@spt-aki/helpers/HealthHelper"; import { HealthHelper } from "@spt-aki/helpers/HealthHelper";
import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper"; import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
@ -66,7 +65,7 @@ export class HealthController
const output = this.eventOutputHolder.getOutput(sessionID); const output = this.eventOutputHolder.getOutput(sessionID);
// Update medkit used (hpresource) // Update medkit used (hpresource)
const healingItemToUse = pmcData.Inventory.items.find((item) => item._id === request.item); const healingItemToUse = pmcData.Inventory.items.find(item => item._id === request.item);
if (!healingItemToUse) if (!healingItemToUse)
{ {
const errorMessage = this.localisationService.getText( const errorMessage = this.localisationService.getText(
@ -114,7 +113,7 @@ export class HealthController
const output = this.eventOutputHolder.getOutput(sessionID); const output = this.eventOutputHolder.getOutput(sessionID);
let resourceLeft = 0; let resourceLeft = 0;
const itemToConsume = pmcData.Inventory.items.find((x) => x._id === request.item); const itemToConsume = pmcData.Inventory.items.find(x => x._id === request.item);
if (!itemToConsume) if (!itemToConsume)
{ {
// Item not found, very bad // Item not found, very bad

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ScavCaseRewardGenerator } from "@spt-aki/generators/ScavCaseRewardGenerator"; import { ScavCaseRewardGenerator } from "@spt-aki/generators/ScavCaseRewardGenerator";
import { HideoutHelper } from "@spt-aki/helpers/HideoutHelper"; import { HideoutHelper } from "@spt-aki/helpers/HideoutHelper";
import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper"; import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
@ -106,7 +105,7 @@ export class HideoutController
{ {
const items = request.items.map((reqItem) => const items = request.items.map((reqItem) =>
{ {
const item = pmcData.Inventory.items.find((invItem) => invItem._id === reqItem.id); const item = pmcData.Inventory.items.find(invItem => invItem._id === reqItem.id);
return { inventoryItem: item, requestedItem: reqItem }; return { inventoryItem: item, requestedItem: reqItem };
}); });
@ -139,7 +138,7 @@ export class HideoutController
} }
// Construction time management // Construction time management
const profileHideoutArea = pmcData.Hideout.Areas.find((area) => area.type === request.areaType); const profileHideoutArea = pmcData.Hideout.Areas.find(area => area.type === request.areaType);
if (!profileHideoutArea) if (!profileHideoutArea)
{ {
this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType)); this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType));
@ -148,8 +147,8 @@ export class HideoutController
return; return;
} }
const hideoutDataDb = this.databaseServer.getTables().hideout.areas.find((area) => const hideoutDataDb = this.databaseServer.getTables().hideout.areas.find(area =>
area.type === request.areaType area.type === request.areaType,
); );
if (!hideoutDataDb) if (!hideoutDataDb)
{ {
@ -192,7 +191,7 @@ export class HideoutController
{ {
const db = this.databaseServer.getTables(); const db = this.databaseServer.getTables();
const profileHideoutArea = pmcData.Hideout.Areas.find((area) => area.type === request.areaType); const profileHideoutArea = pmcData.Hideout.Areas.find(area => area.type === request.areaType);
if (!profileHideoutArea) if (!profileHideoutArea)
{ {
this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType)); this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType));
@ -206,7 +205,7 @@ export class HideoutController
profileHideoutArea.completeTime = 0; profileHideoutArea.completeTime = 0;
profileHideoutArea.constructing = false; profileHideoutArea.constructing = false;
const hideoutData = db.hideout.areas.find((area) => area.type === profileHideoutArea.type); const hideoutData = db.hideout.areas.find(area => area.type === profileHideoutArea.type);
if (!hideoutData) if (!hideoutData)
{ {
this.logger.error( this.logger.error(
@ -264,11 +263,11 @@ export class HideoutController
*/ */
protected checkAndUpgradeWall(pmcData: IPmcData): void protected checkAndUpgradeWall(pmcData: IPmcData): void
{ {
const medStation = pmcData.Hideout.Areas.find((area) => area.type === HideoutAreas.MEDSTATION); const medStation = pmcData.Hideout.Areas.find(area => area.type === HideoutAreas.MEDSTATION);
const waterCollector = pmcData.Hideout.Areas.find((area) => area.type === HideoutAreas.WATER_COLLECTOR); const waterCollector = pmcData.Hideout.Areas.find(area => area.type === HideoutAreas.WATER_COLLECTOR);
if (medStation?.level >= 1 && waterCollector?.level >= 1) if (medStation?.level >= 1 && waterCollector?.level >= 1)
{ {
const wall = pmcData.Hideout.Areas.find((area) => area.type === HideoutAreas.EMERGENCY_WALL); const wall = pmcData.Hideout.Areas.find(area => area.type === HideoutAreas.EMERGENCY_WALL);
if (wall?.level === 0) if (wall?.level === 0)
{ {
wall.level = 3; wall.level = 3;
@ -310,8 +309,8 @@ export class HideoutController
} }
// Some areas like gun stand have a child area linked to it, it needs to do the same as above // Some areas like gun stand have a child area linked to it, it needs to do the same as above
const childDbArea = this.databaseServer.getTables().hideout.areas.find((x) => const childDbArea = this.databaseServer.getTables().hideout.areas.find(x =>
x.parentArea === dbHideoutArea._id x.parentArea === dbHideoutArea._id,
); );
if (childDbArea) if (childDbArea)
{ {
@ -322,8 +321,8 @@ export class HideoutController
} }
// Set child area level to same as parent area // Set child area level to same as parent area
pmcData.Hideout.Areas.find((x) => x.type === childDbArea.type).level = pmcData.Hideout.Areas.find((x) => pmcData.Hideout.Areas.find(x => x.type === childDbArea.type).level = pmcData.Hideout.Areas.find(x =>
x.type === profileParentHideoutArea.type x.type === profileParentHideoutArea.type,
).level; ).level;
// Add/upgrade stash item in player inventory // Add/upgrade stash item in player inventory
@ -343,7 +342,7 @@ export class HideoutController
*/ */
protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void protected addUpdateInventoryItemToProfile(pmcData: IPmcData, dbHideoutData: IHideoutArea, hideoutStage: Stage): void
{ {
const existingInventoryItem = pmcData.Inventory.items.find((x) => x._id === dbHideoutData._id); const existingInventoryItem = pmcData.Inventory.items.find(x => x._id === dbHideoutData._id);
if (existingInventoryItem) if (existingInventoryItem)
{ {
// Update existing items container tpl to point to new id (tpl) // Update existing items container tpl to point to new id (tpl)
@ -400,11 +399,11 @@ export class HideoutController
const itemsToAdd = Object.entries(addItemToHideoutRequest.items).map((kvp) => const itemsToAdd = Object.entries(addItemToHideoutRequest.items).map((kvp) =>
{ {
const item = pmcData.Inventory.items.find((invItem) => invItem._id === kvp[1].id); const item = pmcData.Inventory.items.find(invItem => invItem._id === kvp[1].id);
return { inventoryItem: item, requestedItem: kvp[1], slot: kvp[0] }; return { inventoryItem: item, requestedItem: kvp[1], slot: kvp[0] };
}); });
const hideoutArea = pmcData.Hideout.Areas.find((area) => area.type === addItemToHideoutRequest.areaType); const hideoutArea = pmcData.Hideout.Areas.find(area => area.type === addItemToHideoutRequest.areaType);
if (!hideoutArea) if (!hideoutArea)
{ {
this.logger.error( this.logger.error(
@ -431,7 +430,7 @@ export class HideoutController
// Add item to area.slots // Add item to area.slots
const destinationLocationIndex = Number(item.slot); const destinationLocationIndex = Number(item.slot);
const hideoutSlotIndex = hideoutArea.slots.findIndex((x) => x.locationIndex === destinationLocationIndex); const hideoutSlotIndex = hideoutArea.slots.findIndex(x => x.locationIndex === destinationLocationIndex);
hideoutArea.slots[hideoutSlotIndex].item = [{ hideoutArea.slots[hideoutSlotIndex].item = [{
_id: item.inventoryItem._id, _id: item.inventoryItem._id,
_tpl: item.inventoryItem._tpl, _tpl: item.inventoryItem._tpl,
@ -463,7 +462,7 @@ export class HideoutController
{ {
const output = this.eventOutputHolder.getOutput(sessionID); const output = this.eventOutputHolder.getOutput(sessionID);
const hideoutArea = pmcData.Hideout.Areas.find((area) => area.type === request.areaType); const hideoutArea = pmcData.Hideout.Areas.find(area => area.type === request.areaType);
if (!hideoutArea) if (!hideoutArea)
{ {
this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType)); this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType));
@ -520,7 +519,7 @@ export class HideoutController
const slotIndexToRemove = removeResourceRequest.slots[0]; const slotIndexToRemove = removeResourceRequest.slots[0];
// Assume only one item in slot // Assume only one item in slot
const itemToReturn = hideoutArea.slots.find((slot) => slot.locationIndex === slotIndexToRemove).item[0]; const itemToReturn = hideoutArea.slots.find(slot => slot.locationIndex === slotIndexToRemove).item[0];
const request: IAddItemDirectRequest = { const request: IAddItemDirectRequest = {
itemWithModsToAdd: [itemToReturn], itemWithModsToAdd: [itemToReturn],
@ -537,7 +536,7 @@ export class HideoutController
} }
// Remove items from slot, locationIndex remains // Remove items from slot, locationIndex remains
const hideoutSlotIndex = hideoutArea.slots.findIndex((slot) => slot.locationIndex === slotIndexToRemove); const hideoutSlotIndex = hideoutArea.slots.findIndex(slot => slot.locationIndex === slotIndexToRemove);
hideoutArea.slots[hideoutSlotIndex].item = undefined; hideoutArea.slots[hideoutSlotIndex].item = undefined;
return output; return output;
@ -562,7 +561,7 @@ export class HideoutController
// Force a production update (occur before area is toggled as it could be generator and doing it after generator enabled would cause incorrect calculaton of production progress) // Force a production update (occur before area is toggled as it could be generator and doing it after generator enabled would cause incorrect calculaton of production progress)
this.hideoutHelper.updatePlayerHideout(sessionID); this.hideoutHelper.updatePlayerHideout(sessionID);
const hideoutArea = pmcData.Hideout.Areas.find((area) => area.type === request.areaType); const hideoutArea = pmcData.Hideout.Areas.find(area => area.type === request.areaType);
if (!hideoutArea) if (!hideoutArea)
{ {
this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType)); this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType));
@ -592,20 +591,20 @@ export class HideoutController
this.hideoutHelper.registerProduction(pmcData, body, sessionID); this.hideoutHelper.registerProduction(pmcData, body, sessionID);
// Find the recipe of the production // Find the recipe of the production
const recipe = this.databaseServer.getTables().hideout.production.find((p) => p._id === body.recipeId); const recipe = this.databaseServer.getTables().hideout.production.find(p => p._id === body.recipeId);
// Find the actual amount of items we need to remove because body can send weird data // Find the actual amount of items we need to remove because body can send weird data
const recipeRequirementsClone = this.jsonUtil.clone( const recipeRequirementsClone = this.jsonUtil.clone(
recipe.requirements.filter((i) => i.type === "Item" || i.type === "Tool"), recipe.requirements.filter(i => i.type === "Item" || i.type === "Tool"),
); );
const output = this.eventOutputHolder.getOutput(sessionID); const output = this.eventOutputHolder.getOutput(sessionID);
const itemsToDelete = body.items.concat(body.tools); const itemsToDelete = body.items.concat(body.tools);
for (const itemToDelete of itemsToDelete) for (const itemToDelete of itemsToDelete)
{ {
const itemToCheck = pmcData.Inventory.items.find((i) => i._id === itemToDelete.id); const itemToCheck = pmcData.Inventory.items.find(i => i._id === itemToDelete.id);
const requirement = recipeRequirementsClone.find((requirement) => const requirement = recipeRequirementsClone.find(requirement =>
requirement.templateId === itemToCheck._tpl requirement.templateId === itemToCheck._tpl,
); );
// Handle tools not having a `count`, but always only requiring 1 // Handle tools not having a `count`, but always only requiring 1
@ -645,7 +644,7 @@ export class HideoutController
for (const requestedItem of body.items) for (const requestedItem of body.items)
{ {
const inventoryItem = pmcData.Inventory.items.find((item) => item._id === requestedItem.id); const inventoryItem = pmcData.Inventory.items.find(item => item._id === requestedItem.id);
if (!inventoryItem) if (!inventoryItem)
{ {
this.logger.error( this.logger.error(
@ -667,7 +666,7 @@ export class HideoutController
} }
} }
const recipe = this.databaseServer.getTables().hideout.scavcase.find((r) => r._id === body.recipeId); const recipe = this.databaseServer.getTables().hideout.scavcase.find(r => r._id === body.recipeId);
if (!recipe) if (!recipe)
{ {
this.logger.error( this.logger.error(
@ -679,13 +678,12 @@ export class HideoutController
// @Important: Here we need to be very exact: // @Important: Here we need to be very exact:
// - normal recipe: Production time value is stored in attribute "productionTime" with small "p" // - normal recipe: Production time value is stored in attribute "productionTime" with small "p"
// - scav case recipe: Production time value is stored in attribute "ProductionTime" with capital "P" // - scav case recipe: Production time value is stored in attribute "ProductionTime" with capital "P"
const adjustedCraftTime = recipe.ProductionTime const adjustedCraftTime = recipe.ProductionTime - this.hideoutHelper.getSkillProductionTimeReduction(
- this.hideoutHelper.getSkillProductionTimeReduction( pmcData,
pmcData, recipe.ProductionTime,
recipe.ProductionTime, SkillTypes.CRAFTING,
SkillTypes.CRAFTING, this.databaseServer.getTables().globals.config.SkillsSettings.Crafting.CraftTimeReductionPerLevel,
this.databaseServer.getTables().globals.config.SkillsSettings.Crafting.CraftTimeReductionPerLevel, );
);
const modifiedScavCaseTime = this.getScavCaseTime(pmcData, adjustedCraftTime); const modifiedScavCaseTime = this.getScavCaseTime(pmcData, adjustedCraftTime);
@ -772,7 +770,7 @@ export class HideoutController
return output; return output;
} }
const recipe = hideoutDb.production.find((r) => r._id === request.recipeId); const recipe = hideoutDb.production.find(r => r._id === request.recipeId);
if (recipe) if (recipe)
{ {
this.handleRecipe(sessionID, recipe, pmcData, request, output); this.handleRecipe(sessionID, recipe, pmcData, request, output);
@ -780,7 +778,7 @@ export class HideoutController
return output; return output;
} }
const scavCase = hideoutDb.scavcase.find((r) => r._id === request.recipeId); const scavCase = hideoutDb.scavcase.find(r => r._id === request.recipeId);
if (scavCase) if (scavCase)
{ {
this.handleScavCase(sessionID, pmcData, request, output); this.handleScavCase(sessionID, pmcData, request, output);
@ -938,7 +936,7 @@ export class HideoutController
} }
// Check if the recipe is the same as the last one - get bonus when crafting same thing multiple times // Check if the recipe is the same as the last one - get bonus when crafting same thing multiple times
const area = pmcData.Hideout.Areas.find((area) => area.type === recipe.areaType); const area = pmcData.Hideout.Areas.find(area => area.type === recipe.areaType);
if (area && request.recipeId !== area.lastRecipe) if (area && request.recipeId !== area.lastRecipe)
{ {
// 1 point per craft upon the end of production for alternating between 2 different crafting recipes in the same module // 1 point per craft upon the end of production for alternating between 2 different crafting recipes in the same module
@ -948,7 +946,7 @@ export class HideoutController
// Update variable with time spent crafting item(s) // Update variable with time spent crafting item(s)
// 1 point per 8 hours of crafting // 1 point per 8 hours of crafting
hoursCrafting += recipe.productionTime; hoursCrafting += recipe.productionTime;
if ((hoursCrafting / this.hideoutConfig.hoursForSkillCrafting) >= 1) if (hoursCrafting / this.hideoutConfig.hoursForSkillCrafting >= 1)
{ {
// Spent enough time crafting to get a bonus xp multipler // Spent enough time crafting to get a bonus xp multipler
const multiplierCrafting = Math.floor(hoursCrafting / this.hideoutConfig.hoursForSkillCrafting); const multiplierCrafting = Math.floor(hoursCrafting / this.hideoutConfig.hoursForSkillCrafting);
@ -1016,7 +1014,7 @@ export class HideoutController
{ {
this.profileHelper.addSkillPointsToPlayer(pmcData, SkillTypes.CRAFTING, craftingExpAmount); this.profileHelper.addSkillPointsToPlayer(pmcData, SkillTypes.CRAFTING, craftingExpAmount);
const intellectAmountToGive = 0.5 * (Math.round(craftingExpAmount / 15)); const intellectAmountToGive = 0.5 * Math.round(craftingExpAmount / 15);
if (intellectAmountToGive > 0) if (intellectAmountToGive > 0)
{ {
this.profileHelper.addSkillPointsToPlayer(pmcData, SkillTypes.INTELLECT, intellectAmountToGive); this.profileHelper.addSkillPointsToPlayer(pmcData, SkillTypes.INTELLECT, intellectAmountToGive);
@ -1189,14 +1187,14 @@ export class HideoutController
public recordShootingRangePoints(sessionId: string, pmcData: IPmcData, request: IRecordShootingRangePoints): void public recordShootingRangePoints(sessionId: string, pmcData: IPmcData, request: IRecordShootingRangePoints): void
{ {
// Check if counter exists, add placeholder if it doesnt // Check if counter exists, add placeholder if it doesnt
if (!pmcData.Stats.Eft.OverallCounters.Items.find((x) => x.Key.includes("ShootingRangePoints"))) if (!pmcData.Stats.Eft.OverallCounters.Items.find(x => x.Key.includes("ShootingRangePoints")))
{ {
pmcData.Stats.Eft.OverallCounters.Items.push({ Key: ["ShootingRangePoints"], Value: 0 }); pmcData.Stats.Eft.OverallCounters.Items.push({ Key: ["ShootingRangePoints"], Value: 0 });
} }
// Find counter by key and update value // Find counter by key and update value
const shootingRangeHighScore = pmcData.Stats.Eft.OverallCounters.Items.find((x) => const shootingRangeHighScore = pmcData.Stats.Eft.OverallCounters.Items.find(x =>
x.Key.includes("ShootingRangePoints") x.Key.includes("ShootingRangePoints"),
); );
shootingRangeHighScore.Value = request.points; shootingRangeHighScore.Value = request.points;
} }
@ -1218,7 +1216,7 @@ export class HideoutController
// Create mapping of required item with corrisponding item from player inventory // Create mapping of required item with corrisponding item from player inventory
const items = request.items.map((reqItem) => const items = request.items.map((reqItem) =>
{ {
const item = pmcData.Inventory.items.find((invItem) => invItem._id === reqItem.id); const item = pmcData.Inventory.items.find(invItem => invItem._id === reqItem.id);
return { inventoryItem: item, requestedItem: reqItem }; return { inventoryItem: item, requestedItem: reqItem };
}); });
@ -1248,14 +1246,14 @@ export class HideoutController
} }
} }
const profileHideoutArea = pmcData.Hideout.Areas.find((x) => x.type === request.areaType); const profileHideoutArea = pmcData.Hideout.Areas.find(x => x.type === request.areaType);
if (!profileHideoutArea) if (!profileHideoutArea)
{ {
this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType)); this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType));
return this.httpResponse.appendErrorToOutput(output); return this.httpResponse.appendErrorToOutput(output);
} }
const hideoutDbData = this.databaseServer.getTables().hideout.areas.find((x) => x.type === request.areaType); const hideoutDbData = this.databaseServer.getTables().hideout.areas.find(x => x.type === request.areaType);
if (!hideoutDbData) if (!hideoutDbData)
{ {
this.logger.error( this.logger.error(

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
import { ContextVariableType } from "@spt-aki/context/ContextVariableType"; import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
import { PlayerScavGenerator } from "@spt-aki/generators/PlayerScavGenerator"; import { PlayerScavGenerator } from "@spt-aki/generators/PlayerScavGenerator";
@ -204,8 +203,8 @@ export class InraidController
if (locationName === "lighthouse" && postRaidRequest.profile.Info.Side.toLowerCase() === "usec") if (locationName === "lighthouse" && postRaidRequest.profile.Info.Side.toLowerCase() === "usec")
{ {
// Decrement counter if it exists, don't go below 0 // Decrement counter if it exists, don't go below 0
const remainingCounter = serverPmcProfile?.Stats.Eft.OverallCounters.Items.find((x) => const remainingCounter = serverPmcProfile?.Stats.Eft.OverallCounters.Items.find(x =>
x.Key.includes("UsecRaidRemainKills") x.Key.includes("UsecRaidRemainKills"),
); );
if (remainingCounter?.Value > 0) if (remainingCounter?.Value > 0)
{ {
@ -229,9 +228,9 @@ export class InraidController
// Not dead // Not dead
// Check for cultist amulets in special slot (only slot it can fit) // Check for cultist amulets in special slot (only slot it can fit)
const amuletOnPlayer = serverPmcProfile.Inventory.items.filter((item) => const amuletOnPlayer = serverPmcProfile.Inventory.items.filter(item =>
item.slotId?.startsWith("SpecialSlot") item.slotId?.startsWith("SpecialSlot"),
).find((item) => item._tpl === "64d0b40fbe2eed70e254e2d4"); ).find(item => item._tpl === "64d0b40fbe2eed70e254e2d4");
if (amuletOnPlayer) if (amuletOnPlayer)
{ {
// No charges left, delete it // No charges left, delete it
@ -250,8 +249,8 @@ export class InraidController
} }
} }
const victims = postRaidRequest.profile.Stats.Eft.Victims.filter((x) => const victims = postRaidRequest.profile.Stats.Eft.Victims.filter(x =>
["sptbear", "sptusec"].includes(x.Role.toLowerCase()) ["sptbear", "sptusec"].includes(x.Role.toLowerCase()),
); );
if (victims?.length > 0) if (victims?.length > 0)
{ {
@ -283,9 +282,13 @@ export class InraidController
// Find and remove the completed condition from profile if player died, otherwise quest is stuck in limbo // Find and remove the completed condition from profile if player died, otherwise quest is stuck in limbo
// and quest items cannot be picked up again // and quest items cannot be picked up again
const allQuests = this.questHelper.getQuestsFromDb(); const allQuests = this.questHelper.getQuestsFromDb();
const activeQuestIdsInProfile = pmcData.Quests.filter((profileQuest) => const activeQuestIdsInProfile = pmcData.Quests.filter(
![QuestStatus.AvailableForStart, QuestStatus.Success, QuestStatus.Expired].includes(profileQuest.status) profileQuest => ![
).map((x) => x.qid); QuestStatus.AvailableForStart,
QuestStatus.Success,
QuestStatus.Expired,
].includes(profileQuest.status),
).map(x => x.qid);
for (const questItem of postRaidSaveRequest.profile.Stats.Eft.CarriedQuestItems) for (const questItem of postRaidSaveRequest.profile.Stats.Eft.CarriedQuestItems)
{ {
// Get quest/find condition for carried quest item // Get quest/find condition for carried quest item
@ -399,7 +402,7 @@ export class InraidController
*/ */
protected mergePmcAndScavEncyclopedias(primary: IPmcData, secondary: IPmcData): void protected mergePmcAndScavEncyclopedias(primary: IPmcData, secondary: IPmcData): void
{ {
function extend(target: { [key: string]: boolean; }, source: Record<string, boolean>) function extend(target: { [key: string]: boolean }, source: Record<string, boolean>)
{ {
for (const key in source) for (const key in source)
{ {
@ -469,7 +472,7 @@ export class InraidController
for (const quest of scavProfile.Quests) for (const quest of scavProfile.Quests)
{ {
const pmcQuest = pmcProfile.Quests.find((x) => x.qid === quest.qid); const pmcQuest = pmcProfile.Quests.find(x => x.qid === quest.qid);
if (!pmcQuest) if (!pmcQuest)
{ {
this.logger.warning(`No PMC quest found for ID: ${quest.qid}`); this.logger.warning(`No PMC quest found for ID: ${quest.qid}`);
@ -504,7 +507,7 @@ export class InraidController
for (const scavCounter of Object.values(scavProfile.TaskConditionCounters)) for (const scavCounter of Object.values(scavProfile.TaskConditionCounters))
{ {
// If this is an achievement that isn't for the scav, don't process it // If this is an achievement that isn't for the scav, don't process it
const achievement = achievements.find((achievement) => achievement.id === scavCounter.sourceId); const achievement = achievements.find(achievement => achievement.id === scavCounter.sourceId);
if (achievement && achievement.side !== "Savage") if (achievement && achievement.side !== "Savage")
{ {
continue; continue;
@ -541,7 +544,7 @@ export class InraidController
*/ */
protected isPlayerDead(statusOnExit: PlayerRaidEndState): boolean protected isPlayerDead(statusOnExit: PlayerRaidEndState): boolean
{ {
return (statusOnExit !== PlayerRaidEndState.SURVIVED && statusOnExit !== PlayerRaidEndState.RUNNER); return statusOnExit !== PlayerRaidEndState.SURVIVED && statusOnExit !== PlayerRaidEndState.RUNNER;
} }
/** /**
@ -686,8 +689,8 @@ export class InraidController
// Remove any items that were returned by the item delivery, but also insured, from the player's insurance list // Remove any items that were returned by the item delivery, but also insured, from the player's insurance list
// This is to stop items being duplicated by being returned from both the item delivery, and insurance // This is to stop items being duplicated by being returned from both the item delivery, and insurance
const deliveredItemIds = items.map((x) => x._id); const deliveredItemIds = items.map(x => x._id);
pmcData.InsuredItems = pmcData.InsuredItems.filter((x) => !deliveredItemIds.includes(x.itemId)); pmcData.InsuredItems = pmcData.InsuredItems.filter(x => !deliveredItemIds.includes(x.itemId));
// Send the items to the player // Send the items to the player
this.mailSendService.sendLocalisedNpcMessageToPlayer( this.mailSendService.sendLocalisedNpcMessageToPlayer(

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper"; import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
@ -113,7 +112,7 @@ export class InsuranceController
this.logger.debug(`Found ${profileInsuranceDetails.length} insurance packages in profile ${sessionID}`); this.logger.debug(`Found ${profileInsuranceDetails.length} insurance packages in profile ${sessionID}`);
} }
return profileInsuranceDetails.filter((insured) => insuranceTime >= insured.scheduledTime); return profileInsuranceDetails.filter(insured => insuranceTime >= insured.scheduledTime);
} }
/** /**
@ -161,7 +160,7 @@ export class InsuranceController
*/ */
protected countAllInsuranceItems(insurance: Insurance[]): number protected countAllInsuranceItems(insurance: Insurance[]): number
{ {
return this.mathUtil.arraySum(insurance.map((ins) => ins.items.length)); return this.mathUtil.arraySum(insurance.map(ins => ins.items.length));
} }
/** /**
@ -174,11 +173,11 @@ export class InsuranceController
protected removeInsurancePackageFromProfile(sessionID: string, insPackage: Insurance): void protected removeInsurancePackageFromProfile(sessionID: string, insPackage: Insurance): void
{ {
const profile = this.saveServer.getProfile(sessionID); const profile = this.saveServer.getProfile(sessionID);
profile.insurance = profile.insurance.filter((insurance) => profile.insurance = profile.insurance.filter(insurance =>
insurance.traderId !== insPackage.traderId insurance.traderId !== insPackage.traderId
|| insurance.systemData.date !== insPackage.systemData.date || insurance.systemData.date !== insPackage.systemData.date
|| insurance.systemData.time !== insPackage.systemData.time || insurance.systemData.time !== insPackage.systemData.time
|| insurance.systemData.location !== insPackage.systemData.location || insurance.systemData.location !== insPackage.systemData.location,
); );
this.logger.debug(`Removed processed insurance package. Remaining packages: ${profile.insurance.length}`); this.logger.debug(`Removed processed insurance package. Remaining packages: ${profile.insurance.length}`);
@ -201,8 +200,8 @@ export class InsuranceController
let parentAttachmentsMap = this.populateParentAttachmentsMap(rootItemParentID, insured, itemsMap); let parentAttachmentsMap = this.populateParentAttachmentsMap(rootItemParentID, insured, itemsMap);
// Check to see if any regular items are present. // Check to see if any regular items are present.
const hasRegularItems = Array.from(itemsMap.values()).some((item) => const hasRegularItems = Array.from(itemsMap.values()).some(item =>
!this.itemHelper.isAttachmentAttached(item) !this.itemHelper.isAttachmentAttached(item),
); );
// Process all items that are not attached, attachments; those are handled separately, by value. // Process all items that are not attached, attachments; those are handled separately, by value.
@ -250,7 +249,7 @@ export class InsuranceController
for (const insuredItem of insured.items) for (const insuredItem of insured.items)
{ {
// Use the parent ID from the item to get the parent item. // Use the parent ID from the item to get the parent item.
const parentItem = insured.items.find((item) => item._id === insuredItem.parentId); const parentItem = insured.items.find(item => item._id === insuredItem.parentId);
// The parent (not the hideout) could not be found. Skip and warn. // The parent (not the hideout) could not be found. Skip and warn.
if (!parentItem && insuredItem.parentId !== rootItemParentID) if (!parentItem && insuredItem.parentId !== rootItemParentID)
@ -490,7 +489,7 @@ export class InsuranceController
{ {
this.logger.debug( this.logger.debug(
`Attachment ${index} Id: ${attachmentId} Tpl: ${ `Attachment ${index} Id: ${attachmentId} Tpl: ${
attachments.find((x) => x._id === attachmentId)?._tpl attachments.find(x => x._id === attachmentId)?._tpl
} - Price: ${attachmentPrices[attachmentId]}`, } - Price: ${attachmentPrices[attachmentId]}`,
); );
index++; index++;
@ -557,7 +556,7 @@ export class InsuranceController
*/ */
protected removeItemsFromInsurance(insured: Insurance, toDelete: Set<string>): void protected removeItemsFromInsurance(insured: Insurance, toDelete: Set<string>): void
{ {
insured.items = insured.items.filter((item) => !toDelete.has(item._id)); insured.items = insured.items.filter(item => !toDelete.has(item._id));
} }
/** /**
@ -746,6 +745,6 @@ export class InsuranceController
// Represents an insurance item that has had it's common locale-name and value added to it. // Represents an insurance item that has had it's common locale-name and value added to it.
interface EnrichedItem extends Item interface EnrichedItem extends Item
{ {
name: string; name: string
dynamicPrice: number; dynamicPrice: number
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator";
import { HideoutHelper } from "@spt-aki/helpers/HideoutHelper"; import { HideoutHelper } from "@spt-aki/helpers/HideoutHelper";
import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper"; import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
@ -107,7 +106,7 @@ export class InventoryController
} }
// Check for item in inventory before allowing internal transfer // Check for item in inventory before allowing internal transfer
const originalItemLocation = ownerInventoryItems.from.find((item) => item._id === moveRequest.item); const originalItemLocation = ownerInventoryItems.from.find(item => item._id === moveRequest.item);
if (!originalItemLocation) if (!originalItemLocation)
{ {
// Internal item move but item never existed, possible dupe glitch // Internal item move but item never existed, possible dupe glitch
@ -169,7 +168,7 @@ export class InventoryController
return; return;
} }
const profileToRemoveItemFrom = (!request.fromOwner || request.fromOwner.id === pmcData._id) const profileToRemoveItemFrom = !request.fromOwner || request.fromOwner.id === pmcData._id
? pmcData ? pmcData
: this.profileHelper.getFullProfile(sessionID).characters.scav; : this.profileHelper.getFullProfile(sessionID).characters.scav;
@ -198,12 +197,12 @@ export class InventoryController
// Handle cartridge edge-case // Handle cartridge edge-case
if (!request.container.location && request.container.container === "cartridges") if (!request.container.location && request.container.container === "cartridges")
{ {
const matchingItems = inventoryItems.to.filter((x) => x.parentId === request.container.id); const matchingItems = inventoryItems.to.filter(x => x.parentId === request.container.id);
request.container.location = matchingItems.length; // Wrong location for first cartridge request.container.location = matchingItems.length; // Wrong location for first cartridge
} }
// The item being merged has three possible sources: pmc, scav or mail, getOwnerInventoryItems() handles getting correct one // The item being merged has three possible sources: pmc, scav or mail, getOwnerInventoryItems() handles getting correct one
const itemToSplit = inventoryItems.from.find((x) => x._id === request.splitItem); const itemToSplit = inventoryItems.from.find(x => x._id === request.splitItem);
if (!itemToSplit) if (!itemToSplit)
{ {
const errorMessage = `Unable to split stack as source item: ${request.splitItem} cannot be found`; const errorMessage = `Unable to split stack as source item: ${request.splitItem} cannot be found`;
@ -259,7 +258,7 @@ export class InventoryController
const inventoryItems = this.inventoryHelper.getOwnerInventoryItems(body, sessionID); const inventoryItems = this.inventoryHelper.getOwnerInventoryItems(body, sessionID);
// Get source item (can be from player or trader or mail) // Get source item (can be from player or trader or mail)
const sourceItem = inventoryItems.from.find((x) => x._id === body.item); const sourceItem = inventoryItems.from.find(x => x._id === body.item);
if (!sourceItem) if (!sourceItem)
{ {
const errorMessage = `Unable to merge stacks as source item: ${body.with} cannot be found`; const errorMessage = `Unable to merge stacks as source item: ${body.with} cannot be found`;
@ -271,7 +270,7 @@ export class InventoryController
} }
// Get item being merged into // Get item being merged into
const destinationItem = inventoryItems.to.find((x) => x._id === body.with); const destinationItem = inventoryItems.to.find(x => x._id === body.with);
if (!destinationItem) if (!destinationItem)
{ {
const errorMessage = `Unable to merge stacks as destination item: ${body.with} cannot be found`; const errorMessage = `Unable to merge stacks as destination item: ${body.with} cannot be found`;
@ -282,7 +281,7 @@ export class InventoryController
return output; return output;
} }
if (!(destinationItem.upd?.StackObjectsCount)) if (!destinationItem.upd?.StackObjectsCount)
{ {
// No stackcount on destination, add one // No stackcount on destination, add one
destinationItem.upd = { StackObjectsCount: 1 }; destinationItem.upd = { StackObjectsCount: 1 };
@ -307,7 +306,7 @@ export class InventoryController
destinationItem.upd.StackObjectsCount += sourceItem.upd.StackObjectsCount; // Add source stackcount to destination destinationItem.upd.StackObjectsCount += sourceItem.upd.StackObjectsCount; // Add source stackcount to destination
output.profileChanges[sessionID].items.del.push({ _id: sourceItem._id }); // Inform client source item being deleted output.profileChanges[sessionID].items.del.push({ _id: sourceItem._id }); // Inform client source item being deleted
const indexOfItemToRemove = inventoryItems.from.findIndex((x) => x._id === sourceItem._id); const indexOfItemToRemove = inventoryItems.from.findIndex(x => x._id === sourceItem._id);
if (indexOfItemToRemove === -1) if (indexOfItemToRemove === -1)
{ {
const errorMessage = `Unable to find item: ${sourceItem._id} to remove from sender inventory`; const errorMessage = `Unable to find item: ${sourceItem._id} to remove from sender inventory`;
@ -340,8 +339,8 @@ export class InventoryController
): IItemEventRouterResponse ): IItemEventRouterResponse
{ {
const inventoryItems = this.inventoryHelper.getOwnerInventoryItems(body, sessionID); const inventoryItems = this.inventoryHelper.getOwnerInventoryItems(body, sessionID);
const sourceItem = inventoryItems.from.find((item) => item._id === body.item); const sourceItem = inventoryItems.from.find(item => item._id === body.item);
const destinationItem = inventoryItems.to.find((item) => item._id === body.with); const destinationItem = inventoryItems.to.find(item => item._id === body.with);
if (sourceItem === null) if (sourceItem === null)
{ {
@ -397,13 +396,13 @@ export class InventoryController
*/ */
public swapItem(pmcData: IPmcData, request: IInventorySwapRequestData, sessionID: string): IItemEventRouterResponse public swapItem(pmcData: IPmcData, request: IInventorySwapRequestData, sessionID: string): IItemEventRouterResponse
{ {
const itemOne = pmcData.Inventory.items.find((x) => x._id === request.item); const itemOne = pmcData.Inventory.items.find(x => x._id === request.item);
if (!itemOne) if (!itemOne)
{ {
this.logger.error(`Unable to find item: ${request.item} to swap positions with: ${request.item2}`); this.logger.error(`Unable to find item: ${request.item} to swap positions with: ${request.item2}`);
} }
const itemTwo = pmcData.Inventory.items.find((x) => x._id === request.item2); const itemTwo = pmcData.Inventory.items.find(x => x._id === request.item2);
if (!itemTwo) if (!itemTwo)
{ {
this.logger.error(`Unable to find item: ${request.item2} to swap positions with: ${request.item}`); this.logger.error(`Unable to find item: ${request.item2} to swap positions with: ${request.item}`);
@ -454,7 +453,7 @@ export class InventoryController
playerData = this.profileHelper.getScavProfile(sessionID); playerData = this.profileHelper.getScavProfile(sessionID);
} }
const itemToFold = playerData.Inventory.items.find((item) => item?._id === request.item); const itemToFold = playerData.Inventory.items.find(item => item?._id === request.item);
if (!itemToFold) if (!itemToFold)
{ {
// Item not found // Item not found
@ -488,7 +487,7 @@ export class InventoryController
playerData = this.profileHelper.getScavProfile(sessionID); playerData = this.profileHelper.getScavProfile(sessionID);
} }
const itemToToggle = playerData.Inventory.items.find((x) => x._id === body.item); const itemToToggle = playerData.Inventory.items.find(x => x._id === body.item);
if (itemToToggle) if (itemToToggle)
{ {
this.itemHelper.addUpdObjectToItem( this.itemHelper.addUpdObjectToItem(
@ -689,15 +688,15 @@ export class InventoryController
if (request.fromOwner.id === Traders.FENCE) if (request.fromOwner.id === Traders.FENCE)
{ {
// Get tpl from fence assorts // Get tpl from fence assorts
return this.fenceService.getRawFenceAssorts().items.find((x) => x._id === request.item)._tpl; return this.fenceService.getRawFenceAssorts().items.find(x => x._id === request.item)._tpl;
} }
if (request.fromOwner.type === "Trader") if (request.fromOwner.type === "Trader")
{ {
// Not fence // Not fence
// get tpl from trader assort // get tpl from trader assort
return this.databaseServer.getTables().traders[request.fromOwner.id].assort.items.find((item) => return this.databaseServer.getTables().traders[request.fromOwner.id].assort.items.find(item =>
item._id === request.item item._id === request.item,
)._tpl; )._tpl;
} }
@ -718,7 +717,7 @@ export class InventoryController
} }
// Try find examine item inside offer items array // Try find examine item inside offer items array
const matchingItem = offer.items.find((offerItem) => offerItem._id === request.item); const matchingItem = offer.items.find(offerItem => offerItem._id === request.item);
if (matchingItem) if (matchingItem)
{ {
return matchingItem._tpl; return matchingItem._tpl;
@ -754,7 +753,7 @@ export class InventoryController
{ {
for (const change of request.changedItems) for (const change of request.changedItems)
{ {
const inventoryItem = pmcData.Inventory.items.find((x) => x._id === change._id); const inventoryItem = pmcData.Inventory.items.find(x => x._id === change._id);
if (!inventoryItem) if (!inventoryItem)
{ {
this.logger.error( this.logger.error(
@ -793,7 +792,7 @@ export class InventoryController
): void ): void
{ {
// Get map from inventory // Get map from inventory
const mapItem = pmcData.Inventory.items.find((i) => i._id === request.item); const mapItem = pmcData.Inventory.items.find(i => i._id === request.item);
// add marker // add marker
mapItem.upd.Map = mapItem.upd.Map || { Markers: [] }; mapItem.upd.Map = mapItem.upd.Map || { Markers: [] };
@ -819,7 +818,7 @@ export class InventoryController
): void ): void
{ {
// Get map from inventory // Get map from inventory
const mapItem = pmcData.Inventory.items.find((i) => i._id === request.item); const mapItem = pmcData.Inventory.items.find(i => i._id === request.item);
// remove marker // remove marker
const markers = mapItem.upd.Map.Markers.filter((marker) => const markers = mapItem.upd.Map.Markers.filter((marker) =>
@ -847,10 +846,10 @@ export class InventoryController
): void ): void
{ {
// Get map from inventory // Get map from inventory
const mapItem = pmcData.Inventory.items.find((i) => i._id === request.item); const mapItem = pmcData.Inventory.items.find(i => i._id === request.item);
// edit marker // edit marker
const indexOfExistingNote = mapItem.upd.Map.Markers.findIndex((m) => m.X === request.X && m.Y === request.Y); const indexOfExistingNote = mapItem.upd.Map.Markers.findIndex(m => m.X === request.X && m.Y === request.Y);
request.mapMarker.Note = this.sanitiseMapMarkerText(request.mapMarker.Note); request.mapMarker.Note = this.sanitiseMapMarkerText(request.mapMarker.Note);
mapItem.upd.Map.Markers[indexOfExistingNote] = request.mapMarker; mapItem.upd.Map.Markers[indexOfExistingNote] = request.mapMarker;
@ -884,7 +883,7 @@ export class InventoryController
): void ): void
{ {
/** Container player opened in their inventory */ /** Container player opened in their inventory */
const openedItem = pmcData.Inventory.items.find((item) => item._id === body.item); const openedItem = pmcData.Inventory.items.find(item => item._id === body.item);
const containerDetailsDb = this.itemHelper.getItem(openedItem._tpl); const containerDetailsDb = this.itemHelper.getItem(openedItem._tpl);
const isSealedWeaponBox = containerDetailsDb[1]._name.includes("event_container_airdrop"); const isSealedWeaponBox = containerDetailsDb[1]._name.includes("event_container_airdrop");
@ -935,8 +934,8 @@ export class InventoryController
// Hard coded to `SYSTEM` for now // Hard coded to `SYSTEM` for now
// TODO: make this dynamic // TODO: make this dynamic
const dialog = fullProfile.dialogues["59e7125688a45068a6249071"]; const dialog = fullProfile.dialogues["59e7125688a45068a6249071"];
const mail = dialog.messages.find((x) => x._id === event.MessageId); const mail = dialog.messages.find(x => x._id === event.MessageId);
const mailEvent = mail.profileChangeEvents.find((x) => x._id === event.EventId); const mailEvent = mail.profileChangeEvents.find(x => x._id === event.EventId);
switch (mailEvent.Type) switch (mailEvent.Type)
{ {
@ -955,15 +954,15 @@ export class InventoryController
break; break;
case "SkillPoints": case "SkillPoints":
{ {
const profileSkill = pmcData.Skills.Common.find((x) => x.Id === mailEvent.entity); const profileSkill = pmcData.Skills.Common.find(x => x.Id === mailEvent.entity);
profileSkill.Progress = mailEvent.value; profileSkill.Progress = mailEvent.value;
this.logger.success(`Set profile skill: ${mailEvent.entity} to: ${mailEvent.value}`); this.logger.success(`Set profile skill: ${mailEvent.entity} to: ${mailEvent.value}`);
break; break;
} }
case "ExamineAllItems": case "ExamineAllItems":
{ {
const itemsToInspect = this.itemHelper.getItems().filter((x) => x._type !== "Node"); const itemsToInspect = this.itemHelper.getItems().filter(x => x._type !== "Node");
this.flagItemsAsInspectedAndRewardXp(itemsToInspect.map((x) => x._id), fullProfile); this.flagItemsAsInspectedAndRewardXp(itemsToInspect.map(x => x._id), fullProfile);
this.logger.success(`Flagged ${itemsToInspect.length} items as examined`); this.logger.success(`Flagged ${itemsToInspect.length} items as examined`);
break; break;
} }
@ -988,7 +987,7 @@ export class InventoryController
for (const itemId of request.items) for (const itemId of request.items)
{ {
// If id already exists in array, we're removing it // If id already exists in array, we're removing it
const indexOfItemAlreadyFavorited = pmcData.Inventory.favoriteItems.findIndex((x) => x === itemId); const indexOfItemAlreadyFavorited = pmcData.Inventory.favoriteItems.findIndex(x => x === itemId);
if (indexOfItemAlreadyFavorited > -1) if (indexOfItemAlreadyFavorited > -1)
{ {
pmcData.Inventory.favoriteItems.splice(indexOfItemAlreadyFavorited, 1); pmcData.Inventory.favoriteItems.splice(indexOfItemAlreadyFavorited, 1);

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper"; import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader"; import { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
import { ContextVariableType } from "@spt-aki/context/ContextVariableType"; import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
import { ContextVariableType } from "@spt-aki/context/ContextVariableType"; import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator";
@ -191,7 +190,7 @@ export class MatchController
return false; return false;
} }
return (this.inRaidConfig.coopExtracts.includes(extractName.trim())); return this.inRaidConfig.coopExtracts.includes(extractName.trim());
} }
protected sendCoopTakenFenceMessage(sessionId: string): void protected sendCoopTakenFenceMessage(sessionId: string): void

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { Note } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Note } from "@spt-aki/models/eft/common/tables/IBotBase";
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper"; import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
import { NotifierHelper } from "@spt-aki/helpers/NotifierHelper"; import { NotifierHelper } from "@spt-aki/helpers/NotifierHelper";
import { INotifierChannel } from "@spt-aki/models/eft/notifier/INotifier"; import { INotifierChannel } from "@spt-aki/models/eft/notifier/INotifier";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper"; import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { IPreset } from "@spt-aki/models/eft/common/IGlobals"; import { IPreset } from "@spt-aki/models/eft/common/IGlobals";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger"; import { ILogger } from "@spt-aki/models/spt/utils/ILogger";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { PlayerScavGenerator } from "@spt-aki/generators/PlayerScavGenerator"; import { PlayerScavGenerator } from "@spt-aki/generators/PlayerScavGenerator";
import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper"; import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
@ -81,7 +80,7 @@ export class ProfileController
const pmc = profile.characters.pmc; const pmc = profile.characters.pmc;
// make sure character completed creation // make sure character completed creation
if (!(pmc?.Info?.Level)) if (!pmc?.Info?.Level)
{ {
return { return {
username: profile.info.username, username: profile.info.username,
@ -104,7 +103,7 @@ export class ProfileController
side: pmc.Info.Side, side: pmc.Info.Side,
currlvl: pmc.Info.Level, currlvl: pmc.Info.Level,
currexp: pmc.Info.Experience ?? 0, currexp: pmc.Info.Experience ?? 0,
prevexp: (currlvl === 0) ? 0 : this.profileHelper.getExperience(currlvl), prevexp: currlvl === 0 ? 0 : this.profileHelper.getExperience(currlvl),
nextlvl: nextlvl, nextlvl: nextlvl,
maxlvl: maxlvl, maxlvl: maxlvl,
akiData: profile.aki, akiData: profile.aki,
@ -130,8 +129,10 @@ export class ProfileController
public createProfile(info: IProfileCreateRequestData, sessionID: string): string public createProfile(info: IProfileCreateRequestData, sessionID: string): string
{ {
const account = this.saveServer.getProfile(sessionID).info; const account = this.saveServer.getProfile(sessionID).info;
const profile: ITemplateSide = const profile: ITemplateSide = this.databaseServer
this.databaseServer.getTables().templates.profiles[account.edition][info.side.toLowerCase()]; .getTables()
.templates
.profiles[account.edition][info.side.toLowerCase()];
const pmcData = profile.character; const pmcData = profile.character;
// Delete existing profile // Delete existing profile
@ -151,7 +152,7 @@ export class ProfileController
pmcData.Customization.Head = info.headId; pmcData.Customization.Head = info.headId;
pmcData.Health.UpdateTime = this.timeUtil.getTimestamp(); pmcData.Health.UpdateTime = this.timeUtil.getTimestamp();
pmcData.Quests = []; pmcData.Quests = [];
pmcData.Hideout.Seed = this.timeUtil.getTimestamp() + (8 * 60 * 60 * 24 * 365); // 8 years in future why? who knows, we saw it in live pmcData.Hideout.Seed = this.timeUtil.getTimestamp() + 8 * 60 * 60 * 24 * 365; // 8 years in future why? who knows, we saw it in live
pmcData.RepeatableQuests = []; pmcData.RepeatableQuests = [];
pmcData.CarExtractCounts = {}; pmcData.CarExtractCounts = {};
pmcData.CoopExtractCounts = {}; pmcData.CoopExtractCounts = {};
@ -458,7 +459,7 @@ export class ProfileController
skills: playerPmc.Skills, skills: playerPmc.Skills,
equipment: { equipment: {
// Default inventory tpl // Default inventory tpl
Id: playerPmc.Inventory.items.find((x) => x._tpl === "55d7217a4bdc2d86028b456d")._id, Id: playerPmc.Inventory.items.find(x => x._tpl === "55d7217a4bdc2d86028b456d")._id,
Items: playerPmc.Inventory.items, Items: playerPmc.Inventory.items,
}, },
achievements: playerPmc.Achievements, achievements: playerPmc.Achievements,

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper"; import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
@ -79,7 +78,7 @@ export class QuestController
for (const quest of allQuests) for (const quest of allQuests)
{ {
// Player already accepted the quest, show it regardless of status // Player already accepted the quest, show it regardless of status
const questInProfile = profile.Quests.find((x) => x.qid === quest._id); const questInProfile = profile.Quests.find(x => x.qid === quest._id);
if (questInProfile) if (questInProfile)
{ {
quest.sptStatus = questInProfile.status; quest.sptStatus = questInProfile.status;
@ -137,8 +136,8 @@ export class QuestController
for (const conditionToFulfil of questRequirements) for (const conditionToFulfil of questRequirements)
{ {
// If the previous quest isn't in the user profile, it hasn't been completed or started // If the previous quest isn't in the user profile, it hasn't been completed or started
const prerequisiteQuest = profile.Quests.find((profileQuest) => const prerequisiteQuest = profile.Quests.find(profileQuest =>
conditionToFulfil.target.includes(profileQuest.qid) conditionToFulfil.target.includes(profileQuest.qid),
); );
if (!prerequisiteQuest) if (!prerequisiteQuest)
{ {
@ -148,7 +147,7 @@ export class QuestController
// Prereq does not have its status requirement fulfilled // Prereq does not have its status requirement fulfilled
// Some bsg status ids are strings, MUST convert to number before doing includes check // Some bsg status ids are strings, MUST convert to number before doing includes check
if (!conditionToFulfil.status.map((status) => Number(status)).includes(prerequisiteQuest.status)) if (!conditionToFulfil.status.map(status => Number(status)).includes(prerequisiteQuest.status))
{ {
haveCompletedPreviousQuest = false; haveCompletedPreviousQuest = false;
break; break;
@ -292,7 +291,7 @@ export class QuestController
// Does quest exist in profile // Does quest exist in profile
// Restarting a failed quest can mean quest exists in profile // Restarting a failed quest can mean quest exists in profile
const existingQuestStatus = pmcData.Quests.find((x) => x.qid === acceptedQuest.qid); const existingQuestStatus = pmcData.Quests.find(x => x.qid === acceptedQuest.qid);
if (existingQuestStatus) if (existingQuestStatus)
{ {
// Update existing // Update existing
@ -399,15 +398,15 @@ export class QuestController
fullProfile.characters.scav.Quests.push(newRepeatableQuest); fullProfile.characters.scav.Quests.push(newRepeatableQuest);
} }
const repeatableSettings = pmcData.RepeatableQuests.find((x) => const repeatableSettings = pmcData.RepeatableQuests.find(x =>
x.name === repeatableQuestProfile.sptRepatableGroupName x.name === repeatableQuestProfile.sptRepatableGroupName,
); );
const change = {}; const change = {};
change[repeatableQuestProfile._id] = repeatableSettings.changeRequirement[repeatableQuestProfile._id]; change[repeatableQuestProfile._id] = repeatableSettings.changeRequirement[repeatableQuestProfile._id];
const responseData: IPmcDataRepeatableQuest = { const responseData: IPmcDataRepeatableQuest = {
id: repeatableSettings.id ?? this.questConfig.repeatableQuests.find((x) => id: repeatableSettings.id ?? this.questConfig.repeatableQuests.find(x =>
x.name === repeatableQuestProfile.sptRepatableGroupName x.name === repeatableQuestProfile.sptRepatableGroupName,
).id, ).id,
name: repeatableSettings.name, name: repeatableSettings.name,
endTime: repeatableSettings.endTime, endTime: repeatableSettings.endTime,
@ -435,7 +434,7 @@ export class QuestController
{ {
for (const repeatableQuest of pmcData.RepeatableQuests) for (const repeatableQuest of pmcData.RepeatableQuests)
{ {
const matchingQuest = repeatableQuest.activeQuests.find((x) => x._id === acceptedQuest.qid); const matchingQuest = repeatableQuest.activeQuests.find(x => x._id === acceptedQuest.qid);
if (matchingQuest) if (matchingQuest)
{ {
this.logger.debug(`Accepted repeatable quest ${acceptedQuest.qid} from ${repeatableQuest.name}`); this.logger.debug(`Accepted repeatable quest ${acceptedQuest.qid} from ${repeatableQuest.name}`);
@ -504,8 +503,8 @@ export class QuestController
// Check if it's a repeatable quest. If so, remove from Quests // Check if it's a repeatable quest. If so, remove from Quests
for (const currentRepeatable of pmcData.RepeatableQuests) for (const currentRepeatable of pmcData.RepeatableQuests)
{ {
const repeatableQuest = currentRepeatable.activeQuests.find((activeRepeatable) => const repeatableQuest = currentRepeatable.activeQuests.find(activeRepeatable =>
activeRepeatable._id === completedQuestId activeRepeatable._id === completedQuestId,
); );
if (repeatableQuest) if (repeatableQuest)
{ {
@ -548,15 +547,15 @@ export class QuestController
// Quest already failed in profile, skip // Quest already failed in profile, skip
if ( if (
pmcProfile.Quests.some((profileQuest) => pmcProfile.Quests.some(profileQuest =>
profileQuest.qid === quest._id && profileQuest.status === QuestStatus.Fail profileQuest.qid === quest._id && profileQuest.status === QuestStatus.Fail,
) )
) )
{ {
return false; return false;
} }
return quest.conditions.Fail.some((condition) => condition.target?.includes(completedQuestId)); return quest.conditions.Fail.some(condition => condition.target?.includes(completedQuestId));
}); });
} }
@ -568,7 +567,7 @@ export class QuestController
protected removeQuestFromScavProfile(sessionId: string, questIdToRemove: string): void protected removeQuestFromScavProfile(sessionId: string, questIdToRemove: string): void
{ {
const fullProfile = this.profileHelper.getFullProfile(sessionId); const fullProfile = this.profileHelper.getFullProfile(sessionId);
const repeatableInScavProfile = fullProfile.characters.scav.Quests?.find((x) => x.qid === questIdToRemove); const repeatableInScavProfile = fullProfile.characters.scav.Quests?.find(x => x.qid === questIdToRemove);
if (!repeatableInScavProfile) if (!repeatableInScavProfile)
{ {
this.logger.warning( this.logger.warning(
@ -600,7 +599,7 @@ export class QuestController
for (const quest of postQuestStatuses) for (const quest of postQuestStatuses)
{ {
// Add quest if status differs or quest not found // Add quest if status differs or quest not found
const preQuest = preQuestStatusus.find((x) => x.qid === quest.qid); const preQuest = preQuestStatusus.find(x => x.qid === quest.qid);
if (!preQuest || preQuest.status !== quest.status) if (!preQuest || preQuest.status !== quest.status)
{ {
result.push(quest); result.push(quest);
@ -653,8 +652,8 @@ export class QuestController
for (const quest of quests) for (const quest of quests)
{ {
// If quest has prereq of completed quest + availableAfter value > 0 (quest has wait time) // If quest has prereq of completed quest + availableAfter value > 0 (quest has wait time)
const nextQuestWaitCondition = quest.conditions.AvailableForStart.find((x) => const nextQuestWaitCondition = quest.conditions.AvailableForStart.find(x =>
x.target?.includes(completedQuestId) && x.availableAfter > 0 x.target?.includes(completedQuestId) && x.availableAfter > 0,
); );
if (nextQuestWaitCondition) if (nextQuestWaitCondition)
{ {
@ -662,7 +661,7 @@ export class QuestController
const availableAfterTimestamp = this.timeUtil.getTimestamp() + nextQuestWaitCondition.availableAfter; const availableAfterTimestamp = this.timeUtil.getTimestamp() + nextQuestWaitCondition.availableAfter;
// Update quest in profile with status of AvailableAfter // Update quest in profile with status of AvailableAfter
const existingQuestInProfile = pmcData.Quests.find((x) => x.qid === quest._id); const existingQuestInProfile = pmcData.Quests.find(x => x.qid === quest._id);
if (existingQuestInProfile) if (existingQuestInProfile)
{ {
existingQuestInProfile.availableAfter = availableAfterTimestamp; existingQuestInProfile.availableAfter = availableAfterTimestamp;
@ -679,7 +678,7 @@ export class QuestController
status: QuestStatus.AvailableAfter, status: QuestStatus.AvailableAfter,
statusTimers: { statusTimers: {
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
"9": this.timeUtil.getTimestamp(), 9: this.timeUtil.getTimestamp(),
}, },
availableAfter: availableAfterTimestamp, availableAfter: availableAfterTimestamp,
}); });
@ -705,12 +704,12 @@ export class QuestController
for (const questToFail of questsToFail) for (const questToFail of questsToFail)
{ {
// Skip failing a quest that has a fail status of something other than success // Skip failing a quest that has a fail status of something other than success
if (questToFail.conditions.Fail?.some((x) => x.status?.some((status) => status !== QuestStatus.Success))) if (questToFail.conditions.Fail?.some(x => x.status?.some(status => status !== QuestStatus.Success)))
{ {
continue; continue;
} }
const isActiveQuestInPlayerProfile = pmcData.Quests.find((quest) => quest.qid === questToFail._id); const isActiveQuestInPlayerProfile = pmcData.Quests.find(quest => quest.qid === questToFail._id);
if (isActiveQuestInPlayerProfile) if (isActiveQuestInPlayerProfile)
{ {
if (isActiveQuestInPlayerProfile.status !== QuestStatus.Fail) if (isActiveQuestInPlayerProfile.status !== QuestStatus.Fail)
@ -772,7 +771,7 @@ export class QuestController
isItemHandoverQuest = condition.conditionType === handoverQuestTypes[0]; isItemHandoverQuest = condition.conditionType === handoverQuestTypes[0];
handoverRequirements = condition; handoverRequirements = condition;
const profileCounter = (handoverQuestRequest.conditionId in pmcData.TaskConditionCounters) const profileCounter = handoverQuestRequest.conditionId in pmcData.TaskConditionCounters
? pmcData.TaskConditionCounters[handoverQuestRequest.conditionId].value ? pmcData.TaskConditionCounters[handoverQuestRequest.conditionId].value
: 0; : 0;
handedInCount -= profileCounter; handedInCount -= profileCounter;
@ -806,7 +805,7 @@ export class QuestController
let totalItemCountToRemove = 0; let totalItemCountToRemove = 0;
for (const itemHandover of handoverQuestRequest.items) for (const itemHandover of handoverQuestRequest.items)
{ {
const matchingItemInProfile = pmcData.Inventory.items.find((item) => item._id === itemHandover.id); const matchingItemInProfile = pmcData.Inventory.items.find(item => item._id === itemHandover.id);
if (!(matchingItemInProfile && handoverRequirements.target.includes(matchingItemInProfile._tpl))) if (!(matchingItemInProfile && handoverRequirements.target.includes(matchingItemInProfile._tpl)))
{ {
// Item handed in by player doesnt match what was requested // Item handed in by player doesnt match what was requested

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { RagfairOfferGenerator } from "@spt-aki/generators/RagfairOfferGenerator"; import { RagfairOfferGenerator } from "@spt-aki/generators/RagfairOfferGenerator";
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper"; import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper"; import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
@ -160,7 +159,7 @@ export class RagfairController
public getOfferById(sessionId: string, request: IGetRagfairOfferByIdRequest): IRagfairOffer public getOfferById(sessionId: string, request: IGetRagfairOfferByIdRequest): IRagfairOffer
{ {
const offers = this.ragfairOfferService.getOffers(); const offers = this.ragfairOfferService.getOffers();
const offerToReturn = offers.find((x) => x.intId === request.id); const offerToReturn = offers.find(x => x.intId === request.id);
return offerToReturn; return offerToReturn;
} }
@ -208,14 +207,18 @@ export class RagfairController
): Record<string, number> ): Record<string, number>
{ {
// Linked/required search categories // Linked/required search categories
const playerHasFleaUnlocked = const playerHasFleaUnlocked = pmcProfile.Info.Level >= this.databaseServer
pmcProfile.Info.Level >= this.databaseServer.getTables().globals.config.RagFair.minUserLevel; .getTables()
.globals
.config
.RagFair
.minUserLevel;
let offerPool = []; let offerPool = [];
if (this.isLinkedSearch(searchRequest) || this.isRequiredSearch(searchRequest)) if (this.isLinkedSearch(searchRequest) || this.isRequiredSearch(searchRequest))
{ {
offerPool = offers; offerPool = offers;
} }
else if ((!(this.isLinkedSearch(searchRequest) || this.isRequiredSearch(searchRequest)))) else if (!(this.isLinkedSearch(searchRequest) || this.isRequiredSearch(searchRequest)))
{ {
// Get all categories // Get all categories
offerPool = this.ragfairOfferService.getOffers(); offerPool = this.ragfairOfferService.getOffers();
@ -260,7 +263,7 @@ export class RagfairController
const traderAssorts = this.traderHelper.getTraderAssortsByTraderId(offer.user.id).items; const traderAssorts = this.traderHelper.getTraderAssortsByTraderId(offer.user.id).items;
const assortId = offer.items[0]._id; const assortId = offer.items[0]._id;
const assortData = traderAssorts.find((x) => x._id === assortId); const assortData = traderAssorts.find(x => x._id === assortId);
// Use value stored in profile, otherwise use value directly from in-memory trader assort data // Use value stored in profile, otherwise use value directly from in-memory trader assort data
offer.buyRestrictionCurrent = fullProfile.traderPurchases[offer.user.id][assortId] offer.buyRestrictionCurrent = fullProfile.traderPurchases[offer.user.id][assortId]
@ -279,7 +282,7 @@ export class RagfairController
const firstItem = offer.items[0]; const firstItem = offer.items[0];
const traderAssorts = this.traderHelper.getTraderAssortsByTraderId(offer.user.id).items; const traderAssorts = this.traderHelper.getTraderAssortsByTraderId(offer.user.id).items;
const assortPurchased = traderAssorts.find((x) => x._id === offer.items[0]._id); const assortPurchased = traderAssorts.find(x => x._id === offer.items[0]._id);
if (!assortPurchased) if (!assortPurchased)
{ {
this.logger.warning( this.logger.warning(
@ -357,7 +360,7 @@ export class RagfairController
const avg = offers.reduce((sum, offer) => const avg = offers.reduce((sum, offer) =>
{ {
// Exclude barter items, they tend to have outrageous equivalent prices // Exclude barter items, they tend to have outrageous equivalent prices
if (offer.requirements.some((req) => !this.paymentHelper.isMoneyTpl(req._tpl))) if (offer.requirements.some(req => !this.paymentHelper.isMoneyTpl(req._tpl)))
{ {
return sum; return sum;
} }
@ -456,15 +459,15 @@ export class RagfairController
// Multiply single item price by stack count and quality // Multiply single item price by stack count and quality
averageOfferPrice *= rootItem.upd.StackObjectsCount * qualityMultiplier; averageOfferPrice *= rootItem.upd.StackObjectsCount * qualityMultiplier;
const itemStackCount = (offerRequest.sellInOnePiece) ? 1 : rootItem.upd.StackObjectsCount; const itemStackCount = offerRequest.sellInOnePiece ? 1 : rootItem.upd.StackObjectsCount;
// Get averaged price of a single item being listed // Get averaged price of a single item being listed
const averageSingleItemPrice = (offerRequest.sellInOnePiece) const averageSingleItemPrice = offerRequest.sellInOnePiece
? averageOfferPrice / rootItem.upd.StackObjectsCount // Packs are a single offer made of many items ? averageOfferPrice / rootItem.upd.StackObjectsCount // Packs are a single offer made of many items
: averageOfferPrice / itemStackCount; : averageOfferPrice / itemStackCount;
// Get averaged price of listing // Get averaged price of listing
const averagePlayerListedPriceInRub = (offerRequest.sellInOnePiece) const averagePlayerListedPriceInRub = offerRequest.sellInOnePiece
? playerListedPriceInRub / rootItem.upd.StackObjectsCount ? playerListedPriceInRub / rootItem.upd.StackObjectsCount
: playerListedPriceInRub; : playerListedPriceInRub;
@ -540,7 +543,7 @@ export class RagfairController
offerRequest.sellInOnePiece, offerRequest.sellInOnePiece,
); );
this.logger.debug(`Offer tax to charge: ${tax}, pulled from client: ${(!!storedClientTaxValue)}`); this.logger.debug(`Offer tax to charge: ${tax}, pulled from client: ${!!storedClientTaxValue}`);
// cleanup of cache now we've used the tax value from it // cleanup of cache now we've used the tax value from it
this.ragfairTaxService.clearStoredOfferTaxById(offerRequest.items[0]); this.ragfairTaxService.clearStoredOfferTaxById(offerRequest.items[0]);
@ -602,8 +605,8 @@ export class RagfairController
} }
else else
{ {
requirementsPriceInRub += this.ragfairPriceService.getDynamicPriceForItem(requestedItemTpl) requirementsPriceInRub += this.ragfairPriceService
* item.count; .getDynamicPriceForItem(requestedItemTpl) * item.count;
} }
} }
@ -619,7 +622,7 @@ export class RagfairController
protected getItemsToListOnFleaFromInventory( protected getItemsToListOnFleaFromInventory(
pmcData: IPmcData, pmcData: IPmcData,
itemIdsFromFleaOfferRequest: string[], itemIdsFromFleaOfferRequest: string[],
): { items: Item[] | null; errorMessage: string | null; } ): { items: Item[] | null, errorMessage: string | null }
{ {
const itemsToReturn = []; const itemsToReturn = [];
let errorMessage: string | null = null; let errorMessage: string | null = null;
@ -627,7 +630,7 @@ export class RagfairController
// Count how many items are being sold and multiply the requested amount accordingly // Count how many items are being sold and multiply the requested amount accordingly
for (const itemId of itemIdsFromFleaOfferRequest) for (const itemId of itemIdsFromFleaOfferRequest)
{ {
let item = pmcData.Inventory.items.find((i) => i._id === itemId); let item = pmcData.Inventory.items.find(i => i._id === itemId);
if (!item) if (!item)
{ {
errorMessage = this.localisationService.getText("ragfair-unable_to_find_item_in_inventory", { errorMessage = this.localisationService.getText("ragfair-unable_to_find_item_in_inventory", {
@ -663,7 +666,7 @@ export class RagfairController
const loyalLevel = 1; const loyalLevel = 1;
const formattedItems: Item[] = items.map((item) => const formattedItems: Item[] = items.map((item) =>
{ {
const isChild = items.find((it) => it._id === item.parentId); const isChild = items.find(it => it._id === item.parentId);
return { return {
_id: item._id, _id: item._id,
@ -724,7 +727,7 @@ export class RagfairController
pmcData.RagfairInfo.offers = []; pmcData.RagfairInfo.offers = [];
} }
const playerOfferIndex = playerProfileOffers.findIndex((offer) => offer._id === removeRequest.offerId); const playerOfferIndex = playerProfileOffers.findIndex(offer => offer._id === removeRequest.offerId);
if (playerOfferIndex === -1) if (playerOfferIndex === -1)
{ {
this.logger.error( this.logger.error(
@ -761,7 +764,7 @@ export class RagfairController
const pmcData = this.saveServer.getProfile(sessionId).characters.pmc; const pmcData = this.saveServer.getProfile(sessionId).characters.pmc;
const playerOffers = pmcData.RagfairInfo.offers; const playerOffers = pmcData.RagfairInfo.offers;
const playerOfferIndex = playerOffers.findIndex((offer) => offer._id === extendRequest.offerId); const playerOfferIndex = playerOffers.findIndex(offer => offer._id === extendRequest.offerId);
const secondsToAdd = extendRequest.renewalTime * TimeUtil.ONE_HOUR_AS_SECONDS; const secondsToAdd = extendRequest.renewalTime * TimeUtil.ONE_HOUR_AS_SECONDS;
if (playerOfferIndex === -1) if (playerOfferIndex === -1)

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { QuestHelper } from "@spt-aki/helpers/QuestHelper"; import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
import { RepairHelper } from "@spt-aki/helpers/RepairHelper"; import { RepairHelper } from "@spt-aki/helpers/RepairHelper";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { RepeatableQuestGenerator } from "@spt-aki/generators/RepeatableQuestGenerator"; import { RepeatableQuestGenerator } from "@spt-aki/generators/RepeatableQuestGenerator";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { QuestHelper } from "@spt-aki/helpers/QuestHelper"; import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
@ -83,15 +82,15 @@ export class RepeatableQuestController
* @param {string} _info Request from client * @param {string} _info Request from client
* @param {string} sessionID Player's session id * @param {string} sessionID Player's session id
* *
* @returns {array} Array of "repeatableQuestObjects" as descibed above * @returns {array} Array of "repeatableQuestObjects" as described above
*/ */
public getClientRepeatableQuests(_info: IEmptyRequestData, sessionID: string): IPmcDataRepeatableQuest[] public getClientRepeatableQuests(_info: IEmptyRequestData, sessionID: string): IPmcDataRepeatableQuest[]
{ {
const returnData: Array<IPmcDataRepeatableQuest> = []; const returnData: Array<IPmcDataRepeatableQuest> = [];
const pmcData = this.profileHelper.getPmcProfile(sessionID); const pmcData = this.profileHelper.getPmcProfile(sessionID);
const time = this.timeUtil.getTimestamp(); const time = this.timeUtil.getTimestamp();
const scavQuestUnlocked = const scavQuestUnlocked
pmcData?.Hideout?.Areas?.find((hideoutArea) => hideoutArea.type === HideoutAreas.INTEL_CENTER)?.level >= 1; = pmcData?.Hideout?.Areas?.find(hideoutArea => hideoutArea.type === HideoutAreas.INTEL_CENTER)?.level >= 1;
// Daily / weekly / Daily_Savage // Daily / weekly / Daily_Savage
for (const repeatableConfig of this.questConfig.repeatableQuests) for (const repeatableConfig of this.questConfig.repeatableQuests)
@ -119,7 +118,7 @@ export class RepeatableQuestController
for (const activeQuest of currentRepeatableQuestType.activeQuests) for (const activeQuest of currentRepeatableQuestType.activeQuests)
{ {
// Keep finished quests in list so player can hand in // Keep finished quests in list so player can hand in
const quest = pmcData.Quests.find((quest) => quest.qid === activeQuest._id); const quest = pmcData.Quests.find(quest => quest.qid === activeQuest._id);
if (quest) if (quest)
{ {
if (quest.status === QuestStatus.AvailableForFinish) if (quest.status === QuestStatus.AvailableForFinish)
@ -135,7 +134,7 @@ export class RepeatableQuestController
this.profileFixerService.removeDanglingConditionCounters(pmcData); this.profileFixerService.removeDanglingConditionCounters(pmcData);
// Remove expired quest from pmc.quest array // Remove expired quest from pmc.quest array
pmcData.Quests = pmcData.Quests.filter((quest) => quest.qid !== activeQuest._id); pmcData.Quests = pmcData.Quests.filter(quest => quest.qid !== activeQuest._id);
currentRepeatableQuestType.inactiveQuests.push(activeQuest); currentRepeatableQuestType.inactiveQuests.push(activeQuest);
} }
currentRepeatableQuestType.activeQuests = questsToKeep; currentRepeatableQuestType.activeQuests = questsToKeep;
@ -217,9 +216,14 @@ export class RepeatableQuestController
) )
{ {
// Elite charisma skill gives extra daily quest(s) // Elite charisma skill gives extra daily quest(s)
return repeatableConfig.numQuests return repeatableConfig.numQuests + this.databaseServer.getTables()
+ this.databaseServer.getTables().globals.config.SkillsSettings.Charisma.BonusSettings .globals
.EliteBonusSettings.RepeatableQuestExtraCount; .config
.SkillsSettings
.Charisma
.BonusSettings
.EliteBonusSettings
.RepeatableQuestExtraCount;
} }
return repeatableConfig.numQuests; return repeatableConfig.numQuests;
@ -237,7 +241,7 @@ export class RepeatableQuestController
): IPmcDataRepeatableQuest ): IPmcDataRepeatableQuest
{ {
// Get from profile, add if missing // Get from profile, add if missing
let repeatableQuestDetails = pmcData.RepeatableQuests.find((x) => x.name === repeatableConfig.name); let repeatableQuestDetails = pmcData.RepeatableQuests.find(x => x.name === repeatableConfig.name);
if (!repeatableQuestDetails) if (!repeatableQuestDetails)
{ {
repeatableQuestDetails = { repeatableQuestDetails = {
@ -327,8 +331,8 @@ export class RepeatableQuestController
const possibleLocations = Object.keys(locations); const possibleLocations = Object.keys(locations);
// Set possible locations for elimination task, if target is savage, exclude labs from locations // Set possible locations for elimination task, if target is savage, exclude labs from locations
questPool.pool.Elimination.targets[probabilityObject.key] = (probabilityObject.key === "Savage") questPool.pool.Elimination.targets[probabilityObject.key] = probabilityObject.key === "Savage"
? { locations: possibleLocations.filter((x) => x !== "laboratory") } ? { locations: possibleLocations.filter(x => x !== "laboratory") }
: { locations: possibleLocations }; : { locations: possibleLocations };
} }
} }
@ -396,7 +400,7 @@ export class RepeatableQuestController
return true; return true;
} }
return (pmcLevel <= locationBase.RequiredPlayerLevelMax && pmcLevel >= locationBase.RequiredPlayerLevelMin); return pmcLevel <= locationBase.RequiredPlayerLevelMax && pmcLevel >= locationBase.RequiredPlayerLevelMin;
} }
public debugLogRepeatableQuestIds(pmcData: IPmcData): void public debugLogRepeatableQuestIds(pmcData: IPmcData): void
@ -439,7 +443,7 @@ export class RepeatableQuestController
for (const currentRepeatablePool of pmcData.RepeatableQuests) for (const currentRepeatablePool of pmcData.RepeatableQuests)
{ {
// Check for existing quest in (daily/weekly/scav arrays) // Check for existing quest in (daily/weekly/scav arrays)
const questToReplace = currentRepeatablePool.activeQuests.find((x) => x._id === changeRequest.qid); const questToReplace = currentRepeatablePool.activeQuests.find(x => x._id === changeRequest.qid);
if (!questToReplace) if (!questToReplace)
{ {
continue; continue;
@ -449,8 +453,8 @@ export class RepeatableQuestController
replacedQuestTraderId = questToReplace.traderId; replacedQuestTraderId = questToReplace.traderId;
// Update active quests to exclude the quest we're replacing // Update active quests to exclude the quest we're replacing
currentRepeatablePool.activeQuests = currentRepeatablePool.activeQuests.filter((x) => currentRepeatablePool.activeQuests = currentRepeatablePool.activeQuests.filter(x =>
x._id !== changeRequest.qid x._id !== changeRequest.qid,
); );
// Get cost to replace existing quest // Get cost to replace existing quest
@ -458,8 +462,8 @@ export class RepeatableQuestController
delete currentRepeatablePool.changeRequirement[changeRequest.qid]; delete currentRepeatablePool.changeRequirement[changeRequest.qid];
// TODO: somehow we need to reduce the questPool by the currently active quests (for all repeatables) // TODO: somehow we need to reduce the questPool by the currently active quests (for all repeatables)
const repeatableConfig = this.questConfig.repeatableQuests.find((x) => const repeatableConfig = this.questConfig.repeatableQuests.find(x =>
x.name === currentRepeatablePool.name x.name === currentRepeatablePool.name,
); );
const questTypePool = this.generateQuestPool(repeatableConfig, pmcData.Info.Level); const questTypePool = this.generateQuestPool(repeatableConfig, pmcData.Info.Level);
const newRepeatableQuest = this.attemptToGenerateRepeatableQuest(pmcData, questTypePool, repeatableConfig); const newRepeatableQuest = this.attemptToGenerateRepeatableQuest(pmcData, questTypePool, repeatableConfig);

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { TradeHelper } from "@spt-aki/helpers/TradeHelper"; import { TradeHelper } from "@spt-aki/helpers/TradeHelper";
@ -294,7 +293,7 @@ export class TradeController
this.traderHelper.getTraderById(trader), this.traderHelper.getTraderById(trader),
MessageType.MESSAGE_WITH_ITEMS, MessageType.MESSAGE_WITH_ITEMS,
this.randomUtil.getArrayValue(this.databaseServer.getTables().traders[trader].dialogue.soldItems), this.randomUtil.getArrayValue(this.databaseServer.getTables().traders[trader].dialogue.soldItems),
curencyReward.flatMap((x) => x), curencyReward.flatMap(x => x),
this.timeUtil.getHoursAsSeconds(72), this.timeUtil.getHoursAsSeconds(72),
); );
} }
@ -320,12 +319,12 @@ export class TradeController
for (const itemToSell of itemWithChildren) for (const itemToSell of itemWithChildren)
{ {
const itemDetails = this.itemHelper.getItem(itemToSell._tpl); const itemDetails = this.itemHelper.getItem(itemToSell._tpl);
if ( if (!(itemDetails[0] && this.itemHelper.isOfBaseclasses(
!(itemDetails[0] itemDetails[1]._id,
&& this.itemHelper.isOfBaseclasses(itemDetails[1]._id, traderDetails.items_buy.category)) traderDetails.items_buy.category,
) )))
{ {
// Skip if tpl isnt item OR item doesn't fulfill match traders buy categories // Skip if tpl isn't item OR item doesn't fulfil match traders buy categories
continue; continue;
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { FenceBaseAssortGenerator } from "@spt-aki/generators/FenceBaseAssortGenerator"; import { FenceBaseAssortGenerator } from "@spt-aki/generators/FenceBaseAssortGenerator";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper"; import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import { TraderAssortHelper } from "@spt-aki/helpers/TraderAssortHelper"; import { TraderAssortHelper } from "@spt-aki/helpers/TraderAssortHelper";
@ -30,8 +29,7 @@ export class TraderController
@inject("ProfileHelper") protected profileHelper: ProfileHelper, @inject("ProfileHelper") protected profileHelper: ProfileHelper,
@inject("TraderHelper") protected traderHelper: TraderHelper, @inject("TraderHelper") protected traderHelper: TraderHelper,
@inject("TraderAssortService") protected traderAssortService: TraderAssortService, @inject("TraderAssortService") protected traderAssortService: TraderAssortService,
@inject("TraderPurchasePersisterService") protected traderPurchasePersisterService: @inject("TraderPurchasePersisterService") protected traderPurchasePersisterService: TraderPurchasePersisterService,
TraderPurchasePersisterService,
@inject("FenceService") protected fenceService: FenceService, @inject("FenceService") protected fenceService: FenceService,
@inject("FenceBaseAssortGenerator") protected fenceBaseAssortGenerator: FenceBaseAssortGenerator, @inject("FenceBaseAssortGenerator") protected fenceBaseAssortGenerator: FenceBaseAssortGenerator,
@inject("JsonUtil") protected jsonUtil: JsonUtil, @inject("JsonUtil") protected jsonUtil: JsonUtil,

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { WeatherGenerator } from "@spt-aki/generators/WeatherGenerator"; import { WeatherGenerator } from "@spt-aki/generators/WeatherGenerator";
import { IWeatherData } from "@spt-aki/models/eft/weather/IWeatherData"; import { IWeatherData } from "@spt-aki/models/eft/weather/IWeatherData";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes"; import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
import { IWishlistActionData } from "@spt-aki/models/eft/wishlist/IWishlistActionData"; import { IWishlistActionData } from "@spt-aki/models/eft/wishlist/IWishlistActionData";

View File

@ -1,5 +1,4 @@
import { DependencyContainer, Lifecycle } from "tsyringe"; import { DependencyContainer, Lifecycle } from "tsyringe";
import { AchievementCallbacks } from "@spt-aki/callbacks/AchievementCallbacks"; import { AchievementCallbacks } from "@spt-aki/callbacks/AchievementCallbacks";
import { BotCallbacks } from "@spt-aki/callbacks/BotCallbacks"; import { BotCallbacks } from "@spt-aki/callbacks/BotCallbacks";
import { BuildsCallbacks } from "@spt-aki/callbacks/BuildsCallbacks"; import { BuildsCallbacks } from "@spt-aki/callbacks/BuildsCallbacks";
@ -71,18 +70,18 @@ import { BotWeaponGenerator } from "@spt-aki/generators/BotWeaponGenerator";
import { FenceBaseAssortGenerator } from "@spt-aki/generators/FenceBaseAssortGenerator"; import { FenceBaseAssortGenerator } from "@spt-aki/generators/FenceBaseAssortGenerator";
import { LocationGenerator } from "@spt-aki/generators/LocationGenerator"; import { LocationGenerator } from "@spt-aki/generators/LocationGenerator";
import { LootGenerator } from "@spt-aki/generators/LootGenerator"; import { LootGenerator } from "@spt-aki/generators/LootGenerator";
import { PMCLootGenerator } from "@spt-aki/generators/PMCLootGenerator";
import { PlayerScavGenerator } from "@spt-aki/generators/PlayerScavGenerator"; import { PlayerScavGenerator } from "@spt-aki/generators/PlayerScavGenerator";
import { PMCLootGenerator } from "@spt-aki/generators/PMCLootGenerator";
import { RagfairAssortGenerator } from "@spt-aki/generators/RagfairAssortGenerator"; import { RagfairAssortGenerator } from "@spt-aki/generators/RagfairAssortGenerator";
import { RagfairOfferGenerator } from "@spt-aki/generators/RagfairOfferGenerator"; import { RagfairOfferGenerator } from "@spt-aki/generators/RagfairOfferGenerator";
import { RepeatableQuestGenerator } from "@spt-aki/generators/RepeatableQuestGenerator"; import { RepeatableQuestGenerator } from "@spt-aki/generators/RepeatableQuestGenerator";
import { RepeatableQuestRewardGenerator } from "@spt-aki/generators/RepeatableQuestRewardGenerator"; import { RepeatableQuestRewardGenerator } from "@spt-aki/generators/RepeatableQuestRewardGenerator";
import { ScavCaseRewardGenerator } from "@spt-aki/generators/ScavCaseRewardGenerator"; import { ScavCaseRewardGenerator } from "@spt-aki/generators/ScavCaseRewardGenerator";
import { WeatherGenerator } from "@spt-aki/generators/WeatherGenerator";
import { BarrelInventoryMagGen } from "@spt-aki/generators/weapongen/implementations/BarrelInventoryMagGen"; import { BarrelInventoryMagGen } from "@spt-aki/generators/weapongen/implementations/BarrelInventoryMagGen";
import { ExternalInventoryMagGen } from "@spt-aki/generators/weapongen/implementations/ExternalInventoryMagGen"; import { ExternalInventoryMagGen } from "@spt-aki/generators/weapongen/implementations/ExternalInventoryMagGen";
import { InternalMagazineInventoryMagGen } from "@spt-aki/generators/weapongen/implementations/InternalMagazineInventoryMagGen"; import { InternalMagazineInventoryMagGen } from "@spt-aki/generators/weapongen/implementations/InternalMagazineInventoryMagGen";
import { UbglExternalMagGen } from "@spt-aki/generators/weapongen/implementations/UbglExternalMagGen"; import { UbglExternalMagGen } from "@spt-aki/generators/weapongen/implementations/UbglExternalMagGen";
import { WeatherGenerator } from "@spt-aki/generators/WeatherGenerator";
import { AssortHelper } from "@spt-aki/helpers/AssortHelper"; import { AssortHelper } from "@spt-aki/helpers/AssortHelper";
import { BotDifficultyHelper } from "@spt-aki/helpers/BotDifficultyHelper"; import { BotDifficultyHelper } from "@spt-aki/helpers/BotDifficultyHelper";
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper"; import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
@ -133,10 +132,6 @@ import { PostAkiModLoader } from "@spt-aki/loaders/PostAkiModLoader";
import { PostDBModLoader } from "@spt-aki/loaders/PostDBModLoader"; import { PostDBModLoader } from "@spt-aki/loaders/PostDBModLoader";
import { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader"; import { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";
import { IAsyncQueue } from "@spt-aki/models/spt/utils/IAsyncQueue"; import { IAsyncQueue } from "@spt-aki/models/spt/utils/IAsyncQueue";
import { EventOutputHolder } from "@spt-aki/routers/EventOutputHolder";
import { HttpRouter } from "@spt-aki/routers/HttpRouter";
import { ImageRouter } from "@spt-aki/routers/ImageRouter";
import { ItemEventRouter } from "@spt-aki/routers/ItemEventRouter";
import { BotDynamicRouter } from "@spt-aki/routers/dynamic/BotDynamicRouter"; import { BotDynamicRouter } from "@spt-aki/routers/dynamic/BotDynamicRouter";
import { BundleDynamicRouter } from "@spt-aki/routers/dynamic/BundleDynamicRouter"; import { BundleDynamicRouter } from "@spt-aki/routers/dynamic/BundleDynamicRouter";
import { CustomizationDynamicRouter } from "@spt-aki/routers/dynamic/CustomizationDynamicRouter"; import { CustomizationDynamicRouter } from "@spt-aki/routers/dynamic/CustomizationDynamicRouter";
@ -146,6 +141,9 @@ import { InraidDynamicRouter } from "@spt-aki/routers/dynamic/InraidDynamicRoute
import { LocationDynamicRouter } from "@spt-aki/routers/dynamic/LocationDynamicRouter"; import { LocationDynamicRouter } from "@spt-aki/routers/dynamic/LocationDynamicRouter";
import { NotifierDynamicRouter } from "@spt-aki/routers/dynamic/NotifierDynamicRouter"; import { NotifierDynamicRouter } from "@spt-aki/routers/dynamic/NotifierDynamicRouter";
import { TraderDynamicRouter } from "@spt-aki/routers/dynamic/TraderDynamicRouter"; import { TraderDynamicRouter } from "@spt-aki/routers/dynamic/TraderDynamicRouter";
import { EventOutputHolder } from "@spt-aki/routers/EventOutputHolder";
import { HttpRouter } from "@spt-aki/routers/HttpRouter";
import { ImageRouter } from "@spt-aki/routers/ImageRouter";
import { CustomizationItemEventRouter } from "@spt-aki/routers/item_events/CustomizationItemEventRouter"; import { CustomizationItemEventRouter } from "@spt-aki/routers/item_events/CustomizationItemEventRouter";
import { HealthItemEventRouter } from "@spt-aki/routers/item_events/HealthItemEventRouter"; import { HealthItemEventRouter } from "@spt-aki/routers/item_events/HealthItemEventRouter";
import { HideoutItemEventRouter } from "@spt-aki/routers/item_events/HideoutItemEventRouter"; import { HideoutItemEventRouter } from "@spt-aki/routers/item_events/HideoutItemEventRouter";
@ -157,6 +155,7 @@ import { RagfairItemEventRouter } from "@spt-aki/routers/item_events/RagfairItem
import { RepairItemEventRouter } from "@spt-aki/routers/item_events/RepairItemEventRouter"; import { RepairItemEventRouter } from "@spt-aki/routers/item_events/RepairItemEventRouter";
import { TradeItemEventRouter } from "@spt-aki/routers/item_events/TradeItemEventRouter"; import { TradeItemEventRouter } from "@spt-aki/routers/item_events/TradeItemEventRouter";
import { WishlistItemEventRouter } from "@spt-aki/routers/item_events/WishlistItemEventRouter"; import { WishlistItemEventRouter } from "@spt-aki/routers/item_events/WishlistItemEventRouter";
import { ItemEventRouter } from "@spt-aki/routers/ItemEventRouter";
import { HealthSaveLoadRouter } from "@spt-aki/routers/save_load/HealthSaveLoadRouter"; import { HealthSaveLoadRouter } from "@spt-aki/routers/save_load/HealthSaveLoadRouter";
import { InraidSaveLoadRouter } from "@spt-aki/routers/save_load/InraidSaveLoadRouter"; import { InraidSaveLoadRouter } from "@spt-aki/routers/save_load/InraidSaveLoadRouter";
import { InsuranceSaveLoadRouter } from "@spt-aki/routers/save_load/InsuranceSaveLoadRouter"; import { InsuranceSaveLoadRouter } from "@spt-aki/routers/save_load/InsuranceSaveLoadRouter";
@ -188,16 +187,18 @@ import { TraderStaticRouter } from "@spt-aki/routers/static/TraderStaticRouter";
import { WeatherStaticRouter } from "@spt-aki/routers/static/WeatherStaticRouter"; import { WeatherStaticRouter } from "@spt-aki/routers/static/WeatherStaticRouter";
import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer"; import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { AkiHttpListener } from "@spt-aki/servers/http/AkiHttpListener";
import { HttpServer } from "@spt-aki/servers/HttpServer"; import { HttpServer } from "@spt-aki/servers/HttpServer";
import { RagfairServer } from "@spt-aki/servers/RagfairServer"; import { RagfairServer } from "@spt-aki/servers/RagfairServer";
import { SaveServer } from "@spt-aki/servers/SaveServer"; import { SaveServer } from "@spt-aki/servers/SaveServer";
import { WebSocketServer } from "@spt-aki/servers/WebSocketServer"; import { WebSocketServer } from "@spt-aki/servers/WebSocketServer";
import { AkiHttpListener } from "@spt-aki/servers/http/AkiHttpListener";
import { BotEquipmentFilterService } from "@spt-aki/services/BotEquipmentFilterService"; import { BotEquipmentFilterService } from "@spt-aki/services/BotEquipmentFilterService";
import { BotEquipmentModPoolService } from "@spt-aki/services/BotEquipmentModPoolService"; import { BotEquipmentModPoolService } from "@spt-aki/services/BotEquipmentModPoolService";
import { BotGenerationCacheService } from "@spt-aki/services/BotGenerationCacheService"; import { BotGenerationCacheService } from "@spt-aki/services/BotGenerationCacheService";
import { BotLootCacheService } from "@spt-aki/services/BotLootCacheService"; import { BotLootCacheService } from "@spt-aki/services/BotLootCacheService";
import { BotWeaponModLimitService } from "@spt-aki/services/BotWeaponModLimitService"; import { BotWeaponModLimitService } from "@spt-aki/services/BotWeaponModLimitService";
import { BundleHashCacheService } from "@spt-aki/services/cache/BundleHashCacheService";
import { ModHashCacheService } from "@spt-aki/services/cache/ModHashCacheService";
import { CustomLocationWaveService } from "@spt-aki/services/CustomLocationWaveService"; import { CustomLocationWaveService } from "@spt-aki/services/CustomLocationWaveService";
import { FenceService } from "@spt-aki/services/FenceService"; import { FenceService } from "@spt-aki/services/FenceService";
import { GiftService } from "@spt-aki/services/GiftService"; import { GiftService } from "@spt-aki/services/GiftService";
@ -209,6 +210,13 @@ import { LocalisationService } from "@spt-aki/services/LocalisationService";
import { MailSendService } from "@spt-aki/services/MailSendService"; import { MailSendService } from "@spt-aki/services/MailSendService";
import { MatchBotDetailsCacheService } from "@spt-aki/services/MatchBotDetailsCacheService"; import { MatchBotDetailsCacheService } from "@spt-aki/services/MatchBotDetailsCacheService";
import { MatchLocationService } from "@spt-aki/services/MatchLocationService"; import { MatchLocationService } from "@spt-aki/services/MatchLocationService";
import { CustomItemService } from "@spt-aki/services/mod/CustomItemService";
import { DynamicRouterModService } from "@spt-aki/services/mod/dynamicRouter/DynamicRouterModService";
import { HttpListenerModService } from "@spt-aki/services/mod/httpListener/HttpListenerModService";
import { ImageRouteService } from "@spt-aki/services/mod/image/ImageRouteService";
import { OnLoadModService } from "@spt-aki/services/mod/onLoad/OnLoadModService";
import { OnUpdateModService } from "@spt-aki/services/mod/onUpdate/OnUpdateModService";
import { StaticRouterModService } from "@spt-aki/services/mod/staticRouter/StaticRouterModService";
import { ModCompilerService } from "@spt-aki/services/ModCompilerService"; import { ModCompilerService } from "@spt-aki/services/ModCompilerService";
import { NotificationService } from "@spt-aki/services/NotificationService"; import { NotificationService } from "@spt-aki/services/NotificationService";
import { OpenZoneService } from "@spt-aki/services/OpenZoneService"; import { OpenZoneService } from "@spt-aki/services/OpenZoneService";
@ -230,15 +238,6 @@ import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService";
import { TraderAssortService } from "@spt-aki/services/TraderAssortService"; import { TraderAssortService } from "@spt-aki/services/TraderAssortService";
import { TraderPurchasePersisterService } from "@spt-aki/services/TraderPurchasePersisterService"; import { TraderPurchasePersisterService } from "@spt-aki/services/TraderPurchasePersisterService";
import { TraderServicesService } from "@spt-aki/services/TraderServicesService"; import { TraderServicesService } from "@spt-aki/services/TraderServicesService";
import { BundleHashCacheService } from "@spt-aki/services/cache/BundleHashCacheService";
import { ModHashCacheService } from "@spt-aki/services/cache/ModHashCacheService";
import { CustomItemService } from "@spt-aki/services/mod/CustomItemService";
import { DynamicRouterModService } from "@spt-aki/services/mod/dynamicRouter/DynamicRouterModService";
import { HttpListenerModService } from "@spt-aki/services/mod/httpListener/HttpListenerModService";
import { ImageRouteService } from "@spt-aki/services/mod/image/ImageRouteService";
import { OnLoadModService } from "@spt-aki/services/mod/onLoad/OnLoadModService";
import { OnUpdateModService } from "@spt-aki/services/mod/onUpdate/OnUpdateModService";
import { StaticRouterModService } from "@spt-aki/services/mod/staticRouter/StaticRouterModService";
import { App } from "@spt-aki/utils/App"; import { App } from "@spt-aki/utils/App";
import { AsyncQueue } from "@spt-aki/utils/AsyncQueue"; import { AsyncQueue } from "@spt-aki/utils/AsyncQueue";
import { CompareUtil } from "@spt-aki/utils/CompareUtil"; import { CompareUtil } from "@spt-aki/utils/CompareUtil";
@ -249,14 +248,14 @@ import { HttpFileUtil } from "@spt-aki/utils/HttpFileUtil";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil"; import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { ImporterUtil } from "@spt-aki/utils/ImporterUtil"; import { ImporterUtil } from "@spt-aki/utils/ImporterUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { WinstonMainLogger } from "@spt-aki/utils/logging/WinstonMainLogger";
import { WinstonRequestLogger } from "@spt-aki/utils/logging/WinstonRequestLogger";
import { MathUtil } from "@spt-aki/utils/MathUtil"; import { MathUtil } from "@spt-aki/utils/MathUtil";
import { ObjectId } from "@spt-aki/utils/ObjectId"; import { ObjectId } from "@spt-aki/utils/ObjectId";
import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil";
import { TimeUtil } from "@spt-aki/utils/TimeUtil"; import { TimeUtil } from "@spt-aki/utils/TimeUtil";
import { VFS } from "@spt-aki/utils/VFS"; import { VFS } from "@spt-aki/utils/VFS";
import { Watermark, WatermarkLocale } from "@spt-aki/utils/Watermark"; import { Watermark, WatermarkLocale } from "@spt-aki/utils/Watermark";
import { WinstonMainLogger } from "@spt-aki/utils/logging/WinstonMainLogger";
import { WinstonRequestLogger } from "@spt-aki/utils/logging/WinstonRequestLogger";
/** /**
* Handle the registration of classes to be used by the Dependency Injection code * Handle the registration of classes to be used by the Dependency Injection code

View File

@ -1,5 +1,5 @@
export interface OnLoad export interface OnLoad
{ {
onLoad(): Promise<void>; onLoad(): Promise<void>
getRoute(): string; getRoute(): string
} }

View File

@ -1,5 +1,5 @@
export interface OnUpdate export interface OnUpdate
{ {
onUpdate(timeSinceLastRun: number): Promise<boolean>; onUpdate(timeSinceLastRun: number): Promise<boolean>
getRoute(): string; getRoute(): string
} }

View File

@ -29,9 +29,9 @@ export class Router
{ {
if (partialMatch) if (partialMatch)
{ {
return this.getInternalHandledRoutes().filter((r) => r.dynamic).some((r) => url.includes(r.route)); return this.getInternalHandledRoutes().filter(r => r.dynamic).some(r => url.includes(r.route));
} }
return this.getInternalHandledRoutes().filter((r) => !r.dynamic).some((r) => r.route === url); return this.getInternalHandledRoutes().filter(r => !r.dynamic).some(r => r.route === url);
} }
} }
@ -44,12 +44,12 @@ export class StaticRouter extends Router
public handleStatic(url: string, info: any, sessionID: string, output: string): any public handleStatic(url: string, info: any, sessionID: string, output: string): any
{ {
return this.routes.find((route) => route.url === url).action(url, info, sessionID, output); return this.routes.find(route => route.url === url).action(url, info, sessionID, output);
} }
public override getHandledRoutes(): HandledRoute[] public override getHandledRoutes(): HandledRoute[]
{ {
return this.routes.map((route) => new HandledRoute(route.url, false)); return this.routes.map(route => new HandledRoute(route.url, false));
} }
} }
@ -62,12 +62,12 @@ export class DynamicRouter extends Router
public handleDynamic(url: string, info: any, sessionID: string, output: string): any public handleDynamic(url: string, info: any, sessionID: string, output: string): any
{ {
return this.routes.find((r) => url.includes(r.url)).action(url, info, sessionID, output); return this.routes.find(r => url.includes(r.url)).action(url, info, sessionID, output);
} }
public override getHandledRoutes(): HandledRoute[] public override getHandledRoutes(): HandledRoute[]
{ {
return this.routes.map((route) => new HandledRoute(route.url, true)); return this.routes.map(route => new HandledRoute(route.url, true));
} }
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper"; import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
import { BotHelper } from "@spt-aki/helpers/BotHelper"; import { BotHelper } from "@spt-aki/helpers/BotHelper";
import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper";
@ -234,8 +233,8 @@ export class BotEquipmentModGenerator
} }
// Get the front/back/side weights based on bots level // Get the front/back/side weights based on bots level
const plateSlotWeights = settings.botEquipmentConfig?.armorPlateWeighting?.find((armorWeight) => const plateSlotWeights = settings.botEquipmentConfig?.armorPlateWeighting?.find(armorWeight =>
settings.botLevel >= armorWeight.levelRange.min && settings.botLevel <= armorWeight.levelRange.max settings.botLevel >= armorWeight.levelRange.min && settings.botLevel <= armorWeight.levelRange.max,
); );
if (!plateSlotWeights) if (!plateSlotWeights)
{ {
@ -261,17 +260,17 @@ export class BotEquipmentModGenerator
const chosenArmorPlateLevel = this.weightedRandomHelper.getWeightedValue<string>(plateWeights); const chosenArmorPlateLevel = this.weightedRandomHelper.getWeightedValue<string>(plateWeights);
// Convert the array of ids into database items // Convert the array of ids into database items
const platesFromDb = existingPlateTplPool.map((plateTpl) => this.itemHelper.getItem(plateTpl)[1]); const platesFromDb = existingPlateTplPool.map(plateTpl => this.itemHelper.getItem(plateTpl)[1]);
// Filter plates to the chosen level based on its armorClass property // Filter plates to the chosen level based on its armorClass property
const filteredPlates = platesFromDb.filter((item) => item._props.armorClass === chosenArmorPlateLevel); const filteredPlates = platesFromDb.filter(item => item._props.armorClass === chosenArmorPlateLevel);
if (filteredPlates.length === 0) if (filteredPlates.length === 0)
{ {
this.logger.debug( this.logger.debug(
`Plate filter was too restrictive for armor: ${armorItem._id}, unable to find plates of level: ${chosenArmorPlateLevel}. Using mod items default plate`, `Plate filter was too restrictive for armor: ${armorItem._id}, unable to find plates of level: ${chosenArmorPlateLevel}. Using mod items default plate`,
); );
const relatedItemDbModSlot = armorItem._props.Slots.find((slot) => slot._name.toLowerCase() === modSlot); const relatedItemDbModSlot = armorItem._props.Slots.find(slot => slot._name.toLowerCase() === modSlot);
const defaultPlate = relatedItemDbModSlot._props.filters[0].Plate; const defaultPlate = relatedItemDbModSlot._props.filters[0].Plate;
if (!defaultPlate) if (!defaultPlate)
{ {
@ -281,8 +280,8 @@ export class BotEquipmentModGenerator
const defaultPreset = this.presetHelper.getDefaultPreset(armorItem._id); const defaultPreset = this.presetHelper.getDefaultPreset(armorItem._id);
if (defaultPreset) if (defaultPreset)
{ {
const relatedPresetSlot = defaultPreset._items.find((item) => const relatedPresetSlot = defaultPreset._items.find(item =>
item.slotId?.toLowerCase() === modSlot item.slotId?.toLowerCase() === modSlot,
); );
if (relatedPresetSlot) if (relatedPresetSlot)
{ {
@ -306,7 +305,7 @@ export class BotEquipmentModGenerator
// Only return the items ids // Only return the items ids
result.result = Result.SUCCESS; result.result = Result.SUCCESS;
result.plateModTpls = filteredPlates.map((item) => item._id); result.plateModTpls = filteredPlates.map(item => item._id);
return result; return result;
} }
@ -346,8 +345,8 @@ export class BotEquipmentModGenerator
const compatibleModsPool = modPool[parentTemplate._id]; const compatibleModsPool = modPool[parentTemplate._id];
if ( if (
!((parentTemplate._props.Slots.length || parentTemplate._props.Cartridges?.length) !(parentTemplate._props.Slots.length || parentTemplate._props.Cartridges?.length
|| parentTemplate._props.Chambers?.length) || parentTemplate._props.Chambers?.length)
) )
{ {
this.logger.error( this.logger.error(
@ -468,10 +467,10 @@ export class BotEquipmentModGenerator
// Handguard mod can take a sub handguard mod + weapon has no UBGL (takes same slot) // Handguard mod can take a sub handguard mod + weapon has no UBGL (takes same slot)
// Force spawn chance to be 100% to ensure it gets added // Force spawn chance to be 100% to ensure it gets added
if ( if (
modSlot === "mod_handguard" && modToAddTemplate._props.Slots.find((slot) => modSlot === "mod_handguard" && modToAddTemplate._props.Slots.find(slot =>
slot._name === "mod_handguard" slot._name === "mod_handguard",
) )
&& !weapon.find((item) => item.slotId === "mod_launcher") && !weapon.find(item => item.slotId === "mod_launcher")
) )
{ {
// Needed for handguards with lower // Needed for handguards with lower
@ -481,9 +480,9 @@ export class BotEquipmentModGenerator
// If stock mod can take a sub stock mod, force spawn chance to be 100% to ensure sub-stock gets added // If stock mod can take a sub stock mod, force spawn chance to be 100% to ensure sub-stock gets added
// Or if mod_stock is configured to be forced on // Or if mod_stock is configured to be forced on
if ( if (
modSlot === "mod_stock" && (modToAddTemplate._props.Slots.find((slot) => modSlot === "mod_stock" && modToAddTemplate._props.Slots.find(slot =>
slot._name.includes("mod_stock") || botEquipConfig.forceStock slot._name.includes("mod_stock") || botEquipConfig.forceStock,
)) )
) )
{ {
// Stock mod can take additional stocks, could be a locking device, force 100% chance // Stock mod can take additional stocks, could be a locking device, force 100% chance
@ -700,11 +699,11 @@ export class BotEquipmentModGenerator
case "patron_in_weapon": case "patron_in_weapon":
case "patron_in_weapon_000": case "patron_in_weapon_000":
case "patron_in_weapon_001": case "patron_in_weapon_001":
return parentTemplate._props.Chambers.find((chamber) => chamber._name.includes(modSlotLower)); return parentTemplate._props.Chambers.find(chamber => chamber._name.includes(modSlotLower));
case "cartridges": case "cartridges":
return parentTemplate._props.Cartridges.find((c) => c._name.toLowerCase() === modSlotLower); return parentTemplate._props.Cartridges.find(c => c._name.toLowerCase() === modSlotLower);
default: default:
return parentTemplate._props.Slots.find((s) => s._name.toLowerCase() === modSlotLower); return parentTemplate._props.Slots.find(s => s._name.toLowerCase() === modSlotLower);
} }
} }
@ -762,7 +761,7 @@ export class BotEquipmentModGenerator
): [boolean, ITemplateItem] ): [boolean, ITemplateItem]
{ {
/** Slot mod will fill */ /** Slot mod will fill */
const parentSlot = parentTemplate._props.Slots.find((i) => i._name === modSlot); const parentSlot = parentTemplate._props.Slots.find(i => i._name === modSlot);
const weaponTemplate = this.itemHelper.getItem(weapon[0]._tpl)[1]; const weaponTemplate = this.itemHelper.getItem(weapon[0]._tpl)[1];
// It's ammo, use predefined ammo parameter // It's ammo, use predefined ammo parameter
@ -950,8 +949,8 @@ export class BotEquipmentModGenerator
if (modSpawnResult === ModSpawn.DEFAULT_MOD) if (modSpawnResult === ModSpawn.DEFAULT_MOD)
{ {
const matchingPreset = this.getMatchingPreset(weaponTemplate, parentTemplate._id); const matchingPreset = this.getMatchingPreset(weaponTemplate, parentTemplate._id);
const matchingMod = matchingPreset._items.find((item) => const matchingMod = matchingPreset._items.find(item =>
item?.slotId?.toLowerCase() === modSlot.toLowerCase() item?.slotId?.toLowerCase() === modSlot.toLowerCase(),
); );
// Only filter mods down to single default item if it already exists in existing itemModPool, OR the default item has no children // Only filter mods down to single default item if it already exists in existing itemModPool, OR the default item has no children
@ -967,8 +966,8 @@ export class BotEquipmentModGenerator
} }
// Check the filter of the slot to ensure a chosen mod fits // Check the filter of the slot to ensure a chosen mod fits
const parentSlotCompatibleItems = parentTemplate._props.Slots?.find((slot) => const parentSlotCompatibleItems = parentTemplate._props.Slots?.find(slot =>
slot._name.toLowerCase() === modSlot.toLowerCase() slot._name.toLowerCase() === modSlot.toLowerCase(),
)._props.filters[0].Filter; )._props.filters[0].Filter;
// Mod isnt in existing pool, only add if it has no children and matches parent filter // Mod isnt in existing pool, only add if it has no children and matches parent filter
@ -1176,7 +1175,7 @@ export class BotEquipmentModGenerator
botEquipBlacklist: EquipmentFilterDetails, botEquipBlacklist: EquipmentFilterDetails,
): void ): void
{ {
const desiredSlotObject = modTemplate._props.Slots.find((slot) => slot._name.includes(desiredSlotName)); const desiredSlotObject = modTemplate._props.Slots.find(slot => slot._name.includes(desiredSlotName));
if (desiredSlotObject) if (desiredSlotObject)
{ {
const supportedSubMods = desiredSlotObject._props.filters[0].Filter; const supportedSubMods = desiredSlotObject._props.filters[0].Filter;
@ -1262,7 +1261,7 @@ export class BotEquipmentModGenerator
const blacklist = this.itemFilterService.getBlacklistedItems().concat( const blacklist = this.itemFilterService.getBlacklistedItems().concat(
botEquipBlacklist.equipment[modSlot] || [], botEquipBlacklist.equipment[modSlot] || [],
); );
result = allowedMods.filter((tpl) => !blacklist.includes(tpl)); result = allowedMods.filter(tpl => !blacklist.includes(tpl));
return result; return result;
} }
@ -1288,7 +1287,7 @@ export class BotEquipmentModGenerator
weaponName: parentTemplate._name, weaponName: parentTemplate._name,
}), }),
); );
const camoraSlots = parentTemplate._props.Slots.filter((slot) => slot._name.startsWith("camora")); const camoraSlots = parentTemplate._props.Slots.filter(slot => slot._name.startsWith("camora"));
// Attempt to generate camora slots for item // Attempt to generate camora slots for item
modPool[parentTemplate._id] = {}; modPool[parentTemplate._id] = {};
@ -1422,17 +1421,17 @@ export class BotEquipmentModGenerator
{ {
// Check to see if mount has a scope slot (only include primary slot, ignore the rest like the backup sight slots) // Check to see if mount has a scope slot (only include primary slot, ignore the rest like the backup sight slots)
// Should only find 1 as there's currently no items with a mod_scope AND a mod_scope_000 // Should only find 1 as there's currently no items with a mod_scope AND a mod_scope_000
const scopeSlot = itemDetails._props.Slots.filter((slot) => const scopeSlot = itemDetails._props.Slots.filter(slot =>
["mod_scope", "mod_scope_000"].includes(slot._name) ["mod_scope", "mod_scope_000"].includes(slot._name),
); );
// Mods scope slot found must allow ALL whitelisted scope types OR be a mount // Mods scope slot found must allow ALL whitelisted scope types OR be a mount
if ( if (
scopeSlot?.every((slot) => scopeSlot?.every(slot =>
slot._props.filters[0].Filter.every((tpl) => slot._props.filters[0].Filter.every(tpl =>
this.itemHelper.isOfBaseclasses(tpl, whitelistedSightTypes) this.itemHelper.isOfBaseclasses(tpl, whitelistedSightTypes)
|| this.itemHelper.isOfBaseclass(tpl, BaseClasses.MOUNT) || this.itemHelper.isOfBaseclass(tpl, BaseClasses.MOUNT),
) ),
) )
) )
{ {

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { BotInventoryGenerator } from "@spt-aki/generators/BotInventoryGenerator"; import { BotInventoryGenerator } from "@spt-aki/generators/BotInventoryGenerator";
import { BotLevelGenerator } from "@spt-aki/generators/BotLevelGenerator"; import { BotLevelGenerator } from "@spt-aki/generators/BotLevelGenerator";
import { BotDifficultyHelper } from "@spt-aki/helpers/BotDifficultyHelper"; import { BotDifficultyHelper } from "@spt-aki/helpers/BotDifficultyHelper";
@ -111,7 +110,7 @@ export class BotGenerator
// Get raw json data for bot (Cloned) // Get raw json data for bot (Cloned)
const botJsonTemplateClone = this.jsonUtil.clone( const botJsonTemplateClone = this.jsonUtil.clone(
this.botHelper.getBotTemplate((botGenerationDetails.isPmc) ? bot.Info.Side : botGenerationDetails.role), this.botHelper.getBotTemplate(botGenerationDetails.isPmc ? bot.Info.Side : botGenerationDetails.role),
); );
bot = this.generateBot(sessionId, bot, botJsonTemplateClone, botGenerationDetails); bot = this.generateBot(sessionId, bot, botJsonTemplateClone, botGenerationDetails);
@ -446,7 +445,7 @@ export class BotGenerator
} }
return skillToAdd; return skillToAdd;
}).filter((x) => x !== null); }).filter(x => x !== null);
} }
/** /**
@ -546,7 +545,7 @@ export class BotGenerator
Nickname: bot.Info.Nickname, Nickname: bot.Info.Nickname,
Side: bot.Info.Side, Side: bot.Info.Side,
Level: bot.Info.Level, Level: bot.Info.Level,
Time: (new Date().toISOString()), Time: new Date().toISOString(),
Status: "Killed by ", Status: "Killed by ",
KillerAccountId: "Unknown", KillerAccountId: "Unknown",
KillerProfileId: "Unknown", KillerProfileId: "Unknown",
@ -557,7 +556,7 @@ export class BotGenerator
const inventoryItem: Item = { const inventoryItem: Item = {
_id: this.hashUtil.generate(), _id: this.hashUtil.generate(),
_tpl: ((bot.Info.Side === "Usec") ? BaseClasses.DOG_TAG_USEC : BaseClasses.DOG_TAG_BEAR), _tpl: bot.Info.Side === "Usec" ? BaseClasses.DOG_TAG_USEC : BaseClasses.DOG_TAG_BEAR,
parentId: bot.Inventory.equipment, parentId: bot.Inventory.equipment,
slotId: "Dogtag", slotId: "Dogtag",
location: undefined, location: undefined,

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { BotEquipmentModGenerator } from "@spt-aki/generators/BotEquipmentModGenerator"; import { BotEquipmentModGenerator } from "@spt-aki/generators/BotEquipmentModGenerator";
import { BotLootGenerator } from "@spt-aki/generators/BotLootGenerator"; import { BotLootGenerator } from "@spt-aki/generators/BotLootGenerator";
import { BotWeaponGenerator } from "@spt-aki/generators/BotWeaponGenerator"; import { BotWeaponGenerator } from "@spt-aki/generators/BotWeaponGenerator";
@ -308,12 +307,11 @@ export class BotInventoryGenerator
*/ */
protected generateEquipment(settings: IGenerateEquipmentProperties): boolean protected generateEquipment(settings: IGenerateEquipmentProperties): boolean
{ {
const spawnChance = const spawnChance = ([EquipmentSlots.POCKETS, EquipmentSlots.SECURED_CONTAINER] as string[])
([EquipmentSlots.POCKETS, EquipmentSlots.SECURED_CONTAINER] as string[]).includes( .includes(settings.rootEquipmentSlot)
settings.rootEquipmentSlot, ? 100
) : settings.spawnChances.equipment[settings.rootEquipmentSlot];
? 100
: settings.spawnChances.equipment[settings.rootEquipmentSlot];
if (typeof spawnChance === "undefined") if (typeof spawnChance === "undefined")
{ {
this.logger.warning( this.logger.warning(
@ -444,7 +442,7 @@ export class BotInventoryGenerator
for (const modSlot of Object.keys(modPool ?? [])) for (const modSlot of Object.keys(modPool ?? []))
{ {
const blacklistedMods = equipmentBlacklist[0]?.equipment[modSlot] || []; const blacklistedMods = equipmentBlacklist[0]?.equipment[modSlot] || [];
const filteredMods = modPool[modSlot].filter((x) => !blacklistedMods.includes(x)); const filteredMods = modPool[modSlot].filter(x => !blacklistedMods.includes(x));
if (filteredMods.length > 0) if (filteredMods.length > 0)
{ {
@ -503,7 +501,7 @@ export class BotInventoryGenerator
* @param equipmentChances Chances bot has certain equipment * @param equipmentChances Chances bot has certain equipment
* @returns What slots bot should have weapons generated for * @returns What slots bot should have weapons generated for
*/ */
protected getDesiredWeaponsForBot(equipmentChances: Chances): { slot: EquipmentSlots; shouldSpawn: boolean; }[] protected getDesiredWeaponsForBot(equipmentChances: Chances): { slot: EquipmentSlots, shouldSpawn: boolean }[]
{ {
const shouldSpawnPrimary = this.randomUtil.getChance100(equipmentChances.equipment.FirstPrimaryWeapon); const shouldSpawnPrimary = this.randomUtil.getChance100(equipmentChances.equipment.FirstPrimaryWeapon);
return [{ slot: EquipmentSlots.FIRST_PRIMARY_WEAPON, shouldSpawn: shouldSpawnPrimary }, { return [{ slot: EquipmentSlots.FIRST_PRIMARY_WEAPON, shouldSpawn: shouldSpawnPrimary }, {
@ -532,7 +530,7 @@ export class BotInventoryGenerator
*/ */
protected addWeaponAndMagazinesToInventory( protected addWeaponAndMagazinesToInventory(
sessionId: string, sessionId: string,
weaponSlot: { slot: EquipmentSlots; shouldSpawn: boolean; }, weaponSlot: { slot: EquipmentSlots, shouldSpawn: boolean },
templateInventory: Inventory, templateInventory: Inventory,
botInventory: PmcInventory, botInventory: PmcInventory,
equipmentChances: Chances, equipmentChances: Chances,
@ -567,18 +565,18 @@ export class BotInventoryGenerator
export interface IGenerateEquipmentProperties export interface IGenerateEquipmentProperties
{ {
/** Root Slot being generated */ /** Root Slot being generated */
rootEquipmentSlot: string; rootEquipmentSlot: string
/** Equipment pool for root slot being generated */ /** Equipment pool for root slot being generated */
rootEquipmentPool: Record<string, number>; rootEquipmentPool: Record<string, number>
modPool: Mods; modPool: Mods
/** Dictionary of mod items and their chance to spawn for this bot type */ /** Dictionary of mod items and their chance to spawn for this bot type */
spawnChances: Chances; spawnChances: Chances
/** Role being generated for */ /** Role being generated for */
botRole: string; botRole: string
/** Level of bot being generated */ /** Level of bot being generated */
botLevel: number; botLevel: number
inventory: PmcInventory; inventory: PmcInventory
botEquipmentConfig: EquipmentFilters; botEquipmentConfig: EquipmentFilters
/** Settings from bot.json to adjust how item is generated */ /** Settings from bot.json to adjust how item is generated */
randomisationDetails: RandomisationDetails; randomisationDetails: RandomisationDetails
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { MinMax } from "@spt-aki/models/common/MinMax"; import { MinMax } from "@spt-aki/models/common/MinMax";
import { IRandomisedBotLevelResult } from "@spt-aki/models/eft/bot/IRandomisedBotLevelResult"; import { IRandomisedBotLevelResult } from "@spt-aki/models/eft/bot/IRandomisedBotLevelResult";
import { IExpTable } from "@spt-aki/models/eft/common/IGlobals"; import { IExpTable } from "@spt-aki/models/eft/common/IGlobals";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { BotWeaponGenerator } from "@spt-aki/generators/BotWeaponGenerator"; import { BotWeaponGenerator } from "@spt-aki/generators/BotWeaponGenerator";
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper"; import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
import { BotHelper } from "@spt-aki/helpers/BotHelper"; import { BotHelper } from "@spt-aki/helpers/BotHelper";
@ -292,7 +291,7 @@ export class BotLootGenerator
// Secure // Secure
// only add if not a pmc or is pmc and flag is true // only add if not a pmc or is pmc and flag is true
if (!isPmc || (isPmc && this.pmcConfig.addSecureContainerLootFromBotConfig)) if (!isPmc || isPmc && this.pmcConfig.addSecureContainerLootFromBotConfig)
{ {
this.addLootFromPool( this.addLootFromPool(
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.SECURE, botJsonTemplate), this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.SECURE, botJsonTemplate),
@ -317,12 +316,12 @@ export class BotLootGenerator
{ {
const result = [EquipmentSlots.POCKETS]; const result = [EquipmentSlots.POCKETS];
if (botInventory.items.find((item) => item.slotId === EquipmentSlots.TACTICAL_VEST)) if (botInventory.items.find(item => item.slotId === EquipmentSlots.TACTICAL_VEST))
{ {
result.push(EquipmentSlots.TACTICAL_VEST); result.push(EquipmentSlots.TACTICAL_VEST);
} }
if (botInventory.items.find((item) => item.slotId === EquipmentSlots.BACKPACK)) if (botInventory.items.find(item => item.slotId === EquipmentSlots.BACKPACK))
{ {
result.push(EquipmentSlots.BACKPACK); result.push(EquipmentSlots.BACKPACK);
} }
@ -476,7 +475,7 @@ export class BotLootGenerator
); );
} }
itemWithChildrenToAdd.push(...itemsToAdd.flatMap((moneyStack) => moneyStack)); itemWithChildrenToAdd.push(...itemsToAdd.flatMap(moneyStack => moneyStack));
} }
} }
} }

View File

@ -1,5 +1,4 @@
import { inject, injectAll, injectable } from "tsyringe"; import { inject, injectAll, injectable } from "tsyringe";
import { BotEquipmentModGenerator } from "@spt-aki/generators/BotEquipmentModGenerator"; import { BotEquipmentModGenerator } from "@spt-aki/generators/BotEquipmentModGenerator";
import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen"; import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen";
import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
@ -200,7 +199,7 @@ export class BotWeaponGenerator
} }
// Fill existing magazines to full and sync ammo type // Fill existing magazines to full and sync ammo type
for (const magazine of weaponWithModsArray.filter((item) => item.slotId === this.modMagazineSlotId)) for (const magazine of weaponWithModsArray.filter(item => item.slotId === this.modMagazineSlotId))
{ {
this.fillExistingMagazines(weaponWithModsArray, magazine, ammoTpl); this.fillExistingMagazines(weaponWithModsArray, magazine, ammoTpl);
} }
@ -212,12 +211,12 @@ export class BotWeaponGenerator
) )
{ {
// Guns have variety of possible Chamber ids, patron_in_weapon/patron_in_weapon_000/patron_in_weapon_001 // Guns have variety of possible Chamber ids, patron_in_weapon/patron_in_weapon_000/patron_in_weapon_001
const chamberSlotNames = weaponItemTemplate._props.Chambers.map((x) => x._name); const chamberSlotNames = weaponItemTemplate._props.Chambers.map(x => x._name);
this.addCartridgeToChamber(weaponWithModsArray, ammoTpl, chamberSlotNames); this.addCartridgeToChamber(weaponWithModsArray, ammoTpl, chamberSlotNames);
} }
// Fill UBGL if found // Fill UBGL if found
const ubglMod = weaponWithModsArray.find((x) => x.slotId === "mod_launcher"); const ubglMod = weaponWithModsArray.find(x => x.slotId === "mod_launcher");
let ubglAmmoTpl: string = undefined; let ubglAmmoTpl: string = undefined;
if (ubglMod) if (ubglMod)
{ {
@ -246,7 +245,7 @@ export class BotWeaponGenerator
{ {
for (const slotId of chamberSlotIds) for (const slotId of chamberSlotIds)
{ {
const existingItemWithSlot = weaponWithModsArray.find((x) => x.slotId === slotId); const existingItemWithSlot = weaponWithModsArray.find(x => x.slotId === slotId);
if (!existingItemWithSlot) if (!existingItemWithSlot)
{ {
// Not found, add new slot to weapon // Not found, add new slot to weapon
@ -367,11 +366,11 @@ export class BotWeaponGenerator
} }
// Iterate over required slots in db item, check mod exists for that slot // Iterate over required slots in db item, check mod exists for that slot
for (const modSlotTemplate of modTemplate._props.Slots.filter((slot) => slot._required)) for (const modSlotTemplate of modTemplate._props.Slots.filter(slot => slot._required))
{ {
const slotName = modSlotTemplate._name; const slotName = modSlotTemplate._name;
const weaponSlotItem = weaponItemArray.find((weaponItem) => const weaponSlotItem = weaponItemArray.find(weaponItem =>
weaponItem.parentId === mod._id && weaponItem.slotId === slotName weaponItem.parentId === mod._id && weaponItem.slotId === slotName,
); );
if (!weaponSlotItem) if (!weaponSlotItem)
{ {
@ -442,7 +441,7 @@ export class BotWeaponGenerator
ammoTemplate, ammoTemplate,
inventory, inventory,
); );
this.inventoryMagGenComponents.find((v) => v.canHandleInventoryMagGen(inventoryMagGenModel)).process( this.inventoryMagGenComponents.find(v => v.canHandleInventoryMagGen(inventoryMagGenModel)).process(
inventoryMagGenModel, inventoryMagGenModel,
); );
@ -468,13 +467,13 @@ export class BotWeaponGenerator
): void ): void
{ {
// Find ubgl mod item + get details of it from db // Find ubgl mod item + get details of it from db
const ubglMod = weaponMods.find((x) => x.slotId === "mod_launcher"); const ubglMod = weaponMods.find(x => x.slotId === "mod_launcher");
const ubglDbTemplate = this.itemHelper.getItem(ubglMod._tpl)[1]; const ubglDbTemplate = this.itemHelper.getItem(ubglMod._tpl)[1];
// Define min/max of how many grenades bot will have // Define min/max of how many grenades bot will have
const ubglMinMax: GenerationData = { const ubglMinMax: GenerationData = {
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
weights: { "1": 1, "2": 1 }, weights: { 1: 1, 2: 1 },
whitelist: {}, whitelist: {},
}; };
@ -489,7 +488,7 @@ export class BotWeaponGenerator
ubglAmmoDbTemplate, ubglAmmoDbTemplate,
inventory, inventory,
); );
this.inventoryMagGenComponents.find((v) => v.canHandleInventoryMagGen(ubglAmmoGenModel)).process( this.inventoryMagGenComponents.find(v => v.canHandleInventoryMagGen(ubglAmmoGenModel)).process(
ubglAmmoGenModel, ubglAmmoGenModel,
); );
@ -537,7 +536,7 @@ export class BotWeaponGenerator
botRole: string, botRole: string,
): string ): string
{ {
const magazine = weaponMods.find((m) => m.slotId === this.modMagazineSlotId); const magazine = weaponMods.find(m => m.slotId === this.modMagazineSlotId);
if (!magazine) if (!magazine)
{ {
// Edge case - magazineless chamber loaded weapons dont have magazines, e.g. mp18 // Edge case - magazineless chamber loaded weapons dont have magazines, e.g. mp18
@ -737,8 +736,8 @@ export class BotWeaponGenerator
magazineTemplate: ITemplateItem, magazineTemplate: ITemplateItem,
): void ): void
{ {
const magazineCartridgeChildItem = weaponWithMods.find((m) => const magazineCartridgeChildItem = weaponWithMods.find(m =>
m.parentId === magazine._id && m.slotId === "cartridges" m.parentId === magazine._id && m.slotId === "cartridges",
); );
if (magazineCartridgeChildItem) if (magazineCartridgeChildItem)
{ {
@ -767,7 +766,7 @@ export class BotWeaponGenerator
// for CylinderMagazine we exchange the ammo in the "camoras". // for CylinderMagazine we exchange the ammo in the "camoras".
// This might not be necessary since we already filled the camoras with a random whitelisted and compatible ammo type, // This might not be necessary since we already filled the camoras with a random whitelisted and compatible ammo type,
// but I'm not sure whether this is also used elsewhere // but I'm not sure whether this is also used elsewhere
const camoras = weaponMods.filter((x) => x.parentId === magazineId && x.slotId.startsWith("camora")); const camoras = weaponMods.filter(x => x.parentId === magazineId && x.slotId.startsWith("camora"));
for (const camora of camoras) for (const camora of camoras)
{ {
camora._tpl = ammoTpl; camora._tpl = ammoTpl;

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper"; import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper"; import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
@ -50,7 +49,7 @@ export class FenceBaseAssortGenerator
const blockedSeasonalItems = this.seasonalEventService.getInactiveSeasonalEventItems(); const blockedSeasonalItems = this.seasonalEventService.getInactiveSeasonalEventItems();
const baseFenceAssort = this.databaseServer.getTables().traders[Traders.FENCE].assort; const baseFenceAssort = this.databaseServer.getTables().traders[Traders.FENCE].assort;
for (const rootItemDb of this.itemHelper.getItems().filter((item) => this.isValidFenceItem(item))) for (const rootItemDb of this.itemHelper.getItems().filter(item => this.isValidFenceItem(item)))
{ {
// Skip blacklisted items // Skip blacklisted items
if (this.itemFilterService.isItemBlacklisted(rootItemDb._id)) if (this.itemFilterService.isItemBlacklisted(rootItemDb._id))
@ -144,7 +143,7 @@ export class FenceBaseAssortGenerator
for (const defaultPreset of defaultPresets) for (const defaultPreset of defaultPresets)
{ {
// Skip presets we've already added // Skip presets we've already added
if (baseFenceAssort.items.some((item) => item.upd && item.upd.sptPresetId === defaultPreset._id)) if (baseFenceAssort.items.some(item => item.upd && item.upd.sptPresetId === defaultPreset._id))
{ {
continue; continue;
} }
@ -252,7 +251,7 @@ export class FenceBaseAssortGenerator
} }
// Check for and add required soft inserts to armors // Check for and add required soft inserts to armors
const requiredSlots = itemDbDetails._props.Slots.filter((slot) => slot._required); const requiredSlots = itemDbDetails._props.Slots.filter(slot => slot._required);
const hasRequiredSlots = requiredSlots.length > 0; const hasRequiredSlots = requiredSlots.length > 0;
if (hasRequiredSlots) if (hasRequiredSlots)
{ {
@ -284,8 +283,8 @@ export class FenceBaseAssortGenerator
} }
// Check for and add plate items // Check for and add plate items
const plateSlots = itemDbDetails._props.Slots.filter((slot) => const plateSlots = itemDbDetails._props.Slots.filter(slot =>
this.itemHelper.isRemovablePlateSlot(slot._name) this.itemHelper.isRemovablePlateSlot(slot._name),
); );
if (plateSlots.length > 0) if (plateSlots.length > 0)
{ {

View File

@ -1,7 +1,7 @@
export interface IFilterPlateModsForSlotByLevelResult export interface IFilterPlateModsForSlotByLevelResult
{ {
result: Result; result: Result
plateModTpls: string[]; plateModTpls: string[]
} }
export enum Result export enum Result

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ContainerHelper } from "@spt-aki/helpers/ContainerHelper"; import { ContainerHelper } from "@spt-aki/helpers/ContainerHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper"; import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
@ -29,17 +28,17 @@ import { ProbabilityObject, ProbabilityObjectArray, RandomUtil } from "@spt-aki/
export interface IContainerItem export interface IContainerItem
{ {
items: Item[]; items: Item[]
width: number; width: number
height: number; height: number
} }
export interface IContainerGroupCount export interface IContainerGroupCount
{ {
/** Containers this group has + probabilty to spawn */ /** Containers this group has + probabilty to spawn */
containerIdsWithProbability: Record<string, number>; containerIdsWithProbability: Record<string, number>
/** How many containers the map should spawn with this group id */ /** How many containers the map should spawn with this group id */
chosenCount: number; chosenCount: number
} }
@injectable() @injectable()
@ -135,7 +134,7 @@ export class LocationGenerator
// Randomisation is turned off globally or just turned off for this map // Randomisation is turned off globally or just turned off for this map
if ( if (
!(this.locationConfig.containerRandomisationSettings.enabled !(this.locationConfig.containerRandomisationSettings.enabled
&& this.locationConfig.containerRandomisationSettings.maps[locationId]) && this.locationConfig.containerRandomisationSettings.maps[locationId])
) )
{ {
this.logger.debug( this.logger.debug(
@ -218,8 +217,8 @@ export class LocationGenerator
for (const chosenContainerId of chosenContainerIds) for (const chosenContainerId of chosenContainerIds)
{ {
// Look up container object from full list of containers on map // Look up container object from full list of containers on map
const containerObject = staticRandomisableContainersOnMap.find((staticContainer) => const containerObject = staticRandomisableContainersOnMap.find(staticContainer =>
staticContainer.template.Id === chosenContainerId staticContainer.template.Id === chosenContainerId,
); );
if (!containerObject) if (!containerObject)
{ {
@ -262,11 +261,11 @@ export class LocationGenerator
*/ */
protected getRandomisableContainersOnMap(staticContainers: IStaticContainerData[]): IStaticContainerData[] protected getRandomisableContainersOnMap(staticContainers: IStaticContainerData[]): IStaticContainerData[]
{ {
return staticContainers.filter((staticContainer) => return staticContainers.filter(staticContainer =>
staticContainer.probability !== 1 && !staticContainer.template.IsAlwaysSpawn staticContainer.probability !== 1 && !staticContainer.template.IsAlwaysSpawn
&& !this.locationConfig.containerRandomisationSettings.containerTypesToNotRandomise.includes( && !this.locationConfig.containerRandomisationSettings.containerTypesToNotRandomise.includes(
staticContainer.template.Items[0]._tpl, staticContainer.template.Items[0]._tpl,
) ),
); );
} }
@ -277,11 +276,11 @@ export class LocationGenerator
*/ */
protected getGuaranteedContainers(staticContainersOnMap: IStaticContainerData[]): IStaticContainerData[] protected getGuaranteedContainers(staticContainersOnMap: IStaticContainerData[]): IStaticContainerData[]
{ {
return staticContainersOnMap.filter((staticContainer) => return staticContainersOnMap.filter(staticContainer =>
staticContainer.probability === 1 || staticContainer.template.IsAlwaysSpawn staticContainer.probability === 1 || staticContainer.template.IsAlwaysSpawn
|| this.locationConfig.containerRandomisationSettings.containerTypesToNotRandomise.includes( || this.locationConfig.containerRandomisationSettings.containerTypesToNotRandomise.includes(
staticContainer.template.Items[0]._tpl, staticContainer.template.Items[0]._tpl,
) ),
); );
} }
@ -338,11 +337,11 @@ export class LocationGenerator
chosenCount: this.randomUtil.getInt( chosenCount: this.randomUtil.getInt(
Math.round( Math.round(
groupData.minContainers groupData.minContainers
* this.locationConfig.containerRandomisationSettings.containerGroupMinSizeMultiplier, * this.locationConfig.containerRandomisationSettings.containerGroupMinSizeMultiplier,
), ),
Math.round( Math.round(
groupData.maxContainers groupData.maxContainers
* this.locationConfig.containerRandomisationSettings.containerGroupMaxSizeMultiplier, * this.locationConfig.containerRandomisationSettings.containerGroupMaxSizeMultiplier,
), ),
), ),
}; };
@ -412,9 +411,9 @@ export class LocationGenerator
const containerLootPool = this.getPossibleLootItemsForContainer(containerTpl, staticLootDist); const containerLootPool = this.getPossibleLootItemsForContainer(containerTpl, staticLootDist);
// Some containers need to have items forced into it (quest keys etc) // Some containers need to have items forced into it (quest keys etc)
const tplsForced = staticForced.filter((forcedStaticProp) => const tplsForced = staticForced.filter(forcedStaticProp =>
forcedStaticProp.containerId === containerClone.template.Id forcedStaticProp.containerId === containerClone.template.Id,
).map((x) => x.itemTpl); ).map(x => x.itemTpl);
// Draw random loot // Draw random loot
// Money spawn more than once in container // Money spawn more than once in container
@ -427,7 +426,7 @@ export class LocationGenerator
itemCountToAdd, itemCountToAdd,
this.locationConfig.allowDuplicateItemsInStaticContainers, this.locationConfig.allowDuplicateItemsInStaticContainers,
locklist, locklist,
).filter((tpl) => !tplsForced.includes(tpl)); ).filter(tpl => !tplsForced.includes(tpl));
// Add forced loot to chosen item pool // Add forced loot to chosen item pool
const tplsToAddToContainer = tplsForced.concat(chosenTpls); const tplsToAddToContainer = tplsForced.concat(chosenTpls);
@ -597,7 +596,7 @@ export class LocationGenerator
// Build the list of forced loot from both `spawnpointsForced` and any point marked `IsAlwaysSpawn` // Build the list of forced loot from both `spawnpointsForced` and any point marked `IsAlwaysSpawn`
dynamicForcedSpawnPoints.push(...dynamicLootDist.spawnpointsForced); dynamicForcedSpawnPoints.push(...dynamicLootDist.spawnpointsForced);
dynamicForcedSpawnPoints.push(...dynamicLootDist.spawnpoints.filter((point) => point.template.IsAlwaysSpawn)); dynamicForcedSpawnPoints.push(...dynamicLootDist.spawnpoints.filter(point => point.template.IsAlwaysSpawn));
// Add forced loot // Add forced loot
this.addForcedLoot(loot, dynamicForcedSpawnPoints, locationName); this.addForcedLoot(loot, dynamicForcedSpawnPoints, locationName);
@ -607,10 +606,10 @@ export class LocationGenerator
// Draw from random distribution // Draw from random distribution
const desiredSpawnpointCount = Math.round( const desiredSpawnpointCount = Math.round(
this.getLooseLootMultiplerForLocation(locationName) this.getLooseLootMultiplerForLocation(locationName)
* this.randomUtil.getNormallyDistributedRandomNumber( * this.randomUtil.getNormallyDistributedRandomNumber(
dynamicLootDist.spawnpointCount.mean, dynamicLootDist.spawnpointCount.mean,
dynamicLootDist.spawnpointCount.std, dynamicLootDist.spawnpointCount.std,
), ),
); );
// Positions not in forced but have 100% chance to spawn // Positions not in forced but have 100% chance to spawn
@ -660,11 +659,11 @@ export class LocationGenerator
// Filter out duplicate locationIds // Filter out duplicate locationIds
chosenSpawnpoints = [ chosenSpawnpoints = [
...new Map(chosenSpawnpoints.map((spawnPoint) => [spawnPoint.locationId, spawnPoint])).values(), ...new Map(chosenSpawnpoints.map(spawnPoint => [spawnPoint.locationId, spawnPoint])).values(),
]; ];
// Do we have enough items in pool to fulfill requirement // Do we have enough items in pool to fulfill requirement
const tooManySpawnPointsRequested = (desiredSpawnpointCount - chosenSpawnpoints.length) > 0; const tooManySpawnPointsRequested = desiredSpawnpointCount - chosenSpawnpoints.length > 0;
if (tooManySpawnPointsRequested) if (tooManySpawnPointsRequested)
{ {
this.logger.debug( this.logger.debug(
@ -704,7 +703,7 @@ export class LocationGenerator
{ {
if ( if (
!seasonalEventActive && seasonalItemTplBlacklist.includes( !seasonalEventActive && seasonalItemTplBlacklist.includes(
spawnPoint.template.Items.find((item) => item._id === itemDist.composedKey.key)._tpl, spawnPoint.template.Items.find(item => item._id === itemDist.composedKey.key)._tpl,
) )
) )
{ {
@ -755,8 +754,8 @@ export class LocationGenerator
for (const itemTpl of lootToForceSingleAmountOnMap) for (const itemTpl of lootToForceSingleAmountOnMap)
{ {
// Get all spawn positions for item tpl in forced loot array // Get all spawn positions for item tpl in forced loot array
const items = forcedSpawnPoints.filter((forcedSpawnPoint) => const items = forcedSpawnPoints.filter(forcedSpawnPoint =>
forcedSpawnPoint.template.Items[0]._tpl === itemTpl forcedSpawnPoint.template.Items[0]._tpl === itemTpl,
); );
if (!items || items.length === 0) if (!items || items.length === 0)
{ {
@ -780,7 +779,7 @@ export class LocationGenerator
// Choose 1 out of all found spawn positions for spawn id and add to loot array // Choose 1 out of all found spawn positions for spawn id and add to loot array
for (const spawnPointLocationId of spawnpointArray.draw(1, false)) for (const spawnPointLocationId of spawnpointArray.draw(1, false))
{ {
const itemToAdd = items.find((item) => item.locationId === spawnPointLocationId); const itemToAdd = items.find(item => item.locationId === spawnPointLocationId);
const lootItem = itemToAdd.template; const lootItem = itemToAdd.template;
lootItem.Root = this.objectId.generate(); lootItem.Root = this.objectId.generate();
lootItem.Items[0]._id = lootItem.Root; lootItem.Items[0]._id = lootItem.Root;
@ -816,8 +815,8 @@ export class LocationGenerator
locationTemplateToAdd.Items[0]._id = locationTemplateToAdd.Root; locationTemplateToAdd.Items[0]._id = locationTemplateToAdd.Root;
// Push forced location into array as long as it doesnt exist already // Push forced location into array as long as it doesnt exist already
const existingLocation = lootLocationTemplates.find((spawnPoint) => const existingLocation = lootLocationTemplates.find(spawnPoint =>
spawnPoint.Id === locationTemplateToAdd.Id spawnPoint.Id === locationTemplateToAdd.Id,
); );
if (!existingLocation) if (!existingLocation)
{ {
@ -845,7 +844,7 @@ export class LocationGenerator
staticAmmoDist: Record<string, IStaticAmmoDetails[]>, staticAmmoDist: Record<string, IStaticAmmoDetails[]>,
): IContainerItem ): IContainerItem
{ {
const chosenItem = spawnPoint.template.Items.find((item) => item._id === chosenComposedKey); const chosenItem = spawnPoint.template.Items.find(item => item._id === chosenComposedKey);
const chosenTpl = chosenItem._tpl; const chosenTpl = chosenItem._tpl;
const itemTemplate = this.itemHelper.getItem(chosenTpl)[1]; const itemTemplate = this.itemHelper.getItem(chosenTpl)[1];
@ -945,10 +944,10 @@ export class LocationGenerator
{ {
if (this.itemHelper.isOfBaseclass(chosenTpl, BaseClasses.WEAPON)) if (this.itemHelper.isOfBaseclass(chosenTpl, BaseClasses.WEAPON))
{ {
return items.find((v) => v._tpl === chosenTpl && v.parentId === undefined); return items.find(v => v._tpl === chosenTpl && v.parentId === undefined);
} }
return items.find((item) => item._tpl === chosenTpl); return items.find(item => item._tpl === chosenTpl);
} }
// TODO: rewrite, BIG yikes // TODO: rewrite, BIG yikes
@ -1052,7 +1051,7 @@ export class LocationGenerator
// it can handle revolver ammo (it's not restructured to be used here yet.) // it can handle revolver ammo (it's not restructured to be used here yet.)
// General: Make a WeaponController for Ragfair preset stuff and the generating weapons and ammo stuff from // General: Make a WeaponController for Ragfair preset stuff and the generating weapons and ammo stuff from
// BotGenerator // BotGenerator
const magazine = items.filter((item) => item.slotId === "mod_magazine")[0]; const magazine = items.filter(item => item.slotId === "mod_magazine")[0];
// some weapon presets come without magazine; only fill the mag if it exists // some weapon presets come without magazine; only fill the mag if it exists
if (magazine) if (magazine)
{ {

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper"; import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper"; import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
@ -21,7 +20,7 @@ import { HashUtil } from "@spt-aki/utils/HashUtil";
import { JsonUtil } from "@spt-aki/utils/JsonUtil"; import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { RandomUtil } from "@spt-aki/utils/RandomUtil"; import { RandomUtil } from "@spt-aki/utils/RandomUtil";
type ItemLimit = { current: number; max: number; }; type ItemLimit = { current: number, max: number };
@injectable() @injectable()
export class LootGenerator export class LootGenerator
@ -74,8 +73,8 @@ export class LootGenerator
if (desiredWeaponCrateCount > 0) if (desiredWeaponCrateCount > 0)
{ {
// Get list of all sealed containers from db // Get list of all sealed containers from db
const sealedWeaponContainerPool = Object.values(tables.templates.items).filter((x) => const sealedWeaponContainerPool = Object.values(tables.templates.items).filter(x =>
x._name.includes("event_container_airdrop") x._name.includes("event_container_airdrop"),
); );
for (let index = 0; index < desiredWeaponCrateCount; index++) for (let index = 0; index < desiredWeaponCrateCount; index++)
@ -92,11 +91,11 @@ export class LootGenerator
} }
// Get items from items.json that have a type of item + not in global blacklist + basetype is in whitelist // Get items from items.json that have a type of item + not in global blacklist + basetype is in whitelist
const items = Object.entries(tables.templates.items).filter((x) => const items = Object.entries(tables.templates.items).filter(x =>
!itemBlacklist.has(x[1]._id) !itemBlacklist.has(x[1]._id)
&& x[1]._type.toLowerCase() === "item" && x[1]._type.toLowerCase() === "item"
&& !x[1]._props.QuestItem && !x[1]._props.QuestItem
&& options.itemTypeWhitelist.includes(x[1]._parent) && options.itemTypeWhitelist.includes(x[1]._parent),
); );
if (items.length > 0) if (items.length > 0)
@ -122,8 +121,8 @@ export class LootGenerator
); );
if (randomisedWeaponPresetCount > 0) if (randomisedWeaponPresetCount > 0)
{ {
const weaponDefaultPresets = globalDefaultPresets.filter((preset) => const weaponDefaultPresets = globalDefaultPresets.filter(preset =>
this.itemHelper.isOfBaseclass(preset._encyclopedia, BaseClasses.WEAPON) this.itemHelper.isOfBaseclass(preset._encyclopedia, BaseClasses.WEAPON),
); );
if (weaponDefaultPresets.length > 0) if (weaponDefaultPresets.length > 0)
@ -153,11 +152,11 @@ export class LootGenerator
); );
if (randomisedArmorPresetCount > 0) if (randomisedArmorPresetCount > 0)
{ {
const armorDefaultPresets = globalDefaultPresets.filter((preset) => const armorDefaultPresets = globalDefaultPresets.filter(preset =>
this.itemHelper.armorItemCanHoldMods(preset._encyclopedia) this.itemHelper.armorItemCanHoldMods(preset._encyclopedia),
); );
const levelFilteredArmorPresets = armorDefaultPresets.filter((armor) => const levelFilteredArmorPresets = armorDefaultPresets.filter(armor =>
this.armorIsDesiredProtectionLevel(armor, options) this.armorIsDesiredProtectionLevel(armor, options),
); );
// Add some armors to rewards // Add some armors to rewards
@ -192,21 +191,21 @@ export class LootGenerator
*/ */
protected armorIsDesiredProtectionLevel(armor: IPreset, options: LootRequest): boolean protected armorIsDesiredProtectionLevel(armor: IPreset, options: LootRequest): boolean
{ {
const frontPlate = armor._items.find((mod) => mod?.slotId?.toLowerCase() === "front_plate"); const frontPlate = armor._items.find(mod => mod?.slotId?.toLowerCase() === "front_plate");
if (frontPlate) if (frontPlate)
{ {
const plateDb = this.itemHelper.getItem(frontPlate._tpl); const plateDb = this.itemHelper.getItem(frontPlate._tpl);
return options.armorLevelWhitelist.includes(Number.parseInt(plateDb[1]._props.armorClass as any)); return options.armorLevelWhitelist.includes(Number.parseInt(plateDb[1]._props.armorClass as any));
} }
const helmetTop = armor._items.find((mod) => mod?.slotId?.toLowerCase() === "helmet_top"); const helmetTop = armor._items.find(mod => mod?.slotId?.toLowerCase() === "helmet_top");
if (helmetTop) if (helmetTop)
{ {
const plateDb = this.itemHelper.getItem(helmetTop._tpl); const plateDb = this.itemHelper.getItem(helmetTop._tpl);
return options.armorLevelWhitelist.includes(Number.parseInt(plateDb[1]._props.armorClass as any)); return options.armorLevelWhitelist.includes(Number.parseInt(plateDb[1]._props.armorClass as any));
} }
const softArmorFront = armor._items.find((mod) => mod?.slotId?.toLowerCase() === "soft_armor_front"); const softArmorFront = armor._items.find(mod => mod?.slotId?.toLowerCase() === "soft_armor_front");
if (softArmorFront) if (softArmorFront)
{ {
const plateDb = this.itemHelper.getItem(softArmorFront._tpl); const plateDb = this.itemHelper.getItem(softArmorFront._tpl);
@ -242,7 +241,7 @@ export class LootGenerator
*/ */
protected findAndAddRandomItemToLoot( protected findAndAddRandomItemToLoot(
items: [string, ITemplateItem][], items: [string, ITemplateItem][],
itemTypeCounts: Record<string, { current: number; max: number; }>, itemTypeCounts: Record<string, { current: number, max: number }>,
options: LootRequest, options: LootRequest,
result: LootItem[], result: LootItem[],
): boolean ): boolean
@ -317,7 +316,7 @@ export class LootGenerator
*/ */
protected findAndAddRandomPresetToLoot( protected findAndAddRandomPresetToLoot(
presetPool: IPreset[], presetPool: IPreset[],
itemTypeCounts: Record<string, { current: number; max: number; }>, itemTypeCounts: Record<string, { current: number, max: number }>,
itemBlacklist: string[], itemBlacklist: string[],
result: LootItem[], result: LootItem[],
): boolean ): boolean
@ -408,7 +407,7 @@ export class LootGenerator
} }
// Get weapon preset - default or choose a random one from globals.json preset pool // Get weapon preset - default or choose a random one from globals.json preset pool
let chosenWeaponPreset = (containerSettings.defaultPresetsOnly) let chosenWeaponPreset = containerSettings.defaultPresetsOnly
? this.presetHelper.getDefaultPreset(chosenWeaponTpl) ? this.presetHelper.getDefaultPreset(chosenWeaponTpl)
: this.randomUtil.getArrayValue(this.presetHelper.getPresets(chosenWeaponTpl)); : this.randomUtil.getArrayValue(this.presetHelper.getPresets(chosenWeaponTpl));
@ -473,7 +472,7 @@ export class LootGenerator
// Need to find boxes that matches weapons caliber // Need to find boxes that matches weapons caliber
const weaponCaliber = weaponDetailsDb._props.ammoCaliber; const weaponCaliber = weaponDetailsDb._props.ammoCaliber;
const ammoBoxesMatchingCaliber = ammoBoxesDetails.filter((x) => x._props.ammoCaliber === weaponCaliber); const ammoBoxesMatchingCaliber = ammoBoxesDetails.filter(x => x._props.ammoCaliber === weaponCaliber);
if (ammoBoxesMatchingCaliber.length === 0) if (ammoBoxesMatchingCaliber.length === 0)
{ {
this.logger.debug(`No ammo box with caliber ${weaponCaliber} found, skipping`); this.logger.debug(`No ammo box with caliber ${weaponCaliber} found, skipping`);
@ -493,12 +492,12 @@ export class LootGenerator
} }
// Get all items of the desired type + not quest items + not globally blacklisted // Get all items of the desired type + not quest items + not globally blacklisted
const rewardItemPool = Object.values(this.databaseServer.getTables().templates.items).filter((x) => const rewardItemPool = Object.values(this.databaseServer.getTables().templates.items).filter(x =>
x._parent === rewardTypeId x._parent === rewardTypeId
&& x._type.toLowerCase() === "item" && x._type.toLowerCase() === "item"
&& !this.itemFilterService.isItemBlacklisted(x._id) && !this.itemFilterService.isItemBlacklisted(x._id)
&& (!(containerSettings.allowBossItems || this.itemFilterService.isBossItem(x._id))) && !(containerSettings.allowBossItems || this.itemFilterService.isBossItem(x._id))
&& !x._props.QuestItem && !x._props.QuestItem,
); );
if (rewardItemPool.length === 0) if (rewardItemPool.length === 0)
@ -547,8 +546,8 @@ export class LootGenerator
} }
// Get items that fulfil reward type criteria from items that fit on gun // Get items that fulfil reward type criteria from items that fit on gun
const relatedItems = linkedItemsToWeapon.filter((x) => const relatedItems = linkedItemsToWeapon.filter(x =>
x._parent === rewardTypeId && !this.itemFilterService.isItemBlacklisted(x._id) x._parent === rewardTypeId && !this.itemFilterService.isItemBlacklisted(x._id),
); );
if (!relatedItems || relatedItems.length === 0) if (!relatedItems || relatedItems.length === 0)
{ {

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper";
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem"; import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
@ -48,8 +47,8 @@ export class PMCLootGenerator
if (Object.keys(this.pocketLootPool).length === 0) if (Object.keys(this.pocketLootPool).length === 0)
{ {
const items = this.databaseServer.getTables().templates.items; const items = this.databaseServer.getTables().templates.items;
const pmcPriceOverrides = const pmcPriceOverrides
this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items = this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items
.Pockets; .Pockets;
const allowedItemTypes = this.pmcConfig.pocketLoot.whitelist; const allowedItemTypes = this.pmcConfig.pocketLoot.whitelist;
@ -59,13 +58,13 @@ export class PMCLootGenerator
// Blacklist inactive seasonal items // Blacklist inactive seasonal items
itemBlacklist.push(...this.seasonalEventService.getInactiveSeasonalEventItems()); itemBlacklist.push(...this.seasonalEventService.getInactiveSeasonalEventItems());
const itemsToAdd = Object.values(items).filter((item) => const itemsToAdd = Object.values(items).filter(item =>
allowedItemTypes.includes(item._parent) allowedItemTypes.includes(item._parent)
&& this.itemHelper.isValidItem(item._id) && this.itemHelper.isValidItem(item._id)
&& !pmcItemBlacklist.includes(item._id) && !pmcItemBlacklist.includes(item._id)
&& !itemBlacklist.includes(item._id) && !itemBlacklist.includes(item._id)
&& item._props.Width === 1 && item._props.Width === 1
&& item._props.Height === 1 && item._props.Height === 1,
); );
for (const itemToAdd of itemsToAdd) for (const itemToAdd of itemsToAdd)
@ -88,7 +87,7 @@ export class PMCLootGenerator
{ {
// Invert price so cheapest has a larger weight // Invert price so cheapest has a larger weight
// Times by highest price so most expensive item has weight of 1 // Times by highest price so most expensive item has weight of 1
this.pocketLootPool[key] = Math.round((1 / this.pocketLootPool[key]) * highestPrice); this.pocketLootPool[key] = Math.round(1 / this.pocketLootPool[key] * highestPrice);
} }
this.weightedRandomHelper.reduceWeightValues(this.pocketLootPool); this.weightedRandomHelper.reduceWeightValues(this.pocketLootPool);
@ -107,8 +106,8 @@ export class PMCLootGenerator
if (Object.keys(this.vestLootPool).length === 0) if (Object.keys(this.vestLootPool).length === 0)
{ {
const items = this.databaseServer.getTables().templates.items; const items = this.databaseServer.getTables().templates.items;
const pmcPriceOverrides = const pmcPriceOverrides
this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items = this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items
.TacticalVest; .TacticalVest;
const allowedItemTypes = this.pmcConfig.vestLoot.whitelist; const allowedItemTypes = this.pmcConfig.vestLoot.whitelist;
@ -118,12 +117,12 @@ export class PMCLootGenerator
// Blacklist seasonal items // Blacklist seasonal items
itemBlacklist.push(...this.seasonalEventService.getInactiveSeasonalEventItems()); itemBlacklist.push(...this.seasonalEventService.getInactiveSeasonalEventItems());
const itemsToAdd = Object.values(items).filter((item) => const itemsToAdd = Object.values(items).filter(item =>
allowedItemTypes.includes(item._parent) allowedItemTypes.includes(item._parent)
&& this.itemHelper.isValidItem(item._id) && this.itemHelper.isValidItem(item._id)
&& !pmcItemBlacklist.includes(item._id) && !pmcItemBlacklist.includes(item._id)
&& !itemBlacklist.includes(item._id) && !itemBlacklist.includes(item._id)
&& this.itemFitsInto2By2Slot(item) && this.itemFitsInto2By2Slot(item),
); );
for (const itemToAdd of itemsToAdd) for (const itemToAdd of itemsToAdd)
@ -146,7 +145,7 @@ export class PMCLootGenerator
{ {
// Invert price so cheapest has a larger weight // Invert price so cheapest has a larger weight
// Times by highest price so most expensive item has weight of 1 // Times by highest price so most expensive item has weight of 1
this.vestLootPool[key] = Math.round((1 / this.vestLootPool[key]) * highestPrice); this.vestLootPool[key] = Math.round(1 / this.vestLootPool[key] * highestPrice);
} }
this.weightedRandomHelper.reduceWeightValues(this.vestLootPool); this.weightedRandomHelper.reduceWeightValues(this.vestLootPool);
@ -176,8 +175,8 @@ export class PMCLootGenerator
if (Object.keys(this.backpackLootPool).length === 0) if (Object.keys(this.backpackLootPool).length === 0)
{ {
const items = this.databaseServer.getTables().templates.items; const items = this.databaseServer.getTables().templates.items;
const pmcPriceOverrides = const pmcPriceOverrides
this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items = this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items
.Backpack; .Backpack;
const allowedItemTypes = this.pmcConfig.backpackLoot.whitelist; const allowedItemTypes = this.pmcConfig.backpackLoot.whitelist;
@ -187,11 +186,11 @@ export class PMCLootGenerator
// Blacklist seasonal items // Blacklist seasonal items
itemBlacklist.push(...this.seasonalEventService.getInactiveSeasonalEventItems()); itemBlacklist.push(...this.seasonalEventService.getInactiveSeasonalEventItems());
const itemsToAdd = Object.values(items).filter((item) => const itemsToAdd = Object.values(items).filter(item =>
allowedItemTypes.includes(item._parent) allowedItemTypes.includes(item._parent)
&& this.itemHelper.isValidItem(item._id) && this.itemHelper.isValidItem(item._id)
&& !pmcItemBlacklist.includes(item._id) && !pmcItemBlacklist.includes(item._id)
&& !itemBlacklist.includes(item._id) && !itemBlacklist.includes(item._id),
); );
for (const itemToAdd of itemsToAdd) for (const itemToAdd of itemsToAdd)
@ -214,7 +213,7 @@ export class PMCLootGenerator
{ {
// Invert price so cheapest has a larger weight // Invert price so cheapest has a larger weight
// Times by highest price so most expensive item has weight of 1 // Times by highest price so most expensive item has weight of 1
this.backpackLootPool[key] = Math.round((1 / this.backpackLootPool[key]) * highestPrice); this.backpackLootPool[key] = Math.round(1 / this.backpackLootPool[key] * highestPrice);
} }
this.weightedRandomHelper.reduceWeightValues(this.backpackLootPool); this.weightedRandomHelper.reduceWeightValues(this.backpackLootPool);

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { BotGenerator } from "@spt-aki/generators/BotGenerator"; import { BotGenerator } from "@spt-aki/generators/BotGenerator";
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper"; import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
import { BotHelper } from "@spt-aki/helpers/BotHelper"; import { BotHelper } from "@spt-aki/helpers/BotHelper";
@ -310,7 +309,7 @@ export class PlayerScavGenerator
protected getScavLevel(scavProfile: IPmcData): number protected getScavLevel(scavProfile: IPmcData): number
{ {
// Info can be null on initial account creation // Info can be null on initial account creation
if (!(scavProfile.Info?.Level)) if (!scavProfile.Info?.Level)
{ {
return 1; return 1;
} }
@ -321,7 +320,7 @@ export class PlayerScavGenerator
protected getScavExperience(scavProfile: IPmcData): number protected getScavExperience(scavProfile: IPmcData): number
{ {
// Info can be null on initial account creation // Info can be null on initial account creation
if (!(scavProfile.Info?.Experience)) if (!scavProfile.Info?.Experience)
{ {
return 0; return 0;
} }
@ -364,7 +363,7 @@ export class PlayerScavGenerator
scavLockDuration = 10; scavLockDuration = 10;
} }
scavData.Info.SavageLockTime = (Date.now() / 1000) + scavLockDuration; scavData.Info.SavageLockTime = Date.now() / 1000 + scavLockDuration;
return scavData; return scavData;
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper"; import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { IPreset } from "@spt-aki/models/eft/common/IGlobals"; import { IPreset } from "@spt-aki/models/eft/common/IGlobals";
@ -75,7 +74,7 @@ export class RagfairAssortGenerator
const results: Item[][] = []; const results: Item[][] = [];
/** Get cloned items from db */ /** Get cloned items from db */
const dbItemsClone = this.itemHelper.getItems().filter((item) => item._type !== "Node"); const dbItemsClone = this.itemHelper.getItems().filter(item => item._type !== "Node");
/** Store processed preset tpls so we dont add them when procesing non-preset items */ /** Store processed preset tpls so we dont add them when procesing non-preset items */
const processedArmorItems: string[] = []; const processedArmorItems: string[] = [];
@ -136,7 +135,7 @@ export class RagfairAssortGenerator
*/ */
protected getPresetsToAdd(): IPreset[] protected getPresetsToAdd(): IPreset[]
{ {
return (this.ragfairConfig.dynamic.showDefaultPresetsOnly) return this.ragfairConfig.dynamic.showDefaultPresetsOnly
? Object.values(this.presetHelper.getDefaultPresets()) ? Object.values(this.presetHelper.getDefaultPresets())
: this.presetHelper.getAllPresets(); : this.presetHelper.getAllPresets();
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { RagfairAssortGenerator } from "@spt-aki/generators/RagfairAssortGenerator"; import { RagfairAssortGenerator } from "@spt-aki/generators/RagfairAssortGenerator";
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper"; import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
@ -37,7 +36,7 @@ import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export class RagfairOfferGenerator export class RagfairOfferGenerator
{ {
protected ragfairConfig: IRagfairConfig; protected ragfairConfig: IRagfairConfig;
protected allowedFleaPriceItemsForBarter: { tpl: string; price: number; }[]; protected allowedFleaPriceItemsForBarter: { tpl: string, price: number }[];
/** Internal counter to ensure each offer created has a unique value for its intId property */ /** Internal counter to ensure each offer created has a unique value for its intId property */
protected offerCounter = 0; protected offerCounter = 0;
@ -136,7 +135,7 @@ export class RagfairOfferGenerator
} }
} }
const itemCount = items.filter((x) => x.slotId === "hideout").length; const itemCount = items.filter(x => x.slotId === "hideout").length;
const roublePrice = Math.round(this.convertOfferRequirementsIntoRoubles(offerRequirements)); const roublePrice = Math.round(this.convertOfferRequirementsIntoRoubles(offerRequirements));
const offer: IRagfairOffer = { const offer: IRagfairOffer = {
@ -144,7 +143,7 @@ export class RagfairOfferGenerator
intId: this.offerCounter, intId: this.offerCounter,
user: { user: {
id: this.getTraderId(userID), id: this.getTraderId(userID),
memberType: (userID === "ragfair") memberType: userID === "ragfair"
? MemberCategory.DEFAULT ? MemberCategory.DEFAULT
: this.ragfairServerHelper.getMemberType(userID), : this.ragfairServerHelper.getMemberType(userID),
nickname: this.ragfairServerHelper.getNickname(userID), nickname: this.ragfairServerHelper.getNickname(userID),
@ -297,8 +296,8 @@ export class RagfairOfferGenerator
if (this.ragfairServerHelper.isPlayer(userID)) if (this.ragfairServerHelper.isPlayer(userID))
{ {
// Player offer = current time + offerDurationTimeInHour; // Player offer = current time + offerDurationTimeInHour;
const offerDurationTimeHours = const offerDurationTimeHours
this.databaseServer.getTables().globals.config.RagFair.offerDurationTimeInHour; = this.databaseServer.getTables().globals.config.RagFair.offerDurationTimeInHour;
return this.timeUtil.getTimestamp() + Math.round(offerDurationTimeHours * TimeUtil.ONE_HOUR_AS_SECONDS); return this.timeUtil.getTimestamp() + Math.round(offerDurationTimeHours * TimeUtil.ONE_HOUR_AS_SECONDS);
} }
@ -311,10 +310,10 @@ export class RagfairOfferGenerator
// Generated fake-player offer // Generated fake-player offer
return Math.round( return Math.round(
time time
+ this.randomUtil.getInt( + this.randomUtil.getInt(
this.ragfairConfig.dynamic.endTimeSeconds.min, this.ragfairConfig.dynamic.endTimeSeconds.min,
this.ragfairConfig.dynamic.endTimeSeconds.max, this.ragfairConfig.dynamic.endTimeSeconds.max,
), ),
); );
} }
@ -411,8 +410,8 @@ export class RagfairOfferGenerator
return false; return false;
} }
const plateSlots = presetWithChildren.filter((item) => const plateSlots = presetWithChildren.filter(item =>
this.itemHelper.getRemovablePlateSlotIds().includes(item.slotId?.toLowerCase()) this.itemHelper.getRemovablePlateSlotIds().includes(item.slotId?.toLowerCase()),
); );
if (plateSlots.length === 0) if (plateSlots.length === 0)
{ {
@ -461,12 +460,12 @@ export class RagfairOfferGenerator
const isBarterOffer = this.randomUtil.getChance100(this.ragfairConfig.dynamic.barter.chancePercent); const isBarterOffer = this.randomUtil.getChance100(this.ragfairConfig.dynamic.barter.chancePercent);
const isPackOffer = this.randomUtil.getChance100(this.ragfairConfig.dynamic.pack.chancePercent) const isPackOffer = this.randomUtil.getChance100(this.ragfairConfig.dynamic.pack.chancePercent)
&& !isBarterOffer && !isBarterOffer
&& itemWithChildren.length === 1 && itemWithChildren.length === 1
&& this.itemHelper.isOfBaseclasses( && this.itemHelper.isOfBaseclasses(
itemWithChildren[0]._tpl, itemWithChildren[0]._tpl,
this.ragfairConfig.dynamic.pack.itemTypeWhitelist, this.ragfairConfig.dynamic.pack.itemTypeWhitelist,
); );
const randomUserId = this.hashUtil.generate(); const randomUserId = this.hashUtil.generate();
@ -478,8 +477,8 @@ export class RagfairOfferGenerator
const shouldRemovePlates = this.randomUtil.getChance100(armorConfig.removeRemovablePlateChance); const shouldRemovePlates = this.randomUtil.getChance100(armorConfig.removeRemovablePlateChance);
if (shouldRemovePlates && this.itemHelper.armorItemHasRemovablePlateSlots(itemWithChildren[0]._tpl)) if (shouldRemovePlates && this.itemHelper.armorItemHasRemovablePlateSlots(itemWithChildren[0]._tpl))
{ {
const offerItemPlatesToRemove = itemWithChildren.filter((item) => const offerItemPlatesToRemove = itemWithChildren.filter(item =>
armorConfig.plateSlotIdToRemovePool.includes(item.slotId?.toLowerCase()) armorConfig.plateSlotIdToRemovePool.includes(item.slotId?.toLowerCase()),
); );
for (const plateItem of offerItemPlatesToRemove) for (const plateItem of offerItemPlatesToRemove)
@ -684,8 +683,8 @@ export class RagfairOfferGenerator
this.randomiseArmorDurabilityValues(itemWithMods, currentMultiplier, maxMultiplier); this.randomiseArmorDurabilityValues(itemWithMods, currentMultiplier, maxMultiplier);
// Add hits to visor // Add hits to visor
const visorMod = itemWithMods.find((item) => const visorMod = itemWithMods.find(item =>
item.parentId === BaseClasses.ARMORED_EQUIPMENT && item.slotId === "mod_equipment_000" item.parentId === BaseClasses.ARMORED_EQUIPMENT && item.slotId === "mod_equipment_000",
); );
if (this.randomUtil.getChance100(25) && visorMod) if (this.randomUtil.getChance100(25) && visorMod)
{ {
@ -717,7 +716,7 @@ export class RagfairOfferGenerator
{ {
// randomize key uses // randomize key uses
rootItem.upd.Key.NumberOfUsages = Math.round(itemDetails._props.MaximumNumberOfUsage * (1 - maxMultiplier)) rootItem.upd.Key.NumberOfUsages = Math.round(itemDetails._props.MaximumNumberOfUsage * (1 - maxMultiplier))
|| 0; || 0;
return; return;
} }
@ -789,12 +788,12 @@ export class RagfairOfferGenerator
for (const armorItem of armorWithMods) for (const armorItem of armorWithMods)
{ {
const itemDbDetails = this.itemHelper.getItem(armorItem._tpl)[1]; const itemDbDetails = this.itemHelper.getItem(armorItem._tpl)[1];
if ((Number.parseInt(<string>itemDbDetails._props.armorClass)) > 1) if (Number.parseInt(<string>itemDbDetails._props.armorClass) > 1)
{ {
this.itemHelper.addUpdObjectToItem(armorItem); this.itemHelper.addUpdObjectToItem(armorItem);
const lowestMaxDurability = this.randomUtil.getFloat(maxMultiplier, 1) const lowestMaxDurability = this.randomUtil.getFloat(maxMultiplier, 1)
* itemDbDetails._props.MaxDurability; * itemDbDetails._props.MaxDurability;
const chosenMaxDurability = Math.round( const chosenMaxDurability = Math.round(
this.randomUtil.getFloat(lowestMaxDurability, itemDbDetails._props.MaxDurability), this.randomUtil.getFloat(lowestMaxDurability, itemDbDetails._props.MaxDurability),
); );
@ -888,9 +887,9 @@ export class RagfairOfferGenerator
const fleaPrices = this.getFleaPricesAsArray(); const fleaPrices = this.getFleaPricesAsArray();
// Filter possible barters to items that match the price range + not itself // Filter possible barters to items that match the price range + not itself
const filtered = fleaPrices.filter((x) => const filtered = fleaPrices.filter(x =>
x.price >= desiredItemCost - offerCostVariance && x.price <= desiredItemCost + offerCostVariance x.price >= desiredItemCost - offerCostVariance && x.price <= desiredItemCost + offerCostVariance
&& x.tpl !== offerItems[0]._tpl && x.tpl !== offerItems[0]._tpl,
); );
// No items on flea have a matching price, fall back to currency // No items on flea have a matching price, fall back to currency
@ -909,7 +908,7 @@ export class RagfairOfferGenerator
* Get an array of flea prices + item tpl, cached in generator class inside `allowedFleaPriceItemsForBarter` * Get an array of flea prices + item tpl, cached in generator class inside `allowedFleaPriceItemsForBarter`
* @returns array with tpl/price values * @returns array with tpl/price values
*/ */
protected getFleaPricesAsArray(): { tpl: string; price: number; }[] protected getFleaPricesAsArray(): { tpl: string, price: number }[]
{ {
// Generate if needed // Generate if needed
if (!this.allowedFleaPriceItemsForBarter) if (!this.allowedFleaPriceItemsForBarter)
@ -918,10 +917,10 @@ export class RagfairOfferGenerator
const fleaArray = Object.entries(fleaPrices).map(([tpl, price]) => ({ tpl: tpl, price: price })); const fleaArray = Object.entries(fleaPrices).map(([tpl, price]) => ({ tpl: tpl, price: price }));
// Only get item prices for items that also exist in items.json // Only get item prices for items that also exist in items.json
const filteredItems = fleaArray.filter((x) => this.itemHelper.getItem(x.tpl)[0]); const filteredItems = fleaArray.filter(x => this.itemHelper.getItem(x.tpl)[0]);
this.allowedFleaPriceItemsForBarter = filteredItems.filter((x) => this.allowedFleaPriceItemsForBarter = filteredItems.filter(x =>
!this.itemHelper.isOfBaseclasses(x.tpl, this.ragfairConfig.dynamic.barter.itemTypeBlacklist) !this.itemHelper.isOfBaseclasses(x.tpl, this.ragfairConfig.dynamic.barter.itemTypeBlacklist),
); );
} }
@ -943,7 +942,7 @@ export class RagfairOfferGenerator
{ {
const currency = this.ragfairServerHelper.getDynamicOfferCurrency(); const currency = this.ragfairServerHelper.getDynamicOfferCurrency();
const price = this.ragfairPriceService.getDynamicOfferPriceForOffer(offerWithChildren, currency, isPackOffer) const price = this.ragfairPriceService.getDynamicOfferPriceForOffer(offerWithChildren, currency, isPackOffer)
* multipler; * multipler;
return [{ count: price, _tpl: currency }]; return [{ count: price, _tpl: currency }];
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { RepeatableQuestRewardGenerator } from "@spt-aki/generators/RepeatableQuestRewardGenerator"; import { RepeatableQuestRewardGenerator } from "@spt-aki/generators/RepeatableQuestRewardGenerator";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { RepeatableQuestHelper } from "@spt-aki/helpers/RepeatableQuestHelper"; import { RepeatableQuestHelper } from "@spt-aki/helpers/RepeatableQuestHelper";
@ -42,7 +41,7 @@ export class RepeatableQuestGenerator
@inject("ObjectId") protected objectId: ObjectId, @inject("ObjectId") protected objectId: ObjectId,
@inject("RepeatableQuestHelper") protected repeatableQuestHelper: RepeatableQuestHelper, @inject("RepeatableQuestHelper") protected repeatableQuestHelper: RepeatableQuestHelper,
@inject("RepeatableQuestRewardGenerator") protected repeatableQuestRewardGenerator: @inject("RepeatableQuestRewardGenerator") protected repeatableQuestRewardGenerator:
RepeatableQuestRewardGenerator, RepeatableQuestRewardGenerator,
@inject("ConfigServer") protected configServer: ConfigServer, @inject("ConfigServer") protected configServer: ConfigServer,
) )
{ {
@ -68,11 +67,11 @@ export class RepeatableQuestGenerator
const questType = this.randomUtil.drawRandomFromList<string>(questTypePool.types)[0]; const questType = this.randomUtil.drawRandomFromList<string>(questTypePool.types)[0];
// get traders from whitelist and filter by quest type availability // get traders from whitelist and filter by quest type availability
let traders = repeatableConfig.traderWhitelist.filter((x) => x.questTypes.includes(questType)).map((x) => let traders = repeatableConfig.traderWhitelist.filter(x => x.questTypes.includes(questType)).map(x =>
x.traderId x.traderId,
); );
// filter out locked traders // filter out locked traders
traders = traders.filter((x) => pmcTraderInfo[x].unlocked); traders = traders.filter(x => pmcTraderInfo[x].unlocked);
const traderId = this.randomUtil.drawRandomFromList(traders)[0]; const traderId = this.randomUtil.drawRandomFromList(traders)[0];
switch (questType) switch (questType)
@ -159,15 +158,15 @@ export class RepeatableQuestGenerator
return Math.sqrt(Math.sqrt(target) + bodyPart + dist + weaponRequirement) * kill; return Math.sqrt(Math.sqrt(target) + bodyPart + dist + weaponRequirement) * kill;
} }
targetsConfig = targetsConfig.filter((x) => targetsConfig = targetsConfig.filter(x =>
Object.keys(questTypePool.pool.Elimination.targets).includes(x.key) Object.keys(questTypePool.pool.Elimination.targets).includes(x.key),
); );
if (targetsConfig.length === 0 || targetsConfig.every((x) => x.data.isBoss)) if (targetsConfig.length === 0 || targetsConfig.every(x => x.data.isBoss))
{ {
// There are no more targets left for elimination; delete it as a possible quest type // There are no more targets left for elimination; delete it as a possible quest type
// also if only bosses are left we need to leave otherwise it's a guaranteed boss elimination // also if only bosses are left we need to leave otherwise it's a guaranteed boss elimination
// -> then it would not be a quest with low probability anymore // -> then it would not be a quest with low probability anymore
questTypePool.types = questTypePool.types.filter((t) => t !== "Elimination"); questTypePool.types = questTypePool.types.filter(t => t !== "Elimination");
return null; return null;
} }
@ -189,12 +188,12 @@ export class RepeatableQuestGenerator
} }
else else
{ {
locations = locations.filter((l) => l !== "any"); locations = locations.filter(l => l !== "any");
if (locations.length > 0) if (locations.length > 0)
{ {
locationKey = this.randomUtil.drawRandomFromList<string>(locations)[0]; locationKey = this.randomUtil.drawRandomFromList<string>(locations)[0];
questTypePool.pool.Elimination.targets[targetKey].locations = locations.filter((l) => questTypePool.pool.Elimination.targets[targetKey].locations = locations.filter(l =>
l !== locationKey l !== locationKey,
); );
if (questTypePool.pool.Elimination.targets[targetKey].locations.length === 0) if (questTypePool.pool.Elimination.targets[targetKey].locations.length === 0)
{ {
@ -239,18 +238,18 @@ export class RepeatableQuestGenerator
if (targetsConfig.data(targetKey).isBoss) if (targetsConfig.data(targetKey).isBoss)
{ {
// Get all boss spawn information // Get all boss spawn information
const bossSpawns = Object.values(this.databaseServer.getTables().locations).filter((x) => const bossSpawns = Object.values(this.databaseServer.getTables().locations).filter(x =>
"base" in x && "Id" in x.base "base" in x && "Id" in x.base,
).map((x) => ({ Id: x.base.Id, BossSpawn: x.base.BossLocationSpawn })); ).map(x => ({ Id: x.base.Id, BossSpawn: x.base.BossLocationSpawn }));
// filter for the current boss to spawn on map // filter for the current boss to spawn on map
const thisBossSpawns = bossSpawns.map((x) => ({ const thisBossSpawns = bossSpawns.map(x => ({
Id: x.Id, Id: x.Id,
BossSpawn: x.BossSpawn.filter((e) => e.BossName === targetKey), BossSpawn: x.BossSpawn.filter(e => e.BossName === targetKey),
})).filter((x) => x.BossSpawn.length > 0); })).filter(x => x.BossSpawn.length > 0);
// remove blacklisted locations // remove blacklisted locations
const allowedSpawns = thisBossSpawns.filter((x) => !eliminationConfig.distLocationBlacklist.includes(x.Id)); const allowedSpawns = thisBossSpawns.filter(x => !eliminationConfig.distLocationBlacklist.includes(x.Id));
// if the boss spawns on nom-blacklisted locations and the current location is allowed we can generate a distance kill requirement // if the boss spawns on nom-blacklisted locations and the current location is allowed we can generate a distance kill requirement
isDistanceRequirementAllowed = isDistanceRequirementAllowed && (allowedSpawns.length > 0); isDistanceRequirementAllowed = isDistanceRequirementAllowed && allowedSpawns.length > 0;
} }
if (eliminationConfig.distProb > Math.random() && isDistanceRequirementAllowed) if (eliminationConfig.distProb > Math.random() && isDistanceRequirementAllowed)
@ -258,7 +257,7 @@ export class RepeatableQuestGenerator
// Random distance with lower values more likely; simple distribution for starters... // Random distance with lower values more likely; simple distribution for starters...
distance = Math.floor( distance = Math.floor(
Math.abs(Math.random() - Math.random()) * (1 + eliminationConfig.maxDist - eliminationConfig.minDist) Math.abs(Math.random() - Math.random()) * (1 + eliminationConfig.maxDist - eliminationConfig.minDist)
+ eliminationConfig.minDist, + eliminationConfig.minDist,
); );
distance = Math.ceil(distance / 5) * 5; distance = Math.ceil(distance / 5) * 5;
distanceDifficulty = maxDistDifficulty * distance / eliminationConfig.maxDist; distanceDifficulty = maxDistDifficulty * distance / eliminationConfig.maxDist;
@ -270,14 +269,14 @@ export class RepeatableQuestGenerator
// Filter out close range weapons from far distance requirement // Filter out close range weapons from far distance requirement
if (distance > 50) if (distance > 50)
{ {
weaponCategoryRequirementConfig = weaponCategoryRequirementConfig.filter((category) => weaponCategoryRequirementConfig = weaponCategoryRequirementConfig.filter(category =>
["Shotgun", "Pistol"].includes(category.key) ["Shotgun", "Pistol"].includes(category.key),
); );
} }
else if (distance < 20) else if (distance < 20)
{ // Filter out far range weapons from close distance requirement { // Filter out far range weapons from close distance requirement
weaponCategoryRequirementConfig = weaponCategoryRequirementConfig.filter((category) => weaponCategoryRequirementConfig = weaponCategoryRequirementConfig.filter(category =>
["MarksmanRifle", "DMR"].includes(category.key) ["MarksmanRifle", "DMR"].includes(category.key),
); );
} }
@ -310,7 +309,7 @@ export class RepeatableQuestGenerator
bodyPartDifficulty / maxBodyPartsDifficulty, bodyPartDifficulty / maxBodyPartsDifficulty,
distanceDifficulty / maxDistDifficulty, distanceDifficulty / maxDistDifficulty,
killDifficulty / maxKillDifficulty, killDifficulty / maxKillDifficulty,
(allowedWeaponsCategory || allowedWeapon) ? 1 : 0, allowedWeaponsCategory || allowedWeapon ? 1 : 0,
); );
// Aforementioned issue makes it a bit crazy since now all easier quests give significantly lower rewards than Completion / Exploration // Aforementioned issue makes it a bit crazy since now all easier quests give significantly lower rewards than Completion / Exploration
@ -498,27 +497,27 @@ export class RepeatableQuestGenerator
this.mathUtil.interp1(pmcLevel, levelsConfig, roublesConfig) * this.randomUtil.getFloat(0.5, 1), this.mathUtil.interp1(pmcLevel, levelsConfig, roublesConfig) * this.randomUtil.getFloat(0.5, 1),
); );
roublesBudget = Math.max(roublesBudget, 5000); roublesBudget = Math.max(roublesBudget, 5000);
let itemSelection = possibleItemsToRetrievePool.filter((x) => let itemSelection = possibleItemsToRetrievePool.filter(x =>
this.itemHelper.getItemPrice(x[0]) < roublesBudget this.itemHelper.getItemPrice(x[0]) < roublesBudget,
); );
// We also have the option to use whitelist and/or blacklist which is defined in repeatableQuests.json as // We also have the option to use whitelist and/or blacklist which is defined in repeatableQuests.json as
// [{"minPlayerLevel": 1, "itemIds": ["id1",...]}, {"minPlayerLevel": 15, "itemIds": ["id3",...]}] // [{"minPlayerLevel": 1, "itemIds": ["id1",...]}, {"minPlayerLevel": 15, "itemIds": ["id3",...]}]
if (repeatableConfig.questConfig.Completion.useWhitelist) if (repeatableConfig.questConfig.Completion.useWhitelist)
{ {
const itemWhitelist = const itemWhitelist
this.databaseServer.getTables().templates.repeatableQuests.data.Completion.itemsWhitelist; = this.databaseServer.getTables().templates.repeatableQuests.data.Completion.itemsWhitelist;
// Filter and concatenate the arrays according to current player level // Filter and concatenate the arrays according to current player level
const itemIdsWhitelisted = itemWhitelist.filter((p) => p.minPlayerLevel <= pmcLevel).reduce( const itemIdsWhitelisted = itemWhitelist.filter(p => p.minPlayerLevel <= pmcLevel).reduce(
(a, p) => a.concat(p.itemIds), (a, p) => a.concat(p.itemIds),
[], [],
); );
itemSelection = itemSelection.filter((x) => itemSelection = itemSelection.filter((x) =>
{ {
// Whitelist can contain item tpls and item base type ids // Whitelist can contain item tpls and item base type ids
return (itemIdsWhitelisted.some((v) => this.itemHelper.isOfBaseclass(x[0], v)) return itemIdsWhitelisted.some(v => this.itemHelper.isOfBaseclass(x[0], v))
|| itemIdsWhitelisted.includes(x[0])); || itemIdsWhitelisted.includes(x[0]);
}); });
// check if items are missing // check if items are missing
// const flatList = itemSelection.reduce((a, il) => a.concat(il[0]), []); // const flatList = itemSelection.reduce((a, il) => a.concat(il[0]), []);
@ -527,19 +526,19 @@ export class RepeatableQuestGenerator
if (repeatableConfig.questConfig.Completion.useBlacklist) if (repeatableConfig.questConfig.Completion.useBlacklist)
{ {
const itemBlacklist = const itemBlacklist
this.databaseServer.getTables().templates.repeatableQuests.data.Completion.itemsBlacklist; = this.databaseServer.getTables().templates.repeatableQuests.data.Completion.itemsBlacklist;
// we filter and concatenate the arrays according to current player level // we filter and concatenate the arrays according to current player level
const itemIdsBlacklisted = itemBlacklist.filter((p) => p.minPlayerLevel <= pmcLevel).reduce( const itemIdsBlacklisted = itemBlacklist.filter(p => p.minPlayerLevel <= pmcLevel).reduce(
(a, p) => a.concat(p.itemIds), (a, p) => a.concat(p.itemIds),
[], [],
); );
itemSelection = itemSelection.filter((x) => itemSelection = itemSelection.filter((x) =>
{ {
return itemIdsBlacklisted.every((v) => !this.itemHelper.isOfBaseclass(x[0], v)) return itemIdsBlacklisted.every(v => !this.itemHelper.isOfBaseclass(x[0], v))
|| !itemIdsBlacklisted.includes(x[0]); || !itemIdsBlacklisted.includes(x[0]);
}); });
} }
@ -602,7 +601,7 @@ export class RepeatableQuestGenerator
if (roublesBudget > 0) if (roublesBudget > 0)
{ {
// reduce the list possible items to fulfill the new budget constraint // reduce the list possible items to fulfill the new budget constraint
itemSelection = itemSelection.filter((x) => this.itemHelper.getItemPrice(x[0]) < roublesBudget); itemSelection = itemSelection.filter(x => this.itemHelper.getItemPrice(x[0]) < roublesBudget);
if (itemSelection.length === 0) if (itemSelection.length === 0)
{ {
break; break;
@ -687,13 +686,13 @@ export class RepeatableQuestGenerator
): IRepeatableQuest ): IRepeatableQuest
{ {
const explorationConfig = repeatableConfig.questConfig.Exploration; const explorationConfig = repeatableConfig.questConfig.Exploration;
const requiresSpecificExtract = const requiresSpecificExtract
Math.random() < repeatableConfig.questConfig.Exploration.specificExits.probability; = Math.random() < repeatableConfig.questConfig.Exploration.specificExits.probability;
if (Object.keys(questTypePool.pool.Exploration.locations).length === 0) if (Object.keys(questTypePool.pool.Exploration.locations).length === 0)
{ {
// there are no more locations left for exploration; delete it as a possible quest type // there are no more locations left for exploration; delete it as a possible quest type
questTypePool.types = questTypePool.types.filter((t) => t !== "Exploration"); questTypePool.types = questTypePool.types.filter(t => t !== "Exploration");
return null; return null;
} }
@ -738,15 +737,13 @@ export class RepeatableQuestGenerator
const mapExits = this.getLocationExitsForSide(locationKey, repeatableConfig.side); const mapExits = this.getLocationExitsForSide(locationKey, repeatableConfig.side);
// Only get exits that have a greater than 0% chance to spawn // Only get exits that have a greater than 0% chance to spawn
const exitPool = mapExits.filter((exit) => exit.Chance > 0); const exitPool = mapExits.filter(exit => exit.Chance > 0);
// Exclude exits with a requirement to leave (e.g. car extracts) // Exclude exits with a requirement to leave (e.g. car extracts)
const possibleExits = exitPool.filter(( const possibleExits = exitPool.filter(exit => !("PassageRequirement" in exit)
exit, || repeatableConfig.questConfig.Exploration.specificExits.passageRequirementWhitelist.includes(
) => (!("PassageRequirement" in exit) exit.PassageRequirement,
|| repeatableConfig.questConfig.Exploration.specificExits.passageRequirementWhitelist.includes( ),
exit.PassageRequirement,
))
); );
if (possibleExits.length === 0) if (possibleExits.length === 0)
@ -791,7 +788,7 @@ export class RepeatableQuestGenerator
const mapExtracts = this.databaseServer.getTables().locations[locationKey.toLocaleLowerCase()] const mapExtracts = this.databaseServer.getTables().locations[locationKey.toLocaleLowerCase()]
.allExtracts as Exit[]; .allExtracts as Exit[];
return mapExtracts.filter((exit) => exit.Side === playerSide); return mapExtracts.filter(exit => exit.Side === playerSide);
} }
protected generatePickupQuest( protected generatePickupQuest(
@ -814,18 +811,18 @@ export class RepeatableQuestGenerator
// const locationKey: string = this.randomUtil.drawRandomFromDict(questTypePool.pool.Pickup.locations)[0]; // const locationKey: string = this.randomUtil.drawRandomFromDict(questTypePool.pool.Pickup.locations)[0];
// const locationTarget = questTypePool.pool.Pickup.locations[locationKey]; // const locationTarget = questTypePool.pool.Pickup.locations[locationKey];
const findCondition = quest.conditions.AvailableForFinish.find((x) => x.conditionType === "FindItem"); const findCondition = quest.conditions.AvailableForFinish.find(x => x.conditionType === "FindItem");
findCondition.target = [itemTypeToFetchWithCount.itemType]; findCondition.target = [itemTypeToFetchWithCount.itemType];
findCondition.value = itemCountToFetch; findCondition.value = itemCountToFetch;
const counterCreatorCondition = quest.conditions.AvailableForFinish.find((x) => const counterCreatorCondition = quest.conditions.AvailableForFinish.find(x =>
x.conditionType === "CounterCreator" x.conditionType === "CounterCreator",
); );
// const locationCondition = counterCreatorCondition._props.counter.conditions.find(x => x._parent === "Location"); // const locationCondition = counterCreatorCondition._props.counter.conditions.find(x => x._parent === "Location");
// (locationCondition._props as ILocationConditionProps).target = [...locationTarget]; // (locationCondition._props as ILocationConditionProps).target = [...locationTarget];
const equipmentCondition = counterCreatorCondition.counter.conditions.find((x) => const equipmentCondition = counterCreatorCondition.counter.conditions.find(x =>
x.conditionType === "Equipment" x.conditionType === "Equipment",
); );
equipmentCondition.equipmentInclusive = [[itemTypeToFetchWithCount.itemType]]; equipmentCondition.equipmentInclusive = [[itemTypeToFetchWithCount.itemType]];

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper"; import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper"; import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
@ -96,20 +95,20 @@ export class RepeatableQuestRewardGenerator
// rewards are generated based on pmcLevel, difficulty and a random spread // rewards are generated based on pmcLevel, difficulty and a random spread
const rewardXP = Math.floor( const rewardXP = Math.floor(
effectiveDifficulty * this.mathUtil.interp1(pmcLevel, levelsConfig, xpConfig) effectiveDifficulty * this.mathUtil.interp1(pmcLevel, levelsConfig, xpConfig)
* this.randomUtil.getFloat(1 - rewardSpreadConfig, 1 + rewardSpreadConfig), * this.randomUtil.getFloat(1 - rewardSpreadConfig, 1 + rewardSpreadConfig),
); );
const rewardRoubles = Math.floor( const rewardRoubles = Math.floor(
effectiveDifficulty * this.mathUtil.interp1(pmcLevel, levelsConfig, roublesConfig) effectiveDifficulty * this.mathUtil.interp1(pmcLevel, levelsConfig, roublesConfig)
* this.randomUtil.getFloat(1 - rewardSpreadConfig, 1 + rewardSpreadConfig), * this.randomUtil.getFloat(1 - rewardSpreadConfig, 1 + rewardSpreadConfig),
); );
const rewardNumItems = this.randomUtil.randInt( const rewardNumItems = this.randomUtil.randInt(
1, 1,
Math.round(this.mathUtil.interp1(pmcLevel, levelsConfig, itemsConfig)) + 1, Math.round(this.mathUtil.interp1(pmcLevel, levelsConfig, itemsConfig)) + 1,
); );
const rewardReputation = const rewardReputation
Math.round( = Math.round(
100 * effectiveDifficulty * this.mathUtil.interp1(pmcLevel, levelsConfig, reputationConfig) 100 * effectiveDifficulty * this.mathUtil.interp1(pmcLevel, levelsConfig, reputationConfig)
* this.randomUtil.getFloat(1 - rewardSpreadConfig, 1 + rewardSpreadConfig), * this.randomUtil.getFloat(1 - rewardSpreadConfig, 1 + rewardSpreadConfig),
) / 100; ) / 100;
const skillRewardChance = this.mathUtil.interp1(pmcLevel, levelsConfig, skillRewardChanceConfig); const skillRewardChance = this.mathUtil.interp1(pmcLevel, levelsConfig, skillRewardChanceConfig);
const skillPointReward = this.mathUtil.interp1(pmcLevel, levelsConfig, skillPointRewardConfig); const skillPointReward = this.mathUtil.interp1(pmcLevel, levelsConfig, skillPointRewardConfig);
@ -135,7 +134,7 @@ export class RepeatableQuestRewardGenerator
this.addMoneyReward(traderId, rewards, rewardRoubles, rewardIndex); this.addMoneyReward(traderId, rewards, rewardRoubles, rewardIndex);
rewardIndex++; rewardIndex++;
const traderWhitelistDetails = repeatableConfig.traderWhitelist.find((x) => x.traderId === traderId); const traderWhitelistDetails = repeatableConfig.traderWhitelist.find(x => x.traderId === traderId);
if ( if (
traderWhitelistDetails.rewardCanBeWeapon traderWhitelistDetails.rewardCanBeWeapon
&& this.randomUtil.getChance100(traderWhitelistDetails.weaponRewardChancePercent) && this.randomUtil.getChance100(traderWhitelistDetails.weaponRewardChancePercent)
@ -151,7 +150,7 @@ export class RepeatableQuestRewardGenerator
while (defaultPresetPool.hasValues()) while (defaultPresetPool.hasValues())
{ {
const randomPreset = defaultPresetPool.getRandomValue(); const randomPreset = defaultPresetPool.getRandomValue();
const tpls = randomPreset._items.map((item) => item._tpl); const tpls = randomPreset._items.map(item => item._tpl);
const presetPrice = this.itemHelper.getItemAndChildrenPrice(tpls); const presetPrice = this.itemHelper.getItemAndChildrenPrice(tpls);
if (presetPrice <= roublesBudget) if (presetPrice <= roublesBudget)
{ {
@ -309,13 +308,13 @@ export class RepeatableQuestRewardGenerator
protected canIncreaseRewardItemStackSize(item: ITemplateItem, maxRoublePriceToStack: number): boolean protected canIncreaseRewardItemStackSize(item: ITemplateItem, maxRoublePriceToStack: number): boolean
{ {
return this.presetHelper.getDefaultPresetOrItemPrice(item._id) < maxRoublePriceToStack return this.presetHelper.getDefaultPresetOrItemPrice(item._id) < maxRoublePriceToStack
&& !this.itemHelper.isOfBaseclasses(item._id, [ && !this.itemHelper.isOfBaseclasses(item._id, [
BaseClasses.WEAPON, BaseClasses.WEAPON,
BaseClasses.ARMORED_EQUIPMENT, BaseClasses.ARMORED_EQUIPMENT,
BaseClasses.AMMO, BaseClasses.AMMO,
]) ])
&& !this.itemHelper.itemRequiresSoftInserts(item._id) && !this.itemHelper.itemRequiresSoftInserts(item._id)
&& this.randomUtil.getChance100(25); && this.randomUtil.getChance100(25);
} }
protected calculateAmmoStackSizeThatFitsBudget( protected calculateAmmoStackSizeThatFitsBudget(
@ -355,7 +354,7 @@ export class RepeatableQuestRewardGenerator
const rewardableItemPool = this.getRewardableItems(repeatableConfig, traderId); const rewardableItemPool = this.getRewardableItems(repeatableConfig, traderId);
const minPrice = Math.min(25000, 0.5 * roublesBudget); const minPrice = Math.min(25000, 0.5 * roublesBudget);
let rewardableItemPoolWithinBudget = rewardableItemPool.map((x) => x[1]); let rewardableItemPoolWithinBudget = rewardableItemPool.map(x => x[1]);
rewardableItemPoolWithinBudget = this.filterRewardPoolWithinBudget( rewardableItemPoolWithinBudget = this.filterRewardPoolWithinBudget(
rewardableItemPoolWithinBudget, rewardableItemPoolWithinBudget,
roublesBudget, roublesBudget,
@ -370,9 +369,9 @@ export class RepeatableQuestRewardGenerator
}), }),
); );
// In case we don't find any items in the price range // In case we don't find any items in the price range
rewardableItemPoolWithinBudget = rewardableItemPool.filter((x) => rewardableItemPoolWithinBudget = rewardableItemPool.filter(x =>
this.itemHelper.getItemPrice(x[0]) < roublesBudget this.itemHelper.getItemPrice(x[0]) < roublesBudget,
).map((x) => x[1]); ).map(x => x[1]);
} }
return rewardableItemPoolWithinBudget; return rewardableItemPoolWithinBudget;
@ -393,7 +392,7 @@ export class RepeatableQuestRewardGenerator
if (preset) if (preset)
{ {
const rootItem = preset.find((x) => x._tpl === tpl); const rootItem = preset.find(x => x._tpl === tpl);
rewardItem.items = this.itemHelper.reparentItemAndChildren(rootItem, preset); rewardItem.items = this.itemHelper.reparentItemAndChildren(rootItem, preset);
rewardItem.target = rootItem._id; // Target property and root items id must match rewardItem.target = rootItem._id; // Target property and root items id must match
} }
@ -436,8 +435,8 @@ export class RepeatableQuestRewardGenerator
return false; return false;
} }
const traderWhitelist = repeatableQuestConfig.traderWhitelist.find((trader) => const traderWhitelist = repeatableQuestConfig.traderWhitelist.find(trader =>
trader.traderId === traderId trader.traderId === traderId,
); );
return this.isValidRewardItem(tpl, repeatableQuestConfig, traderWhitelist?.rewardBaseWhitelist); return this.isValidRewardItem(tpl, repeatableQuestConfig, traderWhitelist?.rewardBaseWhitelist);
}, },

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { PresetHelper } from "@spt-aki/helpers/PresetHelper"; import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
import { Product } from "@spt-aki/models/eft/common/tables/IBotBase"; import { Product } from "@spt-aki/models/eft/common/tables/IBotBase";
@ -61,7 +60,7 @@ export class ScavCaseRewardGenerator
this.cacheDbItems(); this.cacheDbItems();
// Get scavcase details from hideout/scavcase.json // Get scavcase details from hideout/scavcase.json
const scavCaseDetails = this.databaseServer.getTables().hideout.scavcase.find((r) => r._id === recipeId); const scavCaseDetails = this.databaseServer.getTables().hideout.scavcase.find(r => r._id === recipeId);
const rewardItemCounts = this.getScavCaseRewardCountsAndPrices(scavCaseDetails); const rewardItemCounts = this.getScavCaseRewardCountsAndPrices(scavCaseDetails);
// Get items that fit the price criteria as set by the scavCase config // Get items that fit the price criteria as set by the scavCase config
@ -122,7 +121,7 @@ export class ScavCaseRewardGenerator
// Skip item if item id is on blacklist // Skip item if item id is on blacklist
if ( if (
(item._type !== "Item") item._type !== "Item"
|| this.scavCaseConfig.rewardItemBlacklist.includes(item._id) || this.scavCaseConfig.rewardItemBlacklist.includes(item._id)
|| this.itemFilterService.isItemBlacklisted(item._id) || this.itemFilterService.isItemBlacklisted(item._id)
) )

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
import { ContextVariableType } from "@spt-aki/context/ContextVariableType"; import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper";
@ -72,10 +71,10 @@ export class WeatherGenerator
public getInRaidTime(): Date public getInRaidTime(): Date
{ {
// tarkov time = (real time * 7 % 24 hr) + 3 hour // tarkov time = (real time * 7 % 24 hr) + 3 hour
const russiaOffset = (this.timeUtil.getHoursAsSeconds(3)) * 1000; const russiaOffset = this.timeUtil.getHoursAsSeconds(3) * 1000;
return new Date( return new Date(
(russiaOffset + (new Date().getTime() * this.weatherConfig.acceleration)) (russiaOffset + new Date().getTime() * this.weatherConfig.acceleration)
% (this.timeUtil.getHoursAsSeconds(24) * 1000), % (this.timeUtil.getHoursAsSeconds(24) * 1000),
); );
} }
@ -103,7 +102,7 @@ export class WeatherGenerator
wind_direction: this.getWeightedWindDirection(), wind_direction: this.getWeightedWindDirection(),
wind_gustiness: this.getRandomFloat("windGustiness"), wind_gustiness: this.getRandomFloat("windGustiness"),
rain: rain, rain: rain,
rain_intensity: (rain > 1) ? this.getRandomFloat("rainIntensity") : 0, rain_intensity: rain > 1 ? this.getRandomFloat("rainIntensity") : 0,
fog: this.getWeightedFog(), fog: this.getWeightedFog(),
temp: this.getRandomFloat("temp"), temp: this.getRandomFloat("temp"),
pressure: this.getRandomFloat("pressure"), pressure: this.getRandomFloat("pressure"),

View File

@ -2,7 +2,7 @@ import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
export interface IInventoryMagGen export interface IInventoryMagGen
{ {
getPriority(): number; getPriority(): number
canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean; canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean
process(inventoryMagGen: InventoryMagGen): void; process(inventoryMagGen: InventoryMagGen): void
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen"; import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen";
import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen"; import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen";
import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper"; import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
@ -154,15 +153,15 @@ export class ExternalInventoryMagGen implements IInventoryMagGen
): ITemplateItem ): ITemplateItem
{ {
// The mag Slot data for the weapon // The mag Slot data for the weapon
const magSlot = this.itemHelper.getItem(weaponTpl)[1]._props.Slots.find((x) => x._name === "mod_magazine"); const magSlot = this.itemHelper.getItem(weaponTpl)[1]._props.Slots.find(x => x._name === "mod_magazine");
if (!magSlot) if (!magSlot)
{ {
return null; return null;
} }
// All possible mags that fit into the weapon excluding blacklisted // All possible mags that fit into the weapon excluding blacklisted
const magazinePool = magSlot._props.filters[0].Filter.filter((x) => !magazineBlacklist.includes(x)).map((x) => const magazinePool = magSlot._props.filters[0].Filter.filter(x => !magazineBlacklist.includes(x)).map(x =>
this.itemHelper.getItem(x)[1] this.itemHelper.getItem(x)[1],
); );
if (!magazinePool) if (!magazinePool)
{ {
@ -170,7 +169,7 @@ export class ExternalInventoryMagGen implements IInventoryMagGen
} }
// Non-internal magazines that fit into the weapon // Non-internal magazines that fit into the weapon
const externalMagazineOnlyPool = magazinePool.filter((x) => x._props.ReloadMagType !== "InternalMagazine"); const externalMagazineOnlyPool = magazinePool.filter(x => x._props.ReloadMagType !== "InternalMagazine");
if (!externalMagazineOnlyPool || externalMagazineOnlyPool?.length === 0) if (!externalMagazineOnlyPool || externalMagazineOnlyPool?.length === 0)
{ {
return null; return null;

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen"; import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen";
import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen"; import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen";
import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen"; import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper"; import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { QuestHelper } from "@spt-aki/helpers/QuestHelper"; import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData"; import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
@ -77,7 +76,7 @@ export class AssortHelper
protected getQuestIdAndStatusThatShowAssort( protected getQuestIdAndStatusThatShowAssort(
mergedQuestAssorts: Record<string, Record<string, string>>, mergedQuestAssorts: Record<string, Record<string, string>>,
assortId: string, assortId: string,
): { questId: string; status: QuestStatus[]; } ): { questId: string, status: QuestStatus[] }
{ {
if (assortId in mergedQuestAssorts.started) if (assortId in mergedQuestAssorts.started)
{ {

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { BotHelper } from "@spt-aki/helpers/BotHelper"; import { BotHelper } from "@spt-aki/helpers/BotHelper";
import { Difficulty } from "@spt-aki/models/eft/common/tables/IBotType"; import { Difficulty } from "@spt-aki/models/eft/common/tables/IBotType";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes"; import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { ApplicationContext } from "@spt-aki/context/ApplicationContext"; import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
import { ContextVariableType } from "@spt-aki/context/ContextVariableType"; import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
import { ContainerHelper } from "@spt-aki/helpers/ContainerHelper"; import { ContainerHelper } from "@spt-aki/helpers/ContainerHelper";
@ -52,7 +51,7 @@ export class BotGeneratorHelper
* @param botRole Used by weapons to randomize the durability values. Null for non-equipped items * @param botRole Used by weapons to randomize the durability values. Null for non-equipped items
* @returns Item Upd object with extra properties * @returns Item Upd object with extra properties
*/ */
public generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: string): { upd?: Upd; } public generateExtraPropertiesForItem(itemTemplate: ITemplateItem, botRole?: string): { upd?: Upd }
{ {
// Get raid settings, if no raid, default to day // Get raid settings, if no raid, default to day
const raidSettings = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue< const raidSettings = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue<
@ -123,7 +122,7 @@ export class BotGeneratorHelper
? this.getBotEquipmentSettingFromConfig(botRole, "lightIsActiveNightChancePercent", 50) ? this.getBotEquipmentSettingFromConfig(botRole, "lightIsActiveNightChancePercent", 50)
: this.getBotEquipmentSettingFromConfig(botRole, "lightIsActiveDayChancePercent", 25); : this.getBotEquipmentSettingFromConfig(botRole, "lightIsActiveDayChancePercent", 25);
itemProperties.Light = { itemProperties.Light = {
IsActive: (this.randomUtil.getChance100(lightLaserActiveChance)), IsActive: this.randomUtil.getChance100(lightLaserActiveChance),
SelectedMode: 0, SelectedMode: 0,
}; };
} }
@ -136,7 +135,7 @@ export class BotGeneratorHelper
50, 50,
); );
itemProperties.Light = { itemProperties.Light = {
IsActive: (this.randomUtil.getChance100(lightLaserActiveChance)), IsActive: this.randomUtil.getChance100(lightLaserActiveChance),
SelectedMode: 0, SelectedMode: 0,
}; };
} }
@ -147,7 +146,7 @@ export class BotGeneratorHelper
const nvgActiveChance = raidIsNight const nvgActiveChance = raidIsNight
? this.getBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceNightPercent", 90) ? this.getBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceNightPercent", 90)
: this.getBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceDayPercent", 15); : this.getBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceDayPercent", 15);
itemProperties.Togglable = { On: (this.randomUtil.getChance100(nvgActiveChance)) }; itemProperties.Togglable = { On: this.randomUtil.getChance100(nvgActiveChance) };
} }
// Togglable face shield // Togglable face shield
@ -159,7 +158,7 @@ export class BotGeneratorHelper
"faceShieldIsActiveChancePercent", "faceShieldIsActiveChancePercent",
75, 75,
); );
itemProperties.Togglable = { On: (this.randomUtil.getChance100(faceShieldActiveChance)) }; itemProperties.Togglable = { On: this.randomUtil.getChance100(faceShieldActiveChance) };
} }
return Object.keys(itemProperties).length ? { upd: itemProperties } : {}; return Object.keys(itemProperties).length ? { upd: itemProperties } : {};
@ -288,7 +287,7 @@ export class BotGeneratorHelper
): IChooseRandomCompatibleModResult ): IChooseRandomCompatibleModResult
{ {
// TODO: Can probably be optimized to cache itemTemplates as items are added to inventory // TODO: Can probably be optimized to cache itemTemplates as items are added to inventory
const equippedItemsDb = itemsEquipped.map((item) => this.databaseServer.getTables().templates.items[item._tpl]); const equippedItemsDb = itemsEquipped.map(item => this.databaseServer.getTables().templates.items[item._tpl]);
const itemToEquipDb = this.itemHelper.getItem(tplToCheck); const itemToEquipDb = this.itemHelper.getItem(tplToCheck);
const itemToEquip = itemToEquipDb[1]; const itemToEquip = itemToEquipDb[1];
@ -319,7 +318,7 @@ export class BotGeneratorHelper
} }
// Check if any of the current weapon mod templates have the incoming item defined as incompatible // Check if any of the current weapon mod templates have the incoming item defined as incompatible
const blockingItem = equippedItemsDb.find((x) => x._props.ConflictingItems?.includes(tplToCheck)); const blockingItem = equippedItemsDb.find(x => x._props.ConflictingItems?.includes(tplToCheck));
if (blockingItem) if (blockingItem)
{ {
return { return {
@ -332,7 +331,7 @@ export class BotGeneratorHelper
} }
// Check inverse to above, if the incoming item has any existing mods in its conflicting items array // Check inverse to above, if the incoming item has any existing mods in its conflicting items array
const blockingModItem = itemsEquipped.find((item) => itemToEquip._props.ConflictingItems?.includes(item._tpl)); const blockingModItem = itemsEquipped.find(item => itemToEquip._props.ConflictingItems?.includes(item._tpl));
if (blockingModItem) if (blockingModItem)
{ {
return { return {
@ -366,7 +365,7 @@ export class BotGeneratorHelper
} }
// TODO: Can probably be optimized to cache itemTemplates as items are added to inventory // TODO: Can probably be optimized to cache itemTemplates as items are added to inventory
const equippedItemsDb = itemsEquipped.map((i) => this.databaseServer.getTables().templates.items[i._tpl]); const equippedItemsDb = itemsEquipped.map(i => this.databaseServer.getTables().templates.items[i._tpl]);
const itemToEquipDb = this.itemHelper.getItem(tplToCheck); const itemToEquipDb = this.itemHelper.getItem(tplToCheck);
const itemToEquip = itemToEquipDb[1]; const itemToEquip = itemToEquipDb[1];
@ -396,7 +395,7 @@ export class BotGeneratorHelper
} }
// Does an equipped item have a property that blocks the desired item - check for prop "BlocksX" .e.g BlocksEarpiece / BlocksFaceCover // Does an equipped item have a property that blocks the desired item - check for prop "BlocksX" .e.g BlocksEarpiece / BlocksFaceCover
let blockingItem = equippedItemsDb.find((x) => x._props[`Blocks${equipmentSlot}`]); let blockingItem = equippedItemsDb.find(x => x._props[`Blocks${equipmentSlot}`]);
if (blockingItem) if (blockingItem)
{ {
// this.logger.warning(`1 incompatibility found between - ${itemToEquip[1]._name} and ${blockingItem._name} - ${equipmentSlot}`); // this.logger.warning(`1 incompatibility found between - ${itemToEquip[1]._name} and ${blockingItem._name} - ${equipmentSlot}`);
@ -410,7 +409,7 @@ export class BotGeneratorHelper
} }
// Check if any of the current inventory templates have the incoming item defined as incompatible // Check if any of the current inventory templates have the incoming item defined as incompatible
blockingItem = equippedItemsDb.find((x) => x._props.ConflictingItems?.includes(tplToCheck)); blockingItem = equippedItemsDb.find(x => x._props.ConflictingItems?.includes(tplToCheck));
if (blockingItem) if (blockingItem)
{ {
// this.logger.warning(`2 incompatibility found between - ${itemToEquip[1]._name} and ${blockingItem._props.Name} - ${equipmentSlot}`); // this.logger.warning(`2 incompatibility found between - ${itemToEquip[1]._name} and ${blockingItem._props.Name} - ${equipmentSlot}`);
@ -426,7 +425,7 @@ export class BotGeneratorHelper
// Does item being checked get blocked/block existing item // Does item being checked get blocked/block existing item
if (itemToEquip._props.BlocksHeadwear) if (itemToEquip._props.BlocksHeadwear)
{ {
const existingHeadwear = itemsEquipped.find((x) => x.slotId === "Headwear"); const existingHeadwear = itemsEquipped.find(x => x.slotId === "Headwear");
if (existingHeadwear) if (existingHeadwear)
{ {
return { return {
@ -442,7 +441,7 @@ export class BotGeneratorHelper
// Does item being checked get blocked/block existing item // Does item being checked get blocked/block existing item
if (itemToEquip._props.BlocksFaceCover) if (itemToEquip._props.BlocksFaceCover)
{ {
const existingFaceCover = itemsEquipped.find((item) => item.slotId === "FaceCover"); const existingFaceCover = itemsEquipped.find(item => item.slotId === "FaceCover");
if (existingFaceCover) if (existingFaceCover)
{ {
return { return {
@ -458,7 +457,7 @@ export class BotGeneratorHelper
// Does item being checked get blocked/block existing item // Does item being checked get blocked/block existing item
if (itemToEquip._props.BlocksEarpiece) if (itemToEquip._props.BlocksEarpiece)
{ {
const existingEarpiece = itemsEquipped.find((item) => item.slotId === "Earpiece"); const existingEarpiece = itemsEquipped.find(item => item.slotId === "Earpiece");
if (existingEarpiece) if (existingEarpiece)
{ {
return { return {
@ -474,7 +473,7 @@ export class BotGeneratorHelper
// Does item being checked get blocked/block existing item // Does item being checked get blocked/block existing item
if (itemToEquip._props.BlocksArmorVest) if (itemToEquip._props.BlocksArmorVest)
{ {
const existingArmorVest = itemsEquipped.find((item) => item.slotId === "ArmorVest"); const existingArmorVest = itemsEquipped.find(item => item.slotId === "ArmorVest");
if (existingArmorVest) if (existingArmorVest)
{ {
return { return {
@ -488,7 +487,7 @@ export class BotGeneratorHelper
} }
// Check if the incoming item has any inventory items defined as incompatible // Check if the incoming item has any inventory items defined as incompatible
const blockingInventoryItem = itemsEquipped.find((x) => itemToEquip._props.ConflictingItems?.includes(x._tpl)); const blockingInventoryItem = itemsEquipped.find(x => itemToEquip._props.ConflictingItems?.includes(x._tpl));
if (blockingInventoryItem) if (blockingInventoryItem)
{ {
// this.logger.warning(`3 incompatibility found between - ${itemToEquip[1]._name} and ${blockingInventoryItem._tpl} - ${equipmentSlot}`) // this.logger.warning(`3 incompatibility found between - ${itemToEquip[1]._name} and ${blockingInventoryItem._tpl} - ${equipmentSlot}`)
@ -510,9 +509,9 @@ export class BotGeneratorHelper
*/ */
public getBotEquipmentRole(botRole: string): string public getBotEquipmentRole(botRole: string): string
{ {
return ([this.pmcConfig.usecType.toLowerCase(), this.pmcConfig.bearType.toLowerCase()].includes( return [this.pmcConfig.usecType.toLowerCase(), this.pmcConfig.bearType.toLowerCase()].includes(
botRole.toLowerCase(), botRole.toLowerCase(),
)) )
? "pmc" ? "pmc"
: botRole; : botRole;
} }
@ -544,7 +543,7 @@ export class BotGeneratorHelper
continue; continue;
} }
// Get container to put item into // Get container to put item into
const container = inventory.items.find((item) => item.slotId === equipmentSlotId); const container = inventory.items.find(item => item.slotId === equipmentSlotId);
if (!container) if (!container)
{ {
missingContainerCount++; missingContainerCount++;
@ -590,8 +589,8 @@ export class BotGeneratorHelper
{ {
// Grid is empty, skip or item size is bigger than grid // Grid is empty, skip or item size is bigger than grid
if ( if (
(slotGrid._props.cellsH === 0 || slotGrid._props.cellsV === 0) slotGrid._props.cellsH === 0 || slotGrid._props.cellsV === 0
|| (itemSize[0] * itemSize[1] > slotGrid._props.cellsV * slotGrid._props.cellsH) || itemSize[0] * itemSize[1] > slotGrid._props.cellsV * slotGrid._props.cellsH
) )
{ {
continue; continue;
@ -605,12 +604,12 @@ export class BotGeneratorHelper
} }
// Get all root items in found container // Get all root items in found container
const existingContainerItems = inventory.items.filter((item) => const existingContainerItems = inventory.items.filter(item =>
item.parentId === container._id && item.slotId === slotGrid._name item.parentId === container._id && item.slotId === slotGrid._name,
); );
// Get root items in container we can iterate over to find out what space is free // Get root items in container we can iterate over to find out what space is free
const containerItemsToCheck = existingContainerItems.filter((x) => x.slotId === slotGrid._name); const containerItemsToCheck = existingContainerItems.filter(x => x.slotId === slotGrid._name);
for (const item of containerItemsToCheck) for (const item of containerItemsToCheck)
{ {
// Look for children on items, insert into array if found // Look for children on items, insert into array if found
@ -636,7 +635,7 @@ export class BotGeneratorHelper
// Open slot found, add item to inventory // Open slot found, add item to inventory
if (findSlotResult.success) if (findSlotResult.success)
{ {
const parentItem = itemWithChildren.find((i) => i._id === rootItemId); const parentItem = itemWithChildren.find(i => i._id === rootItemId);
// Set items parent to container id // Set items parent to container id
parentItem.parentId = container._id; parentItem.parentId = container._id;
@ -666,7 +665,7 @@ export class BotGeneratorHelper
if (containersIdFull) if (containersIdFull)
{ {
// if the item was a one by one, we know it must be full. Or if the maps cant find a slot for a one by one // if the item was a one by one, we know it must be full. Or if the maps cant find a slot for a one by one
if ((itemSize[0] === 1 && itemSize[1] === 1)) if (itemSize[0] === 1 && itemSize[1] === 1)
{ {
containersIdFull.add(equipmentSlotId); containersIdFull.add(equipmentSlotId);
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { MinMax } from "@spt-aki/models/common/MinMax"; import { MinMax } from "@spt-aki/models/common/MinMax";
import { Difficulty, IBotType } from "@spt-aki/models/eft/common/tables/IBotType"; import { Difficulty, IBotType } from "@spt-aki/models/eft/common/tables/IBotType";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes"; import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
@ -64,12 +63,12 @@ export class BotHelper
*/ */
public isBotPmc(botRole: string): boolean public isBotPmc(botRole: string): boolean
{ {
return (["usec", "bear", "pmc", "sptbear", "sptusec"].includes(botRole?.toLowerCase())); return ["usec", "bear", "pmc", "sptbear", "sptusec"].includes(botRole?.toLowerCase());
} }
public isBotBoss(botRole: string): boolean public isBotBoss(botRole: string): boolean
{ {
return this.botConfig.bosses.some((x) => x.toLowerCase() === botRole?.toLowerCase()); return this.botConfig.bosses.some(x => x.toLowerCase() === botRole?.toLowerCase());
} }
public isBotFollower(botRole: string): boolean public isBotFollower(botRole: string): boolean
@ -186,7 +185,7 @@ export class BotHelper
public rollChanceToBePmc(role: string, botConvertMinMax: MinMax): boolean public rollChanceToBePmc(role: string, botConvertMinMax: MinMax): boolean
{ {
return role.toLowerCase() in this.pmcConfig.convertIntoPmcChance return role.toLowerCase() in this.pmcConfig.convertIntoPmcChance
&& this.randomUtil.getChance100(this.randomUtil.getInt(botConvertMinMax.min, botConvertMinMax.max)); && this.randomUtil.getChance100(this.randomUtil.getInt(botConvertMinMax.min, botConvertMinMax.max));
} }
public botRoleIsPmc(botRole: string): boolean public botRoleIsPmc(botRole: string): boolean
@ -210,7 +209,7 @@ export class BotHelper
return null; return null;
} }
return botEquipConfig.randomisation.find((x) => botLevel >= x.levelRange.min && botLevel <= x.levelRange.max); return botEquipConfig.randomisation.find(x => botLevel >= x.levelRange.min && botLevel <= x.levelRange.max);
} }
/** /**
@ -219,7 +218,7 @@ export class BotHelper
*/ */
public getRandomizedPmcRole(): string public getRandomizedPmcRole(): string
{ {
return (this.randomUtil.getChance100(this.pmcConfig.isUsec)) return this.randomUtil.getChance100(this.pmcConfig.isUsec)
? this.pmcConfig.usecType ? this.pmcConfig.usecType
: this.pmcConfig.bearType; : this.pmcConfig.bearType;
} }
@ -248,6 +247,6 @@ export class BotHelper
*/ */
protected getRandomizedPmcSide(): string protected getRandomizedPmcSide(): string
{ {
return (this.randomUtil.getChance100(this.pmcConfig.isUsec)) ? "Usec" : "Bear"; return this.randomUtil.getChance100(this.pmcConfig.isUsec) ? "Usec" : "Bear";
} }
} }

View File

@ -1,5 +1,4 @@
import { inject, injectable } from "tsyringe"; import { inject, injectable } from "tsyringe";
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper"; import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
import { ItemHelper } from "@spt-aki/helpers/ItemHelper"; import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper"; import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper";
@ -46,7 +45,7 @@ export class BotWeaponGeneratorHelper
{ {
const firstSlotAmmoTpl = magTemplate._props.Cartridges[0]._props.filters[0].Filter[0]; const firstSlotAmmoTpl = magTemplate._props.Cartridges[0]._props.filters[0].Filter[0];
const ammoMaxStackSize = this.itemHelper.getItem(firstSlotAmmoTpl)[1]?._props?.StackMaxSize ?? 1; const ammoMaxStackSize = this.itemHelper.getItem(firstSlotAmmoTpl)[1]?._props?.StackMaxSize ?? 1;
chamberBulletCount = (ammoMaxStackSize === 1) chamberBulletCount = ammoMaxStackSize === 1
? 1 // Rotating grenade launcher ? 1 // Rotating grenade launcher
: magTemplate._props.Slots.length; // Shotguns/revolvers. We count the number of camoras as the _max_count of the magazine is 0 : magTemplate._props.Slots.length; // Shotguns/revolvers. We count the number of camoras as the _max_count of the magazine is 0
} }

View File

@ -35,7 +35,7 @@ export class ContainerHelper
const limitX = containerX - minVolume; const limitX = containerX - minVolume;
// Every x+y slot taken up in container, exit // Every x+y slot taken up in container, exit
if (container2D.every((x) => x.every((y) => y === 1))) if (container2D.every(x => x.every(y => y === 1)))
{ {
return new FindSlotResult(false); return new FindSlotResult(false);
} }
@ -44,7 +44,7 @@ export class ContainerHelper
for (let y = 0; y < limitY; y++) for (let y = 0; y < limitY; y++)
{ {
// Across // Across
if (container2D[y].every((x) => x === 1)) if (container2D[y].every(x => x === 1))
{ {
// Every item in row is full, skip row // Every item in row is full, skip row
continue; continue;

View File

@ -26,7 +26,7 @@ export abstract class AbstractDialogueChatBot implements IDialogueChatBot
public registerChatCommand(chatCommand: IChatCommand | ICommandoCommand): void public registerChatCommand(chatCommand: IChatCommand | ICommandoCommand): void
{ {
if (this.chatCommands.some((cc) => cc.getCommandPrefix() === chatCommand.getCommandPrefix())) if (this.chatCommands.some(cc => cc.getCommandPrefix() === chatCommand.getCommandPrefix()))
{ {
throw new Error( throw new Error(
`The command "${chatCommand.getCommandPrefix()}" attempting to be registered already exists.`, `The command "${chatCommand.getCommandPrefix()}" attempting to be registered already exists.`,
@ -49,7 +49,7 @@ export abstract class AbstractDialogueChatBot implements IDialogueChatBot
const splitCommand = request.text.split(" "); const splitCommand = request.text.split(" ");
const commandos = this.chatCommands.filter((c) => c.getCommandPrefix() === splitCommand[0]); const commandos = this.chatCommands.filter(c => c.getCommandPrefix() === splitCommand[0]);
if (commandos[0]?.getCommands().has(splitCommand[1])) if (commandos[0]?.getCommands().has(splitCommand[1]))
{ {
return commandos[0].handle(splitCommand[1], this.getChatBot(), sessionId, request); return commandos[0].handle(splitCommand[1], this.getChatBot(), sessionId, request);

View File

@ -8,8 +8,8 @@ import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
export type ICommandoCommand = IChatCommand; export type ICommandoCommand = IChatCommand;
export interface IChatCommand export interface IChatCommand
{ {
getCommandPrefix(): string; getCommandPrefix(): string
getCommandHelp(command: string): string; getCommandHelp(command: string): string
getCommands(): Set<string>; getCommands(): Set<string>
handle(command: string, commandHandler: IUserDialogInfo, sessionId: string, request: ISendMessageRequest): string; handle(command: string, commandHandler: IUserDialogInfo, sessionId: string, request: ISendMessageRequest): string
} }

View File

@ -1,3 +1,4 @@
import { inject, injectAll, injectable } from "tsyringe";
import { IChatCommand } from "@spt-aki/helpers/Dialogue/Commando/IChatCommand"; import { IChatCommand } from "@spt-aki/helpers/Dialogue/Commando/IChatCommand";
import { ISptCommand } from "@spt-aki/helpers/Dialogue/Commando/SptCommands/ISptCommand"; import { ISptCommand } from "@spt-aki/helpers/Dialogue/Commando/SptCommands/ISptCommand";
import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest"; import { ISendMessageRequest } from "@spt-aki/models/eft/dialog/ISendMessageRequest";
@ -5,7 +6,6 @@ import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes"; import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig"; import { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig";
import { ConfigServer } from "@spt-aki/servers/ConfigServer"; import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { inject, injectAll, injectable } from "tsyringe";
@injectable() @injectable()
export class SptCommandoCommands implements IChatCommand export class SptCommandoCommands implements IChatCommand
@ -19,17 +19,17 @@ export class SptCommandoCommands implements IChatCommand
// if give command is disabled or commando commands are disabled // if give command is disabled or commando commands are disabled
if ( if (
!(coreConfigs.features?.chatbotFeatures?.commandoFeatures?.giveCommandEnabled !(coreConfigs.features?.chatbotFeatures?.commandoFeatures?.giveCommandEnabled
&& coreConfigs.features?.chatbotFeatures?.commandoEnabled) && coreConfigs.features?.chatbotFeatures?.commandoEnabled)
) )
{ {
const giveCommand = this.sptCommands.find((c) => c.getCommand().toLocaleLowerCase() === "give"); const giveCommand = this.sptCommands.find(c => c.getCommand().toLocaleLowerCase() === "give");
this.sptCommands.splice(this.sptCommands.indexOf(giveCommand), 1); this.sptCommands.splice(this.sptCommands.indexOf(giveCommand), 1);
} }
} }
public registerSptCommandoCommand(command: ISptCommand): void public registerSptCommandoCommand(command: ISptCommand): void
{ {
if (this.sptCommands.some((c) => c.getCommand() === command.getCommand())) if (this.sptCommands.some(c => c.getCommand() === command.getCommand()))
{ {
throw new Error(`The command "${command.getCommand()}" attempting to be registered already exists.`); throw new Error(`The command "${command.getCommand()}" attempting to be registered already exists.`);
} }
@ -38,7 +38,7 @@ export class SptCommandoCommands implements IChatCommand
public getCommandHelp(command: string): string public getCommandHelp(command: string): string
{ {
return this.sptCommands.find((c) => c.getCommand() === command)?.getCommandHelp(); return this.sptCommands.find(c => c.getCommand() === command)?.getCommandHelp();
} }
public getCommandPrefix(): string public getCommandPrefix(): string
@ -48,7 +48,7 @@ export class SptCommandoCommands implements IChatCommand
public getCommands(): Set<string> public getCommands(): Set<string>
{ {
return new Set(this.sptCommands.map((c) => c.getCommand())); return new Set(this.sptCommands.map(c => c.getCommand()));
} }
public handle( public handle(
@ -58,7 +58,7 @@ export class SptCommandoCommands implements IChatCommand
request: ISendMessageRequest, request: ISendMessageRequest,
): string ): string
{ {
return this.sptCommands.find((c) => c.getCommand() === command).performAction( return this.sptCommands.find(c => c.getCommand() === command).performAction(
commandHandler, commandHandler,
sessionId, sessionId,
request, request,

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