fix with null guards
This commit is contained in:
@@ -74,27 +74,27 @@ public class AssortHelper(
|
||||
Dictionary<string, Dictionary<string, string>> mergedQuestAssorts,
|
||||
string assortId)
|
||||
{
|
||||
if (mergedQuestAssorts.Get<Dictionary<string, string>>("started").Contains(assortId))
|
||||
if (mergedQuestAssorts.TryGetValue("started", out var dict1) && dict1.Contains(assortId))
|
||||
{
|
||||
// Assort unlocked by starting quest, assort is visible to player when : started or ready to hand in + handed in
|
||||
return new KeyValuePair<string, List<QuestStatusEnum>>(
|
||||
mergedQuestAssorts.Get<Dictionary<string, string>>("started")[assortId],
|
||||
mergedQuestAssorts["started"][assortId],
|
||||
[QuestStatusEnum.Started, QuestStatusEnum.AvailableForFinish, QuestStatusEnum.Success]
|
||||
);
|
||||
}
|
||||
|
||||
if (mergedQuestAssorts.Get<Dictionary<string, string>>("success").Contains(assortId))
|
||||
if (mergedQuestAssorts.TryGetValue("started", out var dict2) && dict2.Contains(assortId))
|
||||
{
|
||||
return new KeyValuePair<string, List<QuestStatusEnum>>(
|
||||
mergedQuestAssorts.Get<Dictionary<string, string>>("success")[assortId],
|
||||
mergedQuestAssorts["success"][assortId],
|
||||
[QuestStatusEnum.Success]
|
||||
);
|
||||
}
|
||||
|
||||
if (mergedQuestAssorts.Get<Dictionary<string, string>>("fail").Contains(assortId))
|
||||
if (mergedQuestAssorts.TryGetValue("fail", out var dict3) && dict3.Contains(assortId))
|
||||
{
|
||||
return new KeyValuePair<string, List<QuestStatusEnum>>(
|
||||
mergedQuestAssorts.Get<Dictionary<string, string>>("success")[assortId],
|
||||
mergedQuestAssorts["fail"][assortId],
|
||||
[QuestStatusEnum.Fail]
|
||||
);
|
||||
}
|
||||
@@ -143,9 +143,9 @@ public class AssortHelper(
|
||||
{
|
||||
var idsToRemove = _itemHelper.FindAndReturnChildrenByItems(assort.Items, itemID);
|
||||
|
||||
if (assort.BarterScheme[itemID] is not null && flea)
|
||||
if (assort.BarterScheme.TryGetValue(itemID, out var lisToUse) && lisToUse is not null && flea)
|
||||
{
|
||||
foreach (var barterSchemes in assort.BarterScheme[itemID])
|
||||
foreach (var barterSchemes in lisToUse)
|
||||
{
|
||||
foreach (var barterScheme in barterSchemes)
|
||||
{
|
||||
|
||||
@@ -72,7 +72,7 @@ public class TraderAssortHelper(
|
||||
traderId
|
||||
);
|
||||
|
||||
foreach (var assortId in assortPurchasesfromTrader)
|
||||
foreach (var assortId in assortPurchasesfromTrader ?? [])
|
||||
{
|
||||
// Find assort we want to update current buy count of
|
||||
var assortToAdjust = traderClone.Assort.Items.FirstOrDefault(x => x.Id == assortId.Key);
|
||||
@@ -159,24 +159,25 @@ public class TraderAssortHelper(
|
||||
{
|
||||
// Loop every trader
|
||||
var traders = _databaseService.GetTraders();
|
||||
foreach (var trader in traders)
|
||||
foreach (var traderId in traders)
|
||||
{
|
||||
// Trader has quest assort data
|
||||
if (trader.Value.QuestAssort is not null)
|
||||
var trader = traders[traderId.Key];
|
||||
if (trader.QuestAssort is not null)
|
||||
{
|
||||
// Started/Success/fail
|
||||
foreach (var assort in trader.Value.QuestAssort)
|
||||
foreach (var questStatus in trader.QuestAssort)
|
||||
{
|
||||
// Each assort to quest id record
|
||||
foreach (var assortId in assort.Value.Values)
|
||||
foreach (var assortId in trader.QuestAssort[questStatus.Key])
|
||||
{
|
||||
// Null guard
|
||||
if (!_mergedQuestAssorts.TryGetValue(assortId, out var _))
|
||||
if (!_mergedQuestAssorts.TryGetValue(questStatus.Key, out var _))
|
||||
{
|
||||
_mergedQuestAssorts.TryAdd(assortId, new Dictionary<string, string>());
|
||||
_mergedQuestAssorts.TryAdd(questStatus.Key, new Dictionary<string, string>());
|
||||
}
|
||||
|
||||
_mergedQuestAssorts[assort.Key][assortId] = trader.Value.QuestAssort[assort.Key][assortId];
|
||||
_mergedQuestAssorts[questStatus.Key][assortId.Key] = trader.QuestAssort[questStatus.Key][assortId.Key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,16 +130,22 @@ public class TraderHelper(
|
||||
ProfileTraderTemplate rawProfileTemplate =
|
||||
profiles[fullProfile.ProfileInfo.Edition][pmcData.Info.Side.ToLower()].Trader;
|
||||
|
||||
pmcData.TradersInfo[traderID] = new TraderInfo
|
||||
var newTraderData = new TraderInfo
|
||||
{
|
||||
Disabled = false,
|
||||
LoyaltyLevel = rawProfileTemplate.InitialLoyaltyLevel[traderID] ?? 1,
|
||||
LoyaltyLevel = rawProfileTemplate.InitialLoyaltyLevel.TryGetValue(traderID, out var value) ? value : 4,
|
||||
SalesSum = rawProfileTemplate.InitialSalesSum,
|
||||
Standing = GetStartingStanding(traderID, rawProfileTemplate),
|
||||
NextResupply = trader.Base.NextResupply,
|
||||
Unlocked = trader.Base.UnlockedByDefault
|
||||
};
|
||||
|
||||
if (!pmcData.TradersInfo.TryAdd(traderID, newTraderData))
|
||||
{
|
||||
pmcData.TradersInfo[traderID] = newTraderData;
|
||||
}
|
||||
|
||||
|
||||
// Check if trader should be locked by default
|
||||
if (rawProfileTemplate.LockedByDefaultOverride?.Contains(traderID) ?? false)
|
||||
{
|
||||
@@ -192,15 +198,20 @@ public class TraderHelper(
|
||||
/// <param name="traderId">Trader id to get standing for</param>
|
||||
/// <param name="rawProfileTemplate">Raw profile from profiles.json to look up standing from</param>
|
||||
/// <returns>Standing value</returns>
|
||||
protected double GetStartingStanding(string traderId, ProfileTraderTemplate rawProfileTemplate)
|
||||
protected double? GetStartingStanding(string traderId, ProfileTraderTemplate rawProfileTemplate)
|
||||
{
|
||||
var initialStanding = rawProfileTemplate.InitialStanding[traderId] ?? 0D;
|
||||
// Edge case for Lightkeeper, 0 standing means seeing `Make Amends - Buyout` quest
|
||||
if (traderId == Traders.LIGHTHOUSEKEEPER && initialStanding == 0) {
|
||||
return 0.01;
|
||||
if (rawProfileTemplate.InitialStanding.TryGetValue(traderId, out var standing))
|
||||
{
|
||||
// Edge case for Lightkeeper, 0 standing means seeing `Make Amends - Buyout` quest
|
||||
if (traderId == Traders.LIGHTHOUSEKEEPER && standing == 0)
|
||||
{
|
||||
return 0.01;
|
||||
}
|
||||
|
||||
return standing;
|
||||
}
|
||||
|
||||
return initialStanding;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -210,13 +221,16 @@ public class TraderHelper(
|
||||
/// <param name="suitIds">Suit Ids to add</param>
|
||||
protected void AddSuitsToProfile(SptProfile fullProfile, List<string> suitIds)
|
||||
{
|
||||
if (fullProfile.Suits is null) {
|
||||
if (fullProfile.Suits is null)
|
||||
{
|
||||
fullProfile.Suits = [];
|
||||
}
|
||||
|
||||
foreach (var suitId in suitIds) {
|
||||
foreach (var suitId in suitIds)
|
||||
{
|
||||
// Don't add dupes
|
||||
if (!fullProfile.Suits.Contains(suitId)) {
|
||||
if (!fullProfile.Suits.Contains(suitId))
|
||||
{
|
||||
fullProfile.Suits.Add(suitId);
|
||||
}
|
||||
}
|
||||
@@ -232,7 +246,8 @@ public class TraderHelper(
|
||||
{
|
||||
var pmcData = _profileHelper.GetPmcProfile(sessionId);
|
||||
var profileTraderData = pmcData.TradersInfo[traderId];
|
||||
if (profileTraderData is null) {
|
||||
if (profileTraderData is null)
|
||||
{
|
||||
_logger.Error($"Unable to set trader {traderId} unlocked state to: {status} as trader cannot be found in profile");
|
||||
|
||||
return;
|
||||
@@ -255,7 +270,8 @@ public class TraderHelper(
|
||||
// Add standing to trader
|
||||
pmcTraderInfo.Standing = AddStandingValuesTogether(pmcTraderInfo.Standing, standingToAdd);
|
||||
|
||||
if (traderId == Traders.FENCE) {
|
||||
if (traderId == Traders.FENCE)
|
||||
{
|
||||
// Must add rep to scav profile to ensure consistency
|
||||
fullProfile.CharacterData.ScavData.TradersInfo[traderId].Standing = pmcTraderInfo.Standing;
|
||||
}
|
||||
@@ -285,7 +301,8 @@ public class TraderHelper(
|
||||
{
|
||||
var profile = _profileHelper.GetPmcProfile(sessionId);
|
||||
var traders = _databaseService.GetTraders();
|
||||
foreach (var trader in traders) {
|
||||
foreach (var trader in traders)
|
||||
{
|
||||
this.LevelUp(trader.Key, profile);
|
||||
}
|
||||
}
|
||||
@@ -309,12 +326,14 @@ public class TraderHelper(
|
||||
// Round standing to 2 decimal places to address floating point inaccuracies
|
||||
pmcData.TradersInfo[traderID].Standing = Math.Round((pmcData.TradersInfo[traderID].Standing * 100) ?? 0) / 100;
|
||||
|
||||
foreach (var loyaltyLevel in loyaltyLevels) {
|
||||
foreach (var loyaltyLevel in loyaltyLevels)
|
||||
{
|
||||
if (loyaltyLevel.MinLevel <= pmcData.Info.Level &&
|
||||
loyaltyLevel.MinSalesSum <= pmcData.TradersInfo[traderID].SalesSum &&
|
||||
loyaltyLevel.MinStanding <= pmcData.TradersInfo[traderID].Standing &&
|
||||
targetLevel < 4
|
||||
) {
|
||||
)
|
||||
{
|
||||
// level reached
|
||||
targetLevel++;
|
||||
}
|
||||
|
||||
@@ -508,7 +508,7 @@ public class FenceService(
|
||||
var fenceLevels = fenceSettings.Levels.Select(x => x.Key);
|
||||
var minLevel = fenceLevels.Min();
|
||||
var maxLevel = fenceLevels.Max();
|
||||
var pmcFenceLevel = Math.Floor(pmcFenceInfo.Standing.Value);
|
||||
var pmcFenceLevel = Math.Floor(pmcFenceInfo.Standing ?? 0);
|
||||
|
||||
if (pmcFenceLevel < int.Parse(minLevel))
|
||||
{
|
||||
|
||||
@@ -21,8 +21,13 @@ namespace SptCommon.Extensions
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Contains<T>(this object obj, T key)
|
||||
public static bool Contains<T>(this object? obj, T key)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(obj));
|
||||
}
|
||||
|
||||
return TryGetCachedProperty(obj.GetType(), key.ToString(), out _);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user