From e5324540534d2c59b5c88f0dc4e7d3a69a06264c Mon Sep 17 00:00:00 2001 From: Chomp Date: Sat, 7 Dec 2024 15:02:59 +0000 Subject: [PATCH] Updated types and readme to 3.10.2 --- README.md | 2 +- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../13AddTrader/types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../1LogToConsole/types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../24WebSocket/types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../2EditDatabase/types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../7OnLoadHook/types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../8OnUpdateHook/types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- .../types/controllers/ProfileController.d.ts | 3 + .../generators/BotEquipmentModGenerator.d.ts | 3 +- .../generators/RagfairOfferGenerator.d.ts | 4 +- .../types/helpers/ProfileHelper.d.ts | 6 + .../types/helpers/QuestHelper.d.ts | 19 +- .../types/helpers/RagfairOfferHelper.d.ts | 27 ++- .../types/helpers/TraderAssortHelper.d.ts | 14 +- .../models/eft/common/tables/IBotBase.d.ts | 2 +- .../types/models/eft/profile/ISptProfile.d.ts | 7 + .../enums/hideout/CircleRewardType.d.ts | 4 + .../models/spt/config/IHideoutConfig.d.ts | 21 ++- .../models/spt/config/ITraderConfig.d.ts | 2 +- .../spt/hideout/ICircleCraftDetails.d.ts | 8 + .../services/CircleOfCultistService.d.ts | 100 +++++++--- .../types/services/ProfileFixerService.d.ts | 6 + .../types/services/SeasonalEventService.d.ts | 6 + .../utils/DatabaseDecompressionUtil.d.ts | 38 ---- .../9RouterHooks/types/utils/RandomUtil.d.ts | 174 ++++++++++++++---- 505 files changed, 8597 insertions(+), 3837 deletions(-) create mode 100644 TypeScript/10ScopesAndTypes/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/10ScopesAndTypes/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/10ScopesAndTypes/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/11BundleLoadingSample/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/11BundleLoadingSample/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/11BundleLoadingSample/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/12ClassExtensionOverride/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/12ClassExtensionOverride/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/12ClassExtensionOverride/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/13.1AddTraderWithAssortJSON/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/13.1AddTraderWithAssortJSON/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/13AddTrader/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/13AddTrader/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/13AddTrader/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/14AfterDBLoadHook/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/14AfterDBLoadHook/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/14AfterDBLoadHook/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/15HttpListenerExample/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/15HttpListenerExample/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/15HttpListenerExample/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/16ImporterUtil/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/16ImporterUtil/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/16ImporterUtil/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/17AsyncImporterWithDependency1/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/17AsyncImporterWithDependency1/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/17AsyncImporterWithDependency1/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/17AsyncImporterWithDependency2/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/17AsyncImporterWithDependency2/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/17AsyncImporterWithDependency2/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/18.1CustomItemServiceLootBox/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/18.1CustomItemServiceLootBox/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/18.1CustomItemServiceLootBox/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/18CustomItemService/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/18CustomItemService/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/18CustomItemService/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/19UseExternalLibraries/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/19UseExternalLibraries/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/19UseExternalLibraries/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/1LogToConsole/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/1LogToConsole/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/1LogToConsole/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/20CustomChatBot/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/20CustomChatBot/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/20CustomChatBot/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/21CustomCommandoCommand/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/21CustomCommandoCommand/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/21CustomCommandoCommand/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/22CustomSptCommand/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/22CustomSptCommand/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/22CustomSptCommand/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/23CustomAbstractChatBot/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/23CustomAbstractChatBot/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/23CustomAbstractChatBot/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/24WebSocket/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/24WebSocket/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/24WebSocket/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/2EditDatabase/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/2EditDatabase/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/2EditDatabase/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/3GetSptConfigFile/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/3GetSptConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/3GetSptConfigFile/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/4UseACustomConfigFile/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/4UseACustomConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/4UseACustomConfigFile/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/5ReplaceMethod/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/5ReplaceMethod/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/5ReplaceMethod/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/6ReferenceAnotherClass/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/6ReferenceAnotherClass/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/6ReferenceAnotherClass/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/7OnLoadHook/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/7OnLoadHook/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/7OnLoadHook/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/8OnUpdateHook/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/8OnUpdateHook/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/8OnUpdateHook/types/utils/DatabaseDecompressionUtil.d.ts create mode 100644 TypeScript/9RouterHooks/types/models/enums/hideout/CircleRewardType.d.ts create mode 100644 TypeScript/9RouterHooks/types/models/spt/hideout/ICircleCraftDetails.d.ts delete mode 100644 TypeScript/9RouterHooks/types/utils/DatabaseDecompressionUtil.d.ts diff --git a/README.md b/README.md index d816071..9e5aacd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Mod examples for v3.10.1 +# Mod examples for v3.10.2 A collection of example mods that perform typical actions in SPT diff --git a/TypeScript/10ScopesAndTypes/types/controllers/ProfileController.d.ts b/TypeScript/10ScopesAndTypes/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/10ScopesAndTypes/types/controllers/ProfileController.d.ts +++ b/TypeScript/10ScopesAndTypes/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/10ScopesAndTypes/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/10ScopesAndTypes/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/10ScopesAndTypes/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/10ScopesAndTypes/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/10ScopesAndTypes/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/10ScopesAndTypes/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/10ScopesAndTypes/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/10ScopesAndTypes/types/helpers/ProfileHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/10ScopesAndTypes/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/10ScopesAndTypes/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts +++ b/TypeScript/10ScopesAndTypes/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/10ScopesAndTypes/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/10ScopesAndTypes/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/10ScopesAndTypes/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/10ScopesAndTypes/types/helpers/TraderAssortHelper.d.ts b/TypeScript/10ScopesAndTypes/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/10ScopesAndTypes/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/10ScopesAndTypes/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/10ScopesAndTypes/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/10ScopesAndTypes/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/10ScopesAndTypes/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/10ScopesAndTypes/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/10ScopesAndTypes/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/10ScopesAndTypes/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/10ScopesAndTypes/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/10ScopesAndTypes/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/10ScopesAndTypes/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/10ScopesAndTypes/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/10ScopesAndTypes/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/10ScopesAndTypes/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/10ScopesAndTypes/types/services/CircleOfCultistService.d.ts b/TypeScript/10ScopesAndTypes/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/10ScopesAndTypes/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/10ScopesAndTypes/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts b/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts +++ b/TypeScript/10ScopesAndTypes/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/10ScopesAndTypes/types/services/SeasonalEventService.d.ts b/TypeScript/10ScopesAndTypes/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/10ScopesAndTypes/types/services/SeasonalEventService.d.ts +++ b/TypeScript/10ScopesAndTypes/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/10ScopesAndTypes/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/10ScopesAndTypes/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/10ScopesAndTypes/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts b/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts +++ b/TypeScript/10ScopesAndTypes/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/11BundleLoadingSample/types/controllers/ProfileController.d.ts b/TypeScript/11BundleLoadingSample/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/11BundleLoadingSample/types/controllers/ProfileController.d.ts +++ b/TypeScript/11BundleLoadingSample/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/11BundleLoadingSample/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/11BundleLoadingSample/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/11BundleLoadingSample/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/11BundleLoadingSample/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/11BundleLoadingSample/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/11BundleLoadingSample/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/11BundleLoadingSample/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/11BundleLoadingSample/types/helpers/ProfileHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/11BundleLoadingSample/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/11BundleLoadingSample/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts +++ b/TypeScript/11BundleLoadingSample/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/11BundleLoadingSample/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/11BundleLoadingSample/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/11BundleLoadingSample/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/11BundleLoadingSample/types/helpers/TraderAssortHelper.d.ts b/TypeScript/11BundleLoadingSample/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/11BundleLoadingSample/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/11BundleLoadingSample/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/11BundleLoadingSample/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/11BundleLoadingSample/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/11BundleLoadingSample/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/11BundleLoadingSample/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/11BundleLoadingSample/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/11BundleLoadingSample/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/11BundleLoadingSample/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/11BundleLoadingSample/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/11BundleLoadingSample/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/11BundleLoadingSample/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/11BundleLoadingSample/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/11BundleLoadingSample/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/11BundleLoadingSample/types/services/CircleOfCultistService.d.ts b/TypeScript/11BundleLoadingSample/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/11BundleLoadingSample/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/11BundleLoadingSample/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts b/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts +++ b/TypeScript/11BundleLoadingSample/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/11BundleLoadingSample/types/services/SeasonalEventService.d.ts b/TypeScript/11BundleLoadingSample/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/11BundleLoadingSample/types/services/SeasonalEventService.d.ts +++ b/TypeScript/11BundleLoadingSample/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/11BundleLoadingSample/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/11BundleLoadingSample/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/11BundleLoadingSample/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts b/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts +++ b/TypeScript/11BundleLoadingSample/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/12ClassExtensionOverride/types/controllers/ProfileController.d.ts b/TypeScript/12ClassExtensionOverride/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/12ClassExtensionOverride/types/controllers/ProfileController.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/12ClassExtensionOverride/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/12ClassExtensionOverride/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/12ClassExtensionOverride/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/12ClassExtensionOverride/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/12ClassExtensionOverride/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/ProfileHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/12ClassExtensionOverride/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/12ClassExtensionOverride/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/12ClassExtensionOverride/types/helpers/TraderAssortHelper.d.ts b/TypeScript/12ClassExtensionOverride/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/12ClassExtensionOverride/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/12ClassExtensionOverride/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/12ClassExtensionOverride/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/12ClassExtensionOverride/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/12ClassExtensionOverride/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/12ClassExtensionOverride/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/12ClassExtensionOverride/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/12ClassExtensionOverride/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/12ClassExtensionOverride/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/12ClassExtensionOverride/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/12ClassExtensionOverride/types/services/CircleOfCultistService.d.ts b/TypeScript/12ClassExtensionOverride/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/12ClassExtensionOverride/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts b/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/12ClassExtensionOverride/types/services/SeasonalEventService.d.ts b/TypeScript/12ClassExtensionOverride/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/12ClassExtensionOverride/types/services/SeasonalEventService.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/12ClassExtensionOverride/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/12ClassExtensionOverride/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/12ClassExtensionOverride/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts b/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts +++ b/TypeScript/12ClassExtensionOverride/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/controllers/ProfileController.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/controllers/ProfileController.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/ProfileHelper.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/QuestHelper.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/QuestHelper.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/TraderAssortHelper.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/services/CircleOfCultistService.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/services/ProfileFixerService.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/services/ProfileFixerService.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/services/SeasonalEventService.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/services/SeasonalEventService.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/13.1AddTraderWithAssortJSON/types/utils/RandomUtil.d.ts b/TypeScript/13.1AddTraderWithAssortJSON/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/13.1AddTraderWithAssortJSON/types/utils/RandomUtil.d.ts +++ b/TypeScript/13.1AddTraderWithAssortJSON/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/13AddTrader/types/controllers/ProfileController.d.ts b/TypeScript/13AddTrader/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/13AddTrader/types/controllers/ProfileController.d.ts +++ b/TypeScript/13AddTrader/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/13AddTrader/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/13AddTrader/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/13AddTrader/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/13AddTrader/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/13AddTrader/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/13AddTrader/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/13AddTrader/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/13AddTrader/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/13AddTrader/types/helpers/ProfileHelper.d.ts b/TypeScript/13AddTrader/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/13AddTrader/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/13AddTrader/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts b/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts +++ b/TypeScript/13AddTrader/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/13AddTrader/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/13AddTrader/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/13AddTrader/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/13AddTrader/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/13AddTrader/types/helpers/TraderAssortHelper.d.ts b/TypeScript/13AddTrader/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/13AddTrader/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/13AddTrader/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/13AddTrader/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/13AddTrader/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/13AddTrader/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/13AddTrader/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/13AddTrader/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/13AddTrader/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/13AddTrader/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/13AddTrader/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/13AddTrader/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/13AddTrader/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/13AddTrader/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/13AddTrader/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/13AddTrader/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/13AddTrader/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/13AddTrader/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/13AddTrader/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/13AddTrader/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/13AddTrader/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/13AddTrader/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/13AddTrader/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/13AddTrader/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/13AddTrader/types/services/CircleOfCultistService.d.ts b/TypeScript/13AddTrader/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/13AddTrader/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/13AddTrader/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts b/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts +++ b/TypeScript/13AddTrader/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/13AddTrader/types/services/SeasonalEventService.d.ts b/TypeScript/13AddTrader/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/13AddTrader/types/services/SeasonalEventService.d.ts +++ b/TypeScript/13AddTrader/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/13AddTrader/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/13AddTrader/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/13AddTrader/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts b/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts +++ b/TypeScript/13AddTrader/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/14AfterDBLoadHook/types/controllers/ProfileController.d.ts b/TypeScript/14AfterDBLoadHook/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/14AfterDBLoadHook/types/controllers/ProfileController.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/14AfterDBLoadHook/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/14AfterDBLoadHook/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/14AfterDBLoadHook/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/14AfterDBLoadHook/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/14AfterDBLoadHook/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/ProfileHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/14AfterDBLoadHook/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/14AfterDBLoadHook/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/14AfterDBLoadHook/types/helpers/TraderAssortHelper.d.ts b/TypeScript/14AfterDBLoadHook/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/14AfterDBLoadHook/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/14AfterDBLoadHook/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/14AfterDBLoadHook/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/14AfterDBLoadHook/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/14AfterDBLoadHook/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/14AfterDBLoadHook/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/14AfterDBLoadHook/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/14AfterDBLoadHook/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/14AfterDBLoadHook/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/14AfterDBLoadHook/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/14AfterDBLoadHook/types/services/CircleOfCultistService.d.ts b/TypeScript/14AfterDBLoadHook/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/14AfterDBLoadHook/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts b/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/14AfterDBLoadHook/types/services/SeasonalEventService.d.ts b/TypeScript/14AfterDBLoadHook/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/14AfterDBLoadHook/types/services/SeasonalEventService.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/14AfterDBLoadHook/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/14AfterDBLoadHook/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/14AfterDBLoadHook/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts b/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts +++ b/TypeScript/14AfterDBLoadHook/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/15HttpListenerExample/types/controllers/ProfileController.d.ts b/TypeScript/15HttpListenerExample/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/15HttpListenerExample/types/controllers/ProfileController.d.ts +++ b/TypeScript/15HttpListenerExample/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/15HttpListenerExample/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/15HttpListenerExample/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/15HttpListenerExample/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/15HttpListenerExample/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/15HttpListenerExample/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/15HttpListenerExample/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/15HttpListenerExample/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/15HttpListenerExample/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/15HttpListenerExample/types/helpers/ProfileHelper.d.ts b/TypeScript/15HttpListenerExample/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/15HttpListenerExample/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/15HttpListenerExample/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/15HttpListenerExample/types/helpers/QuestHelper.d.ts b/TypeScript/15HttpListenerExample/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/15HttpListenerExample/types/helpers/QuestHelper.d.ts +++ b/TypeScript/15HttpListenerExample/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/15HttpListenerExample/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/15HttpListenerExample/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/15HttpListenerExample/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/15HttpListenerExample/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/15HttpListenerExample/types/helpers/TraderAssortHelper.d.ts b/TypeScript/15HttpListenerExample/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/15HttpListenerExample/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/15HttpListenerExample/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/15HttpListenerExample/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/15HttpListenerExample/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/15HttpListenerExample/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/15HttpListenerExample/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/15HttpListenerExample/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/15HttpListenerExample/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/15HttpListenerExample/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/15HttpListenerExample/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/15HttpListenerExample/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/15HttpListenerExample/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/15HttpListenerExample/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/15HttpListenerExample/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/15HttpListenerExample/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/15HttpListenerExample/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/15HttpListenerExample/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/15HttpListenerExample/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/15HttpListenerExample/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/15HttpListenerExample/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/15HttpListenerExample/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/15HttpListenerExample/types/services/CircleOfCultistService.d.ts b/TypeScript/15HttpListenerExample/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/15HttpListenerExample/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/15HttpListenerExample/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/15HttpListenerExample/types/services/ProfileFixerService.d.ts b/TypeScript/15HttpListenerExample/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/15HttpListenerExample/types/services/ProfileFixerService.d.ts +++ b/TypeScript/15HttpListenerExample/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/15HttpListenerExample/types/services/SeasonalEventService.d.ts b/TypeScript/15HttpListenerExample/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/15HttpListenerExample/types/services/SeasonalEventService.d.ts +++ b/TypeScript/15HttpListenerExample/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/15HttpListenerExample/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/15HttpListenerExample/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/15HttpListenerExample/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/15HttpListenerExample/types/utils/RandomUtil.d.ts b/TypeScript/15HttpListenerExample/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/15HttpListenerExample/types/utils/RandomUtil.d.ts +++ b/TypeScript/15HttpListenerExample/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/16ImporterUtil/types/controllers/ProfileController.d.ts b/TypeScript/16ImporterUtil/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/16ImporterUtil/types/controllers/ProfileController.d.ts +++ b/TypeScript/16ImporterUtil/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/16ImporterUtil/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/16ImporterUtil/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/16ImporterUtil/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/16ImporterUtil/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/16ImporterUtil/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/16ImporterUtil/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/16ImporterUtil/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/16ImporterUtil/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/16ImporterUtil/types/helpers/ProfileHelper.d.ts b/TypeScript/16ImporterUtil/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/16ImporterUtil/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/16ImporterUtil/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/16ImporterUtil/types/helpers/QuestHelper.d.ts b/TypeScript/16ImporterUtil/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/16ImporterUtil/types/helpers/QuestHelper.d.ts +++ b/TypeScript/16ImporterUtil/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/16ImporterUtil/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/16ImporterUtil/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/16ImporterUtil/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/16ImporterUtil/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/16ImporterUtil/types/helpers/TraderAssortHelper.d.ts b/TypeScript/16ImporterUtil/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/16ImporterUtil/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/16ImporterUtil/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/16ImporterUtil/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/16ImporterUtil/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/16ImporterUtil/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/16ImporterUtil/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/16ImporterUtil/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/16ImporterUtil/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/16ImporterUtil/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/16ImporterUtil/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/16ImporterUtil/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/16ImporterUtil/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/16ImporterUtil/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/16ImporterUtil/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/16ImporterUtil/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/16ImporterUtil/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/16ImporterUtil/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/16ImporterUtil/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/16ImporterUtil/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/16ImporterUtil/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/16ImporterUtil/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/16ImporterUtil/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/16ImporterUtil/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/16ImporterUtil/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/16ImporterUtil/types/services/CircleOfCultistService.d.ts b/TypeScript/16ImporterUtil/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/16ImporterUtil/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/16ImporterUtil/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/16ImporterUtil/types/services/ProfileFixerService.d.ts b/TypeScript/16ImporterUtil/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/16ImporterUtil/types/services/ProfileFixerService.d.ts +++ b/TypeScript/16ImporterUtil/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/16ImporterUtil/types/services/SeasonalEventService.d.ts b/TypeScript/16ImporterUtil/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/16ImporterUtil/types/services/SeasonalEventService.d.ts +++ b/TypeScript/16ImporterUtil/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/16ImporterUtil/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/16ImporterUtil/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/16ImporterUtil/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/16ImporterUtil/types/utils/RandomUtil.d.ts b/TypeScript/16ImporterUtil/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/16ImporterUtil/types/utils/RandomUtil.d.ts +++ b/TypeScript/16ImporterUtil/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/17AsyncImporterWithDependency1/types/controllers/ProfileController.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/controllers/ProfileController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/17AsyncImporterWithDependency1/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/17AsyncImporterWithDependency1/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/17AsyncImporterWithDependency1/types/helpers/ProfileHelper.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/17AsyncImporterWithDependency1/types/helpers/QuestHelper.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/helpers/QuestHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/17AsyncImporterWithDependency1/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/17AsyncImporterWithDependency1/types/helpers/TraderAssortHelper.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/17AsyncImporterWithDependency1/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency1/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/17AsyncImporterWithDependency1/types/services/CircleOfCultistService.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/17AsyncImporterWithDependency1/types/services/ProfileFixerService.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/services/ProfileFixerService.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/17AsyncImporterWithDependency1/types/services/SeasonalEventService.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/services/SeasonalEventService.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/17AsyncImporterWithDependency1/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/17AsyncImporterWithDependency1/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/17AsyncImporterWithDependency1/types/utils/RandomUtil.d.ts b/TypeScript/17AsyncImporterWithDependency1/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/17AsyncImporterWithDependency1/types/utils/RandomUtil.d.ts +++ b/TypeScript/17AsyncImporterWithDependency1/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/17AsyncImporterWithDependency2/types/controllers/ProfileController.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/controllers/ProfileController.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/17AsyncImporterWithDependency2/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/17AsyncImporterWithDependency2/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/17AsyncImporterWithDependency2/types/helpers/ProfileHelper.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/17AsyncImporterWithDependency2/types/helpers/QuestHelper.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/helpers/QuestHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/17AsyncImporterWithDependency2/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/17AsyncImporterWithDependency2/types/helpers/TraderAssortHelper.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/17AsyncImporterWithDependency2/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/17AsyncImporterWithDependency2/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/17AsyncImporterWithDependency2/types/services/CircleOfCultistService.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/17AsyncImporterWithDependency2/types/services/ProfileFixerService.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/services/ProfileFixerService.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/17AsyncImporterWithDependency2/types/services/SeasonalEventService.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/services/SeasonalEventService.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/17AsyncImporterWithDependency2/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/17AsyncImporterWithDependency2/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/17AsyncImporterWithDependency2/types/utils/RandomUtil.d.ts b/TypeScript/17AsyncImporterWithDependency2/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/17AsyncImporterWithDependency2/types/utils/RandomUtil.d.ts +++ b/TypeScript/17AsyncImporterWithDependency2/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/controllers/ProfileController.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/controllers/ProfileController.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/helpers/ProfileHelper.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/helpers/QuestHelper.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/helpers/QuestHelper.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/helpers/TraderAssortHelper.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/18.1CustomItemServiceLootBox/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/18.1CustomItemServiceLootBox/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/services/CircleOfCultistService.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/services/ProfileFixerService.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/services/ProfileFixerService.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/services/SeasonalEventService.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/services/SeasonalEventService.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/18.1CustomItemServiceLootBox/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/18.1CustomItemServiceLootBox/types/utils/RandomUtil.d.ts b/TypeScript/18.1CustomItemServiceLootBox/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/18.1CustomItemServiceLootBox/types/utils/RandomUtil.d.ts +++ b/TypeScript/18.1CustomItemServiceLootBox/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/18CustomItemService/types/controllers/ProfileController.d.ts b/TypeScript/18CustomItemService/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/18CustomItemService/types/controllers/ProfileController.d.ts +++ b/TypeScript/18CustomItemService/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/18CustomItemService/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/18CustomItemService/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/18CustomItemService/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/18CustomItemService/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/18CustomItemService/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/18CustomItemService/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/18CustomItemService/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/18CustomItemService/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/18CustomItemService/types/helpers/ProfileHelper.d.ts b/TypeScript/18CustomItemService/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/18CustomItemService/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/18CustomItemService/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/18CustomItemService/types/helpers/QuestHelper.d.ts b/TypeScript/18CustomItemService/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/18CustomItemService/types/helpers/QuestHelper.d.ts +++ b/TypeScript/18CustomItemService/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/18CustomItemService/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/18CustomItemService/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/18CustomItemService/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/18CustomItemService/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/18CustomItemService/types/helpers/TraderAssortHelper.d.ts b/TypeScript/18CustomItemService/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/18CustomItemService/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/18CustomItemService/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/18CustomItemService/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/18CustomItemService/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/18CustomItemService/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/18CustomItemService/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/18CustomItemService/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/18CustomItemService/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/18CustomItemService/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/18CustomItemService/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/18CustomItemService/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/18CustomItemService/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/18CustomItemService/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/18CustomItemService/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/18CustomItemService/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/18CustomItemService/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/18CustomItemService/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/18CustomItemService/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/18CustomItemService/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/18CustomItemService/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/18CustomItemService/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/18CustomItemService/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/18CustomItemService/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/18CustomItemService/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/18CustomItemService/types/services/CircleOfCultistService.d.ts b/TypeScript/18CustomItemService/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/18CustomItemService/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/18CustomItemService/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/18CustomItemService/types/services/ProfileFixerService.d.ts b/TypeScript/18CustomItemService/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/18CustomItemService/types/services/ProfileFixerService.d.ts +++ b/TypeScript/18CustomItemService/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/18CustomItemService/types/services/SeasonalEventService.d.ts b/TypeScript/18CustomItemService/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/18CustomItemService/types/services/SeasonalEventService.d.ts +++ b/TypeScript/18CustomItemService/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/18CustomItemService/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/18CustomItemService/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/18CustomItemService/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/18CustomItemService/types/utils/RandomUtil.d.ts b/TypeScript/18CustomItemService/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/18CustomItemService/types/utils/RandomUtil.d.ts +++ b/TypeScript/18CustomItemService/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/19UseExternalLibraries/types/controllers/ProfileController.d.ts b/TypeScript/19UseExternalLibraries/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/19UseExternalLibraries/types/controllers/ProfileController.d.ts +++ b/TypeScript/19UseExternalLibraries/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/19UseExternalLibraries/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/19UseExternalLibraries/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/19UseExternalLibraries/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/19UseExternalLibraries/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/19UseExternalLibraries/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/19UseExternalLibraries/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/19UseExternalLibraries/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/19UseExternalLibraries/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/19UseExternalLibraries/types/helpers/ProfileHelper.d.ts b/TypeScript/19UseExternalLibraries/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/19UseExternalLibraries/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/19UseExternalLibraries/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/19UseExternalLibraries/types/helpers/QuestHelper.d.ts b/TypeScript/19UseExternalLibraries/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/19UseExternalLibraries/types/helpers/QuestHelper.d.ts +++ b/TypeScript/19UseExternalLibraries/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/19UseExternalLibraries/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/19UseExternalLibraries/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/19UseExternalLibraries/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/19UseExternalLibraries/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/19UseExternalLibraries/types/helpers/TraderAssortHelper.d.ts b/TypeScript/19UseExternalLibraries/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/19UseExternalLibraries/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/19UseExternalLibraries/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/19UseExternalLibraries/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/19UseExternalLibraries/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/19UseExternalLibraries/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/19UseExternalLibraries/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/19UseExternalLibraries/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/19UseExternalLibraries/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/19UseExternalLibraries/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/19UseExternalLibraries/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/19UseExternalLibraries/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/19UseExternalLibraries/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/19UseExternalLibraries/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/19UseExternalLibraries/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/19UseExternalLibraries/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/19UseExternalLibraries/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/19UseExternalLibraries/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/19UseExternalLibraries/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/19UseExternalLibraries/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/19UseExternalLibraries/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/19UseExternalLibraries/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/19UseExternalLibraries/types/services/CircleOfCultistService.d.ts b/TypeScript/19UseExternalLibraries/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/19UseExternalLibraries/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/19UseExternalLibraries/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/19UseExternalLibraries/types/services/ProfileFixerService.d.ts b/TypeScript/19UseExternalLibraries/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/19UseExternalLibraries/types/services/ProfileFixerService.d.ts +++ b/TypeScript/19UseExternalLibraries/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/19UseExternalLibraries/types/services/SeasonalEventService.d.ts b/TypeScript/19UseExternalLibraries/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/19UseExternalLibraries/types/services/SeasonalEventService.d.ts +++ b/TypeScript/19UseExternalLibraries/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/19UseExternalLibraries/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/19UseExternalLibraries/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/19UseExternalLibraries/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/19UseExternalLibraries/types/utils/RandomUtil.d.ts b/TypeScript/19UseExternalLibraries/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/19UseExternalLibraries/types/utils/RandomUtil.d.ts +++ b/TypeScript/19UseExternalLibraries/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/1LogToConsole/types/controllers/ProfileController.d.ts b/TypeScript/1LogToConsole/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/1LogToConsole/types/controllers/ProfileController.d.ts +++ b/TypeScript/1LogToConsole/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/1LogToConsole/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/1LogToConsole/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/1LogToConsole/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/1LogToConsole/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/1LogToConsole/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/1LogToConsole/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/1LogToConsole/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/1LogToConsole/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/1LogToConsole/types/helpers/ProfileHelper.d.ts b/TypeScript/1LogToConsole/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/1LogToConsole/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/1LogToConsole/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/1LogToConsole/types/helpers/QuestHelper.d.ts b/TypeScript/1LogToConsole/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/1LogToConsole/types/helpers/QuestHelper.d.ts +++ b/TypeScript/1LogToConsole/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/1LogToConsole/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/1LogToConsole/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/1LogToConsole/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/1LogToConsole/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/1LogToConsole/types/helpers/TraderAssortHelper.d.ts b/TypeScript/1LogToConsole/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/1LogToConsole/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/1LogToConsole/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/1LogToConsole/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/1LogToConsole/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/1LogToConsole/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/1LogToConsole/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/1LogToConsole/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/1LogToConsole/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/1LogToConsole/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/1LogToConsole/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/1LogToConsole/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/1LogToConsole/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/1LogToConsole/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/1LogToConsole/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/1LogToConsole/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/1LogToConsole/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/1LogToConsole/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/1LogToConsole/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/1LogToConsole/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/1LogToConsole/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/1LogToConsole/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/1LogToConsole/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/1LogToConsole/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/1LogToConsole/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/1LogToConsole/types/services/CircleOfCultistService.d.ts b/TypeScript/1LogToConsole/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/1LogToConsole/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/1LogToConsole/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/1LogToConsole/types/services/ProfileFixerService.d.ts b/TypeScript/1LogToConsole/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/1LogToConsole/types/services/ProfileFixerService.d.ts +++ b/TypeScript/1LogToConsole/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/1LogToConsole/types/services/SeasonalEventService.d.ts b/TypeScript/1LogToConsole/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/1LogToConsole/types/services/SeasonalEventService.d.ts +++ b/TypeScript/1LogToConsole/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/1LogToConsole/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/1LogToConsole/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/1LogToConsole/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/1LogToConsole/types/utils/RandomUtil.d.ts b/TypeScript/1LogToConsole/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/1LogToConsole/types/utils/RandomUtil.d.ts +++ b/TypeScript/1LogToConsole/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/20CustomChatBot/types/controllers/ProfileController.d.ts b/TypeScript/20CustomChatBot/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/20CustomChatBot/types/controllers/ProfileController.d.ts +++ b/TypeScript/20CustomChatBot/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/20CustomChatBot/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/20CustomChatBot/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/20CustomChatBot/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/20CustomChatBot/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/20CustomChatBot/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/20CustomChatBot/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/20CustomChatBot/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/20CustomChatBot/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/20CustomChatBot/types/helpers/ProfileHelper.d.ts b/TypeScript/20CustomChatBot/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/20CustomChatBot/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/20CustomChatBot/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/20CustomChatBot/types/helpers/QuestHelper.d.ts b/TypeScript/20CustomChatBot/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/20CustomChatBot/types/helpers/QuestHelper.d.ts +++ b/TypeScript/20CustomChatBot/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/20CustomChatBot/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/20CustomChatBot/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/20CustomChatBot/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/20CustomChatBot/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/20CustomChatBot/types/helpers/TraderAssortHelper.d.ts b/TypeScript/20CustomChatBot/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/20CustomChatBot/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/20CustomChatBot/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/20CustomChatBot/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/20CustomChatBot/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/20CustomChatBot/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/20CustomChatBot/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/20CustomChatBot/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/20CustomChatBot/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/20CustomChatBot/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/20CustomChatBot/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/20CustomChatBot/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/20CustomChatBot/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/20CustomChatBot/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/20CustomChatBot/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/20CustomChatBot/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/20CustomChatBot/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/20CustomChatBot/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/20CustomChatBot/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/20CustomChatBot/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/20CustomChatBot/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/20CustomChatBot/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/20CustomChatBot/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/20CustomChatBot/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/20CustomChatBot/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/20CustomChatBot/types/services/CircleOfCultistService.d.ts b/TypeScript/20CustomChatBot/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/20CustomChatBot/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/20CustomChatBot/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/20CustomChatBot/types/services/ProfileFixerService.d.ts b/TypeScript/20CustomChatBot/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/20CustomChatBot/types/services/ProfileFixerService.d.ts +++ b/TypeScript/20CustomChatBot/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/20CustomChatBot/types/services/SeasonalEventService.d.ts b/TypeScript/20CustomChatBot/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/20CustomChatBot/types/services/SeasonalEventService.d.ts +++ b/TypeScript/20CustomChatBot/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/20CustomChatBot/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/20CustomChatBot/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/20CustomChatBot/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/20CustomChatBot/types/utils/RandomUtil.d.ts b/TypeScript/20CustomChatBot/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/20CustomChatBot/types/utils/RandomUtil.d.ts +++ b/TypeScript/20CustomChatBot/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/21CustomCommandoCommand/types/controllers/ProfileController.d.ts b/TypeScript/21CustomCommandoCommand/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/21CustomCommandoCommand/types/controllers/ProfileController.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/21CustomCommandoCommand/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/21CustomCommandoCommand/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/21CustomCommandoCommand/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/21CustomCommandoCommand/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/21CustomCommandoCommand/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/21CustomCommandoCommand/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/21CustomCommandoCommand/types/helpers/ProfileHelper.d.ts b/TypeScript/21CustomCommandoCommand/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/21CustomCommandoCommand/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/21CustomCommandoCommand/types/helpers/QuestHelper.d.ts b/TypeScript/21CustomCommandoCommand/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/21CustomCommandoCommand/types/helpers/QuestHelper.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/21CustomCommandoCommand/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/21CustomCommandoCommand/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/21CustomCommandoCommand/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/21CustomCommandoCommand/types/helpers/TraderAssortHelper.d.ts b/TypeScript/21CustomCommandoCommand/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/21CustomCommandoCommand/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/21CustomCommandoCommand/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/21CustomCommandoCommand/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/21CustomCommandoCommand/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/21CustomCommandoCommand/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/21CustomCommandoCommand/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/21CustomCommandoCommand/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/21CustomCommandoCommand/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/21CustomCommandoCommand/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/21CustomCommandoCommand/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/21CustomCommandoCommand/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/21CustomCommandoCommand/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/21CustomCommandoCommand/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/21CustomCommandoCommand/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/21CustomCommandoCommand/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/21CustomCommandoCommand/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/21CustomCommandoCommand/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/21CustomCommandoCommand/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/21CustomCommandoCommand/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/21CustomCommandoCommand/types/services/CircleOfCultistService.d.ts b/TypeScript/21CustomCommandoCommand/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/21CustomCommandoCommand/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/21CustomCommandoCommand/types/services/ProfileFixerService.d.ts b/TypeScript/21CustomCommandoCommand/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/21CustomCommandoCommand/types/services/ProfileFixerService.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/21CustomCommandoCommand/types/services/SeasonalEventService.d.ts b/TypeScript/21CustomCommandoCommand/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/21CustomCommandoCommand/types/services/SeasonalEventService.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/21CustomCommandoCommand/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/21CustomCommandoCommand/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/21CustomCommandoCommand/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/21CustomCommandoCommand/types/utils/RandomUtil.d.ts b/TypeScript/21CustomCommandoCommand/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/21CustomCommandoCommand/types/utils/RandomUtil.d.ts +++ b/TypeScript/21CustomCommandoCommand/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/22CustomSptCommand/types/controllers/ProfileController.d.ts b/TypeScript/22CustomSptCommand/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/22CustomSptCommand/types/controllers/ProfileController.d.ts +++ b/TypeScript/22CustomSptCommand/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/22CustomSptCommand/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/22CustomSptCommand/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/22CustomSptCommand/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/22CustomSptCommand/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/22CustomSptCommand/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/22CustomSptCommand/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/22CustomSptCommand/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/22CustomSptCommand/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/22CustomSptCommand/types/helpers/ProfileHelper.d.ts b/TypeScript/22CustomSptCommand/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/22CustomSptCommand/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/22CustomSptCommand/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/22CustomSptCommand/types/helpers/QuestHelper.d.ts b/TypeScript/22CustomSptCommand/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/22CustomSptCommand/types/helpers/QuestHelper.d.ts +++ b/TypeScript/22CustomSptCommand/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/22CustomSptCommand/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/22CustomSptCommand/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/22CustomSptCommand/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/22CustomSptCommand/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/22CustomSptCommand/types/helpers/TraderAssortHelper.d.ts b/TypeScript/22CustomSptCommand/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/22CustomSptCommand/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/22CustomSptCommand/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/22CustomSptCommand/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/22CustomSptCommand/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/22CustomSptCommand/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/22CustomSptCommand/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/22CustomSptCommand/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/22CustomSptCommand/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/22CustomSptCommand/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/22CustomSptCommand/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/22CustomSptCommand/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/22CustomSptCommand/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/22CustomSptCommand/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/22CustomSptCommand/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/22CustomSptCommand/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/22CustomSptCommand/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/22CustomSptCommand/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/22CustomSptCommand/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/22CustomSptCommand/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/22CustomSptCommand/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/22CustomSptCommand/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/22CustomSptCommand/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/22CustomSptCommand/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/22CustomSptCommand/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/22CustomSptCommand/types/services/CircleOfCultistService.d.ts b/TypeScript/22CustomSptCommand/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/22CustomSptCommand/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/22CustomSptCommand/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/22CustomSptCommand/types/services/ProfileFixerService.d.ts b/TypeScript/22CustomSptCommand/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/22CustomSptCommand/types/services/ProfileFixerService.d.ts +++ b/TypeScript/22CustomSptCommand/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/22CustomSptCommand/types/services/SeasonalEventService.d.ts b/TypeScript/22CustomSptCommand/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/22CustomSptCommand/types/services/SeasonalEventService.d.ts +++ b/TypeScript/22CustomSptCommand/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/22CustomSptCommand/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/22CustomSptCommand/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/22CustomSptCommand/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/22CustomSptCommand/types/utils/RandomUtil.d.ts b/TypeScript/22CustomSptCommand/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/22CustomSptCommand/types/utils/RandomUtil.d.ts +++ b/TypeScript/22CustomSptCommand/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/23CustomAbstractChatBot/types/controllers/ProfileController.d.ts b/TypeScript/23CustomAbstractChatBot/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/23CustomAbstractChatBot/types/controllers/ProfileController.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/23CustomAbstractChatBot/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/23CustomAbstractChatBot/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/23CustomAbstractChatBot/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/23CustomAbstractChatBot/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/23CustomAbstractChatBot/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/23CustomAbstractChatBot/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/23CustomAbstractChatBot/types/helpers/ProfileHelper.d.ts b/TypeScript/23CustomAbstractChatBot/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/23CustomAbstractChatBot/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/23CustomAbstractChatBot/types/helpers/QuestHelper.d.ts b/TypeScript/23CustomAbstractChatBot/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/23CustomAbstractChatBot/types/helpers/QuestHelper.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/23CustomAbstractChatBot/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/23CustomAbstractChatBot/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/23CustomAbstractChatBot/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/23CustomAbstractChatBot/types/helpers/TraderAssortHelper.d.ts b/TypeScript/23CustomAbstractChatBot/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/23CustomAbstractChatBot/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/23CustomAbstractChatBot/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/23CustomAbstractChatBot/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/23CustomAbstractChatBot/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/23CustomAbstractChatBot/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/23CustomAbstractChatBot/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/23CustomAbstractChatBot/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/23CustomAbstractChatBot/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/23CustomAbstractChatBot/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/23CustomAbstractChatBot/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/23CustomAbstractChatBot/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/23CustomAbstractChatBot/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/23CustomAbstractChatBot/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/23CustomAbstractChatBot/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/23CustomAbstractChatBot/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/23CustomAbstractChatBot/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/23CustomAbstractChatBot/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/23CustomAbstractChatBot/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/23CustomAbstractChatBot/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/23CustomAbstractChatBot/types/services/CircleOfCultistService.d.ts b/TypeScript/23CustomAbstractChatBot/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/23CustomAbstractChatBot/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/23CustomAbstractChatBot/types/services/ProfileFixerService.d.ts b/TypeScript/23CustomAbstractChatBot/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/23CustomAbstractChatBot/types/services/ProfileFixerService.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/23CustomAbstractChatBot/types/services/SeasonalEventService.d.ts b/TypeScript/23CustomAbstractChatBot/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/23CustomAbstractChatBot/types/services/SeasonalEventService.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/23CustomAbstractChatBot/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/23CustomAbstractChatBot/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/23CustomAbstractChatBot/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/23CustomAbstractChatBot/types/utils/RandomUtil.d.ts b/TypeScript/23CustomAbstractChatBot/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/23CustomAbstractChatBot/types/utils/RandomUtil.d.ts +++ b/TypeScript/23CustomAbstractChatBot/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/24WebSocket/types/controllers/ProfileController.d.ts b/TypeScript/24WebSocket/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/24WebSocket/types/controllers/ProfileController.d.ts +++ b/TypeScript/24WebSocket/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/24WebSocket/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/24WebSocket/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/24WebSocket/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/24WebSocket/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/24WebSocket/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/24WebSocket/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/24WebSocket/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/24WebSocket/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/24WebSocket/types/helpers/ProfileHelper.d.ts b/TypeScript/24WebSocket/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/24WebSocket/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/24WebSocket/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/24WebSocket/types/helpers/QuestHelper.d.ts b/TypeScript/24WebSocket/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/24WebSocket/types/helpers/QuestHelper.d.ts +++ b/TypeScript/24WebSocket/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/24WebSocket/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/24WebSocket/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/24WebSocket/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/24WebSocket/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/24WebSocket/types/helpers/TraderAssortHelper.d.ts b/TypeScript/24WebSocket/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/24WebSocket/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/24WebSocket/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/24WebSocket/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/24WebSocket/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/24WebSocket/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/24WebSocket/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/24WebSocket/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/24WebSocket/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/24WebSocket/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/24WebSocket/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/24WebSocket/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/24WebSocket/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/24WebSocket/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/24WebSocket/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/24WebSocket/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/24WebSocket/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/24WebSocket/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/24WebSocket/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/24WebSocket/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/24WebSocket/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/24WebSocket/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/24WebSocket/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/24WebSocket/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/24WebSocket/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/24WebSocket/types/services/CircleOfCultistService.d.ts b/TypeScript/24WebSocket/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/24WebSocket/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/24WebSocket/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/24WebSocket/types/services/ProfileFixerService.d.ts b/TypeScript/24WebSocket/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/24WebSocket/types/services/ProfileFixerService.d.ts +++ b/TypeScript/24WebSocket/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/24WebSocket/types/services/SeasonalEventService.d.ts b/TypeScript/24WebSocket/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/24WebSocket/types/services/SeasonalEventService.d.ts +++ b/TypeScript/24WebSocket/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/24WebSocket/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/24WebSocket/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/24WebSocket/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/24WebSocket/types/utils/RandomUtil.d.ts b/TypeScript/24WebSocket/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/24WebSocket/types/utils/RandomUtil.d.ts +++ b/TypeScript/24WebSocket/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/2EditDatabase/types/controllers/ProfileController.d.ts b/TypeScript/2EditDatabase/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/2EditDatabase/types/controllers/ProfileController.d.ts +++ b/TypeScript/2EditDatabase/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/2EditDatabase/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/2EditDatabase/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/2EditDatabase/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/2EditDatabase/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/2EditDatabase/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/2EditDatabase/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/2EditDatabase/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/2EditDatabase/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/2EditDatabase/types/helpers/ProfileHelper.d.ts b/TypeScript/2EditDatabase/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/2EditDatabase/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/2EditDatabase/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/2EditDatabase/types/helpers/QuestHelper.d.ts b/TypeScript/2EditDatabase/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/2EditDatabase/types/helpers/QuestHelper.d.ts +++ b/TypeScript/2EditDatabase/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/2EditDatabase/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/2EditDatabase/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/2EditDatabase/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/2EditDatabase/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/2EditDatabase/types/helpers/TraderAssortHelper.d.ts b/TypeScript/2EditDatabase/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/2EditDatabase/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/2EditDatabase/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/2EditDatabase/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/2EditDatabase/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/2EditDatabase/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/2EditDatabase/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/2EditDatabase/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/2EditDatabase/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/2EditDatabase/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/2EditDatabase/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/2EditDatabase/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/2EditDatabase/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/2EditDatabase/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/2EditDatabase/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/2EditDatabase/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/2EditDatabase/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/2EditDatabase/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/2EditDatabase/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/2EditDatabase/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/2EditDatabase/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/2EditDatabase/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/2EditDatabase/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/2EditDatabase/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/2EditDatabase/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/2EditDatabase/types/services/CircleOfCultistService.d.ts b/TypeScript/2EditDatabase/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/2EditDatabase/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/2EditDatabase/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/2EditDatabase/types/services/ProfileFixerService.d.ts b/TypeScript/2EditDatabase/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/2EditDatabase/types/services/ProfileFixerService.d.ts +++ b/TypeScript/2EditDatabase/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/2EditDatabase/types/services/SeasonalEventService.d.ts b/TypeScript/2EditDatabase/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/2EditDatabase/types/services/SeasonalEventService.d.ts +++ b/TypeScript/2EditDatabase/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/2EditDatabase/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/2EditDatabase/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/2EditDatabase/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/2EditDatabase/types/utils/RandomUtil.d.ts b/TypeScript/2EditDatabase/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/2EditDatabase/types/utils/RandomUtil.d.ts +++ b/TypeScript/2EditDatabase/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/3GetSptConfigFile/types/controllers/ProfileController.d.ts b/TypeScript/3GetSptConfigFile/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/3GetSptConfigFile/types/controllers/ProfileController.d.ts +++ b/TypeScript/3GetSptConfigFile/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/3GetSptConfigFile/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/3GetSptConfigFile/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/3GetSptConfigFile/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/3GetSptConfigFile/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/3GetSptConfigFile/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/3GetSptConfigFile/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/3GetSptConfigFile/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/3GetSptConfigFile/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/3GetSptConfigFile/types/helpers/ProfileHelper.d.ts b/TypeScript/3GetSptConfigFile/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/3GetSptConfigFile/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/3GetSptConfigFile/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/3GetSptConfigFile/types/helpers/QuestHelper.d.ts b/TypeScript/3GetSptConfigFile/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/3GetSptConfigFile/types/helpers/QuestHelper.d.ts +++ b/TypeScript/3GetSptConfigFile/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/3GetSptConfigFile/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/3GetSptConfigFile/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/3GetSptConfigFile/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/3GetSptConfigFile/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/3GetSptConfigFile/types/helpers/TraderAssortHelper.d.ts b/TypeScript/3GetSptConfigFile/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/3GetSptConfigFile/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/3GetSptConfigFile/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/3GetSptConfigFile/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/3GetSptConfigFile/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/3GetSptConfigFile/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/3GetSptConfigFile/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/3GetSptConfigFile/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/3GetSptConfigFile/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/3GetSptConfigFile/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/3GetSptConfigFile/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/3GetSptConfigFile/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/3GetSptConfigFile/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/3GetSptConfigFile/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/3GetSptConfigFile/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/3GetSptConfigFile/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/3GetSptConfigFile/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/3GetSptConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/3GetSptConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/3GetSptConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/3GetSptConfigFile/types/services/CircleOfCultistService.d.ts b/TypeScript/3GetSptConfigFile/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/3GetSptConfigFile/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/3GetSptConfigFile/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/3GetSptConfigFile/types/services/ProfileFixerService.d.ts b/TypeScript/3GetSptConfigFile/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/3GetSptConfigFile/types/services/ProfileFixerService.d.ts +++ b/TypeScript/3GetSptConfigFile/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/3GetSptConfigFile/types/services/SeasonalEventService.d.ts b/TypeScript/3GetSptConfigFile/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/3GetSptConfigFile/types/services/SeasonalEventService.d.ts +++ b/TypeScript/3GetSptConfigFile/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/3GetSptConfigFile/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/3GetSptConfigFile/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/3GetSptConfigFile/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/3GetSptConfigFile/types/utils/RandomUtil.d.ts b/TypeScript/3GetSptConfigFile/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/3GetSptConfigFile/types/utils/RandomUtil.d.ts +++ b/TypeScript/3GetSptConfigFile/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/ProfileController.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/ProfileController.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/ProfileHelper.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/QuestHelper.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/QuestHelper.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/TraderAssortHelper.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/CircleOfCultistService.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/ProfileFixerService.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/ProfileFixerService.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/SeasonalEventService.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/SeasonalEventService.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/RandomUtil.d.ts b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/RandomUtil.d.ts +++ b/TypeScript/4.1UseACustomJson5OrJsonCConfigFile/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/4UseACustomConfigFile/types/controllers/ProfileController.d.ts b/TypeScript/4UseACustomConfigFile/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/4UseACustomConfigFile/types/controllers/ProfileController.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/4UseACustomConfigFile/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/4UseACustomConfigFile/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/4UseACustomConfigFile/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/4UseACustomConfigFile/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/4UseACustomConfigFile/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/ProfileHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/4UseACustomConfigFile/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/4UseACustomConfigFile/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/4UseACustomConfigFile/types/helpers/TraderAssortHelper.d.ts b/TypeScript/4UseACustomConfigFile/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/4UseACustomConfigFile/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/4UseACustomConfigFile/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/4UseACustomConfigFile/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/4UseACustomConfigFile/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/4UseACustomConfigFile/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/4UseACustomConfigFile/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/4UseACustomConfigFile/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/4UseACustomConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/4UseACustomConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/4UseACustomConfigFile/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/4UseACustomConfigFile/types/services/CircleOfCultistService.d.ts b/TypeScript/4UseACustomConfigFile/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/4UseACustomConfigFile/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts b/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/4UseACustomConfigFile/types/services/SeasonalEventService.d.ts b/TypeScript/4UseACustomConfigFile/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/4UseACustomConfigFile/types/services/SeasonalEventService.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/4UseACustomConfigFile/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/4UseACustomConfigFile/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/4UseACustomConfigFile/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts b/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts +++ b/TypeScript/4UseACustomConfigFile/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/5ReplaceMethod/types/controllers/ProfileController.d.ts b/TypeScript/5ReplaceMethod/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/5ReplaceMethod/types/controllers/ProfileController.d.ts +++ b/TypeScript/5ReplaceMethod/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/5ReplaceMethod/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/5ReplaceMethod/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/5ReplaceMethod/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/5ReplaceMethod/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/5ReplaceMethod/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/5ReplaceMethod/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/5ReplaceMethod/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/5ReplaceMethod/types/helpers/ProfileHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/5ReplaceMethod/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/5ReplaceMethod/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts +++ b/TypeScript/5ReplaceMethod/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/5ReplaceMethod/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/5ReplaceMethod/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/5ReplaceMethod/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/5ReplaceMethod/types/helpers/TraderAssortHelper.d.ts b/TypeScript/5ReplaceMethod/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/5ReplaceMethod/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/5ReplaceMethod/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/5ReplaceMethod/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/5ReplaceMethod/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/5ReplaceMethod/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/5ReplaceMethod/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/5ReplaceMethod/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/5ReplaceMethod/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/5ReplaceMethod/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/5ReplaceMethod/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/5ReplaceMethod/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/5ReplaceMethod/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/5ReplaceMethod/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/5ReplaceMethod/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/5ReplaceMethod/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/5ReplaceMethod/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/5ReplaceMethod/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/5ReplaceMethod/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/5ReplaceMethod/types/services/CircleOfCultistService.d.ts b/TypeScript/5ReplaceMethod/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/5ReplaceMethod/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/5ReplaceMethod/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts b/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts +++ b/TypeScript/5ReplaceMethod/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/5ReplaceMethod/types/services/SeasonalEventService.d.ts b/TypeScript/5ReplaceMethod/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/5ReplaceMethod/types/services/SeasonalEventService.d.ts +++ b/TypeScript/5ReplaceMethod/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/5ReplaceMethod/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/5ReplaceMethod/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/5ReplaceMethod/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts b/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts +++ b/TypeScript/5ReplaceMethod/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/6ReferenceAnotherClass/types/controllers/ProfileController.d.ts b/TypeScript/6ReferenceAnotherClass/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/6ReferenceAnotherClass/types/controllers/ProfileController.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/6ReferenceAnotherClass/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/6ReferenceAnotherClass/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/6ReferenceAnotherClass/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/6ReferenceAnotherClass/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/ProfileHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/6ReferenceAnotherClass/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/6ReferenceAnotherClass/types/helpers/TraderAssortHelper.d.ts b/TypeScript/6ReferenceAnotherClass/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/6ReferenceAnotherClass/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/6ReferenceAnotherClass/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/6ReferenceAnotherClass/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/6ReferenceAnotherClass/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/6ReferenceAnotherClass/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/6ReferenceAnotherClass/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/6ReferenceAnotherClass/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/6ReferenceAnotherClass/types/services/CircleOfCultistService.d.ts b/TypeScript/6ReferenceAnotherClass/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/6ReferenceAnotherClass/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts b/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/6ReferenceAnotherClass/types/services/SeasonalEventService.d.ts b/TypeScript/6ReferenceAnotherClass/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/6ReferenceAnotherClass/types/services/SeasonalEventService.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/6ReferenceAnotherClass/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/6ReferenceAnotherClass/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/6ReferenceAnotherClass/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts b/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts +++ b/TypeScript/6ReferenceAnotherClass/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/7OnLoadHook/types/controllers/ProfileController.d.ts b/TypeScript/7OnLoadHook/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/7OnLoadHook/types/controllers/ProfileController.d.ts +++ b/TypeScript/7OnLoadHook/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/7OnLoadHook/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/7OnLoadHook/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/7OnLoadHook/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/7OnLoadHook/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/7OnLoadHook/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/7OnLoadHook/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/7OnLoadHook/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/7OnLoadHook/types/helpers/ProfileHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/7OnLoadHook/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/7OnLoadHook/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts +++ b/TypeScript/7OnLoadHook/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/7OnLoadHook/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/7OnLoadHook/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/7OnLoadHook/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/7OnLoadHook/types/helpers/TraderAssortHelper.d.ts b/TypeScript/7OnLoadHook/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/7OnLoadHook/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/7OnLoadHook/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/7OnLoadHook/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/7OnLoadHook/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/7OnLoadHook/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/7OnLoadHook/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/7OnLoadHook/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/7OnLoadHook/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/7OnLoadHook/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/7OnLoadHook/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/7OnLoadHook/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/7OnLoadHook/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/7OnLoadHook/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/7OnLoadHook/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/7OnLoadHook/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/7OnLoadHook/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/7OnLoadHook/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/7OnLoadHook/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/7OnLoadHook/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/7OnLoadHook/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/7OnLoadHook/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/7OnLoadHook/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/7OnLoadHook/types/services/CircleOfCultistService.d.ts b/TypeScript/7OnLoadHook/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/7OnLoadHook/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/7OnLoadHook/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts b/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts +++ b/TypeScript/7OnLoadHook/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/7OnLoadHook/types/services/SeasonalEventService.d.ts b/TypeScript/7OnLoadHook/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/7OnLoadHook/types/services/SeasonalEventService.d.ts +++ b/TypeScript/7OnLoadHook/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/7OnLoadHook/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/7OnLoadHook/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/7OnLoadHook/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts b/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts +++ b/TypeScript/7OnLoadHook/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/8OnUpdateHook/types/controllers/ProfileController.d.ts b/TypeScript/8OnUpdateHook/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/8OnUpdateHook/types/controllers/ProfileController.d.ts +++ b/TypeScript/8OnUpdateHook/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/8OnUpdateHook/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/8OnUpdateHook/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/8OnUpdateHook/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/8OnUpdateHook/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/8OnUpdateHook/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/8OnUpdateHook/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/8OnUpdateHook/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/8OnUpdateHook/types/helpers/ProfileHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/8OnUpdateHook/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/8OnUpdateHook/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts +++ b/TypeScript/8OnUpdateHook/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/8OnUpdateHook/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/8OnUpdateHook/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/8OnUpdateHook/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/8OnUpdateHook/types/helpers/TraderAssortHelper.d.ts b/TypeScript/8OnUpdateHook/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/8OnUpdateHook/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/8OnUpdateHook/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/8OnUpdateHook/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/8OnUpdateHook/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/8OnUpdateHook/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/8OnUpdateHook/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/8OnUpdateHook/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/8OnUpdateHook/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/8OnUpdateHook/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/8OnUpdateHook/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/8OnUpdateHook/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/8OnUpdateHook/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/8OnUpdateHook/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/8OnUpdateHook/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/8OnUpdateHook/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/8OnUpdateHook/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/8OnUpdateHook/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/8OnUpdateHook/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/8OnUpdateHook/types/services/CircleOfCultistService.d.ts b/TypeScript/8OnUpdateHook/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/8OnUpdateHook/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/8OnUpdateHook/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts b/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts +++ b/TypeScript/8OnUpdateHook/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/8OnUpdateHook/types/services/SeasonalEventService.d.ts b/TypeScript/8OnUpdateHook/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/8OnUpdateHook/types/services/SeasonalEventService.d.ts +++ b/TypeScript/8OnUpdateHook/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/8OnUpdateHook/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/8OnUpdateHook/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/8OnUpdateHook/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts b/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts +++ b/TypeScript/8OnUpdateHook/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; } diff --git a/TypeScript/9RouterHooks/types/controllers/ProfileController.d.ts b/TypeScript/9RouterHooks/types/controllers/ProfileController.d.ts index 71fd9e6..dd20b5d 100644 --- a/TypeScript/9RouterHooks/types/controllers/ProfileController.d.ts +++ b/TypeScript/9RouterHooks/types/controllers/ProfileController.d.ts @@ -118,6 +118,9 @@ export declare class ProfileController { * Handle client/profile/status */ getProfileStatus(sessionId: string): IGetProfileStatusResponseData; + /** + * Handle client/profile/view + */ getOtherProfile(sessionId: string, request: IGetOtherProfileRequest): IGetOtherProfileResponse; /** * Handle client/profile/settings diff --git a/TypeScript/9RouterHooks/types/generators/BotEquipmentModGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/BotEquipmentModGenerator.d.ts index 40c361f..29aa5cd 100644 --- a/TypeScript/9RouterHooks/types/generators/BotEquipmentModGenerator.d.ts +++ b/TypeScript/9RouterHooks/types/generators/BotEquipmentModGenerator.d.ts @@ -114,9 +114,10 @@ export declare class BotEquipmentModGenerator { /** * Sort mod slots into an ordering that maximises chance of a successful weapon generation * @param unsortedSlotKeys Array of mod slot strings to sort + * @param itemTplWithKeysToSort The Tpl of the item with mod keys being sorted * @returns Sorted array */ - protected sortModKeys(unsortedSlotKeys: string[]): string[]; + protected sortModKeys(unsortedSlotKeys: string[], itemTplWithKeysToSort: string): string[]; /** * Get a Slot property for an item (chamber/cartridge/slot) * @param modSlot e.g patron_in_weapon diff --git a/TypeScript/9RouterHooks/types/generators/RagfairOfferGenerator.d.ts b/TypeScript/9RouterHooks/types/generators/RagfairOfferGenerator.d.ts index 60d6c9d..324df2e 100644 --- a/TypeScript/9RouterHooks/types/generators/RagfairOfferGenerator.d.ts +++ b/TypeScript/9RouterHooks/types/generators/RagfairOfferGenerator.d.ts @@ -12,6 +12,7 @@ import { IBarterScheme } from "@spt/models/eft/common/tables/ITrader"; import { IOfferRequirement, IRagfairOffer, IRagfairOfferUser } from "@spt/models/eft/ragfair/IRagfairOffer"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { IArmorPlateBlacklistSettings, IBarterDetails, IDynamic, IRagfairConfig } from "@spt/models/spt/config/IRagfairConfig"; +import { ITraderConfig } from "@spt/models/spt/config/ITraderConfig"; import { ITplWithFleaPrice } from "@spt/models/spt/ragfair/ITplWithFleaPrice"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -47,6 +48,7 @@ export declare class RagfairOfferGenerator { protected configServer: ConfigServer; protected cloner: ICloner; protected ragfairConfig: IRagfairConfig; + protected traderConfig: ITraderConfig; protected botConfig: IBotConfig; protected allowedFleaPriceItemsForBarter: { tpl: string; @@ -83,7 +85,7 @@ export declare class RagfairOfferGenerator { * @param isTrader Is the user creating the offer a trader * @returns IRagfairOfferUser */ - createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; + protected createUserDataForFleaOffer(userID: string, isTrader: boolean): IRagfairOfferUser; /** * Calculate the offer price that's listed on the flea listing * @param offerRequirements barter requirements for offer diff --git a/TypeScript/9RouterHooks/types/helpers/ProfileHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/ProfileHelper.d.ts index ce9af11..c2871b4 100644 --- a/TypeScript/9RouterHooks/types/helpers/ProfileHelper.d.ts +++ b/TypeScript/9RouterHooks/types/helpers/ProfileHelper.d.ts @@ -209,4 +209,10 @@ export declare class ProfileHelper { * @returns Array of item objects */ getQuestItemsInProfile(profile: IPmcData): IItem[]; + /** + * Return a favorites array in the format expected by the getOtherProfile call + * @param profile + * @returns An array of IItem objects representing the favorited data + */ + getOtherProfileFavorites(profile: IPmcData): IItem[]; } diff --git a/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts index 52aad0a..414cc0a 100644 --- a/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts +++ b/TypeScript/9RouterHooks/types/helpers/QuestHelper.d.ts @@ -282,10 +282,10 @@ export declare class QuestHelper { */ protected findAndAddHideoutProductionIdToProfile(pmcData: IPmcData, craftUnlockReward: IQuestReward, questDetails: IQuest, sessionID: string, response: IItemEventRouterResponse): void; /** - * Find hideout craft id for the specified quest reward - * @param craftUnlockReward - * @param questDetails - * @returns + * Find hideout craft for the specified quest reward + * @param craftUnlockReward Reward item from quest with craft unlock details + * @param questDetails Quest with craft unlock reward + * @returns Hideout craft */ getRewardProductionMatch(craftUnlockReward: IQuestReward, questDetails: IQuest): IHideoutProduction[]; /** @@ -332,16 +332,15 @@ export declare class QuestHelper { /** * Create a clone of the given quest array with the rewards updated to reflect the * given game version - * - * @param quests The list of quests to check - * @param gameVersion The game version of the profile - * @returns array of IQuest objects with the rewards filtered correctly for the game version + * @param quests List of quests to check + * @param gameVersion Game version of the profile + * @returns Array of IQuest objects with the rewards filtered correctly for the game version */ protected updateQuestsForGameEdition(quests: IQuest[], gameVersion: string): IQuest[]; /** * Return a list of quests that would fail when supplied quest is completed - * @param completedQuestId quest completed id - * @returns array of IQuest objects + * @param completedQuestId Quest completed id + * @returns Array of IQuest objects */ protected getQuestsFromProfileFailedByCompletingQuest(completedQuestId: string, pmcProfile: IPmcData): IQuest[]; /** diff --git a/TypeScript/9RouterHooks/types/helpers/RagfairOfferHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/RagfairOfferHelper.d.ts index 66a146d..9dd5be3 100644 --- a/TypeScript/9RouterHooks/types/helpers/RagfairOfferHelper.d.ts +++ b/TypeScript/9RouterHooks/types/helpers/RagfairOfferHelper.d.ts @@ -67,6 +67,13 @@ export declare class RagfairOfferHelper { * @returns Offers the player should see */ getValidOffers(searchRequest: ISearchRequestData, itemsToAdd: string[], traderAssorts: Record, pmcData: IPmcData): IRagfairOffer[]; + /** + * Disable offer if item is flagged by tiered flea config + * @param tieredFlea Tiered flea settings from ragfair config + * @param offer Ragfair offer to check + * @param tieredFleaLimitTypes Dict of item types with player level to be viewable + * @param playerLevel Level of player viewing offer + */ protected checkAndLockOfferFromPlayerTieredFlea(tieredFlea: ITieredFlea, offer: IRagfairOffer, tieredFleaLimitTypes: string[], playerLevel: number): void; /** * Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level @@ -99,14 +106,14 @@ export declare class RagfairOfferHelper { */ traderOfferItemQuestLocked(offer: IRagfairOffer, traderAssorts: Record): boolean; /** - * Has a traders offer ran out of stock to sell to player + * Has trader offer ran out of stock to sell to player * @param offer Offer to check stock of * @returns true if out of stock */ protected traderOutOfStock(offer: IRagfairOffer): boolean; /** * Check if trader offers' BuyRestrictionMax value has been reached - * @param offer offer to check restriction properties of + * @param offer Offer to check restriction properties of * @returns true if restriction reached, false if no restrictions/not reached */ protected traderBuyRestrictionReached(offer: IRagfairOffer): boolean; @@ -114,7 +121,7 @@ export declare class RagfairOfferHelper { * Get an array of flea offers that are inaccessible to player due to their inadequate loyalty level * @param offers Offers to check * @param pmcProfile Players profile with trader loyalty levels - * @returns array of offer ids player cannot see + * @returns Array of offer ids player cannot see */ protected getLoyaltyLockedOffers(offers: IRagfairOffer[], pmcProfile: IPmcData): string[]; /** @@ -126,7 +133,7 @@ export declare class RagfairOfferHelper { /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up - * @returns Total count + * @returns Total stack count */ getTotalStackCountSize(itemsInInventoryToList: IItem[][]): number; /** @@ -164,16 +171,16 @@ export declare class RagfairOfferHelper { protected getLocalisedOfferSoldMessage(itemTpl: string, boughtAmount: number): string; /** * Check an offer passes the various search criteria the player requested - * @param searchRequest - * @param offer - * @param pmcData - * @returns True + * @param searchRequest Client search request + * @param offer Offer to check + * @param pmcData Player profile + * @returns True if offer passes criteria */ protected passesSearchFilterCriteria(searchRequest: ISearchRequestData, offer: IRagfairOffer, pmcData: IPmcData): boolean; /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer - * @param offer The flea offer + * @param offer Flea offer to check * @returns True if the given item is functional */ isItemFunctional(offerRootItem: IItem, offer: IRagfairOffer): boolean; @@ -181,7 +188,7 @@ export declare class RagfairOfferHelper { * Should a ragfair offer be visible to the player * @param searchRequest Search request * @param itemsToAdd ? - * @param traderAssorts Trader assort items + * @param traderAssorts Trader assort items - used for filtering out locked trader items * @param offer The flea offer * @param pmcProfile Player profile * @returns True = should be shown to player diff --git a/TypeScript/9RouterHooks/types/helpers/TraderAssortHelper.d.ts b/TypeScript/9RouterHooks/types/helpers/TraderAssortHelper.d.ts index a50b589..70946a2 100644 --- a/TypeScript/9RouterHooks/types/helpers/TraderAssortHelper.d.ts +++ b/TypeScript/9RouterHooks/types/helpers/TraderAssortHelper.d.ts @@ -44,10 +44,10 @@ export declare class TraderAssortHelper { * Filter out assorts not unlocked due to level OR quest completion * @param sessionId session id * @param traderId traders id - * @param flea Should assorts player hasn't unlocked be returned - default false + * @param showLockedAssorts Should assorts player hasn't unlocked be returned - default false * @returns a traders' assorts */ - getAssort(sessionId: string, traderId: string, flea?: boolean): ITraderAssort; + getAssort(sessionId: string, traderId: string, showLockedAssorts?: boolean): ITraderAssort; /** * Given the blacklist provided, remove root items from assort * @param assortToFilter Trader assort to modify @@ -75,20 +75,10 @@ export declare class TraderAssortHelper { * @returns true they need refreshing */ traderAssortsHaveExpired(traderID: string): boolean; - /** - * Iterate over all assorts barter_scheme values, find barters selling for money and multiply by multipler in config - * @param traderAssort Assorts to multiple price of - */ - protected multiplyItemPricesByConfigMultiplier(traderAssort: ITraderAssort): void; /** * Get an array of pristine trader items prior to any alteration by player (as they were on server start) * @param traderId trader id * @returns array of Items */ protected getPristineTraderAssorts(traderId: string): IItem[]; - /** - * Returns generated ragfair offers in a trader assort format - * @returns Trader assort object - */ - protected getRagfairDataAsTraderAssort(): ITraderAssort; } diff --git a/TypeScript/9RouterHooks/types/models/eft/common/tables/IBotBase.d.ts b/TypeScript/9RouterHooks/types/models/eft/common/tables/IBotBase.d.ts index 5becac2..d3fd87e 100644 --- a/TypeScript/9RouterHooks/types/models/eft/common/tables/IBotBase.d.ts +++ b/TypeScript/9RouterHooks/types/models/eft/common/tables/IBotBase.d.ts @@ -153,7 +153,7 @@ export interface IInventory { /** Key is hideout area enum numeric as string e.g. "24", value is area _id */ hideoutAreaStashes: Record; fastPanel: Record; - favoriteItems: IItem[]; + favoriteItems: string[]; } export interface IBaseJsonSkills { Common: Record; diff --git a/TypeScript/9RouterHooks/types/models/eft/profile/ISptProfile.d.ts b/TypeScript/9RouterHooks/types/models/eft/profile/ISptProfile.d.ts index 8290b1c..aba539b 100644 --- a/TypeScript/9RouterHooks/types/models/eft/profile/ISptProfile.d.ts +++ b/TypeScript/9RouterHooks/types/models/eft/profile/ISptProfile.d.ts @@ -169,6 +169,13 @@ export interface ISpt { freeRepeatableRefreshUsedCount?: Record; /** When was a profile migrated, value is timestamp */ migrations?: Record; + /** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */ + cultistRewards?: Map; +} +export interface IAcceptedCultistReward { + timestamp: number; + sacrificeItems: string[]; + rewardItems: string[]; } export interface IModDetails { name: string; diff --git a/TypeScript/9RouterHooks/types/models/enums/hideout/CircleRewardType.d.ts b/TypeScript/9RouterHooks/types/models/enums/hideout/CircleRewardType.d.ts new file mode 100644 index 0000000..71e83a2 --- /dev/null +++ b/TypeScript/9RouterHooks/types/models/enums/hideout/CircleRewardType.d.ts @@ -0,0 +1,4 @@ +export declare enum CircleRewardType { + RANDOM = 0, + HIDEOUT_TASK = 1 +} diff --git a/TypeScript/9RouterHooks/types/models/spt/config/IHideoutConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/IHideoutConfig.d.ts index 5257777..a2483a9 100644 --- a/TypeScript/9RouterHooks/types/models/spt/config/IHideoutConfig.d.ts +++ b/TypeScript/9RouterHooks/types/models/spt/config/IHideoutConfig.d.ts @@ -18,11 +18,21 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + /** The odds that meeting the highest threshold gives you a bonus to crafting time */ + bonusAmountMultiplier: number; + bonusChanceMultiplier: number; + /** What is considered a "high-value" item */ + highValueThresholdRub: number; + /** Hideout/task reward crafts have a unique craft time */ + hideoutTaskRewardTimeSeconds: number; + /** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */ + hideoutCraftSacrificeThresholdRub: number; craftTimeThreshholds: ICraftTimeThreshhold[]; - /** -1 means no override */ + /** -1 means no override, value in seconds */ craftTimeOverride: number; - /** Specific reward pool when player sacrificed one specific item */ - directRewards: Record; + /** Specific reward pool when player sacrifice specific item(s) */ + directRewards: IDirectRewardSettings[]; + /** Overrides for reward stack sizes, keyed by item tpl */ directRewardStackSize: Record; /** Item tpls to exclude from the reward pool */ rewardItemBlacklist: string[]; @@ -34,6 +44,9 @@ export interface ICraftTimeThreshhold extends MinMax { craftTimeSeconds: number; } export interface IDirectRewardSettings { - rewardTpls: string[]; + reward: string[]; + requiredItems: string[]; craftTimeSeconds: number; + /** Is the reward a one time reward or can it be given multiple times */ + repeatable: boolean; } diff --git a/TypeScript/9RouterHooks/types/models/spt/config/ITraderConfig.d.ts b/TypeScript/9RouterHooks/types/models/spt/config/ITraderConfig.d.ts index 5d2d4a6..2835a0d 100644 --- a/TypeScript/9RouterHooks/types/models/spt/config/ITraderConfig.d.ts +++ b/TypeScript/9RouterHooks/types/models/spt/config/ITraderConfig.d.ts @@ -4,10 +4,10 @@ import { ILootRequest } from "@spt/models/spt/services/ILootRequest"; export interface ITraderConfig extends IBaseConfig { kind: "spt-trader"; updateTime: IUpdateTime[]; + updateTimeDefault: number; purchasesAreFoundInRaid: boolean; /** Should trader reset times be set based on server start time (false = bsg time - on the hour) */ tradersResetFromServerStart: boolean; - updateTimeDefault: number; traderPriceMultipler: number; fence: IFenceConfig; moddedTraders: IModdedTraders; diff --git a/TypeScript/9RouterHooks/types/models/spt/hideout/ICircleCraftDetails.d.ts b/TypeScript/9RouterHooks/types/models/spt/hideout/ICircleCraftDetails.d.ts new file mode 100644 index 0000000..991e349 --- /dev/null +++ b/TypeScript/9RouterHooks/types/models/spt/hideout/ICircleCraftDetails.d.ts @@ -0,0 +1,8 @@ +import { CircleRewardType } from "@spt/models/enums/hideout/CircleRewardType"; +import { ICraftTimeThreshhold } from "@spt/models/spt/config/IHideoutConfig"; +export interface ICircleCraftDetails { + time: number; + rewardType: CircleRewardType; + rewardAmountRoubles: number; + rewardDetails?: ICraftTimeThreshhold; +} diff --git a/TypeScript/9RouterHooks/types/services/CircleOfCultistService.d.ts b/TypeScript/9RouterHooks/types/services/CircleOfCultistService.d.ts index e4d3410..e804617 100644 --- a/TypeScript/9RouterHooks/types/services/CircleOfCultistService.d.ts +++ b/TypeScript/9RouterHooks/types/services/CircleOfCultistService.d.ts @@ -3,14 +3,17 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper"; import { ItemHelper } from "@spt/helpers/ItemHelper"; import { PresetHelper } from "@spt/helpers/PresetHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { QuestHelper } from "@spt/helpers/QuestHelper"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; import { IBotHideoutArea } from "@spt/models/eft/common/tables/IBotBase"; import { IItem } from "@spt/models/eft/common/tables/IItem"; import { IStageRequirement } from "@spt/models/eft/hideout/IHideoutArea"; import { IHideoutCircleOfCultistProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutCircleOfCultistProductionStartRequestData"; -import { IHideoutProduction, IHideoutProductionData, IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; +import { IRequirement, IRequirementBase } from "@spt/models/eft/hideout/IHideoutProduction"; import { IItemEventRouterResponse } from "@spt/models/eft/itemEvent/IItemEventRouterResponse"; -import { IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICraftTimeThreshhold, ICultistCircleSettings, IDirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig"; +import { ICircleCraftDetails } from "@spt/models/spt/hideout/ICircleCraftDetails"; +import { IHideout } from "@spt/models/spt/hideout/IHideout"; import { ILogger } from "@spt/models/spt/utils/ILogger"; import { EventOutputHolder } from "@spt/routers/EventOutputHolder"; import { ConfigServer } from "@spt/servers/ConfigServer"; @@ -33,13 +36,14 @@ export declare class CircleOfCultistService { protected profileHelper: ProfileHelper; protected inventoryHelper: InventoryHelper; protected hideoutHelper: HideoutHelper; + protected questHelper: QuestHelper; protected databaseService: DatabaseService; protected itemFilterService: ItemFilterService; protected seasonalEventService: SeasonalEventService; protected configServer: ConfigServer; protected static circleOfCultistSlotId: string; protected hideoutConfig: IHideoutConfig; - constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); + constructor(logger: ILogger, timeUtil: TimeUtil, cloner: ICloner, eventOutputHolder: EventOutputHolder, randomUtil: RandomUtil, hashUtil: HashUtil, itemHelper: ItemHelper, presetHelper: PresetHelper, profileHelper: ProfileHelper, inventoryHelper: InventoryHelper, hideoutHelper: HideoutHelper, questHelper: QuestHelper, databaseService: DatabaseService, itemFilterService: ItemFilterService, seasonalEventService: SeasonalEventService, configServer: ConfigServer); /** * Start a sacrifice event * Generate rewards @@ -50,24 +54,38 @@ export declare class CircleOfCultistService { * @returns IItemEventRouterResponse */ startSacrifice(sessionId: string, pmcData: IPmcData, request: IHideoutCircleOfCultistProductionStartRequestData): IItemEventRouterResponse; + /** + * Create a map of the possible direct rewards, keyed by the items needed to be sacrificed + * @param directRewards Direct rewards array from hideout config + * @returns Map + */ + protected generateSacrificedItemsCache(directRewards: IDirectRewardSettings[]): Map; + /** + * Get the reward amount multiple value based on players hideout management skill + configs rewardPriceMultiplerMinMax values + * @param pmcData Player profile + * @param cultistCircleSettings Circle config settings + * @returns Reward Amount Multipler + */ + protected getRewardAmountMultipler(pmcData: IPmcData, cultistCircleSettings: ICultistCircleSettings): number; /** * Register production inside player profile * @param sessionId Session id * @param pmcData Player profile * @param recipeId Recipe id * @param sacrificedItems Items player sacrificed - * @param rewardAmountRoubles Rouble amount to reward player in items with - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards + * @param craftingTime How long the ritual should take */ - protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): void; + protected registerCircleOfCultistProduction(sessionId: string, pmcData: IPmcData, recipeId: string, sacrificedItems: IItem[], craftingTime: number): void; /** * Get the circle craft time as seconds, value is based on reward item value - * OR rewards are direct, then use custom craft time defined in oarameter object + * And get the bonus status to determine what tier of reward is given * @param rewardAmountRoubles Value of rewards in roubles - * @param directRewardSettings OPTIONAL: If craft is giving direct rewards - * @returns craft time seconds + * @param circleConfig Circle config values + * @param directRewardSettings OPTIONAL - Values related to direct reward being given + * @returns craft time + type of reward + reward details */ - protected getCircleCraftTimeSeconds(rewardAmountRoubles: number, directRewardSettings?: IDirectRewardSettings): number; + protected getCircleCraftingInfo(rewardAmountRoubles: number, circleConfig: ICultistCircleSettings, directRewardSettings?: IDirectRewardSettings): ICircleCraftDetails; + protected getMatchingThreshold(thresholds: ICraftTimeThreshhold[], rewardAmountRoubles: number): ICraftTimeThreshhold; /** * Get the items player sacrificed in circle * @param pmcData Player profile @@ -81,20 +99,40 @@ export declare class CircleOfCultistService { * @param cultistCircleStashId Id of stash item * @returns Array of item arrays */ - protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string): IItem[][]; + protected getRewardsWithinBudget(rewardItemTplPool: string[], rewardBudget: number, cultistCircleStashId: string, circleConfig: ICultistCircleSettings): IItem[][]; /** - * Give every item as a reward that's passed in - * @param rewardTpls Item tpls to turn into reward items + * Get direct rewards + * @param sessionId sessionId + * @param directReward Items sacrificed * @param cultistCircleStashId Id of stash item - * @returns Array of item arrays + * @returns The reward object */ - protected getExplicitRewards(explicitRewardSettings: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + protected getDirectRewards(sessionId: string, directReward: IDirectRewardSettings, cultistCircleStashId: string): IItem[][]; + /** + * Check for direct rewards from what player sacrificed + * @param sessionId sessionId + * @param sacrificedItems Items sacrificed + * @returns Direct reward items to send to player + */ + protected checkForDirectReward(sessionId: string, sacrificedItems: IItem[], directRewardsCache: Map): IDirectRewardSettings; + /** + * Create an md5 key of the sacrificed + reward items + * @param directReward Direct reward to create key for + * @returns Key + */ + protected getDirectRewardHashKey(directReward: IDirectRewardSettings): string; /** * Explicit rewards have thier own stack sizes as they dont use a reward rouble pool * @param rewardTpl Item being rewarded to get stack size of * @returns stack size of item */ - protected getExplicitRewardBaseTypeStackSize(rewardTpl: string): number; + protected getDirectRewardBaseTypeStackSize(rewardTpl: string): number; + /** + * Add a record to the players profile to signal they have accepted a non-repeatable direct reward + * @param sessionId Session id + * @param directReward Reward sent to player + */ + protected flagDirectRewardAsAcceptedInProfile(sessionId: string, directReward: IDirectRewardSettings): void; /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack @@ -107,9 +145,26 @@ export declare class CircleOfCultistService { * Get a pool of tpl IDs of items the player needs to complete hideout crafts/upgrade areas * @param sessionId Session id * @param pmcData Profile of player who will be getting the rewards + * @param rewardType Do we return bonus items (hideout/task items) + * @param cultistCircleConfig Circle config * @returns Array of tpls */ - protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData): string[]; + protected getCultistCircleRewardPool(sessionId: string, pmcData: IPmcData, craftingInfo: ICircleCraftDetails, cultistCircleConfig: ICultistCircleSettings): string[]; + /** + * Check players profile for quests with hand-in requirements and add those required items to the pool + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addTaskItemRequirementsToRewardPool(pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; + /** + * Adds items the player needs to complete hideout crafts/upgrades to the reward pool + * @param hideoutDbData Hideout area data + * @param pmcData Player profile + * @param itemRewardBlacklist Items not to add to pool + * @param rewardPool Pool to add items to + */ + protected addHideoutUpgradeRequirementsToRewardPool(hideoutDbData: IHideout, pmcData: IPmcData, itemRewardBlacklist: string[], rewardPool: Set): void; /** * Get all active hideout areas * @param areas Hideout areas to iterate over @@ -117,12 +172,13 @@ export declare class CircleOfCultistService { */ protected getPlayerAccessibleHideoutAreas(areas: IBotHideoutArea[]): IBotHideoutArea[]; /** - * Get all recipes the player has access to, includes base + unlocked recipes - * @param unlockedRecipes Recipes player has flagged as unlocked - * @param allRecipes All recipes - * @returns Array of recipes + * Get array of random reward items + * @param rewardPool Reward pool to add to + * @param itemRewardBlacklist Reward Blacklist + * @param itemsShouldBeHighValue Should these items meet the valuable threshold + * @returns rewardPool */ - protected getPlayerAccessibleRecipes(unlockedRecipes: string[], allRecipes: IHideoutProductionData): IHideoutProduction[]; + protected generateRandomisedItemsAndAddToRewardPool(rewardPool: Set, itemRewardBlacklist: string[], itemsShouldBeHighValue: boolean): Set; /** * Iterate over passed in hideout requirements and return the Item * @param requirements Requirements to iterate over diff --git a/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts b/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts index ccb9d07..4a3a5ff 100644 --- a/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts +++ b/TypeScript/9RouterHooks/types/services/ProfileFixerService.d.ts @@ -87,6 +87,12 @@ export declare class ProfileFixerService { * @returns */ protected verifyQuestProductionUnlock(pmcProfile: IPmcData, productionUnlockReward: IQuestReward, questDetails: IQuest): void; + /** + * Initial release of SPT 3.10 used an incorrect favorites structure, reformat + * the structure to the correct MongoID array structure + * @param pmcProfile + */ + protected fixFavorites(pmcProfile: IPmcData): void; /** * If the profile has elite Hideout Managment skill, add the additional slots from globals * NOTE: This seems redundant, but we will leave it here just incase. diff --git a/TypeScript/9RouterHooks/types/services/SeasonalEventService.d.ts b/TypeScript/9RouterHooks/types/services/SeasonalEventService.d.ts index d239ee9..446cccc 100644 --- a/TypeScript/9RouterHooks/types/services/SeasonalEventService.d.ts +++ b/TypeScript/9RouterHooks/types/services/SeasonalEventService.d.ts @@ -138,6 +138,12 @@ export declare class SeasonalEventService { */ protected enableHalloweenSummonEvent(): void; protected configureZombies(zombieSettings: IZombieSettings): void; + /** + * Get location ids of maps with an infection above 0 + * @param locationInfections Dict of locations with their infection percentage + * @returns Array of location ids + */ + protected getLocationsWithZombies(locationInfections: Record): string[]; /** * BSG store the location ids differently inside `LocationInfection`, need to convert to matching location IDs * @param infectedLocationKey Key to convert diff --git a/TypeScript/9RouterHooks/types/utils/DatabaseDecompressionUtil.d.ts b/TypeScript/9RouterHooks/types/utils/DatabaseDecompressionUtil.d.ts deleted file mode 100644 index b6722d1..0000000 --- a/TypeScript/9RouterHooks/types/utils/DatabaseDecompressionUtil.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { ILogger } from "@spt/models/spt/utils/ILogger"; -export declare class DatabaseDecompressionUtil { - protected logger: ILogger; - private compressedDir; - private assetsDir; - private compiled; - constructor(logger: ILogger); - /** - * Checks if the application is running in a compiled environment. A simple check is done to see if the relative - * assets directory exists. If it does not, the application is assumed to be running in a compiled environment. All - * relative asset paths are different within a compiled environment, so this simple check is sufficient. - */ - private isCompiled; - /** - * Initializes the database compression utility. - * - * This method will decompress all 7-zip archives within the compressed database directory. The decompressed files - * are placed in their respective directories based on the name and location of the compressed file. - */ - initialize(): Promise; - /** - * Retrieves a list of all 7-zip archives within the compressed database directory. - */ - private getCompressedFiles; - /** - * Processes a compressed file by checking if the target directory is empty, and if so, decompressing the file into - * the target directory. - */ - private processCompressedFile; - /** - * Checks if a directory exists and is empty. - */ - private isDirectoryEmpty; - /** - * Decompresses a 7-zip archive to the target directory. - */ - private decompressFile; -} diff --git a/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts b/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts index 0da184f..601300c 100644 --- a/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts +++ b/TypeScript/9RouterHooks/types/utils/RandomUtil.d.ts @@ -106,77 +106,177 @@ export declare class RandomUtil { protected cloner: ICloner; protected logger: ILogger; constructor(cloner: ICloner, logger: ILogger); + /** + * Generates a secure random number between 0 (inclusive) and 1 (exclusive). + * + * This method uses the `crypto` module to generate a 48-bit random integer, + * which is then divided by the maximum possible 48-bit integer value to + * produce a floating-point number in the range [0, 1). + * + * @returns A secure random number between 0 (inclusive) and 1 (exclusive). + */ + private getSecureRandomNumber; + /** + * Generates a random integer between the specified minimum and maximum values, inclusive. + * + * @param min - The minimum value (inclusive). + * @param max - The maximum value (inclusive). + * @returns A random integer between the specified minimum and maximum values. + */ getInt(min: number, max: number): number; + /** + * Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive). + * If the maximum value is less than or equal to 1, it returns 1. + * + * @param max - The upper bound (exclusive) for the random integer generation. + * @returns A random integer between 1 and max - 1, or 1 if max is less than or equal to 1. + */ getIntEx(max: number): number; + /** + * Generates a random floating-point number within the specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (exclusive). + * @returns A random floating-point number between `min` (inclusive) and `max` (exclusive). + */ getFloat(min: number, max: number): number; + /** + * Generates a random boolean value. + * + * @returns A random boolean value, where the probability of `true` and `false` is approximately equal. + */ getBool(): boolean; + /** + * Calculates the percentage of a given number and returns the result. + * + * @param percent - The percentage to calculate. + * @param number - The number to calculate the percentage of. + * @param toFixed - The number of decimal places to round the result to (default is 2). + * @returns The calculated percentage of the given number, rounded to the specified number of decimal places. + */ getPercentOfValue(percent: number, number: number, toFixed?: number): number; /** - * Reduce a value by a percentage - * @param number Value to reduce - * @param percentage Percentage to reduce value by - * @returns Reduced value + * Reduces a given number by a specified percentage. + * + * @param number - The original number to be reduced. + * @param percentage - The percentage by which to reduce the number. + * @returns The reduced number after applying the percentage reduction. */ reduceValueByPercent(number: number, percentage: number): number; /** - * Check if number passes a check out of 100 - * @param chancePercent value check needs to be above - * @returns true if value passes check + * Determines if a random event occurs based on the given chance percentage. + * + * @param chancePercent - The percentage chance (0-100) that the event will occur. + * @returns `true` if the event occurs, `false` otherwise. */ getChance100(chancePercent: number): boolean; + /** + * Returns a random string from the provided array of strings. + * + * This method is separate from getArrayValue so we can use a generic inferance with getArrayValue. + * + * @param arr - The array of strings to select a random value from. + * @returns A randomly selected string from the array. + */ getStringArrayValue(arr: string[]): string; + /** + * Returns a random element from the provided array. + * + * @template T - The type of elements in the array. + * @param arr - The array from which to select a random element. + * @returns A random element from the array. + */ getArrayValue(arr: T[]): T; + /** + * Retrieves a random key from the given object. + * + * @param node - The object from which to retrieve a key. + * @returns A string representing one of the keys of the node object. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKey(node: any): string; + /** + * Retrieves the value associated with a key from the given node object. + * + * @param node - An object with string keys and any type of values. + * @returns The value associated with the key obtained from the node. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 + */ getKeyValue(node: { [x: string]: any; }): any; /** - * Generate a normally distributed random number - * Uses the Box-Muller transform - * @param {number} mean Mean of the normal distribution - * @param {number} sigma Standard deviation of the normal distribution - * @returns {number} The value drawn + * Generates a normally distributed random number using the Box-Muller transform. + * + * @param mean - The mean (μ) of the normal distribution. + * @param sigma - The standard deviation (σ) of the normal distribution. + * @param attempt - The current attempt count to generate a valid number (default is 0). + * @returns A normally distributed random number. + * + * @remarks + * This function uses the Box-Muller transform to generate a normally distributed random number. + * If the generated number is less than 0, it will recursively attempt to generate a valid number up to 100 times. + * If it fails to generate a valid number after 100 attempts, it will return a random float between 0.01 and twice the mean. */ getNormallyDistributedRandomNumber(mean: number, sigma: number, attempt?: number): number; /** - * Draw Random integer low inclusive, high exclusive - * if high is not set we draw from 0 to low (exclusive) - * @param {integer} low Lower bound inclusive, when high is not set, this is high - * @param {integer} high Higher bound exclusive - * @returns {integer} The random integer in [low, high) + * Generates a random integer between the specified range. + * + * @param low - The lower bound of the range (inclusive). + * @param high - The upper bound of the range (exclusive). If not provided, the range will be from 0 to `low`. + * @returns A random integer within the specified range. */ randInt(low: number, high?: number): number; /** - * Draw a random element of the provided list N times to return an array of N random elements - * Drawing can be with or without replacement - * @param {array} list The array we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with or without replacement from the input array(default true) - * @return {array} Array consisting of N random elements + * Draws a specified number of random elements from a given list. + * + * @template T - The type of elements in the list. + * @param originalList - The list to draw elements from. + * @param count - The number of elements to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array containing the drawn elements. */ drawRandomFromList(originalList: Array, count?: number, replacement?: boolean): Array; /** - * Draw a random (top level) element of the provided dictionary N times to return an array of N random dictionary keys - * Drawing can be with or without replacement - * @param {any} dict The dictionary we want to draw randomly from - * @param {integer} count The number of times we want to draw - * @param {boolean} replacement Draw with ot without replacement from the input dict - * @return {array} Array consisting of N random keys of the dictionary + * Draws a specified number of random keys from a given dictionary. + * + * @param dict - The dictionary from which to draw keys. + * @param count - The number of keys to draw. Defaults to 1. + * @param replacement - Whether to draw with replacement. Defaults to true. + * @returns An array of randomly drawn keys from the dictionary. + * + * TODO: v3.11 - This method is not type-safe and should be refactored to use a more specific type: + * https://github.com/sp-tarkov/server/pull/972/commits/f2b8efe211d95f71aec0a4bc84f4542335433412 */ drawRandomFromDict(dict: any, count?: number, replacement?: boolean): any[]; + /** + * Generates a biased random number within a specified range. + * + * @param min - The minimum value of the range (inclusive). + * @param max - The maximum value of the range (inclusive). + * @param shift - The bias shift to apply to the random number generation. + * @param n - The number of iterations to use for generating a Gaussian random number. + * @returns A biased random number within the specified range. + * @throws Will throw if `max` is less than `min` or if `n` is less than 1. + */ getBiasedRandomNumber(min: number, max: number, shift: number, n: number): number; /** - * Fisher-Yates shuffle an array - * @param array Array to shuffle - * @returns Shuffled array + * Shuffles an array in place using the Fisher-Yates algorithm. + * + * @template T - The type of elements in the array. + * @param array - The array to shuffle. + * @returns The shuffled array. */ shuffle(array: Array): Array; /** - * Rolls for a probability based on chance - * @param number Probability Chance as float (0-1) - * @returns If roll succeed or not - * @example - * rollForChanceProbability(0.25); // returns true 25% probability + * Rolls for a chance probability and returns whether the roll is successful. + * + * @param probabilityChance - The probability chance to roll for, represented as a number between 0 and 1. + * @returns `true` if the random number is less than or equal to the probability chance, otherwise `false`. */ rollForChanceProbability(probabilityChance: number): boolean; }