Fixed various Biome issues

This commit is contained in:
Dev 2024-07-23 17:30:20 +01:00
parent 5740774a46
commit 7be6b47e23
48 changed files with 326 additions and 318 deletions

View File

@ -18,6 +18,7 @@
"tests/__coverage__/*", "tests/__coverage__/*",
"types/*", "types/*",
"user/mods/*", "user/mods/*",
"user/profiles/*",
"assets/database/*" "assets/database/*"
] ]
}, },

View File

@ -49,7 +49,7 @@ export class ClientLogCallbacks {
data.isBeta = globalThis.G_WATERMARK_ENABLED; data.isBeta = globalThis.G_WATERMARK_ENABLED;
data.isModdable = globalThis.G_MODS_ENABLED; data.isModdable = globalThis.G_MODS_ENABLED;
data.isModded = this.modLoadOrder.getLoadOrder().length > 0 ? true : false; data.isModded = this.modLoadOrder.getLoadOrder().length > 0;
return this.httpResponse.noBody(data); return this.httpResponse.noBody(data);
} }

View File

@ -168,7 +168,7 @@ export class DataCallbacks {
let result = locales.global[localeId]; let result = locales.global[localeId];
if (result === undefined) { if (result === undefined) {
result = locales.global["en"]; result = locales.global.en;
} }
return this.httpResponse.getUnclearedBody(result); return this.httpResponse.getUnclearedBody(result);

View File

@ -29,7 +29,7 @@ export class ApplicationContext {
if (this.variables.has(type)) { if (this.variables.has(type)) {
const res: ContextVariable[] = []; const res: ContextVariable[] = [];
for (const value of this.variables.get(type)!.values()) { for (const value of this.variables.get(type).values()) {
res.push(value); res.push(value);
} }
@ -41,7 +41,7 @@ export class ApplicationContext {
public addValue(type: ContextVariableType, value: any): void { public addValue(type: ContextVariableType, value: any): void {
let list: LinkedList<ContextVariable>; let list: LinkedList<ContextVariable>;
if (this.variables.has(type)) { if (this.variables.has(type)) {
list = this.variables.get(type)!; list = this.variables.get(type);
} else { } else {
list = new LinkedList<ContextVariable>(); list = new LinkedList<ContextVariable>();
} }

View File

@ -48,7 +48,7 @@ export class CustomizationController {
if (matchingSuits === undefined) if (matchingSuits === undefined)
throw new Error(this.localisationService.getText("customisation-unable_to_get_trader_suits", traderID)); throw new Error(this.localisationService.getText("customisation-unable_to_get_trader_suits", traderID));
return matchedSuits!; return matchedSuits;
} }
/** /**

View File

@ -36,13 +36,11 @@ export class DialogueController {
if (!coreConfigs.features?.chatbotFeatures?.commandoEnabled) { if (!coreConfigs.features?.chatbotFeatures?.commandoEnabled) {
const sptCommando = this.dialogueChatBots.find( const sptCommando = this.dialogueChatBots.find(
(c) => c.getChatBot()._id.toLocaleLowerCase() === "sptcommando", (c) => c.getChatBot()._id.toLocaleLowerCase() === "sptcommando",
)!; );
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptCommando), 1); this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptCommando), 1);
} }
if (!coreConfigs.features?.chatbotFeatures?.sptFriendEnabled) { if (!coreConfigs.features?.chatbotFeatures?.sptFriendEnabled) {
const sptFriend = this.dialogueChatBots.find( const sptFriend = this.dialogueChatBots.find((c) => c.getChatBot()._id.toLocaleLowerCase() === "sptFriend");
(c) => c.getChatBot()._id.toLocaleLowerCase() === "sptFriend",
)!;
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptFriend), 1); this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptFriend), 1);
} }
} }
@ -205,7 +203,7 @@ export class DialogueController {
if (!profile.dialogues[request.dialogId].Users) { if (!profile.dialogues[request.dialogId].Users) {
profile.dialogues[request.dialogId].Users = []; profile.dialogues[request.dialogId].Users = [];
} }
profile.dialogues[request.dialogId].Users!.push(chatBot.getChatBot()); profile.dialogues[request.dialogId].Users.push(chatBot.getChatBot());
} }
} }
} }

View File

@ -797,8 +797,8 @@ export class GameController {
*/ */
protected validateQuestAssortUnlocksExist(): void { protected validateQuestAssortUnlocksExist(): void {
const db = this.databaseService.getTables(); const db = this.databaseService.getTables();
const traders = db.traders!; const traders = db.traders;
const quests = db.templates!.quests; const quests = db.templates.quests;
for (const traderId of Object.values(Traders)) { for (const traderId of Object.values(Traders)) {
const traderData = traders[traderId]; const traderData = traders[traderId];
const traderAssorts = traderData?.assort; const traderAssorts = traderData?.assort;
@ -875,7 +875,7 @@ export class GameController {
* Make non-trigger-spawned raiders spawn earlier + always * Make non-trigger-spawned raiders spawn earlier + always
*/ */
protected adjustLabsRaiderSpawnRate(): void { protected adjustLabsRaiderSpawnRate(): void {
const labsBase = this.databaseService.getLocations().laboratory!.base; const labsBase = this.databaseService.getLocations().laboratory.base;
// Find spawns with empty string for triggerId/TriggerName // Find spawns with empty string for triggerId/TriggerName
const nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.filter( const nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.filter(

View File

@ -905,7 +905,7 @@ export class InventoryController {
this.logger.success(`Item ${mailEvent.entity} is now blacklisted`); this.logger.success(`Item ${mailEvent.entity} is now blacklisted`);
break; break;
case "HideoutAreaLevel": case "HideoutAreaLevel": {
const areaName = mailEvent.entity; const areaName = mailEvent.entity;
const newValue = mailEvent.value; const newValue = mailEvent.value;
const hideoutAreaCode = HideoutAreas[areaName.toUpperCase()]; const hideoutAreaCode = HideoutAreas[areaName.toUpperCase()];
@ -917,6 +917,7 @@ export class InventoryController {
} }
break; break;
}
default: default:
this.logger.warning(`Unhandled profile reward event: ${mailEvent.Type}`); this.logger.warning(`Unhandled profile reward event: ${mailEvent.Type}`);

View File

@ -120,6 +120,6 @@ export class MatchController {
/** Handle client/match/local/end */ /** Handle client/match/local/end */
public endLocalRaid(sessionId: string, request: IEndLocalRaidRequestData): void { public endLocalRaid(sessionId: string, request: IEndLocalRaidRequestData): void {
return this.locationLifecycleService.endLocalRaid(sessionId, request); this.locationLifecycleService.endLocalRaid(sessionId, request);
} }
} }

View File

@ -344,7 +344,7 @@ export class QuestController {
); );
const change = {}; const change = {};
change[repeatableQuestProfile._id] = repeatableSettings!.changeRequirement[repeatableQuestProfile._id]; change[repeatableQuestProfile._id] = repeatableSettings.changeRequirement[repeatableQuestProfile._id];
const repeatableData: IPmcDataRepeatableQuest = { const repeatableData: IPmcDataRepeatableQuest = {
id: id:

View File

@ -703,11 +703,13 @@ export class RagfairController {
* @returns FleaOfferType * @returns FleaOfferType
*/ */
protected getOfferType(offerRequest: IAddOfferRequestData): FleaOfferType { protected getOfferType(offerRequest: IAddOfferRequestData): FleaOfferType {
if (offerRequest.items.length == 1 && !offerRequest.sellInOnePiece) { if (offerRequest.items.length === 1 && !offerRequest.sellInOnePiece) {
return FleaOfferType.SINGLE; return FleaOfferType.SINGLE;
} else if (offerRequest.items.length > 1 && !offerRequest.sellInOnePiece) { }
if (offerRequest.items.length > 1 && !offerRequest.sellInOnePiece) {
return FleaOfferType.MULTI; return FleaOfferType.MULTI;
} else if (offerRequest.sellInOnePiece) { }
if (offerRequest.sellInOnePiece) {
return FleaOfferType.PACK; return FleaOfferType.PACK;
} }

View File

@ -81,7 +81,7 @@ export class RepeatableQuestController {
*/ */
public getClientRepeatableQuests(sessionID: string): IPmcDataRepeatableQuest[] { public getClientRepeatableQuests(sessionID: string): IPmcDataRepeatableQuest[] {
const returnData: Array<IPmcDataRepeatableQuest> = []; const returnData: Array<IPmcDataRepeatableQuest> = [];
const fullProfile = this.profileHelper.getFullProfile(sessionID)!; const fullProfile = this.profileHelper.getFullProfile(sessionID);
const pmcData = fullProfile.characters.pmc; const pmcData = fullProfile.characters.pmc;
const currentTime = this.timeUtil.getTimestamp(); const currentTime = this.timeUtil.getTimestamp();

View File

@ -246,7 +246,7 @@ export class TradeController {
} }
// Does offer id exist in profile // Does offer id exist in profile
return offerCreatorProfile.RagfairInfo.offers.some((offer) => offer._id == offerId); return offerCreatorProfile.RagfairInfo.offers.some((offer) => offer._id === offerId);
} }
/** /**

View File

@ -759,7 +759,7 @@ export class BotEquipmentModGenerator {
} }
} }
if (request.modSlot == "mod_gas_block") { if (request.modSlot === "mod_gas_block") {
if (request.weaponStats.hasOptic && modPool.length > 1) { if (request.weaponStats.hasOptic && modPool.length > 1) {
// Attempt to limit modpool to low profile gas blocks when weapon has an optic // Attempt to limit modpool to low profile gas blocks when weapon has an optic
const onlyLowProfileGasBlocks = modPool.filter((tpl) => const onlyLowProfileGasBlocks = modPool.filter((tpl) =>
@ -782,18 +782,18 @@ export class BotEquipmentModGenerator {
// Pick random mod that's compatible // Pick random mod that's compatible
const chosenModResult = this.pickWeaponModTplForSlotFromPool( const chosenModResult = this.pickWeaponModTplForSlotFromPool(
modPool, modPool,
parentSlot!, parentSlot,
request.modSpawnResult, request.modSpawnResult,
request.weapon, request.weapon,
request.modSlot, request.modSlot,
); );
if (chosenModResult.slotBlocked && !parentSlot!._required) { if (chosenModResult.slotBlocked && !parentSlot._required) {
// Don't bother trying to fit mod, slot is completely blocked // Don't bother trying to fit mod, slot is completely blocked
return undefined; return undefined;
} }
// Log if mod chosen was incompatible // Log if mod chosen was incompatible
if (chosenModResult.incompatible && parentSlot!._required) { if (chosenModResult.incompatible && parentSlot._required) {
this.logger.debug(chosenModResult.reason); this.logger.debug(chosenModResult.reason);
// this.logger.debug(`Weapon: ${weapon.map(x => `${x._tpl} ${x.slotId ?? ""}`).join(",")}`) // this.logger.debug(`Weapon: ${weapon.map(x => `${x._tpl} ${x.slotId ?? ""}`).join(",")}`)
} }
@ -819,7 +819,7 @@ export class BotEquipmentModGenerator {
return undefined; return undefined;
} }
return this.itemHelper.getItem(chosenModResult.chosenTpl!); return this.itemHelper.getItem(chosenModResult.chosenTpl);
} }
/** /**
@ -847,7 +847,7 @@ export class BotEquipmentModGenerator {
const maxBlockedAttempts = Math.round(modPool.length * 0.75); // Roughly 75% of pool size const maxBlockedAttempts = Math.round(modPool.length * 0.75); // Roughly 75% of pool size
let blockedAttemptCount = 0; let blockedAttemptCount = 0;
while (exhaustableModPool.hasValues()) { while (exhaustableModPool.hasValues()) {
chosenTpl = exhaustableModPool.getRandomValue()!; chosenTpl = exhaustableModPool.getRandomValue();
if (choiceTypeEnum === ModSpawn.DEFAULT_MOD && modPool.length === 1) { if (choiceTypeEnum === ModSpawn.DEFAULT_MOD && modPool.length === 1) {
// Default mod wanted and only one choice in pool // Default mod wanted and only one choice in pool
chosenModResult.found = true; chosenModResult.found = true;
@ -1065,7 +1065,7 @@ export class BotEquipmentModGenerator {
const exhaustableModPool = new ExhaustableArray(allowedItems, this.randomUtil, this.cloner); const exhaustableModPool = new ExhaustableArray(allowedItems, this.randomUtil, this.cloner);
let tmpModTpl = fallbackModTpl; let tmpModTpl = fallbackModTpl;
while (exhaustableModPool.hasValues()) { while (exhaustableModPool.hasValues()) {
tmpModTpl = exhaustableModPool.getRandomValue()!; tmpModTpl = exhaustableModPool.getRandomValue();
if (!this.botGeneratorHelper.isItemIncompatibleWithCurrentItems(items, tmpModTpl, modSlot).incompatible) { if (!this.botGeneratorHelper.isItemIncompatibleWithCurrentItems(items, tmpModTpl, modSlot).incompatible) {
return tmpModTpl; return tmpModTpl;
} }

View File

@ -642,7 +642,7 @@ export class BotGenerator {
* @returns item tpl * @returns item tpl
*/ */
protected getDogtagTplByGameVersionAndSide(side: string, gameVersion: string): string { protected getDogtagTplByGameVersionAndSide(side: string, gameVersion: string): string {
if (side.toLowerCase() == "usec") { if (side.toLowerCase() === "usec") {
switch (gameVersion) { switch (gameVersion) {
case GameEditions.EDGE_OF_DARKNESS: case GameEditions.EDGE_OF_DARKNESS:
return ItemTpl.BARTER_DOGTAG_USEC_EOD; return ItemTpl.BARTER_DOGTAG_USEC_EOD;

View File

@ -440,8 +440,8 @@ export class LocationLootGenerator {
this.containerHelper.fillContainerMapWithItem( this.containerHelper.fillContainerMapWithItem(
containerMap, containerMap,
result.x!, result.x,
result.y!, result.y,
width, width,
height, height,
result.rotation, result.rotation,
@ -449,7 +449,7 @@ export class LocationLootGenerator {
const rotation = result.rotation ? 1 : 0; const rotation = result.rotation ? 1 : 0;
items[0].slotId = "main"; items[0].slotId = "main";
items[0].location = { x: result.x!, y: result.y!, r: rotation }; items[0].location = { x: result.x, y: result.y, r: rotation };
// Add loot to container before returning // Add loot to container before returning
for (const item of items) { for (const item of items) {
@ -470,8 +470,8 @@ export class LocationLootGenerator {
const containerTemplate = this.itemHelper.getItem(containerTpl)[1]; const containerTemplate = this.itemHelper.getItem(containerTpl)[1];
// Get height/width // Get height/width
const height = containerTemplate._props.Grids![0]._props.cellsV; const height = containerTemplate._props.Grids[0]._props.cellsV;
const width = containerTemplate._props.Grids![0]._props.cellsH; const width = containerTemplate._props.Grids[0]._props.cellsH;
// Calcualte 2d array and return // Calcualte 2d array and return
return Array(height) return Array(height)
@ -633,7 +633,7 @@ export class LocationLootGenerator {
if (randomSpawnpointCount > 0 && spawnpointArray.length > 0) { if (randomSpawnpointCount > 0 && spawnpointArray.length > 0) {
// Add randomly chosen spawn points // Add randomly chosen spawn points
for (const si of spawnpointArray.draw(randomSpawnpointCount, false)) { for (const si of spawnpointArray.draw(randomSpawnpointCount, false)) {
chosenSpawnpoints.push(spawnpointArray.data(si)!); chosenSpawnpoints.push(spawnpointArray.data(si));
} }
} }
@ -842,7 +842,7 @@ export class LocationLootGenerator {
const stackCount = const stackCount =
itemTemplate._props.StackMaxSize === 1 itemTemplate._props.StackMaxSize === 1
? 1 ? 1
: this.randomUtil.getInt(itemTemplate._props.StackMinRandom!, itemTemplate._props.StackMaxRandom!); : this.randomUtil.getInt(itemTemplate._props.StackMinRandom, itemTemplate._props.StackMaxRandom);
itemWithMods.push({ itemWithMods.push({
_id: this.objectId.generate(), _id: this.objectId.generate(),
@ -931,8 +931,8 @@ export class LocationLootGenerator {
parentId?: string, parentId?: string,
): IContainerItem { ): IContainerItem {
const itemTemplate = this.itemHelper.getItem(chosenTpl)[1]; const itemTemplate = this.itemHelper.getItem(chosenTpl)[1];
let width = itemTemplate._props.Width!; let width = itemTemplate._props.Width;
let height = itemTemplate._props.Height!; let height = itemTemplate._props.Height;
let items: Item[] = [{ _id: this.objectId.generate(), _tpl: chosenTpl }]; let items: Item[] = [{ _id: this.objectId.generate(), _tpl: chosenTpl }];
const rootItem = items[0]; const rootItem = items[0];
@ -949,7 +949,7 @@ export class LocationLootGenerator {
const stackCount = const stackCount =
itemTemplate._props.StackMaxSize === 1 itemTemplate._props.StackMaxSize === 1
? 1 ? 1
: this.randomUtil.getInt(itemTemplate._props.StackMinRandom!, itemTemplate._props.StackMaxRandom!); : this.randomUtil.getInt(itemTemplate._props.StackMinRandom, itemTemplate._props.StackMaxRandom);
rootItem.upd = { StackObjectsCount: stackCount }; rootItem.upd = { StackObjectsCount: stackCount };
} }

View File

@ -179,7 +179,7 @@ export class RagfairOfferGenerator {
const isPlayerOffer = this.profileHelper.isPlayer(userID); const isPlayerOffer = this.profileHelper.isPlayer(userID);
if (isPlayerOffer) { if (isPlayerOffer) {
const playerProfile = this.profileHelper.getPmcProfile(userID)!; const playerProfile = this.profileHelper.getPmcProfile(userID);
return { return {
id: playerProfile._id, id: playerProfile._id,
memberType: playerProfile.Info.MemberCategory, memberType: playerProfile.Info.MemberCategory,
@ -342,7 +342,7 @@ export class RagfairOfferGenerator {
// get assort items from param if they exist, otherwise grab freshly generated assorts // get assort items from param if they exist, otherwise grab freshly generated assorts
const assortItemsToProcess: Item[][] = replacingExpiredOffers const assortItemsToProcess: Item[][] = replacingExpiredOffers
? expiredOffers! ? expiredOffers
: this.ragfairAssortGenerator.getAssortItems(); : this.ragfairAssortGenerator.getAssortItems();
// Create offers for each item set concurrently // Create offers for each item set concurrently

View File

@ -88,7 +88,7 @@ export class BotGeneratorHelper {
itemProperties.MedKit = { itemProperties.MedKit = {
HpResource: this.getRandomizedResourceValue( HpResource: this.getRandomizedResourceValue(
itemTemplate._props.MaxHpResource, itemTemplate._props.MaxHpResource,
this.botConfig.lootItemResourceRandomization[botRole!]?.meds, this.botConfig.lootItemResourceRandomization[botRole]?.meds,
), ),
}; };
} }
@ -97,7 +97,7 @@ export class BotGeneratorHelper {
itemProperties.FoodDrink = { itemProperties.FoodDrink = {
HpPercent: this.getRandomizedResourceValue( HpPercent: this.getRandomizedResourceValue(
itemTemplate._props.MaxResource, itemTemplate._props.MaxResource,
this.botConfig.lootItemResourceRandomization[botRole!]?.food, this.botConfig.lootItemResourceRandomization[botRole]?.food,
), ),
}; };
} }
@ -236,8 +236,8 @@ export class BotGeneratorHelper {
let maxDurability: number; let maxDurability: number;
let currentDurability: number; let currentDurability: number;
if (Number.parseInt(`${itemTemplate._props.armorClass}`) === 0) { if (Number.parseInt(`${itemTemplate._props.armorClass}`) === 0) {
maxDurability = itemTemplate._props.MaxDurability!; maxDurability = itemTemplate._props.MaxDurability;
currentDurability = itemTemplate._props.MaxDurability!; currentDurability = itemTemplate._props.MaxDurability;
} else { } else {
maxDurability = this.durabilityLimitsHelper.getRandomizedMaxArmorDurability(itemTemplate, botRole); maxDurability = this.durabilityLimitsHelper.getRandomizedMaxArmorDurability(itemTemplate, botRole);
currentDurability = this.durabilityLimitsHelper.getRandomizedArmorDurability( currentDurability = this.durabilityLimitsHelper.getRandomizedArmorDurability(
@ -563,14 +563,14 @@ export class BotGeneratorHelper {
// Open slot found, add item to inventory // Open slot found, add item to inventory
if (findSlotResult.success) { if (findSlotResult.success) {
const parentItem = itemWithChildren.find((i) => i._id === rootItemId)!; const parentItem = itemWithChildren.find((i) => i._id === rootItemId);
// Set items parent to container id // Set items parent to container id
parentItem.parentId = container._id; parentItem.parentId = container._id;
parentItem.slotId = slotGrid._name; parentItem.slotId = slotGrid._name;
parentItem.location = { parentItem.location = {
x: findSlotResult.x!, x: findSlotResult.x,
y: findSlotResult.y!, y: findSlotResult.y,
r: findSlotResult.rotation ? 1 : 0, r: findSlotResult.rotation ? 1 : 0,
}; };

View File

@ -47,7 +47,7 @@ export class DurabilityLimitsHelper {
* @returns max durability * @returns max durability
*/ */
public getRandomizedMaxArmorDurability(itemTemplate: ITemplateItem, botRole?: string): number { public getRandomizedMaxArmorDurability(itemTemplate: ITemplateItem, botRole?: string): number {
const itemMaxDurability = itemTemplate._props.MaxDurability!; const itemMaxDurability = itemTemplate._props.MaxDurability;
if (botRole && this.botHelper.isBotPmc(botRole)) { if (botRole && this.botHelper.isBotPmc(botRole)) {
return this.generateMaxPmcArmorDurability(itemMaxDurability); return this.generateMaxPmcArmorDurability(itemMaxDurability);
@ -134,16 +134,16 @@ export class DurabilityLimitsHelper {
} }
protected getLowestMaxWeaponFromConfig(botRole?: string): number { protected getLowestMaxWeaponFromConfig(botRole?: string): number {
if (this.botConfig.durability[botRole!]) { if (this.botConfig.durability[botRole]) {
return this.botConfig.durability[botRole!].weapon.lowestMax; return this.botConfig.durability[botRole].weapon.lowestMax;
} }
return this.botConfig.durability.default.weapon.lowestMax; return this.botConfig.durability.default.weapon.lowestMax;
} }
protected getHighestMaxWeaponDurabilityFromConfig(botRole?: string): number { protected getHighestMaxWeaponDurabilityFromConfig(botRole?: string): number {
if (this.botConfig.durability[botRole!]) { if (this.botConfig.durability[botRole]) {
return this.botConfig.durability[botRole!].weapon.highestMax; return this.botConfig.durability[botRole].weapon.highestMax;
} }
return this.botConfig.durability.default.weapon.highestMax; return this.botConfig.durability.default.weapon.highestMax;
@ -176,48 +176,48 @@ export class DurabilityLimitsHelper {
} }
protected getMinWeaponDeltaFromConfig(botRole?: string): number { protected getMinWeaponDeltaFromConfig(botRole?: string): number {
if (this.botConfig.durability[botRole!]) { if (this.botConfig.durability[botRole]) {
return this.botConfig.durability[botRole!].weapon.minDelta; return this.botConfig.durability[botRole].weapon.minDelta;
} }
return this.botConfig.durability.default.weapon.minDelta; return this.botConfig.durability.default.weapon.minDelta;
} }
protected getMaxWeaponDeltaFromConfig(botRole?: string): number { protected getMaxWeaponDeltaFromConfig(botRole?: string): number {
if (this.botConfig.durability[botRole!]) { if (this.botConfig.durability[botRole]) {
return this.botConfig.durability[botRole!].weapon.maxDelta; return this.botConfig.durability[botRole].weapon.maxDelta;
} }
return this.botConfig.durability.default.weapon.maxDelta; return this.botConfig.durability.default.weapon.maxDelta;
} }
protected getMinArmorDeltaFromConfig(botRole?: string): number { protected getMinArmorDeltaFromConfig(botRole?: string): number {
if (this.botConfig.durability[botRole!]) { if (this.botConfig.durability[botRole]) {
return this.botConfig.durability[botRole!].armor.minDelta; return this.botConfig.durability[botRole].armor.minDelta;
} }
return this.botConfig.durability.default.armor.minDelta; return this.botConfig.durability.default.armor.minDelta;
} }
protected getMaxArmorDeltaFromConfig(botRole?: string): number { protected getMaxArmorDeltaFromConfig(botRole?: string): number {
if (this.botConfig.durability[botRole!]) { if (this.botConfig.durability[botRole]) {
return this.botConfig.durability[botRole!].armor.maxDelta; return this.botConfig.durability[botRole].armor.maxDelta;
} }
return this.botConfig.durability.default.armor.maxDelta; return this.botConfig.durability.default.armor.maxDelta;
} }
protected getMinArmorLimitPercentFromConfig(botRole?: string): number { protected getMinArmorLimitPercentFromConfig(botRole?: string): number {
if (this.botConfig.durability[botRole!]) { if (this.botConfig.durability[botRole]) {
return this.botConfig.durability[botRole!].armor.minLimitPercent; return this.botConfig.durability[botRole].armor.minLimitPercent;
} }
return this.botConfig.durability.default.armor.minLimitPercent; return this.botConfig.durability.default.armor.minLimitPercent;
} }
protected getMinWeaponLimitPercentFromConfig(botRole?: string): number { protected getMinWeaponLimitPercentFromConfig(botRole?: string): number {
if (this.botConfig.durability[botRole!]) { if (this.botConfig.durability[botRole]) {
return this.botConfig.durability[botRole!].weapon.minLimitPercent; return this.botConfig.durability[botRole].weapon.minLimitPercent;
} }
return this.botConfig.durability.default.weapon.minLimitPercent; return this.botConfig.durability.default.weapon.minLimitPercent;

View File

@ -35,7 +35,7 @@ export class HealthHelper {
if (!profile.vitality) { if (!profile.vitality) {
// Occurs on newly created profiles // Occurs on newly created profiles
profile.vitality = { health: undefined!, effects: undefined! }; profile.vitality = { health: undefined, effects: undefined };
} }
profile.vitality.health = { profile.vitality.health = {
Hydration: 0, Hydration: 0,
@ -176,7 +176,7 @@ export class HealthHelper {
const fullProfile = this.saveServer.getProfile(sessionID); const fullProfile = this.saveServer.getProfile(sessionID);
const profileEffects = fullProfile.vitality.effects; const profileEffects = fullProfile.vitality.effects;
this.storeHydrationEnergyTempInProfile(fullProfile, request.Hydration!, request.Energy!, request.Temperature!); this.storeHydrationEnergyTempInProfile(fullProfile, request.Hydration, request.Energy, request.Temperature);
// Process request data into profile // Process request data into profile
for (const bodyPart in postRaidBodyParts) { for (const bodyPart in postRaidBodyParts) {

View File

@ -268,7 +268,7 @@ export class ProfileHelper {
return { return {
Eft: { Eft: {
CarriedQuestItems: [], CarriedQuestItems: [],
DamageHistory: { LethalDamagePart: "Head", LethalDamage: undefined!, BodyParts: <any>[] }, DamageHistory: { LethalDamagePart: "Head", LethalDamage: undefined, BodyParts: <any>[] },
DroppedItems: [], DroppedItems: [],
ExperienceBonusMult: 0, ExperienceBonusMult: 0,
FoundInRaidItems: [], FoundInRaidItems: [],

View File

@ -715,14 +715,14 @@ export class RagfairOfferHelper {
protected isConditionItem(item: Item): boolean { protected isConditionItem(item: Item): boolean {
// thanks typescript, undefined assertion is not returnable since it // thanks typescript, undefined assertion is not returnable since it
// tries to return a multitype object // tries to return a multitype object
return item.upd.MedKit || return !!(
item.upd.MedKit ||
item.upd.Repairable || item.upd.Repairable ||
item.upd.Resource || item.upd.Resource ||
item.upd.FoodDrink || item.upd.FoodDrink ||
item.upd.Key || item.upd.Key ||
item.upd.RepairKit item.upd.RepairKit
? true );
: false;
} }
/** /**

View File

@ -61,8 +61,8 @@ export class RagfairSortHelper {
protected sortOffersByBarter(a: IRagfairOffer, b: IRagfairOffer): number { protected sortOffersByBarter(a: IRagfairOffer, b: IRagfairOffer): number {
const moneyTpls = Object.values<string>(Money); const moneyTpls = Object.values<string>(Money);
const aIsOnlyMoney = a.requirements.length == 1 && moneyTpls.includes(a.requirements[0]._tpl) ? 1 : 0; const aIsOnlyMoney = a.requirements.length === 1 && moneyTpls.includes(a.requirements[0]._tpl) ? 1 : 0;
const bIsOnlyMoney = b.requirements.length == 1 && moneyTpls.includes(b.requirements[0]._tpl) ? 1 : 0; const bIsOnlyMoney = b.requirements.length === 1 && moneyTpls.includes(b.requirements[0]._tpl) ? 1 : 0;
return aIsOnlyMoney - bIsOnlyMoney; return aIsOnlyMoney - bIsOnlyMoney;
} }

View File

@ -218,7 +218,7 @@ export class TraderAssortHelper {
*/ */
public traderAssortsHaveExpired(traderID: string): boolean { public traderAssortsHaveExpired(traderID: string): boolean {
const time = this.timeUtil.getTimestamp(); const time = this.timeUtil.getTimestamp();
const trader = this.databaseService.getTables().traders![traderID]; const trader = this.databaseService.getTables().traders[traderID];
return trader.base.nextResupply <= time; return trader.base.nextResupply <= time;
} }

View File

@ -149,13 +149,13 @@ export class TraderHelper {
// Force suit ids into profile // Force suit ids into profile
this.addSuitsToProfile( this.addSuitsToProfile(
fullProfile, fullProfile,
clothing!.map((suit) => suit.suiteId), clothing.map((suit) => suit.suiteId),
); );
} }
} }
if ((rawProfileTemplate.fleaBlockedDays ?? 0) > 0) { if ((rawProfileTemplate.fleaBlockedDays ?? 0) > 0) {
const newBanDateTime = this.timeUtil.getTimeStampFromNowDays(rawProfileTemplate.fleaBlockedDays!); const newBanDateTime = this.timeUtil.getTimeStampFromNowDays(rawProfileTemplate.fleaBlockedDays);
const existingBan = pmcData.Info.Bans.find((ban) => ban.banType === BanType.RAGFAIR); const existingBan = pmcData.Info.Bans.find((ban) => ban.banType === BanType.RAGFAIR);
if (existingBan) { if (existingBan) {
existingBan.dateTime = newBanDateTime; existingBan.dateTime = newBanDateTime;
@ -334,9 +334,9 @@ export class TraderHelper {
}, },
); );
return undefined; return undefined;
} else {
return this.randomUtil.getInt(traderDetails.seconds.min, traderDetails.seconds.max);
} }
return this.randomUtil.getInt(traderDetails.seconds.min, traderDetails.seconds.max);
} }
public getLoyaltyLevel(traderID: string, pmcData: IPmcData): LoyaltyLevel { public getLoyaltyLevel(traderID: string, pmcData: IPmcData): LoyaltyLevel {
@ -390,14 +390,14 @@ export class TraderHelper {
if ( if (
profile.traderPurchases[traderId][purchasedItem.itemId].count + purchasedItem.count > profile.traderPurchases[traderId][purchasedItem.itemId].count + purchasedItem.count >
this.getAccountTypeAdjustedTraderPurchaseLimit( this.getAccountTypeAdjustedTraderPurchaseLimit(
itemPurchased.upd!.BuyRestrictionMax!, itemPurchased.upd.BuyRestrictionMax,
profile.characters.pmc.Info.GameVersion, profile.characters.pmc.Info.GameVersion,
) )
) { ) {
throw new Error( throw new Error(
this.localisationService.getText("trader-unable_to_purchase_item_limit_reached", { this.localisationService.getText("trader-unable_to_purchase_item_limit_reached", {
traderId: traderId, traderId: traderId,
limit: itemPurchased.upd!.BuyRestrictionMax, limit: itemPurchased.upd.BuyRestrictionMax,
}), }),
); );
} }

View File

@ -11,7 +11,7 @@ export class HealthSaveLoadRouter extends SaveLoadRouter {
public override handleLoad(profile: ISptProfile): ISptProfile { public override handleLoad(profile: ISptProfile): ISptProfile {
if (!profile.vitality) { if (!profile.vitality) {
// Occurs on newly created profiles // Occurs on newly created profiles
profile.vitality = { health: undefined!, effects: undefined! }; profile.vitality = { health: undefined, effects: undefined };
} }
profile.vitality.health = { profile.vitality.health = {
Hydration: 0, Hydration: 0,

View File

@ -1,4 +1,4 @@
import { IncomingMessage } from "http"; import { IncomingMessage } from "node:http";
import { ProfileHelper } from "@spt/helpers/ProfileHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper";
import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent"; import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent";
import { ConfigTypes } from "@spt/models/enums/ConfigTypes"; import { ConfigTypes } from "@spt/models/enums/ConfigTypes";

View File

@ -60,7 +60,7 @@ export class AirdropService {
// Reparent loot items to create we added above // Reparent loot items to create we added above
for (const item of crateLoot) { for (const item of crateLoot) {
if (item._id == airdropCrateItem._id) { if (item._id === airdropCrateItem._id) {
// Crate itself, don't alter // Crate itself, don't alter
continue; continue;
} }

View File

@ -48,7 +48,7 @@ export class DatabaseService {
throw new Error(this.localisationService.getText("database-data_at_path_missing", "assets/database/bots")); throw new Error(this.localisationService.getText("database-data_at_path_missing", "assets/database/bots"));
} }
return this.databaseServer.getTables().bots!; return this.databaseServer.getTables().bots;
} }
/** /**
@ -61,7 +61,7 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().globals!; return this.databaseServer.getTables().globals;
} }
/** /**
@ -74,7 +74,7 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().hideout!; return this.databaseServer.getTables().hideout;
} }
/** /**
@ -87,7 +87,7 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().locales!; return this.databaseServer.getTables().locales;
} }
/** /**
@ -100,7 +100,7 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().locations!; return this.databaseServer.getTables().locations;
} }
/** /**
@ -115,7 +115,7 @@ export class DatabaseService {
throw new Error(this.localisationService.getText("database-no_location_found_with_id", locationId)); throw new Error(this.localisationService.getText("database-no_location_found_with_id", locationId));
} }
return desiredLocation!; return desiredLocation;
} }
/** /**
@ -128,7 +128,7 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().match!; return this.databaseServer.getTables().match;
} }
/** /**
@ -141,7 +141,7 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().server!; return this.databaseServer.getTables().server;
} }
/** /**
@ -154,7 +154,7 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().settings!; return this.databaseServer.getTables().settings;
} }
/** /**
@ -167,14 +167,14 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().templates!; return this.databaseServer.getTables().templates;
} }
/** /**
* @returns assets/database/templates/achievements.json * @returns assets/database/templates/achievements.json
*/ */
public getAchievements(): IAchievement[] { public getAchievements(): IAchievement[] {
if (!this.databaseServer.getTables().templates!.achievements) { if (!this.databaseServer.getTables().templates.achievements) {
throw new Error( throw new Error(
this.localisationService.getText( this.localisationService.getText(
"database-data_at_path_missing", "database-data_at_path_missing",
@ -183,14 +183,14 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().templates!.achievements!; return this.databaseServer.getTables().templates.achievements;
} }
/** /**
* @returns assets/database/templates/customisation.json * @returns assets/database/templates/customisation.json
*/ */
public getCustomization(): Record<string, ICustomizationItem> { public getCustomization(): Record<string, ICustomizationItem> {
if (!this.databaseServer.getTables().templates!.customization) { if (!this.databaseServer.getTables().templates.customization) {
throw new Error( throw new Error(
this.localisationService.getText( this.localisationService.getText(
"database-data_at_path_missing", "database-data_at_path_missing",
@ -199,14 +199,14 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().templates!.customization!; return this.databaseServer.getTables().templates.customization;
} }
/** /**
* @returns assets/database/templates/items.json * @returns assets/database/templates/items.json
*/ */
public getHandbook(): IHandbookBase { public getHandbook(): IHandbookBase {
if (!this.databaseServer.getTables().templates!.handbook) { if (!this.databaseServer.getTables().templates.handbook) {
throw new Error( throw new Error(
this.localisationService.getText( this.localisationService.getText(
"database-data_at_path_missing", "database-data_at_path_missing",
@ -215,14 +215,14 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().templates!.handbook!; return this.databaseServer.getTables().templates.handbook;
} }
/** /**
* @returns assets/database/templates/items.json * @returns assets/database/templates/items.json
*/ */
public getItems(): Record<string, ITemplateItem> { public getItems(): Record<string, ITemplateItem> {
if (!this.databaseServer.getTables().templates!.items) { if (!this.databaseServer.getTables().templates.items) {
throw new Error( throw new Error(
this.localisationService.getText( this.localisationService.getText(
"database-data_at_path_missing", "database-data_at_path_missing",
@ -231,14 +231,14 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().templates!.items!; return this.databaseServer.getTables().templates.items;
} }
/** /**
* @returns assets/database/templates/prices.json * @returns assets/database/templates/prices.json
*/ */
public getPrices(): Record<string, number> { public getPrices(): Record<string, number> {
if (!this.databaseServer.getTables().templates!.prices) { if (!this.databaseServer.getTables().templates.prices) {
throw new Error( throw new Error(
this.localisationService.getText( this.localisationService.getText(
"database-data_at_path_missing", "database-data_at_path_missing",
@ -247,14 +247,14 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().templates!.prices!; return this.databaseServer.getTables().templates.prices;
} }
/** /**
* @returns assets/database/templates/profiles.json * @returns assets/database/templates/profiles.json
*/ */
public getProfiles(): IProfileTemplates { public getProfiles(): IProfileTemplates {
if (!this.databaseServer.getTables().templates!.profiles) { if (!this.databaseServer.getTables().templates.profiles) {
throw new Error( throw new Error(
this.localisationService.getText( this.localisationService.getText(
"database-data_at_path_missing", "database-data_at_path_missing",
@ -263,14 +263,14 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().templates!.profiles!; return this.databaseServer.getTables().templates.profiles;
} }
/** /**
* @returns assets/database/templates/items.json * @returns assets/database/templates/items.json
*/ */
public getQuests(): Record<string, IQuest> { public getQuests(): Record<string, IQuest> {
if (!this.databaseServer.getTables().templates!.quests) { if (!this.databaseServer.getTables().templates.quests) {
throw new Error( throw new Error(
this.localisationService.getText( this.localisationService.getText(
"database-data_at_path_missing", "database-data_at_path_missing",
@ -279,7 +279,7 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().templates!.quests!; return this.databaseServer.getTables().templates.quests;
} }
/** /**
@ -292,7 +292,7 @@ export class DatabaseService {
); );
} }
return this.databaseServer.getTables().traders!; return this.databaseServer.getTables().traders;
} }
/** /**
@ -307,19 +307,19 @@ export class DatabaseService {
throw new Error(this.localisationService.getText("database-no_trader_found_with_id", traderId)); throw new Error(this.localisationService.getText("database-no_trader_found_with_id", traderId));
} }
return desiredTrader!; return desiredTrader;
} }
/** /**
* @returns assets/database/locationServices/ * @returns assets/database/locationServices/
*/ */
public getLocationServices(): ILocationServices { public getLocationServices(): ILocationServices {
if (!this.databaseServer.getTables().templates!.locationServices) { if (!this.databaseServer.getTables().templates.locationServices) {
throw new Error( throw new Error(
this.localisationService.getText("database-data_at_path_missing", "assets/database/locationServices"), this.localisationService.getText("database-data_at_path_missing", "assets/database/locationServices"),
); );
} }
return this.databaseServer.getTables().templates!.locationServices!; return this.databaseServer.getTables().templates.locationServices;
} }
} }

View File

@ -126,22 +126,22 @@ export class FenceService {
// Clone assorts so we can adjust prices before sending to client // Clone assorts so we can adjust prices before sending to client
const assort = this.cloner.clone(this.fenceAssort); const assort = this.cloner.clone(this.fenceAssort);
this.adjustAssortItemPricesByConfigMultiplier(assort!, 1, this.traderConfig.fence.presetPriceMult); this.adjustAssortItemPricesByConfigMultiplier(assort, 1, this.traderConfig.fence.presetPriceMult);
// merge normal fence assorts + discount assorts if player standing is large enough // merge normal fence assorts + discount assorts if player standing is large enough
if (pmcProfile.TradersInfo[Traders.FENCE].standing >= 6) { if (pmcProfile.TradersInfo[Traders.FENCE].standing >= 6) {
const discountAssort = this.cloner.clone(this.fenceDiscountAssort); const discountAssort = this.cloner.clone(this.fenceDiscountAssort);
this.adjustAssortItemPricesByConfigMultiplier( this.adjustAssortItemPricesByConfigMultiplier(
discountAssort!, discountAssort,
this.traderConfig.fence.discountOptions.itemPriceMult, this.traderConfig.fence.discountOptions.itemPriceMult,
this.traderConfig.fence.discountOptions.presetPriceMult, this.traderConfig.fence.discountOptions.presetPriceMult,
); );
const mergedAssorts = this.mergeAssorts(assort!, discountAssort!); const mergedAssorts = this.mergeAssorts(assort, discountAssort);
return mergedAssorts; return mergedAssorts;
} }
return assort!; return assort;
} }
/** /**
@ -172,7 +172,7 @@ export class FenceService {
createAssort.sptItems.push(clonedItems); createAssort.sptItems.push(clonedItems);
createAssort.loyal_level_items[root._id] = 1; createAssort.loyal_level_items[root._id] = 1;
this.updateFenceAssorts(createAssort, this.fenceAssort!); this.updateFenceAssorts(createAssort, this.fenceAssort);
} }
/** /**
@ -279,7 +279,7 @@ export class FenceService {
* @returns ITraderAssort * @returns ITraderAssort
*/ */
public getRawFenceAssorts(): ITraderAssort { public getRawFenceAssorts(): ITraderAssort {
return this.mergeAssorts(this.cloner.clone(this.fenceAssort!), this.cloner.clone(this.fenceDiscountAssort!)); return this.mergeAssorts(this.cloner.clone(this.fenceAssort), this.cloner.clone(this.fenceDiscountAssort));
} }
/** /**
@ -300,45 +300,45 @@ export class FenceService {
); );
// Simulate players buying items // Simulate players buying items
this.deleteRandomAssorts(itemCountToReplace, this.fenceAssort!); this.deleteRandomAssorts(itemCountToReplace, this.fenceAssort);
this.deleteRandomAssorts(discountItemCountToReplace, this.fenceDiscountAssort!); this.deleteRandomAssorts(discountItemCountToReplace, this.fenceDiscountAssort);
const normalItemCountsToGenerate = this.getItemCountsToGenerate( const normalItemCountsToGenerate = this.getItemCountsToGenerate(
this.fenceAssort!.items, this.fenceAssort.items,
this.desiredAssortCounts.normal, this.desiredAssortCounts.normal,
); );
const newItems = this.createAssorts(normalItemCountsToGenerate, 1); const newItems = this.createAssorts(normalItemCountsToGenerate, 1);
// Push newly generated assorts into existing data // Push newly generated assorts into existing data
this.updateFenceAssorts(newItems, this.fenceAssort!); this.updateFenceAssorts(newItems, this.fenceAssort);
const discountItemCountsToGenerate = this.getItemCountsToGenerate( const discountItemCountsToGenerate = this.getItemCountsToGenerate(
this.fenceDiscountAssort!.items, this.fenceDiscountAssort.items,
this.desiredAssortCounts.discount, this.desiredAssortCounts.discount,
); );
const newDiscountItems = this.createAssorts(discountItemCountsToGenerate, 2); const newDiscountItems = this.createAssorts(discountItemCountsToGenerate, 2);
// Push newly generated discount assorts into existing data // Push newly generated discount assorts into existing data
this.updateFenceAssorts(newDiscountItems, this.fenceDiscountAssort!); this.updateFenceAssorts(newDiscountItems, this.fenceDiscountAssort);
// Add new barter items to fence barter scheme // Add new barter items to fence barter scheme
for (const barterItemKey in newItems.barter_scheme) { for (const barterItemKey in newItems.barter_scheme) {
this.fenceAssort!.barter_scheme[barterItemKey] = newItems.barter_scheme[barterItemKey]; this.fenceAssort.barter_scheme[barterItemKey] = newItems.barter_scheme[barterItemKey];
} }
// Add loyalty items to fence assorts loyalty object // Add loyalty items to fence assorts loyalty object
for (const loyaltyItemKey in newItems.loyal_level_items) { for (const loyaltyItemKey in newItems.loyal_level_items) {
this.fenceAssort!.loyal_level_items[loyaltyItemKey] = newItems.loyal_level_items[loyaltyItemKey]; this.fenceAssort.loyal_level_items[loyaltyItemKey] = newItems.loyal_level_items[loyaltyItemKey];
} }
// Add new barter items to fence assorts discounted barter scheme // Add new barter items to fence assorts discounted barter scheme
for (const barterItemKey in newDiscountItems.barter_scheme) { for (const barterItemKey in newDiscountItems.barter_scheme) {
this.fenceDiscountAssort!.barter_scheme[barterItemKey] = newDiscountItems.barter_scheme[barterItemKey]; this.fenceDiscountAssort.barter_scheme[barterItemKey] = newDiscountItems.barter_scheme[barterItemKey];
} }
// Add loyalty items to fence discount assorts loyalty object // Add loyalty items to fence discount assorts loyalty object
for (const loyaltyItemKey in newDiscountItems.loyal_level_items) { for (const loyaltyItemKey in newDiscountItems.loyal_level_items) {
this.fenceDiscountAssort!.loyal_level_items[loyaltyItemKey] = this.fenceDiscountAssort.loyal_level_items[loyaltyItemKey] =
newDiscountItems.loyal_level_items[loyaltyItemKey]; newDiscountItems.loyal_level_items[loyaltyItemKey];
} }
@ -387,11 +387,11 @@ export class FenceService {
) { ) {
// Guard against a missing stack count // Guard against a missing stack count
if (existingRootItem.upd?.StackObjectsCount === undefined) { if (existingRootItem.upd?.StackObjectsCount === undefined) {
existingRootItem.upd!.StackObjectsCount = 1; existingRootItem.upd.StackObjectsCount = 1;
} }
// Merge new items count into existing, dont add new loyalty/barter data as it already exists // Merge new items count into existing, dont add new loyalty/barter data as it already exists
existingRootItem.upd!.StackObjectsCount += newRootItem?.upd?.StackObjectsCount ?? 1; existingRootItem.upd.StackObjectsCount += newRootItem?.upd?.StackObjectsCount ?? 1;
continue; continue;
} }
@ -493,7 +493,7 @@ export class FenceService {
} }
// Reduce stack to at smallest, 1 // Reduce stack to at smallest, 1
rootItemToAdjust.upd!.StackObjectsCount! -= Math.max(1, itemCountToRemove); rootItemToAdjust.upd.StackObjectsCount -= Math.max(1, itemCountToRemove);
return; return;
} }
@ -689,7 +689,7 @@ export class FenceService {
); );
const itemDbDetails = this.itemHelper.getItem(chosenBaseAssortRoot._tpl)[1]; const itemDbDetails = this.itemHelper.getItem(chosenBaseAssortRoot._tpl)[1];
const itemLimitCount = this.getMatchingItemLimit(itemTypeLimits, itemDbDetails._id)!; const itemLimitCount = this.getMatchingItemLimit(itemTypeLimits, itemDbDetails._id);
if (itemLimitCount?.current >= itemLimitCount?.max) { if (itemLimitCount?.current >= itemLimitCount?.max) {
// Skip adding item as assort as limit reached, decrement i counter so we still get another item // Skip adding item as assort as limit reached, decrement i counter so we still get another item
i--; i--;
@ -723,7 +723,7 @@ export class FenceService {
const rootItemBeingAdded = desiredAssortItemAndChildrenClone[0]; const rootItemBeingAdded = desiredAssortItemAndChildrenClone[0];
// Set stack size based on possible overrides, e.g. ammos, otherwise set to 1 // Set stack size based on possible overrides, e.g. ammos, otherwise set to 1
rootItemBeingAdded.upd!.StackObjectsCount = this.getSingleItemStackCount(itemDbDetails); rootItemBeingAdded.upd.StackObjectsCount = this.getSingleItemStackCount(itemDbDetails);
// Only randomise upd values for single // Only randomise upd values for single
const isSingleStack = (rootItemBeingAdded.upd?.StackObjectsCount ?? 0) === 1; const isSingleStack = (rootItemBeingAdded.upd?.StackObjectsCount ?? 0) === 1;
@ -732,12 +732,12 @@ export class FenceService {
} }
// Skip items already in the assort if it exists in the prevent duplicate list // Skip items already in the assort if it exists in the prevent duplicate list
const existingItemThatMatches = this.getMatchingItem(rootItemBeingAdded, itemDbDetails, assorts.sptItems)!; const existingItemThatMatches = this.getMatchingItem(rootItemBeingAdded, itemDbDetails, assorts.sptItems);
const shouldBeStacked = this.itemShouldBeForceStacked(existingItemThatMatches, itemDbDetails); const shouldBeStacked = this.itemShouldBeForceStacked(existingItemThatMatches, itemDbDetails);
if (shouldBeStacked && existingItemThatMatches) { if (shouldBeStacked && existingItemThatMatches) {
// Decrement loop counter so another items gets added // Decrement loop counter so another items gets added
i--; i--;
existingItemThatMatches.upd!.StackObjectsCount!++; existingItemThatMatches.upd.StackObjectsCount++;
continue; continue;
} }
@ -803,7 +803,7 @@ export class FenceService {
// Items have sub properties that need to be checked against // Items have sub properties that need to be checked against
for (const item of matchingItems) { for (const item of matchingItems) {
if (isMedical && rootItemBeingAdded.upd!.MedKit?.HpResource === item.upd!.MedKit?.HpResource) { if (isMedical && rootItemBeingAdded.upd.MedKit?.HpResource === item.upd.MedKit?.HpResource) {
// e.g. bandages with multiple use // e.g. bandages with multiple use
// Both undefined === both max resoruce left // Both undefined === both max resoruce left
return item; return item;
@ -812,8 +812,8 @@ export class FenceService {
// Armors/helmets etc // Armors/helmets etc
if ( if (
isGearAndHasSlots && isGearAndHasSlots &&
rootItemBeingAdded.upd!.Repairable?.Durability === item.upd!.Repairable?.Durability && rootItemBeingAdded.upd.Repairable?.Durability === item.upd.Repairable?.Durability &&
rootItemBeingAdded.upd!.Repairable?.MaxDurability === item.upd!.Repairable?.MaxDurability rootItemBeingAdded.upd.Repairable?.MaxDurability === item.upd.Repairable?.MaxDurability
) { ) {
return item; return item;
} }
@ -860,7 +860,7 @@ export class FenceService {
): void { ): void {
// Healing items // Healing items
if (itemRoot.upd?.MedKit) { if (itemRoot.upd?.MedKit) {
const itemTotalMax = itemTemplate._props.MaxHpResource!; const itemTotalMax = itemTemplate._props.MaxHpResource;
const current = itemRoot.upd.MedKit.HpResource; const current = itemRoot.upd.MedKit.HpResource;
// Current and max match, no adjustment necessary // Current and max match, no adjustment necessary
@ -1042,7 +1042,7 @@ export class FenceService {
// Check for and adjust soft insert durability values // Check for and adjust soft insert durability values
const requiredSlots = itemDbDetails._props.Slots?.filter((slot) => slot._required); const requiredSlots = itemDbDetails._props.Slots?.filter((slot) => slot._required);
if (Boolean(requiredSlots?.length)) { if (requiredSlots?.length) {
this.randomiseArmorSoftInsertDurabilities(requiredSlots, armor); this.randomiseArmorSoftInsertDurabilities(requiredSlots, armor);
} }
@ -1050,7 +1050,7 @@ export class FenceService {
const plateSlots = itemDbDetails._props.Slots?.filter((slot) => const plateSlots = itemDbDetails._props.Slots?.filter((slot) =>
this.itemHelper.isRemovablePlateSlot(slot._name), this.itemHelper.isRemovablePlateSlot(slot._name),
); );
if (Boolean(plateSlots?.length)) { if (plateSlots?.length) {
this.randomiseArmorInsertsDurabilities(plateSlots, armor); this.randomiseArmorInsertsDurabilities(plateSlots, armor);
} }
} }
@ -1061,8 +1061,8 @@ export class FenceService {
* @param armorItemAndMods Array of armor + inserts to get items from * @param armorItemAndMods Array of armor + inserts to get items from
*/ */
protected randomiseArmorSoftInsertDurabilities(softInsertSlots: Slot[], armorItemAndMods: Item[]): void { protected randomiseArmorSoftInsertDurabilities(softInsertSlots: Slot[], armorItemAndMods: Item[]): void {
for (const requiredSlot of softInsertSlots!) { for (const requiredSlot of softInsertSlots) {
const modItemDbDetails = this.itemHelper.getItem(requiredSlot._props.filters[0].Plate!)[1]; const modItemDbDetails = this.itemHelper.getItem(requiredSlot._props.filters[0].Plate)[1];
const durabilityValues = this.getRandomisedArmorDurabilityValues( const durabilityValues = this.getRandomisedArmorDurabilityValues(
modItemDbDetails, modItemDbDetails,
this.traderConfig.fence.armorMaxDurabilityPercentMinMax, this.traderConfig.fence.armorMaxDurabilityPercentMinMax,
@ -1075,29 +1075,29 @@ export class FenceService {
// Find items mod to apply dura changes to // Find items mod to apply dura changes to
const modItemToAdjust = armorItemAndMods.find( const modItemToAdjust = armorItemAndMods.find(
(mod) => mod.slotId!.toLowerCase() === requiredSlot._name.toLowerCase(), (mod) => mod.slotId.toLowerCase() === requiredSlot._name.toLowerCase(),
)!; );
this.itemHelper.addUpdObjectToItem(modItemToAdjust); this.itemHelper.addUpdObjectToItem(modItemToAdjust);
if (!modItemToAdjust.upd!.Repairable) { if (!modItemToAdjust.upd.Repairable) {
modItemToAdjust.upd!.Repairable = { modItemToAdjust.upd.Repairable = {
Durability: modItemDbDetails._props.MaxDurability!, Durability: modItemDbDetails._props.MaxDurability,
MaxDurability: modItemDbDetails._props.MaxDurability!, MaxDurability: modItemDbDetails._props.MaxDurability,
}; };
} }
modItemToAdjust.upd!.Repairable.Durability = durabilityValues.Durability; modItemToAdjust.upd.Repairable.Durability = durabilityValues.Durability;
modItemToAdjust.upd!.Repairable.MaxDurability = durabilityValues.MaxDurability; modItemToAdjust.upd.Repairable.MaxDurability = durabilityValues.MaxDurability;
// 25% chance to add shots to visor items when its below max durability // 25% chance to add shots to visor items when its below max durability
if ( if (
this.randomUtil.getChance100(25) && this.randomUtil.getChance100(25) &&
modItemToAdjust.parentId === BaseClasses.ARMORED_EQUIPMENT && modItemToAdjust.parentId === BaseClasses.ARMORED_EQUIPMENT &&
modItemToAdjust.slotId === "mod_equipment_000" && modItemToAdjust.slotId === "mod_equipment_000" &&
modItemToAdjust.upd!.Repairable.Durability < modItemDbDetails._props.MaxDurability! modItemToAdjust.upd.Repairable.Durability < modItemDbDetails._props.MaxDurability
) { ) {
// Is damaged // Is damaged
modItemToAdjust.upd!.FaceShield = { Hits: this.randomUtil.getInt(1, 3) }; modItemToAdjust.upd.FaceShield = { Hits: this.randomUtil.getInt(1, 3) };
} }
} }
} }
@ -1109,7 +1109,7 @@ export class FenceService {
* @param armorItemAndMods Array of armor + inserts to get items from * @param armorItemAndMods Array of armor + inserts to get items from
*/ */
protected randomiseArmorInsertsDurabilities(plateSlots: Slot[], armorItemAndMods: Item[]): void { protected randomiseArmorInsertsDurabilities(plateSlots: Slot[], armorItemAndMods: Item[]): void {
for (const plateSlot of plateSlots!) { for (const plateSlot of plateSlots) {
const plateTpl = plateSlot._props.filters[0].Plate; const plateTpl = plateSlot._props.filters[0].Plate;
if (!plateTpl) { if (!plateTpl) {
// Bsg data lacks a default plate, skip randomisng for this mod // Bsg data lacks a default plate, skip randomisng for this mod
@ -1124,7 +1124,7 @@ export class FenceService {
if (!this.randomUtil.getChance100(plateExistsChance)) { if (!this.randomUtil.getChance100(plateExistsChance)) {
// Remove plate from armor // Remove plate from armor
armorItemAndMods = armorItemAndMods.filter( armorItemAndMods = armorItemAndMods.filter(
(item) => item.slotId!.toLowerCase() !== plateSlot._name.toLowerCase(), (item) => item.slotId.toLowerCase() !== plateSlot._name.toLowerCase(),
); );
continue; continue;
@ -1137,7 +1137,7 @@ export class FenceService {
// Find items mod to apply dura changes to // Find items mod to apply dura changes to
const modItemToAdjust = armorItemAndMods.find( const modItemToAdjust = armorItemAndMods.find(
(mod) => mod.slotId!.toLowerCase() === plateSlot._name.toLowerCase(), (mod) => mod.slotId.toLowerCase() === plateSlot._name.toLowerCase(),
); );
if (!modItemToAdjust) { if (!modItemToAdjust) {
@ -1150,14 +1150,14 @@ export class FenceService {
this.itemHelper.addUpdObjectToItem(modItemToAdjust); this.itemHelper.addUpdObjectToItem(modItemToAdjust);
if (!modItemToAdjust?.upd?.Repairable) { if (!modItemToAdjust?.upd?.Repairable) {
modItemToAdjust!.upd!.Repairable = { modItemToAdjust.upd.Repairable = {
Durability: modItemDbDetails._props.MaxDurability!, Durability: modItemDbDetails._props.MaxDurability,
MaxDurability: modItemDbDetails._props.MaxDurability!, MaxDurability: modItemDbDetails._props.MaxDurability,
}; };
} }
modItemToAdjust!.upd!.Repairable.Durability = durabilityValues.Durability; modItemToAdjust.upd.Repairable.Durability = durabilityValues.Durability;
modItemToAdjust!.upd!.Repairable.MaxDurability = durabilityValues.MaxDurability; modItemToAdjust.upd.Repairable.MaxDurability = durabilityValues.MaxDurability;
} }
} }
@ -1176,7 +1176,7 @@ export class FenceService {
// No override, use stack max size from item db // No override, use stack max size from item db
return itemDbDetails._props.StackMaxSize === 1 return itemDbDetails._props.StackMaxSize === 1
? 1 ? 1
: this.randomUtil.getInt(itemDbDetails._props.StackMinRandom!, itemDbDetails._props.StackMaxRandom!); : this.randomUtil.getInt(itemDbDetails._props.StackMinRandom, itemDbDetails._props.StackMaxRandom);
} }
// Check for override in config, use values if exists // Check for override in config, use values if exists
@ -1232,7 +1232,7 @@ export class FenceService {
*/ */
protected presetModItemWillBeRemoved(weaponMod: Item, itemsBeingDeleted: string[]): boolean { protected presetModItemWillBeRemoved(weaponMod: Item, itemsBeingDeleted: string[]): boolean {
const slotIdsThatCanFail = this.traderConfig.fence.presetSlotsToRemoveChancePercent; const slotIdsThatCanFail = this.traderConfig.fence.presetSlotsToRemoveChancePercent;
const removalChance = slotIdsThatCanFail[weaponMod.slotId!]; const removalChance = slotIdsThatCanFail[weaponMod.slotId];
if (!removalChance) { if (!removalChance) {
return false; return false;
} }
@ -1259,7 +1259,7 @@ export class FenceService {
// Randomise hp resource of med items // Randomise hp resource of med items
if ("MaxHpResource" in itemDetails._props && (itemDetails._props.MaxHpResource ?? 0) > 0) { if ("MaxHpResource" in itemDetails._props && (itemDetails._props.MaxHpResource ?? 0) > 0) {
itemToAdjust.upd!.MedKit = { HpResource: this.randomUtil.getInt(1, itemDetails._props.MaxHpResource!) }; itemToAdjust.upd.MedKit = { HpResource: this.randomUtil.getInt(1, itemDetails._props.MaxHpResource) };
} }
// Randomise armor durability // Randomise armor durability
@ -1273,7 +1273,7 @@ export class FenceService {
itemDetails, itemDetails,
this.traderConfig.fence.armorMaxDurabilityPercentMinMax, this.traderConfig.fence.armorMaxDurabilityPercentMinMax,
); );
itemToAdjust.upd!.Repairable = { Durability: values.Durability, MaxDurability: values.MaxDurability }; itemToAdjust.upd.Repairable = { Durability: values.Durability, MaxDurability: values.MaxDurability };
return; return;
} }
@ -1281,25 +1281,25 @@ export class FenceService {
// Randomise Weapon durability // Randomise Weapon durability
if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.WEAPON)) { if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.WEAPON)) {
const weaponDurabilityLimits = this.traderConfig.fence.weaponDurabilityPercentMinMax; const weaponDurabilityLimits = this.traderConfig.fence.weaponDurabilityPercentMinMax;
const maxDuraMin = (weaponDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability!; const maxDuraMin = (weaponDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability;
const maxDuraMax = (weaponDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability!; const maxDuraMax = (weaponDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability;
const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax); const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax);
const currentDuraMin = (weaponDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability!; const currentDuraMin = (weaponDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability;
const currentDuraMax = (weaponDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability!; const currentDuraMax = (weaponDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability;
const currentDurability = Math.min( const currentDurability = Math.min(
this.randomUtil.getInt(currentDuraMin, currentDuraMax), this.randomUtil.getInt(currentDuraMin, currentDuraMax),
chosenMaxDurability, chosenMaxDurability,
); );
itemToAdjust.upd!.Repairable = { Durability: currentDurability, MaxDurability: chosenMaxDurability }; itemToAdjust.upd.Repairable = { Durability: currentDurability, MaxDurability: chosenMaxDurability };
return; return;
} }
if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.REPAIR_KITS)) { if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.REPAIR_KITS)) {
itemToAdjust.upd!.RepairKit = { itemToAdjust.upd.RepairKit = {
Resource: this.randomUtil.getInt(1, itemDetails._props.MaxRepairResource!), Resource: this.randomUtil.getInt(1, itemDetails._props.MaxRepairResource),
}; };
return; return;
@ -1310,8 +1310,8 @@ export class FenceService {
this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.KEY_MECHANICAL) && this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.KEY_MECHANICAL) &&
(itemDetails._props.MaximumNumberOfUsage ?? 0) > 1 (itemDetails._props.MaximumNumberOfUsage ?? 0) > 1
) { ) {
itemToAdjust.upd!.Key = { itemToAdjust.upd.Key = {
NumberOfUsages: this.randomUtil.getInt(0, itemDetails._props.MaximumNumberOfUsage! - 1), NumberOfUsages: this.randomUtil.getInt(0, itemDetails._props.MaximumNumberOfUsage - 1),
}; };
return; return;
@ -1319,10 +1319,10 @@ export class FenceService {
// Randomise items that use resources (e.g. fuel) // Randomise items that use resources (e.g. fuel)
if ((itemDetails._props.MaxResource ?? 0) > 0) { if ((itemDetails._props.MaxResource ?? 0) > 0) {
const resourceMax = itemDetails._props.MaxResource!; const resourceMax = itemDetails._props.MaxResource;
const resourceCurrent = this.randomUtil.getInt(1, itemDetails._props.MaxResource!); const resourceCurrent = this.randomUtil.getInt(1, itemDetails._props.MaxResource);
itemToAdjust.upd!.Resource = { Value: resourceMax - resourceCurrent, UnitsConsumed: resourceCurrent }; itemToAdjust.upd.Resource = { Value: resourceMax - resourceCurrent, UnitsConsumed: resourceCurrent };
} }
} }
@ -1336,12 +1336,12 @@ export class FenceService {
itemDetails: ITemplateItem, itemDetails: ITemplateItem,
equipmentDurabilityLimits: IItemDurabilityCurrentMax, equipmentDurabilityLimits: IItemDurabilityCurrentMax,
): Repairable { ): Repairable {
const maxDuraMin = (equipmentDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability!; const maxDuraMin = (equipmentDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability;
const maxDuraMax = (equipmentDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability!; const maxDuraMax = (equipmentDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability;
const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax); const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax);
const currentDuraMin = (equipmentDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability!; const currentDuraMin = (equipmentDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability;
const currentDuraMax = (equipmentDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability!; const currentDuraMax = (equipmentDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability;
const chosenCurrentDurability = Math.min( const chosenCurrentDurability = Math.min(
this.randomUtil.getInt(currentDuraMin, currentDuraMax), this.randomUtil.getInt(currentDuraMin, currentDuraMax),
chosenMaxDurability, chosenMaxDurability,
@ -1380,7 +1380,7 @@ export class FenceService {
* @returns Refresh time in seconds * @returns Refresh time in seconds
*/ */
protected getFenceRefreshTime(): number { protected getFenceRefreshTime(): number {
const fence = this.traderConfig.updateTime.find((x) => x.traderId === Traders.FENCE)!.seconds; const fence = this.traderConfig.updateTime.find((x) => x.traderId === Traders.FENCE).seconds;
return this.randomUtil.getInt(fence.min, fence.max); return this.randomUtil.getInt(fence.min, fence.max);
} }
@ -1421,10 +1421,10 @@ export class FenceService {
*/ */
public amendOrRemoveFenceOffer(assortId: string, buyCount: number): void { public amendOrRemoveFenceOffer(assortId: string, buyCount: number): void {
let isNormalAssort = true; let isNormalAssort = true;
let fenceAssortItem = this.fenceAssort!.items.find((item) => item._id === assortId); let fenceAssortItem = this.fenceAssort.items.find((item) => item._id === assortId);
if (!fenceAssortItem) { if (!fenceAssortItem) {
// Not in main assorts, check secondary section // Not in main assorts, check secondary section
fenceAssortItem = this.fenceDiscountAssort!.items.find((item) => item._id === assortId); fenceAssortItem = this.fenceDiscountAssort.items.find((item) => item._id === assortId);
if (!fenceAssortItem) { if (!fenceAssortItem) {
this.logger.error(this.localisationService.getText("fence-unable_to_find_offer_by_id", assortId)); this.logger.error(this.localisationService.getText("fence-unable_to_find_offer_by_id", assortId));
@ -1434,14 +1434,14 @@ export class FenceService {
} }
// Player wants to buy whole stack, delete stack // Player wants to buy whole stack, delete stack
if (fenceAssortItem.upd!.StackObjectsCount === buyCount) { if (fenceAssortItem.upd.StackObjectsCount === buyCount) {
this.deleteOffer(assortId, isNormalAssort ? this.fenceAssort!.items : this.fenceDiscountAssort!.items); this.deleteOffer(assortId, isNormalAssort ? this.fenceAssort.items : this.fenceDiscountAssort.items);
return; return;
} }
// Adjust stack size // Adjust stack size
fenceAssortItem.upd!.StackObjectsCount! -= buyCount; fenceAssortItem.upd.StackObjectsCount -= buyCount;
} }
protected deleteOffer(assortId: string, assorts: Item[]): void { protected deleteOffer(assortId: string, assorts: Item[]): void {
@ -1452,8 +1452,8 @@ export class FenceService {
// No offer found in main assort, check discount items // No offer found in main assort, check discount items
if (indexToRemove === -1) { if (indexToRemove === -1) {
indexToRemove = this.fenceDiscountAssort!.items.findIndex((item) => item._id === itemToRemove._id); indexToRemove = this.fenceDiscountAssort.items.findIndex((item) => item._id === itemToRemove._id);
this.fenceDiscountAssort!.items.splice(indexToRemove, 1); this.fenceDiscountAssort.items.splice(indexToRemove, 1);
if (indexToRemove === -1) { if (indexToRemove === -1) {
this.logger.warning( this.logger.warning(

View File

@ -115,7 +115,7 @@ export class GiftService {
if (giftData.localeTextId) { if (giftData.localeTextId) {
this.mailSendService.sendLocalisedNpcMessageToPlayer( this.mailSendService.sendLocalisedNpcMessageToPlayer(
playerId, playerId,
giftData.trader!, giftData.trader,
MessageType.MESSAGE_WITH_ITEMS, MessageType.MESSAGE_WITH_ITEMS,
giftData.localeTextId, giftData.localeTextId,
giftData.items, giftData.items,
@ -124,7 +124,7 @@ export class GiftService {
} else { } else {
this.mailSendService.sendDirectNpcMessageToPlayer( this.mailSendService.sendDirectNpcMessageToPlayer(
playerId, playerId,
giftData.trader!, giftData.trader,
MessageType.MESSAGE_WITH_ITEMS, MessageType.MESSAGE_WITH_ITEMS,
giftData.messageText, giftData.messageText,
giftData.items, giftData.items,
@ -136,9 +136,9 @@ export class GiftService {
// Trader / ragfair // Trader / ragfair
const details: ISendMessageDetails = { const details: ISendMessageDetails = {
recipientId: playerId, recipientId: playerId,
sender: this.getMessageType(giftData)!, sender: this.getMessageType(giftData),
senderDetails: { senderDetails: {
_id: this.getSenderId(giftData)!, _id: this.getSenderId(giftData),
aid: 1234567, // TODO - pass proper aid value aid: 1234567, // TODO - pass proper aid value
Info: undefined, Info: undefined,
}, },
@ -166,7 +166,7 @@ export class GiftService {
*/ */
protected getSenderId(giftData: Gift): string | undefined { protected getSenderId(giftData: Gift): string | undefined {
if (giftData.sender === GiftSenderType.TRADER) { if (giftData.sender === GiftSenderType.TRADER) {
return Traders[giftData.trader!]; return Traders[giftData.trader];
} }
if (giftData.sender === GiftSenderType.USER) { if (giftData.sender === GiftSenderType.USER) {

View File

@ -142,7 +142,7 @@ export class InsuranceService {
(bonus) => bonus.type === BonusType.INSURANCE_RETURN_TIME, (bonus) => bonus.type === BonusType.INSURANCE_RETURN_TIME,
); );
const insuranceReturnTimeBonusPercent = const insuranceReturnTimeBonusPercent =
1.0 - (insuranceReturnTimeBonus ? Math.abs(insuranceReturnTimeBonus!.value ?? 0) : 0) / 100; 1.0 - (insuranceReturnTimeBonus ? Math.abs(insuranceReturnTimeBonus.value ?? 0) : 0) / 100;
const traderMinReturnAsSeconds = trader.insurance.min_return_hour * TimeUtil.ONE_HOUR_AS_SECONDS; const traderMinReturnAsSeconds = trader.insurance.min_return_hour * TimeUtil.ONE_HOUR_AS_SECONDS;
const traderMaxReturnAsSeconds = trader.insurance.max_return_hour * TimeUtil.ONE_HOUR_AS_SECONDS; const traderMaxReturnAsSeconds = trader.insurance.max_return_hour * TimeUtil.ONE_HOUR_AS_SECONDS;
@ -214,7 +214,7 @@ export class InsuranceService {
const result: IInsuranceEquipmentPkg[] = []; const result: IInsuranceEquipmentPkg[] = [];
for (const lostItem of lostInsuredItems) { for (const lostItem of lostInsuredItems) {
const insuranceDetails = pmcProfile.InsuredItems.find((insuredItem) => insuredItem.itemId == lostItem._id); const insuranceDetails = pmcProfile.InsuredItems.find((insuredItem) => insuredItem.itemId === lostItem._id);
if (!insuranceDetails) { if (!insuranceDetails) {
this.logger.error( this.logger.error(
`unable to find insurance details for item id: ${lostItem._id} with tpl: ${lostItem._tpl}`, `unable to find insurance details for item id: ${lostItem._id} with tpl: ${lostItem._tpl}`,

View File

@ -25,7 +25,7 @@ export class LocaleService {
* @returns dictionary * @returns dictionary
*/ */
public getLocaleDb(): Record<string, string> { public getLocaleDb(): Record<string, string> {
const desiredLocale = this.databaseServer.getTables().locales!.global[this.getDesiredGameLocale()]; const desiredLocale = this.databaseServer.getTables().locales.global[this.getDesiredGameLocale()];
if (desiredLocale) { if (desiredLocale) {
return desiredLocale; return desiredLocale;
} }
@ -34,7 +34,7 @@ export class LocaleService {
`Unable to find desired locale file using locale: ${this.getDesiredGameLocale()} from config/locale.json, falling back to 'en'`, `Unable to find desired locale file using locale: ${this.getDesiredGameLocale()} from config/locale.json, falling back to 'en'`,
); );
return this.databaseServer.getTables().locales!.global.en; return this.databaseServer.getTables().locales.global.en;
} }
/** /**
@ -118,7 +118,7 @@ export class LocaleService {
return "en"; return "en";
} }
const locales = this.databaseServer.getTables().locales!; const locales = this.databaseServer.getTables().locales;
const baseNameCode = platformLocale.baseName?.toLocaleLowerCase(); const baseNameCode = platformLocale.baseName?.toLocaleLowerCase();
if (baseNameCode && locales.global[baseNameCode]) { if (baseNameCode && locales.global[baseNameCode]) {
return baseNameCode; return baseNameCode;

View File

@ -51,7 +51,7 @@ export class LocalisationService {
* @returns string array of keys * @returns string array of keys
*/ */
public getKeys(): string[] { public getKeys(): string[] {
return Object.keys(this.databaseServer.getTables().locales!.server.en); return Object.keys(this.databaseServer.getTables().locales.server.en);
} }
/** /**
@ -60,7 +60,7 @@ export class LocalisationService {
* @returns locale text * @returns locale text
*/ */
public getRandomTextThatMatchesPartialKey(partialKey: string): string { public getRandomTextThatMatchesPartialKey(partialKey: string): string {
const filteredKeys = Object.keys(this.databaseServer.getTables().locales!.server.en).filter((x) => const filteredKeys = Object.keys(this.databaseServer.getTables().locales.server.en).filter((x) =>
x.startsWith(partialKey), x.startsWith(partialKey),
); );
const chosenKey = this.randomUtil.getArrayValue(filteredKeys); const chosenKey = this.randomUtil.getArrayValue(filteredKeys);

View File

@ -168,7 +168,7 @@ export class LocationLifecycleService {
const fullProfile = this.profileHelper.getFullProfile(sessionId); const fullProfile = this.profileHelper.getFullProfile(sessionId);
const pmcProfile = fullProfile.characters.pmc; const pmcProfile = fullProfile.characters.pmc;
const scavProfile = fullProfile.characters.scav; const scavProfile = fullProfile.characters.scav;
const postRaidProfile = request.results.profile!; const postRaidProfile = request.results.profile;
// TODO: // TODO:
// Rep gain/loss? // Rep gain/loss?

View File

@ -396,7 +396,7 @@ export class MailSendService {
let itemsToSendToPlayer: MessageItems = {}; let itemsToSendToPlayer: MessageItems = {};
if ((messageDetails.items?.length ?? 0) > 0) { if ((messageDetails.items?.length ?? 0) > 0) {
// Find base item that should be the 'primary' + have its parent id be used as the dialogs 'stash' value // Find base item that should be the 'primary' + have its parent id be used as the dialogs 'stash' value
const parentItem = this.getBaseItemFromRewards(messageDetails.items!); const parentItem = this.getBaseItemFromRewards(messageDetails.items);
if (!parentItem) { if (!parentItem) {
this.localisationService.getText("mailsend-missing_parent", { this.localisationService.getText("mailsend-missing_parent", {
traderId: messageDetails.trader, traderId: messageDetails.trader,
@ -414,7 +414,7 @@ export class MailSendService {
itemsToSendToPlayer = { stash: parentItem.parentId, data: [] }; itemsToSendToPlayer = { stash: parentItem.parentId, data: [] };
// Ensure Ids are unique and cont collide with items in player inventory later // Ensure Ids are unique and cont collide with items in player inventory later
messageDetails.items = this.itemHelper.replaceIDs(messageDetails.items!); messageDetails.items = this.itemHelper.replaceIDs(messageDetails.items);
for (const reward of messageDetails.items) { for (const reward of messageDetails.items) {
// Ensure item exists in items db // Ensure item exists in items db
@ -444,7 +444,7 @@ export class MailSendService {
this.itemHelper.addCartridgesToAmmoBox(boxAndCartridges, itemTemplate); this.itemHelper.addCartridgesToAmmoBox(boxAndCartridges, itemTemplate);
// Push box + cartridge children into array // Push box + cartridge children into array
itemsToSendToPlayer.data!.push(...boxAndCartridges); itemsToSendToPlayer.data.push(...boxAndCartridges);
} else { } else {
if ("StackSlots" in itemTemplate._props) { if ("StackSlots" in itemTemplate._props) {
this.logger.error( this.logger.error(
@ -453,12 +453,12 @@ export class MailSendService {
} }
// Item is sanitised and ready to be pushed into holding array // Item is sanitised and ready to be pushed into holding array
itemsToSendToPlayer.data!.push(reward); itemsToSendToPlayer.data.push(reward);
} }
} }
// Remove empty data property if no rewards // Remove empty data property if no rewards
if (itemsToSendToPlayer.data!.length === 0) { if (itemsToSendToPlayer.data.length === 0) {
delete itemsToSendToPlayer.data; delete itemsToSendToPlayer.data;
} }
} }

View File

@ -190,14 +190,14 @@ export class PaymentService {
} }
// Found currency item // Found currency item
if (item.upd!.StackObjectsCount! < currencyMaxStackSize) { if (item.upd.StackObjectsCount < currencyMaxStackSize) {
if (item.upd!.StackObjectsCount! + calcAmount > currencyMaxStackSize) { if (item.upd.StackObjectsCount + calcAmount > currencyMaxStackSize) {
// calculate difference // calculate difference
calcAmount -= currencyMaxStackSize - item.upd!.StackObjectsCount!; calcAmount -= currencyMaxStackSize - item.upd.StackObjectsCount;
item.upd!.StackObjectsCount! = currencyMaxStackSize; item.upd.StackObjectsCount = currencyMaxStackSize;
} else { } else {
skipSendingMoneyToStash = true; skipSendingMoneyToStash = true;
item.upd!.StackObjectsCount! = item.upd!.StackObjectsCount! + calcAmount; item.upd.StackObjectsCount = item.upd.StackObjectsCount + calcAmount;
} }
// Inform client of change to items StackObjectsCount // Inform client of change to items StackObjectsCount
@ -257,7 +257,7 @@ export class PaymentService {
pmcData.Inventory.stash, pmcData.Inventory.stash,
); );
const amountAvailable = moneyItemsInInventory.reduce( const amountAvailable = moneyItemsInInventory.reduce(
(accumulator, item) => accumulator + item.upd!.StackObjectsCount!, (accumulator, item) => accumulator + item.upd.StackObjectsCount,
0, 0,
); );
@ -280,12 +280,12 @@ export class PaymentService {
let leftToPay = amountToPay; let leftToPay = amountToPay;
for (const profileMoneyItem of moneyItemsInInventory) { for (const profileMoneyItem of moneyItemsInInventory) {
const itemAmount = profileMoneyItem.upd!.StackObjectsCount!; const itemAmount = profileMoneyItem.upd.StackObjectsCount;
if (leftToPay >= itemAmount) { if (leftToPay >= itemAmount) {
leftToPay -= itemAmount; leftToPay -= itemAmount;
this.inventoryHelper.removeItem(pmcData, profileMoneyItem._id, sessionID, output); this.inventoryHelper.removeItem(pmcData, profileMoneyItem._id, sessionID, output);
} else { } else {
profileMoneyItem.upd!.StackObjectsCount! -= leftToPay; profileMoneyItem.upd.StackObjectsCount -= leftToPay;
leftToPay = 0; leftToPay = 0;
output.profileChanges[sessionID].items.change.push(profileMoneyItem); output.profileChanges[sessionID].items.change.push(profileMoneyItem);
} }

View File

@ -84,7 +84,7 @@ export class ProfileFixerService {
this.reorderHideoutAreasWithResouceInputs(pmcProfile); this.reorderHideoutAreasWithResouceInputs(pmcProfile);
if ( if (
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.GENERATOR)!.slots.length < pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.GENERATOR).slots.length <
6 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.Generator.Slots 6 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.Generator.Slots
) { ) {
this.logger.debug("Updating generator area slots to a size of 6 + hideout management skill"); this.logger.debug("Updating generator area slots to a size of 6 + hideout management skill");
@ -96,7 +96,7 @@ export class ProfileFixerService {
} }
if ( if (
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.WATER_COLLECTOR)!.slots.length < pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.WATER_COLLECTOR).slots.length <
1 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.WaterCollector.Slots 1 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.WaterCollector.Slots
) { ) {
this.logger.debug("Updating water collector area slots to a size of 1 + hideout management skill"); this.logger.debug("Updating water collector area slots to a size of 1 + hideout management skill");
@ -108,7 +108,7 @@ export class ProfileFixerService {
} }
if ( if (
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.AIR_FILTERING)!.slots.length < pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.AIR_FILTERING).slots.length <
3 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.AirFilteringUnit.Slots 3 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.AirFilteringUnit.Slots
) { ) {
this.logger.debug("Updating air filter area slots to a size of 3 + hideout management skill"); this.logger.debug("Updating air filter area slots to a size of 3 + hideout management skill");
@ -121,7 +121,7 @@ export class ProfileFixerService {
// BTC Farm doesnt have extra slots for hideout management, but we still check for modded stuff!! // BTC Farm doesnt have extra slots for hideout management, but we still check for modded stuff!!
if ( if (
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.BITCOIN_FARM)!.slots.length < pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.BITCOIN_FARM).slots.length <
50 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.BitcoinFarm.Slots 50 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.BitcoinFarm.Slots
) { ) {
this.logger.debug("Updating bitcoin farm area slots to a size of 50 + hideout management skill"); this.logger.debug("Updating bitcoin farm area slots to a size of 50 + hideout management skill");
@ -172,8 +172,8 @@ export class ProfileFixerService {
} }
const hideout = this.databaseService.getHideout(); const hideout = this.databaseService.getHideout();
const hideoutStandAreaDb = hideout.areas.find((area) => area.type === HideoutAreas.WEAPON_STAND)!; const hideoutStandAreaDb = hideout.areas.find((area) => area.type === HideoutAreas.WEAPON_STAND);
const hideoutStandSecondaryAreaDb = hideout.areas.find((x) => x.parentArea === hideoutStandAreaDb._id)!; const hideoutStandSecondaryAreaDb = hideout.areas.find((x) => x.parentArea === hideoutStandAreaDb._id);
const stageCurrentAt = hideoutStandAreaDb.stages[weaponStandArea.level]; const stageCurrentAt = hideoutStandAreaDb.stages[weaponStandArea.level];
const hideoutStandStashId = pmcProfile.Inventory.hideoutAreaStashes[HideoutAreas.WEAPON_STAND]; const hideoutStandStashId = pmcProfile.Inventory.hideoutAreaStashes[HideoutAreas.WEAPON_STAND];
const hideoutSecondaryStashId = pmcProfile.Inventory.hideoutAreaStashes[HideoutAreas.WEAPON_STAND_SECONDARY]; const hideoutSecondaryStashId = pmcProfile.Inventory.hideoutAreaStashes[HideoutAreas.WEAPON_STAND_SECONDARY];
@ -188,12 +188,12 @@ export class ProfileFixerService {
// Add stash item to profile // Add stash item to profile
const gunStandStashItem = pmcProfile.Inventory.items.find((item) => item._id === hideoutStandAreaDb._id); const gunStandStashItem = pmcProfile.Inventory.items.find((item) => item._id === hideoutStandAreaDb._id);
if (gunStandStashItem) { if (gunStandStashItem) {
gunStandStashItem._tpl = stageCurrentAt.container!; gunStandStashItem._tpl = stageCurrentAt.container;
this.logger.debug( this.logger.debug(
`Updated existing gun stand inventory stash: ${gunStandStashItem._id} tpl to ${stageCurrentAt.container}`, `Updated existing gun stand inventory stash: ${gunStandStashItem._id} tpl to ${stageCurrentAt.container}`,
); );
} else { } else {
pmcProfile.Inventory.items.push({ _id: hideoutStandAreaDb._id, _tpl: stageCurrentAt.container! }); pmcProfile.Inventory.items.push({ _id: hideoutStandAreaDb._id, _tpl: stageCurrentAt.container });
this.logger.debug( this.logger.debug(
`Added missing gun stand inventory stash: ${hideoutStandAreaDb._id} tpl to ${stageCurrentAt.container}`, `Added missing gun stand inventory stash: ${hideoutStandAreaDb._id} tpl to ${stageCurrentAt.container}`,
); );
@ -202,16 +202,16 @@ export class ProfileFixerService {
// Add secondary stash item to profile // Add secondary stash item to profile
const gunStandStashSecondaryItem = pmcProfile.Inventory.items.find( const gunStandStashSecondaryItem = pmcProfile.Inventory.items.find(
(item) => item._id === hideoutStandSecondaryAreaDb._id, (item) => item._id === hideoutStandSecondaryAreaDb._id,
)!; );
if (gunStandStashItem) { if (gunStandStashItem) {
gunStandStashSecondaryItem._tpl = stageCurrentAt.container!; gunStandStashSecondaryItem._tpl = stageCurrentAt.container;
this.logger.debug( this.logger.debug(
`Updated gun stand existing inventory secondary stash: ${gunStandStashSecondaryItem._id} tpl to ${stageCurrentAt.container}`, `Updated gun stand existing inventory secondary stash: ${gunStandStashSecondaryItem._id} tpl to ${stageCurrentAt.container}`,
); );
} else { } else {
pmcProfile.Inventory.items.push({ pmcProfile.Inventory.items.push({
_id: hideoutStandSecondaryAreaDb._id, _id: hideoutStandSecondaryAreaDb._id,
_tpl: stageCurrentAt.container!, _tpl: stageCurrentAt.container,
}); });
this.logger.debug( this.logger.debug(
`Added missing gun stand inventory secondary stash: ${hideoutStandSecondaryAreaDb._id} tpl to ${stageCurrentAt.container}`, `Added missing gun stand inventory secondary stash: ${hideoutStandSecondaryAreaDb._id} tpl to ${stageCurrentAt.container}`,
@ -224,23 +224,23 @@ export class ProfileFixerService {
let stashItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandAreaDb._id); let stashItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandAreaDb._id);
if (!stashItem) { if (!stashItem) {
// Stand inventory stash item doesnt exist, add it // Stand inventory stash item doesnt exist, add it
pmcProfile.Inventory.items.push({ _id: hideoutStandAreaDb._id, _tpl: stageCurrentAt.container! }); pmcProfile.Inventory.items.push({ _id: hideoutStandAreaDb._id, _tpl: stageCurrentAt.container });
stashItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandAreaDb._id); stashItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandAreaDb._id);
} }
// `hideoutAreaStashes` has value related stash inventory items tpl doesnt match what's expected // `hideoutAreaStashes` has value related stash inventory items tpl doesnt match what's expected
if (hideoutStandStashId && stashItem!._tpl !== stageCurrentAt.container) { if (hideoutStandStashId && stashItem._tpl !== stageCurrentAt.container) {
this.logger.debug( this.logger.debug(
`primary Stash tpl was: ${stashItem!._tpl}, but should be ${stageCurrentAt.container}, updating`, `primary Stash tpl was: ${stashItem._tpl}, but should be ${stageCurrentAt.container}, updating`,
); );
// The id inside the profile does not match what the hideout db value is, out of sync, adjust // The id inside the profile does not match what the hideout db value is, out of sync, adjust
stashItem!._tpl = stageCurrentAt.container!; stashItem._tpl = stageCurrentAt.container;
} }
let stashSecondaryItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandSecondaryAreaDb._id); let stashSecondaryItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandSecondaryAreaDb._id);
if (!stashSecondaryItem) { if (!stashSecondaryItem) {
// Stand inventory stash item doesnt exist, add it // Stand inventory stash item doesnt exist, add it
pmcProfile.Inventory.items.push({ _id: hideoutStandSecondaryAreaDb._id, _tpl: stageCurrentAt.container! }); pmcProfile.Inventory.items.push({ _id: hideoutStandSecondaryAreaDb._id, _tpl: stageCurrentAt.container });
stashSecondaryItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandSecondaryAreaDb._id); stashSecondaryItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandSecondaryAreaDb._id);
} }
@ -250,7 +250,7 @@ export class ProfileFixerService {
`Secondary stash tpl was: ${stashSecondaryItem?._tpl}, but should be ${stageCurrentAt.container}, updating`, `Secondary stash tpl was: ${stashSecondaryItem?._tpl}, but should be ${stageCurrentAt.container}, updating`,
); );
// The id inside the profile does not match what the hideout db value is, out of sync, adjust // The id inside the profile does not match what the hideout db value is, out of sync, adjust
stashSecondaryItem!._tpl = stageCurrentAt.container!; stashSecondaryItem._tpl = stageCurrentAt.container;
} }
} }
@ -278,12 +278,12 @@ export class ProfileFixerService {
// Add stash item to profile // Add stash item to profile
const placeOfFameStashItem = pmcProfile.Inventory.items.find((item) => item._id === placeOfFameAreaDb._id); const placeOfFameStashItem = pmcProfile.Inventory.items.find((item) => item._id === placeOfFameAreaDb._id);
if (placeOfFameStashItem) { if (placeOfFameStashItem) {
placeOfFameStashItem._tpl = stageCurrentlyAt.container!; placeOfFameStashItem._tpl = stageCurrentlyAt.container;
this.logger.debug( this.logger.debug(
`Updated existing place of fame inventory stash: ${placeOfFameStashItem._id} tpl to ${stageCurrentlyAt.container}`, `Updated existing place of fame inventory stash: ${placeOfFameStashItem._id} tpl to ${stageCurrentlyAt.container}`,
); );
} else { } else {
pmcProfile.Inventory.items.push({ _id: placeOfFameAreaDb._id, _tpl: stageCurrentlyAt.container! }); pmcProfile.Inventory.items.push({ _id: placeOfFameAreaDb._id, _tpl: stageCurrentlyAt.container });
this.logger.debug( this.logger.debug(
`Added missing place of fame inventory stash: ${placeOfFameAreaDb._id} tpl to ${stageCurrentlyAt.container}`, `Added missing place of fame inventory stash: ${placeOfFameAreaDb._id} tpl to ${stageCurrentlyAt.container}`,
); );
@ -295,17 +295,17 @@ export class ProfileFixerService {
let stashItem = pmcProfile.Inventory.items?.find((x) => x._id === placeOfFameAreaDb._id); let stashItem = pmcProfile.Inventory.items?.find((x) => x._id === placeOfFameAreaDb._id);
if (!stashItem) { if (!stashItem) {
// Stand inventory stash item doesnt exist, add it // Stand inventory stash item doesnt exist, add it
pmcProfile.Inventory.items.push({ _id: placeOfFameAreaDb._id, _tpl: stageCurrentlyAt.container! }); pmcProfile.Inventory.items.push({ _id: placeOfFameAreaDb._id, _tpl: stageCurrentlyAt.container });
stashItem = pmcProfile.Inventory.items?.find((x) => x._id === placeOfFameAreaDb._id); stashItem = pmcProfile.Inventory.items?.find((x) => x._id === placeOfFameAreaDb._id);
} }
// `hideoutAreaStashes` has value related stash inventory items tpl doesnt match what's expected // `hideoutAreaStashes` has value related stash inventory items tpl doesnt match what's expected
if (placeOfFameStashId && stashItem!._tpl !== stageCurrentlyAt.container) { if (placeOfFameStashId && stashItem._tpl !== stageCurrentlyAt.container) {
this.logger.debug( this.logger.debug(
`primary Stash tpl was: ${stashItem?._tpl}, but should be ${stageCurrentlyAt.container}, updating`, `primary Stash tpl was: ${stashItem?._tpl}, but should be ${stageCurrentlyAt.container}, updating`,
); );
// The id inside the profile does not match what the hideout db value is, out of sync, adjust // The id inside the profile does not match what the hideout db value is, out of sync, adjust
stashItem!._tpl = stageCurrentlyAt.container!; stashItem._tpl = stageCurrentlyAt.container;
} }
} }
@ -574,13 +574,13 @@ export class ProfileFixerService {
* @param pmcProfile Profile to add improvement data to * @param pmcProfile Profile to add improvement data to
*/ */
protected addMissingWallImprovements(pmcProfile: IPmcData): void { protected addMissingWallImprovements(pmcProfile: IPmcData): void {
const profileWallArea = pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.EMERGENCY_WALL)!; const profileWallArea = pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.EMERGENCY_WALL);
const wallDb = this.databaseService.getHideout().areas.find((x) => x.type === HideoutAreas.EMERGENCY_WALL); const wallDb = this.databaseService.getHideout().areas.find((x) => x.type === HideoutAreas.EMERGENCY_WALL);
if (profileWallArea.level > 0) { if (profileWallArea.level > 0) {
for (let i = 0; i < profileWallArea.level; i++) { for (let i = 0; i < profileWallArea.level; i++) {
// Get wall stage from db // Get wall stage from db
const wallStageDb = wallDb!.stages[i]; const wallStageDb = wallDb.stages[i];
if (wallStageDb.improvements.length === 0) { if (wallStageDb.improvements.length === 0) {
// No improvements, skip // No improvements, skip
continue; continue;
@ -640,7 +640,7 @@ export class ProfileFixerService {
for (const areaId of areasToCheck) { for (const areaId of areasToCheck) {
const area = pmcProfile.Hideout.Areas.find((area) => area.type === areaId); const area = pmcProfile.Hideout.Areas.find((area) => area.type === areaId);
if (!area) { if (!area) {
this.logger.debug(`unable to sort: ${area!.type} (${areaId}) slots, no area found`); this.logger.debug(`unable to sort: ${area.type} (${areaId}) slots, no area found`);
continue; continue;
} }
@ -666,7 +666,7 @@ export class ProfileFixerService {
pmcProfile: IPmcData, pmcProfile: IPmcData,
): void { ): void {
const area = pmcProfile.Hideout.Areas.find((x) => x.type === areaType); const area = pmcProfile.Hideout.Areas.find((x) => x.type === areaType);
area!.slots = this.addObjectsToArray(emptyItemCount, area!.slots); area.slots = this.addObjectsToArray(emptyItemCount, area.slots);
} }
protected addObjectsToArray(count: number, slots: HideoutSlot[]): HideoutSlot[] { protected addObjectsToArray(count: number, slots: HideoutSlot[]): HideoutSlot[] {
@ -878,9 +878,9 @@ export class ProfileFixerService {
continue; continue;
} }
for (const successReward of activeQuest.rewards.Success!) { for (const successReward of activeQuest.rewards.Success) {
if (successReward.type === "Item") { if (successReward.type === "Item") {
for (const rewardItem of successReward.items!) { for (const rewardItem of successReward.items) {
if (!itemsDb[rewardItem._tpl]) { if (!itemsDb[rewardItem._tpl]) {
this.logger.error( this.logger.error(
this.localisationService.getText("fixer-mod_item_found", rewardItem._tpl), this.localisationService.getText("fixer-mod_item_found", rewardItem._tpl),
@ -1009,7 +1009,7 @@ export class ProfileFixerService {
// Only replace ID if items have no children, we dont want orphaned children // Only replace ID if items have no children, we dont want orphaned children
const itemsHaveChildren = pmcProfile.Inventory.items.some((x) => x.parentId === key); const itemsHaveChildren = pmcProfile.Inventory.items.some((x) => x.parentId === key);
if (!itemsHaveChildren) { if (!itemsHaveChildren) {
const itemToAdjust = pmcProfile.Inventory.items.find((x) => x._id === key)!; const itemToAdjust = pmcProfile.Inventory.items.find((x) => x._id === key);
itemToAdjust._id = this.hashUtil.generate(); itemToAdjust._id = this.hashUtil.generate();
this.logger.warning(`Replace duplicate item Id: ${key} with ${itemToAdjust._id}`); this.logger.warning(`Replace duplicate item Id: ${key} with ${itemToAdjust._id}`);
} }
@ -1047,7 +1047,7 @@ export class ProfileFixerService {
const defaultHead = playerIsUsec const defaultHead = playerIsUsec
? customizationDbArray.find((x) => x._name === "DefaultUsecHead") ? customizationDbArray.find((x) => x._name === "DefaultUsecHead")
: customizationDbArray.find((x) => x._name === "DefaultBearHead"); : customizationDbArray.find((x) => x._name === "DefaultBearHead");
pmcProfile.Customization.Head = defaultHead!._id; pmcProfile.Customization.Head = defaultHead._id;
} }
// check Body // check Body
@ -1056,7 +1056,7 @@ export class ProfileFixerService {
pmcProfile.Info.Side.toLowerCase() === "usec" pmcProfile.Info.Side.toLowerCase() === "usec"
? customizationDbArray.find((x) => x._name === "DefaultUsecBody") ? customizationDbArray.find((x) => x._name === "DefaultUsecBody")
: customizationDbArray.find((x) => x._name === "DefaultBearBody"); : customizationDbArray.find((x) => x._name === "DefaultBearBody");
pmcProfile.Customization.Body = defaultBody!._id; pmcProfile.Customization.Body = defaultBody._id;
} }
// check Hands // check Hands
@ -1065,7 +1065,7 @@ export class ProfileFixerService {
pmcProfile.Info.Side.toLowerCase() === "usec" pmcProfile.Info.Side.toLowerCase() === "usec"
? customizationDbArray.find((x) => x._name === "DefaultUsecHands") ? customizationDbArray.find((x) => x._name === "DefaultUsecHands")
: customizationDbArray.find((x) => x._name === "DefaultBearHands"); : customizationDbArray.find((x) => x._name === "DefaultBearHands");
pmcProfile.Customization.Hands = defaultHands!._id; pmcProfile.Customization.Hands = defaultHands._id;
} }
// check Hands // check Hands
@ -1074,7 +1074,7 @@ export class ProfileFixerService {
pmcProfile.Info.Side.toLowerCase() === "usec" pmcProfile.Info.Side.toLowerCase() === "usec"
? customizationDbArray.find((x) => x._name === "DefaultUsecFeet") ? customizationDbArray.find((x) => x._name === "DefaultUsecFeet")
: customizationDbArray.find((x) => x._name === "DefaultBearFeet"); : customizationDbArray.find((x) => x._name === "DefaultBearFeet");
pmcProfile.Customization.Feet = defaultFeet!._id; pmcProfile.Customization.Feet = defaultFeet._id;
} }
} }

View File

@ -136,8 +136,8 @@ export class RagfairOfferService {
public removeOfferStack(offerId: string, amount: number): void { public removeOfferStack(offerId: string, amount: number): void {
const offer = this.ragfairOfferHandler.getOfferById(offerId); const offer = this.ragfairOfferHandler.getOfferById(offerId);
if (offer) { if (offer) {
offer.items[0].upd!.StackObjectsCount! -= amount; offer.items[0].upd.StackObjectsCount -= amount;
if (offer.items[0].upd!.StackObjectsCount! <= 0) { if (offer.items[0].upd.StackObjectsCount <= 0) {
this.processStaleOffer(offer); this.processStaleOffer(offer);
} }
} }
@ -245,10 +245,10 @@ export class RagfairOfferService {
profile.RagfairInfo.isRatingGrowing = false; profile.RagfairInfo.isRatingGrowing = false;
const firstOfferItem = playerOffer.items[0]; const firstOfferItem = playerOffer.items[0];
if (firstOfferItem.upd!.StackObjectsCount! > firstOfferItem.upd!.OriginalStackObjectsCount!) { if (firstOfferItem.upd.StackObjectsCount > firstOfferItem.upd.OriginalStackObjectsCount) {
playerOffer.items[0].upd!.StackObjectsCount = firstOfferItem.upd!.OriginalStackObjectsCount; playerOffer.items[0].upd.StackObjectsCount = firstOfferItem.upd.OriginalStackObjectsCount;
} }
delete playerOffer.items[0].upd!.OriginalStackObjectsCount; delete playerOffer.items[0].upd.OriginalStackObjectsCount;
// Remove player offer from flea // Remove player offer from flea
this.ragfairOfferHandler.removeOffer(playerOffer); this.ragfairOfferHandler.removeOffer(playerOffer);

View File

@ -64,7 +64,7 @@ export class RagfairTaxService {
const requirementsPrice = requirementsValue * (sellInOnePiece ? 1 : offerItemCount); const requirementsPrice = requirementsValue * (sellInOnePiece ? 1 : offerItemCount);
const itemTaxMult = globals.config.RagFair.communityItemTax / 100.0; const itemTaxMult = globals.config.RagFair.communityItemTax / 100.0;
const requirementTaxMult = globals!.config.RagFair.communityRequirementTax / 100.0; const requirementTaxMult = globals.config.RagFair.communityRequirementTax / 100.0;
let itemPriceMult = Math.log10(itemWorth / requirementsPrice); let itemPriceMult = Math.log10(itemWorth / requirementsPrice);
let requirementPriceMult = Math.log10(requirementsPrice / itemWorth); let requirementPriceMult = Math.log10(requirementsPrice / itemWorth);
@ -79,7 +79,7 @@ export class RagfairTaxService {
requirementPriceMult = 4 ** requirementPriceMult; requirementPriceMult = 4 ** requirementPriceMult;
const hideoutFleaTaxDiscountBonus = pmcData.Bonuses.find((b) => b.type === BonusType.RAGFAIR_COMMISSION); const hideoutFleaTaxDiscountBonus = pmcData.Bonuses.find((b) => b.type === BonusType.RAGFAIR_COMMISSION);
const taxDiscountPercent = hideoutFleaTaxDiscountBonus ? Math.abs(hideoutFleaTaxDiscountBonus!.value ?? 0) : 0; const taxDiscountPercent = hideoutFleaTaxDiscountBonus ? Math.abs(hideoutFleaTaxDiscountBonus.value ?? 0) : 0;
const tax = const tax =
itemWorth * itemTaxMult * itemPriceMult + requirementsPrice * requirementTaxMult * requirementPriceMult; itemWorth * itemTaxMult * itemPriceMult + requirementsPrice * requirementTaxMult * requirementPriceMult;
@ -123,7 +123,7 @@ export class RagfairTaxService {
worth += this.calculateItemWorth( worth += this.calculateItemWorth(
child, child,
this.itemHelper.getItem(child._tpl)[1], this.itemHelper.getItem(child._tpl)[1],
child.upd!.StackObjectsCount!, child.upd.StackObjectsCount,
pmcData, pmcData,
false, false,
); );
@ -131,39 +131,39 @@ export class RagfairTaxService {
} }
} }
if ("Dogtag" in item.upd!) { if ("Dogtag" in item.upd) {
worth *= item.upd!.Dogtag!.Level; worth *= item.upd.Dogtag.Level;
} }
if ("Key" in item.upd! && (itemTemplate._props.MaximumNumberOfUsage ?? 0) > 0) { if ("Key" in item.upd && (itemTemplate._props.MaximumNumberOfUsage ?? 0) > 0) {
worth = worth =
(worth / itemTemplate._props.MaximumNumberOfUsage!) * (worth / itemTemplate._props.MaximumNumberOfUsage) *
(itemTemplate._props.MaximumNumberOfUsage! - item.upd!.Key!.NumberOfUsages); (itemTemplate._props.MaximumNumberOfUsage - item.upd.Key.NumberOfUsages);
} }
if ("Resource" in item.upd! && itemTemplate._props.MaxResource! > 0) { if ("Resource" in item.upd && itemTemplate._props.MaxResource > 0) {
worth = worth * 0.1 + ((worth * 0.9) / itemTemplate._props.MaxResource!) * item.upd.Resource!.Value; worth = worth * 0.1 + ((worth * 0.9) / itemTemplate._props.MaxResource) * item.upd.Resource.Value;
} }
if ("SideEffect" in item.upd! && itemTemplate._props.MaxResource! > 0) { if ("SideEffect" in item.upd && itemTemplate._props.MaxResource > 0) {
worth = worth * 0.1 + ((worth * 0.9) / itemTemplate._props.MaxResource!) * item.upd.SideEffect!.Value; worth = worth * 0.1 + ((worth * 0.9) / itemTemplate._props.MaxResource) * item.upd.SideEffect.Value;
} }
if ("MedKit" in item.upd! && itemTemplate._props.MaxHpResource! > 0) { if ("MedKit" in item.upd && itemTemplate._props.MaxHpResource > 0) {
worth = (worth / itemTemplate._props.MaxHpResource!) * item.upd.MedKit!.HpResource; worth = (worth / itemTemplate._props.MaxHpResource) * item.upd.MedKit.HpResource;
} }
if ("FoodDrink" in item.upd! && itemTemplate._props.MaxResource! > 0) { if ("FoodDrink" in item.upd && itemTemplate._props.MaxResource > 0) {
worth = (worth / itemTemplate._props.MaxResource!) * item.upd.FoodDrink!.HpPercent; worth = (worth / itemTemplate._props.MaxResource) * item.upd.FoodDrink.HpPercent;
} }
if ("Repairable" in item.upd! && <number>itemTemplate._props.armorClass > 0) { if ("Repairable" in item.upd && <number>itemTemplate._props.armorClass > 0) {
const num2 = 0.01 * 0.0 ** item.upd.Repairable!.MaxDurability; const num2 = 0.01 * 0.0 ** item.upd.Repairable.MaxDurability;
worth = worth =
worth * (item.upd.Repairable!.MaxDurability / itemTemplate._props.Durability! - num2) - worth * (item.upd.Repairable.MaxDurability / itemTemplate._props.Durability - num2) -
Math.floor( Math.floor(
itemTemplate._props.RepairCost! * itemTemplate._props.RepairCost *
(item.upd.Repairable!.MaxDurability - item.upd.Repairable!.Durability), (item.upd.Repairable.MaxDurability - item.upd.Repairable.Durability),
); );
} }

View File

@ -331,7 +331,7 @@ export class RepairService {
this.addMaxResourceToKitIfMissing(repairKitDetails, repairKitInInventory); this.addMaxResourceToKitIfMissing(repairKitDetails, repairKitInInventory);
// reduce usages on repairkit used // reduce usages on repairkit used
repairKitInInventory.upd!.RepairKit!.Resource -= repairKitReductionAmount; repairKitInInventory.upd.RepairKit.Resource -= repairKitReductionAmount;
output.profileChanges[sessionId].items.change.push(repairKitInInventory); output.profileChanges[sessionId].items.change.push(repairKitInInventory);
} }
@ -425,7 +425,7 @@ export class RepairService {
* @param repairKitInInventory Repair kit to update * @param repairKitInInventory Repair kit to update
*/ */
protected addMaxResourceToKitIfMissing(repairKitDetails: ITemplateItem, repairKitInInventory: Item): void { protected addMaxResourceToKitIfMissing(repairKitDetails: ITemplateItem, repairKitInInventory: Item): void {
const maxRepairAmount = repairKitDetails._props.MaxRepairResource!; const maxRepairAmount = repairKitDetails._props.MaxRepairResource;
if (!repairKitInInventory.upd) { if (!repairKitInInventory.upd) {
this.logger.debug(`Repair kit: ${repairKitInInventory._id} in inventory lacks upd object, adding`); this.logger.debug(`Repair kit: ${repairKitInInventory._id} in inventory lacks upd object, adding`);
repairKitInInventory.upd = { RepairKit: { Resource: maxRepairAmount } }; repairKitInInventory.upd = { RepairKit: { Resource: maxRepairAmount } };
@ -480,13 +480,13 @@ export class RepairService {
const bonusThresholdPercents = itemConfig[bonusRarity][bonusType].activeDurabilityPercentMinMax; const bonusThresholdPercents = itemConfig[bonusRarity][bonusType].activeDurabilityPercentMinMax;
const bonusThresholdPercent = this.randomUtil.getInt(bonusThresholdPercents.min, bonusThresholdPercents.max); const bonusThresholdPercent = this.randomUtil.getInt(bonusThresholdPercents.min, bonusThresholdPercents.max);
item.upd!.Buff = { item.upd.Buff = {
rarity: bonusRarity, rarity: bonusRarity,
buffType: bonusType, buffType: bonusType,
value: bonusValue, value: bonusValue,
thresholdDurability: this.randomUtil.getPercentOfValue( thresholdDurability: this.randomUtil.getPercentOfValue(
bonusThresholdPercent, bonusThresholdPercent,
item.upd!.Repairable!.Durability, item.upd.Repairable.Durability,
), ),
}; };
} }
@ -545,7 +545,7 @@ export class RepairService {
this.localisationService.getText("repair-item_has_no_repair_points", repairDetails.repairedItem._tpl), this.localisationService.getText("repair-item_has_no_repair_points", repairDetails.repairedItem._tpl),
); );
} }
const durabilityToRestorePercent = repairDetails.repairPoints / template._props.MaxDurability!; const durabilityToRestorePercent = repairDetails.repairPoints / template._props.MaxDurability;
const durabilityMultiplier = this.getDurabilityMultiplier( const durabilityMultiplier = this.getDurabilityMultiplier(
receivedDurabilityMaxPercent, receivedDurabilityMaxPercent,
durabilityToRestorePercent, durabilityToRestorePercent,

View File

@ -23,8 +23,8 @@
* - Finalized enum names are created as a combination of the parent name, prefix, item name, and suffix * - Finalized enum names are created as a combination of the parent name, prefix, item name, and suffix
*/ */
import * as fs from "fs"; import * as fs from "node:fs";
import * as path from "path"; import * as path from "node:path";
import { OnLoad } from "@spt/di/OnLoad"; import { OnLoad } from "@spt/di/OnLoad";
import { ItemHelper } from "@spt/helpers/ItemHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper";
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem"; import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
@ -62,7 +62,7 @@ export class ItemTplGenerator {
const currentDir = path.dirname(__filename); const currentDir = path.dirname(__filename);
const projectDir = path.resolve(currentDir, "..", "..", ".."); const projectDir = path.resolve(currentDir, "..", "..", "..");
this.enumDir = path.join(projectDir, "src", "models", "enums"); this.enumDir = path.join(projectDir, "src", "models", "enums");
this.items = this.databaseServer.getTables().templates!.items; this.items = this.databaseServer.getTables().templates.items;
this.itemOverrides = itemTplOverrides.default; this.itemOverrides = itemTplOverrides.default;
// Generate an object containing all item name to ID associations // Generate an object containing all item name to ID associations
@ -98,9 +98,9 @@ export class ItemTplGenerator {
const itemSuffix = this.getItemSuffix(item); const itemSuffix = this.getItemSuffix(item);
// Handle the case where the item starts with the parent category name. Avoids things like 'POCKETS_POCKETS' // Handle the case where the item starts with the parent category name. Avoids things like 'POCKETS_POCKETS'
if (itemParentName == itemName.substring(1, itemParentName.length + 1) && itemPrefix == "") { if (itemParentName === itemName.substring(1, itemParentName.length + 1) && itemPrefix === "") {
itemName = itemName.substring(itemParentName.length + 1); itemName = itemName.substring(itemParentName.length + 1);
if (itemName.length > 0 && itemName.at(0) != "_") { if (itemName.length > 0 && itemName.at(0) !== "_") {
itemName = `_${itemName}`; itemName = `_${itemName}`;
} }
} }
@ -179,7 +179,7 @@ export class ItemTplGenerator {
continue; continue;
} }
const caliber = this.cleanCaliber(item._props.ammoCaliber!.toUpperCase()); const caliber = this.cleanCaliber(item._props.ammoCaliber.toUpperCase());
let weaponShortName = this.localeService.getLocaleDb()[`${itemId} ShortName`]?.toUpperCase(); let weaponShortName = this.localeService.getLocaleDb()[`${itemId} ShortName`]?.toUpperCase();
// Special case for the weird duplicated grenade launcher // Special case for the weird duplicated grenade launcher
@ -236,29 +236,37 @@ export class ItemTplGenerator {
private getParentName(item: ITemplateItem): string { private getParentName(item: ITemplateItem): string {
if (item._props.QuestItem) { if (item._props.QuestItem) {
return "QUEST"; return "QUEST";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.BARTER_ITEM)) { }
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.BARTER_ITEM)) {
return "BARTER"; return "BARTER";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.THROW_WEAPON)) { }
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.THROW_WEAPON)) {
return "GRENADE"; return "GRENADE";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.STIMULATOR)) { }
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.STIMULATOR)) {
return "STIM"; return "STIM";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MAGAZINE)) { }
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MAGAZINE)) {
return "MAGAZINE"; return "MAGAZINE";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.KEY_MECHANICAL)) { }
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.KEY_MECHANICAL)) {
return "KEY"; return "KEY";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MOB_CONTAINER)) { }
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MOB_CONTAINER)) {
return "SECURE"; return "SECURE";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.SIMPLE_CONTAINER)) { }
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.SIMPLE_CONTAINER)) {
return "CONTAINER"; return "CONTAINER";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.PORTABLE_RANGE_FINDER)) { }
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.PORTABLE_RANGE_FINDER)) {
return "RANGEFINDER"; return "RANGEFINDER";
} }
// Why are flares grenade launcher...? // Why are flares grenade launcher...?
else if (item._name.startsWith("weapon_rsp30")) { if (item._name.startsWith("weapon_rsp30")) {
return "FLARE"; return "FLARE";
} }
// This is a special case for the signal pistol, I'm not adding it as a Grenade Launcher // This is a special case for the signal pistol, I'm not adding it as a Grenade Launcher
else if (item._id == "620109578d82e67e7911abf2") { if (item._id === "620109578d82e67e7911abf2") {
return "SIGNALPISTOL"; return "SIGNALPISTOL";
} }
@ -302,7 +310,7 @@ export class ItemTplGenerator {
} }
// Make sure there's an underscore separator // Make sure there's an underscore separator
if (prefix.length > 0 && prefix.at(0) != "_") { if (prefix.length > 0 && prefix.at(0) !== "_") {
prefix = `_${prefix}`; prefix = `_${prefix}`;
} }
@ -314,11 +322,11 @@ export class ItemTplGenerator {
// Add mag size for magazines // Add mag size for magazines
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MAGAZINE)) { if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MAGAZINE)) {
suffix = item._props.Cartridges![0]?._max_count?.toString() + "RND"; suffix = `${item._props.Cartridges[0]?._max_count?.toString()}RND`;
} }
// Add pack size for ammo boxes // Add pack size for ammo boxes
else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.AMMO_BOX)) { else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.AMMO_BOX)) {
suffix = item._props.StackSlots![0]?._max_count.toString() + "RND"; suffix = `${item._props.StackSlots[0]?._max_count.toString()}RND`;
} }
// Add "DAMAGED" for damaged items // Add "DAMAGED" for damaged items
@ -327,7 +335,7 @@ export class ItemTplGenerator {
} }
// Make sure there's an underscore separator // Make sure there's an underscore separator
if (suffix.length > 0 && suffix.at(0) != "_") { if (suffix.length > 0 && suffix.at(0) !== "_") {
suffix = `_${suffix}`; suffix = `_${suffix}`;
} }
@ -335,7 +343,7 @@ export class ItemTplGenerator {
} }
private getAmmoPrefix(item: ITemplateItem): string { private getAmmoPrefix(item: ITemplateItem): string {
const prefix = item._props.Caliber!.toUpperCase(); const prefix = item._props.Caliber.toUpperCase();
return this.cleanCaliber(prefix); return this.cleanCaliber(prefix);
} }
@ -352,13 +360,13 @@ export class ItemTplGenerator {
} }
private getAmmoBoxPrefix(item: ITemplateItem): string { private getAmmoBoxPrefix(item: ITemplateItem): string {
const ammoItem = item._props.StackSlots![0]?._props.filters[0].Filter[0]; const ammoItem = item._props.StackSlots[0]?._props.filters[0].Filter[0];
return this.getAmmoPrefix(this.items[ammoItem]); return this.getAmmoPrefix(this.items[ammoItem]);
} }
private getMagazinePrefix(item: ITemplateItem): string { private getMagazinePrefix(item: ITemplateItem): string {
const ammoItem = item._props.Cartridges![0]?._props.filters[0].Filter[0]; const ammoItem = item._props.Cartridges[0]?._props.filters[0].Filter[0];
return this.getAmmoPrefix(this.items[ammoItem]); return this.getAmmoPrefix(this.items[ammoItem]);
} }
@ -369,7 +377,7 @@ export class ItemTplGenerator {
* @returns The name of the given item * @returns The name of the given item
*/ */
private getItemName(item) { private getItemName(item) {
let itemName; let itemName: string;
// Manual item name overrides // Manual item name overrides
if (this.itemOverrides[item._id]) { if (this.itemOverrides[item._id]) {
@ -420,12 +428,12 @@ export class ItemTplGenerator {
// Add grid size for lootable containers // Add grid size for lootable containers
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.LOOT_CONTAINER)) { if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.LOOT_CONTAINER)) {
return `${item._props.Grids![0]?._props.cellsH}X${item._props.Grids![0]?._props.cellsV}`; return `${item._props.Grids[0]?._props.cellsH}X${item._props.Grids[0]?._props.cellsV}`;
} }
// Add ammo caliber to conflicting weapons // Add ammo caliber to conflicting weapons
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.WEAPON)) { if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.WEAPON)) {
const caliber = this.cleanCaliber(item._props.ammoCaliber!.toUpperCase()); const caliber = this.cleanCaliber(item._props.ammoCaliber.toUpperCase());
// If the item has a bracketed section at the end of its name, include that // If the item has a bracketed section at the end of its name, include that
const itemNameBracketSuffix = itemName?.match(/\((.+?)\)$/); const itemNameBracketSuffix = itemName?.match(/\((.+?)\)$/);

View File

@ -21,6 +21,6 @@ export class AsyncQueue implements IAsyncQueue {
} }
// When the command is ready, execute it // When the command is ready, execute it
return this.commandsQueue.shift()!.cmd(); return this.commandsQueue.shift().cmd();
} }
} }

View File

@ -46,7 +46,7 @@ export class ImporterUtil {
} }
// set all loadRecursive to be executed asynchronously // set all loadRecursive to be executed asynchronously
const resEntries = Object.entries(result!); const resEntries = Object.entries(result);
const resResolved = await Promise.all(resEntries.map((ent) => ent[1])); const resResolved = await Promise.all(resEntries.map((ent) => ent[1]));
for (let resIdx = 0; resIdx < resResolved.length; resIdx++) { for (let resIdx = 0; resIdx < resResolved.length; resIdx++) {
resEntries[resIdx][1] = resResolved[resIdx]; resEntries[resIdx][1] = resResolved[resIdx];

View File

@ -19,21 +19,21 @@ export class RagfairOfferHolder {
public getOfferById(id: string): IRagfairOffer | undefined { public getOfferById(id: string): IRagfairOffer | undefined {
if (this.offersById.has(id)) { if (this.offersById.has(id)) {
return this.offersById.get(id)!; return this.offersById.get(id);
} }
return undefined; return undefined;
} }
public getOffersByTemplate(templateId: string): Array<IRagfairOffer> | undefined { public getOffersByTemplate(templateId: string): Array<IRagfairOffer> | undefined {
if (this.offersByTemplate.has(templateId)) { if (this.offersByTemplate.has(templateId)) {
return [...this.offersByTemplate.get(templateId)!.values()]; return [...this.offersByTemplate.get(templateId).values()];
} }
return undefined; return undefined;
} }
public getOffersByTrader(traderId: string): Array<IRagfairOffer> | undefined { public getOffersByTrader(traderId: string): Array<IRagfairOffer> | undefined {
if (this.offersByTrader.has(traderId)) { if (this.offersByTrader.has(traderId)) {
return [...this.offersByTrader.get(traderId)!.values()]; return [...this.offersByTrader.get(traderId).values()];
} }
return undefined; return undefined;
} }
@ -76,18 +76,18 @@ export class RagfairOfferHolder {
if (this.offersById.has(offer._id)) { if (this.offersById.has(offer._id)) {
this.offersById.delete(offer._id); this.offersById.delete(offer._id);
if (this.offersByTrader.has(offer.user.id)) { if (this.offersByTrader.has(offer.user.id)) {
this.offersByTrader.get(offer.user.id)!.delete(offer._id); this.offersByTrader.get(offer.user.id).delete(offer._id);
// This was causing a memory leak, we need to make sure that we remove // This was causing a memory leak, we need to make sure that we remove
// the user ID from the cached offers after they dont have anything else // the user ID from the cached offers after they dont have anything else
// on the flea placed. We regenerate the ID for the NPC users, making it // on the flea placed. We regenerate the ID for the NPC users, making it
// continously grow otherwise // continously grow otherwise
if (this.offersByTrader.get(offer.user.id)!.size === 0) { if (this.offersByTrader.get(offer.user.id).size === 0) {
this.offersByTrader.delete(offer.user.id); this.offersByTrader.delete(offer.user.id);
} }
} }
if (this.offersByTemplate.has(offer.items[0]._tpl)) { if (this.offersByTemplate.has(offer.items[0]._tpl)) {
this.offersByTemplate.get(offer.items[0]._tpl)!.delete(offer._id); this.offersByTemplate.get(offer.items[0]._tpl).delete(offer._id);
} }
} }
} }
@ -100,7 +100,7 @@ export class RagfairOfferHolder {
public removeAllOffersByTrader(traderId: string): void { public removeAllOffersByTrader(traderId: string): void {
if (this.offersByTrader.has(traderId)) { if (this.offersByTrader.has(traderId)) {
this.removeOffers([...this.offersByTrader.get(traderId)!.values()]); this.removeOffers([...this.offersByTrader.get(traderId).values()]);
} }
} }
@ -114,7 +114,7 @@ export class RagfairOfferHolder {
protected addOfferByTemplates(template: string, offer: IRagfairOffer): void { protected addOfferByTemplates(template: string, offer: IRagfairOffer): void {
if (this.offersByTemplate.has(template)) { if (this.offersByTemplate.has(template)) {
this.offersByTemplate.get(template)!.set(offer._id, offer); this.offersByTemplate.get(template).set(offer._id, offer);
} else { } else {
const valueMapped = new Map<string, IRagfairOffer>(); const valueMapped = new Map<string, IRagfairOffer>();
valueMapped.set(offer._id, offer); valueMapped.set(offer._id, offer);
@ -124,7 +124,7 @@ export class RagfairOfferHolder {
protected addOfferByTrader(trader: string, offer: IRagfairOffer): void { protected addOfferByTrader(trader: string, offer: IRagfairOffer): void {
if (this.offersByTrader.has(trader)) { if (this.offersByTrader.has(trader)) {
this.offersByTrader.get(trader)!.set(offer._id, offer); this.offersByTrader.get(trader).set(offer._id, offer);
} else { } else {
const valueMapped = new Map<string, IRagfairOffer>(); const valueMapped = new Map<string, IRagfairOffer>();
valueMapped.set(offer._id, offer); valueMapped.set(offer._id, offer);

View File

@ -24,7 +24,6 @@ export class RecursiveCloner implements ICloner {
// clone the object types // clone the object types
if (typeOfObj === "object") { if (typeOfObj === "object") {
if (Array.isArray(obj)) { if (Array.isArray(obj)) {
// biome-ignore lint/suspicious/noExplicitAny: used for clone
const objArr = obj as Array<any>; const objArr = obj as Array<any>;
return objArr.map((v) => this.clone(v)) as T; return objArr.map((v) => this.clone(v)) as T;
} }

View File

@ -163,7 +163,7 @@ export abstract class AbstractWinstonLogger implements ILogger {
} }
public async success(data: string | Record<string, unknown>): Promise<void> { public async success(data: string | Record<string, unknown>): Promise<void> {
const command: ICommand = { uuid: crypto.randomUUID(), cmd: async () => await this.logger.succ!(data) }; const command: ICommand = { uuid: crypto.randomUUID(), cmd: async () => await this.logger.succ(data) };
await this.asyncQueue.waitFor(command); await this.asyncQueue.waitFor(command);
} }

View File

@ -3,7 +3,6 @@ import { container } from "tsyringe";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
describe("LocaleService", () => { describe("LocaleService", () => {
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
let localeService: any; // Using "any" to access private/protected methods without type errors. let localeService: any; // Using "any" to access private/protected methods without type errors.
beforeEach(() => { beforeEach(() => {