Added more comments
This commit is contained in:
@@ -17,10 +17,10 @@ public class RepairController(
|
||||
/// Handle TraderRepair event
|
||||
/// Repair with trader
|
||||
/// </summary>
|
||||
/// <param name="sessionId">session id</param>
|
||||
/// <param name="sessionID">session id</param>
|
||||
/// <param name="body">endpoint request data</param>
|
||||
/// <param name="pmcData">player profile</param>
|
||||
/// <returns>item event router action</returns>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse TraderRepair(
|
||||
string sessionID,
|
||||
TraderRepairActionDataRequest body,
|
||||
@@ -64,7 +64,7 @@ public class RepairController(
|
||||
/// <param name="sessionId">session id</param>
|
||||
/// <param name="body">endpoint request data</param>
|
||||
/// <param name="pmcData">player profile</param>
|
||||
/// <returns></returns>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse RepairWithKit(
|
||||
string sessionId,
|
||||
RepairActionDataRequest body,
|
||||
|
||||
@@ -43,6 +43,13 @@ public class RepeatableQuestController(
|
||||
{
|
||||
protected QuestConfig _questConfig = _configServer.GetConfig<QuestConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// Handle RepeatableQuestChange event
|
||||
/// </summary>
|
||||
/// <param name="pmcData"></param>
|
||||
/// <param name="changeRequest">Change quest request</param>
|
||||
/// <param name="sessionID"></param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse ChangeRepeatableQuest(PmcData pmcData, RepeatableQuestChangeRequest changeRequest,
|
||||
string sessionID)
|
||||
{
|
||||
@@ -175,14 +182,15 @@ public class RepeatableQuestController(
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some accounts have access to free repeatable quest refreshes
|
||||
* Track the usage of them inside players profile
|
||||
* @param fullProfile Player profile
|
||||
* @param repeatableSubType Can be daily / weekly / scav repeatable
|
||||
* @param repeatableTypeName Subtype of repeatable quest: daily / weekly / scav
|
||||
* @returns Is the repeatable being replaced for free
|
||||
*/
|
||||
/// <summary>
|
||||
/// Some accounts have access to free repeatable quest refreshes
|
||||
/// Track the usage of them inside players profile
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fullProfile">Full player profile</param>
|
||||
/// <param name="repeatableSubType">Can be daily / weekly / scav repeatable</param>
|
||||
/// <param name="repeatableTypeName">Subtype of repeatable quest: daily / weekly / scav</param>
|
||||
/// <returns>Is the repeatable being replaced for free</returns>
|
||||
protected bool UseFreeRefreshIfAvailable(SptProfile? fullProfile, PmcDataRepeatableQuest repeatableSubType,
|
||||
string repeatableTypeName)
|
||||
{
|
||||
@@ -218,11 +226,11 @@ public class RepeatableQuestController(
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the repeatables `changeRequirement` dictionary of expired data
|
||||
* @param repeatablesOfTypeInProfile The repeatables that have the replaced and new quest
|
||||
* @param replacedQuestId Id of the replaced quest
|
||||
*/
|
||||
/// <summary>
|
||||
/// Clean up the repeatables `changeRequirement` dictionary of expired data
|
||||
/// </summary>
|
||||
/// <param name="repeatablesOfTypeInProfile">repeatables that have the replaced and new quest</param>
|
||||
/// <param name="replacedQuestId">Id of the replaced quest</param>
|
||||
protected void CleanUpRepeatableChangeRequirements(PmcDataRepeatableQuest repeatablesOfTypeInProfile,
|
||||
string replacedQuestId)
|
||||
{
|
||||
@@ -239,6 +247,14 @@ public class RepeatableQuestController(
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a repeatable quest
|
||||
/// </summary>
|
||||
/// <param name="sessionId"></param>
|
||||
/// <param name="pmcData"></param>
|
||||
/// <param name="questTypePool">What type/level range of quests can be generated for player</param>
|
||||
/// <param name="repeatableConfig">Config for the quest type to generate</param>
|
||||
/// <returns></returns>
|
||||
protected RepeatableQuest? AttemptToGenerateRepeatableQuest(string sessionId, PmcData pmcData,
|
||||
QuestTypePool questTypePool, RepeatableQuestConfig repeatableConfig)
|
||||
{
|
||||
@@ -272,6 +288,11 @@ public class RepeatableQuestController(
|
||||
return newRepeatableQuest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the provided quest from pmc and scav character profiles
|
||||
/// </summary>
|
||||
/// <param name="fullProfile">Profile to remove quest from</param>
|
||||
/// <param name="questToReplaceId">Quest id to remove from profile</param>
|
||||
protected void RemoveQuestFromProfile(SptProfile? fullProfile, string questToReplaceId)
|
||||
{
|
||||
// Find quest we're replacing in pmc profile quests array and remove it
|
||||
@@ -287,12 +308,13 @@ public class RepeatableQuestController(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a repeatable (daily/weekly/scav) from a players profile by its id
|
||||
* @param questId Id of quest to find
|
||||
* @param pmcData Profile that contains quests to look through
|
||||
* @returns IGetRepeatableByIdResult
|
||||
*/
|
||||
/// <summary>
|
||||
/// Find a repeatable (daily/weekly/scav) from a players profile by its id
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="questId">Id of quest to find</param>
|
||||
/// <param name="pmcData">Profile that contains quests to look through</param>
|
||||
/// <returns></returns>
|
||||
protected GetRepeatableByIdResult GetRepeatableById(string questId, PmcData pmcData)
|
||||
{
|
||||
foreach (var repeatablesInProfile in pmcData.RepeatableQuests)
|
||||
@@ -316,6 +338,29 @@ public class RepeatableQuestController(
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle client/repeatalbeQuests/activityPeriods
|
||||
/// Returns an array of objects in the format of repeatable quests to the client.
|
||||
/// repeatableQuestObject = {
|
||||
/// *id: Unique Id,
|
||||
///name: "Daily",
|
||||
///endTime: the time when the quests expire
|
||||
///activeQuests: currently available quests in an array. Each element of quest type format(see assets/ database / templates / repeatableQuests.json).
|
||||
///inactiveQuests: the quests which were previously active(required by client to fail them if they are not completed)
|
||||
/// }
|
||||
///
|
||||
/// The method checks if the player level requirement for repeatable quests(e.g.daily lvl5, weekly lvl15) is met and if the previously active quests
|
||||
/// are still valid.This ischecked by endTime persisted in profile accordning to the resetTime configured for each repeatable kind(daily, weekly)
|
||||
/// in QuestCondig.js
|
||||
///
|
||||
/// If the condition is met, new repeatableQuests are created, old quests(which are persisted in the profile.RepeatableQuests[i].activeQuests) are
|
||||
/// moved to profile.RepeatableQuests[i].inactiveQuests.This memory is required to get rid of old repeatable quest data in the profile, otherwise
|
||||
/// they'll litter the profile's Quests field.
|
||||
/// (if the are on "Succeed" but not "Completed" we keep them, to allow the player to complete them and get the rewards)
|
||||
/// The new quests generated are again persisted in profile.RepeatableQuests
|
||||
/// </summary>
|
||||
/// <param name="sessionID"></param>
|
||||
/// <returns>Array of repeatable quests</returns>
|
||||
public List<PmcDataRepeatableQuest> GetClientRepeatableQuests(string sessionID)
|
||||
{
|
||||
var returnData = new List<PmcDataRepeatableQuest>();
|
||||
@@ -446,6 +491,12 @@ public class RepeatableQuestController(
|
||||
return returnData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get repeatable quest data from profile from name (daily/weekly), creates base repeatable quest object if none exists
|
||||
/// </summary>
|
||||
/// <param name="repeatableConfig">daily/weekly config</param>
|
||||
/// <param name="pmcData"></param>
|
||||
/// <returns>PmcDataRepeatableQuest</returns>
|
||||
protected PmcDataRepeatableQuest GetRepeatableQuestSubTypeFromProfile(RepeatableQuestConfig repeatableConfig,
|
||||
PmcData pmcData)
|
||||
{
|
||||
@@ -475,6 +526,12 @@ public class RepeatableQuestController(
|
||||
return repeatableQuestDetails;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if a repeatable quest type (daily/weekly) is active for the given profile
|
||||
/// </summary>
|
||||
/// <param name="repeatableConfig">Repeatable quest config</param>
|
||||
/// <param name="pmcData"></param>
|
||||
/// <returns>True if profile has access to repeatables</returns>
|
||||
protected bool CanProfileAccessRepeatableQuests(RepeatableQuestConfig repeatableConfig, PmcData pmcData)
|
||||
{
|
||||
// PMC and daily quests not unlocked yet
|
||||
@@ -497,22 +554,22 @@ public class RepeatableQuestController(
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does player have daily pmc quests unlocked
|
||||
* @param pmcData Player profile to check
|
||||
* @param repeatableConfig Config of daily type to check
|
||||
* @returns True if unlocked
|
||||
*/
|
||||
/// <summary>
|
||||
/// Does player have daily pmc quests unlocked
|
||||
/// </summary>
|
||||
/// <param name="pmcData"></param>
|
||||
/// <param name="repeatableConfig">Config of daily type to check</param>
|
||||
/// <returns>True if unlocked</returns>
|
||||
protected static bool PlayerHasDailyPmcQuestsUnlocked(PmcData pmcData, RepeatableQuestConfig repeatableConfig)
|
||||
{
|
||||
return pmcData.Info.Level >= repeatableConfig.MinPlayerLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does player have daily scav quests unlocked
|
||||
* @param pmcData Player profile to check
|
||||
* @returns True if unlocked
|
||||
*/
|
||||
/// <summary>
|
||||
/// Does player have daily scav quests unlocked
|
||||
/// </summary>
|
||||
/// <param name="pmcData"></param>
|
||||
/// <returns>True if unlocked</returns>
|
||||
protected bool PlayerHasDailyScavQuestsUnlocked(PmcData pmcData)
|
||||
{
|
||||
return pmcData?.Hideout?.Areas?.FirstOrDefault(hideoutArea => hideoutArea.Type == HideoutAreas.INTEL_CENTER)
|
||||
@@ -520,6 +577,11 @@ public class RepeatableQuestController(
|
||||
1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expire quests and replace expired quests with ready-to-hand-in quests inside generatedRepeatables.activeQuests
|
||||
/// </summary>
|
||||
/// <param name="generatedRepeatables">Repeatables to process (daily/weekly)</param>
|
||||
/// <param name="pmcData"></param>
|
||||
protected void ProcessExpiredQuests(PmcDataRepeatableQuest generatedRepeatables, PmcData pmcData)
|
||||
{
|
||||
var questsToKeep = new List<RepeatableQuest>();
|
||||
@@ -558,6 +620,14 @@ public class RepeatableQuestController(
|
||||
generatedRepeatables.ActiveQuests = questsToKeep;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to create a quest pool during each cycle of repeatable quest generation. The pool will be subsequently
|
||||
/// narrowed down during quest generation to avoid duplicate quests. Like duplicate extractions or elimination quests
|
||||
/// where you have to e.g. kill scavs in same locations
|
||||
/// </summary>
|
||||
/// <param name="repeatableConfig">main repeatable quest config</param>
|
||||
/// <param name="pmcLevel">Players level</param>
|
||||
/// <returns>Allowed quest pool</returns>
|
||||
protected QuestTypePool GenerateQuestPool(RepeatableQuestConfig repeatableConfig, int? pmcLevel)
|
||||
{
|
||||
var questPool = CreateBaseQuestPool(repeatableConfig);
|
||||
@@ -617,6 +687,11 @@ public class RepeatableQuestController(
|
||||
return questPool;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a pool of quests to generate quests from
|
||||
/// </summary>
|
||||
/// <param name="repeatableConfig">Main repeatable config</param>
|
||||
/// <returns>QuestTypePool</returns>
|
||||
protected QuestTypePool CreateBaseQuestPool(RepeatableQuestConfig repeatableConfig)
|
||||
{
|
||||
return new QuestTypePool
|
||||
@@ -640,11 +715,16 @@ public class RepeatableQuestController(
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a dictionary of map locations the player can access based on their current level
|
||||
/// </summary>
|
||||
/// <param name="locations"></param>
|
||||
/// <param name="pmcLevel"></param>
|
||||
/// <returns>Dictionary</returns>
|
||||
protected Dictionary<ELocationName, List<string>> GetAllowedLocationsForPmcLevel(
|
||||
Dictionary<ELocationName, List<string>> locations, int pmcLevel)
|
||||
{
|
||||
var allowedLocation = new Dictionary<ELocationName, List<string>>();
|
||||
|
||||
foreach (var (location, value) in locations)
|
||||
{
|
||||
var locationNames = new List<string>();
|
||||
@@ -665,12 +745,12 @@ public class RepeatableQuestController(
|
||||
return allowedLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given pmcLevel is allowed on the given location
|
||||
* @param location The location name to check
|
||||
* @param pmcLevel The level of the pmc
|
||||
* @returns True if the given pmc level is allowed to access the given location
|
||||
*/
|
||||
/// <summary>
|
||||
/// Return true if the given pmcLevel is allowed on the given location
|
||||
/// </summary>
|
||||
/// <param name="location">location name to check</param>
|
||||
/// <param name="pmcLevel">level of the pmc</param>
|
||||
/// <returns>True if the given pmc level is allowed to access the given location</returns>
|
||||
protected bool IsPmcLevelAllowedOnLocation(string location, int pmcLevel)
|
||||
{
|
||||
// All PMC levels are allowed for 'any' location requirement
|
||||
|
||||
@@ -82,9 +82,10 @@ public class TraderController(
|
||||
|
||||
/// <summary>
|
||||
/// Adjust trader item prices based on config value multiplier
|
||||
/// only applies to items sold for currency
|
||||
/// </summary>
|
||||
/// <param name="trader"></param>
|
||||
/// <param name="multiplier"></param>
|
||||
/// <param name="trader">Trader to adjust prices of</param>
|
||||
/// <param name="multiplier">Coef to apply to traders' items' prices</param>
|
||||
protected void AdjustTraderItemPrices(Trader trader, double multiplier)
|
||||
{
|
||||
foreach (var kvp in trader.Assort?.BarterScheme)
|
||||
|
||||
@@ -40,7 +40,6 @@ public class BotEquipmentModGenerator(
|
||||
)
|
||||
{
|
||||
protected BotConfig _botConfig = _configServer.GetConfig<BotConfig>();
|
||||
|
||||
protected static HashSet<string> _modSightIds = ["mod_sight_front", "mod_sight_rear"];
|
||||
|
||||
// Slots that hold scopes
|
||||
@@ -380,6 +379,11 @@ public class BotEquipmentModGenerator(
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum and maximum plate class levels from an array of plates
|
||||
/// </summary>
|
||||
/// <param name="platePool">Pool of plates to sort by armorClass to get min and max</param>
|
||||
/// <returns>MinMax of armorClass from plate pool</returns>
|
||||
protected static MinMax<int> GetMinMaxArmorPlateClass(List<TemplateItem> platePool)
|
||||
{
|
||||
platePool.Sort(
|
||||
@@ -406,12 +410,12 @@ public class BotEquipmentModGenerator(
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default plate an armor has in its db item
|
||||
* @param armorItem Item to look up default plate
|
||||
* @param modSlot front/back
|
||||
* @returns Tpl of plate
|
||||
*/
|
||||
/// <summary>
|
||||
/// Get the default plate an armor has in its db item
|
||||
/// </summary>
|
||||
/// <param name="armorItem">Item to look up default plate</param>
|
||||
/// <param name="modSlot">front/back</param>
|
||||
/// <returns>Tpl of plate</returns>
|
||||
protected string? GetDefaultPlateTpl(TemplateItem armorItem, string modSlot)
|
||||
{
|
||||
var relatedItemDbModSlot = armorItem.Properties.Slots?.FirstOrDefault(slot => string.Equals(slot.Name, modSlot, StringComparison.OrdinalIgnoreCase));
|
||||
@@ -419,12 +423,12 @@ public class BotEquipmentModGenerator(
|
||||
return relatedItemDbModSlot?.Props.Filters[0].Plate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the matching armor slot from the default preset matching passed in armor tpl
|
||||
* @param presetItemId Id of preset
|
||||
* @param modSlot front/back
|
||||
* @returns Armor IItem
|
||||
*/
|
||||
/// <summary>
|
||||
/// Get the matching armor slot from the default preset matching passed in armor tpl
|
||||
/// </summary>
|
||||
/// <param name="armorItemTpl"></param>
|
||||
/// <param name="modSlot"></param>
|
||||
/// <returns>Armor IItem</returns>
|
||||
protected Item? GetDefaultPresetArmorSlot(string armorItemTpl, string modSlot)
|
||||
{
|
||||
var defaultPreset = _presetHelper.GetDefaultPreset(armorItemTpl);
|
||||
@@ -433,7 +437,6 @@ public class BotEquipmentModGenerator(
|
||||
string.Equals(item.SlotId, modSlot, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add mods to a weapon using the provided mod pool
|
||||
/// </summary>
|
||||
@@ -713,9 +716,16 @@ public class BotEquipmentModGenerator(
|
||||
return request.Weapon;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the passed in db item lack slot cartridges or chambers
|
||||
/// </summary>
|
||||
/// <param name="item">Item to check</param>
|
||||
/// <returns>True it lacks cartridges/chamber slots</returns>
|
||||
protected bool ItemLacksSlotsCartridgesAndChambers(TemplateItem item)
|
||||
{
|
||||
return item.Properties.Slots?.Count == 0 && item.Properties.Cartridges?.Count == 0 && item.Properties.Chambers?.Count == 0;
|
||||
return item.Properties.Slots?.Count == 0
|
||||
&& item.Properties.Cartridges?.Count == 0
|
||||
&& item.Properties.Chambers?.Count == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -734,7 +744,7 @@ public class BotEquipmentModGenerator(
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this modslot a front or rear sight
|
||||
/// Is passed in modslot a front or rear sight
|
||||
/// </summary>
|
||||
/// <param name="modSlot">Slot to check</param>
|
||||
/// <param name="tpl"></param>
|
||||
@@ -968,7 +978,7 @@ public class BotEquipmentModGenerator(
|
||||
/// <returns>itemHelper.getItem() result</returns>
|
||||
public KeyValuePair<bool, TemplateItem>? ChooseModToPutIntoSlot(ModToSpawnRequest request)
|
||||
{
|
||||
/** Slot mod will fill */
|
||||
// Slot mod will fill
|
||||
var parentSlot = request.ParentTemplate.Properties.Slots?.FirstOrDefault(i => i.Name == request.ModSlot);
|
||||
var weaponTemplate = _itemHelper.GetItem(request.Weapon[0].Template).Value;
|
||||
|
||||
@@ -1291,7 +1301,7 @@ public class BotEquipmentModGenerator(
|
||||
}
|
||||
|
||||
// Required mod is not default or randomisable, use existing pool
|
||||
if (request.ItemModPool.TryGetValue(request.ModSlot, out var modsForSlot))
|
||||
if (!request.ItemModPool.TryGetValue(request.ModSlot, out var modsForSlot))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -1299,6 +1309,12 @@ public class BotEquipmentModGenerator(
|
||||
return modsForSlot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a pool of mods from the default weapon preset for passed in weapon
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="weaponTemplate"></param>
|
||||
/// <returns>Hashset of mods keyed by slot</returns>
|
||||
public HashSet<string> GetModPoolForDefaultSlot(ModToSpawnRequest request, TemplateItem weaponTemplate)
|
||||
{
|
||||
var matchingModFromPreset = GetMatchingModFromPreset(request, weaponTemplate);
|
||||
@@ -1380,7 +1396,13 @@ public class BotEquipmentModGenerator(
|
||||
return request.ItemModPool[request.ModSlot];
|
||||
}
|
||||
|
||||
public Item? GetMatchingModFromPreset(ModToSpawnRequest request, TemplateItem weaponTemplate)
|
||||
/// <summary>
|
||||
/// Get Desired item from preset
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="weaponTemplate"></param>
|
||||
/// <returns></returns>
|
||||
protected Item? GetMatchingModFromPreset(ModToSpawnRequest request, TemplateItem weaponTemplate)
|
||||
{
|
||||
var matchingPreset = GetMatchingPreset(weaponTemplate, request.ParentTemplate.Id);
|
||||
return matchingPreset?.Items?.FirstOrDefault(item =>
|
||||
@@ -1393,7 +1415,7 @@ public class BotEquipmentModGenerator(
|
||||
/// <param name="weaponTemplate">Weapons db template</param>
|
||||
/// <param name="parentItemTpl">Tpl of the parent item</param>
|
||||
/// <returns>Default preset found</returns>
|
||||
public Preset? GetMatchingPreset(TemplateItem weaponTemplate, string parentItemTpl)
|
||||
protected Preset? GetMatchingPreset(TemplateItem weaponTemplate, string parentItemTpl)
|
||||
{
|
||||
// Edge case - using mp5sd reciever means default mp5 handguard doesn't fit
|
||||
var isMp5sd = parentItemTpl == "5926f2e086f7745aae644231";
|
||||
@@ -1493,7 +1515,7 @@ public class BotEquipmentModGenerator(
|
||||
/// <summary>
|
||||
/// Check if mod exists in db + is for a required slot
|
||||
/// </summary>
|
||||
/// <param name="modtoAdd">Db template of mod to check</param>
|
||||
/// <param name="modToAdd">Db template of mod to check</param>
|
||||
/// <param name="slotAddedToTemplate">Slot object the item will be placed as child into</param>
|
||||
/// <param name="modSlot">Slot the mod will fill</param>
|
||||
/// <param name="parentTemplate">Db template of the mods being added</param>
|
||||
|
||||
Reference in New Issue
Block a user