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__/*",
"types/*",
"user/mods/*",
"user/profiles/*",
"assets/database/*"
]
},

View File

@ -49,7 +49,7 @@ export class ClientLogCallbacks {
data.isBeta = globalThis.G_WATERMARK_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);
}

View File

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

View File

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

View File

@ -48,7 +48,7 @@ export class CustomizationController {
if (matchingSuits === undefined)
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) {
const sptCommando = this.dialogueChatBots.find(
(c) => c.getChatBot()._id.toLocaleLowerCase() === "sptcommando",
)!;
);
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptCommando), 1);
}
if (!coreConfigs.features?.chatbotFeatures?.sptFriendEnabled) {
const sptFriend = this.dialogueChatBots.find(
(c) => c.getChatBot()._id.toLocaleLowerCase() === "sptFriend",
)!;
const sptFriend = this.dialogueChatBots.find((c) => c.getChatBot()._id.toLocaleLowerCase() === "sptFriend");
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptFriend), 1);
}
}
@ -205,7 +203,7 @@ export class DialogueController {
if (!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 {
const db = this.databaseService.getTables();
const traders = db.traders!;
const quests = db.templates!.quests;
const traders = db.traders;
const quests = db.templates.quests;
for (const traderId of Object.values(Traders)) {
const traderData = traders[traderId];
const traderAssorts = traderData?.assort;
@ -875,7 +875,7 @@ export class GameController {
* Make non-trigger-spawned raiders spawn earlier + always
*/
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
const nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.filter(

View File

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

View File

@ -120,6 +120,6 @@ export class MatchController {
/** Handle client/match/local/end */
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 = {};
change[repeatableQuestProfile._id] = repeatableSettings!.changeRequirement[repeatableQuestProfile._id];
change[repeatableQuestProfile._id] = repeatableSettings.changeRequirement[repeatableQuestProfile._id];
const repeatableData: IPmcDataRepeatableQuest = {
id:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -35,7 +35,7 @@ export class HealthHelper {
if (!profile.vitality) {
// Occurs on newly created profiles
profile.vitality = { health: undefined!, effects: undefined! };
profile.vitality = { health: undefined, effects: undefined };
}
profile.vitality.health = {
Hydration: 0,
@ -176,7 +176,7 @@ export class HealthHelper {
const fullProfile = this.saveServer.getProfile(sessionID);
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
for (const bodyPart in postRaidBodyParts) {

View File

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

View File

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

View File

@ -61,8 +61,8 @@ export class RagfairSortHelper {
protected sortOffersByBarter(a: IRagfairOffer, b: IRagfairOffer): number {
const moneyTpls = Object.values<string>(Money);
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 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;
return aIsOnlyMoney - bIsOnlyMoney;
}

View File

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

View File

@ -149,13 +149,13 @@ export class TraderHelper {
// Force suit ids into profile
this.addSuitsToProfile(
fullProfile,
clothing!.map((suit) => suit.suiteId),
clothing.map((suit) => suit.suiteId),
);
}
}
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);
if (existingBan) {
existingBan.dateTime = newBanDateTime;
@ -334,9 +334,9 @@ export class TraderHelper {
},
);
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 {
@ -390,14 +390,14 @@ export class TraderHelper {
if (
profile.traderPurchases[traderId][purchasedItem.itemId].count + purchasedItem.count >
this.getAccountTypeAdjustedTraderPurchaseLimit(
itemPurchased.upd!.BuyRestrictionMax!,
itemPurchased.upd.BuyRestrictionMax,
profile.characters.pmc.Info.GameVersion,
)
) {
throw new Error(
this.localisationService.getText("trader-unable_to_purchase_item_limit_reached", {
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 {
if (!profile.vitality) {
// Occurs on newly created profiles
profile.vitality = { health: undefined!, effects: undefined! };
profile.vitality = { health: undefined, effects: undefined };
}
profile.vitality.health = {
Hydration: 0,

View File

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

View File

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

View File

@ -48,7 +48,7 @@ export class DatabaseService {
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));
}
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
*/
public getAchievements(): IAchievement[] {
if (!this.databaseServer.getTables().templates!.achievements) {
if (!this.databaseServer.getTables().templates.achievements) {
throw new Error(
this.localisationService.getText(
"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
*/
public getCustomization(): Record<string, ICustomizationItem> {
if (!this.databaseServer.getTables().templates!.customization) {
if (!this.databaseServer.getTables().templates.customization) {
throw new Error(
this.localisationService.getText(
"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
*/
public getHandbook(): IHandbookBase {
if (!this.databaseServer.getTables().templates!.handbook) {
if (!this.databaseServer.getTables().templates.handbook) {
throw new Error(
this.localisationService.getText(
"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
*/
public getItems(): Record<string, ITemplateItem> {
if (!this.databaseServer.getTables().templates!.items) {
if (!this.databaseServer.getTables().templates.items) {
throw new Error(
this.localisationService.getText(
"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
*/
public getPrices(): Record<string, number> {
if (!this.databaseServer.getTables().templates!.prices) {
if (!this.databaseServer.getTables().templates.prices) {
throw new Error(
this.localisationService.getText(
"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
*/
public getProfiles(): IProfileTemplates {
if (!this.databaseServer.getTables().templates!.profiles) {
if (!this.databaseServer.getTables().templates.profiles) {
throw new Error(
this.localisationService.getText(
"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
*/
public getQuests(): Record<string, IQuest> {
if (!this.databaseServer.getTables().templates!.quests) {
if (!this.databaseServer.getTables().templates.quests) {
throw new Error(
this.localisationService.getText(
"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));
}
return desiredTrader!;
return desiredTrader;
}
/**
* @returns assets/database/locationServices/
*/
public getLocationServices(): ILocationServices {
if (!this.databaseServer.getTables().templates!.locationServices) {
if (!this.databaseServer.getTables().templates.locationServices) {
throw new Error(
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
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
if (pmcProfile.TradersInfo[Traders.FENCE].standing >= 6) {
const discountAssort = this.cloner.clone(this.fenceDiscountAssort);
this.adjustAssortItemPricesByConfigMultiplier(
discountAssort!,
discountAssort,
this.traderConfig.fence.discountOptions.itemPriceMult,
this.traderConfig.fence.discountOptions.presetPriceMult,
);
const mergedAssorts = this.mergeAssorts(assort!, discountAssort!);
const mergedAssorts = this.mergeAssorts(assort, discountAssort);
return mergedAssorts;
}
return assort!;
return assort;
}
/**
@ -172,7 +172,7 @@ export class FenceService {
createAssort.sptItems.push(clonedItems);
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
*/
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
this.deleteRandomAssorts(itemCountToReplace, this.fenceAssort!);
this.deleteRandomAssorts(discountItemCountToReplace, this.fenceDiscountAssort!);
this.deleteRandomAssorts(itemCountToReplace, this.fenceAssort);
this.deleteRandomAssorts(discountItemCountToReplace, this.fenceDiscountAssort);
const normalItemCountsToGenerate = this.getItemCountsToGenerate(
this.fenceAssort!.items,
this.fenceAssort.items,
this.desiredAssortCounts.normal,
);
const newItems = this.createAssorts(normalItemCountsToGenerate, 1);
// Push newly generated assorts into existing data
this.updateFenceAssorts(newItems, this.fenceAssort!);
this.updateFenceAssorts(newItems, this.fenceAssort);
const discountItemCountsToGenerate = this.getItemCountsToGenerate(
this.fenceDiscountAssort!.items,
this.fenceDiscountAssort.items,
this.desiredAssortCounts.discount,
);
const newDiscountItems = this.createAssorts(discountItemCountsToGenerate, 2);
// 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
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
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
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
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];
}
@ -387,11 +387,11 @@ export class FenceService {
) {
// Guard against a missing stack count
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
existingRootItem.upd!.StackObjectsCount += newRootItem?.upd?.StackObjectsCount ?? 1;
existingRootItem.upd.StackObjectsCount += newRootItem?.upd?.StackObjectsCount ?? 1;
continue;
}
@ -493,7 +493,7 @@ export class FenceService {
}
// Reduce stack to at smallest, 1
rootItemToAdjust.upd!.StackObjectsCount! -= Math.max(1, itemCountToRemove);
rootItemToAdjust.upd.StackObjectsCount -= Math.max(1, itemCountToRemove);
return;
}
@ -689,7 +689,7 @@ export class FenceService {
);
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) {
// Skip adding item as assort as limit reached, decrement i counter so we still get another item
i--;
@ -723,7 +723,7 @@ export class FenceService {
const rootItemBeingAdded = desiredAssortItemAndChildrenClone[0];
// 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
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
const existingItemThatMatches = this.getMatchingItem(rootItemBeingAdded, itemDbDetails, assorts.sptItems)!;
const existingItemThatMatches = this.getMatchingItem(rootItemBeingAdded, itemDbDetails, assorts.sptItems);
const shouldBeStacked = this.itemShouldBeForceStacked(existingItemThatMatches, itemDbDetails);
if (shouldBeStacked && existingItemThatMatches) {
// Decrement loop counter so another items gets added
i--;
existingItemThatMatches.upd!.StackObjectsCount!++;
existingItemThatMatches.upd.StackObjectsCount++;
continue;
}
@ -803,7 +803,7 @@ export class FenceService {
// Items have sub properties that need to be checked against
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
// Both undefined === both max resoruce left
return item;
@ -812,8 +812,8 @@ export class FenceService {
// Armors/helmets etc
if (
isGearAndHasSlots &&
rootItemBeingAdded.upd!.Repairable?.Durability === item.upd!.Repairable?.Durability &&
rootItemBeingAdded.upd!.Repairable?.MaxDurability === item.upd!.Repairable?.MaxDurability
rootItemBeingAdded.upd.Repairable?.Durability === item.upd.Repairable?.Durability &&
rootItemBeingAdded.upd.Repairable?.MaxDurability === item.upd.Repairable?.MaxDurability
) {
return item;
}
@ -860,7 +860,7 @@ export class FenceService {
): void {
// Healing items
if (itemRoot.upd?.MedKit) {
const itemTotalMax = itemTemplate._props.MaxHpResource!;
const itemTotalMax = itemTemplate._props.MaxHpResource;
const current = itemRoot.upd.MedKit.HpResource;
// Current and max match, no adjustment necessary
@ -1042,7 +1042,7 @@ export class FenceService {
// Check for and adjust soft insert durability values
const requiredSlots = itemDbDetails._props.Slots?.filter((slot) => slot._required);
if (Boolean(requiredSlots?.length)) {
if (requiredSlots?.length) {
this.randomiseArmorSoftInsertDurabilities(requiredSlots, armor);
}
@ -1050,7 +1050,7 @@ export class FenceService {
const plateSlots = itemDbDetails._props.Slots?.filter((slot) =>
this.itemHelper.isRemovablePlateSlot(slot._name),
);
if (Boolean(plateSlots?.length)) {
if (plateSlots?.length) {
this.randomiseArmorInsertsDurabilities(plateSlots, armor);
}
}
@ -1061,8 +1061,8 @@ export class FenceService {
* @param armorItemAndMods Array of armor + inserts to get items from
*/
protected randomiseArmorSoftInsertDurabilities(softInsertSlots: Slot[], armorItemAndMods: Item[]): void {
for (const requiredSlot of softInsertSlots!) {
const modItemDbDetails = this.itemHelper.getItem(requiredSlot._props.filters[0].Plate!)[1];
for (const requiredSlot of softInsertSlots) {
const modItemDbDetails = this.itemHelper.getItem(requiredSlot._props.filters[0].Plate)[1];
const durabilityValues = this.getRandomisedArmorDurabilityValues(
modItemDbDetails,
this.traderConfig.fence.armorMaxDurabilityPercentMinMax,
@ -1075,29 +1075,29 @@ export class FenceService {
// Find items mod to apply dura changes to
const modItemToAdjust = armorItemAndMods.find(
(mod) => mod.slotId!.toLowerCase() === requiredSlot._name.toLowerCase(),
)!;
(mod) => mod.slotId.toLowerCase() === requiredSlot._name.toLowerCase(),
);
this.itemHelper.addUpdObjectToItem(modItemToAdjust);
if (!modItemToAdjust.upd!.Repairable) {
modItemToAdjust.upd!.Repairable = {
Durability: modItemDbDetails._props.MaxDurability!,
MaxDurability: modItemDbDetails._props.MaxDurability!,
if (!modItemToAdjust.upd.Repairable) {
modItemToAdjust.upd.Repairable = {
Durability: modItemDbDetails._props.MaxDurability,
MaxDurability: modItemDbDetails._props.MaxDurability,
};
}
modItemToAdjust.upd!.Repairable.Durability = durabilityValues.Durability;
modItemToAdjust.upd!.Repairable.MaxDurability = durabilityValues.MaxDurability;
modItemToAdjust.upd.Repairable.Durability = durabilityValues.Durability;
modItemToAdjust.upd.Repairable.MaxDurability = durabilityValues.MaxDurability;
// 25% chance to add shots to visor items when its below max durability
if (
this.randomUtil.getChance100(25) &&
modItemToAdjust.parentId === BaseClasses.ARMORED_EQUIPMENT &&
modItemToAdjust.slotId === "mod_equipment_000" &&
modItemToAdjust.upd!.Repairable.Durability < modItemDbDetails._props.MaxDurability!
modItemToAdjust.upd.Repairable.Durability < modItemDbDetails._props.MaxDurability
) {
// 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
*/
protected randomiseArmorInsertsDurabilities(plateSlots: Slot[], armorItemAndMods: Item[]): void {
for (const plateSlot of plateSlots!) {
for (const plateSlot of plateSlots) {
const plateTpl = plateSlot._props.filters[0].Plate;
if (!plateTpl) {
// Bsg data lacks a default plate, skip randomisng for this mod
@ -1124,7 +1124,7 @@ export class FenceService {
if (!this.randomUtil.getChance100(plateExistsChance)) {
// Remove plate from armor
armorItemAndMods = armorItemAndMods.filter(
(item) => item.slotId!.toLowerCase() !== plateSlot._name.toLowerCase(),
(item) => item.slotId.toLowerCase() !== plateSlot._name.toLowerCase(),
);
continue;
@ -1137,7 +1137,7 @@ export class FenceService {
// Find items mod to apply dura changes to
const modItemToAdjust = armorItemAndMods.find(
(mod) => mod.slotId!.toLowerCase() === plateSlot._name.toLowerCase(),
(mod) => mod.slotId.toLowerCase() === plateSlot._name.toLowerCase(),
);
if (!modItemToAdjust) {
@ -1150,14 +1150,14 @@ export class FenceService {
this.itemHelper.addUpdObjectToItem(modItemToAdjust);
if (!modItemToAdjust?.upd?.Repairable) {
modItemToAdjust!.upd!.Repairable = {
Durability: modItemDbDetails._props.MaxDurability!,
MaxDurability: modItemDbDetails._props.MaxDurability!,
modItemToAdjust.upd.Repairable = {
Durability: modItemDbDetails._props.MaxDurability,
MaxDurability: modItemDbDetails._props.MaxDurability,
};
}
modItemToAdjust!.upd!.Repairable.Durability = durabilityValues.Durability;
modItemToAdjust!.upd!.Repairable.MaxDurability = durabilityValues.MaxDurability;
modItemToAdjust.upd.Repairable.Durability = durabilityValues.Durability;
modItemToAdjust.upd.Repairable.MaxDurability = durabilityValues.MaxDurability;
}
}
@ -1176,7 +1176,7 @@ export class FenceService {
// No override, use stack max size from item db
return itemDbDetails._props.StackMaxSize === 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
@ -1232,7 +1232,7 @@ export class FenceService {
*/
protected presetModItemWillBeRemoved(weaponMod: Item, itemsBeingDeleted: string[]): boolean {
const slotIdsThatCanFail = this.traderConfig.fence.presetSlotsToRemoveChancePercent;
const removalChance = slotIdsThatCanFail[weaponMod.slotId!];
const removalChance = slotIdsThatCanFail[weaponMod.slotId];
if (!removalChance) {
return false;
}
@ -1259,7 +1259,7 @@ export class FenceService {
// Randomise hp resource of med items
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
@ -1273,7 +1273,7 @@ export class FenceService {
itemDetails,
this.traderConfig.fence.armorMaxDurabilityPercentMinMax,
);
itemToAdjust.upd!.Repairable = { Durability: values.Durability, MaxDurability: values.MaxDurability };
itemToAdjust.upd.Repairable = { Durability: values.Durability, MaxDurability: values.MaxDurability };
return;
}
@ -1281,25 +1281,25 @@ export class FenceService {
// Randomise Weapon durability
if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.WEAPON)) {
const weaponDurabilityLimits = this.traderConfig.fence.weaponDurabilityPercentMinMax;
const maxDuraMin = (weaponDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability!;
const maxDuraMax = (weaponDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability!;
const maxDuraMin = (weaponDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability;
const maxDuraMax = (weaponDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability;
const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax);
const currentDuraMin = (weaponDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability!;
const currentDuraMax = (weaponDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability!;
const currentDuraMin = (weaponDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability;
const currentDuraMax = (weaponDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability;
const currentDurability = Math.min(
this.randomUtil.getInt(currentDuraMin, currentDuraMax),
chosenMaxDurability,
);
itemToAdjust.upd!.Repairable = { Durability: currentDurability, MaxDurability: chosenMaxDurability };
itemToAdjust.upd.Repairable = { Durability: currentDurability, MaxDurability: chosenMaxDurability };
return;
}
if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.REPAIR_KITS)) {
itemToAdjust.upd!.RepairKit = {
Resource: this.randomUtil.getInt(1, itemDetails._props.MaxRepairResource!),
itemToAdjust.upd.RepairKit = {
Resource: this.randomUtil.getInt(1, itemDetails._props.MaxRepairResource),
};
return;
@ -1310,8 +1310,8 @@ export class FenceService {
this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.KEY_MECHANICAL) &&
(itemDetails._props.MaximumNumberOfUsage ?? 0) > 1
) {
itemToAdjust.upd!.Key = {
NumberOfUsages: this.randomUtil.getInt(0, itemDetails._props.MaximumNumberOfUsage! - 1),
itemToAdjust.upd.Key = {
NumberOfUsages: this.randomUtil.getInt(0, itemDetails._props.MaximumNumberOfUsage - 1),
};
return;
@ -1319,10 +1319,10 @@ export class FenceService {
// Randomise items that use resources (e.g. fuel)
if ((itemDetails._props.MaxResource ?? 0) > 0) {
const resourceMax = itemDetails._props.MaxResource!;
const resourceCurrent = this.randomUtil.getInt(1, itemDetails._props.MaxResource!);
const resourceMax = 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,
equipmentDurabilityLimits: IItemDurabilityCurrentMax,
): Repairable {
const maxDuraMin = (equipmentDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability!;
const maxDuraMax = (equipmentDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability!;
const maxDuraMin = (equipmentDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability;
const maxDuraMax = (equipmentDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability;
const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax);
const currentDuraMin = (equipmentDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability!;
const currentDuraMax = (equipmentDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability!;
const currentDuraMin = (equipmentDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability;
const currentDuraMax = (equipmentDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability;
const chosenCurrentDurability = Math.min(
this.randomUtil.getInt(currentDuraMin, currentDuraMax),
chosenMaxDurability,
@ -1380,7 +1380,7 @@ export class FenceService {
* @returns Refresh time in seconds
*/
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);
}
@ -1421,10 +1421,10 @@ export class FenceService {
*/
public amendOrRemoveFenceOffer(assortId: string, buyCount: number): void {
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) {
// 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) {
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
if (fenceAssortItem.upd!.StackObjectsCount === buyCount) {
this.deleteOffer(assortId, isNormalAssort ? this.fenceAssort!.items : this.fenceDiscountAssort!.items);
if (fenceAssortItem.upd.StackObjectsCount === buyCount) {
this.deleteOffer(assortId, isNormalAssort ? this.fenceAssort.items : this.fenceDiscountAssort.items);
return;
}
// Adjust stack size
fenceAssortItem.upd!.StackObjectsCount! -= buyCount;
fenceAssortItem.upd.StackObjectsCount -= buyCount;
}
protected deleteOffer(assortId: string, assorts: Item[]): void {
@ -1452,8 +1452,8 @@ export class FenceService {
// No offer found in main assort, check discount items
if (indexToRemove === -1) {
indexToRemove = this.fenceDiscountAssort!.items.findIndex((item) => item._id === itemToRemove._id);
this.fenceDiscountAssort!.items.splice(indexToRemove, 1);
indexToRemove = this.fenceDiscountAssort.items.findIndex((item) => item._id === itemToRemove._id);
this.fenceDiscountAssort.items.splice(indexToRemove, 1);
if (indexToRemove === -1) {
this.logger.warning(

View File

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

View File

@ -142,7 +142,7 @@ export class InsuranceService {
(bonus) => bonus.type === BonusType.INSURANCE_RETURN_TIME,
);
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 traderMaxReturnAsSeconds = trader.insurance.max_return_hour * TimeUtil.ONE_HOUR_AS_SECONDS;
@ -214,7 +214,7 @@ export class InsuranceService {
const result: IInsuranceEquipmentPkg[] = [];
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) {
this.logger.error(
`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
*/
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) {
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'`,
);
return this.databaseServer.getTables().locales!.global.en;
return this.databaseServer.getTables().locales.global.en;
}
/**
@ -118,7 +118,7 @@ export class LocaleService {
return "en";
}
const locales = this.databaseServer.getTables().locales!;
const locales = this.databaseServer.getTables().locales;
const baseNameCode = platformLocale.baseName?.toLocaleLowerCase();
if (baseNameCode && locales.global[baseNameCode]) {
return baseNameCode;

View File

@ -51,7 +51,7 @@ export class LocalisationService {
* @returns string array of keys
*/
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
*/
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),
);
const chosenKey = this.randomUtil.getArrayValue(filteredKeys);

View File

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

View File

@ -396,7 +396,7 @@ export class MailSendService {
let itemsToSendToPlayer: MessageItems = {};
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
const parentItem = this.getBaseItemFromRewards(messageDetails.items!);
const parentItem = this.getBaseItemFromRewards(messageDetails.items);
if (!parentItem) {
this.localisationService.getText("mailsend-missing_parent", {
traderId: messageDetails.trader,
@ -414,7 +414,7 @@ export class MailSendService {
itemsToSendToPlayer = { stash: parentItem.parentId, data: [] };
// 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) {
// Ensure item exists in items db
@ -444,7 +444,7 @@ export class MailSendService {
this.itemHelper.addCartridgesToAmmoBox(boxAndCartridges, itemTemplate);
// Push box + cartridge children into array
itemsToSendToPlayer.data!.push(...boxAndCartridges);
itemsToSendToPlayer.data.push(...boxAndCartridges);
} else {
if ("StackSlots" in itemTemplate._props) {
this.logger.error(
@ -453,12 +453,12 @@ export class MailSendService {
}
// 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
if (itemsToSendToPlayer.data!.length === 0) {
if (itemsToSendToPlayer.data.length === 0) {
delete itemsToSendToPlayer.data;
}
}

View File

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

View File

@ -84,7 +84,7 @@ export class ProfileFixerService {
this.reorderHideoutAreasWithResouceInputs(pmcProfile);
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
) {
this.logger.debug("Updating generator area slots to a size of 6 + hideout management skill");
@ -96,7 +96,7 @@ export class ProfileFixerService {
}
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
) {
this.logger.debug("Updating water collector area slots to a size of 1 + hideout management skill");
@ -108,7 +108,7 @@ export class ProfileFixerService {
}
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
) {
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!!
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
) {
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 hideoutStandAreaDb = hideout.areas.find((area) => area.type === HideoutAreas.WEAPON_STAND)!;
const hideoutStandSecondaryAreaDb = hideout.areas.find((x) => x.parentArea === hideoutStandAreaDb._id)!;
const hideoutStandAreaDb = hideout.areas.find((area) => area.type === HideoutAreas.WEAPON_STAND);
const hideoutStandSecondaryAreaDb = hideout.areas.find((x) => x.parentArea === hideoutStandAreaDb._id);
const stageCurrentAt = hideoutStandAreaDb.stages[weaponStandArea.level];
const hideoutStandStashId = pmcProfile.Inventory.hideoutAreaStashes[HideoutAreas.WEAPON_STAND];
const hideoutSecondaryStashId = pmcProfile.Inventory.hideoutAreaStashes[HideoutAreas.WEAPON_STAND_SECONDARY];
@ -188,12 +188,12 @@ export class ProfileFixerService {
// Add stash item to profile
const gunStandStashItem = pmcProfile.Inventory.items.find((item) => item._id === hideoutStandAreaDb._id);
if (gunStandStashItem) {
gunStandStashItem._tpl = stageCurrentAt.container!;
gunStandStashItem._tpl = stageCurrentAt.container;
this.logger.debug(
`Updated existing gun stand inventory stash: ${gunStandStashItem._id} tpl to ${stageCurrentAt.container}`,
);
} else {
pmcProfile.Inventory.items.push({ _id: hideoutStandAreaDb._id, _tpl: stageCurrentAt.container! });
pmcProfile.Inventory.items.push({ _id: hideoutStandAreaDb._id, _tpl: stageCurrentAt.container });
this.logger.debug(
`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
const gunStandStashSecondaryItem = pmcProfile.Inventory.items.find(
(item) => item._id === hideoutStandSecondaryAreaDb._id,
)!;
);
if (gunStandStashItem) {
gunStandStashSecondaryItem._tpl = stageCurrentAt.container!;
gunStandStashSecondaryItem._tpl = stageCurrentAt.container;
this.logger.debug(
`Updated gun stand existing inventory secondary stash: ${gunStandStashSecondaryItem._id} tpl to ${stageCurrentAt.container}`,
);
} else {
pmcProfile.Inventory.items.push({
_id: hideoutStandSecondaryAreaDb._id,
_tpl: stageCurrentAt.container!,
_tpl: stageCurrentAt.container,
});
this.logger.debug(
`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);
if (!stashItem) {
// 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);
}
// `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(
`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
stashItem!._tpl = stageCurrentAt.container!;
stashItem._tpl = stageCurrentAt.container;
}
let stashSecondaryItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandSecondaryAreaDb._id);
if (!stashSecondaryItem) {
// 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);
}
@ -250,7 +250,7 @@ export class ProfileFixerService {
`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
stashSecondaryItem!._tpl = stageCurrentAt.container!;
stashSecondaryItem._tpl = stageCurrentAt.container;
}
}
@ -278,12 +278,12 @@ export class ProfileFixerService {
// Add stash item to profile
const placeOfFameStashItem = pmcProfile.Inventory.items.find((item) => item._id === placeOfFameAreaDb._id);
if (placeOfFameStashItem) {
placeOfFameStashItem._tpl = stageCurrentlyAt.container!;
placeOfFameStashItem._tpl = stageCurrentlyAt.container;
this.logger.debug(
`Updated existing place of fame inventory stash: ${placeOfFameStashItem._id} tpl to ${stageCurrentlyAt.container}`,
);
} else {
pmcProfile.Inventory.items.push({ _id: placeOfFameAreaDb._id, _tpl: stageCurrentlyAt.container! });
pmcProfile.Inventory.items.push({ _id: placeOfFameAreaDb._id, _tpl: stageCurrentlyAt.container });
this.logger.debug(
`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);
if (!stashItem) {
// 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);
}
// `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(
`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
stashItem!._tpl = stageCurrentlyAt.container!;
stashItem._tpl = stageCurrentlyAt.container;
}
}
@ -574,13 +574,13 @@ export class ProfileFixerService {
* @param pmcProfile Profile to add improvement data to
*/
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);
if (profileWallArea.level > 0) {
for (let i = 0; i < profileWallArea.level; i++) {
// Get wall stage from db
const wallStageDb = wallDb!.stages[i];
const wallStageDb = wallDb.stages[i];
if (wallStageDb.improvements.length === 0) {
// No improvements, skip
continue;
@ -640,7 +640,7 @@ export class ProfileFixerService {
for (const areaId of areasToCheck) {
const area = pmcProfile.Hideout.Areas.find((area) => area.type === areaId);
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;
}
@ -666,7 +666,7 @@ export class ProfileFixerService {
pmcProfile: IPmcData,
): void {
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[] {
@ -878,9 +878,9 @@ export class ProfileFixerService {
continue;
}
for (const successReward of activeQuest.rewards.Success!) {
for (const successReward of activeQuest.rewards.Success) {
if (successReward.type === "Item") {
for (const rewardItem of successReward.items!) {
for (const rewardItem of successReward.items) {
if (!itemsDb[rewardItem._tpl]) {
this.logger.error(
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
const itemsHaveChildren = pmcProfile.Inventory.items.some((x) => x.parentId === key);
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();
this.logger.warning(`Replace duplicate item Id: ${key} with ${itemToAdjust._id}`);
}
@ -1047,7 +1047,7 @@ export class ProfileFixerService {
const defaultHead = playerIsUsec
? customizationDbArray.find((x) => x._name === "DefaultUsecHead")
: customizationDbArray.find((x) => x._name === "DefaultBearHead");
pmcProfile.Customization.Head = defaultHead!._id;
pmcProfile.Customization.Head = defaultHead._id;
}
// check Body
@ -1056,7 +1056,7 @@ export class ProfileFixerService {
pmcProfile.Info.Side.toLowerCase() === "usec"
? customizationDbArray.find((x) => x._name === "DefaultUsecBody")
: customizationDbArray.find((x) => x._name === "DefaultBearBody");
pmcProfile.Customization.Body = defaultBody!._id;
pmcProfile.Customization.Body = defaultBody._id;
}
// check Hands
@ -1065,7 +1065,7 @@ export class ProfileFixerService {
pmcProfile.Info.Side.toLowerCase() === "usec"
? customizationDbArray.find((x) => x._name === "DefaultUsecHands")
: customizationDbArray.find((x) => x._name === "DefaultBearHands");
pmcProfile.Customization.Hands = defaultHands!._id;
pmcProfile.Customization.Hands = defaultHands._id;
}
// check Hands
@ -1074,7 +1074,7 @@ export class ProfileFixerService {
pmcProfile.Info.Side.toLowerCase() === "usec"
? customizationDbArray.find((x) => x._name === "DefaultUsecFeet")
: 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 {
const offer = this.ragfairOfferHandler.getOfferById(offerId);
if (offer) {
offer.items[0].upd!.StackObjectsCount! -= amount;
if (offer.items[0].upd!.StackObjectsCount! <= 0) {
offer.items[0].upd.StackObjectsCount -= amount;
if (offer.items[0].upd.StackObjectsCount <= 0) {
this.processStaleOffer(offer);
}
}
@ -245,10 +245,10 @@ export class RagfairOfferService {
profile.RagfairInfo.isRatingGrowing = false;
const firstOfferItem = playerOffer.items[0];
if (firstOfferItem.upd!.StackObjectsCount! > firstOfferItem.upd!.OriginalStackObjectsCount!) {
playerOffer.items[0].upd!.StackObjectsCount = firstOfferItem.upd!.OriginalStackObjectsCount;
if (firstOfferItem.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
this.ragfairOfferHandler.removeOffer(playerOffer);

View File

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

View File

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

View File

@ -23,8 +23,8 @@
* - Finalized enum names are created as a combination of the parent name, prefix, item name, and suffix
*/
import * as fs from "fs";
import * as path from "path";
import * as fs from "node:fs";
import * as path from "node:path";
import { OnLoad } from "@spt/di/OnLoad";
import { ItemHelper } from "@spt/helpers/ItemHelper";
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
@ -62,7 +62,7 @@ export class ItemTplGenerator {
const currentDir = path.dirname(__filename);
const projectDir = path.resolve(currentDir, "..", "..", "..");
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;
// Generate an object containing all item name to ID associations
@ -98,9 +98,9 @@ export class ItemTplGenerator {
const itemSuffix = this.getItemSuffix(item);
// 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);
if (itemName.length > 0 && itemName.at(0) != "_") {
if (itemName.length > 0 && itemName.at(0) !== "_") {
itemName = `_${itemName}`;
}
}
@ -179,7 +179,7 @@ export class ItemTplGenerator {
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();
// Special case for the weird duplicated grenade launcher
@ -236,29 +236,37 @@ export class ItemTplGenerator {
private getParentName(item: ITemplateItem): string {
if (item._props.QuestItem) {
return "QUEST";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.BARTER_ITEM)) {
}
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.BARTER_ITEM)) {
return "BARTER";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.THROW_WEAPON)) {
}
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.THROW_WEAPON)) {
return "GRENADE";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.STIMULATOR)) {
}
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.STIMULATOR)) {
return "STIM";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MAGAZINE)) {
}
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MAGAZINE)) {
return "MAGAZINE";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.KEY_MECHANICAL)) {
}
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.KEY_MECHANICAL)) {
return "KEY";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MOB_CONTAINER)) {
}
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MOB_CONTAINER)) {
return "SECURE";
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.SIMPLE_CONTAINER)) {
}
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.SIMPLE_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";
}
// Why are flares grenade launcher...?
else if (item._name.startsWith("weapon_rsp30")) {
if (item._name.startsWith("weapon_rsp30")) {
return "FLARE";
}
// 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";
}
@ -302,7 +310,7 @@ export class ItemTplGenerator {
}
// Make sure there's an underscore separator
if (prefix.length > 0 && prefix.at(0) != "_") {
if (prefix.length > 0 && prefix.at(0) !== "_") {
prefix = `_${prefix}`;
}
@ -314,11 +322,11 @@ export class ItemTplGenerator {
// Add mag size for magazines
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
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
@ -327,7 +335,7 @@ export class ItemTplGenerator {
}
// Make sure there's an underscore separator
if (suffix.length > 0 && suffix.at(0) != "_") {
if (suffix.length > 0 && suffix.at(0) !== "_") {
suffix = `_${suffix}`;
}
@ -335,7 +343,7 @@ export class ItemTplGenerator {
}
private getAmmoPrefix(item: ITemplateItem): string {
const prefix = item._props.Caliber!.toUpperCase();
const prefix = item._props.Caliber.toUpperCase();
return this.cleanCaliber(prefix);
}
@ -352,13 +360,13 @@ export class ItemTplGenerator {
}
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]);
}
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]);
}
@ -369,7 +377,7 @@ export class ItemTplGenerator {
* @returns The name of the given item
*/
private getItemName(item) {
let itemName;
let itemName: string;
// Manual item name overrides
if (this.itemOverrides[item._id]) {
@ -420,12 +428,12 @@ export class ItemTplGenerator {
// Add grid size for lootable containers
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
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
const itemNameBracketSuffix = itemName?.match(/\((.+?)\)$/);

View File

@ -21,6 +21,6 @@ export class AsyncQueue implements IAsyncQueue {
}
// 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
const resEntries = Object.entries(result!);
const resEntries = Object.entries(result);
const resResolved = await Promise.all(resEntries.map((ent) => ent[1]));
for (let resIdx = 0; resIdx < resResolved.length; resIdx++) {
resEntries[resIdx][1] = resResolved[resIdx];

View File

@ -19,21 +19,21 @@ export class RagfairOfferHolder {
public getOfferById(id: string): IRagfairOffer | undefined {
if (this.offersById.has(id)) {
return this.offersById.get(id)!;
return this.offersById.get(id);
}
return undefined;
}
public getOffersByTemplate(templateId: string): Array<IRagfairOffer> | undefined {
if (this.offersByTemplate.has(templateId)) {
return [...this.offersByTemplate.get(templateId)!.values()];
return [...this.offersByTemplate.get(templateId).values()];
}
return undefined;
}
public getOffersByTrader(traderId: string): Array<IRagfairOffer> | undefined {
if (this.offersByTrader.has(traderId)) {
return [...this.offersByTrader.get(traderId)!.values()];
return [...this.offersByTrader.get(traderId).values()];
}
return undefined;
}
@ -76,18 +76,18 @@ export class RagfairOfferHolder {
if (this.offersById.has(offer._id)) {
this.offersById.delete(offer._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
// 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
// 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);
}
}
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 {
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 {
if (this.offersByTemplate.has(template)) {
this.offersByTemplate.get(template)!.set(offer._id, offer);
this.offersByTemplate.get(template).set(offer._id, offer);
} else {
const valueMapped = new Map<string, IRagfairOffer>();
valueMapped.set(offer._id, offer);
@ -124,7 +124,7 @@ export class RagfairOfferHolder {
protected addOfferByTrader(trader: string, offer: IRagfairOffer): void {
if (this.offersByTrader.has(trader)) {
this.offersByTrader.get(trader)!.set(offer._id, offer);
this.offersByTrader.get(trader).set(offer._id, offer);
} else {
const valueMapped = new Map<string, IRagfairOffer>();
valueMapped.set(offer._id, offer);

View File

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

View File

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