2021-08-24 12:08:30 +01:00
using Common.Extensions ;
2021-09-18 22:36:59 +01:00
using Common.Models.Input ;
using Common.Models.Output ;
2023-08-15 09:29:16 +00:00
using Generator.Weighting ;
2021-08-13 16:24:05 +01:00
namespace Generator.Helpers.Gear
{
public static class GearHelpers
{
public static void AddEquippedMods ( Bot botToUpdate , Datum rawParsedBot )
{
var modItemsInRawBot = new List < Item > ( ) ;
var itemsWithModsInRawBot = new List < Item > ( ) ;
modItemsInRawBot = rawParsedBot . Inventory . items
2024-01-01 20:29:58 +00:00
. Where ( x = > x . slotId ! = null
& & ( x . slotId . StartsWith ( "mod_" )
| | x . slotId . ToLower ( ) . StartsWith ( "patron_in_weapon" )
| | x . slotId . ToLower ( ) . StartsWith ( "helmet_" )
| | x . slotId . ToLower ( ) . StartsWith ( "front_" )
| | x . slotId . ToLower ( ) . StartsWith ( "back_" )
| | x . slotId . ToLower ( ) . StartsWith ( "collar" )
| | x . slotId . ToLower ( ) . StartsWith ( "groin" )
| | x . slotId . ToLower ( ) . StartsWith ( "left" )
| | x . slotId . ToLower ( ) . StartsWith ( "right" )
| | x . slotId . ToLower ( ) . StartsWith ( "soft_" ) ) ) . ToList ( ) ;
2021-08-13 16:24:05 +01:00
2023-10-31 19:35:32 +00:00
// Get items with Mods by iterating over mod items and getting the parent item
2021-08-13 16:24:05 +01:00
itemsWithModsInRawBot . AddRange ( modItemsInRawBot
. Select ( modItem = > rawParsedBot . Inventory . items
. Find ( x = > x . _id = = modItem . parentId ) ) ) ;
var itemsWithModsDictionary = botToUpdate . inventory . mods ;
foreach ( var itemToAdd in itemsWithModsInRawBot )
{
var modsToAdd = modItemsInRawBot . Where ( x = > x . parentId = = itemToAdd . _id ) . ToList ( ) ;
2023-10-31 19:35:32 +00:00
// fix pistolgrip that changes slot id name
if ( itemToAdd . _tpl = = "56e0598dd2720bb5668b45a6" )
{
var badMod = modsToAdd . FirstOrDefault ( x = > x . slotId = = "mod_pistol_grip" & & x . _tpl = = "56e05a6ed2720bd0748b4567" ) ;
if ( badMod ! = null )
{
badMod . slotId = "mod_pistolgrip" ;
}
}
2021-08-13 16:24:05 +01:00
AddItemToDictionary ( itemToAdd , modsToAdd , itemsWithModsDictionary ) ;
2023-08-15 09:29:16 +00:00
// check if these mods have sub-mods and add those
foreach ( var modAdded in modsToAdd . Where ( x = > x . slotId = = "mod_magazine" ) )
{
// look for items where parentId is this mods id
var subItems = rawParsedBot . Inventory . items . Where ( x = > x . parentId = = modAdded . _id & & x . slotId ! = "cartridges" ) . ToList ( ) ;
if ( subItems . Count > 0 )
{
AddItemToDictionary ( modAdded , subItems , itemsWithModsDictionary ) ;
}
}
2021-08-13 16:24:05 +01:00
}
botToUpdate . inventory . mods = itemsWithModsDictionary ;
}
2023-08-15 09:29:16 +00:00
internal static void AddAmmo ( Bot botToUpdate , Datum bot )
{
2023-10-31 19:35:32 +00:00
//var weightService = new WeightingService();
foreach ( var ammo in bot . Inventory . items . Where (
x = > x . slotId ! = null
& & ( x . slotId = = "patron_in_weapon"
| | ( x . slotId = = "cartridges" & & bot . Inventory . items . FirstOrDefault ( parent = > parent . _id = = x . parentId ) ? . slotId ! = "main" ) // Ignore cartridges in ammo boxes for ammo usage calc
| | x . slotId . StartsWith ( "camora" ) ) ) )
2023-08-15 09:29:16 +00:00
{
2023-10-31 19:35:32 +00:00
var caliber = ItemTemplateHelper . GetTemplateById ( ammo . _tpl ) . _props . ammoCaliber ;
2023-08-15 09:29:16 +00:00
if ( caliber = = null )
{
2023-10-31 19:35:32 +00:00
caliber = ItemTemplateHelper . GetTemplateById ( ammo . _tpl ) . _props . Caliber ;
2023-08-15 09:29:16 +00:00
}
// Create key if caliber doesnt exist
if ( ! botToUpdate . inventory . Ammo . ContainsKey ( caliber ) )
{
botToUpdate . inventory . Ammo [ caliber ] = new Dictionary < string , int > ( ) ;
}
2023-10-31 19:35:32 +00:00
if ( ! botToUpdate . inventory . Ammo [ caliber ] . ContainsKey ( ammo . _tpl ) )
{
botToUpdate . inventory . Ammo [ caliber ] [ ammo . _tpl ] = 0 ;
}
botToUpdate . inventory . Ammo [ caliber ] [ ammo . _tpl ] + + ;
}
}
public static int CommonDivisor ( List < int > numbers )
{
int result = numbers [ 0 ] ;
for ( int i = 1 ; i < numbers . Count ; i + + )
{
result = GCD ( result , numbers [ i ] ) ;
}
return result ;
}
private static int GCD ( int a , int b )
{
while ( b ! = 0 )
{
int temp = b ;
b = a % b ;
a = temp ;
2023-08-15 09:29:16 +00:00
}
2023-10-31 19:35:32 +00:00
return a ;
2023-08-15 09:29:16 +00:00
}
2021-09-05 12:20:40 +01:00
public static void AddEquippedGear ( Bot botToUpdate , Datum bot )
2021-08-13 16:24:05 +01:00
{
// add equipped gear
2023-08-15 09:29:16 +00:00
var weightService = new WeightingService ( ) ;
foreach ( var inventoryItem in bot . Inventory . items . Where ( x = > x . slotId ! = null ) )
2021-08-13 16:24:05 +01:00
{
switch ( inventoryItem . slotId ? . ToLower ( ) )
{
case "headwear" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . Headwear , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "earpiece" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . Earpiece , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "facecover" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . FaceCover , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "armorvest" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . ArmorVest , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "eyewear" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . Eyewear , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "armband" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . ArmBand , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "tacticalvest" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . TacticalVest , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "backpack" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . Backpack , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "firstprimaryweapon" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . FirstPrimaryWeapon , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "secondprimaryweapon" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . SecondPrimaryWeapon , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "holster" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . Holster , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "scabbard" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . Scabbard , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "pockets" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . Pockets , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
case "securedcontainer" :
2023-10-31 19:35:32 +00:00
IncrementDictionaryValue ( botToUpdate . inventory . equipment . SecuredContainer , inventoryItem . _tpl ) ;
2021-08-13 16:24:05 +01:00
break ;
default :
break ;
}
}
}
2023-10-31 19:35:32 +00:00
public static void IncrementDictionaryValue ( Dictionary < string , int > dictToIncrement , string key )
{
if ( ! dictToIncrement . ContainsKey ( key ) )
{
dictToIncrement [ key ] = 0 ;
}
dictToIncrement [ key ] + + ;
}
2021-08-13 16:24:05 +01:00
public static void AddCartridges ( Bot botToUpdate , Datum rawParsedBot )
{
var cartridgesInRawBot = rawParsedBot . Inventory . items
. Where ( x = > x . slotId ? . StartsWith ( "cartridges" ) = = true ) . ToList ( ) ;
var cartridgeParentIds = cartridgesInRawBot . Select ( x = > x . parentId ) . ToList ( ) ;
var itemsThatTakeCartridges = rawParsedBot . Inventory . items . Where ( x = > cartridgeParentIds . Contains ( x . _id ) ) . ToList ( ) ;
var itemsThatTakeCartridgesDict = CreateDictionaryPopulateWithMagazinesAndCartridges ( itemsThatTakeCartridges , cartridgesInRawBot ) ;
foreach ( var item in itemsThatTakeCartridgesDict )
{
// Item exists update
if ( botToUpdate . inventory . mods . ContainsKey ( item . Key ) )
{
UpdateExistingMagazine ( botToUpdate , item ) ;
}
else // No item found, add fresh
{
AddNewMagazine ( botToUpdate , item ) ;
}
}
}
private static void AddItemToDictionary (
2021-08-13 19:51:01 +01:00
Item itemToAdd ,
List < Item > modsToAdd ,
Dictionary < string , Dictionary < string , List < string > > > itemsWithModsDict )
2021-08-13 16:24:05 +01:00
{
// item key already exists, need to merge mods
if ( itemsWithModsDict . ContainsKey ( itemToAdd . _tpl ) )
{
foreach ( var modItem in modsToAdd )
{
var itemToAddModsTo = itemsWithModsDict [ itemToAdd . _tpl ] ;
// Item doesnt have this mod, add it then add template id
if ( ! itemToAddModsTo . ContainsKey ( modItem . slotId ) )
{
// Mod doesnt exist on item
itemToAddModsTo . Add ( modItem . slotId , new List < string > ( ) ) ; // add mod
itemToAddModsTo [ modItem . slotId ] . AddUnique ( modItem . _tpl ) ;
}
itemToAddModsTo [ modItem . slotId ] . AddUnique ( modItem . _tpl ) ; // add template id to it
}
}
else // item doesnt exist, create it
{
// Add base item
itemsWithModsDict . Add ( itemToAdd . _tpl , new Dictionary < string , List < string > > ( ) ) ;
// Add mod types to item
foreach ( var modItem in modsToAdd )
{
itemsWithModsDict [ itemToAdd . _tpl ] . Add ( modItem . slotId , new List < string > ( ) ) ;
}
// Get mod we're adding mod templateIds to
var modItems = itemsWithModsDict [ itemToAdd . _tpl ] ;
foreach ( var modItem in modsToAdd )
{
var modToUpdate = modItems [ modItem . slotId ] ;
modToUpdate . Add ( modItem . _tpl ) ;
}
}
}
private static void UpdateExistingMagazine ( Bot botToUpdate , KeyValuePair < string , List < string > > item )
{
var existingmagazineItem = botToUpdate . inventory . mods [ item . Key ] ;
var cartridges = existingmagazineItem [ "cartridges" ] ;
foreach ( var itemToAdd in item . Value )
{
cartridges . AddUnique ( itemToAdd ) ;
}
}
private static void AddNewMagazine ( Bot botToUpdate , KeyValuePair < string , List < string > > item )
{
var cartridgeDict = new Dictionary < string , List < string > >
{
{ "cartridges" , item . Value }
} ;
botToUpdate . inventory . mods . Add ( item . Key , cartridgeDict ) ;
}
private static Dictionary < string , List < string > > CreateDictionaryPopulateWithMagazinesAndCartridges ( List < Item > itemsThatTakeCartridges , List < Item > cartridgesInRawBot )
{
var itemsThatTakeCartridgesDict = new Dictionary < string , List < string > > ( ) ;
foreach ( var item in itemsThatTakeCartridges )
{
var cartridgeIdsToAdd = cartridgesInRawBot . Where ( x = > x . parentId = = item . _id ) . Select ( x = > x . _tpl ) . ToList ( ) ;
// magazine id already exists, probably has cartridges in it already
if ( itemsThatTakeCartridgesDict . ContainsKey ( item . _tpl ) )
{
//get existing magazine and add new cartridges to it
var existingMagazine = itemsThatTakeCartridgesDict [ item . _tpl ] ;
foreach ( var cartridge in cartridgeIdsToAdd )
{
existingMagazine . AddUnique ( cartridge ) ;
}
}
else // No magazine found, add new magazine + associated cartridges
{
itemsThatTakeCartridgesDict . Add ( item . _tpl , cartridgeIdsToAdd ) ;
}
}
return itemsThatTakeCartridgesDict ;
}
2023-10-31 19:35:32 +00:00
internal static void ReduceAmmoWeightValues ( Bot botToUpdate )
{
foreach ( var caliber in botToUpdate . inventory . Ammo )
{
foreach ( var cartridge in botToUpdate . inventory . Ammo . Keys )
{
var cartridgeWithWeights = botToUpdate . inventory . Ammo [ cartridge ] ;
var weights = cartridgeWithWeights . Values . Select ( x = > x ) . ToList ( ) ;
var commonAmmoDivisor = CommonDivisor ( weights ) ;
foreach ( var cartridgeWeightKvP in cartridgeWithWeights )
{
botToUpdate . inventory . Ammo [ cartridge ] [ cartridgeWeightKvP . Key ] / = commonAmmoDivisor ;
}
}
}
}
public static void ReduceEquipmentWeightValues ( Equipment equipment )
{
ReduceWeightValues ( equipment . Headwear ) ;
ReduceWeightValues ( equipment . Earpiece ) ;
ReduceWeightValues ( equipment . FaceCover ) ;
ReduceWeightValues ( equipment . ArmorVest ) ;
ReduceWeightValues ( equipment . Eyewear ) ;
ReduceWeightValues ( equipment . ArmBand ) ;
ReduceWeightValues ( equipment . TacticalVest ) ;
ReduceWeightValues ( equipment . Backpack ) ;
ReduceWeightValues ( equipment . FirstPrimaryWeapon ) ;
ReduceWeightValues ( equipment . SecondPrimaryWeapon ) ;
ReduceWeightValues ( equipment . Scabbard ) ;
ReduceWeightValues ( equipment . Holster ) ;
ReduceWeightValues ( equipment . Pockets ) ;
ReduceWeightValues ( equipment . SecuredContainer ) ;
}
public static void ReduceWeightValues ( Dictionary < string , int > equipmentDict )
{
// No values, nothing to reduce
if ( equipmentDict . Count = = 0 )
{
return ;
}
// Only one value, quickly set to 1 and exit
if ( equipmentDict . Count = = 1 )
{
equipmentDict [ equipmentDict . First ( ) . Key ] = 1 ;
return ;
}
var weights = equipmentDict . Values . Select ( x = > x ) . ToList ( ) ;
var commonAmmoDivisor = CommonDivisor ( weights ) ;
// No point in dividing by 1
if ( commonAmmoDivisor = = 1 )
{
return ;
}
foreach ( var itemTplWithWeight in equipmentDict )
{
equipmentDict [ itemTplWithWeight . Key ] / = commonAmmoDivisor ;
}
}
2021-08-13 16:24:05 +01:00
}
}