From 7a16c7e998adfc15b725753879afddf9fd04b726 Mon Sep 17 00:00:00 2001 From: Dev Date: Thu, 13 Jul 2023 10:26:47 +0100 Subject: [PATCH] Improvements to skill points given after performing actions: Item crafting: HideoutManagement skillpoints give Intellect skillpoints given Examining item: Intellect given Repairing weapon/armor Intellect given Cleanup of hideouthelper + reordering of functions Flagged rewardSkillPoints() as dupe of PlayerService.incrementSkillLevel() Flagged incrementSkillLevel() as dupe of QuestHelper.rewardsSkillPoints() Need to decide which one wins Added nullguards to incrementSkillLevel() + added optional multiplication by global skillprogression rate Made it update last access timestamp --- project/src/controllers/HideoutController.ts | 7 +-- .../src/controllers/InventoryController.ts | 6 +++ project/src/controllers/RepairController.ts | 2 +- project/src/helpers/HideoutHelper.ts | 44 ++++++------------- project/src/helpers/QuestHelper.ts | 8 +++- project/src/services/PlayerService.ts | 38 +++++++++++----- project/src/services/RepairService.ts | 10 +++-- 7 files changed, 66 insertions(+), 49 deletions(-) diff --git a/project/src/controllers/HideoutController.ts b/project/src/controllers/HideoutController.ts index 3352e421..a39a90a9 100644 --- a/project/src/controllers/HideoutController.ts +++ b/project/src/controllers/HideoutController.ts @@ -583,7 +583,6 @@ export class HideoutController // check if the recipe is the same as the last one const area = pmcData.Hideout.Areas[recipe.areaType]; - if (area && request.recipeId !== area.lastRecipe) { // 1 point per craft upon the end of production for alternating between 2 different crafting recipes in the same module @@ -607,16 +606,18 @@ export class HideoutController { // manager Hideout skill // ? use a configuration variable for the value? - this.playerService.incrementSkillLevel(pmcData, SkillTypes.HIDEOUT_MANAGEMENT, 4); + const globals = this.databaseServer.getTables().globals; + this.playerService.incrementSkillLevel(pmcData, SkillTypes.HIDEOUT_MANAGEMENT, globals.config.SkillsSettings.HideoutManagement.SkillPointsPerCraft, true); //manager Crafting skill if (craftingExpAmount > 0) { this.playerService.incrementSkillLevel(pmcData, SkillTypes.CRAFTING, craftingExpAmount); + this.playerService.incrementSkillLevel(pmcData, SkillTypes.INTELLECT, 0.5 * (Math.round(craftingExpAmount / 15))); } area.lastRecipe = request.recipeId; counterHoursCrafting.value = hoursCrafting; - //delete production + // Delete production now it's complete delete pmcData.Hideout.Production[prodId]; }; diff --git a/project/src/controllers/InventoryController.ts b/project/src/controllers/InventoryController.ts index 62df3322..586354fa 100644 --- a/project/src/controllers/InventoryController.ts +++ b/project/src/controllers/InventoryController.ts @@ -6,6 +6,7 @@ import { ItemHelper } from "../helpers/ItemHelper"; import { PaymentHelper } from "../helpers/PaymentHelper"; import { PresetHelper } from "../helpers/PresetHelper"; import { ProfileHelper } from "../helpers/ProfileHelper"; +import { QuestHelper } from "../helpers/QuestHelper"; import { IPmcData } from "../models/eft/common/IPmcData"; import { Item } from "../models/eft/common/tables/IItem"; import { IAddItemRequestData } from "../models/eft/inventory/IAddItemRequestData"; @@ -40,6 +41,7 @@ import { } from "../models/eft/inventory/IOpenRandomLootContainerRequestData"; import { IItemEventRouterResponse } from "../models/eft/itemEvent/IItemEventRouterResponse"; import { BackendErrorCodes } from "../models/enums/BackendErrorCodes"; +import { SkillTypes } from "../models/enums/SkillTypes"; import { Traders } from "../models/enums/Traders"; import { ILogger } from "../models/spt/utils/ILogger"; import { EventOutputHolder } from "../routers/EventOutputHolder"; @@ -65,6 +67,7 @@ export class InventoryController @inject("FenceService") protected fenceService: FenceService, @inject("PresetHelper") protected presetHelper: PresetHelper, @inject("InventoryHelper") protected inventoryHelper: InventoryHelper, + @inject("QuestHelper") protected questHelper: QuestHelper, @inject("RagfairOfferService") protected ragfairOfferService: RagfairOfferService, @inject("ProfileHelper") protected profileHelper: ProfileHelper, @inject("PaymentHelper") protected paymentHelper: PaymentHelper, @@ -550,6 +553,9 @@ export class InventoryController pmcData.Info.Experience += item._props.ExamineExperience; pmcData.Encyclopedia[itemId] = true; + + // TODO: update this with correct calculation using values from globals json + this.questHelper.rewardSkillPoints(sessionID, pmcData, SkillTypes.INTELLECT, 0.5); } return this.eventOutputHolder.getOutput(sessionID); diff --git a/project/src/controllers/RepairController.ts b/project/src/controllers/RepairController.ts index c7ed7f3c..6985ed7f 100644 --- a/project/src/controllers/RepairController.ts +++ b/project/src/controllers/RepairController.ts @@ -85,7 +85,7 @@ export class RepairController // add repaired item to send to client output.profileChanges[sessionID].items.change.push(repairDetails.repairedItem); - // Add skill points for repairing weapons + // Add skill points for repairing items this.repairService.addRepairSkillPoints(sessionID, repairDetails, pmcData); return output; diff --git a/project/src/helpers/HideoutHelper.ts b/project/src/helpers/HideoutHelper.ts index 093acf05..c913c99b 100644 --- a/project/src/helpers/HideoutHelper.ts +++ b/project/src/helpers/HideoutHelper.ts @@ -445,8 +445,8 @@ export class HideoutHelper { const fuelItem = HideoutHelper.expeditionaryFuelTank; resourceValue = generatorArea.slots[i].item[0]._tpl === fuelItem - ? resourceValue = 60 - fuelDrainRate - : resourceValue = 100 - fuelDrainRate; + ? 60 - fuelDrainRate + : 100 - fuelDrainRate; pointsConsumed = fuelDrainRate; } else @@ -793,19 +793,11 @@ export class HideoutHelper const bitcoinProduction = this.databaseServer.getTables().hideout.production.find(p => p._id === HideoutHelper.bitcoinFarm); const productionSlots = bitcoinProduction?.productionLimitCount || 3; const hasManagementSkillSlots = this.hasEliteHideoutManagementSkill(pmcData); - const managementSlotsCount = this.getManagementSkillsSlots() || 2; + const managementSlotsCount = this.getBitcoinMinerContainerSlotSize() || 2; return productionSlots + (hasManagementSkillSlots ? managementSlotsCount : 0); } - /** - * Get a count of bitcoins player miner can hold - */ - protected getManagementSkillsSlots(): number - { - return this.databaseServer.getTables().globals.config.SkillsSettings.HideoutManagement.EliteSlots.BitcoinFarm.Container; - } - /** * Does profile have elite hideout management skill * @param pmcData Profile to look at @@ -816,6 +808,14 @@ export class HideoutHelper return this.getHideoutManagementSkill(pmcData)?.Progress >= 5100; // level 51+ } + /** + * Get a count of bitcoins player miner can hold + */ + protected getBitcoinMinerContainerSlotSize(): number + { + return this.databaseServer.getTables().globals.config.SkillsSettings.HideoutManagement.EliteSlots.BitcoinFarm.Container; + } + /** * Get the hideout management skill from player profile * @param pmcData Profile to look at @@ -823,7 +823,7 @@ export class HideoutHelper */ protected getHideoutManagementSkill(pmcData: IPmcData): Common { - return pmcData.Skills.Common.find(x => x.Id === "HideoutManagement"); + return pmcData.Skills.Common.find(x => x.Id === SkillTypes.HIDEOUT_MANAGEMENT); } protected getHideoutManagementConsumptionBonus(pmcData: IPmcData): number @@ -842,24 +842,6 @@ export class HideoutHelper return (roundedLevel * this.databaseServer.getTables().globals.config.SkillsSettings.HideoutManagement.ConsumptionReductionPerLevel) / 100; } - /** - * Get the crafting skill details from player profile - * @param pmcData Player profile - * @returns crafting skill, null if not found - */ - protected getCraftingSkill(pmcData: IPmcData): Common - { - for (const skill of pmcData.Skills.Common) - { - if (skill.Id === SkillTypes.CRAFTING) - { - return skill; - } - } - - return null; - } - /** * Adjust craft time based on crafting skill level found in player profile * @param pmcData Player profile @@ -868,7 +850,7 @@ export class HideoutHelper */ protected getCraftingSkillProductionTimeReduction(pmcData: IPmcData, productionTime: number): number { - const craftingSkill = this.getCraftingSkill(pmcData); + const craftingSkill = pmcData.Skills.Common.find(x=> x.Id === SkillTypes.CRAFTING); if (!craftingSkill) { return productionTime; diff --git a/project/src/helpers/QuestHelper.ts b/project/src/helpers/QuestHelper.ts index a8811d43..fa1399f8 100644 --- a/project/src/helpers/QuestHelper.ts +++ b/project/src/helpers/QuestHelper.ts @@ -128,6 +128,7 @@ export class QuestHelper /** * Increase skill points of a skill on player profile + * Dupe of PlayerService.incrementSkillLevel() * @param sessionID Session id * @param pmcData Player profile * @param skillName Name of skill to increase skill points of @@ -136,7 +137,6 @@ export class QuestHelper public rewardSkillPoints(sessionID: string, pmcData: IPmcData, skillName: string, progressAmount: number): void { const indexOfSkillToUpdate = pmcData.Skills.Common.findIndex(s => s.Id === skillName); - if (indexOfSkillToUpdate === -1) { this.logger.error(this.localisationService.getText("quest-no_skill_found", skillName)); @@ -145,6 +145,12 @@ export class QuestHelper } const profileSkill = pmcData.Skills.Common[indexOfSkillToUpdate]; + if (!profileSkill) + { + this.logger.error(this.localisationService.getText("quest-no_skill_found", skillName)); + + return; + } profileSkill.Progress += progressAmount; profileSkill.LastAccess = this.timeUtil.getTimestamp(); diff --git a/project/src/services/PlayerService.ts b/project/src/services/PlayerService.ts index 255658c5..be228656 100644 --- a/project/src/services/PlayerService.ts +++ b/project/src/services/PlayerService.ts @@ -1,9 +1,9 @@ import { inject, injectable } from "tsyringe"; import { IPmcData } from "../models/eft/common/IPmcData"; -import { Common } from "../models/eft/common/tables/IBotBase"; import { ILogger } from "../models/spt/utils/ILogger"; import { DatabaseServer } from "../servers/DatabaseServer"; +import { TimeUtil } from "../utils/TimeUtil"; import { LocalisationService } from "./LocalisationService"; @injectable() @@ -12,33 +12,51 @@ export class PlayerService constructor( @inject("WinstonLogger") protected logger: ILogger, + @inject("TimeUtil") protected timeUtil: TimeUtil, @inject("LocalisationService") protected localisationService: LocalisationService, @inject("DatabaseServer") protected databaseServer: DatabaseServer ) { } /** - * increases the profile skill and updates any output - * @param {Object} pmcData - * @param {String} skillName - * @param {Number} amount + * Dupe of QuestHelper.rewardsSkillPoints() + * Add xp to a player skill + * @param pmcData Player profile + * @param skillName Name of skill to increment + * @param amount Amount of skill points to add to skill + * @param useSkillProgressRateMultipler Skills are multiplied by a value in globals, default is off to maintain compatibility with legacy code */ - public incrementSkillLevel(pmcData: IPmcData, skillName: string, amount: number): void + public incrementSkillLevel(pmcData: IPmcData, skillName: string, amount: number, useSkillProgressRateMultipler = false): void { - const profileSkill: Common = pmcData.Skills.Common.find(skill => skill.Id === skillName); - if (!amount || amount < 0) { this.logger.error(this.localisationService.getText("player-attempt_to_increment_skill_with_negative_value", skillName)); return; } + const profileSkill = pmcData.Skills.Common.find(skill => skill.Id === skillName); + if (!profileSkill) + { + this.logger.error(this.localisationService.getText("quest-no_skill_found", skillName)); + + return; + } + + if (useSkillProgressRateMultipler) + { + const globals = this.databaseServer.getTables().globals; + const skillProgressRate = globals.config.SkillsSettings.SkillProgressRate; + amount = skillProgressRate * amount; + } + profileSkill.Progress += amount; + profileSkill.LastAccess = this.timeUtil.getTimestamp(); } /** - * @param {Object} pmcData - * @returns number + * Get level of player + * @param pmcData Player profile + * @returns Level of player */ public calculateLevel(pmcData: IPmcData): number { diff --git a/project/src/services/RepairService.ts b/project/src/services/RepairService.ts index af3642cb..75ed7bf4 100644 --- a/project/src/services/RepairService.ts +++ b/project/src/services/RepairService.ts @@ -15,6 +15,7 @@ import { RepairItem } from "../models/eft/repair/ITraderRepairActionDataRequest" import { IProcessBuyTradeRequestData } from "../models/eft/trade/IProcessBuyTradeRequestData"; import { BaseClasses } from "../models/enums/BaseClasses"; import { ConfigTypes } from "../models/enums/ConfigTypes"; +import { SkillTypes } from "../models/enums/SkillTypes"; import { BonusSettings, IRepairConfig } from "../models/spt/config/IRepairConfig"; import { ILogger } from "../models/spt/utils/ILogger"; import { ConfigServer } from "../servers/ConfigServer"; @@ -156,15 +157,18 @@ export class RepairService if (!itemDetails[0]) { this.logger.error(`Unable to find item ${repairDetails.repairedItem._tpl} in items db, cannot add skill points`); + return; } const isHeavyArmor = itemDetails[1]._props.ArmorType === "Heavy"; - const skillToLevel = (isHeavyArmor) ? "HeavyVests" : "LightVests"; - const pointsToAddToSkill = repairDetails.repairAmount * this.repairConfig.armorKitSkillPointGainPerRepairPointMultiplier; + const vestSkillToLevel = (isHeavyArmor) ? "HeavyVests" : "LightVests"; + const pointsToAddToVestSkill = repairDetails.repairAmount * this.repairConfig.armorKitSkillPointGainPerRepairPointMultiplier; - this.questHelper.rewardSkillPoints(sessionId, pmcData, skillToLevel, pointsToAddToSkill); + this.questHelper.rewardSkillPoints(sessionId, pmcData, vestSkillToLevel, pointsToAddToVestSkill); } + + this.questHelper.rewardSkillPoints(sessionId, pmcData, SkillTypes.INTELLECT, repairDetails.repairAmount / 10); } /**