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:
parent
45bf159bb8
commit
50c7a26a58
@ -1,5 +1,4 @@
|
||||
import readline from "node:readline";
|
||||
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
import { AsyncQueue } from "@spt-aki/utils/AsyncQueue";
|
||||
import { WinstonMainLogger } from "@spt-aki/utils/logging/WinstonMainLogger";
|
||||
@ -24,7 +23,7 @@ export class ErrorHandler
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { container } from "tsyringe";
|
||||
|
||||
import { ErrorHandler } from "@spt-aki/ErrorHandler";
|
||||
import { Container } from "@spt-aki/di/Container";
|
||||
import { ErrorHandler } from "@spt-aki/ErrorHandler";
|
||||
import type { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";
|
||||
import { App } from "@spt-aki/utils/App";
|
||||
import { Watermark } from "@spt-aki/utils/Watermark";
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import { AchievementController } from "@spt-aki/controllers/AchievementController";
|
||||
import { ProfileController } from "@spt-aki/controllers/ProfileController";
|
||||
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 { IGetAchievementsResponse } from "@spt-aki/models/eft/profile/IGetAchievementsResponse";
|
||||
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
@injectable()
|
||||
export class AchievementCallbacks
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { BotController } from "@spt-aki/controllers/BotController";
|
||||
import { IGenerateBotsRequestData } from "@spt-aki/models/eft/bot/IGenerateBotsRequestData";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import { BuildController } from "@spt-aki/controllers/BuildController";
|
||||
import { ISetMagazineRequest } from "@spt-aki/models/eft/builds/ISetMagazineRequest";
|
||||
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 { IUserBuilds } from "@spt-aki/models/eft/profile/IAkiProfile";
|
||||
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
@injectable()
|
||||
export class BuildsCallbacks
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { BundleLoader } from "@spt-aki/loaders/BundleLoader";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
import { IHttpConfig } from "@spt-aki/models/spt/config/IHttpConfig";
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import { ClientLogController } from "@spt-aki/controllers/ClientLogController";
|
||||
import { ModLoadOrder } from "@spt-aki/loaders/ModLoadOrder";
|
||||
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 { LocalisationService } from "@spt-aki/services/LocalisationService";
|
||||
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
/** Handle client logging related events */
|
||||
@injectable()
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { CustomizationController } from "@spt-aki/controllers/CustomizationController";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { HideoutController } from "@spt-aki/controllers/HideoutController";
|
||||
import { RagfairController } from "@spt-aki/controllers/RagfairController";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { DialogueController } from "@spt-aki/controllers/DialogueController";
|
||||
import { OnUpdate } from "@spt-aki/di/OnUpdate";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { GameController } from "@spt-aki/controllers/GameController";
|
||||
import { OnLoad } from "@spt-aki/di/OnLoad";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { HandbookController } from "@spt-aki/controllers/HandbookController";
|
||||
import { OnLoad } from "@spt-aki/di/OnLoad";
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { HealthController } from "@spt-aki/controllers/HealthController";
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { HideoutController } from "@spt-aki/controllers/HideoutController";
|
||||
import { OnUpdate } from "@spt-aki/di/OnUpdate";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { OnLoad } from "@spt-aki/di/OnLoad";
|
||||
import { HttpServer } from "@spt-aki/servers/HttpServer";
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { InraidController } from "@spt-aki/controllers/InraidController";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
import { INullResponseData } from "@spt-aki/models/eft/httpResponse/INullResponseData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { InsuranceController } from "@spt-aki/controllers/InsuranceController";
|
||||
import { OnUpdate } from "@spt-aki/di/OnUpdate";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { InventoryController } from "@spt-aki/controllers/InventoryController";
|
||||
import { QuestController } from "@spt-aki/controllers/QuestController";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { IGetBodyResponseData } from "@spt-aki/models/eft/httpResponse/IGetBodyResponseData";
|
||||
import { Warning } from "@spt-aki/models/eft/itemEvent/IItemEventRouterBase";
|
||||
import { IItemEventRouterRequest } from "@spt-aki/models/eft/itemEvent/IItemEventRouterRequest";
|
||||
@ -24,7 +23,7 @@ export class ItemEventCallbacks
|
||||
): IGetBodyResponseData<IItemEventRouterResponse>
|
||||
{
|
||||
const eventResponse = this.itemEventRouter.handleEvents(info, sessionID);
|
||||
const result = (this.isCriticalError(eventResponse.warnings))
|
||||
const result = this.isCriticalError(eventResponse.warnings)
|
||||
? this.httpResponse.getBody(
|
||||
eventResponse,
|
||||
this.getErrorCode(eventResponse.warnings),
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { LauncherController } from "@spt-aki/controllers/LauncherController";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
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
|
||||
{
|
||||
const output = this.launcherController.login(info);
|
||||
return (!output) ? "FAILED" : output;
|
||||
return !output ? "FAILED" : output;
|
||||
}
|
||||
|
||||
public register(url: string, info: IRegisterData, sessionID: string): "FAILED" | "OK"
|
||||
{
|
||||
const output = this.launcherController.register(info);
|
||||
return (!output) ? "FAILED" : "OK";
|
||||
return !output ? "FAILED" : "OK";
|
||||
}
|
||||
|
||||
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"
|
||||
{
|
||||
const output = this.launcherController.changeUsername(info);
|
||||
return (!output) ? "FAILED" : "OK";
|
||||
return !output ? "FAILED" : "OK";
|
||||
}
|
||||
|
||||
public changePassword(url: string, info: IChangeRequestData, sessionID: string): "FAILED" | "OK"
|
||||
{
|
||||
const output = this.launcherController.changePassword(info);
|
||||
return (!output) ? "FAILED" : "OK";
|
||||
return !output ? "FAILED" : "OK";
|
||||
}
|
||||
|
||||
public wipe(url: string, info: IRegisterData, sessionID: string): "FAILED" | "OK"
|
||||
{
|
||||
const output = this.launcherController.wipe(info);
|
||||
return (!output) ? "FAILED" : "OK";
|
||||
return !output ? "FAILED" : "OK";
|
||||
}
|
||||
|
||||
public getServerVersion(): string
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { LocationController } from "@spt-aki/controllers/LocationController";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
import { ILocationBase } from "@spt-aki/models/eft/common/ILocationBase";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { MatchController } from "@spt-aki/controllers/MatchController";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
@ -112,6 +111,7 @@ export class MatchCallbacks
|
||||
{
|
||||
return this.httpResponse.getBody(true);
|
||||
}
|
||||
|
||||
/** Handle client/match/group/transfer */
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public transferGroup(url: string, info: ITransferGroupRequest, sessionID: string): IGetBodyResponseData<boolean>
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { OnLoad } from "@spt-aki/di/OnLoad";
|
||||
import { PostAkiModLoader } from "@spt-aki/loaders/PostAkiModLoader";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { NoteController } from "@spt-aki/controllers/NoteController";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { NotifierController } from "@spt-aki/controllers/NotifierController";
|
||||
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
|
||||
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.
|
||||
*/
|
||||
this.notifierController.notifyAsync(tmpSessionID).then((messages: any) =>
|
||||
messages.map((message: any) => this.jsonUtil.serialize(message)).join("\n")
|
||||
).then((text) => this.httpServerHelper.sendTextJson(resp, text));
|
||||
messages.map((message: any) => this.jsonUtil.serialize(message)).join("\n"),
|
||||
).then(text => this.httpServerHelper.sendTextJson(resp, text));
|
||||
}
|
||||
|
||||
/** Handle push/notifier/get */
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { PresetController } from "@spt-aki/controllers/PresetController";
|
||||
import { OnLoad } from "@spt-aki/di/OnLoad";
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ProfileController } from "@spt-aki/controllers/ProfileController";
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { QuestController } from "@spt-aki/controllers/QuestController";
|
||||
import { RepeatableQuestController } from "@spt-aki/controllers/RepeatableQuestController";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { RagfairController } from "@spt-aki/controllers/RagfairController";
|
||||
import { OnLoad } from "@spt-aki/di/OnLoad";
|
||||
import { OnUpdate } from "@spt-aki/di/OnUpdate";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { RepairController } from "@spt-aki/controllers/RepairController";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { OnLoad } from "@spt-aki/di/OnLoad";
|
||||
import { OnUpdate } from "@spt-aki/di/OnUpdate";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { TradeController } from "@spt-aki/controllers/TradeController";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { TraderController } from "@spt-aki/controllers/TraderController";
|
||||
import { OnLoad } from "@spt-aki/di/OnLoad";
|
||||
import { OnUpdate } from "@spt-aki/di/OnUpdate";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { WeatherController } from "@spt-aki/controllers/WeatherController";
|
||||
import { IEmptyRequestData } from "@spt-aki/models/eft/common/IEmptyRequestData";
|
||||
import { IGetBodyResponseData } from "@spt-aki/models/eft/httpResponse/IGetBodyResponseData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { WishlistController } from "@spt-aki/controllers/WishlistController";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { injectable } from "tsyringe";
|
||||
|
||||
import { ContextVariable } from "@spt-aki/context/ContextVariable";
|
||||
import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
|
||||
import { LinkedList } from "@spt-aki/utils/collections/lists/LinkedList";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ICompletedAchievementsResponse } from "@spt-aki/models/eft/profile/ICompletedAchievementsResponse";
|
||||
import { IGetAchievementsResponse } from "@spt-aki/models/eft/profile/IGetAchievementsResponse";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
|
||||
import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
|
||||
import { BotGenerator } from "@spt-aki/generators/BotGenerator";
|
||||
@ -61,7 +60,7 @@ export class BotController
|
||||
*/
|
||||
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)
|
||||
{
|
||||
@ -147,7 +146,7 @@ export class BotController
|
||||
const result = {};
|
||||
|
||||
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)
|
||||
{
|
||||
const enumType = botType.toLowerCase();
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { ISetMagazineRequest } from "@spt-aki/models/eft/builds/ISetMagazineRequest";
|
||||
@ -43,11 +42,11 @@ export class BuildController
|
||||
const defaultEquipmentPresetsClone = this.jsonUtil.clone(
|
||||
this.databaseServer.getTables().templates.defaultEquipmentPresets,
|
||||
);
|
||||
const playerSecureContainer = profile.characters.pmc.Inventory.items?.find((x) =>
|
||||
x.slotId === secureContainerSlotId
|
||||
const playerSecureContainer = profile.characters.pmc.Inventory.items?.find(x =>
|
||||
x.slotId === secureContainerSlotId,
|
||||
);
|
||||
const firstDefaultItemsSecureContainer = defaultEquipmentPresetsClone[0]?.Items?.find((x) =>
|
||||
x.slotId === secureContainerSlotId
|
||||
const firstDefaultItemsSecureContainer = defaultEquipmentPresetsClone[0]?.Items?.find(x =>
|
||||
x.slotId === secureContainerSlotId,
|
||||
);
|
||||
if (playerSecureContainer && playerSecureContainer?._tpl !== firstDefaultItemsSecureContainer?._tpl)
|
||||
{
|
||||
@ -55,7 +54,7 @@ export class BuildController
|
||||
for (const defaultPreset of defaultEquipmentPresetsClone)
|
||||
{
|
||||
// Find presets secure container
|
||||
const secureContainer = defaultPreset.Items.find((item) => item.slotId === secureContainerSlotId);
|
||||
const secureContainer = defaultPreset.Items.find(item => item.slotId === secureContainerSlotId);
|
||||
if (secureContainer)
|
||||
{
|
||||
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 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)
|
||||
{
|
||||
// exists, replace
|
||||
@ -107,8 +106,8 @@ export class BuildController
|
||||
const buildType = "equipmentBuilds";
|
||||
const pmcData = this.profileHelper.getPmcProfile(sessionID);
|
||||
|
||||
const existingSavedEquipmentBuilds: IEquipmentBuild[] =
|
||||
this.saveServer.getProfile(sessionID).userbuilds[buildType];
|
||||
const existingSavedEquipmentBuilds: IEquipmentBuild[] = this.saveServer.getProfile(sessionID)
|
||||
.userbuilds[buildType];
|
||||
|
||||
// Replace duplicate ID's. The first item is the base item.
|
||||
// Root ID and the base item ID need to match.
|
||||
@ -122,8 +121,8 @@ export class BuildController
|
||||
Items: request.Items,
|
||||
};
|
||||
|
||||
const existingBuild = existingSavedEquipmentBuilds.find((build) =>
|
||||
build.Name === request.Name || build.Id === request.Id
|
||||
const existingBuild = existingSavedEquipmentBuilds.find(build =>
|
||||
build.Name === request.Name || build.Id === request.Id,
|
||||
);
|
||||
if (existingBuild)
|
||||
{
|
||||
@ -141,7 +140,7 @@ export class BuildController
|
||||
}
|
||||
}
|
||||
|
||||
/** Handle client/builds/delete*/
|
||||
/** Handle client/builds/delete */
|
||||
public removeBuild(sessionID: string, request: IRemoveBuildRequestData): void
|
||||
{
|
||||
this.removePlayerBuild(request.id, sessionID);
|
||||
@ -155,7 +154,7 @@ export class BuildController
|
||||
const magazineBuilds = profile.userbuilds.magazineBuilds;
|
||||
|
||||
// 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)
|
||||
{
|
||||
weaponBuilds.splice(weaponBuilds.indexOf(matchingWeaponBuild), 1);
|
||||
@ -164,7 +163,7 @@ export class BuildController
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
equipmentBuilds.splice(equipmentBuilds.indexOf(matchingEquipmentBuild), 1);
|
||||
@ -173,7 +172,7 @@ export class BuildController
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
magazineBuilds.splice(magazineBuilds.indexOf(matchingMagazineBuild), 1);
|
||||
@ -208,7 +207,7 @@ export class BuildController
|
||||
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)
|
||||
{
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
import { IClientLogRequest } from "@spt-aki/models/spt/logging/IClientLogRequest";
|
||||
import { LogBackgroundColor } from "@spt-aki/models/spt/logging/LogBackgroundColor";
|
||||
import { LogLevel } from "@spt-aki/models/spt/logging/LogLevel";
|
||||
import { LogTextColor } from "@spt-aki/models/spt/logging/LogTextColor";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
@injectable()
|
||||
export class ClientLogController
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
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;
|
||||
|
||||
// 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 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
|
||||
{
|
||||
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,
|
||||
): 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)
|
||||
{
|
||||
this.logger.error(
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectAll, injectable } from "tsyringe";
|
||||
|
||||
import { IDialogueChatBot } from "@spt-aki/helpers/Dialogue/IDialogueChatBot";
|
||||
import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper";
|
||||
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 (!coreConfigs.features?.chatbotFeatures?.commandoEnabled)
|
||||
{
|
||||
const sptCommando = this.dialogueChatBots.find((c) =>
|
||||
c.getChatBot()._id.toLocaleLowerCase() === "sptcommando"
|
||||
const sptCommando = this.dialogueChatBots.find(c =>
|
||||
c.getChatBot()._id.toLocaleLowerCase() === "sptcommando",
|
||||
);
|
||||
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptCommando), 1);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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!`);
|
||||
}
|
||||
@ -73,7 +72,7 @@ export class DialogueController
|
||||
public getFriendList(sessionID: string): IGetFriendListDataResponse
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the users involved in a dialog (player + other party)
|
||||
* @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
|
||||
if (
|
||||
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)
|
||||
@ -207,7 +207,7 @@ export class DialogueController
|
||||
if (request.type === MessageType.USER_MESSAGE)
|
||||
{
|
||||
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)
|
||||
{
|
||||
profile.dialogues[request.dialogId].Users.push(chatBot.getChatBot());
|
||||
@ -217,6 +217,7 @@ export class DialogueController
|
||||
|
||||
return profile.dialogues[request.dialogId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the users involved in a mail between two entities
|
||||
* @param fullProfile Player profile
|
||||
@ -230,7 +231,7 @@ export class DialogueController
|
||||
{
|
||||
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
|
||||
const pmcProfile = fullProfile.characters.pmc;
|
||||
@ -278,7 +279,7 @@ export class DialogueController
|
||||
*/
|
||||
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);
|
||||
|
||||
return this.dialogueChatBots.find((cb) => cb.getChatBot()._id === request.dialogId)?.handleMessage(
|
||||
return this.dialogueChatBots.find(cb => cb.getChatBot()._id === request.dialogId)?.handleMessage(
|
||||
sessionId,
|
||||
request,
|
||||
) ?? request.dialogId;
|
||||
@ -391,7 +392,7 @@ export class DialogueController
|
||||
{
|
||||
const timeNow = this.timeUtil.getTimestamp();
|
||||
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[]
|
||||
{
|
||||
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
|
||||
{
|
||||
return (this.timeUtil.getTimestamp()) > (message.dt + message.maxStorageTime);
|
||||
return this.timeUtil.getTimestamp() > message.dt + message.maxStorageTime;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
|
||||
import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
|
||||
import { HideoutHelper } from "@spt-aki/helpers/HideoutHelper";
|
||||
@ -358,8 +357,8 @@ export class GameController
|
||||
for (const positionToAdd of positionsToAdd)
|
||||
{
|
||||
// Exists already, add new items to existing positions pool
|
||||
const existingLootPosition = mapLooseLoot.spawnpoints.find((x) =>
|
||||
x.template.Id === positionToAdd.template.Id
|
||||
const existingLootPosition = mapLooseLoot.spawnpoints.find(x =>
|
||||
x.template.Id === positionToAdd.template.Id,
|
||||
);
|
||||
if (existingLootPosition)
|
||||
{
|
||||
@ -389,7 +388,7 @@ export class GameController
|
||||
const mapLootAdjustmentsDict = adjustments[mapId];
|
||||
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)
|
||||
{
|
||||
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])
|
||||
{
|
||||
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)
|
||||
{
|
||||
// Existing bot type found in MinMaxBots array, edit
|
||||
@ -450,9 +449,9 @@ export class GameController
|
||||
public getGameConfig(sessionID: string): IGameConfigResponse
|
||||
{
|
||||
const profile = this.profileHelper.getPmcProfile(sessionID);
|
||||
const gameTime =
|
||||
profile.Stats?.Eft.OverallCounters.Items?.find((counter) =>
|
||||
counter.Key.includes("LifeTime") && counter.Key.includes("Pmc")
|
||||
const gameTime
|
||||
= profile.Stats?.Eft.OverallCounters.Items?.find(counter =>
|
||||
counter.Key.includes("LifeTime") && counter.Key.includes("Pmc"),
|
||||
)?.Value ?? 0;
|
||||
|
||||
const config: IGameConfigResponse = {
|
||||
@ -589,12 +588,12 @@ export class GameController
|
||||
let hpRegenPerHour = 456.6;
|
||||
|
||||
// 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);
|
||||
hydrationRegenPerHour += pmcProfile.Bonuses.filter((bonus) =>
|
||||
bonus.type === BonusType.HYDRATION_REGENERATION
|
||||
hydrationRegenPerHour += pmcProfile.Bonuses.filter(bonus =>
|
||||
bonus.type === BonusType.HYDRATION_REGENERATION,
|
||||
).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,
|
||||
0,
|
||||
);
|
||||
@ -691,7 +690,7 @@ export class GameController
|
||||
|
||||
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(
|
||||
`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();
|
||||
|
||||
// One day post-profile creation
|
||||
if (currentTimeStamp > (timeStampProfileCreated + oneDaySeconds))
|
||||
if (currentTimeStamp > timeStampProfileCreated + oneDaySeconds)
|
||||
{
|
||||
this.giftService.sendPraporStartingGift(pmcProfile.sessionId, 1);
|
||||
}
|
||||
|
||||
// Two day post-profile creation
|
||||
if (currentTimeStamp > (timeStampProfileCreated + (oneDaySeconds * 2)))
|
||||
if (currentTimeStamp > timeStampProfileCreated + oneDaySeconds * 2)
|
||||
{
|
||||
this.giftService.sendPraporStartingGift(pmcProfile.sessionId, 2);
|
||||
}
|
||||
@ -761,7 +760,7 @@ export class GameController
|
||||
// Wave has size that makes it candidate for splitting
|
||||
if (
|
||||
wave.slots_max - wave.slots_min
|
||||
>= this.locationConfig.splitWaveIntoSingleSpawnsSettings.waveSizeThreshold
|
||||
>= this.locationConfig.splitWaveIntoSingleSpawnsSettings.waveSizeThreshold
|
||||
)
|
||||
{
|
||||
// Get count of bots to be spawned in wave
|
||||
@ -832,8 +831,8 @@ export class GameController
|
||||
{
|
||||
const modDetails = activeMods[modKey];
|
||||
if (
|
||||
fullProfile.aki.mods.some((x) =>
|
||||
x.author === modDetails.author && x.name === modDetails.name && x.version === modDetails.version
|
||||
fullProfile.aki.mods.some(x =>
|
||||
x.author === modDetails.author && x.name === modDetails.name && x.version === modDetails.version,
|
||||
)
|
||||
)
|
||||
{
|
||||
@ -948,8 +947,8 @@ export class GameController
|
||||
protected adjustLabsRaiderSpawnRate(): void
|
||||
{
|
||||
const labsBase = this.databaseServer.getTables().locations.laboratory.base;
|
||||
const nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.filter((x) =>
|
||||
x.TriggerId === "" && x.TriggerName === ""
|
||||
const nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.filter(x =>
|
||||
x.TriggerId === "" && x.TriggerName === "",
|
||||
);
|
||||
if (nonTriggerLabsBossSpawns)
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
|
||||
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { HealthHelper } from "@spt-aki/helpers/HealthHelper";
|
||||
import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
@ -66,7 +65,7 @@ export class HealthController
|
||||
const output = this.eventOutputHolder.getOutput(sessionID);
|
||||
|
||||
// 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)
|
||||
{
|
||||
const errorMessage = this.localisationService.getText(
|
||||
@ -114,7 +113,7 @@ export class HealthController
|
||||
const output = this.eventOutputHolder.getOutput(sessionID);
|
||||
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)
|
||||
{
|
||||
// Item not found, very bad
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ScavCaseRewardGenerator } from "@spt-aki/generators/ScavCaseRewardGenerator";
|
||||
import { HideoutHelper } from "@spt-aki/helpers/HideoutHelper";
|
||||
import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
|
||||
@ -106,7 +105,7 @@ export class HideoutController
|
||||
{
|
||||
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 };
|
||||
});
|
||||
|
||||
@ -139,7 +138,7 @@ export class HideoutController
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType));
|
||||
@ -148,8 +147,8 @@ export class HideoutController
|
||||
return;
|
||||
}
|
||||
|
||||
const hideoutDataDb = this.databaseServer.getTables().hideout.areas.find((area) =>
|
||||
area.type === request.areaType
|
||||
const hideoutDataDb = this.databaseServer.getTables().hideout.areas.find(area =>
|
||||
area.type === request.areaType,
|
||||
);
|
||||
if (!hideoutDataDb)
|
||||
{
|
||||
@ -192,7 +191,7 @@ export class HideoutController
|
||||
{
|
||||
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)
|
||||
{
|
||||
this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType));
|
||||
@ -206,7 +205,7 @@ export class HideoutController
|
||||
profileHideoutArea.completeTime = 0;
|
||||
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)
|
||||
{
|
||||
this.logger.error(
|
||||
@ -264,11 +263,11 @@ export class HideoutController
|
||||
*/
|
||||
protected checkAndUpgradeWall(pmcData: IPmcData): void
|
||||
{
|
||||
const medStation = pmcData.Hideout.Areas.find((area) => area.type === HideoutAreas.MEDSTATION);
|
||||
const waterCollector = pmcData.Hideout.Areas.find((area) => area.type === HideoutAreas.WATER_COLLECTOR);
|
||||
const medStation = pmcData.Hideout.Areas.find(area => area.type === HideoutAreas.MEDSTATION);
|
||||
const waterCollector = pmcData.Hideout.Areas.find(area => area.type === HideoutAreas.WATER_COLLECTOR);
|
||||
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)
|
||||
{
|
||||
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
|
||||
const childDbArea = this.databaseServer.getTables().hideout.areas.find((x) =>
|
||||
x.parentArea === dbHideoutArea._id
|
||||
const childDbArea = this.databaseServer.getTables().hideout.areas.find(x =>
|
||||
x.parentArea === dbHideoutArea._id,
|
||||
);
|
||||
if (childDbArea)
|
||||
{
|
||||
@ -322,8 +321,8 @@ export class HideoutController
|
||||
}
|
||||
|
||||
// Set child area level to same as parent area
|
||||
pmcData.Hideout.Areas.find((x) => x.type === childDbArea.type).level = pmcData.Hideout.Areas.find((x) =>
|
||||
x.type === profileParentHideoutArea.type
|
||||
pmcData.Hideout.Areas.find(x => x.type === childDbArea.type).level = pmcData.Hideout.Areas.find(x =>
|
||||
x.type === profileParentHideoutArea.type,
|
||||
).level;
|
||||
|
||||
// Add/upgrade stash item in player inventory
|
||||
@ -343,7 +342,7 @@ export class HideoutController
|
||||
*/
|
||||
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)
|
||||
{
|
||||
// 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 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] };
|
||||
});
|
||||
|
||||
const hideoutArea = pmcData.Hideout.Areas.find((area) => area.type === addItemToHideoutRequest.areaType);
|
||||
const hideoutArea = pmcData.Hideout.Areas.find(area => area.type === addItemToHideoutRequest.areaType);
|
||||
if (!hideoutArea)
|
||||
{
|
||||
this.logger.error(
|
||||
@ -431,7 +430,7 @@ export class HideoutController
|
||||
|
||||
// Add item to area.slots
|
||||
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 = [{
|
||||
_id: item.inventoryItem._id,
|
||||
_tpl: item.inventoryItem._tpl,
|
||||
@ -463,7 +462,7 @@ export class HideoutController
|
||||
{
|
||||
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)
|
||||
{
|
||||
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];
|
||||
|
||||
// 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 = {
|
||||
itemWithModsToAdd: [itemToReturn],
|
||||
@ -537,7 +536,7 @@ export class HideoutController
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
// 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
|
||||
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 itemsToDelete = body.items.concat(body.tools);
|
||||
for (const itemToDelete of itemsToDelete)
|
||||
{
|
||||
const itemToCheck = pmcData.Inventory.items.find((i) => i._id === itemToDelete.id);
|
||||
const requirement = recipeRequirementsClone.find((requirement) =>
|
||||
requirement.templateId === itemToCheck._tpl
|
||||
const itemToCheck = pmcData.Inventory.items.find(i => i._id === itemToDelete.id);
|
||||
const requirement = recipeRequirementsClone.find(requirement =>
|
||||
requirement.templateId === itemToCheck._tpl,
|
||||
);
|
||||
|
||||
// Handle tools not having a `count`, but always only requiring 1
|
||||
@ -645,7 +644,7 @@ export class HideoutController
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
this.logger.error(
|
||||
@ -679,13 +678,12 @@ export class HideoutController
|
||||
// @Important: Here we need to be very exact:
|
||||
// - 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"
|
||||
const adjustedCraftTime = recipe.ProductionTime
|
||||
- this.hideoutHelper.getSkillProductionTimeReduction(
|
||||
pmcData,
|
||||
recipe.ProductionTime,
|
||||
SkillTypes.CRAFTING,
|
||||
this.databaseServer.getTables().globals.config.SkillsSettings.Crafting.CraftTimeReductionPerLevel,
|
||||
);
|
||||
const adjustedCraftTime = recipe.ProductionTime - this.hideoutHelper.getSkillProductionTimeReduction(
|
||||
pmcData,
|
||||
recipe.ProductionTime,
|
||||
SkillTypes.CRAFTING,
|
||||
this.databaseServer.getTables().globals.config.SkillsSettings.Crafting.CraftTimeReductionPerLevel,
|
||||
);
|
||||
|
||||
const modifiedScavCaseTime = this.getScavCaseTime(pmcData, adjustedCraftTime);
|
||||
|
||||
@ -772,7 +770,7 @@ export class HideoutController
|
||||
return output;
|
||||
}
|
||||
|
||||
const recipe = hideoutDb.production.find((r) => r._id === request.recipeId);
|
||||
const recipe = hideoutDb.production.find(r => r._id === request.recipeId);
|
||||
if (recipe)
|
||||
{
|
||||
this.handleRecipe(sessionID, recipe, pmcData, request, output);
|
||||
@ -780,7 +778,7 @@ export class HideoutController
|
||||
return output;
|
||||
}
|
||||
|
||||
const scavCase = hideoutDb.scavcase.find((r) => r._id === request.recipeId);
|
||||
const scavCase = hideoutDb.scavcase.find(r => r._id === request.recipeId);
|
||||
if (scavCase)
|
||||
{
|
||||
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
|
||||
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)
|
||||
{
|
||||
// 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)
|
||||
// 1 point per 8 hours of crafting
|
||||
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
|
||||
const multiplierCrafting = Math.floor(hoursCrafting / this.hideoutConfig.hoursForSkillCrafting);
|
||||
@ -1016,7 +1014,7 @@ export class HideoutController
|
||||
{
|
||||
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)
|
||||
{
|
||||
this.profileHelper.addSkillPointsToPlayer(pmcData, SkillTypes.INTELLECT, intellectAmountToGive);
|
||||
@ -1189,14 +1187,14 @@ export class HideoutController
|
||||
public recordShootingRangePoints(sessionId: string, pmcData: IPmcData, request: IRecordShootingRangePoints): void
|
||||
{
|
||||
// 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 });
|
||||
}
|
||||
|
||||
// Find counter by key and update value
|
||||
const shootingRangeHighScore = pmcData.Stats.Eft.OverallCounters.Items.find((x) =>
|
||||
x.Key.includes("ShootingRangePoints")
|
||||
const shootingRangeHighScore = pmcData.Stats.Eft.OverallCounters.Items.find(x =>
|
||||
x.Key.includes("ShootingRangePoints"),
|
||||
);
|
||||
shootingRangeHighScore.Value = request.points;
|
||||
}
|
||||
@ -1218,7 +1216,7 @@ export class HideoutController
|
||||
// Create mapping of required item with corrisponding item from player inventory
|
||||
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 };
|
||||
});
|
||||
|
||||
@ -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)
|
||||
{
|
||||
this.logger.error(this.localisationService.getText("hideout-unable_to_find_area", request.areaType));
|
||||
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)
|
||||
{
|
||||
this.logger.error(
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
|
||||
import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
|
||||
import { PlayerScavGenerator } from "@spt-aki/generators/PlayerScavGenerator";
|
||||
@ -204,8 +203,8 @@ export class InraidController
|
||||
if (locationName === "lighthouse" && postRaidRequest.profile.Info.Side.toLowerCase() === "usec")
|
||||
{
|
||||
// Decrement counter if it exists, don't go below 0
|
||||
const remainingCounter = serverPmcProfile?.Stats.Eft.OverallCounters.Items.find((x) =>
|
||||
x.Key.includes("UsecRaidRemainKills")
|
||||
const remainingCounter = serverPmcProfile?.Stats.Eft.OverallCounters.Items.find(x =>
|
||||
x.Key.includes("UsecRaidRemainKills"),
|
||||
);
|
||||
if (remainingCounter?.Value > 0)
|
||||
{
|
||||
@ -229,9 +228,9 @@ export class InraidController
|
||||
// Not dead
|
||||
|
||||
// Check for cultist amulets in special slot (only slot it can fit)
|
||||
const amuletOnPlayer = serverPmcProfile.Inventory.items.filter((item) =>
|
||||
item.slotId?.startsWith("SpecialSlot")
|
||||
).find((item) => item._tpl === "64d0b40fbe2eed70e254e2d4");
|
||||
const amuletOnPlayer = serverPmcProfile.Inventory.items.filter(item =>
|
||||
item.slotId?.startsWith("SpecialSlot"),
|
||||
).find(item => item._tpl === "64d0b40fbe2eed70e254e2d4");
|
||||
if (amuletOnPlayer)
|
||||
{
|
||||
// No charges left, delete it
|
||||
@ -250,8 +249,8 @@ export class InraidController
|
||||
}
|
||||
}
|
||||
|
||||
const victims = postRaidRequest.profile.Stats.Eft.Victims.filter((x) =>
|
||||
["sptbear", "sptusec"].includes(x.Role.toLowerCase())
|
||||
const victims = postRaidRequest.profile.Stats.Eft.Victims.filter(x =>
|
||||
["sptbear", "sptusec"].includes(x.Role.toLowerCase()),
|
||||
);
|
||||
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
|
||||
// and quest items cannot be picked up again
|
||||
const allQuests = this.questHelper.getQuestsFromDb();
|
||||
const activeQuestIdsInProfile = pmcData.Quests.filter((profileQuest) =>
|
||||
![QuestStatus.AvailableForStart, QuestStatus.Success, QuestStatus.Expired].includes(profileQuest.status)
|
||||
).map((x) => x.qid);
|
||||
const activeQuestIdsInProfile = pmcData.Quests.filter(
|
||||
profileQuest => ![
|
||||
QuestStatus.AvailableForStart,
|
||||
QuestStatus.Success,
|
||||
QuestStatus.Expired,
|
||||
].includes(profileQuest.status),
|
||||
).map(x => x.qid);
|
||||
for (const questItem of postRaidSaveRequest.profile.Stats.Eft.CarriedQuestItems)
|
||||
{
|
||||
// Get quest/find condition for carried quest item
|
||||
@ -399,7 +402,7 @@ export class InraidController
|
||||
*/
|
||||
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)
|
||||
{
|
||||
@ -469,7 +472,7 @@ export class InraidController
|
||||
|
||||
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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
// 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")
|
||||
{
|
||||
continue;
|
||||
@ -541,7 +544,7 @@ export class InraidController
|
||||
*/
|
||||
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
|
||||
// This is to stop items being duplicated by being returned from both the item delivery, and insurance
|
||||
const deliveredItemIds = items.map((x) => x._id);
|
||||
pmcData.InsuredItems = pmcData.InsuredItems.filter((x) => !deliveredItemIds.includes(x.itemId));
|
||||
const deliveredItemIds = items.map(x => x._id);
|
||||
pmcData.InsuredItems = pmcData.InsuredItems.filter(x => !deliveredItemIds.includes(x.itemId));
|
||||
|
||||
// Send the items to the player
|
||||
this.mailSendService.sendLocalisedNpcMessageToPlayer(
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
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}`);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
const profile = this.saveServer.getProfile(sessionID);
|
||||
profile.insurance = profile.insurance.filter((insurance) =>
|
||||
profile.insurance = profile.insurance.filter(insurance =>
|
||||
insurance.traderId !== insPackage.traderId
|
||||
|| insurance.systemData.date !== insPackage.systemData.date
|
||||
|| 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}`);
|
||||
@ -201,8 +200,8 @@ export class InsuranceController
|
||||
let parentAttachmentsMap = this.populateParentAttachmentsMap(rootItemParentID, insured, itemsMap);
|
||||
|
||||
// Check to see if any regular items are present.
|
||||
const hasRegularItems = Array.from(itemsMap.values()).some((item) =>
|
||||
!this.itemHelper.isAttachmentAttached(item)
|
||||
const hasRegularItems = Array.from(itemsMap.values()).some(item =>
|
||||
!this.itemHelper.isAttachmentAttached(item),
|
||||
);
|
||||
|
||||
// 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)
|
||||
{
|
||||
// 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.
|
||||
if (!parentItem && insuredItem.parentId !== rootItemParentID)
|
||||
@ -490,7 +489,7 @@ export class InsuranceController
|
||||
{
|
||||
this.logger.debug(
|
||||
`Attachment ${index} Id: ${attachmentId} Tpl: ${
|
||||
attachments.find((x) => x._id === attachmentId)?._tpl
|
||||
attachments.find(x => x._id === attachmentId)?._tpl
|
||||
} - Price: ${attachmentPrices[attachmentId]}`,
|
||||
);
|
||||
index++;
|
||||
@ -557,7 +556,7 @@ export class InsuranceController
|
||||
*/
|
||||
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.
|
||||
interface EnrichedItem extends Item
|
||||
{
|
||||
name: string;
|
||||
dynamicPrice: number;
|
||||
name: string
|
||||
dynamicPrice: number
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { LootGenerator } from "@spt-aki/generators/LootGenerator";
|
||||
import { HideoutHelper } from "@spt-aki/helpers/HideoutHelper";
|
||||
import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
|
||||
@ -107,7 +106,7 @@ export class InventoryController
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
// Internal item move but item never existed, possible dupe glitch
|
||||
@ -169,7 +168,7 @@ export class InventoryController
|
||||
return;
|
||||
}
|
||||
|
||||
const profileToRemoveItemFrom = (!request.fromOwner || request.fromOwner.id === pmcData._id)
|
||||
const profileToRemoveItemFrom = !request.fromOwner || request.fromOwner.id === pmcData._id
|
||||
? pmcData
|
||||
: this.profileHelper.getFullProfile(sessionID).characters.scav;
|
||||
|
||||
@ -198,12 +197,12 @@ export class InventoryController
|
||||
// Handle cartridge edge-case
|
||||
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
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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);
|
||||
|
||||
// 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)
|
||||
{
|
||||
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
|
||||
const destinationItem = inventoryItems.to.find((x) => x._id === body.with);
|
||||
const destinationItem = inventoryItems.to.find(x => x._id === body.with);
|
||||
if (!destinationItem)
|
||||
{
|
||||
const errorMessage = `Unable to merge stacks as destination item: ${body.with} cannot be found`;
|
||||
@ -282,7 +281,7 @@ export class InventoryController
|
||||
return output;
|
||||
}
|
||||
|
||||
if (!(destinationItem.upd?.StackObjectsCount))
|
||||
if (!destinationItem.upd?.StackObjectsCount)
|
||||
{
|
||||
// No stackcount on destination, add one
|
||||
destinationItem.upd = { StackObjectsCount: 1 };
|
||||
@ -307,7 +306,7 @@ export class InventoryController
|
||||
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
|
||||
|
||||
const indexOfItemToRemove = inventoryItems.from.findIndex((x) => x._id === sourceItem._id);
|
||||
const indexOfItemToRemove = inventoryItems.from.findIndex(x => x._id === sourceItem._id);
|
||||
if (indexOfItemToRemove === -1)
|
||||
{
|
||||
const errorMessage = `Unable to find item: ${sourceItem._id} to remove from sender inventory`;
|
||||
@ -340,8 +339,8 @@ export class InventoryController
|
||||
): IItemEventRouterResponse
|
||||
{
|
||||
const inventoryItems = this.inventoryHelper.getOwnerInventoryItems(body, sessionID);
|
||||
const sourceItem = inventoryItems.from.find((item) => item._id === body.item);
|
||||
const destinationItem = inventoryItems.to.find((item) => item._id === body.with);
|
||||
const sourceItem = inventoryItems.from.find(item => item._id === body.item);
|
||||
const destinationItem = inventoryItems.to.find(item => item._id === body.with);
|
||||
|
||||
if (sourceItem === null)
|
||||
{
|
||||
@ -397,13 +396,13 @@ export class InventoryController
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
const itemToFold = playerData.Inventory.items.find((item) => item?._id === request.item);
|
||||
const itemToFold = playerData.Inventory.items.find(item => item?._id === request.item);
|
||||
if (!itemToFold)
|
||||
{
|
||||
// Item not found
|
||||
@ -488,7 +487,7 @@ export class InventoryController
|
||||
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)
|
||||
{
|
||||
this.itemHelper.addUpdObjectToItem(
|
||||
@ -689,15 +688,15 @@ export class InventoryController
|
||||
if (request.fromOwner.id === Traders.FENCE)
|
||||
{
|
||||
// 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")
|
||||
{
|
||||
// Not fence
|
||||
// get tpl from trader assort
|
||||
return this.databaseServer.getTables().traders[request.fromOwner.id].assort.items.find((item) =>
|
||||
item._id === request.item
|
||||
return this.databaseServer.getTables().traders[request.fromOwner.id].assort.items.find(item =>
|
||||
item._id === request.item,
|
||||
)._tpl;
|
||||
}
|
||||
|
||||
@ -718,7 +717,7 @@ export class InventoryController
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
return matchingItem._tpl;
|
||||
@ -754,7 +753,7 @@ export class InventoryController
|
||||
{
|
||||
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)
|
||||
{
|
||||
this.logger.error(
|
||||
@ -793,7 +792,7 @@ export class InventoryController
|
||||
): void
|
||||
{
|
||||
// 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
|
||||
mapItem.upd.Map = mapItem.upd.Map || { Markers: [] };
|
||||
@ -819,7 +818,7 @@ export class InventoryController
|
||||
): void
|
||||
{
|
||||
// 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
|
||||
const markers = mapItem.upd.Map.Markers.filter((marker) =>
|
||||
@ -847,10 +846,10 @@ export class InventoryController
|
||||
): void
|
||||
{
|
||||
// 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
|
||||
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);
|
||||
mapItem.upd.Map.Markers[indexOfExistingNote] = request.mapMarker;
|
||||
|
||||
@ -884,7 +883,7 @@ export class InventoryController
|
||||
): void
|
||||
{
|
||||
/** 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 isSealedWeaponBox = containerDetailsDb[1]._name.includes("event_container_airdrop");
|
||||
|
||||
@ -935,8 +934,8 @@ export class InventoryController
|
||||
// Hard coded to `SYSTEM` for now
|
||||
// TODO: make this dynamic
|
||||
const dialog = fullProfile.dialogues["59e7125688a45068a6249071"];
|
||||
const mail = dialog.messages.find((x) => x._id === event.MessageId);
|
||||
const mailEvent = mail.profileChangeEvents.find((x) => x._id === event.EventId);
|
||||
const mail = dialog.messages.find(x => x._id === event.MessageId);
|
||||
const mailEvent = mail.profileChangeEvents.find(x => x._id === event.EventId);
|
||||
|
||||
switch (mailEvent.Type)
|
||||
{
|
||||
@ -955,15 +954,15 @@ export class InventoryController
|
||||
break;
|
||||
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;
|
||||
this.logger.success(`Set profile skill: ${mailEvent.entity} to: ${mailEvent.value}`);
|
||||
break;
|
||||
}
|
||||
case "ExamineAllItems":
|
||||
{
|
||||
const itemsToInspect = this.itemHelper.getItems().filter((x) => x._type !== "Node");
|
||||
this.flagItemsAsInspectedAndRewardXp(itemsToInspect.map((x) => x._id), fullProfile);
|
||||
const itemsToInspect = this.itemHelper.getItems().filter(x => x._type !== "Node");
|
||||
this.flagItemsAsInspectedAndRewardXp(itemsToInspect.map(x => x._id), fullProfile);
|
||||
this.logger.success(`Flagged ${itemsToInspect.length} items as examined`);
|
||||
break;
|
||||
}
|
||||
@ -988,7 +987,7 @@ export class InventoryController
|
||||
for (const itemId of request.items)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
pmcData.Inventory.favoriteItems.splice(indexOfItemAlreadyFavorited, 1);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
|
||||
import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
|
||||
import { LocationGenerator } from "@spt-aki/generators/LocationGenerator";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
|
||||
import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
|
||||
import { LootGenerator } from "@spt-aki/generators/LootGenerator";
|
||||
@ -191,7 +190,7 @@ export class MatchController
|
||||
return false;
|
||||
}
|
||||
|
||||
return (this.inRaidConfig.coopExtracts.includes(extractName.trim()));
|
||||
return this.inRaidConfig.coopExtracts.includes(extractName.trim());
|
||||
}
|
||||
|
||||
protected sendCoopTakenFenceMessage(sessionId: string): void
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
import { Note } from "@spt-aki/models/eft/common/tables/IBotBase";
|
||||
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
|
||||
import { NotifierHelper } from "@spt-aki/helpers/NotifierHelper";
|
||||
import { INotifierChannel } from "@spt-aki/models/eft/notifier/INotifier";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
|
||||
import { IPreset } from "@spt-aki/models/eft/common/IGlobals";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { PlayerScavGenerator } from "@spt-aki/generators/PlayerScavGenerator";
|
||||
import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
@ -81,7 +80,7 @@ export class ProfileController
|
||||
const pmc = profile.characters.pmc;
|
||||
|
||||
// make sure character completed creation
|
||||
if (!(pmc?.Info?.Level))
|
||||
if (!pmc?.Info?.Level)
|
||||
{
|
||||
return {
|
||||
username: profile.info.username,
|
||||
@ -104,7 +103,7 @@ export class ProfileController
|
||||
side: pmc.Info.Side,
|
||||
currlvl: pmc.Info.Level,
|
||||
currexp: pmc.Info.Experience ?? 0,
|
||||
prevexp: (currlvl === 0) ? 0 : this.profileHelper.getExperience(currlvl),
|
||||
prevexp: currlvl === 0 ? 0 : this.profileHelper.getExperience(currlvl),
|
||||
nextlvl: nextlvl,
|
||||
maxlvl: maxlvl,
|
||||
akiData: profile.aki,
|
||||
@ -130,8 +129,10 @@ export class ProfileController
|
||||
public createProfile(info: IProfileCreateRequestData, sessionID: string): string
|
||||
{
|
||||
const account = this.saveServer.getProfile(sessionID).info;
|
||||
const profile: ITemplateSide =
|
||||
this.databaseServer.getTables().templates.profiles[account.edition][info.side.toLowerCase()];
|
||||
const profile: ITemplateSide = this.databaseServer
|
||||
.getTables()
|
||||
.templates
|
||||
.profiles[account.edition][info.side.toLowerCase()];
|
||||
const pmcData = profile.character;
|
||||
|
||||
// Delete existing profile
|
||||
@ -151,7 +152,7 @@ export class ProfileController
|
||||
pmcData.Customization.Head = info.headId;
|
||||
pmcData.Health.UpdateTime = this.timeUtil.getTimestamp();
|
||||
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.CarExtractCounts = {};
|
||||
pmcData.CoopExtractCounts = {};
|
||||
@ -458,7 +459,7 @@ export class ProfileController
|
||||
skills: playerPmc.Skills,
|
||||
equipment: {
|
||||
// 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,
|
||||
},
|
||||
achievements: playerPmc.Achievements,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { DialogueHelper } from "@spt-aki/helpers/DialogueHelper";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
@ -79,7 +78,7 @@ export class QuestController
|
||||
for (const quest of allQuests)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
quest.sptStatus = questInProfile.status;
|
||||
@ -137,8 +136,8 @@ export class QuestController
|
||||
for (const conditionToFulfil of questRequirements)
|
||||
{
|
||||
// If the previous quest isn't in the user profile, it hasn't been completed or started
|
||||
const prerequisiteQuest = profile.Quests.find((profileQuest) =>
|
||||
conditionToFulfil.target.includes(profileQuest.qid)
|
||||
const prerequisiteQuest = profile.Quests.find(profileQuest =>
|
||||
conditionToFulfil.target.includes(profileQuest.qid),
|
||||
);
|
||||
if (!prerequisiteQuest)
|
||||
{
|
||||
@ -148,7 +147,7 @@ export class QuestController
|
||||
|
||||
// Prereq does not have its status requirement fulfilled
|
||||
// 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;
|
||||
break;
|
||||
@ -292,7 +291,7 @@ export class QuestController
|
||||
|
||||
// Does quest exist 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)
|
||||
{
|
||||
// Update existing
|
||||
@ -399,15 +398,15 @@ export class QuestController
|
||||
fullProfile.characters.scav.Quests.push(newRepeatableQuest);
|
||||
}
|
||||
|
||||
const repeatableSettings = pmcData.RepeatableQuests.find((x) =>
|
||||
x.name === repeatableQuestProfile.sptRepatableGroupName
|
||||
const repeatableSettings = pmcData.RepeatableQuests.find(x =>
|
||||
x.name === repeatableQuestProfile.sptRepatableGroupName,
|
||||
);
|
||||
|
||||
const change = {};
|
||||
change[repeatableQuestProfile._id] = repeatableSettings.changeRequirement[repeatableQuestProfile._id];
|
||||
const responseData: IPmcDataRepeatableQuest = {
|
||||
id: repeatableSettings.id ?? this.questConfig.repeatableQuests.find((x) =>
|
||||
x.name === repeatableQuestProfile.sptRepatableGroupName
|
||||
id: repeatableSettings.id ?? this.questConfig.repeatableQuests.find(x =>
|
||||
x.name === repeatableQuestProfile.sptRepatableGroupName,
|
||||
).id,
|
||||
name: repeatableSettings.name,
|
||||
endTime: repeatableSettings.endTime,
|
||||
@ -435,7 +434,7 @@ export class QuestController
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
for (const currentRepeatable of pmcData.RepeatableQuests)
|
||||
{
|
||||
const repeatableQuest = currentRepeatable.activeQuests.find((activeRepeatable) =>
|
||||
activeRepeatable._id === completedQuestId
|
||||
const repeatableQuest = currentRepeatable.activeQuests.find(activeRepeatable =>
|
||||
activeRepeatable._id === completedQuestId,
|
||||
);
|
||||
if (repeatableQuest)
|
||||
{
|
||||
@ -548,15 +547,15 @@ export class QuestController
|
||||
|
||||
// Quest already failed in profile, skip
|
||||
if (
|
||||
pmcProfile.Quests.some((profileQuest) =>
|
||||
profileQuest.qid === quest._id && profileQuest.status === QuestStatus.Fail
|
||||
pmcProfile.Quests.some(profileQuest =>
|
||||
profileQuest.qid === quest._id && profileQuest.status === QuestStatus.Fail,
|
||||
)
|
||||
)
|
||||
{
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
this.logger.warning(
|
||||
@ -600,7 +599,7 @@ export class QuestController
|
||||
for (const quest of postQuestStatuses)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
result.push(quest);
|
||||
@ -653,8 +652,8 @@ export class QuestController
|
||||
for (const quest of quests)
|
||||
{
|
||||
// If quest has prereq of completed quest + availableAfter value > 0 (quest has wait time)
|
||||
const nextQuestWaitCondition = quest.conditions.AvailableForStart.find((x) =>
|
||||
x.target?.includes(completedQuestId) && x.availableAfter > 0
|
||||
const nextQuestWaitCondition = quest.conditions.AvailableForStart.find(x =>
|
||||
x.target?.includes(completedQuestId) && x.availableAfter > 0,
|
||||
);
|
||||
if (nextQuestWaitCondition)
|
||||
{
|
||||
@ -662,7 +661,7 @@ export class QuestController
|
||||
const availableAfterTimestamp = this.timeUtil.getTimestamp() + nextQuestWaitCondition.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)
|
||||
{
|
||||
existingQuestInProfile.availableAfter = availableAfterTimestamp;
|
||||
@ -679,7 +678,7 @@ export class QuestController
|
||||
status: QuestStatus.AvailableAfter,
|
||||
statusTimers: {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
"9": this.timeUtil.getTimestamp(),
|
||||
9: this.timeUtil.getTimestamp(),
|
||||
},
|
||||
availableAfter: availableAfterTimestamp,
|
||||
});
|
||||
@ -705,12 +704,12 @@ export class QuestController
|
||||
for (const questToFail of questsToFail)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
const isActiveQuestInPlayerProfile = pmcData.Quests.find((quest) => quest.qid === questToFail._id);
|
||||
const isActiveQuestInPlayerProfile = pmcData.Quests.find(quest => quest.qid === questToFail._id);
|
||||
if (isActiveQuestInPlayerProfile)
|
||||
{
|
||||
if (isActiveQuestInPlayerProfile.status !== QuestStatus.Fail)
|
||||
@ -772,7 +771,7 @@ export class QuestController
|
||||
isItemHandoverQuest = condition.conditionType === handoverQuestTypes[0];
|
||||
handoverRequirements = condition;
|
||||
|
||||
const profileCounter = (handoverQuestRequest.conditionId in pmcData.TaskConditionCounters)
|
||||
const profileCounter = handoverQuestRequest.conditionId in pmcData.TaskConditionCounters
|
||||
? pmcData.TaskConditionCounters[handoverQuestRequest.conditionId].value
|
||||
: 0;
|
||||
handedInCount -= profileCounter;
|
||||
@ -806,7 +805,7 @@ export class QuestController
|
||||
let totalItemCountToRemove = 0;
|
||||
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)))
|
||||
{
|
||||
// Item handed in by player doesnt match what was requested
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { RagfairOfferGenerator } from "@spt-aki/generators/RagfairOfferGenerator";
|
||||
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
|
||||
import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
|
||||
@ -160,7 +159,7 @@ export class RagfairController
|
||||
public getOfferById(sessionId: string, request: IGetRagfairOfferByIdRequest): IRagfairOffer
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -208,14 +207,18 @@ export class RagfairController
|
||||
): Record<string, number>
|
||||
{
|
||||
// Linked/required search categories
|
||||
const playerHasFleaUnlocked =
|
||||
pmcProfile.Info.Level >= this.databaseServer.getTables().globals.config.RagFair.minUserLevel;
|
||||
const playerHasFleaUnlocked = pmcProfile.Info.Level >= this.databaseServer
|
||||
.getTables()
|
||||
.globals
|
||||
.config
|
||||
.RagFair
|
||||
.minUserLevel;
|
||||
let offerPool = [];
|
||||
if (this.isLinkedSearch(searchRequest) || this.isRequiredSearch(searchRequest))
|
||||
{
|
||||
offerPool = offers;
|
||||
}
|
||||
else if ((!(this.isLinkedSearch(searchRequest) || this.isRequiredSearch(searchRequest))))
|
||||
else if (!(this.isLinkedSearch(searchRequest) || this.isRequiredSearch(searchRequest)))
|
||||
{
|
||||
// Get all categories
|
||||
offerPool = this.ragfairOfferService.getOffers();
|
||||
@ -260,7 +263,7 @@ export class RagfairController
|
||||
|
||||
const traderAssorts = this.traderHelper.getTraderAssortsByTraderId(offer.user.id).items;
|
||||
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
|
||||
offer.buyRestrictionCurrent = fullProfile.traderPurchases[offer.user.id][assortId]
|
||||
@ -279,7 +282,7 @@ export class RagfairController
|
||||
const firstItem = offer.items[0];
|
||||
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)
|
||||
{
|
||||
this.logger.warning(
|
||||
@ -357,7 +360,7 @@ export class RagfairController
|
||||
const avg = offers.reduce((sum, offer) =>
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
@ -456,15 +459,15 @@ export class RagfairController
|
||||
// Multiply single item price by stack count and quality
|
||||
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
|
||||
const averageSingleItemPrice = (offerRequest.sellInOnePiece)
|
||||
const averageSingleItemPrice = offerRequest.sellInOnePiece
|
||||
? averageOfferPrice / rootItem.upd.StackObjectsCount // Packs are a single offer made of many items
|
||||
: averageOfferPrice / itemStackCount;
|
||||
|
||||
// Get averaged price of listing
|
||||
const averagePlayerListedPriceInRub = (offerRequest.sellInOnePiece)
|
||||
const averagePlayerListedPriceInRub = offerRequest.sellInOnePiece
|
||||
? playerListedPriceInRub / rootItem.upd.StackObjectsCount
|
||||
: playerListedPriceInRub;
|
||||
|
||||
@ -540,7 +543,7 @@ export class RagfairController
|
||||
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
|
||||
this.ragfairTaxService.clearStoredOfferTaxById(offerRequest.items[0]);
|
||||
@ -602,8 +605,8 @@ export class RagfairController
|
||||
}
|
||||
else
|
||||
{
|
||||
requirementsPriceInRub += this.ragfairPriceService.getDynamicPriceForItem(requestedItemTpl)
|
||||
* item.count;
|
||||
requirementsPriceInRub += this.ragfairPriceService
|
||||
.getDynamicPriceForItem(requestedItemTpl) * item.count;
|
||||
}
|
||||
}
|
||||
|
||||
@ -619,7 +622,7 @@ export class RagfairController
|
||||
protected getItemsToListOnFleaFromInventory(
|
||||
pmcData: IPmcData,
|
||||
itemIdsFromFleaOfferRequest: string[],
|
||||
): { items: Item[] | null; errorMessage: string | null; }
|
||||
): { items: Item[] | null, errorMessage: string | null }
|
||||
{
|
||||
const itemsToReturn = [];
|
||||
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
|
||||
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)
|
||||
{
|
||||
errorMessage = this.localisationService.getText("ragfair-unable_to_find_item_in_inventory", {
|
||||
@ -663,7 +666,7 @@ export class RagfairController
|
||||
const loyalLevel = 1;
|
||||
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 {
|
||||
_id: item._id,
|
||||
@ -724,7 +727,7 @@ export class RagfairController
|
||||
pmcData.RagfairInfo.offers = [];
|
||||
}
|
||||
|
||||
const playerOfferIndex = playerProfileOffers.findIndex((offer) => offer._id === removeRequest.offerId);
|
||||
const playerOfferIndex = playerProfileOffers.findIndex(offer => offer._id === removeRequest.offerId);
|
||||
if (playerOfferIndex === -1)
|
||||
{
|
||||
this.logger.error(
|
||||
@ -761,7 +764,7 @@ export class RagfairController
|
||||
|
||||
const pmcData = this.saveServer.getProfile(sessionId).characters.pmc;
|
||||
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;
|
||||
|
||||
if (playerOfferIndex === -1)
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
|
||||
import { RepairHelper } from "@spt-aki/helpers/RepairHelper";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { RepeatableQuestGenerator } from "@spt-aki/generators/RepeatableQuestGenerator";
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
|
||||
@ -83,15 +82,15 @@ export class RepeatableQuestController
|
||||
* @param {string} _info Request from client
|
||||
* @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[]
|
||||
{
|
||||
const returnData: Array<IPmcDataRepeatableQuest> = [];
|
||||
const pmcData = this.profileHelper.getPmcProfile(sessionID);
|
||||
const time = this.timeUtil.getTimestamp();
|
||||
const scavQuestUnlocked =
|
||||
pmcData?.Hideout?.Areas?.find((hideoutArea) => hideoutArea.type === HideoutAreas.INTEL_CENTER)?.level >= 1;
|
||||
const scavQuestUnlocked
|
||||
= pmcData?.Hideout?.Areas?.find(hideoutArea => hideoutArea.type === HideoutAreas.INTEL_CENTER)?.level >= 1;
|
||||
|
||||
// Daily / weekly / Daily_Savage
|
||||
for (const repeatableConfig of this.questConfig.repeatableQuests)
|
||||
@ -119,7 +118,7 @@ export class RepeatableQuestController
|
||||
for (const activeQuest of currentRepeatableQuestType.activeQuests)
|
||||
{
|
||||
// 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.status === QuestStatus.AvailableForFinish)
|
||||
@ -135,7 +134,7 @@ export class RepeatableQuestController
|
||||
this.profileFixerService.removeDanglingConditionCounters(pmcData);
|
||||
|
||||
// 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.activeQuests = questsToKeep;
|
||||
@ -217,9 +216,14 @@ export class RepeatableQuestController
|
||||
)
|
||||
{
|
||||
// Elite charisma skill gives extra daily quest(s)
|
||||
return repeatableConfig.numQuests
|
||||
+ this.databaseServer.getTables().globals.config.SkillsSettings.Charisma.BonusSettings
|
||||
.EliteBonusSettings.RepeatableQuestExtraCount;
|
||||
return repeatableConfig.numQuests + this.databaseServer.getTables()
|
||||
.globals
|
||||
.config
|
||||
.SkillsSettings
|
||||
.Charisma
|
||||
.BonusSettings
|
||||
.EliteBonusSettings
|
||||
.RepeatableQuestExtraCount;
|
||||
}
|
||||
|
||||
return repeatableConfig.numQuests;
|
||||
@ -237,7 +241,7 @@ export class RepeatableQuestController
|
||||
): IPmcDataRepeatableQuest
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
repeatableQuestDetails = {
|
||||
@ -327,8 +331,8 @@ export class RepeatableQuestController
|
||||
const possibleLocations = Object.keys(locations);
|
||||
|
||||
// Set possible locations for elimination task, if target is savage, exclude labs from locations
|
||||
questPool.pool.Elimination.targets[probabilityObject.key] = (probabilityObject.key === "Savage")
|
||||
? { locations: possibleLocations.filter((x) => x !== "laboratory") }
|
||||
questPool.pool.Elimination.targets[probabilityObject.key] = probabilityObject.key === "Savage"
|
||||
? { locations: possibleLocations.filter(x => x !== "laboratory") }
|
||||
: { locations: possibleLocations };
|
||||
}
|
||||
}
|
||||
@ -396,7 +400,7 @@ export class RepeatableQuestController
|
||||
return true;
|
||||
}
|
||||
|
||||
return (pmcLevel <= locationBase.RequiredPlayerLevelMax && pmcLevel >= locationBase.RequiredPlayerLevelMin);
|
||||
return pmcLevel <= locationBase.RequiredPlayerLevelMax && pmcLevel >= locationBase.RequiredPlayerLevelMin;
|
||||
}
|
||||
|
||||
public debugLogRepeatableQuestIds(pmcData: IPmcData): void
|
||||
@ -439,7 +443,7 @@ export class RepeatableQuestController
|
||||
for (const currentRepeatablePool of pmcData.RepeatableQuests)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
continue;
|
||||
@ -449,8 +453,8 @@ export class RepeatableQuestController
|
||||
replacedQuestTraderId = questToReplace.traderId;
|
||||
|
||||
// Update active quests to exclude the quest we're replacing
|
||||
currentRepeatablePool.activeQuests = currentRepeatablePool.activeQuests.filter((x) =>
|
||||
x._id !== changeRequest.qid
|
||||
currentRepeatablePool.activeQuests = currentRepeatablePool.activeQuests.filter(x =>
|
||||
x._id !== changeRequest.qid,
|
||||
);
|
||||
|
||||
// Get cost to replace existing quest
|
||||
@ -458,8 +462,8 @@ export class RepeatableQuestController
|
||||
delete currentRepeatablePool.changeRequirement[changeRequest.qid];
|
||||
// TODO: somehow we need to reduce the questPool by the currently active quests (for all repeatables)
|
||||
|
||||
const repeatableConfig = this.questConfig.repeatableQuests.find((x) =>
|
||||
x.name === currentRepeatablePool.name
|
||||
const repeatableConfig = this.questConfig.repeatableQuests.find(x =>
|
||||
x.name === currentRepeatablePool.name,
|
||||
);
|
||||
const questTypePool = this.generateQuestPool(repeatableConfig, pmcData.Info.Level);
|
||||
const newRepeatableQuest = this.attemptToGenerateRepeatableQuest(pmcData, questTypePool, repeatableConfig);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { TradeHelper } from "@spt-aki/helpers/TradeHelper";
|
||||
@ -294,7 +293,7 @@ export class TradeController
|
||||
this.traderHelper.getTraderById(trader),
|
||||
MessageType.MESSAGE_WITH_ITEMS,
|
||||
this.randomUtil.getArrayValue(this.databaseServer.getTables().traders[trader].dialogue.soldItems),
|
||||
curencyReward.flatMap((x) => x),
|
||||
curencyReward.flatMap(x => x),
|
||||
this.timeUtil.getHoursAsSeconds(72),
|
||||
);
|
||||
}
|
||||
@ -320,12 +319,12 @@ export class TradeController
|
||||
for (const itemToSell of itemWithChildren)
|
||||
{
|
||||
const itemDetails = this.itemHelper.getItem(itemToSell._tpl);
|
||||
if (
|
||||
!(itemDetails[0]
|
||||
&& this.itemHelper.isOfBaseclasses(itemDetails[1]._id, traderDetails.items_buy.category))
|
||||
)
|
||||
if (!(itemDetails[0] && this.itemHelper.isOfBaseclasses(
|
||||
itemDetails[1]._id,
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { FenceBaseAssortGenerator } from "@spt-aki/generators/FenceBaseAssortGenerator";
|
||||
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
||||
import { TraderAssortHelper } from "@spt-aki/helpers/TraderAssortHelper";
|
||||
@ -30,8 +29,7 @@ export class TraderController
|
||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
||||
@inject("TraderHelper") protected traderHelper: TraderHelper,
|
||||
@inject("TraderAssortService") protected traderAssortService: TraderAssortService,
|
||||
@inject("TraderPurchasePersisterService") protected traderPurchasePersisterService:
|
||||
TraderPurchasePersisterService,
|
||||
@inject("TraderPurchasePersisterService") protected traderPurchasePersisterService: TraderPurchasePersisterService,
|
||||
@inject("FenceService") protected fenceService: FenceService,
|
||||
@inject("FenceBaseAssortGenerator") protected fenceBaseAssortGenerator: FenceBaseAssortGenerator,
|
||||
@inject("JsonUtil") protected jsonUtil: JsonUtil,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { WeatherGenerator } from "@spt-aki/generators/WeatherGenerator";
|
||||
import { IWeatherData } from "@spt-aki/models/eft/weather/IWeatherData";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
|
||||
import { IWishlistActionData } from "@spt-aki/models/eft/wishlist/IWishlistActionData";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { DependencyContainer, Lifecycle } from "tsyringe";
|
||||
|
||||
import { AchievementCallbacks } from "@spt-aki/callbacks/AchievementCallbacks";
|
||||
import { BotCallbacks } from "@spt-aki/callbacks/BotCallbacks";
|
||||
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 { LocationGenerator } from "@spt-aki/generators/LocationGenerator";
|
||||
import { LootGenerator } from "@spt-aki/generators/LootGenerator";
|
||||
import { PMCLootGenerator } from "@spt-aki/generators/PMCLootGenerator";
|
||||
import { PlayerScavGenerator } from "@spt-aki/generators/PlayerScavGenerator";
|
||||
import { PMCLootGenerator } from "@spt-aki/generators/PMCLootGenerator";
|
||||
import { RagfairAssortGenerator } from "@spt-aki/generators/RagfairAssortGenerator";
|
||||
import { RagfairOfferGenerator } from "@spt-aki/generators/RagfairOfferGenerator";
|
||||
import { RepeatableQuestGenerator } from "@spt-aki/generators/RepeatableQuestGenerator";
|
||||
import { RepeatableQuestRewardGenerator } from "@spt-aki/generators/RepeatableQuestRewardGenerator";
|
||||
import { ScavCaseRewardGenerator } from "@spt-aki/generators/ScavCaseRewardGenerator";
|
||||
import { WeatherGenerator } from "@spt-aki/generators/WeatherGenerator";
|
||||
import { BarrelInventoryMagGen } from "@spt-aki/generators/weapongen/implementations/BarrelInventoryMagGen";
|
||||
import { ExternalInventoryMagGen } from "@spt-aki/generators/weapongen/implementations/ExternalInventoryMagGen";
|
||||
import { InternalMagazineInventoryMagGen } from "@spt-aki/generators/weapongen/implementations/InternalMagazineInventoryMagGen";
|
||||
import { UbglExternalMagGen } from "@spt-aki/generators/weapongen/implementations/UbglExternalMagGen";
|
||||
import { WeatherGenerator } from "@spt-aki/generators/WeatherGenerator";
|
||||
import { AssortHelper } from "@spt-aki/helpers/AssortHelper";
|
||||
import { BotDifficultyHelper } from "@spt-aki/helpers/BotDifficultyHelper";
|
||||
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 { PreAkiModLoader } from "@spt-aki/loaders/PreAkiModLoader";
|
||||
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 { BundleDynamicRouter } from "@spt-aki/routers/dynamic/BundleDynamicRouter";
|
||||
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 { NotifierDynamicRouter } from "@spt-aki/routers/dynamic/NotifierDynamicRouter";
|
||||
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 { HealthItemEventRouter } from "@spt-aki/routers/item_events/HealthItemEventRouter";
|
||||
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 { TradeItemEventRouter } from "@spt-aki/routers/item_events/TradeItemEventRouter";
|
||||
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 { InraidSaveLoadRouter } from "@spt-aki/routers/save_load/InraidSaveLoadRouter";
|
||||
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 { ConfigServer } from "@spt-aki/servers/ConfigServer";
|
||||
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
||||
import { AkiHttpListener } from "@spt-aki/servers/http/AkiHttpListener";
|
||||
import { HttpServer } from "@spt-aki/servers/HttpServer";
|
||||
import { RagfairServer } from "@spt-aki/servers/RagfairServer";
|
||||
import { SaveServer } from "@spt-aki/servers/SaveServer";
|
||||
import { WebSocketServer } from "@spt-aki/servers/WebSocketServer";
|
||||
import { AkiHttpListener } from "@spt-aki/servers/http/AkiHttpListener";
|
||||
import { BotEquipmentFilterService } from "@spt-aki/services/BotEquipmentFilterService";
|
||||
import { BotEquipmentModPoolService } from "@spt-aki/services/BotEquipmentModPoolService";
|
||||
import { BotGenerationCacheService } from "@spt-aki/services/BotGenerationCacheService";
|
||||
import { BotLootCacheService } from "@spt-aki/services/BotLootCacheService";
|
||||
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 { FenceService } from "@spt-aki/services/FenceService";
|
||||
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 { MatchBotDetailsCacheService } from "@spt-aki/services/MatchBotDetailsCacheService";
|
||||
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 { NotificationService } from "@spt-aki/services/NotificationService";
|
||||
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 { TraderPurchasePersisterService } from "@spt-aki/services/TraderPurchasePersisterService";
|
||||
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 { AsyncQueue } from "@spt-aki/utils/AsyncQueue";
|
||||
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 { ImporterUtil } from "@spt-aki/utils/ImporterUtil";
|
||||
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 { ObjectId } from "@spt-aki/utils/ObjectId";
|
||||
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
|
||||
import { TimeUtil } from "@spt-aki/utils/TimeUtil";
|
||||
import { VFS } from "@spt-aki/utils/VFS";
|
||||
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
|
||||
|
@ -1,5 +1,5 @@
|
||||
export interface OnLoad
|
||||
{
|
||||
onLoad(): Promise<void>;
|
||||
getRoute(): string;
|
||||
onLoad(): Promise<void>
|
||||
getRoute(): string
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
export interface OnUpdate
|
||||
{
|
||||
onUpdate(timeSinceLastRun: number): Promise<boolean>;
|
||||
getRoute(): string;
|
||||
onUpdate(timeSinceLastRun: number): Promise<boolean>
|
||||
getRoute(): string
|
||||
}
|
||||
|
@ -29,9 +29,9 @@ export class Router
|
||||
{
|
||||
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
|
||||
{
|
||||
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[]
|
||||
{
|
||||
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
|
||||
{
|
||||
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[]
|
||||
{
|
||||
return this.routes.map((route) => new HandledRoute(route.url, true));
|
||||
return this.routes.map(route => new HandledRoute(route.url, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
|
||||
import { BotHelper } from "@spt-aki/helpers/BotHelper";
|
||||
import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper";
|
||||
@ -234,8 +233,8 @@ export class BotEquipmentModGenerator
|
||||
}
|
||||
|
||||
// Get the front/back/side weights based on bots level
|
||||
const plateSlotWeights = settings.botEquipmentConfig?.armorPlateWeighting?.find((armorWeight) =>
|
||||
settings.botLevel >= armorWeight.levelRange.min && settings.botLevel <= armorWeight.levelRange.max
|
||||
const plateSlotWeights = settings.botEquipmentConfig?.armorPlateWeighting?.find(armorWeight =>
|
||||
settings.botLevel >= armorWeight.levelRange.min && settings.botLevel <= armorWeight.levelRange.max,
|
||||
);
|
||||
if (!plateSlotWeights)
|
||||
{
|
||||
@ -261,17 +260,17 @@ export class BotEquipmentModGenerator
|
||||
const chosenArmorPlateLevel = this.weightedRandomHelper.getWeightedValue<string>(plateWeights);
|
||||
|
||||
// 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
|
||||
const filteredPlates = platesFromDb.filter((item) => item._props.armorClass === chosenArmorPlateLevel);
|
||||
const filteredPlates = platesFromDb.filter(item => item._props.armorClass === chosenArmorPlateLevel);
|
||||
if (filteredPlates.length === 0)
|
||||
{
|
||||
this.logger.debug(
|
||||
`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;
|
||||
if (!defaultPlate)
|
||||
{
|
||||
@ -281,8 +280,8 @@ export class BotEquipmentModGenerator
|
||||
const defaultPreset = this.presetHelper.getDefaultPreset(armorItem._id);
|
||||
if (defaultPreset)
|
||||
{
|
||||
const relatedPresetSlot = defaultPreset._items.find((item) =>
|
||||
item.slotId?.toLowerCase() === modSlot
|
||||
const relatedPresetSlot = defaultPreset._items.find(item =>
|
||||
item.slotId?.toLowerCase() === modSlot,
|
||||
);
|
||||
if (relatedPresetSlot)
|
||||
{
|
||||
@ -306,7 +305,7 @@ export class BotEquipmentModGenerator
|
||||
|
||||
// Only return the items ids
|
||||
result.result = Result.SUCCESS;
|
||||
result.plateModTpls = filteredPlates.map((item) => item._id);
|
||||
result.plateModTpls = filteredPlates.map(item => item._id);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -346,8 +345,8 @@ export class BotEquipmentModGenerator
|
||||
const compatibleModsPool = modPool[parentTemplate._id];
|
||||
|
||||
if (
|
||||
!((parentTemplate._props.Slots.length || parentTemplate._props.Cartridges?.length)
|
||||
|| parentTemplate._props.Chambers?.length)
|
||||
!(parentTemplate._props.Slots.length || parentTemplate._props.Cartridges?.length
|
||||
|| parentTemplate._props.Chambers?.length)
|
||||
)
|
||||
{
|
||||
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)
|
||||
// Force spawn chance to be 100% to ensure it gets added
|
||||
if (
|
||||
modSlot === "mod_handguard" && modToAddTemplate._props.Slots.find((slot) =>
|
||||
slot._name === "mod_handguard"
|
||||
modSlot === "mod_handguard" && modToAddTemplate._props.Slots.find(slot =>
|
||||
slot._name === "mod_handguard",
|
||||
)
|
||||
&& !weapon.find((item) => item.slotId === "mod_launcher")
|
||||
&& !weapon.find(item => item.slotId === "mod_launcher")
|
||||
)
|
||||
{
|
||||
// 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
|
||||
// Or if mod_stock is configured to be forced on
|
||||
if (
|
||||
modSlot === "mod_stock" && (modToAddTemplate._props.Slots.find((slot) =>
|
||||
slot._name.includes("mod_stock") || botEquipConfig.forceStock
|
||||
))
|
||||
modSlot === "mod_stock" && modToAddTemplate._props.Slots.find(slot =>
|
||||
slot._name.includes("mod_stock") || botEquipConfig.forceStock,
|
||||
)
|
||||
)
|
||||
{
|
||||
// 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_000":
|
||||
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":
|
||||
return parentTemplate._props.Cartridges.find((c) => c._name.toLowerCase() === modSlotLower);
|
||||
return parentTemplate._props.Cartridges.find(c => c._name.toLowerCase() === modSlotLower);
|
||||
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]
|
||||
{
|
||||
/** 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];
|
||||
|
||||
// It's ammo, use predefined ammo parameter
|
||||
@ -950,8 +949,8 @@ export class BotEquipmentModGenerator
|
||||
if (modSpawnResult === ModSpawn.DEFAULT_MOD)
|
||||
{
|
||||
const matchingPreset = this.getMatchingPreset(weaponTemplate, parentTemplate._id);
|
||||
const matchingMod = matchingPreset._items.find((item) =>
|
||||
item?.slotId?.toLowerCase() === modSlot.toLowerCase()
|
||||
const matchingMod = matchingPreset._items.find(item =>
|
||||
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
|
||||
@ -967,8 +966,8 @@ export class BotEquipmentModGenerator
|
||||
}
|
||||
|
||||
// Check the filter of the slot to ensure a chosen mod fits
|
||||
const parentSlotCompatibleItems = parentTemplate._props.Slots?.find((slot) =>
|
||||
slot._name.toLowerCase() === modSlot.toLowerCase()
|
||||
const parentSlotCompatibleItems = parentTemplate._props.Slots?.find(slot =>
|
||||
slot._name.toLowerCase() === modSlot.toLowerCase(),
|
||||
)._props.filters[0].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,
|
||||
): 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)
|
||||
{
|
||||
const supportedSubMods = desiredSlotObject._props.filters[0].Filter;
|
||||
@ -1262,7 +1261,7 @@ export class BotEquipmentModGenerator
|
||||
const blacklist = this.itemFilterService.getBlacklistedItems().concat(
|
||||
botEquipBlacklist.equipment[modSlot] || [],
|
||||
);
|
||||
result = allowedMods.filter((tpl) => !blacklist.includes(tpl));
|
||||
result = allowedMods.filter(tpl => !blacklist.includes(tpl));
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1288,7 +1287,7 @@ export class BotEquipmentModGenerator
|
||||
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
|
||||
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)
|
||||
// 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) =>
|
||||
["mod_scope", "mod_scope_000"].includes(slot._name)
|
||||
const scopeSlot = itemDetails._props.Slots.filter(slot =>
|
||||
["mod_scope", "mod_scope_000"].includes(slot._name),
|
||||
);
|
||||
|
||||
// Mods scope slot found must allow ALL whitelisted scope types OR be a mount
|
||||
if (
|
||||
scopeSlot?.every((slot) =>
|
||||
slot._props.filters[0].Filter.every((tpl) =>
|
||||
scopeSlot?.every(slot =>
|
||||
slot._props.filters[0].Filter.every(tpl =>
|
||||
this.itemHelper.isOfBaseclasses(tpl, whitelistedSightTypes)
|
||||
|| this.itemHelper.isOfBaseclass(tpl, BaseClasses.MOUNT)
|
||||
)
|
||||
|| this.itemHelper.isOfBaseclass(tpl, BaseClasses.MOUNT),
|
||||
),
|
||||
)
|
||||
)
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { BotInventoryGenerator } from "@spt-aki/generators/BotInventoryGenerator";
|
||||
import { BotLevelGenerator } from "@spt-aki/generators/BotLevelGenerator";
|
||||
import { BotDifficultyHelper } from "@spt-aki/helpers/BotDifficultyHelper";
|
||||
@ -111,7 +110,7 @@ export class BotGenerator
|
||||
|
||||
// Get raw json data for bot (Cloned)
|
||||
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);
|
||||
@ -446,7 +445,7 @@ export class BotGenerator
|
||||
}
|
||||
|
||||
return skillToAdd;
|
||||
}).filter((x) => x !== null);
|
||||
}).filter(x => x !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -546,7 +545,7 @@ export class BotGenerator
|
||||
Nickname: bot.Info.Nickname,
|
||||
Side: bot.Info.Side,
|
||||
Level: bot.Info.Level,
|
||||
Time: (new Date().toISOString()),
|
||||
Time: new Date().toISOString(),
|
||||
Status: "Killed by ",
|
||||
KillerAccountId: "Unknown",
|
||||
KillerProfileId: "Unknown",
|
||||
@ -557,7 +556,7 @@ export class BotGenerator
|
||||
|
||||
const inventoryItem: Item = {
|
||||
_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,
|
||||
slotId: "Dogtag",
|
||||
location: undefined,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { BotEquipmentModGenerator } from "@spt-aki/generators/BotEquipmentModGenerator";
|
||||
import { BotLootGenerator } from "@spt-aki/generators/BotLootGenerator";
|
||||
import { BotWeaponGenerator } from "@spt-aki/generators/BotWeaponGenerator";
|
||||
@ -308,12 +307,11 @@ export class BotInventoryGenerator
|
||||
*/
|
||||
protected generateEquipment(settings: IGenerateEquipmentProperties): boolean
|
||||
{
|
||||
const spawnChance =
|
||||
([EquipmentSlots.POCKETS, EquipmentSlots.SECURED_CONTAINER] as string[]).includes(
|
||||
settings.rootEquipmentSlot,
|
||||
)
|
||||
? 100
|
||||
: settings.spawnChances.equipment[settings.rootEquipmentSlot];
|
||||
const spawnChance = ([EquipmentSlots.POCKETS, EquipmentSlots.SECURED_CONTAINER] as string[])
|
||||
.includes(settings.rootEquipmentSlot)
|
||||
? 100
|
||||
: settings.spawnChances.equipment[settings.rootEquipmentSlot];
|
||||
|
||||
if (typeof spawnChance === "undefined")
|
||||
{
|
||||
this.logger.warning(
|
||||
@ -444,7 +442,7 @@ export class BotInventoryGenerator
|
||||
for (const modSlot of Object.keys(modPool ?? []))
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -503,7 +501,7 @@ export class BotInventoryGenerator
|
||||
* @param equipmentChances Chances bot has certain equipment
|
||||
* @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);
|
||||
return [{ slot: EquipmentSlots.FIRST_PRIMARY_WEAPON, shouldSpawn: shouldSpawnPrimary }, {
|
||||
@ -532,7 +530,7 @@ export class BotInventoryGenerator
|
||||
*/
|
||||
protected addWeaponAndMagazinesToInventory(
|
||||
sessionId: string,
|
||||
weaponSlot: { slot: EquipmentSlots; shouldSpawn: boolean; },
|
||||
weaponSlot: { slot: EquipmentSlots, shouldSpawn: boolean },
|
||||
templateInventory: Inventory,
|
||||
botInventory: PmcInventory,
|
||||
equipmentChances: Chances,
|
||||
@ -567,18 +565,18 @@ export class BotInventoryGenerator
|
||||
export interface IGenerateEquipmentProperties
|
||||
{
|
||||
/** Root Slot being generated */
|
||||
rootEquipmentSlot: string;
|
||||
rootEquipmentSlot: string
|
||||
/** Equipment pool for root slot being generated */
|
||||
rootEquipmentPool: Record<string, number>;
|
||||
modPool: Mods;
|
||||
rootEquipmentPool: Record<string, number>
|
||||
modPool: Mods
|
||||
/** Dictionary of mod items and their chance to spawn for this bot type */
|
||||
spawnChances: Chances;
|
||||
spawnChances: Chances
|
||||
/** Role being generated for */
|
||||
botRole: string;
|
||||
botRole: string
|
||||
/** Level of bot being generated */
|
||||
botLevel: number;
|
||||
inventory: PmcInventory;
|
||||
botEquipmentConfig: EquipmentFilters;
|
||||
botLevel: number
|
||||
inventory: PmcInventory
|
||||
botEquipmentConfig: EquipmentFilters
|
||||
/** Settings from bot.json to adjust how item is generated */
|
||||
randomisationDetails: RandomisationDetails;
|
||||
randomisationDetails: RandomisationDetails
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { MinMax } from "@spt-aki/models/common/MinMax";
|
||||
import { IRandomisedBotLevelResult } from "@spt-aki/models/eft/bot/IRandomisedBotLevelResult";
|
||||
import { IExpTable } from "@spt-aki/models/eft/common/IGlobals";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { BotWeaponGenerator } from "@spt-aki/generators/BotWeaponGenerator";
|
||||
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
|
||||
import { BotHelper } from "@spt-aki/helpers/BotHelper";
|
||||
@ -292,7 +291,7 @@ export class BotLootGenerator
|
||||
// Secure
|
||||
|
||||
// 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.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.SECURE, botJsonTemplate),
|
||||
@ -317,12 +316,12 @@ export class BotLootGenerator
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
if (botInventory.items.find((item) => item.slotId === EquipmentSlots.BACKPACK))
|
||||
if (botInventory.items.find(item => item.slotId === 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectAll, injectable } from "tsyringe";
|
||||
|
||||
import { BotEquipmentModGenerator } from "@spt-aki/generators/BotEquipmentModGenerator";
|
||||
import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen";
|
||||
import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
|
||||
@ -200,7 +199,7 @@ export class BotWeaponGenerator
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
@ -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
|
||||
const chamberSlotNames = weaponItemTemplate._props.Chambers.map((x) => x._name);
|
||||
const chamberSlotNames = weaponItemTemplate._props.Chambers.map(x => x._name);
|
||||
this.addCartridgeToChamber(weaponWithModsArray, ammoTpl, chamberSlotNames);
|
||||
}
|
||||
|
||||
// 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;
|
||||
if (ubglMod)
|
||||
{
|
||||
@ -246,7 +245,7 @@ export class BotWeaponGenerator
|
||||
{
|
||||
for (const slotId of chamberSlotIds)
|
||||
{
|
||||
const existingItemWithSlot = weaponWithModsArray.find((x) => x.slotId === slotId);
|
||||
const existingItemWithSlot = weaponWithModsArray.find(x => x.slotId === slotId);
|
||||
if (!existingItemWithSlot)
|
||||
{
|
||||
// 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
|
||||
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 weaponSlotItem = weaponItemArray.find((weaponItem) =>
|
||||
weaponItem.parentId === mod._id && weaponItem.slotId === slotName
|
||||
const weaponSlotItem = weaponItemArray.find(weaponItem =>
|
||||
weaponItem.parentId === mod._id && weaponItem.slotId === slotName,
|
||||
);
|
||||
if (!weaponSlotItem)
|
||||
{
|
||||
@ -442,7 +441,7 @@ export class BotWeaponGenerator
|
||||
ammoTemplate,
|
||||
inventory,
|
||||
);
|
||||
this.inventoryMagGenComponents.find((v) => v.canHandleInventoryMagGen(inventoryMagGenModel)).process(
|
||||
this.inventoryMagGenComponents.find(v => v.canHandleInventoryMagGen(inventoryMagGenModel)).process(
|
||||
inventoryMagGenModel,
|
||||
);
|
||||
|
||||
@ -468,13 +467,13 @@ export class BotWeaponGenerator
|
||||
): void
|
||||
{
|
||||
// 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];
|
||||
|
||||
// Define min/max of how many grenades bot will have
|
||||
const ubglMinMax: GenerationData = {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
weights: { "1": 1, "2": 1 },
|
||||
weights: { 1: 1, 2: 1 },
|
||||
whitelist: {},
|
||||
};
|
||||
|
||||
@ -489,7 +488,7 @@ export class BotWeaponGenerator
|
||||
ubglAmmoDbTemplate,
|
||||
inventory,
|
||||
);
|
||||
this.inventoryMagGenComponents.find((v) => v.canHandleInventoryMagGen(ubglAmmoGenModel)).process(
|
||||
this.inventoryMagGenComponents.find(v => v.canHandleInventoryMagGen(ubglAmmoGenModel)).process(
|
||||
ubglAmmoGenModel,
|
||||
);
|
||||
|
||||
@ -537,7 +536,7 @@ export class BotWeaponGenerator
|
||||
botRole: string,
|
||||
): string
|
||||
{
|
||||
const magazine = weaponMods.find((m) => m.slotId === this.modMagazineSlotId);
|
||||
const magazine = weaponMods.find(m => m.slotId === this.modMagazineSlotId);
|
||||
if (!magazine)
|
||||
{
|
||||
// Edge case - magazineless chamber loaded weapons dont have magazines, e.g. mp18
|
||||
@ -737,8 +736,8 @@ export class BotWeaponGenerator
|
||||
magazineTemplate: ITemplateItem,
|
||||
): void
|
||||
{
|
||||
const magazineCartridgeChildItem = weaponWithMods.find((m) =>
|
||||
m.parentId === magazine._id && m.slotId === "cartridges"
|
||||
const magazineCartridgeChildItem = weaponWithMods.find(m =>
|
||||
m.parentId === magazine._id && m.slotId === "cartridges",
|
||||
);
|
||||
if (magazineCartridgeChildItem)
|
||||
{
|
||||
@ -767,7 +766,7 @@ export class BotWeaponGenerator
|
||||
// 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,
|
||||
// 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)
|
||||
{
|
||||
camora._tpl = ammoTpl;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
|
||||
@ -50,7 +49,7 @@ export class FenceBaseAssortGenerator
|
||||
const blockedSeasonalItems = this.seasonalEventService.getInactiveSeasonalEventItems();
|
||||
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
|
||||
if (this.itemFilterService.isItemBlacklisted(rootItemDb._id))
|
||||
@ -144,7 +143,7 @@ export class FenceBaseAssortGenerator
|
||||
for (const defaultPreset of defaultPresets)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
@ -252,7 +251,7 @@ export class FenceBaseAssortGenerator
|
||||
}
|
||||
|
||||
// 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;
|
||||
if (hasRequiredSlots)
|
||||
{
|
||||
@ -284,8 +283,8 @@ export class FenceBaseAssortGenerator
|
||||
}
|
||||
|
||||
// Check for and add plate items
|
||||
const plateSlots = itemDbDetails._props.Slots.filter((slot) =>
|
||||
this.itemHelper.isRemovablePlateSlot(slot._name)
|
||||
const plateSlots = itemDbDetails._props.Slots.filter(slot =>
|
||||
this.itemHelper.isRemovablePlateSlot(slot._name),
|
||||
);
|
||||
if (plateSlots.length > 0)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
export interface IFilterPlateModsForSlotByLevelResult
|
||||
{
|
||||
result: Result;
|
||||
plateModTpls: string[];
|
||||
result: Result
|
||||
plateModTpls: string[]
|
||||
}
|
||||
|
||||
export enum Result
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ContainerHelper } from "@spt-aki/helpers/ContainerHelper";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
|
||||
@ -29,17 +28,17 @@ import { ProbabilityObject, ProbabilityObjectArray, RandomUtil } from "@spt-aki/
|
||||
|
||||
export interface IContainerItem
|
||||
{
|
||||
items: Item[];
|
||||
width: number;
|
||||
height: number;
|
||||
items: Item[]
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
export interface IContainerGroupCount
|
||||
{
|
||||
/** 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 */
|
||||
chosenCount: number;
|
||||
chosenCount: number
|
||||
}
|
||||
|
||||
@injectable()
|
||||
@ -135,7 +134,7 @@ export class LocationGenerator
|
||||
// Randomisation is turned off globally or just turned off for this map
|
||||
if (
|
||||
!(this.locationConfig.containerRandomisationSettings.enabled
|
||||
&& this.locationConfig.containerRandomisationSettings.maps[locationId])
|
||||
&& this.locationConfig.containerRandomisationSettings.maps[locationId])
|
||||
)
|
||||
{
|
||||
this.logger.debug(
|
||||
@ -218,8 +217,8 @@ export class LocationGenerator
|
||||
for (const chosenContainerId of chosenContainerIds)
|
||||
{
|
||||
// Look up container object from full list of containers on map
|
||||
const containerObject = staticRandomisableContainersOnMap.find((staticContainer) =>
|
||||
staticContainer.template.Id === chosenContainerId
|
||||
const containerObject = staticRandomisableContainersOnMap.find(staticContainer =>
|
||||
staticContainer.template.Id === chosenContainerId,
|
||||
);
|
||||
if (!containerObject)
|
||||
{
|
||||
@ -262,11 +261,11 @@ export class LocationGenerator
|
||||
*/
|
||||
protected getRandomisableContainersOnMap(staticContainers: IStaticContainerData[]): IStaticContainerData[]
|
||||
{
|
||||
return staticContainers.filter((staticContainer) =>
|
||||
return staticContainers.filter(staticContainer =>
|
||||
staticContainer.probability !== 1 && !staticContainer.template.IsAlwaysSpawn
|
||||
&& !this.locationConfig.containerRandomisationSettings.containerTypesToNotRandomise.includes(
|
||||
staticContainer.template.Items[0]._tpl,
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -277,11 +276,11 @@ export class LocationGenerator
|
||||
*/
|
||||
protected getGuaranteedContainers(staticContainersOnMap: IStaticContainerData[]): IStaticContainerData[]
|
||||
{
|
||||
return staticContainersOnMap.filter((staticContainer) =>
|
||||
return staticContainersOnMap.filter(staticContainer =>
|
||||
staticContainer.probability === 1 || staticContainer.template.IsAlwaysSpawn
|
||||
|| this.locationConfig.containerRandomisationSettings.containerTypesToNotRandomise.includes(
|
||||
staticContainer.template.Items[0]._tpl,
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -338,11 +337,11 @@ export class LocationGenerator
|
||||
chosenCount: this.randomUtil.getInt(
|
||||
Math.round(
|
||||
groupData.minContainers
|
||||
* this.locationConfig.containerRandomisationSettings.containerGroupMinSizeMultiplier,
|
||||
* this.locationConfig.containerRandomisationSettings.containerGroupMinSizeMultiplier,
|
||||
),
|
||||
Math.round(
|
||||
groupData.maxContainers
|
||||
* this.locationConfig.containerRandomisationSettings.containerGroupMaxSizeMultiplier,
|
||||
* this.locationConfig.containerRandomisationSettings.containerGroupMaxSizeMultiplier,
|
||||
),
|
||||
),
|
||||
};
|
||||
@ -412,9 +411,9 @@ export class LocationGenerator
|
||||
const containerLootPool = this.getPossibleLootItemsForContainer(containerTpl, staticLootDist);
|
||||
|
||||
// Some containers need to have items forced into it (quest keys etc)
|
||||
const tplsForced = staticForced.filter((forcedStaticProp) =>
|
||||
forcedStaticProp.containerId === containerClone.template.Id
|
||||
).map((x) => x.itemTpl);
|
||||
const tplsForced = staticForced.filter(forcedStaticProp =>
|
||||
forcedStaticProp.containerId === containerClone.template.Id,
|
||||
).map(x => x.itemTpl);
|
||||
|
||||
// Draw random loot
|
||||
// Money spawn more than once in container
|
||||
@ -427,7 +426,7 @@ export class LocationGenerator
|
||||
itemCountToAdd,
|
||||
this.locationConfig.allowDuplicateItemsInStaticContainers,
|
||||
locklist,
|
||||
).filter((tpl) => !tplsForced.includes(tpl));
|
||||
).filter(tpl => !tplsForced.includes(tpl));
|
||||
|
||||
// Add forced loot to chosen item pool
|
||||
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`
|
||||
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
|
||||
this.addForcedLoot(loot, dynamicForcedSpawnPoints, locationName);
|
||||
@ -607,10 +606,10 @@ export class LocationGenerator
|
||||
// Draw from random distribution
|
||||
const desiredSpawnpointCount = Math.round(
|
||||
this.getLooseLootMultiplerForLocation(locationName)
|
||||
* this.randomUtil.getNormallyDistributedRandomNumber(
|
||||
dynamicLootDist.spawnpointCount.mean,
|
||||
dynamicLootDist.spawnpointCount.std,
|
||||
),
|
||||
* this.randomUtil.getNormallyDistributedRandomNumber(
|
||||
dynamicLootDist.spawnpointCount.mean,
|
||||
dynamicLootDist.spawnpointCount.std,
|
||||
),
|
||||
);
|
||||
|
||||
// Positions not in forced but have 100% chance to spawn
|
||||
@ -660,11 +659,11 @@ export class LocationGenerator
|
||||
|
||||
// Filter out duplicate locationIds
|
||||
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
|
||||
const tooManySpawnPointsRequested = (desiredSpawnpointCount - chosenSpawnpoints.length) > 0;
|
||||
const tooManySpawnPointsRequested = desiredSpawnpointCount - chosenSpawnpoints.length > 0;
|
||||
if (tooManySpawnPointsRequested)
|
||||
{
|
||||
this.logger.debug(
|
||||
@ -704,7 +703,7 @@ export class LocationGenerator
|
||||
{
|
||||
if (
|
||||
!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)
|
||||
{
|
||||
// Get all spawn positions for item tpl in forced loot array
|
||||
const items = forcedSpawnPoints.filter((forcedSpawnPoint) =>
|
||||
forcedSpawnPoint.template.Items[0]._tpl === itemTpl
|
||||
const items = forcedSpawnPoints.filter(forcedSpawnPoint =>
|
||||
forcedSpawnPoint.template.Items[0]._tpl === itemTpl,
|
||||
);
|
||||
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
|
||||
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;
|
||||
lootItem.Root = this.objectId.generate();
|
||||
lootItem.Items[0]._id = lootItem.Root;
|
||||
@ -816,8 +815,8 @@ export class LocationGenerator
|
||||
locationTemplateToAdd.Items[0]._id = locationTemplateToAdd.Root;
|
||||
|
||||
// Push forced location into array as long as it doesnt exist already
|
||||
const existingLocation = lootLocationTemplates.find((spawnPoint) =>
|
||||
spawnPoint.Id === locationTemplateToAdd.Id
|
||||
const existingLocation = lootLocationTemplates.find(spawnPoint =>
|
||||
spawnPoint.Id === locationTemplateToAdd.Id,
|
||||
);
|
||||
if (!existingLocation)
|
||||
{
|
||||
@ -845,7 +844,7 @@ export class LocationGenerator
|
||||
staticAmmoDist: Record<string, IStaticAmmoDetails[]>,
|
||||
): 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 itemTemplate = this.itemHelper.getItem(chosenTpl)[1];
|
||||
|
||||
@ -945,10 +944,10 @@ export class LocationGenerator
|
||||
{
|
||||
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
|
||||
@ -1052,7 +1051,7 @@ export class LocationGenerator
|
||||
// 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
|
||||
// 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
|
||||
if (magazine)
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
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 { RandomUtil } from "@spt-aki/utils/RandomUtil";
|
||||
|
||||
type ItemLimit = { current: number; max: number; };
|
||||
type ItemLimit = { current: number, max: number };
|
||||
|
||||
@injectable()
|
||||
export class LootGenerator
|
||||
@ -74,8 +73,8 @@ export class LootGenerator
|
||||
if (desiredWeaponCrateCount > 0)
|
||||
{
|
||||
// Get list of all sealed containers from db
|
||||
const sealedWeaponContainerPool = Object.values(tables.templates.items).filter((x) =>
|
||||
x._name.includes("event_container_airdrop")
|
||||
const sealedWeaponContainerPool = Object.values(tables.templates.items).filter(x =>
|
||||
x._name.includes("event_container_airdrop"),
|
||||
);
|
||||
|
||||
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
|
||||
const items = Object.entries(tables.templates.items).filter((x) =>
|
||||
const items = Object.entries(tables.templates.items).filter(x =>
|
||||
!itemBlacklist.has(x[1]._id)
|
||||
&& x[1]._type.toLowerCase() === "item"
|
||||
&& !x[1]._props.QuestItem
|
||||
&& options.itemTypeWhitelist.includes(x[1]._parent)
|
||||
&& options.itemTypeWhitelist.includes(x[1]._parent),
|
||||
);
|
||||
|
||||
if (items.length > 0)
|
||||
@ -122,8 +121,8 @@ export class LootGenerator
|
||||
);
|
||||
if (randomisedWeaponPresetCount > 0)
|
||||
{
|
||||
const weaponDefaultPresets = globalDefaultPresets.filter((preset) =>
|
||||
this.itemHelper.isOfBaseclass(preset._encyclopedia, BaseClasses.WEAPON)
|
||||
const weaponDefaultPresets = globalDefaultPresets.filter(preset =>
|
||||
this.itemHelper.isOfBaseclass(preset._encyclopedia, BaseClasses.WEAPON),
|
||||
);
|
||||
|
||||
if (weaponDefaultPresets.length > 0)
|
||||
@ -153,11 +152,11 @@ export class LootGenerator
|
||||
);
|
||||
if (randomisedArmorPresetCount > 0)
|
||||
{
|
||||
const armorDefaultPresets = globalDefaultPresets.filter((preset) =>
|
||||
this.itemHelper.armorItemCanHoldMods(preset._encyclopedia)
|
||||
const armorDefaultPresets = globalDefaultPresets.filter(preset =>
|
||||
this.itemHelper.armorItemCanHoldMods(preset._encyclopedia),
|
||||
);
|
||||
const levelFilteredArmorPresets = armorDefaultPresets.filter((armor) =>
|
||||
this.armorIsDesiredProtectionLevel(armor, options)
|
||||
const levelFilteredArmorPresets = armorDefaultPresets.filter(armor =>
|
||||
this.armorIsDesiredProtectionLevel(armor, options),
|
||||
);
|
||||
|
||||
// Add some armors to rewards
|
||||
@ -192,21 +191,21 @@ export class LootGenerator
|
||||
*/
|
||||
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)
|
||||
{
|
||||
const plateDb = this.itemHelper.getItem(frontPlate._tpl);
|
||||
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)
|
||||
{
|
||||
const plateDb = this.itemHelper.getItem(helmetTop._tpl);
|
||||
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)
|
||||
{
|
||||
const plateDb = this.itemHelper.getItem(softArmorFront._tpl);
|
||||
@ -242,7 +241,7 @@ export class LootGenerator
|
||||
*/
|
||||
protected findAndAddRandomItemToLoot(
|
||||
items: [string, ITemplateItem][],
|
||||
itemTypeCounts: Record<string, { current: number; max: number; }>,
|
||||
itemTypeCounts: Record<string, { current: number, max: number }>,
|
||||
options: LootRequest,
|
||||
result: LootItem[],
|
||||
): boolean
|
||||
@ -317,7 +316,7 @@ export class LootGenerator
|
||||
*/
|
||||
protected findAndAddRandomPresetToLoot(
|
||||
presetPool: IPreset[],
|
||||
itemTypeCounts: Record<string, { current: number; max: number; }>,
|
||||
itemTypeCounts: Record<string, { current: number, max: number }>,
|
||||
itemBlacklist: string[],
|
||||
result: LootItem[],
|
||||
): boolean
|
||||
@ -408,7 +407,7 @@ export class LootGenerator
|
||||
}
|
||||
|
||||
// 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.randomUtil.getArrayValue(this.presetHelper.getPresets(chosenWeaponTpl));
|
||||
|
||||
@ -473,7 +472,7 @@ export class LootGenerator
|
||||
|
||||
// Need to find boxes that matches weapons caliber
|
||||
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)
|
||||
{
|
||||
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
|
||||
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._type.toLowerCase() === "item"
|
||||
&& !this.itemFilterService.isItemBlacklisted(x._id)
|
||||
&& (!(containerSettings.allowBossItems || this.itemFilterService.isBossItem(x._id)))
|
||||
&& !x._props.QuestItem
|
||||
&& !(containerSettings.allowBossItems || this.itemFilterService.isBossItem(x._id))
|
||||
&& !x._props.QuestItem,
|
||||
);
|
||||
|
||||
if (rewardItemPool.length === 0)
|
||||
@ -547,8 +546,8 @@ export class LootGenerator
|
||||
}
|
||||
|
||||
// Get items that fulfil reward type criteria from items that fit on gun
|
||||
const relatedItems = linkedItemsToWeapon.filter((x) =>
|
||||
x._parent === rewardTypeId && !this.itemFilterService.isItemBlacklisted(x._id)
|
||||
const relatedItems = linkedItemsToWeapon.filter(x =>
|
||||
x._parent === rewardTypeId && !this.itemFilterService.isItemBlacklisted(x._id),
|
||||
);
|
||||
if (!relatedItems || relatedItems.length === 0)
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper";
|
||||
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
|
||||
@ -48,8 +47,8 @@ export class PMCLootGenerator
|
||||
if (Object.keys(this.pocketLootPool).length === 0)
|
||||
{
|
||||
const items = this.databaseServer.getTables().templates.items;
|
||||
const pmcPriceOverrides =
|
||||
this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items
|
||||
const pmcPriceOverrides
|
||||
= this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items
|
||||
.Pockets;
|
||||
|
||||
const allowedItemTypes = this.pmcConfig.pocketLoot.whitelist;
|
||||
@ -59,13 +58,13 @@ export class PMCLootGenerator
|
||||
// Blacklist inactive seasonal items
|
||||
itemBlacklist.push(...this.seasonalEventService.getInactiveSeasonalEventItems());
|
||||
|
||||
const itemsToAdd = Object.values(items).filter((item) =>
|
||||
const itemsToAdd = Object.values(items).filter(item =>
|
||||
allowedItemTypes.includes(item._parent)
|
||||
&& this.itemHelper.isValidItem(item._id)
|
||||
&& !pmcItemBlacklist.includes(item._id)
|
||||
&& !itemBlacklist.includes(item._id)
|
||||
&& item._props.Width === 1
|
||||
&& item._props.Height === 1
|
||||
&& item._props.Height === 1,
|
||||
);
|
||||
|
||||
for (const itemToAdd of itemsToAdd)
|
||||
@ -88,7 +87,7 @@ export class PMCLootGenerator
|
||||
{
|
||||
// Invert price so cheapest has a larger weight
|
||||
// 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);
|
||||
@ -107,8 +106,8 @@ export class PMCLootGenerator
|
||||
if (Object.keys(this.vestLootPool).length === 0)
|
||||
{
|
||||
const items = this.databaseServer.getTables().templates.items;
|
||||
const pmcPriceOverrides =
|
||||
this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items
|
||||
const pmcPriceOverrides
|
||||
= this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items
|
||||
.TacticalVest;
|
||||
|
||||
const allowedItemTypes = this.pmcConfig.vestLoot.whitelist;
|
||||
@ -118,12 +117,12 @@ export class PMCLootGenerator
|
||||
// Blacklist seasonal items
|
||||
itemBlacklist.push(...this.seasonalEventService.getInactiveSeasonalEventItems());
|
||||
|
||||
const itemsToAdd = Object.values(items).filter((item) =>
|
||||
const itemsToAdd = Object.values(items).filter(item =>
|
||||
allowedItemTypes.includes(item._parent)
|
||||
&& this.itemHelper.isValidItem(item._id)
|
||||
&& !pmcItemBlacklist.includes(item._id)
|
||||
&& !itemBlacklist.includes(item._id)
|
||||
&& this.itemFitsInto2By2Slot(item)
|
||||
&& this.itemFitsInto2By2Slot(item),
|
||||
);
|
||||
|
||||
for (const itemToAdd of itemsToAdd)
|
||||
@ -146,7 +145,7 @@ export class PMCLootGenerator
|
||||
{
|
||||
// Invert price so cheapest has a larger weight
|
||||
// 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);
|
||||
@ -176,8 +175,8 @@ export class PMCLootGenerator
|
||||
if (Object.keys(this.backpackLootPool).length === 0)
|
||||
{
|
||||
const items = this.databaseServer.getTables().templates.items;
|
||||
const pmcPriceOverrides =
|
||||
this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items
|
||||
const pmcPriceOverrides
|
||||
= this.databaseServer.getTables().bots.types[botRole === "sptBear" ? "bear" : "usec"].inventory.items
|
||||
.Backpack;
|
||||
|
||||
const allowedItemTypes = this.pmcConfig.backpackLoot.whitelist;
|
||||
@ -187,11 +186,11 @@ export class PMCLootGenerator
|
||||
// Blacklist seasonal items
|
||||
itemBlacklist.push(...this.seasonalEventService.getInactiveSeasonalEventItems());
|
||||
|
||||
const itemsToAdd = Object.values(items).filter((item) =>
|
||||
const itemsToAdd = Object.values(items).filter(item =>
|
||||
allowedItemTypes.includes(item._parent)
|
||||
&& this.itemHelper.isValidItem(item._id)
|
||||
&& !pmcItemBlacklist.includes(item._id)
|
||||
&& !itemBlacklist.includes(item._id)
|
||||
&& !itemBlacklist.includes(item._id),
|
||||
);
|
||||
|
||||
for (const itemToAdd of itemsToAdd)
|
||||
@ -214,7 +213,7 @@ export class PMCLootGenerator
|
||||
{
|
||||
// Invert price so cheapest has a larger weight
|
||||
// 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);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { BotGenerator } from "@spt-aki/generators/BotGenerator";
|
||||
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
|
||||
import { BotHelper } from "@spt-aki/helpers/BotHelper";
|
||||
@ -310,7 +309,7 @@ export class PlayerScavGenerator
|
||||
protected getScavLevel(scavProfile: IPmcData): number
|
||||
{
|
||||
// Info can be null on initial account creation
|
||||
if (!(scavProfile.Info?.Level))
|
||||
if (!scavProfile.Info?.Level)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -321,7 +320,7 @@ export class PlayerScavGenerator
|
||||
protected getScavExperience(scavProfile: IPmcData): number
|
||||
{
|
||||
// Info can be null on initial account creation
|
||||
if (!(scavProfile.Info?.Experience))
|
||||
if (!scavProfile.Info?.Experience)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -364,7 +363,7 @@ export class PlayerScavGenerator
|
||||
scavLockDuration = 10;
|
||||
}
|
||||
|
||||
scavData.Info.SavageLockTime = (Date.now() / 1000) + scavLockDuration;
|
||||
scavData.Info.SavageLockTime = Date.now() / 1000 + scavLockDuration;
|
||||
|
||||
return scavData;
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
|
||||
import { IPreset } from "@spt-aki/models/eft/common/IGlobals";
|
||||
@ -75,7 +74,7 @@ export class RagfairAssortGenerator
|
||||
const results: Item[][] = [];
|
||||
|
||||
/** 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 */
|
||||
const processedArmorItems: string[] = [];
|
||||
@ -136,7 +135,7 @@ export class RagfairAssortGenerator
|
||||
*/
|
||||
protected getPresetsToAdd(): IPreset[]
|
||||
{
|
||||
return (this.ragfairConfig.dynamic.showDefaultPresetsOnly)
|
||||
return this.ragfairConfig.dynamic.showDefaultPresetsOnly
|
||||
? Object.values(this.presetHelper.getDefaultPresets())
|
||||
: this.presetHelper.getAllPresets();
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { RagfairAssortGenerator } from "@spt-aki/generators/RagfairAssortGenerator";
|
||||
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
@ -37,7 +36,7 @@ import { TimeUtil } from "@spt-aki/utils/TimeUtil";
|
||||
export class RagfairOfferGenerator
|
||||
{
|
||||
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 */
|
||||
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 offer: IRagfairOffer = {
|
||||
@ -144,7 +143,7 @@ export class RagfairOfferGenerator
|
||||
intId: this.offerCounter,
|
||||
user: {
|
||||
id: this.getTraderId(userID),
|
||||
memberType: (userID === "ragfair")
|
||||
memberType: userID === "ragfair"
|
||||
? MemberCategory.DEFAULT
|
||||
: this.ragfairServerHelper.getMemberType(userID),
|
||||
nickname: this.ragfairServerHelper.getNickname(userID),
|
||||
@ -297,8 +296,8 @@ export class RagfairOfferGenerator
|
||||
if (this.ragfairServerHelper.isPlayer(userID))
|
||||
{
|
||||
// Player offer = current time + offerDurationTimeInHour;
|
||||
const offerDurationTimeHours =
|
||||
this.databaseServer.getTables().globals.config.RagFair.offerDurationTimeInHour;
|
||||
const offerDurationTimeHours
|
||||
= this.databaseServer.getTables().globals.config.RagFair.offerDurationTimeInHour;
|
||||
return this.timeUtil.getTimestamp() + Math.round(offerDurationTimeHours * TimeUtil.ONE_HOUR_AS_SECONDS);
|
||||
}
|
||||
|
||||
@ -311,10 +310,10 @@ export class RagfairOfferGenerator
|
||||
// Generated fake-player offer
|
||||
return Math.round(
|
||||
time
|
||||
+ this.randomUtil.getInt(
|
||||
this.ragfairConfig.dynamic.endTimeSeconds.min,
|
||||
this.ragfairConfig.dynamic.endTimeSeconds.max,
|
||||
),
|
||||
+ this.randomUtil.getInt(
|
||||
this.ragfairConfig.dynamic.endTimeSeconds.min,
|
||||
this.ragfairConfig.dynamic.endTimeSeconds.max,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -411,8 +410,8 @@ export class RagfairOfferGenerator
|
||||
return false;
|
||||
}
|
||||
|
||||
const plateSlots = presetWithChildren.filter((item) =>
|
||||
this.itemHelper.getRemovablePlateSlotIds().includes(item.slotId?.toLowerCase())
|
||||
const plateSlots = presetWithChildren.filter(item =>
|
||||
this.itemHelper.getRemovablePlateSlotIds().includes(item.slotId?.toLowerCase()),
|
||||
);
|
||||
if (plateSlots.length === 0)
|
||||
{
|
||||
@ -461,12 +460,12 @@ export class RagfairOfferGenerator
|
||||
|
||||
const isBarterOffer = this.randomUtil.getChance100(this.ragfairConfig.dynamic.barter.chancePercent);
|
||||
const isPackOffer = this.randomUtil.getChance100(this.ragfairConfig.dynamic.pack.chancePercent)
|
||||
&& !isBarterOffer
|
||||
&& itemWithChildren.length === 1
|
||||
&& this.itemHelper.isOfBaseclasses(
|
||||
itemWithChildren[0]._tpl,
|
||||
this.ragfairConfig.dynamic.pack.itemTypeWhitelist,
|
||||
);
|
||||
&& !isBarterOffer
|
||||
&& itemWithChildren.length === 1
|
||||
&& this.itemHelper.isOfBaseclasses(
|
||||
itemWithChildren[0]._tpl,
|
||||
this.ragfairConfig.dynamic.pack.itemTypeWhitelist,
|
||||
);
|
||||
|
||||
const randomUserId = this.hashUtil.generate();
|
||||
|
||||
@ -478,8 +477,8 @@ export class RagfairOfferGenerator
|
||||
const shouldRemovePlates = this.randomUtil.getChance100(armorConfig.removeRemovablePlateChance);
|
||||
if (shouldRemovePlates && this.itemHelper.armorItemHasRemovablePlateSlots(itemWithChildren[0]._tpl))
|
||||
{
|
||||
const offerItemPlatesToRemove = itemWithChildren.filter((item) =>
|
||||
armorConfig.plateSlotIdToRemovePool.includes(item.slotId?.toLowerCase())
|
||||
const offerItemPlatesToRemove = itemWithChildren.filter(item =>
|
||||
armorConfig.plateSlotIdToRemovePool.includes(item.slotId?.toLowerCase()),
|
||||
);
|
||||
|
||||
for (const plateItem of offerItemPlatesToRemove)
|
||||
@ -684,8 +683,8 @@ export class RagfairOfferGenerator
|
||||
this.randomiseArmorDurabilityValues(itemWithMods, currentMultiplier, maxMultiplier);
|
||||
|
||||
// Add hits to visor
|
||||
const visorMod = itemWithMods.find((item) =>
|
||||
item.parentId === BaseClasses.ARMORED_EQUIPMENT && item.slotId === "mod_equipment_000"
|
||||
const visorMod = itemWithMods.find(item =>
|
||||
item.parentId === BaseClasses.ARMORED_EQUIPMENT && item.slotId === "mod_equipment_000",
|
||||
);
|
||||
if (this.randomUtil.getChance100(25) && visorMod)
|
||||
{
|
||||
@ -717,7 +716,7 @@ export class RagfairOfferGenerator
|
||||
{
|
||||
// randomize key uses
|
||||
rootItem.upd.Key.NumberOfUsages = Math.round(itemDetails._props.MaximumNumberOfUsage * (1 - maxMultiplier))
|
||||
|| 0;
|
||||
|| 0;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -789,12 +788,12 @@ export class RagfairOfferGenerator
|
||||
for (const armorItem of armorWithMods)
|
||||
{
|
||||
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);
|
||||
|
||||
const lowestMaxDurability = this.randomUtil.getFloat(maxMultiplier, 1)
|
||||
* itemDbDetails._props.MaxDurability;
|
||||
* itemDbDetails._props.MaxDurability;
|
||||
const chosenMaxDurability = Math.round(
|
||||
this.randomUtil.getFloat(lowestMaxDurability, itemDbDetails._props.MaxDurability),
|
||||
);
|
||||
@ -888,9 +887,9 @@ export class RagfairOfferGenerator
|
||||
const fleaPrices = this.getFleaPricesAsArray();
|
||||
|
||||
// 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.tpl !== offerItems[0]._tpl
|
||||
&& x.tpl !== offerItems[0]._tpl,
|
||||
);
|
||||
|
||||
// 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`
|
||||
* @returns array with tpl/price values
|
||||
*/
|
||||
protected getFleaPricesAsArray(): { tpl: string; price: number; }[]
|
||||
protected getFleaPricesAsArray(): { tpl: string, price: number }[]
|
||||
{
|
||||
// Generate if needed
|
||||
if (!this.allowedFleaPriceItemsForBarter)
|
||||
@ -918,10 +917,10 @@ export class RagfairOfferGenerator
|
||||
const fleaArray = Object.entries(fleaPrices).map(([tpl, price]) => ({ tpl: tpl, price: price }));
|
||||
|
||||
// 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.itemHelper.isOfBaseclasses(x.tpl, this.ragfairConfig.dynamic.barter.itemTypeBlacklist)
|
||||
this.allowedFleaPriceItemsForBarter = filteredItems.filter(x =>
|
||||
!this.itemHelper.isOfBaseclasses(x.tpl, this.ragfairConfig.dynamic.barter.itemTypeBlacklist),
|
||||
);
|
||||
}
|
||||
|
||||
@ -943,7 +942,7 @@ export class RagfairOfferGenerator
|
||||
{
|
||||
const currency = this.ragfairServerHelper.getDynamicOfferCurrency();
|
||||
const price = this.ragfairPriceService.getDynamicOfferPriceForOffer(offerWithChildren, currency, isPackOffer)
|
||||
* multipler;
|
||||
* multipler;
|
||||
|
||||
return [{ count: price, _tpl: currency }];
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { RepeatableQuestRewardGenerator } from "@spt-aki/generators/RepeatableQuestRewardGenerator";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
import { RepeatableQuestHelper } from "@spt-aki/helpers/RepeatableQuestHelper";
|
||||
@ -42,7 +41,7 @@ export class RepeatableQuestGenerator
|
||||
@inject("ObjectId") protected objectId: ObjectId,
|
||||
@inject("RepeatableQuestHelper") protected repeatableQuestHelper: RepeatableQuestHelper,
|
||||
@inject("RepeatableQuestRewardGenerator") protected repeatableQuestRewardGenerator:
|
||||
RepeatableQuestRewardGenerator,
|
||||
RepeatableQuestRewardGenerator,
|
||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
||||
)
|
||||
{
|
||||
@ -68,11 +67,11 @@ export class RepeatableQuestGenerator
|
||||
const questType = this.randomUtil.drawRandomFromList<string>(questTypePool.types)[0];
|
||||
|
||||
// get traders from whitelist and filter by quest type availability
|
||||
let traders = repeatableConfig.traderWhitelist.filter((x) => x.questTypes.includes(questType)).map((x) =>
|
||||
x.traderId
|
||||
let traders = repeatableConfig.traderWhitelist.filter(x => x.questTypes.includes(questType)).map(x =>
|
||||
x.traderId,
|
||||
);
|
||||
// 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];
|
||||
|
||||
switch (questType)
|
||||
@ -159,15 +158,15 @@ export class RepeatableQuestGenerator
|
||||
return Math.sqrt(Math.sqrt(target) + bodyPart + dist + weaponRequirement) * kill;
|
||||
}
|
||||
|
||||
targetsConfig = targetsConfig.filter((x) =>
|
||||
Object.keys(questTypePool.pool.Elimination.targets).includes(x.key)
|
||||
targetsConfig = targetsConfig.filter(x =>
|
||||
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
|
||||
// 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
|
||||
questTypePool.types = questTypePool.types.filter((t) => t !== "Elimination");
|
||||
questTypePool.types = questTypePool.types.filter(t => t !== "Elimination");
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -189,12 +188,12 @@ export class RepeatableQuestGenerator
|
||||
}
|
||||
else
|
||||
{
|
||||
locations = locations.filter((l) => l !== "any");
|
||||
locations = locations.filter(l => l !== "any");
|
||||
if (locations.length > 0)
|
||||
{
|
||||
locationKey = this.randomUtil.drawRandomFromList<string>(locations)[0];
|
||||
questTypePool.pool.Elimination.targets[targetKey].locations = locations.filter((l) =>
|
||||
l !== locationKey
|
||||
questTypePool.pool.Elimination.targets[targetKey].locations = locations.filter(l =>
|
||||
l !== locationKey,
|
||||
);
|
||||
if (questTypePool.pool.Elimination.targets[targetKey].locations.length === 0)
|
||||
{
|
||||
@ -239,18 +238,18 @@ export class RepeatableQuestGenerator
|
||||
if (targetsConfig.data(targetKey).isBoss)
|
||||
{
|
||||
// Get all boss spawn information
|
||||
const bossSpawns = Object.values(this.databaseServer.getTables().locations).filter((x) =>
|
||||
"base" in x && "Id" in x.base
|
||||
).map((x) => ({ Id: x.base.Id, BossSpawn: x.base.BossLocationSpawn }));
|
||||
const bossSpawns = Object.values(this.databaseServer.getTables().locations).filter(x =>
|
||||
"base" in x && "Id" in x.base,
|
||||
).map(x => ({ Id: x.base.Id, BossSpawn: x.base.BossLocationSpawn }));
|
||||
// filter for the current boss to spawn on map
|
||||
const thisBossSpawns = bossSpawns.map((x) => ({
|
||||
const thisBossSpawns = bossSpawns.map(x => ({
|
||||
Id: x.Id,
|
||||
BossSpawn: x.BossSpawn.filter((e) => e.BossName === targetKey),
|
||||
})).filter((x) => x.BossSpawn.length > 0);
|
||||
BossSpawn: x.BossSpawn.filter(e => e.BossName === targetKey),
|
||||
})).filter(x => x.BossSpawn.length > 0);
|
||||
// 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
|
||||
isDistanceRequirementAllowed = isDistanceRequirementAllowed && (allowedSpawns.length > 0);
|
||||
isDistanceRequirementAllowed = isDistanceRequirementAllowed && allowedSpawns.length > 0;
|
||||
}
|
||||
|
||||
if (eliminationConfig.distProb > Math.random() && isDistanceRequirementAllowed)
|
||||
@ -258,7 +257,7 @@ export class RepeatableQuestGenerator
|
||||
// Random distance with lower values more likely; simple distribution for starters...
|
||||
distance = Math.floor(
|
||||
Math.abs(Math.random() - Math.random()) * (1 + eliminationConfig.maxDist - eliminationConfig.minDist)
|
||||
+ eliminationConfig.minDist,
|
||||
+ eliminationConfig.minDist,
|
||||
);
|
||||
distance = Math.ceil(distance / 5) * 5;
|
||||
distanceDifficulty = maxDistDifficulty * distance / eliminationConfig.maxDist;
|
||||
@ -270,14 +269,14 @@ export class RepeatableQuestGenerator
|
||||
// Filter out close range weapons from far distance requirement
|
||||
if (distance > 50)
|
||||
{
|
||||
weaponCategoryRequirementConfig = weaponCategoryRequirementConfig.filter((category) =>
|
||||
["Shotgun", "Pistol"].includes(category.key)
|
||||
weaponCategoryRequirementConfig = weaponCategoryRequirementConfig.filter(category =>
|
||||
["Shotgun", "Pistol"].includes(category.key),
|
||||
);
|
||||
}
|
||||
else if (distance < 20)
|
||||
{ // Filter out far range weapons from close distance requirement
|
||||
weaponCategoryRequirementConfig = weaponCategoryRequirementConfig.filter((category) =>
|
||||
["MarksmanRifle", "DMR"].includes(category.key)
|
||||
weaponCategoryRequirementConfig = weaponCategoryRequirementConfig.filter(category =>
|
||||
["MarksmanRifle", "DMR"].includes(category.key),
|
||||
);
|
||||
}
|
||||
|
||||
@ -310,7 +309,7 @@ export class RepeatableQuestGenerator
|
||||
bodyPartDifficulty / maxBodyPartsDifficulty,
|
||||
distanceDifficulty / maxDistDifficulty,
|
||||
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
|
||||
@ -498,27 +497,27 @@ export class RepeatableQuestGenerator
|
||||
this.mathUtil.interp1(pmcLevel, levelsConfig, roublesConfig) * this.randomUtil.getFloat(0.5, 1),
|
||||
);
|
||||
roublesBudget = Math.max(roublesBudget, 5000);
|
||||
let itemSelection = possibleItemsToRetrievePool.filter((x) =>
|
||||
this.itemHelper.getItemPrice(x[0]) < roublesBudget
|
||||
let itemSelection = possibleItemsToRetrievePool.filter(x =>
|
||||
this.itemHelper.getItemPrice(x[0]) < roublesBudget,
|
||||
);
|
||||
|
||||
// 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",...]}]
|
||||
if (repeatableConfig.questConfig.Completion.useWhitelist)
|
||||
{
|
||||
const itemWhitelist =
|
||||
this.databaseServer.getTables().templates.repeatableQuests.data.Completion.itemsWhitelist;
|
||||
const itemWhitelist
|
||||
= this.databaseServer.getTables().templates.repeatableQuests.data.Completion.itemsWhitelist;
|
||||
|
||||
// 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),
|
||||
[],
|
||||
);
|
||||
itemSelection = itemSelection.filter((x) =>
|
||||
{
|
||||
// Whitelist can contain item tpls and item base type ids
|
||||
return (itemIdsWhitelisted.some((v) => this.itemHelper.isOfBaseclass(x[0], v))
|
||||
|| itemIdsWhitelisted.includes(x[0]));
|
||||
return itemIdsWhitelisted.some(v => this.itemHelper.isOfBaseclass(x[0], v))
|
||||
|| itemIdsWhitelisted.includes(x[0]);
|
||||
});
|
||||
// check if items are missing
|
||||
// const flatList = itemSelection.reduce((a, il) => a.concat(il[0]), []);
|
||||
@ -527,19 +526,19 @@ export class RepeatableQuestGenerator
|
||||
|
||||
if (repeatableConfig.questConfig.Completion.useBlacklist)
|
||||
{
|
||||
const itemBlacklist =
|
||||
this.databaseServer.getTables().templates.repeatableQuests.data.Completion.itemsBlacklist;
|
||||
const itemBlacklist
|
||||
= this.databaseServer.getTables().templates.repeatableQuests.data.Completion.itemsBlacklist;
|
||||
|
||||
// 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),
|
||||
[],
|
||||
);
|
||||
|
||||
itemSelection = itemSelection.filter((x) =>
|
||||
{
|
||||
return itemIdsBlacklisted.every((v) => !this.itemHelper.isOfBaseclass(x[0], v))
|
||||
|| !itemIdsBlacklisted.includes(x[0]);
|
||||
return itemIdsBlacklisted.every(v => !this.itemHelper.isOfBaseclass(x[0], v))
|
||||
|| !itemIdsBlacklisted.includes(x[0]);
|
||||
});
|
||||
}
|
||||
|
||||
@ -602,7 +601,7 @@ export class RepeatableQuestGenerator
|
||||
if (roublesBudget > 0)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
break;
|
||||
@ -687,13 +686,13 @@ export class RepeatableQuestGenerator
|
||||
): IRepeatableQuest
|
||||
{
|
||||
const explorationConfig = repeatableConfig.questConfig.Exploration;
|
||||
const requiresSpecificExtract =
|
||||
Math.random() < repeatableConfig.questConfig.Exploration.specificExits.probability;
|
||||
const requiresSpecificExtract
|
||||
= Math.random() < repeatableConfig.questConfig.Exploration.specificExits.probability;
|
||||
|
||||
if (Object.keys(questTypePool.pool.Exploration.locations).length === 0)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -738,15 +737,13 @@ export class RepeatableQuestGenerator
|
||||
const mapExits = this.getLocationExitsForSide(locationKey, repeatableConfig.side);
|
||||
|
||||
// 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)
|
||||
const possibleExits = exitPool.filter((
|
||||
exit,
|
||||
) => (!("PassageRequirement" in exit)
|
||||
|| repeatableConfig.questConfig.Exploration.specificExits.passageRequirementWhitelist.includes(
|
||||
exit.PassageRequirement,
|
||||
))
|
||||
const possibleExits = exitPool.filter(exit => !("PassageRequirement" in exit)
|
||||
|| repeatableConfig.questConfig.Exploration.specificExits.passageRequirementWhitelist.includes(
|
||||
exit.PassageRequirement,
|
||||
),
|
||||
);
|
||||
|
||||
if (possibleExits.length === 0)
|
||||
@ -791,7 +788,7 @@ export class RepeatableQuestGenerator
|
||||
const mapExtracts = this.databaseServer.getTables().locations[locationKey.toLocaleLowerCase()]
|
||||
.allExtracts as Exit[];
|
||||
|
||||
return mapExtracts.filter((exit) => exit.Side === playerSide);
|
||||
return mapExtracts.filter(exit => exit.Side === playerSide);
|
||||
}
|
||||
|
||||
protected generatePickupQuest(
|
||||
@ -814,18 +811,18 @@ export class RepeatableQuestGenerator
|
||||
// const locationKey: string = this.randomUtil.drawRandomFromDict(questTypePool.pool.Pickup.locations)[0];
|
||||
// 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.value = itemCountToFetch;
|
||||
|
||||
const counterCreatorCondition = quest.conditions.AvailableForFinish.find((x) =>
|
||||
x.conditionType === "CounterCreator"
|
||||
const counterCreatorCondition = quest.conditions.AvailableForFinish.find(x =>
|
||||
x.conditionType === "CounterCreator",
|
||||
);
|
||||
// const locationCondition = counterCreatorCondition._props.counter.conditions.find(x => x._parent === "Location");
|
||||
// (locationCondition._props as ILocationConditionProps).target = [...locationTarget];
|
||||
|
||||
const equipmentCondition = counterCreatorCondition.counter.conditions.find((x) =>
|
||||
x.conditionType === "Equipment"
|
||||
const equipmentCondition = counterCreatorCondition.counter.conditions.find(x =>
|
||||
x.conditionType === "Equipment",
|
||||
);
|
||||
equipmentCondition.equipmentInclusive = [[itemTypeToFetchWithCount.itemType]];
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { HandbookHelper } from "@spt-aki/helpers/HandbookHelper";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
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
|
||||
const rewardXP = Math.floor(
|
||||
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(
|
||||
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(
|
||||
1,
|
||||
Math.round(this.mathUtil.interp1(pmcLevel, levelsConfig, itemsConfig)) + 1,
|
||||
);
|
||||
const rewardReputation =
|
||||
Math.round(
|
||||
const rewardReputation
|
||||
= Math.round(
|
||||
100 * effectiveDifficulty * this.mathUtil.interp1(pmcLevel, levelsConfig, reputationConfig)
|
||||
* this.randomUtil.getFloat(1 - rewardSpreadConfig, 1 + rewardSpreadConfig),
|
||||
* this.randomUtil.getFloat(1 - rewardSpreadConfig, 1 + rewardSpreadConfig),
|
||||
) / 100;
|
||||
const skillRewardChance = this.mathUtil.interp1(pmcLevel, levelsConfig, skillRewardChanceConfig);
|
||||
const skillPointReward = this.mathUtil.interp1(pmcLevel, levelsConfig, skillPointRewardConfig);
|
||||
@ -135,7 +134,7 @@ export class RepeatableQuestRewardGenerator
|
||||
this.addMoneyReward(traderId, rewards, rewardRoubles, rewardIndex);
|
||||
rewardIndex++;
|
||||
|
||||
const traderWhitelistDetails = repeatableConfig.traderWhitelist.find((x) => x.traderId === traderId);
|
||||
const traderWhitelistDetails = repeatableConfig.traderWhitelist.find(x => x.traderId === traderId);
|
||||
if (
|
||||
traderWhitelistDetails.rewardCanBeWeapon
|
||||
&& this.randomUtil.getChance100(traderWhitelistDetails.weaponRewardChancePercent)
|
||||
@ -151,7 +150,7 @@ export class RepeatableQuestRewardGenerator
|
||||
while (defaultPresetPool.hasValues())
|
||||
{
|
||||
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);
|
||||
if (presetPrice <= roublesBudget)
|
||||
{
|
||||
@ -309,13 +308,13 @@ export class RepeatableQuestRewardGenerator
|
||||
protected canIncreaseRewardItemStackSize(item: ITemplateItem, maxRoublePriceToStack: number): boolean
|
||||
{
|
||||
return this.presetHelper.getDefaultPresetOrItemPrice(item._id) < maxRoublePriceToStack
|
||||
&& !this.itemHelper.isOfBaseclasses(item._id, [
|
||||
BaseClasses.WEAPON,
|
||||
BaseClasses.ARMORED_EQUIPMENT,
|
||||
BaseClasses.AMMO,
|
||||
])
|
||||
&& !this.itemHelper.itemRequiresSoftInserts(item._id)
|
||||
&& this.randomUtil.getChance100(25);
|
||||
&& !this.itemHelper.isOfBaseclasses(item._id, [
|
||||
BaseClasses.WEAPON,
|
||||
BaseClasses.ARMORED_EQUIPMENT,
|
||||
BaseClasses.AMMO,
|
||||
])
|
||||
&& !this.itemHelper.itemRequiresSoftInserts(item._id)
|
||||
&& this.randomUtil.getChance100(25);
|
||||
}
|
||||
|
||||
protected calculateAmmoStackSizeThatFitsBudget(
|
||||
@ -355,7 +354,7 @@ export class RepeatableQuestRewardGenerator
|
||||
const rewardableItemPool = this.getRewardableItems(repeatableConfig, traderId);
|
||||
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,
|
||||
roublesBudget,
|
||||
@ -370,9 +369,9 @@ export class RepeatableQuestRewardGenerator
|
||||
}),
|
||||
);
|
||||
// In case we don't find any items in the price range
|
||||
rewardableItemPoolWithinBudget = rewardableItemPool.filter((x) =>
|
||||
this.itemHelper.getItemPrice(x[0]) < roublesBudget
|
||||
).map((x) => x[1]);
|
||||
rewardableItemPoolWithinBudget = rewardableItemPool.filter(x =>
|
||||
this.itemHelper.getItemPrice(x[0]) < roublesBudget,
|
||||
).map(x => x[1]);
|
||||
}
|
||||
|
||||
return rewardableItemPoolWithinBudget;
|
||||
@ -393,7 +392,7 @@ export class RepeatableQuestRewardGenerator
|
||||
|
||||
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.target = rootItem._id; // Target property and root items id must match
|
||||
}
|
||||
@ -436,8 +435,8 @@ export class RepeatableQuestRewardGenerator
|
||||
return false;
|
||||
}
|
||||
|
||||
const traderWhitelist = repeatableQuestConfig.traderWhitelist.find((trader) =>
|
||||
trader.traderId === traderId
|
||||
const traderWhitelist = repeatableQuestConfig.traderWhitelist.find(trader =>
|
||||
trader.traderId === traderId,
|
||||
);
|
||||
return this.isValidRewardItem(tpl, repeatableQuestConfig, traderWhitelist?.rewardBaseWhitelist);
|
||||
},
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
|
||||
import { Product } from "@spt-aki/models/eft/common/tables/IBotBase";
|
||||
@ -61,7 +60,7 @@ export class ScavCaseRewardGenerator
|
||||
this.cacheDbItems();
|
||||
|
||||
// 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);
|
||||
|
||||
// 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
|
||||
if (
|
||||
(item._type !== "Item")
|
||||
item._type !== "Item"
|
||||
|| this.scavCaseConfig.rewardItemBlacklist.includes(item._id)
|
||||
|| this.itemFilterService.isItemBlacklisted(item._id)
|
||||
)
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
|
||||
import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
|
||||
import { WeightedRandomHelper } from "@spt-aki/helpers/WeightedRandomHelper";
|
||||
@ -72,10 +71,10 @@ export class WeatherGenerator
|
||||
public getInRaidTime(): Date
|
||||
{
|
||||
// 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(
|
||||
(russiaOffset + (new Date().getTime() * this.weatherConfig.acceleration))
|
||||
% (this.timeUtil.getHoursAsSeconds(24) * 1000),
|
||||
(russiaOffset + new Date().getTime() * this.weatherConfig.acceleration)
|
||||
% (this.timeUtil.getHoursAsSeconds(24) * 1000),
|
||||
);
|
||||
}
|
||||
|
||||
@ -103,7 +102,7 @@ export class WeatherGenerator
|
||||
wind_direction: this.getWeightedWindDirection(),
|
||||
wind_gustiness: this.getRandomFloat("windGustiness"),
|
||||
rain: rain,
|
||||
rain_intensity: (rain > 1) ? this.getRandomFloat("rainIntensity") : 0,
|
||||
rain_intensity: rain > 1 ? this.getRandomFloat("rainIntensity") : 0,
|
||||
fog: this.getWeightedFog(),
|
||||
temp: this.getRandomFloat("temp"),
|
||||
pressure: this.getRandomFloat("pressure"),
|
||||
|
@ -2,7 +2,7 @@ import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
|
||||
|
||||
export interface IInventoryMagGen
|
||||
{
|
||||
getPriority(): number;
|
||||
canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean;
|
||||
process(inventoryMagGen: InventoryMagGen): void;
|
||||
getPriority(): number
|
||||
canHandleInventoryMagGen(inventoryMagGen: InventoryMagGen): boolean
|
||||
process(inventoryMagGen: InventoryMagGen): void
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen";
|
||||
import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
|
||||
import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen";
|
||||
import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
|
||||
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
|
||||
@ -154,15 +153,15 @@ export class ExternalInventoryMagGen implements IInventoryMagGen
|
||||
): ITemplateItem
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// All possible mags that fit into the weapon excluding blacklisted
|
||||
const magazinePool = magSlot._props.filters[0].Filter.filter((x) => !magazineBlacklist.includes(x)).map((x) =>
|
||||
this.itemHelper.getItem(x)[1]
|
||||
const magazinePool = magSlot._props.filters[0].Filter.filter(x => !magazineBlacklist.includes(x)).map(x =>
|
||||
this.itemHelper.getItem(x)[1],
|
||||
);
|
||||
if (!magazinePool)
|
||||
{
|
||||
@ -170,7 +169,7 @@ export class ExternalInventoryMagGen implements IInventoryMagGen
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
return null;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen";
|
||||
import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
|
||||
import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { IInventoryMagGen } from "@spt-aki/generators/weapongen/IInventoryMagGen";
|
||||
import { InventoryMagGen } from "@spt-aki/generators/weapongen/InventoryMagGen";
|
||||
import { BotWeaponGeneratorHelper } from "@spt-aki/helpers/BotWeaponGeneratorHelper";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
import { QuestHelper } from "@spt-aki/helpers/QuestHelper";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
@ -77,7 +76,7 @@ export class AssortHelper
|
||||
protected getQuestIdAndStatusThatShowAssort(
|
||||
mergedQuestAssorts: Record<string, Record<string, string>>,
|
||||
assortId: string,
|
||||
): { questId: string; status: QuestStatus[]; }
|
||||
): { questId: string, status: QuestStatus[] }
|
||||
{
|
||||
if (assortId in mergedQuestAssorts.started)
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { BotHelper } from "@spt-aki/helpers/BotHelper";
|
||||
import { Difficulty } from "@spt-aki/models/eft/common/tables/IBotType";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
|
||||
import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
|
||||
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
|
||||
* @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
|
||||
const raidSettings = this.applicationContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION)?.getValue<
|
||||
@ -123,7 +122,7 @@ export class BotGeneratorHelper
|
||||
? this.getBotEquipmentSettingFromConfig(botRole, "lightIsActiveNightChancePercent", 50)
|
||||
: this.getBotEquipmentSettingFromConfig(botRole, "lightIsActiveDayChancePercent", 25);
|
||||
itemProperties.Light = {
|
||||
IsActive: (this.randomUtil.getChance100(lightLaserActiveChance)),
|
||||
IsActive: this.randomUtil.getChance100(lightLaserActiveChance),
|
||||
SelectedMode: 0,
|
||||
};
|
||||
}
|
||||
@ -136,7 +135,7 @@ export class BotGeneratorHelper
|
||||
50,
|
||||
);
|
||||
itemProperties.Light = {
|
||||
IsActive: (this.randomUtil.getChance100(lightLaserActiveChance)),
|
||||
IsActive: this.randomUtil.getChance100(lightLaserActiveChance),
|
||||
SelectedMode: 0,
|
||||
};
|
||||
}
|
||||
@ -147,7 +146,7 @@ export class BotGeneratorHelper
|
||||
const nvgActiveChance = raidIsNight
|
||||
? this.getBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceNightPercent", 90)
|
||||
: this.getBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceDayPercent", 15);
|
||||
itemProperties.Togglable = { On: (this.randomUtil.getChance100(nvgActiveChance)) };
|
||||
itemProperties.Togglable = { On: this.randomUtil.getChance100(nvgActiveChance) };
|
||||
}
|
||||
|
||||
// Togglable face shield
|
||||
@ -159,7 +158,7 @@ export class BotGeneratorHelper
|
||||
"faceShieldIsActiveChancePercent",
|
||||
75,
|
||||
);
|
||||
itemProperties.Togglable = { On: (this.randomUtil.getChance100(faceShieldActiveChance)) };
|
||||
itemProperties.Togglable = { On: this.randomUtil.getChance100(faceShieldActiveChance) };
|
||||
}
|
||||
|
||||
return Object.keys(itemProperties).length ? { upd: itemProperties } : {};
|
||||
@ -288,7 +287,7 @@ export class BotGeneratorHelper
|
||||
): IChooseRandomCompatibleModResult
|
||||
{
|
||||
// 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 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
|
||||
const blockingItem = equippedItemsDb.find((x) => x._props.ConflictingItems?.includes(tplToCheck));
|
||||
const blockingItem = equippedItemsDb.find(x => x._props.ConflictingItems?.includes(tplToCheck));
|
||||
if (blockingItem)
|
||||
{
|
||||
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
|
||||
const blockingModItem = itemsEquipped.find((item) => itemToEquip._props.ConflictingItems?.includes(item._tpl));
|
||||
const blockingModItem = itemsEquipped.find(item => itemToEquip._props.ConflictingItems?.includes(item._tpl));
|
||||
if (blockingModItem)
|
||||
{
|
||||
return {
|
||||
@ -366,7 +365,7 @@ export class BotGeneratorHelper
|
||||
}
|
||||
|
||||
// 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 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
|
||||
let blockingItem = equippedItemsDb.find((x) => x._props[`Blocks${equipmentSlot}`]);
|
||||
let blockingItem = equippedItemsDb.find(x => x._props[`Blocks${equipmentSlot}`]);
|
||||
if (blockingItem)
|
||||
{
|
||||
// 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
|
||||
blockingItem = equippedItemsDb.find((x) => x._props.ConflictingItems?.includes(tplToCheck));
|
||||
blockingItem = equippedItemsDb.find(x => x._props.ConflictingItems?.includes(tplToCheck));
|
||||
if (blockingItem)
|
||||
{
|
||||
// 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
|
||||
if (itemToEquip._props.BlocksHeadwear)
|
||||
{
|
||||
const existingHeadwear = itemsEquipped.find((x) => x.slotId === "Headwear");
|
||||
const existingHeadwear = itemsEquipped.find(x => x.slotId === "Headwear");
|
||||
if (existingHeadwear)
|
||||
{
|
||||
return {
|
||||
@ -442,7 +441,7 @@ export class BotGeneratorHelper
|
||||
// Does item being checked get blocked/block existing item
|
||||
if (itemToEquip._props.BlocksFaceCover)
|
||||
{
|
||||
const existingFaceCover = itemsEquipped.find((item) => item.slotId === "FaceCover");
|
||||
const existingFaceCover = itemsEquipped.find(item => item.slotId === "FaceCover");
|
||||
if (existingFaceCover)
|
||||
{
|
||||
return {
|
||||
@ -458,7 +457,7 @@ export class BotGeneratorHelper
|
||||
// Does item being checked get blocked/block existing item
|
||||
if (itemToEquip._props.BlocksEarpiece)
|
||||
{
|
||||
const existingEarpiece = itemsEquipped.find((item) => item.slotId === "Earpiece");
|
||||
const existingEarpiece = itemsEquipped.find(item => item.slotId === "Earpiece");
|
||||
if (existingEarpiece)
|
||||
{
|
||||
return {
|
||||
@ -474,7 +473,7 @@ export class BotGeneratorHelper
|
||||
// Does item being checked get blocked/block existing item
|
||||
if (itemToEquip._props.BlocksArmorVest)
|
||||
{
|
||||
const existingArmorVest = itemsEquipped.find((item) => item.slotId === "ArmorVest");
|
||||
const existingArmorVest = itemsEquipped.find(item => item.slotId === "ArmorVest");
|
||||
if (existingArmorVest)
|
||||
{
|
||||
return {
|
||||
@ -488,7 +487,7 @@ export class BotGeneratorHelper
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
return ([this.pmcConfig.usecType.toLowerCase(), this.pmcConfig.bearType.toLowerCase()].includes(
|
||||
botRole.toLowerCase(),
|
||||
))
|
||||
return [this.pmcConfig.usecType.toLowerCase(), this.pmcConfig.bearType.toLowerCase()].includes(
|
||||
botRole.toLowerCase(),
|
||||
)
|
||||
? "pmc"
|
||||
: botRole;
|
||||
}
|
||||
@ -544,7 +543,7 @@ export class BotGeneratorHelper
|
||||
continue;
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
missingContainerCount++;
|
||||
@ -590,8 +589,8 @@ export class BotGeneratorHelper
|
||||
{
|
||||
// Grid is empty, skip or item size is bigger than grid
|
||||
if (
|
||||
(slotGrid._props.cellsH === 0 || slotGrid._props.cellsV === 0)
|
||||
|| (itemSize[0] * itemSize[1] > slotGrid._props.cellsV * slotGrid._props.cellsH)
|
||||
slotGrid._props.cellsH === 0 || slotGrid._props.cellsV === 0
|
||||
|| itemSize[0] * itemSize[1] > slotGrid._props.cellsV * slotGrid._props.cellsH
|
||||
)
|
||||
{
|
||||
continue;
|
||||
@ -605,12 +604,12 @@ export class BotGeneratorHelper
|
||||
}
|
||||
|
||||
// Get all root items in found container
|
||||
const existingContainerItems = inventory.items.filter((item) =>
|
||||
item.parentId === container._id && item.slotId === slotGrid._name
|
||||
const existingContainerItems = inventory.items.filter(item =>
|
||||
item.parentId === container._id && item.slotId === slotGrid._name,
|
||||
);
|
||||
|
||||
// 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)
|
||||
{
|
||||
// Look for children on items, insert into array if found
|
||||
@ -636,7 +635,7 @@ export class BotGeneratorHelper
|
||||
// Open slot found, add item to inventory
|
||||
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
|
||||
parentItem.parentId = container._id;
|
||||
@ -666,7 +665,7 @@ export class BotGeneratorHelper
|
||||
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 ((itemSize[0] === 1 && itemSize[1] === 1))
|
||||
if (itemSize[0] === 1 && itemSize[1] === 1)
|
||||
{
|
||||
containersIdFull.add(equipmentSlotId);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { MinMax } from "@spt-aki/models/common/MinMax";
|
||||
import { Difficulty, IBotType } from "@spt-aki/models/eft/common/tables/IBotType";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
@ -64,12 +63,12 @@ export class BotHelper
|
||||
*/
|
||||
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
|
||||
{
|
||||
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
|
||||
@ -186,7 +185,7 @@ export class BotHelper
|
||||
public rollChanceToBePmc(role: string, botConvertMinMax: MinMax): boolean
|
||||
{
|
||||
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
|
||||
@ -210,7 +209,7 @@ export class BotHelper
|
||||
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
|
||||
{
|
||||
return (this.randomUtil.getChance100(this.pmcConfig.isUsec))
|
||||
return this.randomUtil.getChance100(this.pmcConfig.isUsec)
|
||||
? this.pmcConfig.usecType
|
||||
: this.pmcConfig.bearType;
|
||||
}
|
||||
@ -248,6 +247,6 @@ export class BotHelper
|
||||
*/
|
||||
protected getRandomizedPmcSide(): string
|
||||
{
|
||||
return (this.randomUtil.getChance100(this.pmcConfig.isUsec)) ? "Usec" : "Bear";
|
||||
return this.randomUtil.getChance100(this.pmcConfig.isUsec) ? "Usec" : "Bear";
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { inject, injectable } from "tsyringe";
|
||||
|
||||
import { BotGeneratorHelper } from "@spt-aki/helpers/BotGeneratorHelper";
|
||||
import { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
||||
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 ammoMaxStackSize = this.itemHelper.getItem(firstSlotAmmoTpl)[1]?._props?.StackMaxSize ?? 1;
|
||||
chamberBulletCount = (ammoMaxStackSize === 1)
|
||||
chamberBulletCount = ammoMaxStackSize === 1
|
||||
? 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
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ export class ContainerHelper
|
||||
const limitX = containerX - minVolume;
|
||||
|
||||
// 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);
|
||||
}
|
||||
@ -44,7 +44,7 @@ export class ContainerHelper
|
||||
for (let y = 0; y < limitY; y++)
|
||||
{
|
||||
// Across
|
||||
if (container2D[y].every((x) => x === 1))
|
||||
if (container2D[y].every(x => x === 1))
|
||||
{
|
||||
// Every item in row is full, skip row
|
||||
continue;
|
||||
|
@ -26,7 +26,7 @@ export abstract class AbstractDialogueChatBot implements IDialogueChatBot
|
||||
|
||||
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(
|
||||
`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 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]))
|
||||
{
|
||||
return commandos[0].handle(splitCommand[1], this.getChatBot(), sessionId, request);
|
||||
|
@ -8,8 +8,8 @@ import { IUserDialogInfo } from "@spt-aki/models/eft/profile/IAkiProfile";
|
||||
export type ICommandoCommand = IChatCommand;
|
||||
export interface IChatCommand
|
||||
{
|
||||
getCommandPrefix(): string;
|
||||
getCommandHelp(command: string): string;
|
||||
getCommands(): Set<string>;
|
||||
handle(command: string, commandHandler: IUserDialogInfo, sessionId: string, request: ISendMessageRequest): string;
|
||||
getCommandPrefix(): string
|
||||
getCommandHelp(command: string): string
|
||||
getCommands(): Set<string>
|
||||
handle(command: string, commandHandler: IUserDialogInfo, sessionId: string, request: ISendMessageRequest): string
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { inject, injectAll, injectable } from "tsyringe";
|
||||
import { IChatCommand } from "@spt-aki/helpers/Dialogue/Commando/IChatCommand";
|
||||
import { ISptCommand } from "@spt-aki/helpers/Dialogue/Commando/SptCommands/ISptCommand";
|
||||
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 { ICoreConfig } from "@spt-aki/models/spt/config/ICoreConfig";
|
||||
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
|
||||
import { inject, injectAll, injectable } from "tsyringe";
|
||||
|
||||
@injectable()
|
||||
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 (
|
||||
!(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);
|
||||
}
|
||||
}
|
||||
|
||||
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.`);
|
||||
}
|
||||
@ -38,7 +38,7 @@ export class SptCommandoCommands implements IChatCommand
|
||||
|
||||
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
|
||||
@ -48,7 +48,7 @@ export class SptCommandoCommands implements IChatCommand
|
||||
|
||||
public getCommands(): Set<string>
|
||||
{
|
||||
return new Set(this.sptCommands.map((c) => c.getCommand()));
|
||||
return new Set(this.sptCommands.map(c => c.getCommand()));
|
||||
}
|
||||
|
||||
public handle(
|
||||
@ -58,7 +58,7 @@ export class SptCommandoCommands implements IChatCommand
|
||||
request: ISendMessageRequest,
|
||||
): string
|
||||
{
|
||||
return this.sptCommands.find((c) => c.getCommand() === command).performAction(
|
||||
return this.sptCommands.find(c => c.getCommand() === command).performAction(
|
||||
commandHandler,
|
||||
sessionId,
|
||||
request,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user