Merge pull request #601 from sp-tarkov/repeatable-completion-quests
Repeatable completion quest level ranges
This commit is contained in:
@@ -597,28 +597,107 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"Completion": {
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"minRequestedAmount": 1,
|
||||
"maxRequestedAmount": 4,
|
||||
"uniqueItemCount": 2,
|
||||
"minRequestedBulletAmount": 15,
|
||||
"maxRequestedBulletAmount": 40,
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
"Completion": [
|
||||
{
|
||||
"levelRange": {
|
||||
"min": 1,
|
||||
"max": 15
|
||||
},
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"requestedItemCount": {
|
||||
"min": 1,
|
||||
"max": 4
|
||||
},
|
||||
"uniqueItemCount": {
|
||||
"min": 1,
|
||||
"max": 1
|
||||
},
|
||||
"requestedBulletCount": {
|
||||
"min": 15,
|
||||
"max": 40
|
||||
},
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
},
|
||||
{
|
||||
"levelRange": {
|
||||
"min": 16,
|
||||
"max": 40
|
||||
},
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"requestedItemCount": {
|
||||
"min": 2,
|
||||
"max": 4
|
||||
},
|
||||
"uniqueItemCount": {
|
||||
"min": 1,
|
||||
"max": 2
|
||||
},
|
||||
"requestedBulletCount": {
|
||||
"min": 15,
|
||||
"max": 40
|
||||
},
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
},
|
||||
{
|
||||
"levelRange": {
|
||||
"min": 41,
|
||||
"max": 100
|
||||
},
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"requestedItemCount": {
|
||||
"min": 3,
|
||||
"max": 6
|
||||
},
|
||||
"uniqueItemCount": {
|
||||
"min": 1,
|
||||
"max": 2
|
||||
},
|
||||
"requestedBulletCount": {
|
||||
"min": 15,
|
||||
"max": 40
|
||||
},
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
}
|
||||
],
|
||||
"Elimination": [
|
||||
{
|
||||
"levelRange": {
|
||||
@@ -1745,28 +1824,107 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"Completion": {
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"minRequestedAmount": 4,
|
||||
"maxRequestedAmount": 12,
|
||||
"uniqueItemCount": 4,
|
||||
"minRequestedBulletAmount": 20,
|
||||
"maxRequestedBulletAmount": 60,
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
"Completion": [
|
||||
{
|
||||
"levelRange": {
|
||||
"min": 1,
|
||||
"max": 15
|
||||
},
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"requestedItemCount": {
|
||||
"min": 4,
|
||||
"max": 6
|
||||
},
|
||||
"uniqueItemCount": {
|
||||
"min": 1,
|
||||
"max": 2
|
||||
},
|
||||
"requestedBulletCount": {
|
||||
"min": 20,
|
||||
"max": 60
|
||||
},
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
},
|
||||
{
|
||||
"levelRange": {
|
||||
"min": 16,
|
||||
"max": 40
|
||||
},
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"requestedItemCount": {
|
||||
"min": 4,
|
||||
"max": 8
|
||||
},
|
||||
"uniqueItemCount": {
|
||||
"min": 1,
|
||||
"max": 2
|
||||
},
|
||||
"requestedBulletCount": {
|
||||
"min": 20,
|
||||
"max": 60
|
||||
},
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
},
|
||||
{
|
||||
"levelRange": {
|
||||
"min": 41,
|
||||
"max": 100
|
||||
},
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"requestedItemCount": {
|
||||
"min": 6,
|
||||
"max": 12
|
||||
},
|
||||
"uniqueItemCount": {
|
||||
"min": 1,
|
||||
"max": 3
|
||||
},
|
||||
"requestedBulletCount": {
|
||||
"min": 20,
|
||||
"max": 60
|
||||
},
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
}
|
||||
],
|
||||
"Elimination": [
|
||||
{
|
||||
"levelRange": {
|
||||
@@ -2887,28 +3045,107 @@
|
||||
],
|
||||
"maxItemFetchCount": 3
|
||||
},
|
||||
"Completion": {
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"minRequestedAmount": 1,
|
||||
"maxRequestedAmount": 3,
|
||||
"uniqueItemCount": 1,
|
||||
"minRequestedBulletAmount": 15,
|
||||
"maxRequestedBulletAmount": 40,
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
"Completion": [
|
||||
{
|
||||
"levelRange": {
|
||||
"min": 1,
|
||||
"max": 15
|
||||
},
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"requestedItemCount": {
|
||||
"min": 1,
|
||||
"max": 3
|
||||
},
|
||||
"uniqueItemCount": {
|
||||
"min": 1,
|
||||
"max": 1
|
||||
},
|
||||
"requestedBulletCount": {
|
||||
"min": 15,
|
||||
"max": 40
|
||||
},
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
},
|
||||
{
|
||||
"levelRange": {
|
||||
"min": 16,
|
||||
"max": 40
|
||||
},
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"requestedItemCount": {
|
||||
"min": 2,
|
||||
"max": 5
|
||||
},
|
||||
"uniqueItemCount": {
|
||||
"min": 1,
|
||||
"max": 1
|
||||
},
|
||||
"requestedBulletCount": {
|
||||
"min": 15,
|
||||
"max": 40
|
||||
},
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
},
|
||||
{
|
||||
"levelRange": {
|
||||
"min": 41,
|
||||
"max": 100
|
||||
},
|
||||
"possibleSkillRewards": [
|
||||
"Endurance",
|
||||
"Strength",
|
||||
"Vitality"
|
||||
],
|
||||
"requestedItemCount": {
|
||||
"min": 4,
|
||||
"max": 6
|
||||
},
|
||||
"uniqueItemCount": {
|
||||
"min": 1,
|
||||
"max": 1
|
||||
},
|
||||
"requestedBulletCount": {
|
||||
"min": 15,
|
||||
"max": 40
|
||||
},
|
||||
"useWhitelist": true,
|
||||
"useBlacklist": false,
|
||||
"requiredItemsAreFiR": true,
|
||||
"requiredItemMinDurabilityMinMax": {
|
||||
"min": 60,
|
||||
"max": 80
|
||||
},
|
||||
"requiredItemTypeBlacklist": [
|
||||
"5485a8684bdc2da71d8b4567"
|
||||
]
|
||||
}
|
||||
],
|
||||
"Elimination": [
|
||||
{
|
||||
"levelRange": {
|
||||
|
||||
@@ -663,6 +663,7 @@
|
||||
"repair-unable_to_find_item_repair_cost": "Unable to find repair cost for item: %s",
|
||||
"repair-unable_to_find_trader_details_by_id": "Unable to find trader: %s repair details",
|
||||
"repeatable-accepted_repeatable_quest_not_found_in_active_quests": "Accepted a repeatable quest: %s which could not be found in the activeQuests array. Please report this bug",
|
||||
"repeatable-completion_config_no_template": "Unable to find completion config for pmc level: {{pmcLevel}}",
|
||||
"repeatable-completion_quest_whitelist_too_small_or_blacklist_too_restrictive": "Generate Completion Quest: No items remain. Either Whitelist is too small or Blacklist too restrictive",
|
||||
"repeatable-difficulty_was_nan": "Repeatable Reward Generation: Difficulty was NaN. Setting to 1.",
|
||||
"repeatable-exploration_config_no_template": "Unable to find exploration config for pmc level: {{pmcLevel}}",
|
||||
|
||||
+14
-10
@@ -47,7 +47,13 @@ public class CompletionQuestGenerator(
|
||||
RepeatableQuestConfig repeatableConfig
|
||||
)
|
||||
{
|
||||
var completionConfig = repeatableConfig.QuestConfig.CompletionConfig;
|
||||
var completionConfig = repeatableQuestHelper.GetCompletionConfigByPmcLevel(pmcLevel, repeatableConfig);
|
||||
if (completionConfig is null)
|
||||
{
|
||||
logger.Warning(localisationService.GetText("repeatable-completion_config_no_template", new { pmcLevel }));
|
||||
return null;
|
||||
}
|
||||
|
||||
var levelsConfig = repeatableConfig.RewardScaling.Levels;
|
||||
var roublesConfig = repeatableConfig.RewardScaling.Roubles;
|
||||
|
||||
@@ -73,12 +79,12 @@ public class CompletionQuestGenerator(
|
||||
|
||||
// We also have the option to use whitelist and/or blacklist which is defined in repeatableQuests.json as
|
||||
// [{"minPlayerLevel": 1, "itemIds": ["id1",...]}, {"minPlayerLevel": 15, "itemIds": ["id3",...]}]
|
||||
if (repeatableConfig.QuestConfig.CompletionConfig.UseWhitelist)
|
||||
if (completionConfig.UseWhitelist)
|
||||
{
|
||||
itemsToRetrievePool = GetWhitelistedItemSelection(itemsToRetrievePool, pmcLevel);
|
||||
}
|
||||
|
||||
if (repeatableConfig.QuestConfig.CompletionConfig.UseBlacklist)
|
||||
if (completionConfig.UseBlacklist)
|
||||
{
|
||||
itemsToRetrievePool = GetBlacklistedItemSelection(itemsToRetrievePool, pmcLevel);
|
||||
}
|
||||
@@ -91,7 +97,7 @@ public class CompletionQuestGenerator(
|
||||
return null;
|
||||
}
|
||||
|
||||
var selectedItems = GenerateAvailableForFinish(quest, completionConfig, repeatableConfig, itemsToRetrievePool.ToList(), budget);
|
||||
var selectedItems = GenerateAvailableForFinish(quest, completionConfig, itemsToRetrievePool.ToList(), budget);
|
||||
|
||||
quest.Rewards = repeatableQuestRewardGenerator.GenerateReward(
|
||||
pmcLevel,
|
||||
@@ -240,20 +246,18 @@ public class CompletionQuestGenerator(
|
||||
/// </summary>
|
||||
/// <param name="quest">Quest to add the conditions to</param>
|
||||
/// <param name="completionConfig">Completion config</param>
|
||||
/// <param name="repeatableConfig">Repeatable config</param>
|
||||
/// <param name="itemSelection">Filtered item selection</param>
|
||||
/// <param name="roublesBudget">Budget in roubles</param>
|
||||
/// <returns>Chosen item template Ids</returns>
|
||||
protected List<MongoId> GenerateAvailableForFinish(
|
||||
RepeatableQuest quest,
|
||||
CompletionConfig completionConfig,
|
||||
RepeatableQuestConfig repeatableConfig,
|
||||
List<MongoId> itemSelection,
|
||||
double roublesBudget
|
||||
)
|
||||
{
|
||||
// Store the indexes of items we are asking player to supply
|
||||
var distinctItemsToRetrieveCount = randomUtil.GetInt(1, completionConfig.UniqueItemCount);
|
||||
var distinctItemsToRetrieveCount = randomUtil.GetInt(completionConfig.UniqueItemCount.Min, completionConfig.UniqueItemCount.Max);
|
||||
var chosenRequirementItemsTpls = new List<MongoId>();
|
||||
var usedItemIndexes = new HashSet<int>();
|
||||
|
||||
@@ -289,8 +293,8 @@ public class CompletionQuestGenerator(
|
||||
|
||||
var tplChosen = itemSelection[chosenItemIndex];
|
||||
var itemPrice = itemHelper.GetItemPrice(tplChosen)!.Value;
|
||||
var minValue = completionConfig.MinimumRequestedAmount;
|
||||
var maxValue = completionConfig.MaximumRequestedAmount;
|
||||
var minValue = completionConfig.RequestedItemCount.Min;
|
||||
var maxValue = completionConfig.RequestedItemCount.Max;
|
||||
|
||||
var value = minValue;
|
||||
|
||||
@@ -308,7 +312,7 @@ public class CompletionQuestGenerator(
|
||||
|
||||
// Push a CompletionCondition with the item and the amount of the item into quest
|
||||
chosenRequirementItemsTpls.Add(tplChosen);
|
||||
quest.Conditions.AvailableForFinish!.Add(GenerateCondition(tplChosen, value, repeatableConfig.QuestConfig.CompletionConfig));
|
||||
quest.Conditions.AvailableForFinish!.Add(GenerateCondition(tplChosen, value, completionConfig));
|
||||
|
||||
// Is there budget left for more items
|
||||
if (roublesBudget > 0)
|
||||
|
||||
@@ -45,6 +45,19 @@ public class RepeatableQuestHelper(
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the relevant completion config based on the current players PMC level
|
||||
/// </summary>
|
||||
/// <param name="pmcLevel">Level of PMC character</param>
|
||||
/// <param name="repeatableConfig">Main repeatable config</param>
|
||||
/// <returns>CompletionConfig</returns>
|
||||
public CompletionConfig? GetCompletionConfigByPmcLevel(int pmcLevel, RepeatableQuestConfig repeatableConfig)
|
||||
{
|
||||
return repeatableConfig.QuestConfig.CompletionConfig.FirstOrDefault(x =>
|
||||
pmcLevel >= x.LevelRange.Min && pmcLevel <= x.LevelRange.Max
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a cloned repeatable quest template for the provided type with a unique id
|
||||
/// </summary>
|
||||
|
||||
@@ -344,7 +344,7 @@ public record RepeatableQuestTypesConfig
|
||||
/// Defines completion repeatable task generation parameters
|
||||
/// </summary>
|
||||
[JsonPropertyName("Completion")]
|
||||
public required CompletionConfig CompletionConfig { get; set; }
|
||||
public required List<CompletionConfig> CompletionConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines pickup repeatable task generation parameters - TODO: Not implemented/No Data - NOTE: Does not work with dynamicLocale
|
||||
@@ -416,34 +416,28 @@ public record SpecificExits
|
||||
public record CompletionConfig : BaseQuestConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimum item count that can be requested
|
||||
/// Level range at which completion tasks should be generated from this config
|
||||
/// </summary>
|
||||
[JsonPropertyName("minRequestedAmount")]
|
||||
public required int MinimumRequestedAmount { get; set; }
|
||||
[JsonPropertyName("levelRange")]
|
||||
public required MinMax<int> LevelRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum item count that can be requested
|
||||
/// The minimum and maximum amounts that can be requested for an item
|
||||
/// </summary>
|
||||
[JsonPropertyName("maxRequestedAmount")]
|
||||
public required int MaximumRequestedAmount { get; set; }
|
||||
[JsonPropertyName("requestedItemCount")]
|
||||
public required MinMax<int> RequestedItemCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many unique items should be requested - TODO: This needs to be a range
|
||||
/// How many different unique items should be requested
|
||||
/// </summary>
|
||||
[JsonPropertyName("uniqueItemCount")]
|
||||
public required int UniqueItemCount { get; set; }
|
||||
public required MinMax<int> UniqueItemCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum bullet count that can be requested - TODO: Not implemented
|
||||
/// The minimum and maximum amounts that can be requested for bullets - TODO: Not implemented
|
||||
/// </summary>
|
||||
[JsonPropertyName("minRequestedBulletAmount")]
|
||||
public required int MinimumRequestedBulletAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum bullet count that can be requested - TODO: Not implemented
|
||||
/// </summary>
|
||||
[JsonPropertyName("maxRequestedBulletAmount")]
|
||||
public required int MaximumRequestedBulletAmount { get; set; }
|
||||
[JsonPropertyName("requestedBulletCount")]
|
||||
public required MinMax<int> RequestedBulletCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should the item whitelist be used
|
||||
@@ -467,7 +461,7 @@ public record CompletionConfig : BaseQuestConfig
|
||||
/// Min/Max durability requirements for the item
|
||||
/// </summary>
|
||||
[JsonPropertyName("requiredItemMinDurabilityMinMax")]
|
||||
public required MinMax<double> RequiredItemMinDurabilityMinMax { get; set; }
|
||||
public required MinMax<int> RequiredItemMinDurabilityMinMax { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Blacklisted item types to not collect
|
||||
|
||||
Reference in New Issue
Block a user