Fixed various Biome issues
This commit is contained in:
parent
5740774a46
commit
7be6b47e23
@ -18,6 +18,7 @@
|
|||||||
"tests/__coverage__/*",
|
"tests/__coverage__/*",
|
||||||
"types/*",
|
"types/*",
|
||||||
"user/mods/*",
|
"user/mods/*",
|
||||||
|
"user/profiles/*",
|
||||||
"assets/database/*"
|
"assets/database/*"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -49,7 +49,7 @@ export class ClientLogCallbacks {
|
|||||||
|
|
||||||
data.isBeta = globalThis.G_WATERMARK_ENABLED;
|
data.isBeta = globalThis.G_WATERMARK_ENABLED;
|
||||||
data.isModdable = globalThis.G_MODS_ENABLED;
|
data.isModdable = globalThis.G_MODS_ENABLED;
|
||||||
data.isModded = this.modLoadOrder.getLoadOrder().length > 0 ? true : false;
|
data.isModded = this.modLoadOrder.getLoadOrder().length > 0;
|
||||||
|
|
||||||
return this.httpResponse.noBody(data);
|
return this.httpResponse.noBody(data);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ export class DataCallbacks {
|
|||||||
let result = locales.global[localeId];
|
let result = locales.global[localeId];
|
||||||
|
|
||||||
if (result === undefined) {
|
if (result === undefined) {
|
||||||
result = locales.global["en"];
|
result = locales.global.en;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.httpResponse.getUnclearedBody(result);
|
return this.httpResponse.getUnclearedBody(result);
|
||||||
|
@ -29,7 +29,7 @@ export class ApplicationContext {
|
|||||||
if (this.variables.has(type)) {
|
if (this.variables.has(type)) {
|
||||||
const res: ContextVariable[] = [];
|
const res: ContextVariable[] = [];
|
||||||
|
|
||||||
for (const value of this.variables.get(type)!.values()) {
|
for (const value of this.variables.get(type).values()) {
|
||||||
res.push(value);
|
res.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ export class ApplicationContext {
|
|||||||
public addValue(type: ContextVariableType, value: any): void {
|
public addValue(type: ContextVariableType, value: any): void {
|
||||||
let list: LinkedList<ContextVariable>;
|
let list: LinkedList<ContextVariable>;
|
||||||
if (this.variables.has(type)) {
|
if (this.variables.has(type)) {
|
||||||
list = this.variables.get(type)!;
|
list = this.variables.get(type);
|
||||||
} else {
|
} else {
|
||||||
list = new LinkedList<ContextVariable>();
|
list = new LinkedList<ContextVariable>();
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ export class CustomizationController {
|
|||||||
if (matchingSuits === undefined)
|
if (matchingSuits === undefined)
|
||||||
throw new Error(this.localisationService.getText("customisation-unable_to_get_trader_suits", traderID));
|
throw new Error(this.localisationService.getText("customisation-unable_to_get_trader_suits", traderID));
|
||||||
|
|
||||||
return matchedSuits!;
|
return matchedSuits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,13 +36,11 @@ export class DialogueController {
|
|||||||
if (!coreConfigs.features?.chatbotFeatures?.commandoEnabled) {
|
if (!coreConfigs.features?.chatbotFeatures?.commandoEnabled) {
|
||||||
const sptCommando = this.dialogueChatBots.find(
|
const sptCommando = this.dialogueChatBots.find(
|
||||||
(c) => c.getChatBot()._id.toLocaleLowerCase() === "sptcommando",
|
(c) => c.getChatBot()._id.toLocaleLowerCase() === "sptcommando",
|
||||||
)!;
|
);
|
||||||
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptCommando), 1);
|
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptCommando), 1);
|
||||||
}
|
}
|
||||||
if (!coreConfigs.features?.chatbotFeatures?.sptFriendEnabled) {
|
if (!coreConfigs.features?.chatbotFeatures?.sptFriendEnabled) {
|
||||||
const sptFriend = this.dialogueChatBots.find(
|
const sptFriend = this.dialogueChatBots.find((c) => c.getChatBot()._id.toLocaleLowerCase() === "sptFriend");
|
||||||
(c) => c.getChatBot()._id.toLocaleLowerCase() === "sptFriend",
|
|
||||||
)!;
|
|
||||||
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptFriend), 1);
|
this.dialogueChatBots.splice(this.dialogueChatBots.indexOf(sptFriend), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,7 +203,7 @@ export class DialogueController {
|
|||||||
if (!profile.dialogues[request.dialogId].Users) {
|
if (!profile.dialogues[request.dialogId].Users) {
|
||||||
profile.dialogues[request.dialogId].Users = [];
|
profile.dialogues[request.dialogId].Users = [];
|
||||||
}
|
}
|
||||||
profile.dialogues[request.dialogId].Users!.push(chatBot.getChatBot());
|
profile.dialogues[request.dialogId].Users.push(chatBot.getChatBot());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -797,8 +797,8 @@ export class GameController {
|
|||||||
*/
|
*/
|
||||||
protected validateQuestAssortUnlocksExist(): void {
|
protected validateQuestAssortUnlocksExist(): void {
|
||||||
const db = this.databaseService.getTables();
|
const db = this.databaseService.getTables();
|
||||||
const traders = db.traders!;
|
const traders = db.traders;
|
||||||
const quests = db.templates!.quests;
|
const quests = db.templates.quests;
|
||||||
for (const traderId of Object.values(Traders)) {
|
for (const traderId of Object.values(Traders)) {
|
||||||
const traderData = traders[traderId];
|
const traderData = traders[traderId];
|
||||||
const traderAssorts = traderData?.assort;
|
const traderAssorts = traderData?.assort;
|
||||||
@ -875,7 +875,7 @@ export class GameController {
|
|||||||
* Make non-trigger-spawned raiders spawn earlier + always
|
* Make non-trigger-spawned raiders spawn earlier + always
|
||||||
*/
|
*/
|
||||||
protected adjustLabsRaiderSpawnRate(): void {
|
protected adjustLabsRaiderSpawnRate(): void {
|
||||||
const labsBase = this.databaseService.getLocations().laboratory!.base;
|
const labsBase = this.databaseService.getLocations().laboratory.base;
|
||||||
|
|
||||||
// Find spawns with empty string for triggerId/TriggerName
|
// Find spawns with empty string for triggerId/TriggerName
|
||||||
const nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.filter(
|
const nonTriggerLabsBossSpawns = labsBase.BossLocationSpawn.filter(
|
||||||
|
@ -905,7 +905,7 @@ export class InventoryController {
|
|||||||
this.logger.success(`Item ${mailEvent.entity} is now blacklisted`);
|
this.logger.success(`Item ${mailEvent.entity} is now blacklisted`);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "HideoutAreaLevel":
|
case "HideoutAreaLevel": {
|
||||||
const areaName = mailEvent.entity;
|
const areaName = mailEvent.entity;
|
||||||
const newValue = mailEvent.value;
|
const newValue = mailEvent.value;
|
||||||
const hideoutAreaCode = HideoutAreas[areaName.toUpperCase()];
|
const hideoutAreaCode = HideoutAreas[areaName.toUpperCase()];
|
||||||
@ -917,6 +917,7 @@ export class InventoryController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
this.logger.warning(`Unhandled profile reward event: ${mailEvent.Type}`);
|
this.logger.warning(`Unhandled profile reward event: ${mailEvent.Type}`);
|
||||||
|
|
||||||
|
@ -120,6 +120,6 @@ export class MatchController {
|
|||||||
|
|
||||||
/** Handle client/match/local/end */
|
/** Handle client/match/local/end */
|
||||||
public endLocalRaid(sessionId: string, request: IEndLocalRaidRequestData): void {
|
public endLocalRaid(sessionId: string, request: IEndLocalRaidRequestData): void {
|
||||||
return this.locationLifecycleService.endLocalRaid(sessionId, request);
|
this.locationLifecycleService.endLocalRaid(sessionId, request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ export class QuestController {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const change = {};
|
const change = {};
|
||||||
change[repeatableQuestProfile._id] = repeatableSettings!.changeRequirement[repeatableQuestProfile._id];
|
change[repeatableQuestProfile._id] = repeatableSettings.changeRequirement[repeatableQuestProfile._id];
|
||||||
|
|
||||||
const repeatableData: IPmcDataRepeatableQuest = {
|
const repeatableData: IPmcDataRepeatableQuest = {
|
||||||
id:
|
id:
|
||||||
|
@ -703,11 +703,13 @@ export class RagfairController {
|
|||||||
* @returns FleaOfferType
|
* @returns FleaOfferType
|
||||||
*/
|
*/
|
||||||
protected getOfferType(offerRequest: IAddOfferRequestData): FleaOfferType {
|
protected getOfferType(offerRequest: IAddOfferRequestData): FleaOfferType {
|
||||||
if (offerRequest.items.length == 1 && !offerRequest.sellInOnePiece) {
|
if (offerRequest.items.length === 1 && !offerRequest.sellInOnePiece) {
|
||||||
return FleaOfferType.SINGLE;
|
return FleaOfferType.SINGLE;
|
||||||
} else if (offerRequest.items.length > 1 && !offerRequest.sellInOnePiece) {
|
}
|
||||||
|
if (offerRequest.items.length > 1 && !offerRequest.sellInOnePiece) {
|
||||||
return FleaOfferType.MULTI;
|
return FleaOfferType.MULTI;
|
||||||
} else if (offerRequest.sellInOnePiece) {
|
}
|
||||||
|
if (offerRequest.sellInOnePiece) {
|
||||||
return FleaOfferType.PACK;
|
return FleaOfferType.PACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ export class RepeatableQuestController {
|
|||||||
*/
|
*/
|
||||||
public getClientRepeatableQuests(sessionID: string): IPmcDataRepeatableQuest[] {
|
public getClientRepeatableQuests(sessionID: string): IPmcDataRepeatableQuest[] {
|
||||||
const returnData: Array<IPmcDataRepeatableQuest> = [];
|
const returnData: Array<IPmcDataRepeatableQuest> = [];
|
||||||
const fullProfile = this.profileHelper.getFullProfile(sessionID)!;
|
const fullProfile = this.profileHelper.getFullProfile(sessionID);
|
||||||
const pmcData = fullProfile.characters.pmc;
|
const pmcData = fullProfile.characters.pmc;
|
||||||
const currentTime = this.timeUtil.getTimestamp();
|
const currentTime = this.timeUtil.getTimestamp();
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ export class TradeController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Does offer id exist in profile
|
// Does offer id exist in profile
|
||||||
return offerCreatorProfile.RagfairInfo.offers.some((offer) => offer._id == offerId);
|
return offerCreatorProfile.RagfairInfo.offers.some((offer) => offer._id === offerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -759,7 +759,7 @@ export class BotEquipmentModGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.modSlot == "mod_gas_block") {
|
if (request.modSlot === "mod_gas_block") {
|
||||||
if (request.weaponStats.hasOptic && modPool.length > 1) {
|
if (request.weaponStats.hasOptic && modPool.length > 1) {
|
||||||
// Attempt to limit modpool to low profile gas blocks when weapon has an optic
|
// Attempt to limit modpool to low profile gas blocks when weapon has an optic
|
||||||
const onlyLowProfileGasBlocks = modPool.filter((tpl) =>
|
const onlyLowProfileGasBlocks = modPool.filter((tpl) =>
|
||||||
@ -782,18 +782,18 @@ export class BotEquipmentModGenerator {
|
|||||||
// Pick random mod that's compatible
|
// Pick random mod that's compatible
|
||||||
const chosenModResult = this.pickWeaponModTplForSlotFromPool(
|
const chosenModResult = this.pickWeaponModTplForSlotFromPool(
|
||||||
modPool,
|
modPool,
|
||||||
parentSlot!,
|
parentSlot,
|
||||||
request.modSpawnResult,
|
request.modSpawnResult,
|
||||||
request.weapon,
|
request.weapon,
|
||||||
request.modSlot,
|
request.modSlot,
|
||||||
);
|
);
|
||||||
if (chosenModResult.slotBlocked && !parentSlot!._required) {
|
if (chosenModResult.slotBlocked && !parentSlot._required) {
|
||||||
// Don't bother trying to fit mod, slot is completely blocked
|
// Don't bother trying to fit mod, slot is completely blocked
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log if mod chosen was incompatible
|
// Log if mod chosen was incompatible
|
||||||
if (chosenModResult.incompatible && parentSlot!._required) {
|
if (chosenModResult.incompatible && parentSlot._required) {
|
||||||
this.logger.debug(chosenModResult.reason);
|
this.logger.debug(chosenModResult.reason);
|
||||||
// this.logger.debug(`Weapon: ${weapon.map(x => `${x._tpl} ${x.slotId ?? ""}`).join(",")}`)
|
// this.logger.debug(`Weapon: ${weapon.map(x => `${x._tpl} ${x.slotId ?? ""}`).join(",")}`)
|
||||||
}
|
}
|
||||||
@ -819,7 +819,7 @@ export class BotEquipmentModGenerator {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.itemHelper.getItem(chosenModResult.chosenTpl!);
|
return this.itemHelper.getItem(chosenModResult.chosenTpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -847,7 +847,7 @@ export class BotEquipmentModGenerator {
|
|||||||
const maxBlockedAttempts = Math.round(modPool.length * 0.75); // Roughly 75% of pool size
|
const maxBlockedAttempts = Math.round(modPool.length * 0.75); // Roughly 75% of pool size
|
||||||
let blockedAttemptCount = 0;
|
let blockedAttemptCount = 0;
|
||||||
while (exhaustableModPool.hasValues()) {
|
while (exhaustableModPool.hasValues()) {
|
||||||
chosenTpl = exhaustableModPool.getRandomValue()!;
|
chosenTpl = exhaustableModPool.getRandomValue();
|
||||||
if (choiceTypeEnum === ModSpawn.DEFAULT_MOD && modPool.length === 1) {
|
if (choiceTypeEnum === ModSpawn.DEFAULT_MOD && modPool.length === 1) {
|
||||||
// Default mod wanted and only one choice in pool
|
// Default mod wanted and only one choice in pool
|
||||||
chosenModResult.found = true;
|
chosenModResult.found = true;
|
||||||
@ -1065,7 +1065,7 @@ export class BotEquipmentModGenerator {
|
|||||||
const exhaustableModPool = new ExhaustableArray(allowedItems, this.randomUtil, this.cloner);
|
const exhaustableModPool = new ExhaustableArray(allowedItems, this.randomUtil, this.cloner);
|
||||||
let tmpModTpl = fallbackModTpl;
|
let tmpModTpl = fallbackModTpl;
|
||||||
while (exhaustableModPool.hasValues()) {
|
while (exhaustableModPool.hasValues()) {
|
||||||
tmpModTpl = exhaustableModPool.getRandomValue()!;
|
tmpModTpl = exhaustableModPool.getRandomValue();
|
||||||
if (!this.botGeneratorHelper.isItemIncompatibleWithCurrentItems(items, tmpModTpl, modSlot).incompatible) {
|
if (!this.botGeneratorHelper.isItemIncompatibleWithCurrentItems(items, tmpModTpl, modSlot).incompatible) {
|
||||||
return tmpModTpl;
|
return tmpModTpl;
|
||||||
}
|
}
|
||||||
|
@ -642,7 +642,7 @@ export class BotGenerator {
|
|||||||
* @returns item tpl
|
* @returns item tpl
|
||||||
*/
|
*/
|
||||||
protected getDogtagTplByGameVersionAndSide(side: string, gameVersion: string): string {
|
protected getDogtagTplByGameVersionAndSide(side: string, gameVersion: string): string {
|
||||||
if (side.toLowerCase() == "usec") {
|
if (side.toLowerCase() === "usec") {
|
||||||
switch (gameVersion) {
|
switch (gameVersion) {
|
||||||
case GameEditions.EDGE_OF_DARKNESS:
|
case GameEditions.EDGE_OF_DARKNESS:
|
||||||
return ItemTpl.BARTER_DOGTAG_USEC_EOD;
|
return ItemTpl.BARTER_DOGTAG_USEC_EOD;
|
||||||
|
@ -440,8 +440,8 @@ export class LocationLootGenerator {
|
|||||||
|
|
||||||
this.containerHelper.fillContainerMapWithItem(
|
this.containerHelper.fillContainerMapWithItem(
|
||||||
containerMap,
|
containerMap,
|
||||||
result.x!,
|
result.x,
|
||||||
result.y!,
|
result.y,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
result.rotation,
|
result.rotation,
|
||||||
@ -449,7 +449,7 @@ export class LocationLootGenerator {
|
|||||||
const rotation = result.rotation ? 1 : 0;
|
const rotation = result.rotation ? 1 : 0;
|
||||||
|
|
||||||
items[0].slotId = "main";
|
items[0].slotId = "main";
|
||||||
items[0].location = { x: result.x!, y: result.y!, r: rotation };
|
items[0].location = { x: result.x, y: result.y, r: rotation };
|
||||||
|
|
||||||
// Add loot to container before returning
|
// Add loot to container before returning
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
@ -470,8 +470,8 @@ export class LocationLootGenerator {
|
|||||||
const containerTemplate = this.itemHelper.getItem(containerTpl)[1];
|
const containerTemplate = this.itemHelper.getItem(containerTpl)[1];
|
||||||
|
|
||||||
// Get height/width
|
// Get height/width
|
||||||
const height = containerTemplate._props.Grids![0]._props.cellsV;
|
const height = containerTemplate._props.Grids[0]._props.cellsV;
|
||||||
const width = containerTemplate._props.Grids![0]._props.cellsH;
|
const width = containerTemplate._props.Grids[0]._props.cellsH;
|
||||||
|
|
||||||
// Calcualte 2d array and return
|
// Calcualte 2d array and return
|
||||||
return Array(height)
|
return Array(height)
|
||||||
@ -633,7 +633,7 @@ export class LocationLootGenerator {
|
|||||||
if (randomSpawnpointCount > 0 && spawnpointArray.length > 0) {
|
if (randomSpawnpointCount > 0 && spawnpointArray.length > 0) {
|
||||||
// Add randomly chosen spawn points
|
// Add randomly chosen spawn points
|
||||||
for (const si of spawnpointArray.draw(randomSpawnpointCount, false)) {
|
for (const si of spawnpointArray.draw(randomSpawnpointCount, false)) {
|
||||||
chosenSpawnpoints.push(spawnpointArray.data(si)!);
|
chosenSpawnpoints.push(spawnpointArray.data(si));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -842,7 +842,7 @@ export class LocationLootGenerator {
|
|||||||
const stackCount =
|
const stackCount =
|
||||||
itemTemplate._props.StackMaxSize === 1
|
itemTemplate._props.StackMaxSize === 1
|
||||||
? 1
|
? 1
|
||||||
: this.randomUtil.getInt(itemTemplate._props.StackMinRandom!, itemTemplate._props.StackMaxRandom!);
|
: this.randomUtil.getInt(itemTemplate._props.StackMinRandom, itemTemplate._props.StackMaxRandom);
|
||||||
|
|
||||||
itemWithMods.push({
|
itemWithMods.push({
|
||||||
_id: this.objectId.generate(),
|
_id: this.objectId.generate(),
|
||||||
@ -931,8 +931,8 @@ export class LocationLootGenerator {
|
|||||||
parentId?: string,
|
parentId?: string,
|
||||||
): IContainerItem {
|
): IContainerItem {
|
||||||
const itemTemplate = this.itemHelper.getItem(chosenTpl)[1];
|
const itemTemplate = this.itemHelper.getItem(chosenTpl)[1];
|
||||||
let width = itemTemplate._props.Width!;
|
let width = itemTemplate._props.Width;
|
||||||
let height = itemTemplate._props.Height!;
|
let height = itemTemplate._props.Height;
|
||||||
let items: Item[] = [{ _id: this.objectId.generate(), _tpl: chosenTpl }];
|
let items: Item[] = [{ _id: this.objectId.generate(), _tpl: chosenTpl }];
|
||||||
const rootItem = items[0];
|
const rootItem = items[0];
|
||||||
|
|
||||||
@ -949,7 +949,7 @@ export class LocationLootGenerator {
|
|||||||
const stackCount =
|
const stackCount =
|
||||||
itemTemplate._props.StackMaxSize === 1
|
itemTemplate._props.StackMaxSize === 1
|
||||||
? 1
|
? 1
|
||||||
: this.randomUtil.getInt(itemTemplate._props.StackMinRandom!, itemTemplate._props.StackMaxRandom!);
|
: this.randomUtil.getInt(itemTemplate._props.StackMinRandom, itemTemplate._props.StackMaxRandom);
|
||||||
|
|
||||||
rootItem.upd = { StackObjectsCount: stackCount };
|
rootItem.upd = { StackObjectsCount: stackCount };
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ export class RagfairOfferGenerator {
|
|||||||
|
|
||||||
const isPlayerOffer = this.profileHelper.isPlayer(userID);
|
const isPlayerOffer = this.profileHelper.isPlayer(userID);
|
||||||
if (isPlayerOffer) {
|
if (isPlayerOffer) {
|
||||||
const playerProfile = this.profileHelper.getPmcProfile(userID)!;
|
const playerProfile = this.profileHelper.getPmcProfile(userID);
|
||||||
return {
|
return {
|
||||||
id: playerProfile._id,
|
id: playerProfile._id,
|
||||||
memberType: playerProfile.Info.MemberCategory,
|
memberType: playerProfile.Info.MemberCategory,
|
||||||
@ -342,7 +342,7 @@ export class RagfairOfferGenerator {
|
|||||||
|
|
||||||
// get assort items from param if they exist, otherwise grab freshly generated assorts
|
// get assort items from param if they exist, otherwise grab freshly generated assorts
|
||||||
const assortItemsToProcess: Item[][] = replacingExpiredOffers
|
const assortItemsToProcess: Item[][] = replacingExpiredOffers
|
||||||
? expiredOffers!
|
? expiredOffers
|
||||||
: this.ragfairAssortGenerator.getAssortItems();
|
: this.ragfairAssortGenerator.getAssortItems();
|
||||||
|
|
||||||
// Create offers for each item set concurrently
|
// Create offers for each item set concurrently
|
||||||
|
@ -88,7 +88,7 @@ export class BotGeneratorHelper {
|
|||||||
itemProperties.MedKit = {
|
itemProperties.MedKit = {
|
||||||
HpResource: this.getRandomizedResourceValue(
|
HpResource: this.getRandomizedResourceValue(
|
||||||
itemTemplate._props.MaxHpResource,
|
itemTemplate._props.MaxHpResource,
|
||||||
this.botConfig.lootItemResourceRandomization[botRole!]?.meds,
|
this.botConfig.lootItemResourceRandomization[botRole]?.meds,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ export class BotGeneratorHelper {
|
|||||||
itemProperties.FoodDrink = {
|
itemProperties.FoodDrink = {
|
||||||
HpPercent: this.getRandomizedResourceValue(
|
HpPercent: this.getRandomizedResourceValue(
|
||||||
itemTemplate._props.MaxResource,
|
itemTemplate._props.MaxResource,
|
||||||
this.botConfig.lootItemResourceRandomization[botRole!]?.food,
|
this.botConfig.lootItemResourceRandomization[botRole]?.food,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -236,8 +236,8 @@ export class BotGeneratorHelper {
|
|||||||
let maxDurability: number;
|
let maxDurability: number;
|
||||||
let currentDurability: number;
|
let currentDurability: number;
|
||||||
if (Number.parseInt(`${itemTemplate._props.armorClass}`) === 0) {
|
if (Number.parseInt(`${itemTemplate._props.armorClass}`) === 0) {
|
||||||
maxDurability = itemTemplate._props.MaxDurability!;
|
maxDurability = itemTemplate._props.MaxDurability;
|
||||||
currentDurability = itemTemplate._props.MaxDurability!;
|
currentDurability = itemTemplate._props.MaxDurability;
|
||||||
} else {
|
} else {
|
||||||
maxDurability = this.durabilityLimitsHelper.getRandomizedMaxArmorDurability(itemTemplate, botRole);
|
maxDurability = this.durabilityLimitsHelper.getRandomizedMaxArmorDurability(itemTemplate, botRole);
|
||||||
currentDurability = this.durabilityLimitsHelper.getRandomizedArmorDurability(
|
currentDurability = this.durabilityLimitsHelper.getRandomizedArmorDurability(
|
||||||
@ -563,14 +563,14 @@ export class BotGeneratorHelper {
|
|||||||
|
|
||||||
// Open slot found, add item to inventory
|
// Open slot found, add item to inventory
|
||||||
if (findSlotResult.success) {
|
if (findSlotResult.success) {
|
||||||
const parentItem = itemWithChildren.find((i) => i._id === rootItemId)!;
|
const parentItem = itemWithChildren.find((i) => i._id === rootItemId);
|
||||||
|
|
||||||
// Set items parent to container id
|
// Set items parent to container id
|
||||||
parentItem.parentId = container._id;
|
parentItem.parentId = container._id;
|
||||||
parentItem.slotId = slotGrid._name;
|
parentItem.slotId = slotGrid._name;
|
||||||
parentItem.location = {
|
parentItem.location = {
|
||||||
x: findSlotResult.x!,
|
x: findSlotResult.x,
|
||||||
y: findSlotResult.y!,
|
y: findSlotResult.y,
|
||||||
r: findSlotResult.rotation ? 1 : 0,
|
r: findSlotResult.rotation ? 1 : 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ export class DurabilityLimitsHelper {
|
|||||||
* @returns max durability
|
* @returns max durability
|
||||||
*/
|
*/
|
||||||
public getRandomizedMaxArmorDurability(itemTemplate: ITemplateItem, botRole?: string): number {
|
public getRandomizedMaxArmorDurability(itemTemplate: ITemplateItem, botRole?: string): number {
|
||||||
const itemMaxDurability = itemTemplate._props.MaxDurability!;
|
const itemMaxDurability = itemTemplate._props.MaxDurability;
|
||||||
|
|
||||||
if (botRole && this.botHelper.isBotPmc(botRole)) {
|
if (botRole && this.botHelper.isBotPmc(botRole)) {
|
||||||
return this.generateMaxPmcArmorDurability(itemMaxDurability);
|
return this.generateMaxPmcArmorDurability(itemMaxDurability);
|
||||||
@ -134,16 +134,16 @@ export class DurabilityLimitsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected getLowestMaxWeaponFromConfig(botRole?: string): number {
|
protected getLowestMaxWeaponFromConfig(botRole?: string): number {
|
||||||
if (this.botConfig.durability[botRole!]) {
|
if (this.botConfig.durability[botRole]) {
|
||||||
return this.botConfig.durability[botRole!].weapon.lowestMax;
|
return this.botConfig.durability[botRole].weapon.lowestMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.botConfig.durability.default.weapon.lowestMax;
|
return this.botConfig.durability.default.weapon.lowestMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getHighestMaxWeaponDurabilityFromConfig(botRole?: string): number {
|
protected getHighestMaxWeaponDurabilityFromConfig(botRole?: string): number {
|
||||||
if (this.botConfig.durability[botRole!]) {
|
if (this.botConfig.durability[botRole]) {
|
||||||
return this.botConfig.durability[botRole!].weapon.highestMax;
|
return this.botConfig.durability[botRole].weapon.highestMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.botConfig.durability.default.weapon.highestMax;
|
return this.botConfig.durability.default.weapon.highestMax;
|
||||||
@ -176,48 +176,48 @@ export class DurabilityLimitsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected getMinWeaponDeltaFromConfig(botRole?: string): number {
|
protected getMinWeaponDeltaFromConfig(botRole?: string): number {
|
||||||
if (this.botConfig.durability[botRole!]) {
|
if (this.botConfig.durability[botRole]) {
|
||||||
return this.botConfig.durability[botRole!].weapon.minDelta;
|
return this.botConfig.durability[botRole].weapon.minDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.botConfig.durability.default.weapon.minDelta;
|
return this.botConfig.durability.default.weapon.minDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getMaxWeaponDeltaFromConfig(botRole?: string): number {
|
protected getMaxWeaponDeltaFromConfig(botRole?: string): number {
|
||||||
if (this.botConfig.durability[botRole!]) {
|
if (this.botConfig.durability[botRole]) {
|
||||||
return this.botConfig.durability[botRole!].weapon.maxDelta;
|
return this.botConfig.durability[botRole].weapon.maxDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.botConfig.durability.default.weapon.maxDelta;
|
return this.botConfig.durability.default.weapon.maxDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getMinArmorDeltaFromConfig(botRole?: string): number {
|
protected getMinArmorDeltaFromConfig(botRole?: string): number {
|
||||||
if (this.botConfig.durability[botRole!]) {
|
if (this.botConfig.durability[botRole]) {
|
||||||
return this.botConfig.durability[botRole!].armor.minDelta;
|
return this.botConfig.durability[botRole].armor.minDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.botConfig.durability.default.armor.minDelta;
|
return this.botConfig.durability.default.armor.minDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getMaxArmorDeltaFromConfig(botRole?: string): number {
|
protected getMaxArmorDeltaFromConfig(botRole?: string): number {
|
||||||
if (this.botConfig.durability[botRole!]) {
|
if (this.botConfig.durability[botRole]) {
|
||||||
return this.botConfig.durability[botRole!].armor.maxDelta;
|
return this.botConfig.durability[botRole].armor.maxDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.botConfig.durability.default.armor.maxDelta;
|
return this.botConfig.durability.default.armor.maxDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getMinArmorLimitPercentFromConfig(botRole?: string): number {
|
protected getMinArmorLimitPercentFromConfig(botRole?: string): number {
|
||||||
if (this.botConfig.durability[botRole!]) {
|
if (this.botConfig.durability[botRole]) {
|
||||||
return this.botConfig.durability[botRole!].armor.minLimitPercent;
|
return this.botConfig.durability[botRole].armor.minLimitPercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.botConfig.durability.default.armor.minLimitPercent;
|
return this.botConfig.durability.default.armor.minLimitPercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getMinWeaponLimitPercentFromConfig(botRole?: string): number {
|
protected getMinWeaponLimitPercentFromConfig(botRole?: string): number {
|
||||||
if (this.botConfig.durability[botRole!]) {
|
if (this.botConfig.durability[botRole]) {
|
||||||
return this.botConfig.durability[botRole!].weapon.minLimitPercent;
|
return this.botConfig.durability[botRole].weapon.minLimitPercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.botConfig.durability.default.weapon.minLimitPercent;
|
return this.botConfig.durability.default.weapon.minLimitPercent;
|
||||||
|
@ -35,7 +35,7 @@ export class HealthHelper {
|
|||||||
|
|
||||||
if (!profile.vitality) {
|
if (!profile.vitality) {
|
||||||
// Occurs on newly created profiles
|
// Occurs on newly created profiles
|
||||||
profile.vitality = { health: undefined!, effects: undefined! };
|
profile.vitality = { health: undefined, effects: undefined };
|
||||||
}
|
}
|
||||||
profile.vitality.health = {
|
profile.vitality.health = {
|
||||||
Hydration: 0,
|
Hydration: 0,
|
||||||
@ -176,7 +176,7 @@ export class HealthHelper {
|
|||||||
const fullProfile = this.saveServer.getProfile(sessionID);
|
const fullProfile = this.saveServer.getProfile(sessionID);
|
||||||
const profileEffects = fullProfile.vitality.effects;
|
const profileEffects = fullProfile.vitality.effects;
|
||||||
|
|
||||||
this.storeHydrationEnergyTempInProfile(fullProfile, request.Hydration!, request.Energy!, request.Temperature!);
|
this.storeHydrationEnergyTempInProfile(fullProfile, request.Hydration, request.Energy, request.Temperature);
|
||||||
|
|
||||||
// Process request data into profile
|
// Process request data into profile
|
||||||
for (const bodyPart in postRaidBodyParts) {
|
for (const bodyPart in postRaidBodyParts) {
|
||||||
|
@ -268,7 +268,7 @@ export class ProfileHelper {
|
|||||||
return {
|
return {
|
||||||
Eft: {
|
Eft: {
|
||||||
CarriedQuestItems: [],
|
CarriedQuestItems: [],
|
||||||
DamageHistory: { LethalDamagePart: "Head", LethalDamage: undefined!, BodyParts: <any>[] },
|
DamageHistory: { LethalDamagePart: "Head", LethalDamage: undefined, BodyParts: <any>[] },
|
||||||
DroppedItems: [],
|
DroppedItems: [],
|
||||||
ExperienceBonusMult: 0,
|
ExperienceBonusMult: 0,
|
||||||
FoundInRaidItems: [],
|
FoundInRaidItems: [],
|
||||||
|
@ -715,14 +715,14 @@ export class RagfairOfferHelper {
|
|||||||
protected isConditionItem(item: Item): boolean {
|
protected isConditionItem(item: Item): boolean {
|
||||||
// thanks typescript, undefined assertion is not returnable since it
|
// thanks typescript, undefined assertion is not returnable since it
|
||||||
// tries to return a multitype object
|
// tries to return a multitype object
|
||||||
return item.upd.MedKit ||
|
return !!(
|
||||||
|
item.upd.MedKit ||
|
||||||
item.upd.Repairable ||
|
item.upd.Repairable ||
|
||||||
item.upd.Resource ||
|
item.upd.Resource ||
|
||||||
item.upd.FoodDrink ||
|
item.upd.FoodDrink ||
|
||||||
item.upd.Key ||
|
item.upd.Key ||
|
||||||
item.upd.RepairKit
|
item.upd.RepairKit
|
||||||
? true
|
);
|
||||||
: false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,8 +61,8 @@ export class RagfairSortHelper {
|
|||||||
|
|
||||||
protected sortOffersByBarter(a: IRagfairOffer, b: IRagfairOffer): number {
|
protected sortOffersByBarter(a: IRagfairOffer, b: IRagfairOffer): number {
|
||||||
const moneyTpls = Object.values<string>(Money);
|
const moneyTpls = Object.values<string>(Money);
|
||||||
const aIsOnlyMoney = a.requirements.length == 1 && moneyTpls.includes(a.requirements[0]._tpl) ? 1 : 0;
|
const aIsOnlyMoney = a.requirements.length === 1 && moneyTpls.includes(a.requirements[0]._tpl) ? 1 : 0;
|
||||||
const bIsOnlyMoney = b.requirements.length == 1 && moneyTpls.includes(b.requirements[0]._tpl) ? 1 : 0;
|
const bIsOnlyMoney = b.requirements.length === 1 && moneyTpls.includes(b.requirements[0]._tpl) ? 1 : 0;
|
||||||
return aIsOnlyMoney - bIsOnlyMoney;
|
return aIsOnlyMoney - bIsOnlyMoney;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ export class TraderAssortHelper {
|
|||||||
*/
|
*/
|
||||||
public traderAssortsHaveExpired(traderID: string): boolean {
|
public traderAssortsHaveExpired(traderID: string): boolean {
|
||||||
const time = this.timeUtil.getTimestamp();
|
const time = this.timeUtil.getTimestamp();
|
||||||
const trader = this.databaseService.getTables().traders![traderID];
|
const trader = this.databaseService.getTables().traders[traderID];
|
||||||
|
|
||||||
return trader.base.nextResupply <= time;
|
return trader.base.nextResupply <= time;
|
||||||
}
|
}
|
||||||
|
@ -149,13 +149,13 @@ export class TraderHelper {
|
|||||||
// Force suit ids into profile
|
// Force suit ids into profile
|
||||||
this.addSuitsToProfile(
|
this.addSuitsToProfile(
|
||||||
fullProfile,
|
fullProfile,
|
||||||
clothing!.map((suit) => suit.suiteId),
|
clothing.map((suit) => suit.suiteId),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rawProfileTemplate.fleaBlockedDays ?? 0) > 0) {
|
if ((rawProfileTemplate.fleaBlockedDays ?? 0) > 0) {
|
||||||
const newBanDateTime = this.timeUtil.getTimeStampFromNowDays(rawProfileTemplate.fleaBlockedDays!);
|
const newBanDateTime = this.timeUtil.getTimeStampFromNowDays(rawProfileTemplate.fleaBlockedDays);
|
||||||
const existingBan = pmcData.Info.Bans.find((ban) => ban.banType === BanType.RAGFAIR);
|
const existingBan = pmcData.Info.Bans.find((ban) => ban.banType === BanType.RAGFAIR);
|
||||||
if (existingBan) {
|
if (existingBan) {
|
||||||
existingBan.dateTime = newBanDateTime;
|
existingBan.dateTime = newBanDateTime;
|
||||||
@ -334,9 +334,9 @@ export class TraderHelper {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
|
||||||
return this.randomUtil.getInt(traderDetails.seconds.min, traderDetails.seconds.max);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.randomUtil.getInt(traderDetails.seconds.min, traderDetails.seconds.max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getLoyaltyLevel(traderID: string, pmcData: IPmcData): LoyaltyLevel {
|
public getLoyaltyLevel(traderID: string, pmcData: IPmcData): LoyaltyLevel {
|
||||||
@ -390,14 +390,14 @@ export class TraderHelper {
|
|||||||
if (
|
if (
|
||||||
profile.traderPurchases[traderId][purchasedItem.itemId].count + purchasedItem.count >
|
profile.traderPurchases[traderId][purchasedItem.itemId].count + purchasedItem.count >
|
||||||
this.getAccountTypeAdjustedTraderPurchaseLimit(
|
this.getAccountTypeAdjustedTraderPurchaseLimit(
|
||||||
itemPurchased.upd!.BuyRestrictionMax!,
|
itemPurchased.upd.BuyRestrictionMax,
|
||||||
profile.characters.pmc.Info.GameVersion,
|
profile.characters.pmc.Info.GameVersion,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
this.localisationService.getText("trader-unable_to_purchase_item_limit_reached", {
|
this.localisationService.getText("trader-unable_to_purchase_item_limit_reached", {
|
||||||
traderId: traderId,
|
traderId: traderId,
|
||||||
limit: itemPurchased.upd!.BuyRestrictionMax,
|
limit: itemPurchased.upd.BuyRestrictionMax,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ export class HealthSaveLoadRouter extends SaveLoadRouter {
|
|||||||
public override handleLoad(profile: ISptProfile): ISptProfile {
|
public override handleLoad(profile: ISptProfile): ISptProfile {
|
||||||
if (!profile.vitality) {
|
if (!profile.vitality) {
|
||||||
// Occurs on newly created profiles
|
// Occurs on newly created profiles
|
||||||
profile.vitality = { health: undefined!, effects: undefined! };
|
profile.vitality = { health: undefined, effects: undefined };
|
||||||
}
|
}
|
||||||
profile.vitality.health = {
|
profile.vitality.health = {
|
||||||
Hydration: 0,
|
Hydration: 0,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { IncomingMessage } from "http";
|
import { IncomingMessage } from "node:http";
|
||||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
||||||
import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent";
|
import { IWsNotificationEvent } from "@spt/models/eft/ws/IWsNotificationEvent";
|
||||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||||
|
@ -60,7 +60,7 @@ export class AirdropService {
|
|||||||
|
|
||||||
// Reparent loot items to create we added above
|
// Reparent loot items to create we added above
|
||||||
for (const item of crateLoot) {
|
for (const item of crateLoot) {
|
||||||
if (item._id == airdropCrateItem._id) {
|
if (item._id === airdropCrateItem._id) {
|
||||||
// Crate itself, don't alter
|
// Crate itself, don't alter
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ export class DatabaseService {
|
|||||||
throw new Error(this.localisationService.getText("database-data_at_path_missing", "assets/database/bots"));
|
throw new Error(this.localisationService.getText("database-data_at_path_missing", "assets/database/bots"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().bots!;
|
return this.databaseServer.getTables().bots;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,7 +61,7 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().globals!;
|
return this.databaseServer.getTables().globals;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,7 +74,7 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().hideout!;
|
return this.databaseServer.getTables().hideout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,7 +87,7 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().locales!;
|
return this.databaseServer.getTables().locales;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,7 +100,7 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().locations!;
|
return this.databaseServer.getTables().locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,7 +115,7 @@ export class DatabaseService {
|
|||||||
throw new Error(this.localisationService.getText("database-no_location_found_with_id", locationId));
|
throw new Error(this.localisationService.getText("database-no_location_found_with_id", locationId));
|
||||||
}
|
}
|
||||||
|
|
||||||
return desiredLocation!;
|
return desiredLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,7 +128,7 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().match!;
|
return this.databaseServer.getTables().match;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,7 +141,7 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().server!;
|
return this.databaseServer.getTables().server;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,7 +154,7 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().settings!;
|
return this.databaseServer.getTables().settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,14 +167,14 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().templates!;
|
return this.databaseServer.getTables().templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns assets/database/templates/achievements.json
|
* @returns assets/database/templates/achievements.json
|
||||||
*/
|
*/
|
||||||
public getAchievements(): IAchievement[] {
|
public getAchievements(): IAchievement[] {
|
||||||
if (!this.databaseServer.getTables().templates!.achievements) {
|
if (!this.databaseServer.getTables().templates.achievements) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
this.localisationService.getText(
|
this.localisationService.getText(
|
||||||
"database-data_at_path_missing",
|
"database-data_at_path_missing",
|
||||||
@ -183,14 +183,14 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().templates!.achievements!;
|
return this.databaseServer.getTables().templates.achievements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns assets/database/templates/customisation.json
|
* @returns assets/database/templates/customisation.json
|
||||||
*/
|
*/
|
||||||
public getCustomization(): Record<string, ICustomizationItem> {
|
public getCustomization(): Record<string, ICustomizationItem> {
|
||||||
if (!this.databaseServer.getTables().templates!.customization) {
|
if (!this.databaseServer.getTables().templates.customization) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
this.localisationService.getText(
|
this.localisationService.getText(
|
||||||
"database-data_at_path_missing",
|
"database-data_at_path_missing",
|
||||||
@ -199,14 +199,14 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().templates!.customization!;
|
return this.databaseServer.getTables().templates.customization;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns assets/database/templates/items.json
|
* @returns assets/database/templates/items.json
|
||||||
*/
|
*/
|
||||||
public getHandbook(): IHandbookBase {
|
public getHandbook(): IHandbookBase {
|
||||||
if (!this.databaseServer.getTables().templates!.handbook) {
|
if (!this.databaseServer.getTables().templates.handbook) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
this.localisationService.getText(
|
this.localisationService.getText(
|
||||||
"database-data_at_path_missing",
|
"database-data_at_path_missing",
|
||||||
@ -215,14 +215,14 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().templates!.handbook!;
|
return this.databaseServer.getTables().templates.handbook;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns assets/database/templates/items.json
|
* @returns assets/database/templates/items.json
|
||||||
*/
|
*/
|
||||||
public getItems(): Record<string, ITemplateItem> {
|
public getItems(): Record<string, ITemplateItem> {
|
||||||
if (!this.databaseServer.getTables().templates!.items) {
|
if (!this.databaseServer.getTables().templates.items) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
this.localisationService.getText(
|
this.localisationService.getText(
|
||||||
"database-data_at_path_missing",
|
"database-data_at_path_missing",
|
||||||
@ -231,14 +231,14 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().templates!.items!;
|
return this.databaseServer.getTables().templates.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns assets/database/templates/prices.json
|
* @returns assets/database/templates/prices.json
|
||||||
*/
|
*/
|
||||||
public getPrices(): Record<string, number> {
|
public getPrices(): Record<string, number> {
|
||||||
if (!this.databaseServer.getTables().templates!.prices) {
|
if (!this.databaseServer.getTables().templates.prices) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
this.localisationService.getText(
|
this.localisationService.getText(
|
||||||
"database-data_at_path_missing",
|
"database-data_at_path_missing",
|
||||||
@ -247,14 +247,14 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().templates!.prices!;
|
return this.databaseServer.getTables().templates.prices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns assets/database/templates/profiles.json
|
* @returns assets/database/templates/profiles.json
|
||||||
*/
|
*/
|
||||||
public getProfiles(): IProfileTemplates {
|
public getProfiles(): IProfileTemplates {
|
||||||
if (!this.databaseServer.getTables().templates!.profiles) {
|
if (!this.databaseServer.getTables().templates.profiles) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
this.localisationService.getText(
|
this.localisationService.getText(
|
||||||
"database-data_at_path_missing",
|
"database-data_at_path_missing",
|
||||||
@ -263,14 +263,14 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().templates!.profiles!;
|
return this.databaseServer.getTables().templates.profiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns assets/database/templates/items.json
|
* @returns assets/database/templates/items.json
|
||||||
*/
|
*/
|
||||||
public getQuests(): Record<string, IQuest> {
|
public getQuests(): Record<string, IQuest> {
|
||||||
if (!this.databaseServer.getTables().templates!.quests) {
|
if (!this.databaseServer.getTables().templates.quests) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
this.localisationService.getText(
|
this.localisationService.getText(
|
||||||
"database-data_at_path_missing",
|
"database-data_at_path_missing",
|
||||||
@ -279,7 +279,7 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().templates!.quests!;
|
return this.databaseServer.getTables().templates.quests;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -292,7 +292,7 @@ export class DatabaseService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().traders!;
|
return this.databaseServer.getTables().traders;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -307,19 +307,19 @@ export class DatabaseService {
|
|||||||
throw new Error(this.localisationService.getText("database-no_trader_found_with_id", traderId));
|
throw new Error(this.localisationService.getText("database-no_trader_found_with_id", traderId));
|
||||||
}
|
}
|
||||||
|
|
||||||
return desiredTrader!;
|
return desiredTrader;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns assets/database/locationServices/
|
* @returns assets/database/locationServices/
|
||||||
*/
|
*/
|
||||||
public getLocationServices(): ILocationServices {
|
public getLocationServices(): ILocationServices {
|
||||||
if (!this.databaseServer.getTables().templates!.locationServices) {
|
if (!this.databaseServer.getTables().templates.locationServices) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
this.localisationService.getText("database-data_at_path_missing", "assets/database/locationServices"),
|
this.localisationService.getText("database-data_at_path_missing", "assets/database/locationServices"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.databaseServer.getTables().templates!.locationServices!;
|
return this.databaseServer.getTables().templates.locationServices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,22 +126,22 @@ export class FenceService {
|
|||||||
|
|
||||||
// Clone assorts so we can adjust prices before sending to client
|
// Clone assorts so we can adjust prices before sending to client
|
||||||
const assort = this.cloner.clone(this.fenceAssort);
|
const assort = this.cloner.clone(this.fenceAssort);
|
||||||
this.adjustAssortItemPricesByConfigMultiplier(assort!, 1, this.traderConfig.fence.presetPriceMult);
|
this.adjustAssortItemPricesByConfigMultiplier(assort, 1, this.traderConfig.fence.presetPriceMult);
|
||||||
|
|
||||||
// merge normal fence assorts + discount assorts if player standing is large enough
|
// merge normal fence assorts + discount assorts if player standing is large enough
|
||||||
if (pmcProfile.TradersInfo[Traders.FENCE].standing >= 6) {
|
if (pmcProfile.TradersInfo[Traders.FENCE].standing >= 6) {
|
||||||
const discountAssort = this.cloner.clone(this.fenceDiscountAssort);
|
const discountAssort = this.cloner.clone(this.fenceDiscountAssort);
|
||||||
this.adjustAssortItemPricesByConfigMultiplier(
|
this.adjustAssortItemPricesByConfigMultiplier(
|
||||||
discountAssort!,
|
discountAssort,
|
||||||
this.traderConfig.fence.discountOptions.itemPriceMult,
|
this.traderConfig.fence.discountOptions.itemPriceMult,
|
||||||
this.traderConfig.fence.discountOptions.presetPriceMult,
|
this.traderConfig.fence.discountOptions.presetPriceMult,
|
||||||
);
|
);
|
||||||
const mergedAssorts = this.mergeAssorts(assort!, discountAssort!);
|
const mergedAssorts = this.mergeAssorts(assort, discountAssort);
|
||||||
|
|
||||||
return mergedAssorts;
|
return mergedAssorts;
|
||||||
}
|
}
|
||||||
|
|
||||||
return assort!;
|
return assort;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,7 +172,7 @@ export class FenceService {
|
|||||||
createAssort.sptItems.push(clonedItems);
|
createAssort.sptItems.push(clonedItems);
|
||||||
createAssort.loyal_level_items[root._id] = 1;
|
createAssort.loyal_level_items[root._id] = 1;
|
||||||
|
|
||||||
this.updateFenceAssorts(createAssort, this.fenceAssort!);
|
this.updateFenceAssorts(createAssort, this.fenceAssort);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -279,7 +279,7 @@ export class FenceService {
|
|||||||
* @returns ITraderAssort
|
* @returns ITraderAssort
|
||||||
*/
|
*/
|
||||||
public getRawFenceAssorts(): ITraderAssort {
|
public getRawFenceAssorts(): ITraderAssort {
|
||||||
return this.mergeAssorts(this.cloner.clone(this.fenceAssort!), this.cloner.clone(this.fenceDiscountAssort!));
|
return this.mergeAssorts(this.cloner.clone(this.fenceAssort), this.cloner.clone(this.fenceDiscountAssort));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -300,45 +300,45 @@ export class FenceService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Simulate players buying items
|
// Simulate players buying items
|
||||||
this.deleteRandomAssorts(itemCountToReplace, this.fenceAssort!);
|
this.deleteRandomAssorts(itemCountToReplace, this.fenceAssort);
|
||||||
this.deleteRandomAssorts(discountItemCountToReplace, this.fenceDiscountAssort!);
|
this.deleteRandomAssorts(discountItemCountToReplace, this.fenceDiscountAssort);
|
||||||
|
|
||||||
const normalItemCountsToGenerate = this.getItemCountsToGenerate(
|
const normalItemCountsToGenerate = this.getItemCountsToGenerate(
|
||||||
this.fenceAssort!.items,
|
this.fenceAssort.items,
|
||||||
this.desiredAssortCounts.normal,
|
this.desiredAssortCounts.normal,
|
||||||
);
|
);
|
||||||
const newItems = this.createAssorts(normalItemCountsToGenerate, 1);
|
const newItems = this.createAssorts(normalItemCountsToGenerate, 1);
|
||||||
|
|
||||||
// Push newly generated assorts into existing data
|
// Push newly generated assorts into existing data
|
||||||
this.updateFenceAssorts(newItems, this.fenceAssort!);
|
this.updateFenceAssorts(newItems, this.fenceAssort);
|
||||||
|
|
||||||
const discountItemCountsToGenerate = this.getItemCountsToGenerate(
|
const discountItemCountsToGenerate = this.getItemCountsToGenerate(
|
||||||
this.fenceDiscountAssort!.items,
|
this.fenceDiscountAssort.items,
|
||||||
this.desiredAssortCounts.discount,
|
this.desiredAssortCounts.discount,
|
||||||
);
|
);
|
||||||
const newDiscountItems = this.createAssorts(discountItemCountsToGenerate, 2);
|
const newDiscountItems = this.createAssorts(discountItemCountsToGenerate, 2);
|
||||||
|
|
||||||
// Push newly generated discount assorts into existing data
|
// Push newly generated discount assorts into existing data
|
||||||
this.updateFenceAssorts(newDiscountItems, this.fenceDiscountAssort!);
|
this.updateFenceAssorts(newDiscountItems, this.fenceDiscountAssort);
|
||||||
|
|
||||||
// Add new barter items to fence barter scheme
|
// Add new barter items to fence barter scheme
|
||||||
for (const barterItemKey in newItems.barter_scheme) {
|
for (const barterItemKey in newItems.barter_scheme) {
|
||||||
this.fenceAssort!.barter_scheme[barterItemKey] = newItems.barter_scheme[barterItemKey];
|
this.fenceAssort.barter_scheme[barterItemKey] = newItems.barter_scheme[barterItemKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add loyalty items to fence assorts loyalty object
|
// Add loyalty items to fence assorts loyalty object
|
||||||
for (const loyaltyItemKey in newItems.loyal_level_items) {
|
for (const loyaltyItemKey in newItems.loyal_level_items) {
|
||||||
this.fenceAssort!.loyal_level_items[loyaltyItemKey] = newItems.loyal_level_items[loyaltyItemKey];
|
this.fenceAssort.loyal_level_items[loyaltyItemKey] = newItems.loyal_level_items[loyaltyItemKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new barter items to fence assorts discounted barter scheme
|
// Add new barter items to fence assorts discounted barter scheme
|
||||||
for (const barterItemKey in newDiscountItems.barter_scheme) {
|
for (const barterItemKey in newDiscountItems.barter_scheme) {
|
||||||
this.fenceDiscountAssort!.barter_scheme[barterItemKey] = newDiscountItems.barter_scheme[barterItemKey];
|
this.fenceDiscountAssort.barter_scheme[barterItemKey] = newDiscountItems.barter_scheme[barterItemKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add loyalty items to fence discount assorts loyalty object
|
// Add loyalty items to fence discount assorts loyalty object
|
||||||
for (const loyaltyItemKey in newDiscountItems.loyal_level_items) {
|
for (const loyaltyItemKey in newDiscountItems.loyal_level_items) {
|
||||||
this.fenceDiscountAssort!.loyal_level_items[loyaltyItemKey] =
|
this.fenceDiscountAssort.loyal_level_items[loyaltyItemKey] =
|
||||||
newDiscountItems.loyal_level_items[loyaltyItemKey];
|
newDiscountItems.loyal_level_items[loyaltyItemKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,11 +387,11 @@ export class FenceService {
|
|||||||
) {
|
) {
|
||||||
// Guard against a missing stack count
|
// Guard against a missing stack count
|
||||||
if (existingRootItem.upd?.StackObjectsCount === undefined) {
|
if (existingRootItem.upd?.StackObjectsCount === undefined) {
|
||||||
existingRootItem.upd!.StackObjectsCount = 1;
|
existingRootItem.upd.StackObjectsCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge new items count into existing, dont add new loyalty/barter data as it already exists
|
// Merge new items count into existing, dont add new loyalty/barter data as it already exists
|
||||||
existingRootItem.upd!.StackObjectsCount += newRootItem?.upd?.StackObjectsCount ?? 1;
|
existingRootItem.upd.StackObjectsCount += newRootItem?.upd?.StackObjectsCount ?? 1;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -493,7 +493,7 @@ export class FenceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reduce stack to at smallest, 1
|
// Reduce stack to at smallest, 1
|
||||||
rootItemToAdjust.upd!.StackObjectsCount! -= Math.max(1, itemCountToRemove);
|
rootItemToAdjust.upd.StackObjectsCount -= Math.max(1, itemCountToRemove);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -689,7 +689,7 @@ export class FenceService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const itemDbDetails = this.itemHelper.getItem(chosenBaseAssortRoot._tpl)[1];
|
const itemDbDetails = this.itemHelper.getItem(chosenBaseAssortRoot._tpl)[1];
|
||||||
const itemLimitCount = this.getMatchingItemLimit(itemTypeLimits, itemDbDetails._id)!;
|
const itemLimitCount = this.getMatchingItemLimit(itemTypeLimits, itemDbDetails._id);
|
||||||
if (itemLimitCount?.current >= itemLimitCount?.max) {
|
if (itemLimitCount?.current >= itemLimitCount?.max) {
|
||||||
// Skip adding item as assort as limit reached, decrement i counter so we still get another item
|
// Skip adding item as assort as limit reached, decrement i counter so we still get another item
|
||||||
i--;
|
i--;
|
||||||
@ -723,7 +723,7 @@ export class FenceService {
|
|||||||
const rootItemBeingAdded = desiredAssortItemAndChildrenClone[0];
|
const rootItemBeingAdded = desiredAssortItemAndChildrenClone[0];
|
||||||
|
|
||||||
// Set stack size based on possible overrides, e.g. ammos, otherwise set to 1
|
// Set stack size based on possible overrides, e.g. ammos, otherwise set to 1
|
||||||
rootItemBeingAdded.upd!.StackObjectsCount = this.getSingleItemStackCount(itemDbDetails);
|
rootItemBeingAdded.upd.StackObjectsCount = this.getSingleItemStackCount(itemDbDetails);
|
||||||
|
|
||||||
// Only randomise upd values for single
|
// Only randomise upd values for single
|
||||||
const isSingleStack = (rootItemBeingAdded.upd?.StackObjectsCount ?? 0) === 1;
|
const isSingleStack = (rootItemBeingAdded.upd?.StackObjectsCount ?? 0) === 1;
|
||||||
@ -732,12 +732,12 @@ export class FenceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip items already in the assort if it exists in the prevent duplicate list
|
// Skip items already in the assort if it exists in the prevent duplicate list
|
||||||
const existingItemThatMatches = this.getMatchingItem(rootItemBeingAdded, itemDbDetails, assorts.sptItems)!;
|
const existingItemThatMatches = this.getMatchingItem(rootItemBeingAdded, itemDbDetails, assorts.sptItems);
|
||||||
const shouldBeStacked = this.itemShouldBeForceStacked(existingItemThatMatches, itemDbDetails);
|
const shouldBeStacked = this.itemShouldBeForceStacked(existingItemThatMatches, itemDbDetails);
|
||||||
if (shouldBeStacked && existingItemThatMatches) {
|
if (shouldBeStacked && existingItemThatMatches) {
|
||||||
// Decrement loop counter so another items gets added
|
// Decrement loop counter so another items gets added
|
||||||
i--;
|
i--;
|
||||||
existingItemThatMatches.upd!.StackObjectsCount!++;
|
existingItemThatMatches.upd.StackObjectsCount++;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -803,7 +803,7 @@ export class FenceService {
|
|||||||
|
|
||||||
// Items have sub properties that need to be checked against
|
// Items have sub properties that need to be checked against
|
||||||
for (const item of matchingItems) {
|
for (const item of matchingItems) {
|
||||||
if (isMedical && rootItemBeingAdded.upd!.MedKit?.HpResource === item.upd!.MedKit?.HpResource) {
|
if (isMedical && rootItemBeingAdded.upd.MedKit?.HpResource === item.upd.MedKit?.HpResource) {
|
||||||
// e.g. bandages with multiple use
|
// e.g. bandages with multiple use
|
||||||
// Both undefined === both max resoruce left
|
// Both undefined === both max resoruce left
|
||||||
return item;
|
return item;
|
||||||
@ -812,8 +812,8 @@ export class FenceService {
|
|||||||
// Armors/helmets etc
|
// Armors/helmets etc
|
||||||
if (
|
if (
|
||||||
isGearAndHasSlots &&
|
isGearAndHasSlots &&
|
||||||
rootItemBeingAdded.upd!.Repairable?.Durability === item.upd!.Repairable?.Durability &&
|
rootItemBeingAdded.upd.Repairable?.Durability === item.upd.Repairable?.Durability &&
|
||||||
rootItemBeingAdded.upd!.Repairable?.MaxDurability === item.upd!.Repairable?.MaxDurability
|
rootItemBeingAdded.upd.Repairable?.MaxDurability === item.upd.Repairable?.MaxDurability
|
||||||
) {
|
) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@ -860,7 +860,7 @@ export class FenceService {
|
|||||||
): void {
|
): void {
|
||||||
// Healing items
|
// Healing items
|
||||||
if (itemRoot.upd?.MedKit) {
|
if (itemRoot.upd?.MedKit) {
|
||||||
const itemTotalMax = itemTemplate._props.MaxHpResource!;
|
const itemTotalMax = itemTemplate._props.MaxHpResource;
|
||||||
const current = itemRoot.upd.MedKit.HpResource;
|
const current = itemRoot.upd.MedKit.HpResource;
|
||||||
|
|
||||||
// Current and max match, no adjustment necessary
|
// Current and max match, no adjustment necessary
|
||||||
@ -1042,7 +1042,7 @@ export class FenceService {
|
|||||||
|
|
||||||
// Check for and adjust soft insert durability values
|
// Check for and adjust soft insert durability values
|
||||||
const requiredSlots = itemDbDetails._props.Slots?.filter((slot) => slot._required);
|
const requiredSlots = itemDbDetails._props.Slots?.filter((slot) => slot._required);
|
||||||
if (Boolean(requiredSlots?.length)) {
|
if (requiredSlots?.length) {
|
||||||
this.randomiseArmorSoftInsertDurabilities(requiredSlots, armor);
|
this.randomiseArmorSoftInsertDurabilities(requiredSlots, armor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1050,7 +1050,7 @@ export class FenceService {
|
|||||||
const plateSlots = itemDbDetails._props.Slots?.filter((slot) =>
|
const plateSlots = itemDbDetails._props.Slots?.filter((slot) =>
|
||||||
this.itemHelper.isRemovablePlateSlot(slot._name),
|
this.itemHelper.isRemovablePlateSlot(slot._name),
|
||||||
);
|
);
|
||||||
if (Boolean(plateSlots?.length)) {
|
if (plateSlots?.length) {
|
||||||
this.randomiseArmorInsertsDurabilities(plateSlots, armor);
|
this.randomiseArmorInsertsDurabilities(plateSlots, armor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1061,8 +1061,8 @@ export class FenceService {
|
|||||||
* @param armorItemAndMods Array of armor + inserts to get items from
|
* @param armorItemAndMods Array of armor + inserts to get items from
|
||||||
*/
|
*/
|
||||||
protected randomiseArmorSoftInsertDurabilities(softInsertSlots: Slot[], armorItemAndMods: Item[]): void {
|
protected randomiseArmorSoftInsertDurabilities(softInsertSlots: Slot[], armorItemAndMods: Item[]): void {
|
||||||
for (const requiredSlot of softInsertSlots!) {
|
for (const requiredSlot of softInsertSlots) {
|
||||||
const modItemDbDetails = this.itemHelper.getItem(requiredSlot._props.filters[0].Plate!)[1];
|
const modItemDbDetails = this.itemHelper.getItem(requiredSlot._props.filters[0].Plate)[1];
|
||||||
const durabilityValues = this.getRandomisedArmorDurabilityValues(
|
const durabilityValues = this.getRandomisedArmorDurabilityValues(
|
||||||
modItemDbDetails,
|
modItemDbDetails,
|
||||||
this.traderConfig.fence.armorMaxDurabilityPercentMinMax,
|
this.traderConfig.fence.armorMaxDurabilityPercentMinMax,
|
||||||
@ -1075,29 +1075,29 @@ export class FenceService {
|
|||||||
|
|
||||||
// Find items mod to apply dura changes to
|
// Find items mod to apply dura changes to
|
||||||
const modItemToAdjust = armorItemAndMods.find(
|
const modItemToAdjust = armorItemAndMods.find(
|
||||||
(mod) => mod.slotId!.toLowerCase() === requiredSlot._name.toLowerCase(),
|
(mod) => mod.slotId.toLowerCase() === requiredSlot._name.toLowerCase(),
|
||||||
)!;
|
);
|
||||||
|
|
||||||
this.itemHelper.addUpdObjectToItem(modItemToAdjust);
|
this.itemHelper.addUpdObjectToItem(modItemToAdjust);
|
||||||
|
|
||||||
if (!modItemToAdjust.upd!.Repairable) {
|
if (!modItemToAdjust.upd.Repairable) {
|
||||||
modItemToAdjust.upd!.Repairable = {
|
modItemToAdjust.upd.Repairable = {
|
||||||
Durability: modItemDbDetails._props.MaxDurability!,
|
Durability: modItemDbDetails._props.MaxDurability,
|
||||||
MaxDurability: modItemDbDetails._props.MaxDurability!,
|
MaxDurability: modItemDbDetails._props.MaxDurability,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
modItemToAdjust.upd!.Repairable.Durability = durabilityValues.Durability;
|
modItemToAdjust.upd.Repairable.Durability = durabilityValues.Durability;
|
||||||
modItemToAdjust.upd!.Repairable.MaxDurability = durabilityValues.MaxDurability;
|
modItemToAdjust.upd.Repairable.MaxDurability = durabilityValues.MaxDurability;
|
||||||
|
|
||||||
// 25% chance to add shots to visor items when its below max durability
|
// 25% chance to add shots to visor items when its below max durability
|
||||||
if (
|
if (
|
||||||
this.randomUtil.getChance100(25) &&
|
this.randomUtil.getChance100(25) &&
|
||||||
modItemToAdjust.parentId === BaseClasses.ARMORED_EQUIPMENT &&
|
modItemToAdjust.parentId === BaseClasses.ARMORED_EQUIPMENT &&
|
||||||
modItemToAdjust.slotId === "mod_equipment_000" &&
|
modItemToAdjust.slotId === "mod_equipment_000" &&
|
||||||
modItemToAdjust.upd!.Repairable.Durability < modItemDbDetails._props.MaxDurability!
|
modItemToAdjust.upd.Repairable.Durability < modItemDbDetails._props.MaxDurability
|
||||||
) {
|
) {
|
||||||
// Is damaged
|
// Is damaged
|
||||||
modItemToAdjust.upd!.FaceShield = { Hits: this.randomUtil.getInt(1, 3) };
|
modItemToAdjust.upd.FaceShield = { Hits: this.randomUtil.getInt(1, 3) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1109,7 +1109,7 @@ export class FenceService {
|
|||||||
* @param armorItemAndMods Array of armor + inserts to get items from
|
* @param armorItemAndMods Array of armor + inserts to get items from
|
||||||
*/
|
*/
|
||||||
protected randomiseArmorInsertsDurabilities(plateSlots: Slot[], armorItemAndMods: Item[]): void {
|
protected randomiseArmorInsertsDurabilities(plateSlots: Slot[], armorItemAndMods: Item[]): void {
|
||||||
for (const plateSlot of plateSlots!) {
|
for (const plateSlot of plateSlots) {
|
||||||
const plateTpl = plateSlot._props.filters[0].Plate;
|
const plateTpl = plateSlot._props.filters[0].Plate;
|
||||||
if (!plateTpl) {
|
if (!plateTpl) {
|
||||||
// Bsg data lacks a default plate, skip randomisng for this mod
|
// Bsg data lacks a default plate, skip randomisng for this mod
|
||||||
@ -1124,7 +1124,7 @@ export class FenceService {
|
|||||||
if (!this.randomUtil.getChance100(plateExistsChance)) {
|
if (!this.randomUtil.getChance100(plateExistsChance)) {
|
||||||
// Remove plate from armor
|
// Remove plate from armor
|
||||||
armorItemAndMods = armorItemAndMods.filter(
|
armorItemAndMods = armorItemAndMods.filter(
|
||||||
(item) => item.slotId!.toLowerCase() !== plateSlot._name.toLowerCase(),
|
(item) => item.slotId.toLowerCase() !== plateSlot._name.toLowerCase(),
|
||||||
);
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -1137,7 +1137,7 @@ export class FenceService {
|
|||||||
|
|
||||||
// Find items mod to apply dura changes to
|
// Find items mod to apply dura changes to
|
||||||
const modItemToAdjust = armorItemAndMods.find(
|
const modItemToAdjust = armorItemAndMods.find(
|
||||||
(mod) => mod.slotId!.toLowerCase() === plateSlot._name.toLowerCase(),
|
(mod) => mod.slotId.toLowerCase() === plateSlot._name.toLowerCase(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!modItemToAdjust) {
|
if (!modItemToAdjust) {
|
||||||
@ -1150,14 +1150,14 @@ export class FenceService {
|
|||||||
this.itemHelper.addUpdObjectToItem(modItemToAdjust);
|
this.itemHelper.addUpdObjectToItem(modItemToAdjust);
|
||||||
|
|
||||||
if (!modItemToAdjust?.upd?.Repairable) {
|
if (!modItemToAdjust?.upd?.Repairable) {
|
||||||
modItemToAdjust!.upd!.Repairable = {
|
modItemToAdjust.upd.Repairable = {
|
||||||
Durability: modItemDbDetails._props.MaxDurability!,
|
Durability: modItemDbDetails._props.MaxDurability,
|
||||||
MaxDurability: modItemDbDetails._props.MaxDurability!,
|
MaxDurability: modItemDbDetails._props.MaxDurability,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
modItemToAdjust!.upd!.Repairable.Durability = durabilityValues.Durability;
|
modItemToAdjust.upd.Repairable.Durability = durabilityValues.Durability;
|
||||||
modItemToAdjust!.upd!.Repairable.MaxDurability = durabilityValues.MaxDurability;
|
modItemToAdjust.upd.Repairable.MaxDurability = durabilityValues.MaxDurability;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1176,7 +1176,7 @@ export class FenceService {
|
|||||||
// No override, use stack max size from item db
|
// No override, use stack max size from item db
|
||||||
return itemDbDetails._props.StackMaxSize === 1
|
return itemDbDetails._props.StackMaxSize === 1
|
||||||
? 1
|
? 1
|
||||||
: this.randomUtil.getInt(itemDbDetails._props.StackMinRandom!, itemDbDetails._props.StackMaxRandom!);
|
: this.randomUtil.getInt(itemDbDetails._props.StackMinRandom, itemDbDetails._props.StackMaxRandom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for override in config, use values if exists
|
// Check for override in config, use values if exists
|
||||||
@ -1232,7 +1232,7 @@ export class FenceService {
|
|||||||
*/
|
*/
|
||||||
protected presetModItemWillBeRemoved(weaponMod: Item, itemsBeingDeleted: string[]): boolean {
|
protected presetModItemWillBeRemoved(weaponMod: Item, itemsBeingDeleted: string[]): boolean {
|
||||||
const slotIdsThatCanFail = this.traderConfig.fence.presetSlotsToRemoveChancePercent;
|
const slotIdsThatCanFail = this.traderConfig.fence.presetSlotsToRemoveChancePercent;
|
||||||
const removalChance = slotIdsThatCanFail[weaponMod.slotId!];
|
const removalChance = slotIdsThatCanFail[weaponMod.slotId];
|
||||||
if (!removalChance) {
|
if (!removalChance) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1259,7 +1259,7 @@ export class FenceService {
|
|||||||
|
|
||||||
// Randomise hp resource of med items
|
// Randomise hp resource of med items
|
||||||
if ("MaxHpResource" in itemDetails._props && (itemDetails._props.MaxHpResource ?? 0) > 0) {
|
if ("MaxHpResource" in itemDetails._props && (itemDetails._props.MaxHpResource ?? 0) > 0) {
|
||||||
itemToAdjust.upd!.MedKit = { HpResource: this.randomUtil.getInt(1, itemDetails._props.MaxHpResource!) };
|
itemToAdjust.upd.MedKit = { HpResource: this.randomUtil.getInt(1, itemDetails._props.MaxHpResource) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Randomise armor durability
|
// Randomise armor durability
|
||||||
@ -1273,7 +1273,7 @@ export class FenceService {
|
|||||||
itemDetails,
|
itemDetails,
|
||||||
this.traderConfig.fence.armorMaxDurabilityPercentMinMax,
|
this.traderConfig.fence.armorMaxDurabilityPercentMinMax,
|
||||||
);
|
);
|
||||||
itemToAdjust.upd!.Repairable = { Durability: values.Durability, MaxDurability: values.MaxDurability };
|
itemToAdjust.upd.Repairable = { Durability: values.Durability, MaxDurability: values.MaxDurability };
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1281,25 +1281,25 @@ export class FenceService {
|
|||||||
// Randomise Weapon durability
|
// Randomise Weapon durability
|
||||||
if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.WEAPON)) {
|
if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.WEAPON)) {
|
||||||
const weaponDurabilityLimits = this.traderConfig.fence.weaponDurabilityPercentMinMax;
|
const weaponDurabilityLimits = this.traderConfig.fence.weaponDurabilityPercentMinMax;
|
||||||
const maxDuraMin = (weaponDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability!;
|
const maxDuraMin = (weaponDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability;
|
||||||
const maxDuraMax = (weaponDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability!;
|
const maxDuraMax = (weaponDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability;
|
||||||
const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax);
|
const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax);
|
||||||
|
|
||||||
const currentDuraMin = (weaponDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability!;
|
const currentDuraMin = (weaponDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability;
|
||||||
const currentDuraMax = (weaponDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability!;
|
const currentDuraMax = (weaponDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability;
|
||||||
const currentDurability = Math.min(
|
const currentDurability = Math.min(
|
||||||
this.randomUtil.getInt(currentDuraMin, currentDuraMax),
|
this.randomUtil.getInt(currentDuraMin, currentDuraMax),
|
||||||
chosenMaxDurability,
|
chosenMaxDurability,
|
||||||
);
|
);
|
||||||
|
|
||||||
itemToAdjust.upd!.Repairable = { Durability: currentDurability, MaxDurability: chosenMaxDurability };
|
itemToAdjust.upd.Repairable = { Durability: currentDurability, MaxDurability: chosenMaxDurability };
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.REPAIR_KITS)) {
|
if (this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.REPAIR_KITS)) {
|
||||||
itemToAdjust.upd!.RepairKit = {
|
itemToAdjust.upd.RepairKit = {
|
||||||
Resource: this.randomUtil.getInt(1, itemDetails._props.MaxRepairResource!),
|
Resource: this.randomUtil.getInt(1, itemDetails._props.MaxRepairResource),
|
||||||
};
|
};
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -1310,8 +1310,8 @@ export class FenceService {
|
|||||||
this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.KEY_MECHANICAL) &&
|
this.itemHelper.isOfBaseclass(itemDetails._id, BaseClasses.KEY_MECHANICAL) &&
|
||||||
(itemDetails._props.MaximumNumberOfUsage ?? 0) > 1
|
(itemDetails._props.MaximumNumberOfUsage ?? 0) > 1
|
||||||
) {
|
) {
|
||||||
itemToAdjust.upd!.Key = {
|
itemToAdjust.upd.Key = {
|
||||||
NumberOfUsages: this.randomUtil.getInt(0, itemDetails._props.MaximumNumberOfUsage! - 1),
|
NumberOfUsages: this.randomUtil.getInt(0, itemDetails._props.MaximumNumberOfUsage - 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -1319,10 +1319,10 @@ export class FenceService {
|
|||||||
|
|
||||||
// Randomise items that use resources (e.g. fuel)
|
// Randomise items that use resources (e.g. fuel)
|
||||||
if ((itemDetails._props.MaxResource ?? 0) > 0) {
|
if ((itemDetails._props.MaxResource ?? 0) > 0) {
|
||||||
const resourceMax = itemDetails._props.MaxResource!;
|
const resourceMax = itemDetails._props.MaxResource;
|
||||||
const resourceCurrent = this.randomUtil.getInt(1, itemDetails._props.MaxResource!);
|
const resourceCurrent = this.randomUtil.getInt(1, itemDetails._props.MaxResource);
|
||||||
|
|
||||||
itemToAdjust.upd!.Resource = { Value: resourceMax - resourceCurrent, UnitsConsumed: resourceCurrent };
|
itemToAdjust.upd.Resource = { Value: resourceMax - resourceCurrent, UnitsConsumed: resourceCurrent };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1336,12 +1336,12 @@ export class FenceService {
|
|||||||
itemDetails: ITemplateItem,
|
itemDetails: ITemplateItem,
|
||||||
equipmentDurabilityLimits: IItemDurabilityCurrentMax,
|
equipmentDurabilityLimits: IItemDurabilityCurrentMax,
|
||||||
): Repairable {
|
): Repairable {
|
||||||
const maxDuraMin = (equipmentDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability!;
|
const maxDuraMin = (equipmentDurabilityLimits.max.min / 100) * itemDetails._props.MaxDurability;
|
||||||
const maxDuraMax = (equipmentDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability!;
|
const maxDuraMax = (equipmentDurabilityLimits.max.max / 100) * itemDetails._props.MaxDurability;
|
||||||
const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax);
|
const chosenMaxDurability = this.randomUtil.getInt(maxDuraMin, maxDuraMax);
|
||||||
|
|
||||||
const currentDuraMin = (equipmentDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability!;
|
const currentDuraMin = (equipmentDurabilityLimits.current.min / 100) * itemDetails._props.MaxDurability;
|
||||||
const currentDuraMax = (equipmentDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability!;
|
const currentDuraMax = (equipmentDurabilityLimits.current.max / 100) * itemDetails._props.MaxDurability;
|
||||||
const chosenCurrentDurability = Math.min(
|
const chosenCurrentDurability = Math.min(
|
||||||
this.randomUtil.getInt(currentDuraMin, currentDuraMax),
|
this.randomUtil.getInt(currentDuraMin, currentDuraMax),
|
||||||
chosenMaxDurability,
|
chosenMaxDurability,
|
||||||
@ -1380,7 +1380,7 @@ export class FenceService {
|
|||||||
* @returns Refresh time in seconds
|
* @returns Refresh time in seconds
|
||||||
*/
|
*/
|
||||||
protected getFenceRefreshTime(): number {
|
protected getFenceRefreshTime(): number {
|
||||||
const fence = this.traderConfig.updateTime.find((x) => x.traderId === Traders.FENCE)!.seconds;
|
const fence = this.traderConfig.updateTime.find((x) => x.traderId === Traders.FENCE).seconds;
|
||||||
|
|
||||||
return this.randomUtil.getInt(fence.min, fence.max);
|
return this.randomUtil.getInt(fence.min, fence.max);
|
||||||
}
|
}
|
||||||
@ -1421,10 +1421,10 @@ export class FenceService {
|
|||||||
*/
|
*/
|
||||||
public amendOrRemoveFenceOffer(assortId: string, buyCount: number): void {
|
public amendOrRemoveFenceOffer(assortId: string, buyCount: number): void {
|
||||||
let isNormalAssort = true;
|
let isNormalAssort = true;
|
||||||
let fenceAssortItem = this.fenceAssort!.items.find((item) => item._id === assortId);
|
let fenceAssortItem = this.fenceAssort.items.find((item) => item._id === assortId);
|
||||||
if (!fenceAssortItem) {
|
if (!fenceAssortItem) {
|
||||||
// Not in main assorts, check secondary section
|
// Not in main assorts, check secondary section
|
||||||
fenceAssortItem = this.fenceDiscountAssort!.items.find((item) => item._id === assortId);
|
fenceAssortItem = this.fenceDiscountAssort.items.find((item) => item._id === assortId);
|
||||||
if (!fenceAssortItem) {
|
if (!fenceAssortItem) {
|
||||||
this.logger.error(this.localisationService.getText("fence-unable_to_find_offer_by_id", assortId));
|
this.logger.error(this.localisationService.getText("fence-unable_to_find_offer_by_id", assortId));
|
||||||
|
|
||||||
@ -1434,14 +1434,14 @@ export class FenceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Player wants to buy whole stack, delete stack
|
// Player wants to buy whole stack, delete stack
|
||||||
if (fenceAssortItem.upd!.StackObjectsCount === buyCount) {
|
if (fenceAssortItem.upd.StackObjectsCount === buyCount) {
|
||||||
this.deleteOffer(assortId, isNormalAssort ? this.fenceAssort!.items : this.fenceDiscountAssort!.items);
|
this.deleteOffer(assortId, isNormalAssort ? this.fenceAssort.items : this.fenceDiscountAssort.items);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust stack size
|
// Adjust stack size
|
||||||
fenceAssortItem.upd!.StackObjectsCount! -= buyCount;
|
fenceAssortItem.upd.StackObjectsCount -= buyCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected deleteOffer(assortId: string, assorts: Item[]): void {
|
protected deleteOffer(assortId: string, assorts: Item[]): void {
|
||||||
@ -1452,8 +1452,8 @@ export class FenceService {
|
|||||||
|
|
||||||
// No offer found in main assort, check discount items
|
// No offer found in main assort, check discount items
|
||||||
if (indexToRemove === -1) {
|
if (indexToRemove === -1) {
|
||||||
indexToRemove = this.fenceDiscountAssort!.items.findIndex((item) => item._id === itemToRemove._id);
|
indexToRemove = this.fenceDiscountAssort.items.findIndex((item) => item._id === itemToRemove._id);
|
||||||
this.fenceDiscountAssort!.items.splice(indexToRemove, 1);
|
this.fenceDiscountAssort.items.splice(indexToRemove, 1);
|
||||||
|
|
||||||
if (indexToRemove === -1) {
|
if (indexToRemove === -1) {
|
||||||
this.logger.warning(
|
this.logger.warning(
|
||||||
|
@ -115,7 +115,7 @@ export class GiftService {
|
|||||||
if (giftData.localeTextId) {
|
if (giftData.localeTextId) {
|
||||||
this.mailSendService.sendLocalisedNpcMessageToPlayer(
|
this.mailSendService.sendLocalisedNpcMessageToPlayer(
|
||||||
playerId,
|
playerId,
|
||||||
giftData.trader!,
|
giftData.trader,
|
||||||
MessageType.MESSAGE_WITH_ITEMS,
|
MessageType.MESSAGE_WITH_ITEMS,
|
||||||
giftData.localeTextId,
|
giftData.localeTextId,
|
||||||
giftData.items,
|
giftData.items,
|
||||||
@ -124,7 +124,7 @@ export class GiftService {
|
|||||||
} else {
|
} else {
|
||||||
this.mailSendService.sendDirectNpcMessageToPlayer(
|
this.mailSendService.sendDirectNpcMessageToPlayer(
|
||||||
playerId,
|
playerId,
|
||||||
giftData.trader!,
|
giftData.trader,
|
||||||
MessageType.MESSAGE_WITH_ITEMS,
|
MessageType.MESSAGE_WITH_ITEMS,
|
||||||
giftData.messageText,
|
giftData.messageText,
|
||||||
giftData.items,
|
giftData.items,
|
||||||
@ -136,9 +136,9 @@ export class GiftService {
|
|||||||
// Trader / ragfair
|
// Trader / ragfair
|
||||||
const details: ISendMessageDetails = {
|
const details: ISendMessageDetails = {
|
||||||
recipientId: playerId,
|
recipientId: playerId,
|
||||||
sender: this.getMessageType(giftData)!,
|
sender: this.getMessageType(giftData),
|
||||||
senderDetails: {
|
senderDetails: {
|
||||||
_id: this.getSenderId(giftData)!,
|
_id: this.getSenderId(giftData),
|
||||||
aid: 1234567, // TODO - pass proper aid value
|
aid: 1234567, // TODO - pass proper aid value
|
||||||
Info: undefined,
|
Info: undefined,
|
||||||
},
|
},
|
||||||
@ -166,7 +166,7 @@ export class GiftService {
|
|||||||
*/
|
*/
|
||||||
protected getSenderId(giftData: Gift): string | undefined {
|
protected getSenderId(giftData: Gift): string | undefined {
|
||||||
if (giftData.sender === GiftSenderType.TRADER) {
|
if (giftData.sender === GiftSenderType.TRADER) {
|
||||||
return Traders[giftData.trader!];
|
return Traders[giftData.trader];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (giftData.sender === GiftSenderType.USER) {
|
if (giftData.sender === GiftSenderType.USER) {
|
||||||
|
@ -142,7 +142,7 @@ export class InsuranceService {
|
|||||||
(bonus) => bonus.type === BonusType.INSURANCE_RETURN_TIME,
|
(bonus) => bonus.type === BonusType.INSURANCE_RETURN_TIME,
|
||||||
);
|
);
|
||||||
const insuranceReturnTimeBonusPercent =
|
const insuranceReturnTimeBonusPercent =
|
||||||
1.0 - (insuranceReturnTimeBonus ? Math.abs(insuranceReturnTimeBonus!.value ?? 0) : 0) / 100;
|
1.0 - (insuranceReturnTimeBonus ? Math.abs(insuranceReturnTimeBonus.value ?? 0) : 0) / 100;
|
||||||
|
|
||||||
const traderMinReturnAsSeconds = trader.insurance.min_return_hour * TimeUtil.ONE_HOUR_AS_SECONDS;
|
const traderMinReturnAsSeconds = trader.insurance.min_return_hour * TimeUtil.ONE_HOUR_AS_SECONDS;
|
||||||
const traderMaxReturnAsSeconds = trader.insurance.max_return_hour * TimeUtil.ONE_HOUR_AS_SECONDS;
|
const traderMaxReturnAsSeconds = trader.insurance.max_return_hour * TimeUtil.ONE_HOUR_AS_SECONDS;
|
||||||
@ -214,7 +214,7 @@ export class InsuranceService {
|
|||||||
const result: IInsuranceEquipmentPkg[] = [];
|
const result: IInsuranceEquipmentPkg[] = [];
|
||||||
|
|
||||||
for (const lostItem of lostInsuredItems) {
|
for (const lostItem of lostInsuredItems) {
|
||||||
const insuranceDetails = pmcProfile.InsuredItems.find((insuredItem) => insuredItem.itemId == lostItem._id);
|
const insuranceDetails = pmcProfile.InsuredItems.find((insuredItem) => insuredItem.itemId === lostItem._id);
|
||||||
if (!insuranceDetails) {
|
if (!insuranceDetails) {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
`unable to find insurance details for item id: ${lostItem._id} with tpl: ${lostItem._tpl}`,
|
`unable to find insurance details for item id: ${lostItem._id} with tpl: ${lostItem._tpl}`,
|
||||||
|
@ -25,7 +25,7 @@ export class LocaleService {
|
|||||||
* @returns dictionary
|
* @returns dictionary
|
||||||
*/
|
*/
|
||||||
public getLocaleDb(): Record<string, string> {
|
public getLocaleDb(): Record<string, string> {
|
||||||
const desiredLocale = this.databaseServer.getTables().locales!.global[this.getDesiredGameLocale()];
|
const desiredLocale = this.databaseServer.getTables().locales.global[this.getDesiredGameLocale()];
|
||||||
if (desiredLocale) {
|
if (desiredLocale) {
|
||||||
return desiredLocale;
|
return desiredLocale;
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ export class LocaleService {
|
|||||||
`Unable to find desired locale file using locale: ${this.getDesiredGameLocale()} from config/locale.json, falling back to 'en'`,
|
`Unable to find desired locale file using locale: ${this.getDesiredGameLocale()} from config/locale.json, falling back to 'en'`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return this.databaseServer.getTables().locales!.global.en;
|
return this.databaseServer.getTables().locales.global.en;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,7 +118,7 @@ export class LocaleService {
|
|||||||
return "en";
|
return "en";
|
||||||
}
|
}
|
||||||
|
|
||||||
const locales = this.databaseServer.getTables().locales!;
|
const locales = this.databaseServer.getTables().locales;
|
||||||
const baseNameCode = platformLocale.baseName?.toLocaleLowerCase();
|
const baseNameCode = platformLocale.baseName?.toLocaleLowerCase();
|
||||||
if (baseNameCode && locales.global[baseNameCode]) {
|
if (baseNameCode && locales.global[baseNameCode]) {
|
||||||
return baseNameCode;
|
return baseNameCode;
|
||||||
|
@ -51,7 +51,7 @@ export class LocalisationService {
|
|||||||
* @returns string array of keys
|
* @returns string array of keys
|
||||||
*/
|
*/
|
||||||
public getKeys(): string[] {
|
public getKeys(): string[] {
|
||||||
return Object.keys(this.databaseServer.getTables().locales!.server.en);
|
return Object.keys(this.databaseServer.getTables().locales.server.en);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,7 +60,7 @@ export class LocalisationService {
|
|||||||
* @returns locale text
|
* @returns locale text
|
||||||
*/
|
*/
|
||||||
public getRandomTextThatMatchesPartialKey(partialKey: string): string {
|
public getRandomTextThatMatchesPartialKey(partialKey: string): string {
|
||||||
const filteredKeys = Object.keys(this.databaseServer.getTables().locales!.server.en).filter((x) =>
|
const filteredKeys = Object.keys(this.databaseServer.getTables().locales.server.en).filter((x) =>
|
||||||
x.startsWith(partialKey),
|
x.startsWith(partialKey),
|
||||||
);
|
);
|
||||||
const chosenKey = this.randomUtil.getArrayValue(filteredKeys);
|
const chosenKey = this.randomUtil.getArrayValue(filteredKeys);
|
||||||
|
@ -168,7 +168,7 @@ export class LocationLifecycleService {
|
|||||||
const fullProfile = this.profileHelper.getFullProfile(sessionId);
|
const fullProfile = this.profileHelper.getFullProfile(sessionId);
|
||||||
const pmcProfile = fullProfile.characters.pmc;
|
const pmcProfile = fullProfile.characters.pmc;
|
||||||
const scavProfile = fullProfile.characters.scav;
|
const scavProfile = fullProfile.characters.scav;
|
||||||
const postRaidProfile = request.results.profile!;
|
const postRaidProfile = request.results.profile;
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// Rep gain/loss?
|
// Rep gain/loss?
|
||||||
|
@ -396,7 +396,7 @@ export class MailSendService {
|
|||||||
let itemsToSendToPlayer: MessageItems = {};
|
let itemsToSendToPlayer: MessageItems = {};
|
||||||
if ((messageDetails.items?.length ?? 0) > 0) {
|
if ((messageDetails.items?.length ?? 0) > 0) {
|
||||||
// Find base item that should be the 'primary' + have its parent id be used as the dialogs 'stash' value
|
// Find base item that should be the 'primary' + have its parent id be used as the dialogs 'stash' value
|
||||||
const parentItem = this.getBaseItemFromRewards(messageDetails.items!);
|
const parentItem = this.getBaseItemFromRewards(messageDetails.items);
|
||||||
if (!parentItem) {
|
if (!parentItem) {
|
||||||
this.localisationService.getText("mailsend-missing_parent", {
|
this.localisationService.getText("mailsend-missing_parent", {
|
||||||
traderId: messageDetails.trader,
|
traderId: messageDetails.trader,
|
||||||
@ -414,7 +414,7 @@ export class MailSendService {
|
|||||||
itemsToSendToPlayer = { stash: parentItem.parentId, data: [] };
|
itemsToSendToPlayer = { stash: parentItem.parentId, data: [] };
|
||||||
|
|
||||||
// Ensure Ids are unique and cont collide with items in player inventory later
|
// Ensure Ids are unique and cont collide with items in player inventory later
|
||||||
messageDetails.items = this.itemHelper.replaceIDs(messageDetails.items!);
|
messageDetails.items = this.itemHelper.replaceIDs(messageDetails.items);
|
||||||
|
|
||||||
for (const reward of messageDetails.items) {
|
for (const reward of messageDetails.items) {
|
||||||
// Ensure item exists in items db
|
// Ensure item exists in items db
|
||||||
@ -444,7 +444,7 @@ export class MailSendService {
|
|||||||
this.itemHelper.addCartridgesToAmmoBox(boxAndCartridges, itemTemplate);
|
this.itemHelper.addCartridgesToAmmoBox(boxAndCartridges, itemTemplate);
|
||||||
|
|
||||||
// Push box + cartridge children into array
|
// Push box + cartridge children into array
|
||||||
itemsToSendToPlayer.data!.push(...boxAndCartridges);
|
itemsToSendToPlayer.data.push(...boxAndCartridges);
|
||||||
} else {
|
} else {
|
||||||
if ("StackSlots" in itemTemplate._props) {
|
if ("StackSlots" in itemTemplate._props) {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
@ -453,12 +453,12 @@ export class MailSendService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Item is sanitised and ready to be pushed into holding array
|
// Item is sanitised and ready to be pushed into holding array
|
||||||
itemsToSendToPlayer.data!.push(reward);
|
itemsToSendToPlayer.data.push(reward);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove empty data property if no rewards
|
// Remove empty data property if no rewards
|
||||||
if (itemsToSendToPlayer.data!.length === 0) {
|
if (itemsToSendToPlayer.data.length === 0) {
|
||||||
delete itemsToSendToPlayer.data;
|
delete itemsToSendToPlayer.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,14 +190,14 @@ export class PaymentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Found currency item
|
// Found currency item
|
||||||
if (item.upd!.StackObjectsCount! < currencyMaxStackSize) {
|
if (item.upd.StackObjectsCount < currencyMaxStackSize) {
|
||||||
if (item.upd!.StackObjectsCount! + calcAmount > currencyMaxStackSize) {
|
if (item.upd.StackObjectsCount + calcAmount > currencyMaxStackSize) {
|
||||||
// calculate difference
|
// calculate difference
|
||||||
calcAmount -= currencyMaxStackSize - item.upd!.StackObjectsCount!;
|
calcAmount -= currencyMaxStackSize - item.upd.StackObjectsCount;
|
||||||
item.upd!.StackObjectsCount! = currencyMaxStackSize;
|
item.upd.StackObjectsCount = currencyMaxStackSize;
|
||||||
} else {
|
} else {
|
||||||
skipSendingMoneyToStash = true;
|
skipSendingMoneyToStash = true;
|
||||||
item.upd!.StackObjectsCount! = item.upd!.StackObjectsCount! + calcAmount;
|
item.upd.StackObjectsCount = item.upd.StackObjectsCount + calcAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inform client of change to items StackObjectsCount
|
// Inform client of change to items StackObjectsCount
|
||||||
@ -257,7 +257,7 @@ export class PaymentService {
|
|||||||
pmcData.Inventory.stash,
|
pmcData.Inventory.stash,
|
||||||
);
|
);
|
||||||
const amountAvailable = moneyItemsInInventory.reduce(
|
const amountAvailable = moneyItemsInInventory.reduce(
|
||||||
(accumulator, item) => accumulator + item.upd!.StackObjectsCount!,
|
(accumulator, item) => accumulator + item.upd.StackObjectsCount,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -280,12 +280,12 @@ export class PaymentService {
|
|||||||
|
|
||||||
let leftToPay = amountToPay;
|
let leftToPay = amountToPay;
|
||||||
for (const profileMoneyItem of moneyItemsInInventory) {
|
for (const profileMoneyItem of moneyItemsInInventory) {
|
||||||
const itemAmount = profileMoneyItem.upd!.StackObjectsCount!;
|
const itemAmount = profileMoneyItem.upd.StackObjectsCount;
|
||||||
if (leftToPay >= itemAmount) {
|
if (leftToPay >= itemAmount) {
|
||||||
leftToPay -= itemAmount;
|
leftToPay -= itemAmount;
|
||||||
this.inventoryHelper.removeItem(pmcData, profileMoneyItem._id, sessionID, output);
|
this.inventoryHelper.removeItem(pmcData, profileMoneyItem._id, sessionID, output);
|
||||||
} else {
|
} else {
|
||||||
profileMoneyItem.upd!.StackObjectsCount! -= leftToPay;
|
profileMoneyItem.upd.StackObjectsCount -= leftToPay;
|
||||||
leftToPay = 0;
|
leftToPay = 0;
|
||||||
output.profileChanges[sessionID].items.change.push(profileMoneyItem);
|
output.profileChanges[sessionID].items.change.push(profileMoneyItem);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ export class ProfileFixerService {
|
|||||||
this.reorderHideoutAreasWithResouceInputs(pmcProfile);
|
this.reorderHideoutAreasWithResouceInputs(pmcProfile);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.GENERATOR)!.slots.length <
|
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.GENERATOR).slots.length <
|
||||||
6 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.Generator.Slots
|
6 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.Generator.Slots
|
||||||
) {
|
) {
|
||||||
this.logger.debug("Updating generator area slots to a size of 6 + hideout management skill");
|
this.logger.debug("Updating generator area slots to a size of 6 + hideout management skill");
|
||||||
@ -96,7 +96,7 @@ export class ProfileFixerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.WATER_COLLECTOR)!.slots.length <
|
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.WATER_COLLECTOR).slots.length <
|
||||||
1 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.WaterCollector.Slots
|
1 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.WaterCollector.Slots
|
||||||
) {
|
) {
|
||||||
this.logger.debug("Updating water collector area slots to a size of 1 + hideout management skill");
|
this.logger.debug("Updating water collector area slots to a size of 1 + hideout management skill");
|
||||||
@ -108,7 +108,7 @@ export class ProfileFixerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.AIR_FILTERING)!.slots.length <
|
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.AIR_FILTERING).slots.length <
|
||||||
3 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.AirFilteringUnit.Slots
|
3 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.AirFilteringUnit.Slots
|
||||||
) {
|
) {
|
||||||
this.logger.debug("Updating air filter area slots to a size of 3 + hideout management skill");
|
this.logger.debug("Updating air filter area slots to a size of 3 + hideout management skill");
|
||||||
@ -121,7 +121,7 @@ export class ProfileFixerService {
|
|||||||
|
|
||||||
// BTC Farm doesnt have extra slots for hideout management, but we still check for modded stuff!!
|
// BTC Farm doesnt have extra slots for hideout management, but we still check for modded stuff!!
|
||||||
if (
|
if (
|
||||||
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.BITCOIN_FARM)!.slots.length <
|
pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.BITCOIN_FARM).slots.length <
|
||||||
50 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.BitcoinFarm.Slots
|
50 + globals.config.SkillsSettings.HideoutManagement.EliteSlots.BitcoinFarm.Slots
|
||||||
) {
|
) {
|
||||||
this.logger.debug("Updating bitcoin farm area slots to a size of 50 + hideout management skill");
|
this.logger.debug("Updating bitcoin farm area slots to a size of 50 + hideout management skill");
|
||||||
@ -172,8 +172,8 @@ export class ProfileFixerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const hideout = this.databaseService.getHideout();
|
const hideout = this.databaseService.getHideout();
|
||||||
const hideoutStandAreaDb = hideout.areas.find((area) => area.type === HideoutAreas.WEAPON_STAND)!;
|
const hideoutStandAreaDb = hideout.areas.find((area) => area.type === HideoutAreas.WEAPON_STAND);
|
||||||
const hideoutStandSecondaryAreaDb = hideout.areas.find((x) => x.parentArea === hideoutStandAreaDb._id)!;
|
const hideoutStandSecondaryAreaDb = hideout.areas.find((x) => x.parentArea === hideoutStandAreaDb._id);
|
||||||
const stageCurrentAt = hideoutStandAreaDb.stages[weaponStandArea.level];
|
const stageCurrentAt = hideoutStandAreaDb.stages[weaponStandArea.level];
|
||||||
const hideoutStandStashId = pmcProfile.Inventory.hideoutAreaStashes[HideoutAreas.WEAPON_STAND];
|
const hideoutStandStashId = pmcProfile.Inventory.hideoutAreaStashes[HideoutAreas.WEAPON_STAND];
|
||||||
const hideoutSecondaryStashId = pmcProfile.Inventory.hideoutAreaStashes[HideoutAreas.WEAPON_STAND_SECONDARY];
|
const hideoutSecondaryStashId = pmcProfile.Inventory.hideoutAreaStashes[HideoutAreas.WEAPON_STAND_SECONDARY];
|
||||||
@ -188,12 +188,12 @@ export class ProfileFixerService {
|
|||||||
// Add stash item to profile
|
// Add stash item to profile
|
||||||
const gunStandStashItem = pmcProfile.Inventory.items.find((item) => item._id === hideoutStandAreaDb._id);
|
const gunStandStashItem = pmcProfile.Inventory.items.find((item) => item._id === hideoutStandAreaDb._id);
|
||||||
if (gunStandStashItem) {
|
if (gunStandStashItem) {
|
||||||
gunStandStashItem._tpl = stageCurrentAt.container!;
|
gunStandStashItem._tpl = stageCurrentAt.container;
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`Updated existing gun stand inventory stash: ${gunStandStashItem._id} tpl to ${stageCurrentAt.container}`,
|
`Updated existing gun stand inventory stash: ${gunStandStashItem._id} tpl to ${stageCurrentAt.container}`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
pmcProfile.Inventory.items.push({ _id: hideoutStandAreaDb._id, _tpl: stageCurrentAt.container! });
|
pmcProfile.Inventory.items.push({ _id: hideoutStandAreaDb._id, _tpl: stageCurrentAt.container });
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`Added missing gun stand inventory stash: ${hideoutStandAreaDb._id} tpl to ${stageCurrentAt.container}`,
|
`Added missing gun stand inventory stash: ${hideoutStandAreaDb._id} tpl to ${stageCurrentAt.container}`,
|
||||||
);
|
);
|
||||||
@ -202,16 +202,16 @@ export class ProfileFixerService {
|
|||||||
// Add secondary stash item to profile
|
// Add secondary stash item to profile
|
||||||
const gunStandStashSecondaryItem = pmcProfile.Inventory.items.find(
|
const gunStandStashSecondaryItem = pmcProfile.Inventory.items.find(
|
||||||
(item) => item._id === hideoutStandSecondaryAreaDb._id,
|
(item) => item._id === hideoutStandSecondaryAreaDb._id,
|
||||||
)!;
|
);
|
||||||
if (gunStandStashItem) {
|
if (gunStandStashItem) {
|
||||||
gunStandStashSecondaryItem._tpl = stageCurrentAt.container!;
|
gunStandStashSecondaryItem._tpl = stageCurrentAt.container;
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`Updated gun stand existing inventory secondary stash: ${gunStandStashSecondaryItem._id} tpl to ${stageCurrentAt.container}`,
|
`Updated gun stand existing inventory secondary stash: ${gunStandStashSecondaryItem._id} tpl to ${stageCurrentAt.container}`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
pmcProfile.Inventory.items.push({
|
pmcProfile.Inventory.items.push({
|
||||||
_id: hideoutStandSecondaryAreaDb._id,
|
_id: hideoutStandSecondaryAreaDb._id,
|
||||||
_tpl: stageCurrentAt.container!,
|
_tpl: stageCurrentAt.container,
|
||||||
});
|
});
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`Added missing gun stand inventory secondary stash: ${hideoutStandSecondaryAreaDb._id} tpl to ${stageCurrentAt.container}`,
|
`Added missing gun stand inventory secondary stash: ${hideoutStandSecondaryAreaDb._id} tpl to ${stageCurrentAt.container}`,
|
||||||
@ -224,23 +224,23 @@ export class ProfileFixerService {
|
|||||||
let stashItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandAreaDb._id);
|
let stashItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandAreaDb._id);
|
||||||
if (!stashItem) {
|
if (!stashItem) {
|
||||||
// Stand inventory stash item doesnt exist, add it
|
// Stand inventory stash item doesnt exist, add it
|
||||||
pmcProfile.Inventory.items.push({ _id: hideoutStandAreaDb._id, _tpl: stageCurrentAt.container! });
|
pmcProfile.Inventory.items.push({ _id: hideoutStandAreaDb._id, _tpl: stageCurrentAt.container });
|
||||||
stashItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandAreaDb._id);
|
stashItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandAreaDb._id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// `hideoutAreaStashes` has value related stash inventory items tpl doesnt match what's expected
|
// `hideoutAreaStashes` has value related stash inventory items tpl doesnt match what's expected
|
||||||
if (hideoutStandStashId && stashItem!._tpl !== stageCurrentAt.container) {
|
if (hideoutStandStashId && stashItem._tpl !== stageCurrentAt.container) {
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`primary Stash tpl was: ${stashItem!._tpl}, but should be ${stageCurrentAt.container}, updating`,
|
`primary Stash tpl was: ${stashItem._tpl}, but should be ${stageCurrentAt.container}, updating`,
|
||||||
);
|
);
|
||||||
// The id inside the profile does not match what the hideout db value is, out of sync, adjust
|
// The id inside the profile does not match what the hideout db value is, out of sync, adjust
|
||||||
stashItem!._tpl = stageCurrentAt.container!;
|
stashItem._tpl = stageCurrentAt.container;
|
||||||
}
|
}
|
||||||
|
|
||||||
let stashSecondaryItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandSecondaryAreaDb._id);
|
let stashSecondaryItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandSecondaryAreaDb._id);
|
||||||
if (!stashSecondaryItem) {
|
if (!stashSecondaryItem) {
|
||||||
// Stand inventory stash item doesnt exist, add it
|
// Stand inventory stash item doesnt exist, add it
|
||||||
pmcProfile.Inventory.items.push({ _id: hideoutStandSecondaryAreaDb._id, _tpl: stageCurrentAt.container! });
|
pmcProfile.Inventory.items.push({ _id: hideoutStandSecondaryAreaDb._id, _tpl: stageCurrentAt.container });
|
||||||
stashSecondaryItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandSecondaryAreaDb._id);
|
stashSecondaryItem = pmcProfile.Inventory.items?.find((x) => x._id === hideoutStandSecondaryAreaDb._id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ export class ProfileFixerService {
|
|||||||
`Secondary stash tpl was: ${stashSecondaryItem?._tpl}, but should be ${stageCurrentAt.container}, updating`,
|
`Secondary stash tpl was: ${stashSecondaryItem?._tpl}, but should be ${stageCurrentAt.container}, updating`,
|
||||||
);
|
);
|
||||||
// The id inside the profile does not match what the hideout db value is, out of sync, adjust
|
// The id inside the profile does not match what the hideout db value is, out of sync, adjust
|
||||||
stashSecondaryItem!._tpl = stageCurrentAt.container!;
|
stashSecondaryItem._tpl = stageCurrentAt.container;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,12 +278,12 @@ export class ProfileFixerService {
|
|||||||
// Add stash item to profile
|
// Add stash item to profile
|
||||||
const placeOfFameStashItem = pmcProfile.Inventory.items.find((item) => item._id === placeOfFameAreaDb._id);
|
const placeOfFameStashItem = pmcProfile.Inventory.items.find((item) => item._id === placeOfFameAreaDb._id);
|
||||||
if (placeOfFameStashItem) {
|
if (placeOfFameStashItem) {
|
||||||
placeOfFameStashItem._tpl = stageCurrentlyAt.container!;
|
placeOfFameStashItem._tpl = stageCurrentlyAt.container;
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`Updated existing place of fame inventory stash: ${placeOfFameStashItem._id} tpl to ${stageCurrentlyAt.container}`,
|
`Updated existing place of fame inventory stash: ${placeOfFameStashItem._id} tpl to ${stageCurrentlyAt.container}`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
pmcProfile.Inventory.items.push({ _id: placeOfFameAreaDb._id, _tpl: stageCurrentlyAt.container! });
|
pmcProfile.Inventory.items.push({ _id: placeOfFameAreaDb._id, _tpl: stageCurrentlyAt.container });
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`Added missing place of fame inventory stash: ${placeOfFameAreaDb._id} tpl to ${stageCurrentlyAt.container}`,
|
`Added missing place of fame inventory stash: ${placeOfFameAreaDb._id} tpl to ${stageCurrentlyAt.container}`,
|
||||||
);
|
);
|
||||||
@ -295,17 +295,17 @@ export class ProfileFixerService {
|
|||||||
let stashItem = pmcProfile.Inventory.items?.find((x) => x._id === placeOfFameAreaDb._id);
|
let stashItem = pmcProfile.Inventory.items?.find((x) => x._id === placeOfFameAreaDb._id);
|
||||||
if (!stashItem) {
|
if (!stashItem) {
|
||||||
// Stand inventory stash item doesnt exist, add it
|
// Stand inventory stash item doesnt exist, add it
|
||||||
pmcProfile.Inventory.items.push({ _id: placeOfFameAreaDb._id, _tpl: stageCurrentlyAt.container! });
|
pmcProfile.Inventory.items.push({ _id: placeOfFameAreaDb._id, _tpl: stageCurrentlyAt.container });
|
||||||
stashItem = pmcProfile.Inventory.items?.find((x) => x._id === placeOfFameAreaDb._id);
|
stashItem = pmcProfile.Inventory.items?.find((x) => x._id === placeOfFameAreaDb._id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// `hideoutAreaStashes` has value related stash inventory items tpl doesnt match what's expected
|
// `hideoutAreaStashes` has value related stash inventory items tpl doesnt match what's expected
|
||||||
if (placeOfFameStashId && stashItem!._tpl !== stageCurrentlyAt.container) {
|
if (placeOfFameStashId && stashItem._tpl !== stageCurrentlyAt.container) {
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`primary Stash tpl was: ${stashItem?._tpl}, but should be ${stageCurrentlyAt.container}, updating`,
|
`primary Stash tpl was: ${stashItem?._tpl}, but should be ${stageCurrentlyAt.container}, updating`,
|
||||||
);
|
);
|
||||||
// The id inside the profile does not match what the hideout db value is, out of sync, adjust
|
// The id inside the profile does not match what the hideout db value is, out of sync, adjust
|
||||||
stashItem!._tpl = stageCurrentlyAt.container!;
|
stashItem._tpl = stageCurrentlyAt.container;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,13 +574,13 @@ export class ProfileFixerService {
|
|||||||
* @param pmcProfile Profile to add improvement data to
|
* @param pmcProfile Profile to add improvement data to
|
||||||
*/
|
*/
|
||||||
protected addMissingWallImprovements(pmcProfile: IPmcData): void {
|
protected addMissingWallImprovements(pmcProfile: IPmcData): void {
|
||||||
const profileWallArea = pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.EMERGENCY_WALL)!;
|
const profileWallArea = pmcProfile.Hideout.Areas.find((x) => x.type === HideoutAreas.EMERGENCY_WALL);
|
||||||
const wallDb = this.databaseService.getHideout().areas.find((x) => x.type === HideoutAreas.EMERGENCY_WALL);
|
const wallDb = this.databaseService.getHideout().areas.find((x) => x.type === HideoutAreas.EMERGENCY_WALL);
|
||||||
|
|
||||||
if (profileWallArea.level > 0) {
|
if (profileWallArea.level > 0) {
|
||||||
for (let i = 0; i < profileWallArea.level; i++) {
|
for (let i = 0; i < profileWallArea.level; i++) {
|
||||||
// Get wall stage from db
|
// Get wall stage from db
|
||||||
const wallStageDb = wallDb!.stages[i];
|
const wallStageDb = wallDb.stages[i];
|
||||||
if (wallStageDb.improvements.length === 0) {
|
if (wallStageDb.improvements.length === 0) {
|
||||||
// No improvements, skip
|
// No improvements, skip
|
||||||
continue;
|
continue;
|
||||||
@ -640,7 +640,7 @@ export class ProfileFixerService {
|
|||||||
for (const areaId of areasToCheck) {
|
for (const areaId of areasToCheck) {
|
||||||
const area = pmcProfile.Hideout.Areas.find((area) => area.type === areaId);
|
const area = pmcProfile.Hideout.Areas.find((area) => area.type === areaId);
|
||||||
if (!area) {
|
if (!area) {
|
||||||
this.logger.debug(`unable to sort: ${area!.type} (${areaId}) slots, no area found`);
|
this.logger.debug(`unable to sort: ${area.type} (${areaId}) slots, no area found`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,7 +666,7 @@ export class ProfileFixerService {
|
|||||||
pmcProfile: IPmcData,
|
pmcProfile: IPmcData,
|
||||||
): void {
|
): void {
|
||||||
const area = pmcProfile.Hideout.Areas.find((x) => x.type === areaType);
|
const area = pmcProfile.Hideout.Areas.find((x) => x.type === areaType);
|
||||||
area!.slots = this.addObjectsToArray(emptyItemCount, area!.slots);
|
area.slots = this.addObjectsToArray(emptyItemCount, area.slots);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected addObjectsToArray(count: number, slots: HideoutSlot[]): HideoutSlot[] {
|
protected addObjectsToArray(count: number, slots: HideoutSlot[]): HideoutSlot[] {
|
||||||
@ -878,9 +878,9 @@ export class ProfileFixerService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const successReward of activeQuest.rewards.Success!) {
|
for (const successReward of activeQuest.rewards.Success) {
|
||||||
if (successReward.type === "Item") {
|
if (successReward.type === "Item") {
|
||||||
for (const rewardItem of successReward.items!) {
|
for (const rewardItem of successReward.items) {
|
||||||
if (!itemsDb[rewardItem._tpl]) {
|
if (!itemsDb[rewardItem._tpl]) {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
this.localisationService.getText("fixer-mod_item_found", rewardItem._tpl),
|
this.localisationService.getText("fixer-mod_item_found", rewardItem._tpl),
|
||||||
@ -1009,7 +1009,7 @@ export class ProfileFixerService {
|
|||||||
// Only replace ID if items have no children, we dont want orphaned children
|
// Only replace ID if items have no children, we dont want orphaned children
|
||||||
const itemsHaveChildren = pmcProfile.Inventory.items.some((x) => x.parentId === key);
|
const itemsHaveChildren = pmcProfile.Inventory.items.some((x) => x.parentId === key);
|
||||||
if (!itemsHaveChildren) {
|
if (!itemsHaveChildren) {
|
||||||
const itemToAdjust = pmcProfile.Inventory.items.find((x) => x._id === key)!;
|
const itemToAdjust = pmcProfile.Inventory.items.find((x) => x._id === key);
|
||||||
itemToAdjust._id = this.hashUtil.generate();
|
itemToAdjust._id = this.hashUtil.generate();
|
||||||
this.logger.warning(`Replace duplicate item Id: ${key} with ${itemToAdjust._id}`);
|
this.logger.warning(`Replace duplicate item Id: ${key} with ${itemToAdjust._id}`);
|
||||||
}
|
}
|
||||||
@ -1047,7 +1047,7 @@ export class ProfileFixerService {
|
|||||||
const defaultHead = playerIsUsec
|
const defaultHead = playerIsUsec
|
||||||
? customizationDbArray.find((x) => x._name === "DefaultUsecHead")
|
? customizationDbArray.find((x) => x._name === "DefaultUsecHead")
|
||||||
: customizationDbArray.find((x) => x._name === "DefaultBearHead");
|
: customizationDbArray.find((x) => x._name === "DefaultBearHead");
|
||||||
pmcProfile.Customization.Head = defaultHead!._id;
|
pmcProfile.Customization.Head = defaultHead._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check Body
|
// check Body
|
||||||
@ -1056,7 +1056,7 @@ export class ProfileFixerService {
|
|||||||
pmcProfile.Info.Side.toLowerCase() === "usec"
|
pmcProfile.Info.Side.toLowerCase() === "usec"
|
||||||
? customizationDbArray.find((x) => x._name === "DefaultUsecBody")
|
? customizationDbArray.find((x) => x._name === "DefaultUsecBody")
|
||||||
: customizationDbArray.find((x) => x._name === "DefaultBearBody");
|
: customizationDbArray.find((x) => x._name === "DefaultBearBody");
|
||||||
pmcProfile.Customization.Body = defaultBody!._id;
|
pmcProfile.Customization.Body = defaultBody._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check Hands
|
// check Hands
|
||||||
@ -1065,7 +1065,7 @@ export class ProfileFixerService {
|
|||||||
pmcProfile.Info.Side.toLowerCase() === "usec"
|
pmcProfile.Info.Side.toLowerCase() === "usec"
|
||||||
? customizationDbArray.find((x) => x._name === "DefaultUsecHands")
|
? customizationDbArray.find((x) => x._name === "DefaultUsecHands")
|
||||||
: customizationDbArray.find((x) => x._name === "DefaultBearHands");
|
: customizationDbArray.find((x) => x._name === "DefaultBearHands");
|
||||||
pmcProfile.Customization.Hands = defaultHands!._id;
|
pmcProfile.Customization.Hands = defaultHands._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check Hands
|
// check Hands
|
||||||
@ -1074,7 +1074,7 @@ export class ProfileFixerService {
|
|||||||
pmcProfile.Info.Side.toLowerCase() === "usec"
|
pmcProfile.Info.Side.toLowerCase() === "usec"
|
||||||
? customizationDbArray.find((x) => x._name === "DefaultUsecFeet")
|
? customizationDbArray.find((x) => x._name === "DefaultUsecFeet")
|
||||||
: customizationDbArray.find((x) => x._name === "DefaultBearFeet");
|
: customizationDbArray.find((x) => x._name === "DefaultBearFeet");
|
||||||
pmcProfile.Customization.Feet = defaultFeet!._id;
|
pmcProfile.Customization.Feet = defaultFeet._id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,8 +136,8 @@ export class RagfairOfferService {
|
|||||||
public removeOfferStack(offerId: string, amount: number): void {
|
public removeOfferStack(offerId: string, amount: number): void {
|
||||||
const offer = this.ragfairOfferHandler.getOfferById(offerId);
|
const offer = this.ragfairOfferHandler.getOfferById(offerId);
|
||||||
if (offer) {
|
if (offer) {
|
||||||
offer.items[0].upd!.StackObjectsCount! -= amount;
|
offer.items[0].upd.StackObjectsCount -= amount;
|
||||||
if (offer.items[0].upd!.StackObjectsCount! <= 0) {
|
if (offer.items[0].upd.StackObjectsCount <= 0) {
|
||||||
this.processStaleOffer(offer);
|
this.processStaleOffer(offer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,10 +245,10 @@ export class RagfairOfferService {
|
|||||||
profile.RagfairInfo.isRatingGrowing = false;
|
profile.RagfairInfo.isRatingGrowing = false;
|
||||||
|
|
||||||
const firstOfferItem = playerOffer.items[0];
|
const firstOfferItem = playerOffer.items[0];
|
||||||
if (firstOfferItem.upd!.StackObjectsCount! > firstOfferItem.upd!.OriginalStackObjectsCount!) {
|
if (firstOfferItem.upd.StackObjectsCount > firstOfferItem.upd.OriginalStackObjectsCount) {
|
||||||
playerOffer.items[0].upd!.StackObjectsCount = firstOfferItem.upd!.OriginalStackObjectsCount;
|
playerOffer.items[0].upd.StackObjectsCount = firstOfferItem.upd.OriginalStackObjectsCount;
|
||||||
}
|
}
|
||||||
delete playerOffer.items[0].upd!.OriginalStackObjectsCount;
|
delete playerOffer.items[0].upd.OriginalStackObjectsCount;
|
||||||
// Remove player offer from flea
|
// Remove player offer from flea
|
||||||
this.ragfairOfferHandler.removeOffer(playerOffer);
|
this.ragfairOfferHandler.removeOffer(playerOffer);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ export class RagfairTaxService {
|
|||||||
const requirementsPrice = requirementsValue * (sellInOnePiece ? 1 : offerItemCount);
|
const requirementsPrice = requirementsValue * (sellInOnePiece ? 1 : offerItemCount);
|
||||||
|
|
||||||
const itemTaxMult = globals.config.RagFair.communityItemTax / 100.0;
|
const itemTaxMult = globals.config.RagFair.communityItemTax / 100.0;
|
||||||
const requirementTaxMult = globals!.config.RagFair.communityRequirementTax / 100.0;
|
const requirementTaxMult = globals.config.RagFair.communityRequirementTax / 100.0;
|
||||||
|
|
||||||
let itemPriceMult = Math.log10(itemWorth / requirementsPrice);
|
let itemPriceMult = Math.log10(itemWorth / requirementsPrice);
|
||||||
let requirementPriceMult = Math.log10(requirementsPrice / itemWorth);
|
let requirementPriceMult = Math.log10(requirementsPrice / itemWorth);
|
||||||
@ -79,7 +79,7 @@ export class RagfairTaxService {
|
|||||||
requirementPriceMult = 4 ** requirementPriceMult;
|
requirementPriceMult = 4 ** requirementPriceMult;
|
||||||
|
|
||||||
const hideoutFleaTaxDiscountBonus = pmcData.Bonuses.find((b) => b.type === BonusType.RAGFAIR_COMMISSION);
|
const hideoutFleaTaxDiscountBonus = pmcData.Bonuses.find((b) => b.type === BonusType.RAGFAIR_COMMISSION);
|
||||||
const taxDiscountPercent = hideoutFleaTaxDiscountBonus ? Math.abs(hideoutFleaTaxDiscountBonus!.value ?? 0) : 0;
|
const taxDiscountPercent = hideoutFleaTaxDiscountBonus ? Math.abs(hideoutFleaTaxDiscountBonus.value ?? 0) : 0;
|
||||||
|
|
||||||
const tax =
|
const tax =
|
||||||
itemWorth * itemTaxMult * itemPriceMult + requirementsPrice * requirementTaxMult * requirementPriceMult;
|
itemWorth * itemTaxMult * itemPriceMult + requirementsPrice * requirementTaxMult * requirementPriceMult;
|
||||||
@ -123,7 +123,7 @@ export class RagfairTaxService {
|
|||||||
worth += this.calculateItemWorth(
|
worth += this.calculateItemWorth(
|
||||||
child,
|
child,
|
||||||
this.itemHelper.getItem(child._tpl)[1],
|
this.itemHelper.getItem(child._tpl)[1],
|
||||||
child.upd!.StackObjectsCount!,
|
child.upd.StackObjectsCount,
|
||||||
pmcData,
|
pmcData,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
@ -131,39 +131,39 @@ export class RagfairTaxService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("Dogtag" in item.upd!) {
|
if ("Dogtag" in item.upd) {
|
||||||
worth *= item.upd!.Dogtag!.Level;
|
worth *= item.upd.Dogtag.Level;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("Key" in item.upd! && (itemTemplate._props.MaximumNumberOfUsage ?? 0) > 0) {
|
if ("Key" in item.upd && (itemTemplate._props.MaximumNumberOfUsage ?? 0) > 0) {
|
||||||
worth =
|
worth =
|
||||||
(worth / itemTemplate._props.MaximumNumberOfUsage!) *
|
(worth / itemTemplate._props.MaximumNumberOfUsage) *
|
||||||
(itemTemplate._props.MaximumNumberOfUsage! - item.upd!.Key!.NumberOfUsages);
|
(itemTemplate._props.MaximumNumberOfUsage - item.upd.Key.NumberOfUsages);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("Resource" in item.upd! && itemTemplate._props.MaxResource! > 0) {
|
if ("Resource" in item.upd && itemTemplate._props.MaxResource > 0) {
|
||||||
worth = worth * 0.1 + ((worth * 0.9) / itemTemplate._props.MaxResource!) * item.upd.Resource!.Value;
|
worth = worth * 0.1 + ((worth * 0.9) / itemTemplate._props.MaxResource) * item.upd.Resource.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("SideEffect" in item.upd! && itemTemplate._props.MaxResource! > 0) {
|
if ("SideEffect" in item.upd && itemTemplate._props.MaxResource > 0) {
|
||||||
worth = worth * 0.1 + ((worth * 0.9) / itemTemplate._props.MaxResource!) * item.upd.SideEffect!.Value;
|
worth = worth * 0.1 + ((worth * 0.9) / itemTemplate._props.MaxResource) * item.upd.SideEffect.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("MedKit" in item.upd! && itemTemplate._props.MaxHpResource! > 0) {
|
if ("MedKit" in item.upd && itemTemplate._props.MaxHpResource > 0) {
|
||||||
worth = (worth / itemTemplate._props.MaxHpResource!) * item.upd.MedKit!.HpResource;
|
worth = (worth / itemTemplate._props.MaxHpResource) * item.upd.MedKit.HpResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("FoodDrink" in item.upd! && itemTemplate._props.MaxResource! > 0) {
|
if ("FoodDrink" in item.upd && itemTemplate._props.MaxResource > 0) {
|
||||||
worth = (worth / itemTemplate._props.MaxResource!) * item.upd.FoodDrink!.HpPercent;
|
worth = (worth / itemTemplate._props.MaxResource) * item.upd.FoodDrink.HpPercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("Repairable" in item.upd! && <number>itemTemplate._props.armorClass > 0) {
|
if ("Repairable" in item.upd && <number>itemTemplate._props.armorClass > 0) {
|
||||||
const num2 = 0.01 * 0.0 ** item.upd.Repairable!.MaxDurability;
|
const num2 = 0.01 * 0.0 ** item.upd.Repairable.MaxDurability;
|
||||||
worth =
|
worth =
|
||||||
worth * (item.upd.Repairable!.MaxDurability / itemTemplate._props.Durability! - num2) -
|
worth * (item.upd.Repairable.MaxDurability / itemTemplate._props.Durability - num2) -
|
||||||
Math.floor(
|
Math.floor(
|
||||||
itemTemplate._props.RepairCost! *
|
itemTemplate._props.RepairCost *
|
||||||
(item.upd.Repairable!.MaxDurability - item.upd.Repairable!.Durability),
|
(item.upd.Repairable.MaxDurability - item.upd.Repairable.Durability),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ export class RepairService {
|
|||||||
this.addMaxResourceToKitIfMissing(repairKitDetails, repairKitInInventory);
|
this.addMaxResourceToKitIfMissing(repairKitDetails, repairKitInInventory);
|
||||||
|
|
||||||
// reduce usages on repairkit used
|
// reduce usages on repairkit used
|
||||||
repairKitInInventory.upd!.RepairKit!.Resource -= repairKitReductionAmount;
|
repairKitInInventory.upd.RepairKit.Resource -= repairKitReductionAmount;
|
||||||
|
|
||||||
output.profileChanges[sessionId].items.change.push(repairKitInInventory);
|
output.profileChanges[sessionId].items.change.push(repairKitInInventory);
|
||||||
}
|
}
|
||||||
@ -425,7 +425,7 @@ export class RepairService {
|
|||||||
* @param repairKitInInventory Repair kit to update
|
* @param repairKitInInventory Repair kit to update
|
||||||
*/
|
*/
|
||||||
protected addMaxResourceToKitIfMissing(repairKitDetails: ITemplateItem, repairKitInInventory: Item): void {
|
protected addMaxResourceToKitIfMissing(repairKitDetails: ITemplateItem, repairKitInInventory: Item): void {
|
||||||
const maxRepairAmount = repairKitDetails._props.MaxRepairResource!;
|
const maxRepairAmount = repairKitDetails._props.MaxRepairResource;
|
||||||
if (!repairKitInInventory.upd) {
|
if (!repairKitInInventory.upd) {
|
||||||
this.logger.debug(`Repair kit: ${repairKitInInventory._id} in inventory lacks upd object, adding`);
|
this.logger.debug(`Repair kit: ${repairKitInInventory._id} in inventory lacks upd object, adding`);
|
||||||
repairKitInInventory.upd = { RepairKit: { Resource: maxRepairAmount } };
|
repairKitInInventory.upd = { RepairKit: { Resource: maxRepairAmount } };
|
||||||
@ -480,13 +480,13 @@ export class RepairService {
|
|||||||
const bonusThresholdPercents = itemConfig[bonusRarity][bonusType].activeDurabilityPercentMinMax;
|
const bonusThresholdPercents = itemConfig[bonusRarity][bonusType].activeDurabilityPercentMinMax;
|
||||||
const bonusThresholdPercent = this.randomUtil.getInt(bonusThresholdPercents.min, bonusThresholdPercents.max);
|
const bonusThresholdPercent = this.randomUtil.getInt(bonusThresholdPercents.min, bonusThresholdPercents.max);
|
||||||
|
|
||||||
item.upd!.Buff = {
|
item.upd.Buff = {
|
||||||
rarity: bonusRarity,
|
rarity: bonusRarity,
|
||||||
buffType: bonusType,
|
buffType: bonusType,
|
||||||
value: bonusValue,
|
value: bonusValue,
|
||||||
thresholdDurability: this.randomUtil.getPercentOfValue(
|
thresholdDurability: this.randomUtil.getPercentOfValue(
|
||||||
bonusThresholdPercent,
|
bonusThresholdPercent,
|
||||||
item.upd!.Repairable!.Durability,
|
item.upd.Repairable.Durability,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -545,7 +545,7 @@ export class RepairService {
|
|||||||
this.localisationService.getText("repair-item_has_no_repair_points", repairDetails.repairedItem._tpl),
|
this.localisationService.getText("repair-item_has_no_repair_points", repairDetails.repairedItem._tpl),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const durabilityToRestorePercent = repairDetails.repairPoints / template._props.MaxDurability!;
|
const durabilityToRestorePercent = repairDetails.repairPoints / template._props.MaxDurability;
|
||||||
const durabilityMultiplier = this.getDurabilityMultiplier(
|
const durabilityMultiplier = this.getDurabilityMultiplier(
|
||||||
receivedDurabilityMaxPercent,
|
receivedDurabilityMaxPercent,
|
||||||
durabilityToRestorePercent,
|
durabilityToRestorePercent,
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
* - Finalized enum names are created as a combination of the parent name, prefix, item name, and suffix
|
* - Finalized enum names are created as a combination of the parent name, prefix, item name, and suffix
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as fs from "fs";
|
import * as fs from "node:fs";
|
||||||
import * as path from "path";
|
import * as path from "node:path";
|
||||||
import { OnLoad } from "@spt/di/OnLoad";
|
import { OnLoad } from "@spt/di/OnLoad";
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
||||||
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
||||||
@ -62,7 +62,7 @@ export class ItemTplGenerator {
|
|||||||
const currentDir = path.dirname(__filename);
|
const currentDir = path.dirname(__filename);
|
||||||
const projectDir = path.resolve(currentDir, "..", "..", "..");
|
const projectDir = path.resolve(currentDir, "..", "..", "..");
|
||||||
this.enumDir = path.join(projectDir, "src", "models", "enums");
|
this.enumDir = path.join(projectDir, "src", "models", "enums");
|
||||||
this.items = this.databaseServer.getTables().templates!.items;
|
this.items = this.databaseServer.getTables().templates.items;
|
||||||
this.itemOverrides = itemTplOverrides.default;
|
this.itemOverrides = itemTplOverrides.default;
|
||||||
|
|
||||||
// Generate an object containing all item name to ID associations
|
// Generate an object containing all item name to ID associations
|
||||||
@ -98,9 +98,9 @@ export class ItemTplGenerator {
|
|||||||
const itemSuffix = this.getItemSuffix(item);
|
const itemSuffix = this.getItemSuffix(item);
|
||||||
|
|
||||||
// Handle the case where the item starts with the parent category name. Avoids things like 'POCKETS_POCKETS'
|
// Handle the case where the item starts with the parent category name. Avoids things like 'POCKETS_POCKETS'
|
||||||
if (itemParentName == itemName.substring(1, itemParentName.length + 1) && itemPrefix == "") {
|
if (itemParentName === itemName.substring(1, itemParentName.length + 1) && itemPrefix === "") {
|
||||||
itemName = itemName.substring(itemParentName.length + 1);
|
itemName = itemName.substring(itemParentName.length + 1);
|
||||||
if (itemName.length > 0 && itemName.at(0) != "_") {
|
if (itemName.length > 0 && itemName.at(0) !== "_") {
|
||||||
itemName = `_${itemName}`;
|
itemName = `_${itemName}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ export class ItemTplGenerator {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const caliber = this.cleanCaliber(item._props.ammoCaliber!.toUpperCase());
|
const caliber = this.cleanCaliber(item._props.ammoCaliber.toUpperCase());
|
||||||
let weaponShortName = this.localeService.getLocaleDb()[`${itemId} ShortName`]?.toUpperCase();
|
let weaponShortName = this.localeService.getLocaleDb()[`${itemId} ShortName`]?.toUpperCase();
|
||||||
|
|
||||||
// Special case for the weird duplicated grenade launcher
|
// Special case for the weird duplicated grenade launcher
|
||||||
@ -236,29 +236,37 @@ export class ItemTplGenerator {
|
|||||||
private getParentName(item: ITemplateItem): string {
|
private getParentName(item: ITemplateItem): string {
|
||||||
if (item._props.QuestItem) {
|
if (item._props.QuestItem) {
|
||||||
return "QUEST";
|
return "QUEST";
|
||||||
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.BARTER_ITEM)) {
|
}
|
||||||
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.BARTER_ITEM)) {
|
||||||
return "BARTER";
|
return "BARTER";
|
||||||
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.THROW_WEAPON)) {
|
}
|
||||||
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.THROW_WEAPON)) {
|
||||||
return "GRENADE";
|
return "GRENADE";
|
||||||
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.STIMULATOR)) {
|
}
|
||||||
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.STIMULATOR)) {
|
||||||
return "STIM";
|
return "STIM";
|
||||||
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MAGAZINE)) {
|
}
|
||||||
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MAGAZINE)) {
|
||||||
return "MAGAZINE";
|
return "MAGAZINE";
|
||||||
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.KEY_MECHANICAL)) {
|
}
|
||||||
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.KEY_MECHANICAL)) {
|
||||||
return "KEY";
|
return "KEY";
|
||||||
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MOB_CONTAINER)) {
|
}
|
||||||
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MOB_CONTAINER)) {
|
||||||
return "SECURE";
|
return "SECURE";
|
||||||
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.SIMPLE_CONTAINER)) {
|
}
|
||||||
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.SIMPLE_CONTAINER)) {
|
||||||
return "CONTAINER";
|
return "CONTAINER";
|
||||||
} else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.PORTABLE_RANGE_FINDER)) {
|
}
|
||||||
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.PORTABLE_RANGE_FINDER)) {
|
||||||
return "RANGEFINDER";
|
return "RANGEFINDER";
|
||||||
}
|
}
|
||||||
// Why are flares grenade launcher...?
|
// Why are flares grenade launcher...?
|
||||||
else if (item._name.startsWith("weapon_rsp30")) {
|
if (item._name.startsWith("weapon_rsp30")) {
|
||||||
return "FLARE";
|
return "FLARE";
|
||||||
}
|
}
|
||||||
// This is a special case for the signal pistol, I'm not adding it as a Grenade Launcher
|
// This is a special case for the signal pistol, I'm not adding it as a Grenade Launcher
|
||||||
else if (item._id == "620109578d82e67e7911abf2") {
|
if (item._id === "620109578d82e67e7911abf2") {
|
||||||
return "SIGNALPISTOL";
|
return "SIGNALPISTOL";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +310,7 @@ export class ItemTplGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure there's an underscore separator
|
// Make sure there's an underscore separator
|
||||||
if (prefix.length > 0 && prefix.at(0) != "_") {
|
if (prefix.length > 0 && prefix.at(0) !== "_") {
|
||||||
prefix = `_${prefix}`;
|
prefix = `_${prefix}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,11 +322,11 @@ export class ItemTplGenerator {
|
|||||||
|
|
||||||
// Add mag size for magazines
|
// Add mag size for magazines
|
||||||
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MAGAZINE)) {
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.MAGAZINE)) {
|
||||||
suffix = item._props.Cartridges![0]?._max_count?.toString() + "RND";
|
suffix = `${item._props.Cartridges[0]?._max_count?.toString()}RND`;
|
||||||
}
|
}
|
||||||
// Add pack size for ammo boxes
|
// Add pack size for ammo boxes
|
||||||
else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.AMMO_BOX)) {
|
else if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.AMMO_BOX)) {
|
||||||
suffix = item._props.StackSlots![0]?._max_count.toString() + "RND";
|
suffix = `${item._props.StackSlots[0]?._max_count.toString()}RND`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add "DAMAGED" for damaged items
|
// Add "DAMAGED" for damaged items
|
||||||
@ -327,7 +335,7 @@ export class ItemTplGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure there's an underscore separator
|
// Make sure there's an underscore separator
|
||||||
if (suffix.length > 0 && suffix.at(0) != "_") {
|
if (suffix.length > 0 && suffix.at(0) !== "_") {
|
||||||
suffix = `_${suffix}`;
|
suffix = `_${suffix}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +343,7 @@ export class ItemTplGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getAmmoPrefix(item: ITemplateItem): string {
|
private getAmmoPrefix(item: ITemplateItem): string {
|
||||||
const prefix = item._props.Caliber!.toUpperCase();
|
const prefix = item._props.Caliber.toUpperCase();
|
||||||
|
|
||||||
return this.cleanCaliber(prefix);
|
return this.cleanCaliber(prefix);
|
||||||
}
|
}
|
||||||
@ -352,13 +360,13 @@ export class ItemTplGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getAmmoBoxPrefix(item: ITemplateItem): string {
|
private getAmmoBoxPrefix(item: ITemplateItem): string {
|
||||||
const ammoItem = item._props.StackSlots![0]?._props.filters[0].Filter[0];
|
const ammoItem = item._props.StackSlots[0]?._props.filters[0].Filter[0];
|
||||||
|
|
||||||
return this.getAmmoPrefix(this.items[ammoItem]);
|
return this.getAmmoPrefix(this.items[ammoItem]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getMagazinePrefix(item: ITemplateItem): string {
|
private getMagazinePrefix(item: ITemplateItem): string {
|
||||||
const ammoItem = item._props.Cartridges![0]?._props.filters[0].Filter[0];
|
const ammoItem = item._props.Cartridges[0]?._props.filters[0].Filter[0];
|
||||||
|
|
||||||
return this.getAmmoPrefix(this.items[ammoItem]);
|
return this.getAmmoPrefix(this.items[ammoItem]);
|
||||||
}
|
}
|
||||||
@ -369,7 +377,7 @@ export class ItemTplGenerator {
|
|||||||
* @returns The name of the given item
|
* @returns The name of the given item
|
||||||
*/
|
*/
|
||||||
private getItemName(item) {
|
private getItemName(item) {
|
||||||
let itemName;
|
let itemName: string;
|
||||||
|
|
||||||
// Manual item name overrides
|
// Manual item name overrides
|
||||||
if (this.itemOverrides[item._id]) {
|
if (this.itemOverrides[item._id]) {
|
||||||
@ -420,12 +428,12 @@ export class ItemTplGenerator {
|
|||||||
|
|
||||||
// Add grid size for lootable containers
|
// Add grid size for lootable containers
|
||||||
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.LOOT_CONTAINER)) {
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.LOOT_CONTAINER)) {
|
||||||
return `${item._props.Grids![0]?._props.cellsH}X${item._props.Grids![0]?._props.cellsV}`;
|
return `${item._props.Grids[0]?._props.cellsH}X${item._props.Grids[0]?._props.cellsV}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add ammo caliber to conflicting weapons
|
// Add ammo caliber to conflicting weapons
|
||||||
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.WEAPON)) {
|
if (this.itemHelper.isOfBaseclass(item._id, BaseClasses.WEAPON)) {
|
||||||
const caliber = this.cleanCaliber(item._props.ammoCaliber!.toUpperCase());
|
const caliber = this.cleanCaliber(item._props.ammoCaliber.toUpperCase());
|
||||||
|
|
||||||
// If the item has a bracketed section at the end of its name, include that
|
// If the item has a bracketed section at the end of its name, include that
|
||||||
const itemNameBracketSuffix = itemName?.match(/\((.+?)\)$/);
|
const itemNameBracketSuffix = itemName?.match(/\((.+?)\)$/);
|
||||||
|
@ -21,6 +21,6 @@ export class AsyncQueue implements IAsyncQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When the command is ready, execute it
|
// When the command is ready, execute it
|
||||||
return this.commandsQueue.shift()!.cmd();
|
return this.commandsQueue.shift().cmd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ export class ImporterUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set all loadRecursive to be executed asynchronously
|
// set all loadRecursive to be executed asynchronously
|
||||||
const resEntries = Object.entries(result!);
|
const resEntries = Object.entries(result);
|
||||||
const resResolved = await Promise.all(resEntries.map((ent) => ent[1]));
|
const resResolved = await Promise.all(resEntries.map((ent) => ent[1]));
|
||||||
for (let resIdx = 0; resIdx < resResolved.length; resIdx++) {
|
for (let resIdx = 0; resIdx < resResolved.length; resIdx++) {
|
||||||
resEntries[resIdx][1] = resResolved[resIdx];
|
resEntries[resIdx][1] = resResolved[resIdx];
|
||||||
|
@ -19,21 +19,21 @@ export class RagfairOfferHolder {
|
|||||||
|
|
||||||
public getOfferById(id: string): IRagfairOffer | undefined {
|
public getOfferById(id: string): IRagfairOffer | undefined {
|
||||||
if (this.offersById.has(id)) {
|
if (this.offersById.has(id)) {
|
||||||
return this.offersById.get(id)!;
|
return this.offersById.get(id);
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getOffersByTemplate(templateId: string): Array<IRagfairOffer> | undefined {
|
public getOffersByTemplate(templateId: string): Array<IRagfairOffer> | undefined {
|
||||||
if (this.offersByTemplate.has(templateId)) {
|
if (this.offersByTemplate.has(templateId)) {
|
||||||
return [...this.offersByTemplate.get(templateId)!.values()];
|
return [...this.offersByTemplate.get(templateId).values()];
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getOffersByTrader(traderId: string): Array<IRagfairOffer> | undefined {
|
public getOffersByTrader(traderId: string): Array<IRagfairOffer> | undefined {
|
||||||
if (this.offersByTrader.has(traderId)) {
|
if (this.offersByTrader.has(traderId)) {
|
||||||
return [...this.offersByTrader.get(traderId)!.values()];
|
return [...this.offersByTrader.get(traderId).values()];
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -76,18 +76,18 @@ export class RagfairOfferHolder {
|
|||||||
if (this.offersById.has(offer._id)) {
|
if (this.offersById.has(offer._id)) {
|
||||||
this.offersById.delete(offer._id);
|
this.offersById.delete(offer._id);
|
||||||
if (this.offersByTrader.has(offer.user.id)) {
|
if (this.offersByTrader.has(offer.user.id)) {
|
||||||
this.offersByTrader.get(offer.user.id)!.delete(offer._id);
|
this.offersByTrader.get(offer.user.id).delete(offer._id);
|
||||||
// This was causing a memory leak, we need to make sure that we remove
|
// This was causing a memory leak, we need to make sure that we remove
|
||||||
// the user ID from the cached offers after they dont have anything else
|
// the user ID from the cached offers after they dont have anything else
|
||||||
// on the flea placed. We regenerate the ID for the NPC users, making it
|
// on the flea placed. We regenerate the ID for the NPC users, making it
|
||||||
// continously grow otherwise
|
// continously grow otherwise
|
||||||
if (this.offersByTrader.get(offer.user.id)!.size === 0) {
|
if (this.offersByTrader.get(offer.user.id).size === 0) {
|
||||||
this.offersByTrader.delete(offer.user.id);
|
this.offersByTrader.delete(offer.user.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.offersByTemplate.has(offer.items[0]._tpl)) {
|
if (this.offersByTemplate.has(offer.items[0]._tpl)) {
|
||||||
this.offersByTemplate.get(offer.items[0]._tpl)!.delete(offer._id);
|
this.offersByTemplate.get(offer.items[0]._tpl).delete(offer._id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,7 +100,7 @@ export class RagfairOfferHolder {
|
|||||||
|
|
||||||
public removeAllOffersByTrader(traderId: string): void {
|
public removeAllOffersByTrader(traderId: string): void {
|
||||||
if (this.offersByTrader.has(traderId)) {
|
if (this.offersByTrader.has(traderId)) {
|
||||||
this.removeOffers([...this.offersByTrader.get(traderId)!.values()]);
|
this.removeOffers([...this.offersByTrader.get(traderId).values()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ export class RagfairOfferHolder {
|
|||||||
|
|
||||||
protected addOfferByTemplates(template: string, offer: IRagfairOffer): void {
|
protected addOfferByTemplates(template: string, offer: IRagfairOffer): void {
|
||||||
if (this.offersByTemplate.has(template)) {
|
if (this.offersByTemplate.has(template)) {
|
||||||
this.offersByTemplate.get(template)!.set(offer._id, offer);
|
this.offersByTemplate.get(template).set(offer._id, offer);
|
||||||
} else {
|
} else {
|
||||||
const valueMapped = new Map<string, IRagfairOffer>();
|
const valueMapped = new Map<string, IRagfairOffer>();
|
||||||
valueMapped.set(offer._id, offer);
|
valueMapped.set(offer._id, offer);
|
||||||
@ -124,7 +124,7 @@ export class RagfairOfferHolder {
|
|||||||
|
|
||||||
protected addOfferByTrader(trader: string, offer: IRagfairOffer): void {
|
protected addOfferByTrader(trader: string, offer: IRagfairOffer): void {
|
||||||
if (this.offersByTrader.has(trader)) {
|
if (this.offersByTrader.has(trader)) {
|
||||||
this.offersByTrader.get(trader)!.set(offer._id, offer);
|
this.offersByTrader.get(trader).set(offer._id, offer);
|
||||||
} else {
|
} else {
|
||||||
const valueMapped = new Map<string, IRagfairOffer>();
|
const valueMapped = new Map<string, IRagfairOffer>();
|
||||||
valueMapped.set(offer._id, offer);
|
valueMapped.set(offer._id, offer);
|
||||||
|
@ -24,7 +24,6 @@ export class RecursiveCloner implements ICloner {
|
|||||||
// clone the object types
|
// clone the object types
|
||||||
if (typeOfObj === "object") {
|
if (typeOfObj === "object") {
|
||||||
if (Array.isArray(obj)) {
|
if (Array.isArray(obj)) {
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: used for clone
|
|
||||||
const objArr = obj as Array<any>;
|
const objArr = obj as Array<any>;
|
||||||
return objArr.map((v) => this.clone(v)) as T;
|
return objArr.map((v) => this.clone(v)) as T;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ export abstract class AbstractWinstonLogger implements ILogger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async success(data: string | Record<string, unknown>): Promise<void> {
|
public async success(data: string | Record<string, unknown>): Promise<void> {
|
||||||
const command: ICommand = { uuid: crypto.randomUUID(), cmd: async () => await this.logger.succ!(data) };
|
const command: ICommand = { uuid: crypto.randomUUID(), cmd: async () => await this.logger.succ(data) };
|
||||||
await this.asyncQueue.waitFor(command);
|
await this.asyncQueue.waitFor(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ import { container } from "tsyringe";
|
|||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
describe("LocaleService", () => {
|
describe("LocaleService", () => {
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
||||||
let localeService: any; // Using "any" to access private/protected methods without type errors.
|
let localeService: any; // Using "any" to access private/protected methods without type errors.
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
Loading…
Reference in New Issue
Block a user