Task: Quest config changes Part 1 (#407)
* Remove nullable and add properties, make side use an enum instead of a string. * remove double semi-colon * fix comment
This commit is contained in:
@@ -25,17 +25,17 @@
|
||||
"profileWhitelist": {
|
||||
"666314b4d7f171c4c20226c3": ["edge_of_darkness"]
|
||||
},
|
||||
"questTemplateIds": {
|
||||
"repeatableQuestTemplateIds": {
|
||||
"pmc": {
|
||||
"elimination": "616052ea3054fc0e2c24ce6e",
|
||||
"completion": "61604635c725987e815b1a46",
|
||||
"exploration": "616041eb031af660100c9967"
|
||||
"Elimination": "616052ea3054fc0e2c24ce6e",
|
||||
"Completion": "61604635c725987e815b1a46",
|
||||
"Exploration": "616041eb031af660100c9967"
|
||||
},
|
||||
"scav": {
|
||||
"elimination": "62825ef60e88d037dc1eb428",
|
||||
"completion": "628f588ebb558574b2260fe5",
|
||||
"exploration": "62825ef60e88d037dc1eb42c",
|
||||
"pickup": "628f588ebb558574b2260fe5"
|
||||
"Elimination": "62825ef60e88d037dc1eb428",
|
||||
"Completion": "628f588ebb558574b2260fe5",
|
||||
"Exploration": "62825ef60e88d037dc1eb42c",
|
||||
"Pickup": "628f588ebb558574b2260fe5"
|
||||
}
|
||||
},
|
||||
"showNonSeasonalEventQuests": false,
|
||||
@@ -1891,6 +1891,7 @@
|
||||
"rewardAmmoStackMinSize": 5,
|
||||
"freeChangesAvailable": 0,
|
||||
"freeChanges": 0,
|
||||
"keepDailyQuestTypeOnReplacement": false,
|
||||
"standingChangeCost": [0, 0.01, 0.01]
|
||||
},
|
||||
{
|
||||
@@ -2314,6 +2315,7 @@
|
||||
"rewardAmmoStackMinSize": 5,
|
||||
"freeChangesAvailable": 0,
|
||||
"freeChanges": 0,
|
||||
"keepDailyQuestTypeOnReplacement": false,
|
||||
"standingChangeCost": [0, 0.01]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -184,7 +184,7 @@ public class RepeatableQuestController(
|
||||
}
|
||||
|
||||
// Add newly generated quest to daily/weekly/scav type array
|
||||
newRepeatableQuest.Side = repeatableConfig.Side;
|
||||
newRepeatableQuest.Side = Enum.GetName(repeatableConfig.Side);
|
||||
repeatablesOfTypeInProfile.ActiveQuests.Add(newRepeatableQuest);
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
@@ -568,7 +568,7 @@ public class RepeatableQuestController(
|
||||
break;
|
||||
}
|
||||
|
||||
quest.Side = repeatableConfig.Side;
|
||||
quest.Side = Enum.GetName(repeatableConfig.Side);
|
||||
generatedRepeatables.ActiveQuests.Add(quest);
|
||||
}
|
||||
|
||||
@@ -674,7 +674,7 @@ public class RepeatableQuestController(
|
||||
{
|
||||
// PMC and daily quests not unlocked yet
|
||||
if (
|
||||
repeatableConfig.Side == "Pmc"
|
||||
repeatableConfig.Side == PlayerGroup.Pmc
|
||||
&& !PlayerHasDailyPmcQuestsUnlocked(pmcData, repeatableConfig)
|
||||
)
|
||||
{
|
||||
@@ -682,7 +682,7 @@ public class RepeatableQuestController(
|
||||
}
|
||||
|
||||
// Scav and daily quests not unlocked yet
|
||||
if (repeatableConfig.Side == "Scav" && !PlayerHasDailyScavQuestsUnlocked(pmcData))
|
||||
if (repeatableConfig.Side == PlayerGroup.Scav && !PlayerHasDailyScavQuestsUnlocked(pmcData))
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
@@ -875,7 +875,7 @@ public class RepeatableQuestController(
|
||||
/// <returns>Quest count</returns>
|
||||
protected int GetQuestCount(RepeatableQuestConfig repeatableConfig, SptProfile fullProfile)
|
||||
{
|
||||
var questCount = repeatableConfig.NumQuests.GetValueOrDefault(0);
|
||||
var questCount = repeatableConfig.NumQuests;
|
||||
if (questCount == 0)
|
||||
{
|
||||
_logger.Warning($"Repeatable: {repeatableConfig.Name} quests have a count of 0");
|
||||
|
||||
@@ -1046,13 +1046,13 @@ public class RepeatableQuestGenerator(
|
||||
/// Filter a maps exits to just those for the desired side
|
||||
/// </summary>
|
||||
/// <param name="locationKey">Map id (e.g. factory4_day)</param>
|
||||
/// <param name="playerSide">Scav/Pmc</param>
|
||||
/// <param name="playerGroup">Pmc/Scav</param>
|
||||
/// <returns>List of Exit objects</returns>
|
||||
protected List<Exit> GetLocationExitsForSide(string locationKey, string playerSide)
|
||||
protected List<Exit> GetLocationExitsForSide(string locationKey, PlayerGroup playerGroup)
|
||||
{
|
||||
var mapExtracts = _databaseService.GetLocation(locationKey.ToLower()).AllExtracts;
|
||||
|
||||
return mapExtracts.Where(exit => exit.Side == playerSide).ToList();
|
||||
return mapExtracts.Where(exit => exit.Side == Enum.GetName(playerGroup)).ToList();
|
||||
}
|
||||
|
||||
protected RepeatableQuest GeneratePickupQuest(
|
||||
@@ -1149,7 +1149,7 @@ public class RepeatableQuestGenerator(
|
||||
/// </summary>
|
||||
/// <param name="type">Quest type: "Elimination", "Completion" or "Extraction"</param>
|
||||
/// <param name="traderId">Trader from which the quest will be provided</param>
|
||||
/// <param name="side">Scav daily or pmc daily/weekly quest</param>
|
||||
/// <param name="playerGroup">Scav daily or pmc daily/weekly quest</param>
|
||||
/// <returns>
|
||||
/// Object which contains the base elements for repeatable quests of the requests type
|
||||
/// (needs to be filled with reward and conditions by called to make a valid quest)
|
||||
@@ -1157,7 +1157,7 @@ public class RepeatableQuestGenerator(
|
||||
protected RepeatableQuest GenerateRepeatableTemplate(
|
||||
string type,
|
||||
string traderId,
|
||||
string side,
|
||||
PlayerGroup playerGroup,
|
||||
string sessionId
|
||||
)
|
||||
{
|
||||
@@ -1188,28 +1188,9 @@ public class RepeatableQuestGenerator(
|
||||
*/
|
||||
|
||||
// Get template id from config based on side and type of quest
|
||||
var typeIds = string.Equals(side, "pmc", StringComparison.OrdinalIgnoreCase)
|
||||
? _questConfig.QuestTemplateIds.Pmc
|
||||
: _questConfig.QuestTemplateIds.Scav;
|
||||
var typeIds = _repeatableQuestHelper.GetRepeatableQuestTemplatesByGroup(playerGroup);
|
||||
|
||||
var templateId = string.Empty;
|
||||
switch (type)
|
||||
{
|
||||
case "Completion":
|
||||
templateId = typeIds.Completion;
|
||||
break;
|
||||
case "Elimination":
|
||||
templateId = typeIds.Elimination;
|
||||
break;
|
||||
case "Exploration":
|
||||
templateId = typeIds.Exploration;
|
||||
break;
|
||||
case "Pickup":
|
||||
templateId = typeIds.Pickup;
|
||||
break;
|
||||
}
|
||||
|
||||
questClone.TemplateId = templateId;
|
||||
questClone.TemplateId = typeIds[type];
|
||||
|
||||
// Force REF templates to use prapors ID - solves missing text issue
|
||||
var desiredTraderId = traderId == Traders.REF ? Traders.PRAPOR : traderId;
|
||||
@@ -1217,30 +1198,39 @@ public class RepeatableQuestGenerator(
|
||||
questClone.Name = questClone
|
||||
.Name.Replace("{traderId}", traderId)
|
||||
.Replace("{templateId}", questClone.TemplateId);
|
||||
|
||||
questClone.Note = questClone
|
||||
.Note.Replace("{traderId}", desiredTraderId)
|
||||
.Replace("{templateId}", questClone.TemplateId);
|
||||
|
||||
questClone.Description = questClone
|
||||
.Description.Replace("{traderId}", desiredTraderId)
|
||||
.Replace("{templateId}", questClone.TemplateId);
|
||||
|
||||
questClone.SuccessMessageText = questClone
|
||||
.SuccessMessageText.Replace("{traderId}", desiredTraderId)
|
||||
.Replace("{templateId}", questClone.TemplateId);
|
||||
|
||||
questClone.FailMessageText = questClone
|
||||
.FailMessageText.Replace("{traderId}", desiredTraderId)
|
||||
.Replace("{templateId}", questClone.TemplateId);
|
||||
|
||||
questClone.StartedMessageText = questClone
|
||||
.StartedMessageText.Replace("{traderId}", desiredTraderId)
|
||||
.Replace("{templateId}", questClone.TemplateId);
|
||||
|
||||
questClone.ChangeQuestMessageText = questClone
|
||||
.ChangeQuestMessageText.Replace("{traderId}", desiredTraderId)
|
||||
.Replace("{templateId}", questClone.TemplateId);
|
||||
|
||||
questClone.AcceptPlayerMessage = questClone
|
||||
.AcceptPlayerMessage.Replace("{traderId}", desiredTraderId)
|
||||
.Replace("{templateId}", questClone.TemplateId);
|
||||
|
||||
questClone.DeclinePlayerMessage = questClone
|
||||
.DeclinePlayerMessage.Replace("{traderId}", desiredTraderId)
|
||||
.Replace("{templateId}", questClone.TemplateId);
|
||||
|
||||
questClone.CompletePlayerMessage = questClone
|
||||
.CompletePlayerMessage.Replace("{traderId}", desiredTraderId)
|
||||
.Replace("{templateId}", questClone.TemplateId);
|
||||
|
||||
@@ -513,7 +513,7 @@ public class QuestHelper(
|
||||
|
||||
// Should non-season event quests be shown to player
|
||||
if (
|
||||
!(_questConfig.ShowNonSeasonalEventQuests ?? false)
|
||||
!_questConfig.ShowNonSeasonalEventQuests
|
||||
&& _seasonalEventService.IsQuestRelatedToEvent(questId, SeasonalEventType.None)
|
||||
)
|
||||
{
|
||||
@@ -1173,10 +1173,10 @@ public class QuestHelper(
|
||||
{
|
||||
if (!_questConfig.MailRedeemTimeHours.TryGetValue(pmcData.Info.GameVersion, out var hours))
|
||||
{
|
||||
return _questConfig.MailRedeemTimeHours["default"] ?? 48;
|
||||
return _questConfig.MailRedeemTimeHours["default"];
|
||||
}
|
||||
|
||||
return hours ?? 48;
|
||||
return hours;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Spt.Config;
|
||||
using SPTarkov.Server.Core.Models.Utils;
|
||||
using SPTarkov.Server.Core.Servers;
|
||||
|
||||
namespace SPTarkov.Server.Core.Helpers;
|
||||
|
||||
[Injectable]
|
||||
public class RepeatableQuestHelper(ISptLogger<RepeatableQuestHelper> _logger)
|
||||
public class RepeatableQuestHelper(
|
||||
ISptLogger<RepeatableQuestHelper> _logger,
|
||||
ConfigServer _configServer
|
||||
)
|
||||
{
|
||||
protected QuestConfig _questConfig = _configServer.GetConfig<QuestConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Get the relevant elimination config based on the current players PMC level
|
||||
/// </summary>
|
||||
@@ -22,4 +29,22 @@ public class RepeatableQuestHelper(ISptLogger<RepeatableQuestHelper> _logger)
|
||||
pmcLevel >= x.LevelRange.Min && pmcLevel <= x.LevelRange.Max
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the repeatable template ids for the provided side
|
||||
/// </summary>
|
||||
/// <param name="playerGroup">Side to get the templates for</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
public Dictionary<string, string>? GetRepeatableQuestTemplatesByGroup(PlayerGroup playerGroup)
|
||||
{
|
||||
var templates = _questConfig.RepeatableQuestTemplates;
|
||||
|
||||
return playerGroup switch
|
||||
{
|
||||
PlayerGroup.Pmc => templates.Pmc,
|
||||
PlayerGroup.Scav => templates.Scav,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(playerGroup), playerGroup, null)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using SPTarkov.Server.Core.Utils.Json.Converters;
|
||||
|
||||
namespace SPTarkov.Server.Core.Models.Enums;
|
||||
|
||||
[EftEnumConverter]
|
||||
public enum PlayerGroup
|
||||
{
|
||||
Pmc,
|
||||
Scav
|
||||
}
|
||||
@@ -15,73 +15,81 @@ public record QuestConfig : BaseConfig
|
||||
/// Hours to get/redeem items from quest mail keyed by profile type
|
||||
/// </summary>
|
||||
[JsonPropertyName("mailRedeemTimeHours")]
|
||||
public Dictionary<string, double?>? MailRedeemTimeHours { get; set; }
|
||||
|
||||
[JsonPropertyName("questTemplateIds")]
|
||||
public PlayerTypeQuestIds? QuestTemplateIds { get; set; }
|
||||
public required Dictionary<string, double> MailRedeemTimeHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Show non-seasonal quests be shown to player
|
||||
/// Collection of quests by id only available to usec
|
||||
/// </summary>
|
||||
[JsonPropertyName("showNonSeasonalEventQuests")]
|
||||
public bool? ShowNonSeasonalEventQuests { get; set; }
|
||||
|
||||
[JsonPropertyName("eventQuests")]
|
||||
public Dictionary<string, EventQuestData>? EventQuests { get; set; }
|
||||
|
||||
[JsonPropertyName("repeatableQuests")]
|
||||
public List<RepeatableQuestConfig>? RepeatableQuests { get; set; }
|
||||
|
||||
[JsonPropertyName("locationIdMap")]
|
||||
public Dictionary<string, string>? LocationIdMap { get; set; }
|
||||
|
||||
[JsonPropertyName("bearOnlyQuests")]
|
||||
public HashSet<string>? BearOnlyQuests { get; set; }
|
||||
|
||||
[JsonPropertyName("usecOnlyQuests")]
|
||||
public HashSet<string>? UsecOnlyQuests { get; set; }
|
||||
public required HashSet<string> UsecOnlyQuests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Collection of quests by id only available to bears
|
||||
/// </summary>
|
||||
[JsonPropertyName("bearOnlyQuests")]
|
||||
public required HashSet<string> BearOnlyQuests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quests that the keyed game version do not see/access
|
||||
/// </summary>
|
||||
[JsonPropertyName("profileBlacklist")]
|
||||
public Dictionary<string, HashSet<string>>? ProfileBlacklist { get; set; }
|
||||
public required Dictionary<string, HashSet<string>> ProfileBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// key=questid, gameversions that can see/access quest
|
||||
/// </summary>
|
||||
[JsonPropertyName("profileWhitelist")]
|
||||
public Dictionary<string, HashSet<string>>? ProfileWhitelist { get; set; }
|
||||
public required Dictionary<string, HashSet<string>> ProfileWhitelist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds repeatable quest template ids for pmc's and scav's
|
||||
/// </summary>
|
||||
[JsonPropertyName("repeatableQuestTemplateIds")]
|
||||
public required RepeatableQuestTemplates RepeatableQuestTemplates { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Show non-seasonal quests be shown to players
|
||||
/// </summary>
|
||||
[JsonPropertyName("showNonSeasonalEventQuests")]
|
||||
public required bool ShowNonSeasonalEventQuests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Collection of event quest data keyed by quest id.
|
||||
/// </summary>
|
||||
[JsonPropertyName("eventQuests")]
|
||||
public required Dictionary<string, EventQuestData> EventQuests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// List of repeatable quest configs for; daily, weekly, and daily scav.
|
||||
/// </summary>
|
||||
[JsonPropertyName("repeatableQuests")]
|
||||
public required List<RepeatableQuestConfig> RepeatableQuests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maps internal map names to their mongoId: Key - internal :: val - Mongoid
|
||||
/// </summary>
|
||||
[JsonPropertyName("locationIdMap")]
|
||||
public required Dictionary<string, string> LocationIdMap { get; set; }
|
||||
}
|
||||
|
||||
public record PlayerTypeQuestIds
|
||||
public record RepeatableQuestTemplates
|
||||
{
|
||||
[JsonExtensionData]
|
||||
public Dictionary<string, object> ExtensionData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pmc repeatable quest template ids keyed by type of quest
|
||||
/// Keys: elimination, completion, exploration
|
||||
/// </summary>
|
||||
[JsonPropertyName("pmc")]
|
||||
public QuestTypeIds? Pmc { get; set; }
|
||||
public required Dictionary<string, string> Pmc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Scav repeatable quest template ids keyed by type of quest
|
||||
/// Keys: elimination, completion, exploration, pickup
|
||||
/// </summary>
|
||||
[JsonPropertyName("scav")]
|
||||
public QuestTypeIds? Scav { get; set; }
|
||||
}
|
||||
|
||||
public record QuestTypeIds
|
||||
{
|
||||
[JsonExtensionData]
|
||||
public Dictionary<string, object> ExtensionData { get; set; }
|
||||
|
||||
[JsonPropertyName("elimination")]
|
||||
public string? Elimination { get; set; }
|
||||
|
||||
[JsonPropertyName("completion")]
|
||||
public string? Completion { get; set; }
|
||||
|
||||
[JsonPropertyName("exploration")]
|
||||
public string? Exploration { get; set; }
|
||||
|
||||
[JsonPropertyName("pickup")]
|
||||
public string? Pickup { get; set; }
|
||||
public required Dictionary<string, string> Scav { get; set; }
|
||||
}
|
||||
|
||||
public record EventQuestData
|
||||
@@ -89,21 +97,36 @@ public record EventQuestData
|
||||
[JsonExtensionData]
|
||||
public Dictionary<string, object> ExtensionData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the event quest
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
public required string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Season to which this quest belongs
|
||||
/// </summary>
|
||||
[JsonPropertyName("season")]
|
||||
public SeasonalEventType? Season { get; set; }
|
||||
public required SeasonalEventType Season { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Start timestamp
|
||||
/// </summary>
|
||||
[JsonPropertyName("startTimestamp")]
|
||||
public long? StartTimestamp { get; set; }
|
||||
public required long StartTimestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// End timestamp
|
||||
/// </summary>
|
||||
[JsonPropertyName("endTimestamp")]
|
||||
[JsonConverter(typeof(StringToNumberFactoryConverter))]
|
||||
public long? EndTimestamp { get; set; }
|
||||
public required long EndTimestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is this quest part of a yearly event, ex: Christmas
|
||||
/// </summary>
|
||||
[JsonPropertyName("yearly")]
|
||||
public bool? Yearly { get; set; }
|
||||
public required bool Yearly { get; set; }
|
||||
}
|
||||
|
||||
public record RepeatableQuestConfig
|
||||
@@ -111,68 +134,115 @@ public record RepeatableQuestConfig
|
||||
[JsonExtensionData]
|
||||
public Dictionary<string, object> ExtensionData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id for type of repeatable quest
|
||||
/// </summary>
|
||||
[JsonPropertyName("id")]
|
||||
public string? Id { get; set; }
|
||||
public required string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Human-readable name for repeatable quest type
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
public required string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Side this config belongs to. Note: Random not implemented, do not use!
|
||||
/// </summary>
|
||||
[JsonPropertyName("side")]
|
||||
public string? Side { get; set; }
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public required PlayerGroup Side { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Types of tasks this config can generate; ex: Elimination
|
||||
/// </summary>
|
||||
[JsonPropertyName("types")]
|
||||
public List<string>? Types { get; set; }
|
||||
public required List<string> Types { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How long does the task stay active for after accepting it
|
||||
/// </summary>
|
||||
[JsonPropertyName("resetTime")]
|
||||
public long? ResetTime { get; set; }
|
||||
public required long ResetTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many quests should we provide per ResetTime
|
||||
/// </summary>
|
||||
[JsonPropertyName("numQuests")]
|
||||
public int? NumQuests { get; set; }
|
||||
public required int NumQuests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Min player level required to receive a quest from this config
|
||||
/// </summary>
|
||||
[JsonPropertyName("minPlayerLevel")]
|
||||
public int? MinPlayerLevel { get; set; }
|
||||
public required int MinPlayerLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reward scaling config
|
||||
/// </summary>
|
||||
[JsonPropertyName("rewardScaling")]
|
||||
public RewardScaling? RewardScaling { get; set; }
|
||||
public required RewardScaling RewardScaling { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Location map
|
||||
/// </summary>
|
||||
[JsonPropertyName("locations")]
|
||||
public Dictionary<ELocationName, List<string>>? Locations { get; set; }
|
||||
public required Dictionary<ELocationName, List<string>> Locations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Traders that are allowed to generate tasks from this config.
|
||||
/// Includes quest types, reward whitelist, and whether rewards can be weapons.
|
||||
/// </summary>
|
||||
[JsonPropertyName("traderWhitelist")]
|
||||
public List<TraderWhitelist>? TraderWhitelist { get; set; }
|
||||
public required List<TraderWhitelist> TraderWhitelist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Quest config, holds information on how a task should be generated
|
||||
/// </summary>
|
||||
[JsonPropertyName("questConfig")]
|
||||
public RepeatableQuestTypesConfig? QuestConfig { get; set; }
|
||||
public RepeatableQuestTypesConfig QuestConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Item base types to block when generating rewards
|
||||
/// </summary>
|
||||
[JsonPropertyName("rewardBaseTypeBlacklist")]
|
||||
public HashSet<string>? RewardBaseTypeBlacklist { get; set; }
|
||||
public required HashSet<string> RewardBaseTypeBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Item tplIds to ignore when generating rewards
|
||||
/// </summary>
|
||||
[JsonPropertyName("rewardBlacklist")]
|
||||
public HashSet<string>? RewardBlacklist { get; set; }
|
||||
public required HashSet<string> RewardBlacklist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum stack size that an ammo reward should be generated with
|
||||
/// </summary>
|
||||
[JsonPropertyName("rewardAmmoStackMinSize")]
|
||||
public int? RewardAmmoStackMinSize { get; set; }
|
||||
public required int RewardAmmoStackMinSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many free task changes are available from this config
|
||||
/// </summary>
|
||||
[JsonPropertyName("freeChangesAvailable")]
|
||||
public int? FreeChangesAvailable { get; set; }
|
||||
public required int FreeChangesAvailable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How many free task changes remain from this config
|
||||
/// </summary>
|
||||
[JsonPropertyName("freeChanges")]
|
||||
public int? FreeChanges { get; set; }
|
||||
public required int FreeChanges { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should the task replacement category be the same as the one its replacing
|
||||
/// </summary>
|
||||
[JsonPropertyName("keepDailyQuestTypeOnReplacement")]
|
||||
public bool? KeepDailyQuestTypeOnReplacement { get; set; }
|
||||
public required bool KeepDailyQuestTypeOnReplacement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reputation standing price for replacing a repeatable
|
||||
/// </summary>
|
||||
[JsonPropertyName("standingChangeCost")]
|
||||
public IList<double>? StandingChangeCost { get; set; }
|
||||
public required IList<double> StandingChangeCost { get; set; }
|
||||
}
|
||||
|
||||
public record RewardScaling
|
||||
|
||||
Reference in New Issue
Block a user