add more generators
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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,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();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Core.Models.Spt.Hideout;
|
||||
|
||||
public class ScavCaseRewardCountsAndPrice
|
||||
public class ScavCaseRewardCountsAndPrices
|
||||
{
|
||||
[JsonPropertyName("Common")]
|
||||
public RewardCountAndPriceDetails Common { get; set; }
|
||||
Reference in New Issue
Block a user