From 04235ca0244d7f2965960fafd63930eaa6edd05a Mon Sep 17 00:00:00 2001 From: Dev Date: Sun, 15 Oct 2023 11:46:33 +0100 Subject: [PATCH] Reward more items for daillies/weeklies Cleanup of `generateReward` item reward pool generation into its own function + return an easier array to work with --- project/assets/configs/quest.json | 4 +- .../generators/RepeatableQuestGenerator.ts | 61 +++++++++++-------- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/project/assets/configs/quest.json b/project/assets/configs/quest.json index 7768fb74..1d346264 100644 --- a/project/assets/configs/quest.json +++ b/project/assets/configs/quest.json @@ -144,7 +144,7 @@ "levels": [1, 10, 20, 30, 40, 50, 60], "experience": [1000, 12000, 42000, 89000, 177000, 300000, 500000], "roubles": [15000, 40000, 75000, 100000, 140000, 170000, 210000], - "items": [2, 2, 3, 3, 4, 5, 6], + "items": [4, 4, 5, 5, 5, 6, 6], "reputation": [0.01, 0.01, 0.02, 0.02], "rewardSpread": 0.5 }, @@ -694,7 +694,7 @@ "levels": [1, 10, 20, 30, 40, 50, 60], "experience": [5000, 25000, 60000, 130000, 240000, 390000, 750000], "roubles": [50000, 150000, 300000, 425000, 550000, 675000, 850000], - "items": [3, 3, 4, 4, 5, 6, 7], + "items": [5, 5, 5, 6, 6, 7, 7], "reputation": [0.02, 0.02, 0.03, 0.03, 0.03, 0.03, 0.03], "rewardSpread": 0.5 }, diff --git a/project/src/generators/RepeatableQuestGenerator.ts b/project/src/generators/RepeatableQuestGenerator.ts index 55b7ea66..0cde67fd 100644 --- a/project/src/generators/RepeatableQuestGenerator.ts +++ b/project/src/generators/RepeatableQuestGenerator.ts @@ -733,18 +733,7 @@ export class RepeatableQuestGenerator // Possible improvement -> draw trader-specific items e.g. with this.itemHelper.isOfBaseclass(val._id, ItemHelper.BASECLASS.FoodDrink) let roublesBudget = rewardRoubles; - - // First filter for type and baseclass to avoid lookup in handbook for non-available items - const rewardableItems = this.getRewardableItems(repeatableConfig); - const minPrice = Math.min(25000, 0.5 * roublesBudget); - let itemSelection = rewardableItems.filter(x => this.itemHelper.getItemPrice(x[0]) < roublesBudget && this.itemHelper.getItemPrice(x[0]) > minPrice); - if (itemSelection.length === 0) - { - this.logger.warning(this.localisationService.getText("repeatable-no_reward_item_found_in_price_range", {minPrice: minPrice, roublesBudget: roublesBudget})); - // In case we don't find any items in the price range - itemSelection = rewardableItems.filter(x => this.itemHelper.getItemPrice(x[0]) < roublesBudget - ); - } + let chosenRewardItems = this.chooseRewardItemsWithinBudget(repeatableConfig, roublesBudget); const rewards: IRewards = { Started: [], @@ -769,47 +758,48 @@ export class RepeatableQuestGenerator } let index = 2; - if (itemSelection.length > 0) + if (chosenRewardItems.length > 0) { for (let i = 0; i < rewardNumItems; i++) { let value = 1; let children = null; - const itemSelected = itemSelection[this.randomUtil.randInt(itemSelection.length)]; - if (this.itemHelper.isOfBaseclass(itemSelected[0], BaseClasses.AMMO)) + const itemSelected = chosenRewardItems[this.randomUtil.randInt(chosenRewardItems.length)]; + if (this.itemHelper.isOfBaseclass(itemSelected._id, BaseClasses.AMMO)) { // Dont reward ammo that stacks to less than what's defined in config - if (itemSelected[1]._props.StackMaxSize < repeatableConfig.rewardAmmoStackMinSize) + if (itemSelected._props.StackMaxSize < repeatableConfig.rewardAmmoStackMinSize) { continue; } // If we provide ammo we don't want to provide just one bullet - value = this.randomUtil.randInt(repeatableConfig.rewardAmmoStackMinSize, itemSelected[1]._props.StackMaxSize); + value = this.randomUtil.randInt(repeatableConfig.rewardAmmoStackMinSize, itemSelected._props.StackMaxSize); } - else if (this.itemHelper.isOfBaseclass(itemSelected[0], BaseClasses.WEAPON)) + else if (this.itemHelper.isOfBaseclass(itemSelected._id, BaseClasses.WEAPON)) { - const defaultPreset = this.presetHelper.getDefaultPreset(itemSelected[0]); + const defaultPreset = this.presetHelper.getDefaultPreset(itemSelected._id); if (defaultPreset) { children = this.ragfairServerHelper.reparentPresets(defaultPreset._items[0], defaultPreset._items); } } - rewards.Success.push(this.generateRewardItem(itemSelected[0], value, index, children)); + rewards.Success.push(this.generateRewardItem(itemSelected._id, value, index, children)); // TODO: maybe also non-default use ragfair to calculate the price // this.ragfairServer.getWeaponPresetPrice(item, items, existingPrice) - roublesBudget -= value * this.itemHelper.getStaticItemPrice(itemSelected[0]); + roublesBudget -= value * this.itemHelper.getStaticItemPrice(itemSelected._id); index += 1; // if we still have budget narrow down the items if (roublesBudget > 0) { - itemSelection = itemSelection.filter(x => this.itemHelper.getStaticItemPrice(x[0]) < roublesBudget); - if (itemSelection.length === 0) + // Filter possible reward items to only items with a price below the remaining budget + chosenRewardItems = chosenRewardItems.filter(x => this.itemHelper.getStaticItemPrice(x._id) < roublesBudget); + if (chosenRewardItems.length === 0) { - break; + break; // No reward items left, exit } } else @@ -819,6 +809,7 @@ export class RepeatableQuestGenerator } } + // Add rep reward to rewards array if (rewardReputation > 0) { const reward: IReward = { @@ -833,6 +824,28 @@ export class RepeatableQuestGenerator return rewards; } + /** + * Select a number of items that have a colelctive value of the passed in parameter + * @param repeatableConfig Config + * @param roublesBudget Total value of items to return + * @returns Array of reward items that fit budget + */ + protected chooseRewardItemsWithinBudget(repeatableConfig: IRepeatableQuestConfig, roublesBudget: number): ITemplateItem[] + { + // First filter for type and baseclass to avoid lookup in handbook for non-available items + const rewardableItems = this.getRewardableItems(repeatableConfig); + const minPrice = Math.min(25000, 0.5 * roublesBudget); + let itemSelection = rewardableItems.filter(x => this.itemHelper.getItemPrice(x[0]) < roublesBudget && this.itemHelper.getItemPrice(x[0]) > minPrice).map(x => x[1]); + if (itemSelection.length === 0) + { + this.logger.warning(this.localisationService.getText("repeatable-no_reward_item_found_in_price_range", {minPrice: minPrice, roublesBudget: roublesBudget})); + // In case we don't find any items in the price range + itemSelection = rewardableItems.filter(x => this.itemHelper.getItemPrice(x[0]) < roublesBudget).map(x => x[1]); + } + + return itemSelection; + } + /** * Helper to create a reward item structured as required by the client *