Fixed various Biome issues
This commit is contained in:
parent
5740774a46
commit
7be6b47e23
@ -18,6 +18,7 @@
|
||||
"tests/__coverage__/*",
|
||||
"types/*",
|
||||
"user/mods/*",
|
||||
"user/profiles/*",
|
||||
"assets/database/*"
|
||||
]
|
||||
},
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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>();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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}`);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 };
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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: [],
|
||||
|
@ -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;
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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) {
|
||||
|
@ -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}`,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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?
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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(/\((.+?)\)$/);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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(() => {
|
||||
|
Loading…
Reference in New Issue
Block a user