Merge pull request #17 from CWXDEV/main

more generators
This commit is contained in:
clodanSPT
2025-01-07 23:20:45 +00:00
committed by GitHub
19 changed files with 2446 additions and 8 deletions
+391
View File
@@ -0,0 +1,391 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Enums;
using Core.Models.Spt.Bots;
using Core.Models.Spt.Config;
namespace Core.Generators;
public class BotEquipmentModGenerator
{
private BotConfig _botConfig;
public BotEquipmentModGenerator()
{
}
/// <summary>
/// Check mods are compatible and add to array
/// </summary>
/// <param name="equipment">Equipment item to add mods to</param>
/// <param name="parentId">Mod list to choose from</param>
/// <param name="parentTemplate">parentid of item to add mod to</param>
/// <param name="settings">Template object of item to add mods to</param>
/// <param name="specificBlacklist">The relevant blacklist from bot.json equipment dictionary</param>
/// <param name="shouldForceSpawn">should this mod be forced to spawn</param>
/// <returns>Item + compatible mods as an array</returns>
public Item GenerateModsForEquipment(List<Item> equipment, string parentId, TemplateItem parentTemplate, GenerateEquipmentProperties settings,
EquipmentFilterDetails specificBlacklist, bool shouldForceSpawn = false)
{
throw new NotImplementedException();
}
/// <summary>
/// Filter a bots plate pool based on its current level
/// </summary>
/// <param name="settings">Bot equipment generation settings</param>
/// <param name="modSlot">Armor slot being filtered</param>
/// <param name="existingPlateTplPool">Plates tpls to choose from</param>
/// <param name="armorItem">The armor items db template</param>
/// <returns>Array of plate tpls to choose from</returns>
public FilterPlateModsForSlotByLevelResult FilterPlateModsForSlotByLevel(GenerateEquipmentProperties settings, string modSlot,
List<string> existingPlateTplPool, TemplateItem armorItem)
{
throw new NotImplementedException();
}
/// <summary>
/// Add mods to a weapon using the provided mod pool
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="request">Data used to generate the weapon</param>
/// <returns>Weapon + mods array</returns>
public List<Item> GenerateModsForWeapon(string sessionId, GenerateWeaponRequest request)
{
throw new NotImplementedException();
}
/// <summary>
/// Should the provided bot have its stock chance values altered to 100%
/// </summary>
/// <param name="modSlot">Slot to check</param>
/// <param name="botEquipConfig">Bots equipment config/chance values</param>
/// <param name="modToAddTemplate">Mod being added to bots weapon</param>
/// <returns>True if it should</returns>
public bool ShouldForceSubStockSlots(string modSlot, EquipmentFilters botEquipConfig, TemplateItem modToAddTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Is this modslot a front or rear sight
/// </summary>
/// <param name="modSlot">Slot to check</param>
/// <param name="tpl"></param>
/// <returns>true if it's a front/rear sight</returns>
public bool ModIsFrontOrRearSight(string modSlot, string tpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Does the provided mod details show the mod can hold a scope
/// </summary>
/// <param name="modSlot">e.g. mod_scope, mod_mount</param>
/// <param name="ModsParentId">Parent id of mod item</param>
/// <returns>true if it can hold a scope</returns>
public bool ModSlotCanHoldScope(string modSlot, string ModsParentId)
{
throw new NotImplementedException();
}
/// <summary>
/// Set mod spawn chances to defined amount
/// </summary>
/// <param name="modSpawnChances">Chance dictionary to update</param>
/// <param name="modSlotsToAdjust"></param>
/// <param name="newChancePercent"></param>
public void AdjustSlotSpawnChances(ModsChances modSpawnChances, List<string> modSlotsToAdjust, double newChancePercent)
{
throw new NotImplementedException();
}
/// <summary>
/// Does the provided modSlot allow muzzle-related items
/// </summary>
/// <param name="modSlot">Slot id to check</param>
/// <param name="modsParentId">OPTIONAL: parent id of modslot being checked</param>
/// <returns>True if modSlot can have muzzle-related items</returns>
public bool AodSlotCanHoldMuzzleDevices(string modSlot, string? modsParentId)
{
throw new NotImplementedException();
}
/// <summary>
/// Sort mod slots into an ordering that maximises chance of a successful weapon generation
/// </summary>
/// <param name="unsortedSlotKeys">Array of mod slot strings to sort</param>
/// <param name="itemTplWithKeysToSort">The Tpl of the item with mod keys being sorted</param>
/// <returns>Sorted array</returns>
public List<string> SortModKeys(List<string> unsortedSlotKeys, string itemTplWithKeysToSort)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a Slot property for an item (chamber/cartridge/slot)
/// </summary>
/// <param name="modSlot">e.g patron_in_weapon</param>
/// <param name="parentTemplate">item template</param>
/// <returns>Slot item</returns>
public Slot GetModItemSlotFromDb(string modSlot, TemplateItem parentTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Randomly choose if a mod should be spawned, 100% for required mods OR mod is ammo slot
/// </summary>
/// <param name="itemSlot">slot the item sits in from db</param>
/// <param name="modSlotName">Name of slot the mod sits in</param>
/// <param name="modSpawnChances">Chances for various mod spawns</param>
/// <param name="botEquipConfig">Various config settings for generating this type of bot</param>
/// <returns>ModSpawn.SPAWN when mod should be spawned, ModSpawn.DEFAULT_MOD when default mod should spawn, ModSpawn.SKIP when mod is skipped</returns>
public ModSpawn ShouldModBeSpawned(Slot itemSlot, string modSlotName, ModsChances modSpawnChances, EquipmentFilters botEquipConfig)
{
throw new NotImplementedException();
}
/// <summary>
/// Choose a mod to fit into the desired slot
/// </summary>
/// <param name="request">Data used to choose an appropriate mod with</param>
/// <returns>itemHelper.getItem() result</returns>
public object? ChooseModToPutIntoSlot(ModToSpawnRequest request) // TODO: type fuckery: [boolean, ITemplateItem] | undefined
{
throw new NotImplementedException();
}
/// <summary>
/// Given the passed in array of magaizne tpls, look up the min size set in config and return only those that have that size or larger
/// </summary>
/// <param name="modSpawnRequest">Request data</param>
/// <param name="modPool">Pool of magazine tpls to filter</param>
/// <returns>Filtered pool of magazine tpls</returns>
/// <exception cref="NotImplementedException"></exception>
public List<string> GetFilterdMagazinePoolByCapacity(ModToSpawnRequest modSpawnRequest, List<string> modPool)
{
throw new NotImplementedException();
}
/// <summary>
/// Choose a weapon mod tpl for a given slot from a pool of choices
/// Checks chosen tpl is compatible with all existing weapon items
/// </summary>
/// <param name="request"></param>
/// <param name="modPool">Pool of mods that can be picked from</param>
/// <param name="parentSlot">Slot the picked mod will have as a parent</param>
/// <param name="choiceTypeEnum">How should chosen tpl be treated: DEFAULT_MOD/SPAWN/SKIP</param>
/// <param name="weapon">Array of weapon items chosen item will be added to</param>
/// <param name="modSlotName">Name of slot picked mod will be placed into</param>
/// <returns>Chosen weapon details</returns>
public ChooseRandomCompatibleModResult GetCompatibleWeaponModTplForSlotFromPool(ModToSpawnRequest request, List<string> modPool, Slot parentSlot,
ModSpawn choiceTypeEnum, List<Item> weapon, string modSlotName)
{
throw new NotImplementedException();
}
/// <summary>
///
/// </summary>
/// <param name="modPool">Pool of item Tpls to choose from</param>
/// <param name="modSpawnType">How should the slot choice be handled - forced/normal etc</param>
/// <param name="weapon">Weapon mods at current time</param>
/// <returns>IChooseRandomCompatibleModResult</returns>
public ChooseRandomCompatibleModResult GetCompatibleModFromPool(List<string> modPool, ModSpawn modSpawnType, List<Item> weapon)
{
throw new NotImplementedException();
}
public object CreateExhaustableArray<T>(T itemsToAddToArray) // TODO: this wont likely be needed, reimplement for C#
{
throw new NotImplementedException();
}
/// <summary>
/// Get a list of mod tpls that are compatible with the current weapon
/// </summary>
/// <param name="modPool"></param>
/// <param name="tplBlacklist">Tpls that are incompatible and should not be used</param>
/// <returns>string array of compatible mod tpls with weapon</returns>
public List<string> GetFilteredModPool(List<string> modPool, List<string> tplBlacklist) // TODO: tplBlacklist was Set<string>
{
throw new NotImplementedException();
}
/// <summary>
/// Filter mod pool down based on various criteria:
/// Is slot flagged as randomisable
/// Is slot required
/// Is slot flagged as default mod only
/// </summary>
/// <param name="request"></param>
/// <param name="weaponTemplate">Mods root parent (weapon/equipment)</param>
/// <returns>Array of mod tpls</returns>
public List<string> GetModPoolForSlot(ModToSpawnRequest request, TemplateItem weaponTemplate)
{
throw new NotImplementedException();
}
public List<string> GetModPoolForDefaultSlot(ModToSpawnRequest request, TemplateItem weaponTemplate)
{
throw new NotImplementedException();
}
public object GetMatchingModFromPreset(ModToSpawnRequest request, TemplateItem weaponTemplate) // TODO: no return type given in node server
{
throw new NotImplementedException();
}
/// <summary>
/// Get default preset for weapon OR get specific weapon presets for edge cases (mp5/silenced dvl)
/// </summary>
/// <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)
{
throw new NotImplementedException();
}
/// <summary>
/// Temp fix to prevent certain combinations of weapons with mods that are known to be incompatible
/// </summary>
/// <param name="weapon">Array of items that make up a weapon</param>
/// <param name="modTpl">Mod to check compatibility with weapon</param>
/// <returns>True if incompatible</returns>
public bool WeaponModComboIsIncompatible(List<Item> weapon, string modTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Create a mod item with provided parameters as properties + add upd property
/// </summary>
/// <param name="modId">_id</param>
/// <param name="modTpl">_tpl</param>
/// <param name="parentId">parentId</param>
/// <param name="modSlot">slotId</param>
/// <param name="modTemplate">Used to add additional properties in the upd object</param>
/// <param name="botRole">The bots role mod is being created for</param>
/// <returns>Item object</returns>
public Item CreateModItem(string modId, string modTpl, string parentId, string modSlot, TemplateItem modTemplate, string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a list of containers that hold ammo
/// e.g. mod_magazine / patron_in_weapon_000
/// </summary>
/// <returns>string array</returns>
public List<string> GetAmmoContainers()
{
throw new NotImplementedException();
}
/// <summary>
/// Get a random mod from an items compatible mods Filter array
/// </summary>
/// <param name="fallbackModTpl">Default value to return if parentSlot Filter is empty</param>
/// <param name="parentSlot">Item mod will go into, used to get compatible items</param>
/// <param name="modSlot">Slot to get mod to fill</param>
/// <param name="items">Items to ensure picked mod is compatible with</param>
/// <returns>Item tpl</returns>
public string? GetRandomModTplFromItemDb(string fallbackModTpl, Slot parentSlot, string modSlot, List<Item> items)
{
throw new NotImplementedException();
}
/// <summary>
/// Check if mod exists in db + is for a required slot
/// TODO: modToAdd type was [boolean, ITemplateItem] in node
/// </summary>
/// <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>
/// <param name="botRole">Bots wildspawntype (assault/pmcBot/exUsec etc)</param>
/// <returns>True if valid for slot</returns>
public bool IsModValidForSlot(object modToAdd, Slot slotAddedToTemplate, string modSlot, TemplateItem parentTemplate, string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Find mod tpls of a provided type and add to modPool
/// </summary>
/// <param name="desiredSlotName">Slot to look up and add we are adding tpls for (e.g mod_scope)</param>
/// <param name="modTemplate">db object for modItem we get compatible mods from</param>
/// <param name="modPool">Pool of mods we are adding to</param>
/// <param name="botEquipBlacklist">A blacklist of items that cannot be picked</param>
public void AddCompatibleModsForProvidedMod(string desiredSlotName, TemplateItem modTemplate, Dictionary<string, Dictionary<string, List<string>>> modPool,
EquipmentFilterDetails botEquipBlacklist)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the possible items that fit a slot
/// </summary>
/// <param name="parentItemId">item tpl to get compatible items for</param>
/// <param name="modSlot">Slot item should fit in</param>
/// <param name="botEquipBlacklist">Equipment that should not be picked</param>
/// <returns>Array of compatible items for that slot</returns>
public List<string> GetDynamicModPool(string parentItemId, string modSlot, EquipmentFilterDetails botEquipBlacklist)
{
throw new NotImplementedException();
}
/// <summary>
/// Take a list of tpls and filter out blacklisted values using itemFilterService + botEquipmentBlacklist
/// </summary>
/// <param name="allowedMods">Base mods to filter</param>
/// <param name="botEquipBlacklist">Equipment blacklist</param>
/// <param name="modSlot">Slot mods belong to</param>
/// <returns>Filtered array of mod tpls</returns>
public List<string> FilterModsByBlacklist(List<string> allowedMods, EquipmentFilterDetails botEquipBlacklist, string modSlot)
{
throw new NotImplementedException();
}
/// <summary>
/// With the shotgun revolver (60db29ce99594040e04c4a27) 12.12 introduced CylinderMagazines.
/// Those magazines (e.g. 60dc519adf4c47305f6d410d) have a "Cartridges" entry with a _max_count=0.
/// Ammo is not put into the magazine directly but assigned to the magazine's slots: The "camora_xxx" slots.
/// This function is a helper called by generateModsForItem for mods with parent type "CylinderMagazine"
/// </summary>
/// <param name="items">The items where the CylinderMagazine's camora are appended to</param>
/// <param name="modPool">ModPool which should include available cartridges</param>
/// <param name="cylinderMagParentId">The CylinderMagazine's UID</param>
/// <param name="cylinderMagTemplate">The CylinderMagazine's template</param>
public void FillCamora(List<Item> items, Dictionary<string, Dictionary<string, List<string>>> modPool, string cylinderMagParentId,
TemplateItem cylinderMagTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Take a record of camoras and merge the compatible shells into one array
/// </summary>
/// <param name="camorasWithShells">Dictionary of camoras we want to merge into one array</param>
/// <returns>String array of shells for multiple camora sources</returns>
public List<string> MergeCamoraPools(Dictionary<string, List<string>> camorasWithShells)
{
throw new NotImplementedException();
}
/// <summary>
/// Filter out non-whitelisted weapon scopes
/// Controlled by bot.json weaponSightWhitelist
/// e.g. filter out rifle scopes from SMGs
/// </summary>
/// <param name="weapon">Weapon scopes will be added to</param>
/// <param name="scopes">Full scope pool</param>
/// <param name="botWeaponSightWhitelist">Whitelist of scope types by weapon base type</param>
/// <returns>Array of scope tpls that have been filtered to just ones allowed for that weapon type</returns>
public List<string> FilterSightsByWeaponType(Item weapon, List<string> scopes, Dictionary<string, List<string>> botWeaponSightWhitelist)
{
throw new NotImplementedException();
}
}
+43
View File
@@ -0,0 +1,43 @@
using Core.Models.Common;
using Core.Models.Eft.Bot;
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Bots;
namespace Core.Generators;
public class BotLevelGenerator
{
public BotLevelGenerator()
{
}
/// <summary>
/// Return a randomised bot level and exp value
/// </summary>
/// <param name="levelDetails">Min and max of level for bot</param>
/// <param name="botGenerationDetails">Details to help generate a bot</param>
/// <param name="bot">Bot the level is being generated for</param>
/// <returns>IRandomisedBotLevelResult object</returns>
public RandomisedBotLevelResult GenerateBotLevel(MinMax levelDetails, BotGenerationDetails botGenerationDetails, BotBase bot)
{
throw new NotImplementedException();
}
public int ChooseBotLevel(int min, int max, int shift, int number)
{
throw new NotImplementedException();
}
/// <summary>
/// Return the min and max bot level based on a relative delta from the PMC level
/// </summary>
/// <param name="botGenerationDetails">Details to help generate a bot</param>
/// <param name="levelDetails"></param>
/// <param name="maxAvailableLevel">Max level allowed</param>
/// <returns>A MinMax of the lowest and highest level to generate the bots</returns>
public MinMax GetRelativeBotLevelRange(BotGenerationDetails botGenerationDetails, MinMax levelDetails, int maxAvailableLevel)
{
throw new NotImplementedException();
}
}
+202
View File
@@ -0,0 +1,202 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Enums;
using Core.Models.Spt.Bots;
using Core.Models.Spt.Config;
namespace Core.Generators;
public class BotLootGenerator
{
private BotConfig _botConfig;
private PmcConfig _pmcConfig;
public BotLootGenerator()
{
}
/// <summary>
///
/// </summary>
/// <param name="botRole"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public ItemSpawnLimitSettings GetItemSpawnLimitsForBot(string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Add loot to bots containers
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="botJsonTemplate">Base json db file for the bot having its loot generated</param>
/// <param name="isPmc">Will bot be a pmc</param>
/// <param name="botRole">Role of bot, e.g. asssult</param>
/// <param name="botInventory">Inventory to add loot to</param>
/// <param name="botLevel">Level of bot</param>
public void GenerateLoot(string sessionId, BotType botJsonTemplate, bool isPmc, string botRole, BotBaseInventory botInventory, int botLevel)
{
throw new NotImplementedException();
}
/// <summary>
/// Gets the rouble cost total for loot in a bots backpack by the bots levl
/// Will return 0 for non PMCs
/// </summary>
/// <param name="botLevel">Bots level</param>
/// <param name="isPmc">Is the bot a PMC</param>
/// <returns>int</returns>
public int GetBackpackRoubleTotalByLevel(int botLevel, bool isPmc)
{
throw new NotImplementedException();
}
/// <summary>
///
/// </summary>
/// <param name="botInventory"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public List<EquipmentSlots> GetAvailableContainersBotCanStoreItemsIn(BotBaseInventory botInventory)
{
throw new NotImplementedException();
}
/// <summary>
/// Force healing items onto bot to ensure they can heal in-raid
/// </summary>
/// <param name="botInventory">Inventory to add items to</param>
/// <param name="botRole">Role of bot (pmcBEAR/pmcUSEC)</param>
public void AddForcedMedicalItemsToPmcSecure(BotBaseInventory botInventory, string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Take random items from a pool and add to an inventory until totalItemCount or totalValueLimit or space limit is reached
/// </summary>
/// <param name="pool">Pool of items to pick from with weight</param>
/// <param name="equipmentSlots">What equipment slot will the loot items be added to</param>
/// <param name="totalItemCount">Max count of items to add</param>
/// <param name="inventoryToAddItemsTo">Bot inventory loot will be added to</param>
/// <param name="botRole">Role of the bot loot is being generated for (assault/pmcbot)</param>
/// <param name="itemSpawnLimits">Item spawn limits the bot must adhere to</param>
/// <param name="containersIdFull"></param>
/// <param name="totalValueLimitRub">Total value of loot allowed in roubles</param>
/// <param name="isPmc">Is bot being generated for a pmc</param>
/// <exception cref="NotImplementedException"></exception>
public void AddLootFromPool(Dictionary<string, int> pool, List<string> equipmentSlots, int totalItemCount, BotBaseInventory inventoryToAddItemsTo, // TODO: type for containersIdFull was Set<string>
string botRole, ItemSpawnLimitSettings? itemSpawnLimits, List<string> containersIdFull, int totalValueLimitRub = 0, bool isPmc = false)
{
throw new NotImplementedException();
}
/// <summary>
///
/// </summary>
/// <param name="walletId"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public List<List<Item>> CrateWalletLoot(string walletId)
{
throw new NotImplementedException();
}
/// <summary>
/// Some items need child items to function, add them to the itemToAddChildrenTo array
/// </summary>
/// <param name="itemToAddTemplate">Db template of item to check</param>
/// <param name="itemToAddChildrenTo">Item to add children to</param>
/// <param name="isPmc">Is the item being generated for a pmc (affects money/ammo stack sizes)</param>
/// <param name="botRole">role bot has that owns item</param>
public void AddRequiredChildItemsToParent(TemplateItem itemToAddTemplate, List<Item> itemToAddChildrenTo, bool isPmc, string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Add generated weapons to inventory as loot
/// </summary>
/// <param name="sessionId"></param>
/// <param name="botInventory">inventory to add preset to</param>
/// <param name="equipmentSlot">slot to place the preset in (backpack)</param>
/// <param name="templateInventory">bots template, assault.json</param>
/// <param name="modsChances">chances for mods to spawn on weapon</param>
/// <param name="botRole">bots role .e.g. pmcBot</param>
/// <param name="isPmc">are we generating for a pmc</param>
/// <param name="botLevel"></param>
/// <param name="containersIdFull"></param>
public void AddLooseWeaponsToInventorySlot(string sessionId, BotBaseInventory botInventory, string equipmentSlot, BotBaseInventory templateInventory, // TODO: type for containersIdFull was Set<string>
ModsChances modsChances, string botRole, bool isPmc, int botLevel, List<string>? containersIdFull)
{
throw new NotImplementedException();
}
/// <summary>
/// Hydrate item limit array to contain items that have a limit for a specific bot type
/// All values are set to 0
/// </summary>
/// <param name="botRole">Role the bot has</param>
/// <param name="limitCount"></param>
public void InitItemLimitArray(string botRole, Dictionary<string, int> limitCount)
{
throw new NotImplementedException();
}
/// <summary>
/// Check if an item has reached its bot-specific spawn limit
/// </summary>
/// <param name="itemTemplate">Item we check to see if its reached spawn limit</param>
/// <param name="botRole">Bot type</param>
/// <param name="itemSpawnLimits"></param>
/// <returns>true if item has reached spawn limit</returns>
public bool ItemHasReachedSpawnLimit(TemplateItem itemTemplate, string botRole, ItemSpawnLimitSettings itemSpawnLimits)
{
throw new NotImplementedException();
}
/// <summary>
/// Randomise the stack size of a money object, uses different values for pmc or scavs
/// </summary>
/// <param name="botRole">Role bot has that has money stack</param>
/// <param name="itemTemplate">item details from db</param>
/// <param name="moneyItem">Money item to randomise</param>
public void RandomiseMoneyStackSize(string botRole, TemplateItem itemTemplate, Item moneyItem)
{
throw new NotImplementedException();
}
/// <summary>
/// Randomise the size of an ammo stack
/// </summary>
/// <param name="isPmc">Is ammo on a PMC bot</param>
/// <param name="itemTemplate">item details from db</param>
/// <param name="ammoItem">Ammo item to randomise</param>
public void RandomiseAmmoStackSize(bool isPmc, TemplateItem itemTemplate, Item ammoItem)
{
throw new NotImplementedException();
}
/// <summary>
/// Get spawn limits for a specific bot type from bot.json config
/// If no limit found for a non pmc bot, fall back to defaults
/// </summary>
/// <param name="botRole">what role does the bot have</param>
/// <returns>Dictionary of tplIds and limit</returns>
public Dictionary<string, int> GetItemSpawnLimitsForBotType(string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the parentId or tplId of item inside spawnLimits object if it exists
/// </summary>
/// <param name="itemTemplate">item we want to look for in spawn limits</param>
/// <param name="spawnLimits">Limits to check for item</param>
/// <returns>id as string, otherwise undefined</returns>
public string? GetMatchingIdFromSpawnLimits(TemplateItem itemTemplate, Dictionary<string, int> spawnLimits)
{
throw new NotImplementedException();
}
}
+243
View File
@@ -0,0 +1,243 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Bots;
using Core.Models.Spt.Config;
namespace Core.Generators;
public class BotWeaponGenerator
{
private const string _modMagazineSlotId = "mod_magazine";
private BotConfig _botConfig;
private PmcConfig _pmcConfig;
private RepairConfig _repairConfig;
public BotWeaponGenerator()
{
}
/// <summary>
/// Pick a random weapon based on weightings and generate a functional weapon
/// </summary>
/// <param name="sessionId">Session identifier</param>
/// <param name="equipmentSlot">Primary/secondary/holster</param>
/// <param name="botTemplateInventory">e.g. assault.json</param>
/// <param name="weaponParentId"></param>
/// <param name="modChances"></param>
/// <param name="botRole">Role of bot, e.g. assault/followerBully</param>
/// <param name="isPmc">Is weapon generated for a pmc</param>
/// <param name="botLevel"></param>
/// <returns>GenerateWeaponResult object</returns>
public GenerateWeaponResult GenerateRandomWeapon(string sessionId, string equipmentSlot, BotBaseInventory botTemplateInventory, string weaponParentId,
ModsChances modChances, string botRole, bool isPmc, int botLevel)
{
throw new NotImplementedException();
}
/// <summary>
/// Gets a random weighted weapon from a bot's pool of weapons.
/// </summary>
/// <param name="equipmentSlot">Primary/secondary/holster</param>
/// <param name="botTemplateInventory">e.g. assault.json</param>
/// <returns>Weapon template</returns>
public string PickWeightedWeaponTemplateFromPool(string equipmentSlot, BotBaseInventory botTemplateInventory)
{
throw new NotImplementedException();
}
/// <summary>
/// Generates a weapon based on the supplied weapon template.
/// </summary>
/// <param name="sessionId">The session identifier.</param>
/// <param name="weaponTpl">Weapon template to generate (use pickWeightedWeaponTplFromPool()).</param>
/// <param name="slotName">Slot to fit into, primary/secondary/holster.</param>
/// <param name="botTemplateInventory">e.g. assault.json.</param>
/// <param name="weaponParentId">Parent ID of the weapon being generated.</param>
/// <param name="modChances">Dictionary of item types and % chance weapon will have that mod.</param>
/// <param name="botRole">e.g. assault/exusec.</param>
/// <param name="isPmc">Is weapon being generated for a PMC.</param>
/// <param name="botLevel">The level of the bot.</param>
/// <returns>GenerateWeaponResult object.</returns>
public GenerateWeaponResult GenerateWeaponByTpl(string sessionId, string weaponTpl, string slotName, BotBaseInventory botTemplateInventory,
string weaponParentId, ModsChances modChances, string botRole, bool isPmc, int botLevel)
{
throw new NotImplementedException();
}
/// <summary>
/// Insert cartridge(s) into a weapon
/// Handles all chambers - patron_in_weapon, patron_in_weapon_000 etc
/// </summary>
/// <param name="weaponWithModsList">Weapon and mods</param>
/// <param name="ammoTemplate">Cartridge to add to weapon</param>
/// <param name="chamberSlotIdentifiers">Name of slots to create or add ammo to</param>
protected void AddCartridgeToChamber(List<Item> weaponWithModsList, string ammoTemplate, List<string> chamberSlotIdentifiers)
{
throw new NotImplementedException();
}
/// <summary>
/// Create a list with weapon base as the only element and
/// add additional properties based on weapon type
/// </summary>
/// <param name="weaponTemplate">Weapon template to create item with</param>
/// <param name="weaponParentId">Weapons parent id</param>
/// <param name="equipmentSlot">e.g. primary/secondary/holster</param>
/// <param name="weaponItemTemplate">Database template for weapon</param>
/// <param name="botRole">For durability values</param>
/// <returns>Base weapon item in a list</returns>
protected List<Item> ConstructWeaponBaseList(string weaponTemplate, string weaponParentId, string equipmentSlot, TemplateItem weaponItemTemplate,
string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the mods necessary to kit out a weapon to its preset level
/// </summary>
/// <param name="weaponTemplate">Weapon to find preset for</param>
/// <param name="equipmentSlot">The slot the weapon will be placed in</param>
/// <param name="weaponParentId">Value used for the parent id</param>
/// <param name="itemTemplate">Item template</param>
/// <param name="botRole">Bot role</param>
/// <returns>List of weapon mods</returns>
protected List<Item> GetPresetWeaponMods(string weaponTemplate, string equipmentSlot, string weaponParentId, TemplateItem itemTemplate, string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Checks if all required slots are occupied on a weapon and all its mods.
/// </summary>
/// <param name="weaponItemList">Weapon + mods</param>
/// <param name="botRole">Role of bot weapon is for</param>
/// <returns>True if valid</returns>
protected bool IsWeaponValid(List<Item> weaponItemList, string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Generates extra magazines or bullets (if magazine is internal) and adds them to TacticalVest and Pockets.
/// Additionally, adds extra bullets to SecuredContainer
/// </summary>
/// <param name="generatedWeaponResult">Object with properties for generated weapon (weapon mods pool / weapon template / ammo tpl)</param>
/// <param name="magWeights">Magazine weights for count to add to inventory</param>
/// <param name="inventory">Inventory to add magazines to</param>
/// <param name="botRole">The bot type we're generating extra mags for</param>
public void AddExtraMagazinesToInventory(GenerateWeaponResult generatedWeaponResult, GenerationData magWeights, BotBaseInventory inventory, string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Add Grenades for UBGL to bot's vest and secure container
/// </summary>
/// <param name="weaponMods">Weapon list with mods</param>
/// <param name="generatedWeaponResult">Result of weapon generation</param>
/// <param name="inventory">Bot inventory to add grenades to</param>
protected void AddUbglGrenadesToBotInventory(List<Item> weaponMods, GenerateWeaponResult generatedWeaponResult, BotBaseInventory inventory)
{
throw new NotImplementedException();
}
/// <summary>
/// Add ammo to the secure container.
/// </summary>
/// <param name="stackCount">How many stacks of ammo to add.</param>
/// <param name="ammoTpl">Ammo type to add.</param>
/// <param name="stackSize">Size of the ammo stack to add.</param>
/// <param name="inventory">Player inventory.</param>
protected void AddAmmoToSecureContainer(int stackCount, string ammoTemplate, int stackSize, BotBaseInventory inventory)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a weapons magazine template from a weapon template.
/// </summary>
/// <param name="weaponMods">Mods from a weapon template.</param>
/// <param name="weaponTemplate">Weapon to get magazine template for.</param>
/// <param name="botRole">The bot type we are getting the magazine for.</param>
/// <returns>Magazine template string.</returns>
protected string GetMagazineTemplateFromWeaponTemplate(List<Item> weaponMods, TemplateItem weaponTemplate, string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Finds and returns a compatible ammo template based on the bots ammo weightings (x.json/inventory/equipment/ammo)
/// </summary>
/// <param name="cartridgePool">Dictionary of all cartridges keyed by type e.g. Caliber556x45NATO</param>
/// <param name="weaponTemplate">Weapon details from database we want to pick ammo for</param>
/// <returns>Ammo template that works with the desired gun</returns>
protected string GetWeightedCompatibleAmmo(Dictionary<string, Dictionary<string, double>> cartridgePool, TemplateItem weaponTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the cartridge ids from a weapon template that work with the weapon
/// </summary>
/// <param name="weaponTemplate">Weapon db template to get cartridges for</param>
/// <returns>List of cartridge tpls</returns>
protected List<string> GetCompatibleCartridgesFromWeaponTemplate(TemplateItem weaponTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a weapons compatible cartridge caliber
/// </summary>
/// <param name="weaponTemplate">Weapon to look up caliber of</param>
/// <returns>Caliber as string</returns>
protected string GetWeaponCaliber(TemplateItem weaponTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Fill existing magazines to full, while replacing their contents with specified ammo
/// </summary>
/// <param name="weaponMods">Weapon with children</param>
/// <param name="magazine">Magazine item</param>
/// <param name="cartridgeTemplate">Cartridge to insert into magazine</param>
protected void FillExistingMagazines(List<Item> weaponMods, Item magazine, string cartridgeTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Add desired ammo template as item to weapon modifications list, placed as child to UBGL.
/// </summary>
/// <param name="weaponMods">Weapon with children.</param>
/// <param name="ubglMod">UBGL item.</param>
/// <param name="ubglAmmoTpl">Grenade ammo template.</param>
protected void FillUbgl(List<Item> weaponMods, Item ubglMod, string ubglAmmoTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Add cartridge item to weapon item list, if it already exists, update
/// </summary>
/// <param name="weaponWithMods">Weapon items list to amend</param>
/// <param name="magazine">Magazine item details we're adding cartridges to</param>
/// <param name="chosenAmmoTpl">Cartridge to put into the magazine</param>
/// <param name="newStackSize">How many cartridges should go into the magazine</param>
/// <param name="magazineTemplate">Magazines db template</param>
protected void AddOrUpdateMagazinesChildWithAmmo(List<Item> weaponWithMods, Item magazine, string chosenAmmoTpl, TemplateItem magazineTemplate)
{
throw new NotImplementedException();
}
/// <summary>
/// Fill each Camora with a bullet
/// </summary>
/// <param name="weaponMods">Weapon mods to find and update camora mod(s) from</param>
/// <param name="magazineId">Magazine id to find and add to</param>
/// <param name="ammoTpl">Ammo template id to hydrate with</param>
protected void FillCamorasWithAmmo(List<Item> weaponMods, string magazineId, string ammoTpl)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,62 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Config;
namespace Core.Generators;
public class FenceBaseAssortGenerator
{
private TraderConfig _traderConfig;
public FenceBaseAssortGenerator()
{
}
/// <summary>
/// Create base fence assorts dynamically and store in memory
/// </summary>
public void GenerateFenceBaseAssorts()
{
throw new NotImplementedException();
}
/// <summary>
/// Check ammo in boxes and loose ammos has a penetration value above the configured value in trader.json / ammoMaxPenLimit
/// </summary>
/// <param name="rootItemDb">Ammo box or ammo item from items.db</param>
/// <returns>True if penetration value is above limit set in config</returns>
protected bool IsAmmoAbovePenetrationLimit(TemplateItem rootItemDb)
{
throw new NotImplementedException();
}
/// <summary>
/// Gets the penetration power value of an ammo, works with ammo boxes and raw ammos.
/// </summary>
/// <param name="rootItemDb">Ammo box or ammo item from items.db</param>
/// <returns>Penetration power of passed in item, undefined if it doesnt have a power</returns>
protected double? GetAmmoPenetrationPower(TemplateItem rootItemDb)
{
throw new NotImplementedException();
}
/// <summary>
/// Add soft inserts and armor plates to an armor.
/// </summary>
/// <param name="armor">Armor item list to add mods into.</param>
/// <param name="itemDbDetails">Armor items db template.</param>
protected void AddChildrenToArmorModSlots(List<Item> armor, TemplateItem itemDbDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Check if item is valid for being added to fence assorts
/// </summary>
/// <param name="item">Item to check</param>
/// <returns>true if valid fence item</returns>
protected bool IsValidFenceItem(TemplateItem item)
{
throw new NotImplementedException();
}
}
+183
View File
@@ -0,0 +1,183 @@
using System.Text.Json.Serialization;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Config;
namespace Core.Generators;
public class LocationLootGenerator
{
private LocationConfig _locationConfig;
private SeasonalEventConfig _seasonalEventConfig;
public LocationLootGenerator()
{
}
/// Create a list of container objects with randomised loot
/// </summary>
/// <param name="locationBase">Map base to generate containers for</param>
/// <param name="staticAmmoDist">Static ammo distribution</param>
/// <returns>List of container objects</returns>
public List<SpawnpointTemplate> GenerateStaticContainers(LocationBase locationBase, Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist)
{
throw new NotImplementedException();
}
/// <summary>
/// Get containers with a non-100% chance to spawn OR are NOT on the container type randomistion blacklist
/// </summary>
/// <param name="staticContainers"></param>
/// <returns>StaticContainerData array</returns>
protected List<StaticContainerData> GetRandomisableContainersOnMap(List<StaticContainerData> staticContainers)
{
throw new NotImplementedException();
}
/// <summary>
/// Get containers with 100% spawn rate or have a type on the randomistion ignore list
/// </summary>
/// <param name="staticContainersOnMap"></param>
/// <returns>IStaticContainerData array</returns>
protected List<StaticContainerData> GetGuaranteedContainers(List<StaticContainerData> staticContainersOnMap)
{
throw new NotImplementedException();
}
/// <summary>
/// Choose a number of containers based on their probabilty value to fulfil the desired count in containerData.chosenCount
/// </summary>
/// <param name="groupId">Name of the group the containers are being collected for</param>
/// <param name="containerData">Containers and probability values for a groupId</param>
/// <returns>List of chosen container Ids</returns>
protected List<string> GetContainersByProbabilty(string groupId, ContainerGroupCount containerData)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a mapping of each groupid and the containers in that group + count of containers to spawn on map
/// </summary>
/// <param name="containersGroups">Container group values</param>
/// <returns>dictionary keyed by groupId</returns>
protected Dictionary<string, ContainerGroupCount> GetGroupIdToContainerMappings(
object staticContainerGroupData, // TODO: Type fuckery staticContainerGroupData was IStaticContainer | Record<string, IContainerMinMax>
List<StaticContainerData> staticContainersOnMap)
{
throw new NotImplementedException();
}
/// <summary>
/// Choose loot to put into a static container based on weighting
/// Handle forced items + seasonal item removal when not in season
/// </summary>
/// <param name="staticContainer">The container itself we will add loot to</param>
/// <param name="staticForced">Loot we need to force into the container</param>
/// <param name="staticLootDist">staticLoot.json</param>
/// <param name="staticAmmoDist">staticAmmo.json</param>
/// <param name="locationName">Name of the map to generate static loot for</param>
/// <returns>StaticContainerData</returns>
protected StaticContainerData AddLootToContainer(StaticContainerData staticContainer, List<StaticForcedProps> staticForced,
Dictionary<string, StaticLootDetails> staticLootDist, Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist, string locationName
)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a 2D grid of a container's item slots
/// </summary>
/// <param name="containerTpl">Tpl id of the container</param>
/// <returns>List<List<int>></returns>
protected List<List<int>> GetContainerMapping(string containerTpl)
{
throw new NotImplementedException();
}
/// <summary>
/// Look up a containers itemcountDistribution data and choose an item count based on the found weights
/// </summary>
/// <param name="containerTypeId">Container to get item count for</param>
/// <param name="staticLootDist">staticLoot.json</param>
/// <param name="locationName">Map name (to get per-map multiplier for from config)</param>
/// <returns>item count</returns>
protected int GetWeightedCountOfContainerItems(string containerTypeId, Dictionary<string, StaticLootDetails> staticLootDist, string locationName)
{
throw new NotImplementedException();
}
/// <summary>
/// Get all possible loot items that can be placed into a container
/// Do not add seasonal items if found + current date is inside seasonal event
/// </summary>
/// <param name="containerTypeId">Container to get possible loot for</param>
/// <param name="staticLootDist">staticLoot.json</param>
/// <returns>ProbabilityObjectArray of item tpls + probabilty</returns>
protected object GetPossibleLootItemsForContainer(string containerTypeId,
Dictionary<string, StaticLootDetails> staticLootDist) // TODO: Type Fuckery, return type was ProbabilityObjectArray<string, number>
{
throw new NotImplementedException();
}
protected double GetLooseLootMultiplerForLocation(string location)
{
throw new NotImplementedException();
}
protected double GetStaticLootMultiplierForLocation(string location)
{
throw new NotImplementedException();
}
/// <summary>
/// Create array of loose + forced loot using probability system
/// </summary>
/// <param name="dynamicLootDist"></param>
/// <param name="staticAmmoDist"></param>
/// <param name="locationName">Location to generate loot for</param>
/// <returns>Array of spawn points with loot in them</returns>
public List<SpawnpointTemplate> GenerateDynamicLoot(LooseLoot dynamicLootDist, Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist,
string locationName)
{
throw new NotImplementedException();
}
/// <summary>
/// Add forced spawn point loot into loot parameter list
/// </summary>
/// <param name="lootLocationTemplates">List to add forced loot spawn locations to</param>
/// <param name="forcedSpawnPoints">Forced loot locations that must be added</param>
/// <param name="locationName">Name of map currently having force loot created for</param>
protected void addForcedLoot(List<SpawnpointTemplate> lootLocationTemplates, List<SpawnpointsForced> forcedSpawnPoints, string locationName,
Dictionary<string, List<StaticAmmoDetails>> staticAmmoDist)
{
throw new NotImplementedException();
}
// TODO: rewrite, BIG yikes
protected ContainerItem CreateStaticLootItem(string chosenTemplate, Dictionary<string, List<StaticAmmoDetails>> staticAmmoDistribution, string? parentIdentifier = null)
{
throw new NotImplementedException();
}
}
public class ContainerGroupCount
{
[JsonPropertyName("containerIdsWithProbability")]
public Dictionary<string, double> ContainerIdsWithProbability { get; set; }
[JsonPropertyName("chosenCount")]
public int ChosenCount { get; set; }
}
public class ContainerItem
{
[JsonPropertyName("items")]
public List<Item> Items { get; set; }
[JsonPropertyName("width")]
public int Width { get; set; }
[JsonPropertyName("height")]
public int Height { get; set; }
}
+177
View File
@@ -0,0 +1,177 @@
using System.Text.Json.Serialization;
using Core.Models.Common;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Config;
using Core.Models.Spt.Services;
namespace Core.Generators;
public class LootGenerator
{
public LootGenerator()
{
}
/// <summary>
/// Generate a list of items based on configuration options parameter
/// </summary>
/// <param name="options">parameters to adjust how loot is generated</param>
/// <returns>An array of loot items</returns>
public List<Item> CreateRandomLoot(LootRequest options)
{
throw new NotImplementedException();
}
/// <summary>
/// Generate An array of items
/// TODO - handle weapon presets/ammo packs
/// </summary>
/// <param name="forcedLootDict">Dictionary of item tpls with minmax values</param>
/// <returns>Array of Item</returns>
public List<Item> CreateForcedLoot(Dictionary<string, MinMax> forcedLootDict)
{
throw new NotImplementedException();
}
/// <summary>
/// Get pool of items from item db that fit passed in param criteria
/// </summary>
/// <param name="itemTplBlacklist">Prevent these items</param>
/// <param name="itemTypeWhitelist">Only allow these items</param>
/// <param name="useRewardItemBlacklist">Should item.json reward item config be used</param>
/// <param name="allowBossItems">Should boss items be allowed in result</param>
/// <returns>results of filtering + blacklist used</returns>
protected object GetItemRewardPool(List<string> itemTplBlacklist, List<string> itemTypeWhitelist,
bool useRewardItemBlacklist, // TODO: type fuckery, return type was { itemPool: [string, ITemplateItem][]; blacklist: Set<string> }
bool allowBossItems)
{
throw new NotImplementedException();
}
/// <summary>
/// Filter armor items by their front plates protection level - top if its a helmet
/// </summary>
/// <param name="armor">Armor preset to check</param>
/// <param name="options">Loot request options - armor level etc</param>
/// <returns>True if item has desired armor level</returns>
protected bool ArmorOfDesiredProtectionLevel(Preset armor, LootRequest options)
{
throw new NotImplementedException();
}
/// <summary>
/// Construct item limit record to hold max and current item count for each item type
/// </summary>
/// <param name="limits">limits as defined in config</param>
/// <returns>record, key: item tplId, value: current/max item count allowed</returns>
protected Dictionary<string, ItemLimit> InitItemLimitCounter(Dictionary<string, int> limits)
{
throw new NotImplementedException();
}
/// <summary>
/// Find a random item in items.json and add to result array
/// </summary>
/// <param name="items">items to choose from</param>
/// <param name="itemTypeCounts">item limit counts</param>
/// <param name="options">item filters</param>
/// <param name="result">array to add found item to</param>
/// <returns>true if item was valid and added to pool</returns>
protected bool FindAndAddRandomItemToLoot(object items, object itemTypeCounts,
LootRequest options, // TODO: items type was [string, ITemplateItem][], itemTypeCounts was Record<string, { current: number; max: number }>
List<Item> result)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a randomised stack count for an item between its StackMinRandom and StackMaxSize values
/// </summary>
/// <param name="item">item to get stack count of</param>
/// <param name="options">loot options</param>
/// <returns>stack count</returns>
protected int GetRandomisedStackCount(TemplateItem item, LootRequest options)
{
throw new NotImplementedException();
}
/// <summary>
/// Find a random item in items.json and add to result list
/// </summary>
/// <param name="presetPool">Presets to choose from</param>
/// <param name="itemTypeCounts">Item limit counts</param>
/// <param name="itemBlacklist">Items to skip</param>
/// <param name="result">List to add chosen preset to</param>
/// <returns>true if preset was valid and added to pool</returns>
protected bool FindAndAddRandomPresetToLoot(List<Preset> presetPool, object itemTypeCounts,
List<string> itemBlacklist, // TODO: type fuckery, itemTypeCounts was Record<string, { current: number; max: number }>
List<Item> result)
{
throw new NotImplementedException();
}
/// <summary>
/// Sealed weapon containers have a weapon + associated mods inside them + assortment of other things (food/meds)
/// </summary>
/// <param name="containerSettings">sealed weapon container settings</param>
/// <returns>List of items with children lists</returns>
public List<List<Item>> GetSealedWeaponCaseLoot(SealedAirdropContainerSettings containerSettings)
{
throw new NotImplementedException();
}
/// <summary>
/// Get non-weapon mod rewards for a sealed container
/// </summary>
/// <param name="containerSettings">Sealed weapon container settings</param>
/// <param name="weaponDetailsDb">Details for the weapon to reward player</param>
/// <returns>List of item with children lists</returns>
protected List<List<Item>> GetSealedContainerNonWeaponModRewards(SealedAirdropContainerSettings containerSettings,
TemplateItem weaponDetailsDb)
{
throw new NotImplementedException();
}
/// <summary>
/// Iterate over the container weaponModRewardLimits settings and create a list of weapon mods to reward player
/// </summary>
/// <param name="containerSettings">Sealed weapon container settings</param>
/// <param name="linkedItemsToWeapon">All items that can be attached/inserted into weapon</param>
/// <param name="chosenWeaponPreset">The weapon preset given to player as reward</param>
/// <returns>List of item with children lists</returns>
protected List<List<Item>> GetSealedContainerWeaponModRewards(SealedAirdropContainerSettings containerSettings, List<TemplateItem> linkedItemsToWeapon,
Preset chosenWeaponPreset)
{
throw new NotImplementedException();
}
/// <summary>
/// Handle event-related loot containers - currently just the halloween jack-o-lanterns that give food rewards
/// </summary>
/// <param name="rewardContainerDetails"></param>
/// <returns>List of item with children lists</returns>
public List<List<Item>> GetRandomLootContainerLoot(RewardDetails rewardContainerDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Pick a reward item based on the reward details data
/// </summary>
/// <param name="rewardContainerDetails"></param>
/// <returns>Single tpl</returns>
protected string PickRewardItem(RewardDetails rewardContainerDetails)
{
throw new NotImplementedException();
}
}
public class ItemLimit
{
[JsonPropertyName("current")]
public double Current { get; set; }
[JsonPropertyName("max")]
public double Max { get; set; }
}
+52 -3
View File
@@ -1,13 +1,62 @@
namespace Core.Generators;
using Core.Models.Eft.Common.Tables;
namespace Core.Generators;
public class PMCLootGenerator
{
public List<string> GeneratePMCPocketLootPool()
public PMCLootGenerator()
{
}
/// <summary>
/// Create a List of loot items a PMC can have in their pockets
/// </summary>
/// <param name="botRole"></param>
/// <returns>Dictionary of string and number</returns>
public Dictionary<string, int> GeneratePMCPocketLootPool(string botRole)
{
throw new NotImplementedException();
}
public List<string> GeneratePMCBackpackLootPool()
/// <summary>
/// Create a List of loot items a PMC can have in their vests
/// </summary>
/// <param name="botRole"></param>
/// <returns>Dictionary of string and number</returns>
public Dictionary<string, int> GeneratePMCVestLootPool(string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Check if item has a width/height that lets it fit into a 2x2 slot
/// 1x1 / 1x2 / 2x1 / 2x2
/// </summary>
/// <param name="item">Item to check size of</param>
/// <returns>true if it fits</returns>
protected bool ItemFitsInto2By2Slot(TemplateItem item)
{
throw new NotImplementedException();
}
/// <summary>
/// Check if item has a width/height that lets it fit into a 1x2 slot
/// 1x1 / 1x2 / 2x1
/// </summary>
/// <param name="item">Item to check size of</param>
/// <returns>true if it fits</returns>
protected bool ItemFitsInto1By2Slot(TemplateItem item)
{
throw new NotImplementedException();
}
/// <summary>
/// Create a List of loot items a PMC can have in their backpack
/// </summary>
/// <param name="botRole"></param>
/// <returns>Dictionary of string and number</returns>
public Dictionary<string, int> GeneratePMCBackpackLootPool(string botRole)
{
throw new NotImplementedException();
}
+105
View File
@@ -0,0 +1,105 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Config;
namespace Core.Generators;
public class PlayerScavGenerator
{
private PlayerScavConfig _playerScavConfig;
public PlayerScavGenerator()
{
}
/// <summary>
/// Update a player profile to include a new player scav profile
/// </summary>
/// <param name="sessionID">session id to specify what profile is updated</param>
/// <returns>profile object</returns>
public PmcData Generate(string sessionID)
{
throw new NotImplementedException();
}
/// <summary>
/// Add items picked from `playerscav.lootItemsToAddChancePercent`
/// </summary>
/// <param name="possibleItemsToAdd">dict of tpl + % chance to be added</param>
/// <param name="scavData"></param>
/// <param name="containersToAddTo">Possible slotIds to add loot to</param>
protected void AddAdditionalLootToPlayerScavContainers(Dictionary<string, double> possibleItemsToAdd, BotBase scavData, List<string> containersToAddTo)
{
throw new NotImplementedException();
}
/// <summary>
/// Get the scav karama level for a profile
/// Is also the fence trader rep level
/// </summary>
/// <param name="pmcData">pmc profile</param>
/// <returns>karma level</returns>
protected double GetScavKarmaLevel(PmcData pmcData)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a baseBot template
/// If the parameter doesnt match "assault", take parts from the loot type and apply to the return bot template
/// </summary>
/// <param name="botTypeForLoot">bot type to use for inventory/chances</param>
/// <returns>IBotType object</returns>
protected BotType ConstructBotBaseTemplate(string botTypeForLoot)
{
throw new NotImplementedException();
}
/// <summary>
/// Adjust equipment/mod/item generation values based on scav karma levels
/// </summary>
/// <param name="karmaSettings">Values to modify the bot template with</param>
/// <param name="baseBotNode">bot template to modify according to karama level settings</param>
protected void AdjustBotTemplateWithKarmaSpecificSettings(KarmaLevel karmaSettings, BotType baseBotNode)
{
throw new NotImplementedException();
}
protected Skills GetScavSkills(PmcData scavProfile)
{
throw new NotImplementedException();
}
protected Skills GetDefaultScavSkills()
{
throw new NotImplementedException();
}
protected Stats GetScavStats(PmcData scavProfile)
{
throw new NotImplementedException();
}
protected int GetScavLevel(PmcData scavProfile)
{
throw new NotImplementedException();
}
protected int GetScavExperience(PmcData scavProfile)
{
throw new NotImplementedException();
}
/// <summary>
/// Set cooldown till scav is playable
/// take into account scav cooldown bonus
/// </summary>
/// <param name="scavData">scav profile</param>
/// <param name="pmcData">pmc profile</param>
/// <returns></returns>
protected PmcData SetScavCooldownTimer(PmcData scavData, PmcData pmcData)
{
throw new NotImplementedException();
}
}
+52 -2
View File
@@ -1,10 +1,60 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
namespace Core.Generators;
public class RagfairAssortGenerator
{
public List<Item> GetAssortItems()
public RagfairAssortGenerator()
{
}
/// <summary>
/// Get an array of arrays that can be sold on the flea
/// Each sub array contains item + children (if any)
/// </summary>
/// <returns>List of Lists</returns>
public List<List<Item>> GetAssortItems()
{
throw new NotImplementedException();
}
/// <summary>
/// Check internal generatedAssortItems array has objects
/// </summary>
/// <returns>true if array has objects</returns>
protected bool AssortsAreGenerated()
{
throw new NotImplementedException();
}
/// <summary>
/// Generate an array of arrays (item + children) the flea can sell
/// </summary>
/// <returns>List of Lists (item + children)</returns>
protected List<List<Item>> GenerateRagfairAssortItems()
{
throw new NotImplementedException();
}
/// <summary>
/// Get presets from globals to add to flea
/// ragfairConfig.dynamic.showDefaultPresetsOnly decides if its all presets or just defaults
/// </summary>
/// <returns>Dictionary</returns>
protected List<Preset> GetPresetsToAdd()
{
throw new NotImplementedException();
}
/// <summary>
/// Create a base assort item and return it with populated values + 999999 stack count + unlimited count = true
/// </summary>
/// <param name="tplId">tplid to add to item</param>
/// <param name="id">id to add to item</param>
/// <returns>Hydrated Item object</returns>
protected Item CreateRagfairAssortRootItem(string tplId, string id_checkTodoComment) // TODO: string id = this.hashUtil.generate()
{
throw new NotImplementedException();
}
+274 -2
View File
@@ -1,12 +1,284 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Ragfair;
using Core.Models.Spt.Config;
using Core.Models.Spt.Ragfair;
namespace Core.Generators;
public class RagfairOfferGenerator
{
public RagfairOffer CreateOffer(string userID, float time, List<Item> items, List<BarterScheme> barterScheme, int loyalLevel, int price,
bool sellInOnePiece)
public RagfairOfferGenerator()
{
}
/// <summary>
/// Create a flea offer and store it in the Ragfair server offers list
/// </summary>
/// <param name="userID">Owner of the offer</param>
/// <param name="time">Time offer is listed at</param>
/// <param name="items">Items in the offer</param>
/// <param name="barterScheme">Cost of item (currency or barter)</param>
/// <param name="loyalLevel">Loyalty level needed to buy item</param>
/// <param name="sellInOnePiece">Flags sellInOnePiece to be true</param>
/// <returns>Created flea offer</returns>
public RagfairOffer CreateAndAddFleaOffer(
string userID,
double time,
List<Item> items,
List<BarterScheme> barterScheme,
int loyalLevel,
bool sellInOnePiece = false)
{
throw new NotImplementedException();
}
/// <summary>
/// Create an offer object ready to send to ragfairOfferService.addOffer()
/// </summary>
/// <param name="userID">Owner of the offer</param>
/// <param name="time">Time offer is listed at</param>
/// <param name="items">Items in the offer</param>
/// <param name="barterScheme">Cost of item (currency or barter)</param>
/// <param name="loyalLevel">Loyalty level needed to buy item</param>
/// <param name="isPackOffer">Is offer being created flagged as a pack</param>
/// <returns>RagfairOffer</returns>
protected RagfairOffer CreateOffer(
string userID,
double time,
List<Item> items,
List<BarterScheme> barterScheme,
int loyalLevel,
bool isPackOffer = false)
{
throw new NotImplementedException();
}
/// <summary>
/// Create the user object stored inside each flea offer object
/// </summary>
/// <param name="userID">user creating the offer</param>
/// <param name="isTrader">Is the user creating the offer a trader</param>
/// <returns>RagfairOfferUser</returns>
protected RagfairOfferUser CreateUserDataForFleaOffer(string userID, bool isTrader)
{
throw new NotImplementedException();
}
/// <summary>
/// Calculate the offer price that's listed on the flea listing
/// </summary>
/// <param name="offerRequirements">barter requirements for offer</param>
/// <returns>rouble cost of offer</returns>
protected decimal ConvertOfferRequirementsIntoRoubles(List<OfferRequirement> offerRequirements)
{
throw new NotImplementedException();
}
/// <summary>
/// Get avatar url from trader table in db
/// </summary>
/// <param name="isTrader">Is user we're getting avatar for a trader</param>
/// <param name="userId">persons id to get avatar of</param>
/// <returns>url of avatar</returns>
protected string GetAvatarUrl(bool isTrader, string userId)
{
throw new NotImplementedException();
}
/// <summary>
/// Convert a count of currency into roubles
/// </summary>
/// <param name="currencyCount">amount of currency to convert into roubles</param>
/// <param name="currencyType">Type of currency (euro/dollar/rouble)</param>
/// <returns>count of roubles</returns>
protected double CalculateRoublePrice(decimal currencyCount, string currencyType)
{
throw new NotImplementedException();
}
/// <summary>
/// Check userId, if its a player, return their pmc _id, otherwise return userId parameter
/// </summary>
/// <param name="userId">Users Id to check</param>
/// <returns>Users Id</returns>
protected string GetTraderId(string userId)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a flea trading rating for the passed in user
/// </summary>
/// <param name="userId">User to get flea rating of</param>
/// <returns>Flea rating value</returns>
protected double GetRating(string userId)
{
throw new NotImplementedException();
}
/// <summary>
/// Is the offers user rating growing
/// </summary>
/// <param name="userID">user to check rating of</param>
/// <returns>true if its growing</returns>
protected bool GetRatingGrowing(string userID)
{
throw new NotImplementedException();
}
/// <summary>
/// Get number of section until offer should expire
/// </summary>
/// <param name="userID">Id of the offer owner</param>
/// <param name="time">Time the offer is posted</param>
/// <returns>number of seconds until offer expires</returns>
protected double GetOfferEndTime(string userID, double time)
{
throw new NotImplementedException();
}
/// <summary>
/// Create multiple offers for items by using a unique list of items we've generated previously
/// </summary>
/// <param name="expiredOffers">optional, expired offers to regenerate</param>
public async Task GenerateDynamicOffers(List<List<Item>> expiredOffers = null)
{
throw new NotImplementedException();
}
/// <summary>
/// </summary>
/// <param name="assortItemWithChildren">Item with its children to process into offers</param>
/// <param name="isExpiredOffer">is an expired offer</param>
/// <param name="config">Ragfair dynamic config</param>
protected async Task CreateOffersFromAssort(List<Item> assortItemWithChildren, bool isExpiredOffer, Dynamic config)
{
throw new NotImplementedException();
}
/// <summary>
/// iterate over an items chidren and look for plates above desired level and remove them
/// </summary>
/// <param name="presetWithChildren">preset to check for plates</param>
/// <param name="plateSettings">Settings</param>
/// <returns>True if plate removed</returns>
protected bool RemoveBannedPlatesFromPreset(List<Item> presetWithChildren, ArmorPlateBlacklistSettings plateSettings)
{
throw new NotImplementedException();
}
/// <summary>
/// Create one flea offer for a specific item
/// </summary>
/// <param name="sellerId">Id of seller</param>
/// <param name="itemWithChildren">Item to create offer for</param>
/// <param name="isPreset">Is item a weapon preset</param>
/// <param name="itemToSellDetails">Raw db item details</param>
/// <returns>Item array</returns>
protected async Task CreateSingleOfferForItem(string sellerId, List<Item> itemWithChildren, bool isPreset, TemplateItem itemToSellDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Generate trader offers on flea using the traders assort data
/// </summary>
/// <param name="traderID">Trader to generate offers for</param>
public void GenerateFleaOffersForTrader(string traderID)
{
throw new NotImplementedException();
}
/// <summary>
/// Get array of an item with its mods + condition properties (e.g durability)
/// Apply randomisation adjustments to condition if item base is found in ragfair.json/dynamic/condition
/// </summary>
/// <param name="userID">id of owner of item</param>
/// <param name="itemWithMods">Item and mods, get condition of first item (only first array item is modified)</param>
/// <param name="itemDetails">db details of first item</param>
protected void RandomiseOfferItemUpdProperties(string userID, List<Item> itemWithMods, TemplateItem itemDetails)
{
throw new NotImplementedException();
}
protected string? GetDynamicConditionIdForTpl(string tpl)
{
throw new NotImplementedException();
}
/**
* Alter an items condition based on its item base type
* @param conditionSettingsId also the parentId of item being altered
* @param itemWithMods Item to adjust condition details of
* @param itemDetails db item details of first item in array
*/
protected void RandomiseItemCondition(string conditionSettingsId, List<Item> itemWithMods, TemplateItem itemDetails)
{
throw new NotImplementedException();
}
/**
* Adjust an items durability/maxDurability value
* @param item item (weapon/armor) to Adjust
* @param itemDbDetails Weapon details from db
* @param maxMultiplier Value to multiply max durability by
* @param currentMultiplier Value to multiply current durability by
*/
protected void RandomiseWeaponDurability(Item item, TemplateItem itemDbDetails, double maxMultiplier, double currentMultiplier)
{
throw new NotImplementedException();
}
/**
* Randomise the durability values for an armors plates and soft inserts
* @param armorWithMods Armor item with its child mods
* @param currentMultiplier Chosen multiplier to use for current durability value
* @param maxMultiplier Chosen multiplier to use for max durability value
*/
protected void RandomiseArmorDurabilityValues(List<Item> armorWithMods, double currentMultiplier, double maxMultiplier)
{
throw new NotImplementedException();
}
/// <summary>
/// Add missing conditions to an item if needed
/// Durability for repairable items
/// HpResource for medical items
/// </summary>
/// <param name="item">item to add conditions to</param>
protected void AddMissingConditions(Item item)
{
throw new NotImplementedException();
}
/// <summary>
/// Create a barter-based barter scheme, if not possible, fall back to making barter scheme currency based
/// </summary>
/// <param name="offerItems">Items for sale in offer</param>
/// <param name="barterConfig">Barter config from ragfairConfig.dynamic.barter</param>
/// <returns>Barter scheme</returns>
protected List<BarterScheme> CreateBarterBarterScheme(List<Item> offerItems, BarterDetails barterConfig)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a list of flea prices + item tpl, cached in generator class inside `allowedFleaPriceItemsForBarter`
/// </summary>
/// <returns>list with tpl/price values</returns>
protected List<TplWithFleaPrice> GetFleaPricesAsList()
{
throw new NotImplementedException();
}
/// <summary>
/// Create a random currency-based barter scheme for a list of items
/// </summary>
/// <param name="offerWithChildren">Items on offer</param>
/// <param name="isPackOffer">Is the barter scheme being created for a pack offer</param>
/// <param name="multipler">What to multiply the resulting price by</param>
/// <returns>Barter scheme for offer</returns>
protected List<BarterScheme> CreateCurrencyBarterScheme(List<Item> offerWithChildren, bool isPackOffer, double multipler = 1)
{
throw new NotImplementedException();
}
+208
View File
@@ -0,0 +1,208 @@
using Core.Models.Eft.Common;
using Core.Models.Eft.Common.Tables;
using Core.Models.Spt.Config;
using Core.Models.Spt.Repeatable;
namespace Core.Generators;
public class RepeatableQuestGenerator
{
public RepeatableQuestGenerator()
{
}
/// <summary>
/// This method is called by /GetClientRepeatableQuests/ and creates one element of quest type format (see assets/database/templates/repeatableQuests.json).
/// It randomly draws a quest type (currently Elimination, Completion or Exploration) as well as a trader who is providing the quest
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="pmcLevel">Player's level for requested items and reward generation</param>
/// <param name="pmcTraderInfo">Players traper standing/rep levels</param>
/// <param name="questTypePool">Possible quest types pool</param>
/// <param name="repeatableConfig">Repeatable quest config</param>
/// <returns>RepeatableQuest</returns>
public RepeatableQuest GenerateRepeatableQuest(
string sessionId,
int pmcLevel,
Dictionary<string, TraderInfo> pmcTraderInfo,
QuestTypePool questTypePool,
RepeatableQuestConfig repeatableConfig
)
{
throw new NotImplementedException();
}
/// <summary>
/// Generate a randomised Elimination quest
/// </summary>
/// <param name="pmcLevel">Player's level for requested items and reward generation</param>
/// <param name="traderId">Trader from which the quest will be provided</param>
/// <param name="questTypePool">Pools for quests (used to avoid redundant quests)</param>
/// <param name="repeatableConfig">The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requestd quest</param>
/// <returns>Object of quest type format for "Elimination" (see assets/database/templates/repeatableQuests.json)</returns>
protected RepeatableQuest GenerateEliminationQuest(
string sessionid,
int pmcLevel,
string traderId,
QuestTypePool questTypePool,
RepeatableQuestConfig repeatableConfig
)
{
throw new NotImplementedException();
}
/// <summary>
/// Get a number of kills neded to complete elimination quest
/// </summary>
/// <param name="targetKey">Target type desired e.g. anyPmc/bossBully/Savage</param>
/// <param name="targetsConfig">Config</param>
/// <param name="eliminationConfig">Config</param>
/// <returns>Number of AI to kill</returns>
protected int GetEliminationKillCount(
string targetKey,
object targetsConfig, // TODO: typing was ProbabilityObjectArray<string, BossInfo>
EliminationConfig eliminationConfig
)
{
throw new NotImplementedException();
}
/// <summary>
/// A repeatable quest, besides some more or less static components, exists of reward and condition (see assets/database/templates/repeatableQuests.json)
/// This is a helper method for GenerateEliminationQuest to create a location condition.
/// </summary>
/// <param name="location">the location on which to fulfill the elimination quest</param>
/// <returns>Elimination-location-subcondition object</returns>
protected QuestConditionCounterCondition GenerateEliminationLocation(List<string> location)
{
throw new NotImplementedException();
}
/// <summary>
/// Create kill condition for an elimination quest
/// </summary>
/// <param name="target">Bot type target of elimination quest e.g. "AnyPmc", "Savage"</param>
/// <param name="targetedBodyParts">Body parts player must hit</param>
/// <param name="distance">Distance from which to kill (currently only >= supported)</param>
/// <param name="allowedWeapon">What weapon must be used - undefined = any</param>
/// <param name="allowedWeaponCategory">What category of weapon must be used - undefined = any</param>
/// <returns>EliminationCondition object</returns>
protected QuestConditionCounterCondition GenerateEliminationCondition(
string target,
List<string> targetedBodyParts,
double distance,
string allowedWeapon,
string allowedWeaponCategory
)
{
throw new NotImplementedException();
}
/// <summary>
/// Generates a valid Completion quest
/// </summary>
/// <param name="pmcLevel">player's level for requested items and reward generation</param>
/// <param name="traderId">trader from which the quest will be provided</param>
/// <param name="repeatableConfig">The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requested quest</param>
/// <returns>quest type format for "Completion" (see assets/database/templates/repeatableQuests.json)</returns>
protected RepeatableQuest GenerateCompletionQuest(
string sessionId,
int pmcLevel,
string traderId,
RepeatableQuestConfig repeatableConfig
)
{
throw new NotImplementedException();
}
/// <summary>
/// A repeatable quest, besides some more or less static components, exists of reward and condition (see assets/database/templates/repeatableQuests.json)
/// This is a helper method for GenerateCompletionQuest to create a completion condition (of which a completion quest theoretically can have many)
/// </summary>
/// <param name="itemTpl">id of the item to request</param>
/// <param name="value">amount of items of this specific type to request</param>
/// <returns>object of "Completion"-condition</returns>
protected RepeatableQuest GenerateCompletionAvailableForFinish(string itemTpl, int value)
{
throw new NotImplementedException();
}
/// <summary>
/// Generates a valid Exploration quest
/// </summary>
/// <param name="sessionId">session id for the quest</param>
/// <param name="pmcLevel">player's level for reward generation</param>
/// <param name="traderId">trader from which the quest will be provided</param>
/// <param name="questTypePool">Pools for quests (used to avoid redundant quests)</param>
/// <param name="repeatableConfig">The configuration for the repeatably kind (daily, weekly) as configured in QuestConfig for the requested quest</param>
/// <returns>object of quest type format for "Exploration" (see assets/database/templates/repeatableQuests.json)</returns>
protected RepeatableQuest GenerateExplorationQuest(
string sessionId,
int pmcLevel,
string traderId,
QuestTypePool questTypePool,
RepeatableQuestConfig repeatableConfig)
{
throw new NotImplementedException();
}
/// <summary>
/// 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>
/// <returns>List of Exit objects</returns>
protected List<Exit> GetLocationExitsForSide(string locationKey, string playerSide)
{
throw new NotImplementedException();
}
protected object GeneratePickupQuest(
string sessionId,
int pmcLevel,
string traderId,
QuestTypePool questTypePool,
RepeatableQuestConfig repeatableConfig)
{
throw new NotImplementedException();
}
/// <summary>
/// Convert a location into an quest code can read (e.g. factory4_day into 55f2d3fd4bdc2d5f408b4567)
/// </summary>
/// <param name="locationKey">e.g factory4_day</param>
/// <returns>guid</returns>
protected string GetQuestLocationByMapId(string locationKey)
{
throw new NotImplementedException();
}
/// <summary>
/// Exploration repeatable quests can specify a required extraction point.
/// This method creates the according object which will be appended to the conditions list
/// </summary>
/// <param name="exit">The exit name to generate the condition for</param>
/// <returns>Exit condition</returns>
protected QuestConditionCounterCondition GenerateExplorationExitCondition(Exit exit)
{
throw new NotImplementedException();
}
/// <summary>
/// Generates the base object of quest type format given as templates in assets/database/templates/repeatableQuests.json
/// The templates include Elimination, Completion and Extraction quest types
/// </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>
/// <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)</returns>
protected RepeatableQuest GenerateRepeatableTemplate(
string type,
string traderId,
string side,
string sessionId)
{
throw new NotImplementedException();
}
}
+125
View File
@@ -0,0 +1,125 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Hideout;
using Core.Models.Spt.Hideout;
namespace Core.Generators;
public class ScavCaseRewardGenerator
{
public ScavCaseRewardGenerator()
{
}
/// <summary>
/// Create an array of rewards that will be given to the player upon completing their scav case build
/// </summary>
/// <param name="recipeId">recipe of the scav case craft</param>
/// <returns>Product array</returns>
public List<List<Product>> Generate(string recipeId)
{
throw new NotImplementedException();
}
/// <summary>
/// Get all db items that are not blacklisted in scavcase config or global blacklist
/// Store in class field
/// </summary>
protected void CacheDbItems()
{
throw new NotImplementedException();
}
/// <summary>
/// Pick a number of items to be rewards, the count is defined by the values in `itemFilters` param
/// </summary>
/// <param name="items">item pool to pick rewards from</param>
/// <param name="itemFilters">how the rewards should be filtered down (by item count)</param>
/// <returns></returns>
protected List<TemplateItem> PickRandomRewards(
List<TemplateItem> items,
RewardCountAndPriceDetails itemFilters,
string rarity)
{
throw new NotImplementedException();
}
/// <summary>
/// Choose if money should be a reward based on the moneyRewardChancePercent config chance in scavCaseConfig
/// </summary>
/// <returns>true if reward should be money</returns>
protected bool RewardShouldBeMoney()
{
throw new NotImplementedException();
}
/// <summary>
/// Choose if ammo should be a reward based on the ammoRewardChancePercent config chance in scavCaseConfig
/// </summary>
/// <returns>true if reward should be ammo</returns>
protected bool RewardShouldBeAmmo()
{
throw new NotImplementedException();
}
/// <summary>
/// Choose from rouble/dollar/euro at random
/// </summary>
protected TemplateItem GetRandomMoney()
{
throw new NotImplementedException();
}
/// <summary>
/// Get a random ammo from items.json that is not in the ammo blacklist AND inside the price range defined in scavcase.json config
/// </summary>
/// <param name="rarity">The rarity this ammo reward is for</param>
/// <returns>random ammo item from items.json</returns>
protected TemplateItem GetRandomAmmo(string rarity)
{
throw new NotImplementedException();
}
/// <summary>
/// Take all the rewards picked create the Product object array ready to return to calling code
/// Also add a stack count to ammo and money
/// </summary>
/// <param name="rewardItems">items to convert</param>
/// <returns>Product array</returns>
protected List<List<TemplateItem>> RandomiseContainerItemRewards(List<TemplateItem> rewardItems, string rarity)
{
throw new NotImplementedException();
}
/// <summary>
/// </summary>
/// <param name="dbItems">all items from the items.json</param>
/// <param name="itemFilters">controls how the dbItems will be filtered and returned (handbook price)</param>
/// <returns>filtered dbItems array</returns>
protected List<TemplateItem> GetFilteredItemsByPrice(
List<TemplateItem> dbItems,
RewardCountAndPriceDetails itemFilters)
{
throw new NotImplementedException();
}
/// <summary>
/// Gathers the reward min and max count params for each reward quality level from config and scavcase.json into a single object
/// </summary>
/// <param name="scavCaseDetails">production.json/scavRecipes object</param>
/// <returns>ScavCaseRewardCountsAndPrices object</returns>
protected ScavCaseRewardCountsAndPrices GetScavCaseRewardCountsAndPrices(ScavRecipe scavCaseDetails)
{
throw new NotImplementedException();
}
/// <summary>
/// Randomises the size of ammo and money stacks
/// </summary>
/// <param name="itemToCalculate">ammo or money item</param>
/// <param name="rarity">rarity (common/rare/superrare)</param>
/// <returns>value to set stack count to</returns>
protected int GetRandomAmountRewardForScavCase(TemplateItem itemToCalculate, string rarity)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,145 @@
using Core.Models.Eft.Common.Tables;
using Core.Models.Eft.Match;
using Core.Models.Spt.Bots;
using Core.Models.Spt.Config;
using Equipment = Core.Models.Eft.Common.Tables.Equipment;
namespace Core.Generators.WeaponGen;
public class BotInventoryGenerator
{
private BotConfig _botConfig;
public BotInventoryGenerator()
{
}
/// <summary>
/// Add equipment/weapons/loot to bot
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="botJsonTemplate">Base json db file for the bot having its loot generated</param>
/// <param name="botRole">Role bot has (assault/pmcBot)</param>
/// <param name="isPmc">Is bot being converted into a pmc</param>
/// <param name="botLevel">Level of bot being generated</param>
/// <param name="chosenGameVersion">Game version for bot, only really applies for PMCs</param>
/// <returns>PmcInventory object with equipment/weapons/loot</returns>
public BotBaseInventory generateInventory(string sessionId, BotType botJsonTemplate, string botRole, bool isPmc, int botLevel, string chosenGameVersion)
{
throw new NotImplementedException();
}
/// <summary>
/// Create a pmcInventory object with all the base/generic items needed
/// </summary>
/// <returns>PmcInventory object</returns>
public BotBaseInventory GenerateInventoryBase()
{
throw new NotImplementedException();
}
/// <summary>
/// Add equipment to a bot
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="templateInventory">bot/x.json data from db</param>
/// <param name="wornItemChances">Chances items will be added to bot</param>
/// <param name="botRole">Role bot has (assault/pmcBot)</param>
/// <param name="botInventory">Inventory to add equipment to</param>
/// <param name="botLevel">Level of bot</param>
/// <param name="chosenGameVersion">Game version for bot, only really applies for PMCs</param>
/// <param name="raidConfig">RadiConfig</param>
public void GenerateAndAddEquipmentToBot(string sessionId, BotBaseInventory templateInventory, Chances wornItemChances, string botRole,
BotBaseInventory botInventory, int botLevel, string chosenGameVersion, GetRaidConfigurationRequestData raidConfig)
{
throw new NotImplementedException();
}
/// <summary>
/// Remove non-armored rigs from parameter data
/// </summary>
/// <param name="templateEquipment">Equpiment to filter TacticalVest of</param>
/// <param name="botRole">Role of bot vests are being filtered for</param>
public void FilterRigsToThoseWithProtection(Equipment templateEquipment, string botRole)
{
throw new NotImplementedException();
}
/// <summary>
/// Remove armored rigs from parameter data
/// </summary>
/// <param name="templateEquipment">Equpiment to filter TacticalVest of</param>
/// <param name="botRole">Role of bot vests are being filtered for</param>
/// <param name="allowEmptyRequest">Should the function return all rigs when 0 unarmored are found</param>
public void FilterRigsTothoseWithoutProtection(Equipment templateEquipment, string botRole, bool allowEmptyRequest = false)
{
throw new NotImplementedException();
}
/// <summary>
/// Add a piece of equipment with mods to inventory from the provided pools
/// </summary>
/// <param name="settings">Values to adjust how item is chosen and added to bot</param>
/// <returns>true when item added</returns>
public bool GenerateEquipment(GenerateEquipmentProperties settings)
{
throw new NotImplementedException();
}
/// <summary>
/// Get all possible mods for item and filter down based on equipment blacklist from bot.json config
/// </summary>
/// <param name="itemTpl">Item mod pool is being retrieved and filtered</param>
/// <param name="equipmentBlacklist">Blacklist to filter mod pool with</param>
/// <returns>Filtered pool of mods</returns>
public Dictionary<string, List<string>> GetFilteredDynamicModsForItem(string itemTpl, Dictionary<string, List<string>> equipmentBlacklist)
{
throw new NotImplementedException();
}
/// <summary>
/// Work out what weapons bot should have equipped and add them to bot inventory
/// </summary>
/// <param name="templateInventory">bot/x.json data from db</param>
/// <param name="equipmentChances">Chances bot can have equipment equipped</param>
/// <param name="sessionId">Session id</param>
/// <param name="botInventory">Inventory to add weapons to</param>
/// <param name="botRole">assault/pmcBot/bossTagilla etc</param>
/// <param name="isPmc">Is the bot being generated as a pmc</param>
/// <param name="itemGenerationLimitsMinMax">Limits for items the bot can have</param>
/// <param name="botLevel">level of bot having weapon generated</param>
public void GenerateAndAddWeaponsToBot(BotBaseInventory templateInventory, Chances equipmentChances, string sessionId, BotBaseInventory botInventory, string botRole,
bool isPmc, Generation itemGenerationLimitsMinMax, int botLevel)
{
throw new NotImplementedException();
}
/// <summary>
/// Calculate if the bot should have weapons in Primary/Secondary/Holster slots
/// </summary>
/// <param name="equipmentChances">Chances bot has certain equipment</param>
/// <returns>What slots bot should have weapons generated for</returns>
public object GetDesiredWeaponsForBot(Chances equipmentChances) // TODO: Type fuckery { slot: EquipmentSlots; shouldSpawn: boolean }[]
{
throw new NotImplementedException();
}
/// <summary>
/// Add weapon + spare mags/ammo to bots inventory
/// </summary>
/// <param name="sessionId">Session id</param>
/// <param name="weaponSlot">Weapon slot being generated</param>
/// <param name="templateInventory">bot/x.json data from db</param>
/// <param name="botInventory">Inventory to add weapon+mags/ammo to</param>
/// <param name="equipmentChances">Chances bot can have equipment equipped</param>
/// <param name="botRole">assault/pmcBot/bossTagilla etc</param>
/// <param name="isPmc">Is the bot being generated as a pmc</param>
/// <param name="itemGenerationWeights"></param>
/// <param name="botLevel"></param>
public void AddWeaponAndMagazineToInventory(string sessionId, object weaponSlot, BotBaseInventory templateInventory, BotBaseInventory botInventory, Chances equipmentChances, string botRole,
bool isPmc, Generation itemGenerationWeights, int botLevel)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,42 @@
using Core.Models.Eft.Common.Tables;
namespace Core.Generators.WeaponGen.Implementations;
public class InventoryMagGen
{
private GenerationData _magCounts;
private TemplateItem _magazineTemplate;
private TemplateItem _weaponTemplate;
private TemplateItem _ammoTemplate;
private BotBaseInventory _pmcInventory;
public InventoryMagGen()
{
}
public GenerationData GetMagCount()
{
return _magCounts;
}
public TemplateItem GetMagazineTemplate()
{
return _magazineTemplate;
}
public TemplateItem GetWeaponTemplate()
{
return _weaponTemplate;
}
public TemplateItem GetAmmoTemplate()
{
return _ammoTemplate;
}
public BotBaseInventory GetPmcInventory()
{
return _pmcInventory;
}
}
+110
View File
@@ -0,0 +1,110 @@
using Core.Models.Eft.Weather;
using Core.Models.Enums;
using Core.Models.Spt.Config;
namespace Core.Generators;
public class WeatherGenerator
{
public WeatherGenerator()
{
}
/**
* Get current + raid datetime and format into correct BSG format and return
* @param data Weather data
* @returns WeatherData
*/
public WeatherData CalculateGameTime(WeatherData data)
{
throw new NotImplementedException();
}
/**
* Get server uptime seconds multiplied by a multiplier and add to current time as seconds
* Format to BSGs requirements
* @param currentDate current date
* @returns formatted time
*/
protected string GetBsgFormattedInRaidTime()
{
throw new NotImplementedException();
}
/**
* Get current time formatted to fit BSGs requirement
* @param date date to format into bsg style
* @returns Time formatted in BSG format
*/
protected string GetBsgFormattedTime(DateTime date)
{
throw new NotImplementedException();
}
/**
* Return randomised Weather data with help of config/weather.json
* @param currentSeason the currently active season
* @param timestamp OPTIONAL what timestamp to generate the weather data at, defaults to now when not supplied
* @returns Randomised weather data
*/
public Weather GenerateWeather(Season currentSeason, int? timestamp = null)
{
throw new NotImplementedException();
}
protected SeasonalValues GetWeatherValuesBySeason(Season currentSeason)
{
throw new NotImplementedException();
}
/**
* Choose a temprature for the raid based on time of day
* @param currentSeason What season tarkov is currently in
* @param inRaidTimestamp What time is the raid running at
* @returns Timestamp
*/
protected double GetRaidTemperature(SeasonalValues weather, int inRaidTimestamp)
{
throw new NotImplementedException();
}
/**
* Set Weather date/time/timestamp values to now
* @param weather Object to update
* @param timestamp OPTIONAL, define timestamp used
*/
protected void SetCurrentDateTime(Weather weather, int? timestamp = null)
{
throw new NotImplementedException();
}
protected WindDirection GetWeightedWindDirection(SeasonalValues weather)
{
throw new NotImplementedException();
}
protected double GetWeightedClouds(SeasonalValues weather)
{
throw new NotImplementedException();
}
protected double GetWeightedWindSpeed(SeasonalValues weather)
{
throw new NotImplementedException();
}
protected double GetWeightedFog(SeasonalValues weather)
{
throw new NotImplementedException();
}
protected double GetWeightedRain(SeasonalValues weather)
{
throw new NotImplementedException();
}
protected double GetRandomFloat(double min, double max, int precision = 3)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;
namespace Core.Models.Eft.Bot;
public class RandomisedBotLevelResult
{
[JsonPropertyName("level")]
public int Level { get; set; }
[JsonPropertyName("exp")]
public int Exp { get; set; }
}
+19
View File
@@ -0,0 +1,19 @@
namespace Core.Models.Enums;
public enum EquipmentSlots
{
HEADWEAR,
EARPIECE,
FACE_COVER,
ARMOR_VEST,
EYEWEAR,
ARM_BAND,
TACTICAL_VEST,
POCKETS,
BACKPACK,
SECURED_CONTAINER,
FIRST_PRIMARY_WEAPON,
SECOND_PRIMARY_WEAPON,
HOLSTER,
SCABBARD
}
@@ -2,7 +2,7 @@
namespace Core.Models.Spt.Hideout;
public class ScavCaseRewardCountsAndPrice
public class ScavCaseRewardCountsAndPrices
{
[JsonPropertyName("Common")]
public RewardCountAndPriceDetails Common { get; set; }