Added New Mods; Removed Backups
- AUG Attachment Pack - Plant Time Modifier
This commit is contained in:
parent
147c9bda00
commit
b292d36c21
|
@ -1,11 +1,11 @@
|
||||||
[General]
|
[General]
|
||||||
gameName=spt
|
gameName=spt
|
||||||
modid=0
|
modid=0
|
||||||
version=d2025.1.8.0
|
version=d2025.1.14.0
|
||||||
newestVersion=
|
newestVersion=
|
||||||
category="1,"
|
category="1,"
|
||||||
nexusFileStatus=1
|
nexusFileStatus=1
|
||||||
installationFile=acidphantasm-progressivebotsystem.zip
|
installationFile=AUG_AttachmentPack.zip
|
||||||
repository=
|
repository=
|
||||||
ignoredVersion=
|
ignoredVersion=
|
||||||
comments=
|
comments=
|
||||||
|
@ -15,7 +15,7 @@ url=
|
||||||
hasCustomURL=false
|
hasCustomURL=false
|
||||||
lastNexusQuery=
|
lastNexusQuery=
|
||||||
lastNexusUpdate=
|
lastNexusUpdate=
|
||||||
nexusLastModified=2024-12-16T07:04:24Z
|
nexusLastModified=2025-01-15T01:12:37Z
|
||||||
nexusCategory=0
|
nexusCategory=0
|
||||||
converted=false
|
converted=false
|
||||||
validated=false
|
validated=false
|
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"manifest": [
|
||||||
|
{
|
||||||
|
"key": "assets/content/items/mods/handguards/handguard_fb20.bundle",
|
||||||
|
"dependencyKeys": [
|
||||||
|
"assets/commonassets/physics/physicsmaterials.bundle",
|
||||||
|
"cubemaps",
|
||||||
|
"shaders"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "assets/content/items/mods/handguards/handguard_guerilla.bundle",
|
||||||
|
"dependencyKeys": [
|
||||||
|
"assets/commonassets/physics/physicsmaterials.bundle",
|
||||||
|
"cubemaps",
|
||||||
|
"shaders"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "assets/content/items/mods/handguards/handguard_turaco.bundle",
|
||||||
|
"dependencyKeys": [
|
||||||
|
"assets/commonassets/physics/physicsmaterials.bundle",
|
||||||
|
"cubemaps",
|
||||||
|
"shaders"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "assets/content/items/mods/magazines/mag_aug_60.bundle",
|
||||||
|
"dependencyKeys": [
|
||||||
|
"assets/commonassets/physics/physicsmaterials.bundle",
|
||||||
|
"cubemaps",
|
||||||
|
"shaders"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
mods/AUG Attachment Pack/user/mods/AUG_AttachmentPack/bundles/assets/content/items/mods/handguards/handguard_fb20.bundle (Stored with Git LFS)
Normal file
BIN
mods/AUG Attachment Pack/user/mods/AUG_AttachmentPack/bundles/assets/content/items/mods/handguards/handguard_fb20.bundle (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mods/AUG Attachment Pack/user/mods/AUG_AttachmentPack/bundles/assets/content/items/mods/handguards/handguard_guerilla.bundle (Stored with Git LFS)
Normal file
BIN
mods/AUG Attachment Pack/user/mods/AUG_AttachmentPack/bundles/assets/content/items/mods/handguards/handguard_guerilla.bundle (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mods/AUG Attachment Pack/user/mods/AUG_AttachmentPack/bundles/assets/content/items/mods/handguards/handguard_turaco.bundle (Stored with Git LFS)
Normal file
BIN
mods/AUG Attachment Pack/user/mods/AUG_AttachmentPack/bundles/assets/content/items/mods/handguards/handguard_turaco.bundle (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mods/AUG Attachment Pack/user/mods/AUG_AttachmentPack/bundles/assets/content/items/mods/magazines/mag_aug_60.bundle (Stored with Git LFS)
Normal file
BIN
mods/AUG Attachment Pack/user/mods/AUG_AttachmentPack/bundles/assets/content/items/mods/magazines/mag_aug_60.bundle (Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"templates": {
|
||||||
|
"6786e03b67ad44fd9b0fabd0": {
|
||||||
|
"Name": "AUG RAS Handguard",
|
||||||
|
"ShortName": "AUG",
|
||||||
|
"Description": "ARMY Metal AUG RAS Handguard For AUG A3 AEG Bullpup Rifle"
|
||||||
|
},
|
||||||
|
"6786e03b67ad44fd9b0fabd1": {
|
||||||
|
"Name": "AUG Cantilever Handguard",
|
||||||
|
"ShortName": "AUG",
|
||||||
|
"Description": "The AUG Cantilever Forend combines a top rail, side rail, and M-LOK forend into a compact, light, and incredibly versatile package."
|
||||||
|
},
|
||||||
|
"6786e03b67ad44fd9b0fabd2": {
|
||||||
|
"Name": "AUG Turaco handguard",
|
||||||
|
"ShortName": "AUG",
|
||||||
|
"Description": "A CNC made handguard with an M-LOK interface."
|
||||||
|
},
|
||||||
|
"6786e03b67ad44fd9b0fabd3": {
|
||||||
|
"Name": "AUG A3 556x45 60-round drum magazine",
|
||||||
|
"ShortName": "AUG",
|
||||||
|
"Description": "A modified PMAG-D60 made to fit Steyr AUG A3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"Items": [
|
||||||
|
{
|
||||||
|
"Id": "6786e03b67ad44fd9b0fabd0",
|
||||||
|
"ParentId": "5b5f75e486f77447ec5d7712",
|
||||||
|
"Price": 20000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "6786e03b67ad44fd9b0fabd1",
|
||||||
|
"ParentId": "5b5f75e486f77447ec5d7712",
|
||||||
|
"Price": 18000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "6786e03b67ad44fd9b0fabd2",
|
||||||
|
"ParentId": "5b5f75e486f77447ec5d7712",
|
||||||
|
"Price": 17000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "6786e03b67ad44fd9b0fabd3",
|
||||||
|
"ParentId": "5b5f754a86f774094242f19b",
|
||||||
|
"Price": 15000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,771 @@
|
||||||
|
{
|
||||||
|
"6786e03b67ad44fd9b0fabd0": {
|
||||||
|
"_id": "6786e03b67ad44fd9b0fabd0",
|
||||||
|
"_name": "handguard_fb20",
|
||||||
|
"_parent": "55818a104bdc2db9688b4569",
|
||||||
|
"_type": "Item",
|
||||||
|
"_props": {
|
||||||
|
"Name": "",
|
||||||
|
"ShortName": "",
|
||||||
|
"Description": "",
|
||||||
|
"Weight": 0.209,
|
||||||
|
"BackgroundColor": "blue",
|
||||||
|
"Width": 2,
|
||||||
|
"Height": 1,
|
||||||
|
"StackMaxSize": 1,
|
||||||
|
"ItemSound": "mod",
|
||||||
|
"Prefab": {
|
||||||
|
"path": "assets/content/items/mods/handguards/handguard_fb20.bundle",
|
||||||
|
"rcid": ""
|
||||||
|
},
|
||||||
|
"UsePrefab": {
|
||||||
|
"path": "",
|
||||||
|
"rcid": ""
|
||||||
|
},
|
||||||
|
"StackObjectsCount": 1,
|
||||||
|
"NotShownInSlot": false,
|
||||||
|
"ExaminedByDefault": true,
|
||||||
|
"ExamineTime": 1,
|
||||||
|
"IsUndiscardable": false,
|
||||||
|
"IsUnsaleable": false,
|
||||||
|
"IsUnbuyable": false,
|
||||||
|
"IsUngivable": false,
|
||||||
|
"IsLockedafterEquip": false,
|
||||||
|
"QuestItem": false,
|
||||||
|
"LootExperience": 10,
|
||||||
|
"ExamineExperience": 3,
|
||||||
|
"HideEntrails": false,
|
||||||
|
"RepairCost": 0,
|
||||||
|
"RepairSpeed": 0,
|
||||||
|
"ExtraSizeLeft": 1,
|
||||||
|
"ExtraSizeRight": 0,
|
||||||
|
"ExtraSizeUp": 0,
|
||||||
|
"ExtraSizeDown": 0,
|
||||||
|
"ExtraSizeForceAdd": false,
|
||||||
|
"MergesWithChildren": true,
|
||||||
|
"CanSellOnRagfair": true,
|
||||||
|
"CanRequireOnRagfair": false,
|
||||||
|
"ConflictingItems": [],
|
||||||
|
"Unlootable": false,
|
||||||
|
"UnlootableFromSlot": "FirstPrimaryWeapon",
|
||||||
|
"UnlootableFromSide": [],
|
||||||
|
"AnimationVariantsNumber": 0,
|
||||||
|
"DiscardingBlock": false,
|
||||||
|
"RagFairCommissionModifier": 1,
|
||||||
|
"IsAlwaysAvailableForInsurance": false,
|
||||||
|
"DiscardLimit": -1,
|
||||||
|
"DropSoundType": "None",
|
||||||
|
"InsuranceDisabled": false,
|
||||||
|
"QuestStashMaxCount": 0,
|
||||||
|
"IsSpecialSlotOnly": false,
|
||||||
|
"IsUnremovable": false,
|
||||||
|
"Grids": [],
|
||||||
|
"Slots": [
|
||||||
|
{
|
||||||
|
"_name": "mod_mount_000",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b3b",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"5a800961159bd4315e3a1657",
|
||||||
|
"57fd23e32459772d0805bcf1",
|
||||||
|
"544909bb4bdc2d6f028b4577",
|
||||||
|
"5d10b49bd7ad1a1a560708b0",
|
||||||
|
"5c06595c0db834001a66af6c",
|
||||||
|
"5cc9c20cd7f00c001336c65d",
|
||||||
|
"5d2369418abbc306c62e0c80",
|
||||||
|
"5b07dd285acfc4001754240d",
|
||||||
|
"56def37dd2720bec348b456a",
|
||||||
|
"5a7b483fe899ef0016170d15",
|
||||||
|
"61605d88ffa6e502ac5e7eeb",
|
||||||
|
"5a5f1ce64f39f90b401987bc",
|
||||||
|
"560d657b4bdc2da74d8b4572",
|
||||||
|
"5b3a337e5acfc4704b4a19a0",
|
||||||
|
"5c5952732e2216398b5abda2",
|
||||||
|
"57d17e212459775a1179a0f5",
|
||||||
|
"6267c6396b642f77f56f5c1c",
|
||||||
|
"6272370ee4013c5d7e31f418",
|
||||||
|
"6272379924e29f06af4d5ecb",
|
||||||
|
"626becf9582c3e319310b837"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_name": "mod_mount_001",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b3c",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"5a800961159bd4315e3a1657",
|
||||||
|
"57fd23e32459772d0805bcf1",
|
||||||
|
"544909bb4bdc2d6f028b4577",
|
||||||
|
"5d10b49bd7ad1a1a560708b0",
|
||||||
|
"5c06595c0db834001a66af6c",
|
||||||
|
"5cc9c20cd7f00c001336c65d",
|
||||||
|
"5d2369418abbc306c62e0c80",
|
||||||
|
"5b07dd285acfc4001754240d",
|
||||||
|
"56def37dd2720bec348b456a",
|
||||||
|
"5a7b483fe899ef0016170d15",
|
||||||
|
"61605d88ffa6e502ac5e7eeb",
|
||||||
|
"5a5f1ce64f39f90b401987bc",
|
||||||
|
"560d657b4bdc2da74d8b4572",
|
||||||
|
"5b3a337e5acfc4704b4a19a0",
|
||||||
|
"5c5952732e2216398b5abda2",
|
||||||
|
"57d17e212459775a1179a0f5",
|
||||||
|
"6267c6396b642f77f56f5c1c",
|
||||||
|
"6272370ee4013c5d7e31f418",
|
||||||
|
"6272379924e29f06af4d5ecb",
|
||||||
|
"626becf9582c3e319310b837"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_name": "mod_tactical",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b3e",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"57fd23e32459772d0805bcf1",
|
||||||
|
"544909bb4bdc2d6f028b4577",
|
||||||
|
"5d10b49bd7ad1a1a560708b0",
|
||||||
|
"5c06595c0db834001a66af6c",
|
||||||
|
"5a7b483fe899ef0016170d15",
|
||||||
|
"61605d88ffa6e502ac5e7eeb",
|
||||||
|
"5c5952732e2216398b5abda2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_name": "mod_foregrip",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b40",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"5c7fc87d2e221644f31c0298",
|
||||||
|
"5cda9bcfd7f00c0c0b53e900",
|
||||||
|
"59f8a37386f7747af3328f06",
|
||||||
|
"619386379fb0c665d5490dbe",
|
||||||
|
"5c87ca002e221600114cb150",
|
||||||
|
"588226d124597767ad33f787",
|
||||||
|
"588226dd24597767ad33f789",
|
||||||
|
"588226e62459776e3e094af7",
|
||||||
|
"588226ef24597767af46e39c",
|
||||||
|
"59fc48e086f77463b1118392",
|
||||||
|
"5fce0cf655375d18a253eff0",
|
||||||
|
"5cf4fb76d7f00c065703d3ac",
|
||||||
|
"5b057b4f5acfc4771e1bd3e9",
|
||||||
|
"5c791e872e2216001219c40a",
|
||||||
|
"558032614bdc2de7118b4585",
|
||||||
|
"58c157be86f77403c74b2bb6",
|
||||||
|
"58c157c886f774032749fb06",
|
||||||
|
"5f6340d3ca442212f4047eb2",
|
||||||
|
"591af28e86f77414a27a9e1d",
|
||||||
|
"5c1cd46f2e22164bef5cfedb",
|
||||||
|
"5c1bc4812e22164bef5cfde7",
|
||||||
|
"5c1bc5612e221602b5429350",
|
||||||
|
"5c1bc5af2e221602b412949b",
|
||||||
|
"5c1bc5fb2e221602b1779b32",
|
||||||
|
"5c1bc7432e221602b412949d",
|
||||||
|
"5c1bc7752e221602b1779b34"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"CanPutIntoDuringTheRaid": true,
|
||||||
|
"CantRemoveFromSlotsDuringRaid": [],
|
||||||
|
"Durability": 100,
|
||||||
|
"Accuracy": 0,
|
||||||
|
"Recoil": -1,
|
||||||
|
"Loudness": 0,
|
||||||
|
"EffectiveDistance": 0,
|
||||||
|
"Ergonomics": 8,
|
||||||
|
"Velocity": 0,
|
||||||
|
"RaidModdable": false,
|
||||||
|
"ToolModdable": true,
|
||||||
|
"BlocksFolding": false,
|
||||||
|
"BlocksCollapsible": false,
|
||||||
|
"IsAnimated": false,
|
||||||
|
"HasShoulderContact": false,
|
||||||
|
"SightingRange": 0,
|
||||||
|
"DoubleActionAccuracyPenaltyMult": 1,
|
||||||
|
"HeatFactor": 0.985,
|
||||||
|
"CoolFactor": 1.055
|
||||||
|
},
|
||||||
|
"_proto": "55d459824bdc2d892f8b4573"
|
||||||
|
},
|
||||||
|
"6786e03b67ad44fd9b0fabd1": {
|
||||||
|
"_id": "6786e03b67ad44fd9b0fabd1",
|
||||||
|
"_name": "handguard_guerilla",
|
||||||
|
"_parent": "55818a104bdc2db9688b4569",
|
||||||
|
"_type": "Item",
|
||||||
|
"_props": {
|
||||||
|
"Name": "",
|
||||||
|
"ShortName": "",
|
||||||
|
"Description": "",
|
||||||
|
"Weight": 0.209,
|
||||||
|
"BackgroundColor": "blue",
|
||||||
|
"Width": 2,
|
||||||
|
"Height": 1,
|
||||||
|
"StackMaxSize": 1,
|
||||||
|
"ItemSound": "mod",
|
||||||
|
"Prefab": {
|
||||||
|
"path": "assets/content/items/mods/handguards/handguard_guerilla.bundle",
|
||||||
|
"rcid": ""
|
||||||
|
},
|
||||||
|
"UsePrefab": {
|
||||||
|
"path": "",
|
||||||
|
"rcid": ""
|
||||||
|
},
|
||||||
|
"StackObjectsCount": 1,
|
||||||
|
"NotShownInSlot": false,
|
||||||
|
"ExaminedByDefault": true,
|
||||||
|
"ExamineTime": 1,
|
||||||
|
"IsUndiscardable": false,
|
||||||
|
"IsUnsaleable": false,
|
||||||
|
"IsUnbuyable": false,
|
||||||
|
"IsUngivable": false,
|
||||||
|
"IsLockedafterEquip": false,
|
||||||
|
"QuestItem": false,
|
||||||
|
"LootExperience": 10,
|
||||||
|
"ExamineExperience": 3,
|
||||||
|
"HideEntrails": false,
|
||||||
|
"RepairCost": 0,
|
||||||
|
"RepairSpeed": 0,
|
||||||
|
"ExtraSizeLeft": 1,
|
||||||
|
"ExtraSizeRight": 0,
|
||||||
|
"ExtraSizeUp": 0,
|
||||||
|
"ExtraSizeDown": 0,
|
||||||
|
"ExtraSizeForceAdd": false,
|
||||||
|
"MergesWithChildren": true,
|
||||||
|
"CanSellOnRagfair": true,
|
||||||
|
"CanRequireOnRagfair": false,
|
||||||
|
"ConflictingItems": [],
|
||||||
|
"Unlootable": false,
|
||||||
|
"UnlootableFromSlot": "FirstPrimaryWeapon",
|
||||||
|
"UnlootableFromSide": [],
|
||||||
|
"AnimationVariantsNumber": 0,
|
||||||
|
"DiscardingBlock": false,
|
||||||
|
"RagFairCommissionModifier": 1,
|
||||||
|
"IsAlwaysAvailableForInsurance": false,
|
||||||
|
"DiscardLimit": -1,
|
||||||
|
"DropSoundType": "None",
|
||||||
|
"InsuranceDisabled": false,
|
||||||
|
"QuestStashMaxCount": 0,
|
||||||
|
"IsSpecialSlotOnly": false,
|
||||||
|
"IsUnremovable": false,
|
||||||
|
"Grids": [],
|
||||||
|
"Slots": [
|
||||||
|
{
|
||||||
|
"_name": "mod_mount_001",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b3c",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"5a800961159bd4315e3a1657",
|
||||||
|
"57fd23e32459772d0805bcf1",
|
||||||
|
"544909bb4bdc2d6f028b4577",
|
||||||
|
"5d10b49bd7ad1a1a560708b0",
|
||||||
|
"5c06595c0db834001a66af6c",
|
||||||
|
"5cc9c20cd7f00c001336c65d",
|
||||||
|
"5d2369418abbc306c62e0c80",
|
||||||
|
"5b07dd285acfc4001754240d",
|
||||||
|
"56def37dd2720bec348b456a",
|
||||||
|
"5a7b483fe899ef0016170d15",
|
||||||
|
"61605d88ffa6e502ac5e7eeb",
|
||||||
|
"5a5f1ce64f39f90b401987bc",
|
||||||
|
"560d657b4bdc2da74d8b4572",
|
||||||
|
"5b3a337e5acfc4704b4a19a0",
|
||||||
|
"5c5952732e2216398b5abda2",
|
||||||
|
"57d17e212459775a1179a0f5",
|
||||||
|
"6267c6396b642f77f56f5c1c",
|
||||||
|
"6272370ee4013c5d7e31f418",
|
||||||
|
"6272379924e29f06af4d5ecb",
|
||||||
|
"626becf9582c3e319310b837"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_name": "mod_foregrip",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b40",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"5c7fc87d2e221644f31c0298",
|
||||||
|
"5cda9bcfd7f00c0c0b53e900",
|
||||||
|
"59f8a37386f7747af3328f06",
|
||||||
|
"619386379fb0c665d5490dbe",
|
||||||
|
"5c87ca002e221600114cb150",
|
||||||
|
"588226d124597767ad33f787",
|
||||||
|
"588226dd24597767ad33f789",
|
||||||
|
"588226e62459776e3e094af7",
|
||||||
|
"588226ef24597767af46e39c",
|
||||||
|
"59fc48e086f77463b1118392",
|
||||||
|
"5fce0cf655375d18a253eff0",
|
||||||
|
"5cf4fb76d7f00c065703d3ac",
|
||||||
|
"5b057b4f5acfc4771e1bd3e9",
|
||||||
|
"5c791e872e2216001219c40a",
|
||||||
|
"558032614bdc2de7118b4585",
|
||||||
|
"58c157be86f77403c74b2bb6",
|
||||||
|
"58c157c886f774032749fb06",
|
||||||
|
"5f6340d3ca442212f4047eb2",
|
||||||
|
"591af28e86f77414a27a9e1d",
|
||||||
|
"5c1cd46f2e22164bef5cfedb",
|
||||||
|
"5c1bc4812e22164bef5cfde7",
|
||||||
|
"5c1bc5612e221602b5429350",
|
||||||
|
"5c1bc5af2e221602b412949b",
|
||||||
|
"5c1bc5fb2e221602b1779b32",
|
||||||
|
"5c1bc7432e221602b412949d",
|
||||||
|
"5c1bc7752e221602b1779b34"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_name": "mod_tactical",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b3e",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"57fd23e32459772d0805bcf1",
|
||||||
|
"544909bb4bdc2d6f028b4577",
|
||||||
|
"5d10b49bd7ad1a1a560708b0",
|
||||||
|
"5c06595c0db834001a66af6c",
|
||||||
|
"5a7b483fe899ef0016170d15",
|
||||||
|
"61605d88ffa6e502ac5e7eeb",
|
||||||
|
"5c5952732e2216398b5abda2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"CanPutIntoDuringTheRaid": true,
|
||||||
|
"CantRemoveFromSlotsDuringRaid": [],
|
||||||
|
"Durability": 100,
|
||||||
|
"Accuracy": 0,
|
||||||
|
"Recoil": -1,
|
||||||
|
"Loudness": 0,
|
||||||
|
"EffectiveDistance": 0,
|
||||||
|
"Ergonomics": 8,
|
||||||
|
"Velocity": 0,
|
||||||
|
"RaidModdable": false,
|
||||||
|
"ToolModdable": true,
|
||||||
|
"BlocksFolding": false,
|
||||||
|
"BlocksCollapsible": false,
|
||||||
|
"IsAnimated": false,
|
||||||
|
"HasShoulderContact": false,
|
||||||
|
"SightingRange": 0,
|
||||||
|
"DoubleActionAccuracyPenaltyMult": 1,
|
||||||
|
"HeatFactor": 0.985,
|
||||||
|
"CoolFactor": 1.055
|
||||||
|
},
|
||||||
|
"_proto": "55d459824bdc2d892f8b4573"
|
||||||
|
},
|
||||||
|
"6786e03b67ad44fd9b0fabd2": {
|
||||||
|
"_id": "6786e03b67ad44fd9b0fabd2",
|
||||||
|
"_name": "handguard_turaco",
|
||||||
|
"_parent": "55818a104bdc2db9688b4569",
|
||||||
|
"_type": "Item",
|
||||||
|
"_props": {
|
||||||
|
"Name": "",
|
||||||
|
"ShortName": "",
|
||||||
|
"Description": "",
|
||||||
|
"Weight": 0.209,
|
||||||
|
"BackgroundColor": "blue",
|
||||||
|
"Width": 2,
|
||||||
|
"Height": 1,
|
||||||
|
"StackMaxSize": 1,
|
||||||
|
"ItemSound": "mod",
|
||||||
|
"Prefab": {
|
||||||
|
"path": "assets/content/items/mods/handguards/handguard_turaco.bundle",
|
||||||
|
"rcid": ""
|
||||||
|
},
|
||||||
|
"UsePrefab": {
|
||||||
|
"path": "",
|
||||||
|
"rcid": ""
|
||||||
|
},
|
||||||
|
"StackObjectsCount": 1,
|
||||||
|
"NotShownInSlot": false,
|
||||||
|
"ExaminedByDefault": true,
|
||||||
|
"ExamineTime": 1,
|
||||||
|
"IsUndiscardable": false,
|
||||||
|
"IsUnsaleable": false,
|
||||||
|
"IsUnbuyable": false,
|
||||||
|
"IsUngivable": false,
|
||||||
|
"IsLockedafterEquip": false,
|
||||||
|
"QuestItem": false,
|
||||||
|
"LootExperience": 10,
|
||||||
|
"ExamineExperience": 3,
|
||||||
|
"HideEntrails": false,
|
||||||
|
"RepairCost": 0,
|
||||||
|
"RepairSpeed": 0,
|
||||||
|
"ExtraSizeLeft": 1,
|
||||||
|
"ExtraSizeRight": 0,
|
||||||
|
"ExtraSizeUp": 0,
|
||||||
|
"ExtraSizeDown": 0,
|
||||||
|
"ExtraSizeForceAdd": false,
|
||||||
|
"MergesWithChildren": true,
|
||||||
|
"CanSellOnRagfair": true,
|
||||||
|
"CanRequireOnRagfair": false,
|
||||||
|
"ConflictingItems": [],
|
||||||
|
"Unlootable": false,
|
||||||
|
"UnlootableFromSlot": "FirstPrimaryWeapon",
|
||||||
|
"UnlootableFromSide": [],
|
||||||
|
"AnimationVariantsNumber": 0,
|
||||||
|
"DiscardingBlock": false,
|
||||||
|
"RagFairCommissionModifier": 1,
|
||||||
|
"IsAlwaysAvailableForInsurance": false,
|
||||||
|
"DiscardLimit": -1,
|
||||||
|
"DropSoundType": "None",
|
||||||
|
"InsuranceDisabled": false,
|
||||||
|
"QuestStashMaxCount": 0,
|
||||||
|
"IsSpecialSlotOnly": false,
|
||||||
|
"IsUnremovable": false,
|
||||||
|
"Grids": [],
|
||||||
|
"Slots": [
|
||||||
|
{
|
||||||
|
"_name": "mod_mount_000",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b3b",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"5a800961159bd4315e3a1657",
|
||||||
|
"57fd23e32459772d0805bcf1",
|
||||||
|
"544909bb4bdc2d6f028b4577",
|
||||||
|
"5d10b49bd7ad1a1a560708b0",
|
||||||
|
"5c06595c0db834001a66af6c",
|
||||||
|
"5cc9c20cd7f00c001336c65d",
|
||||||
|
"5d2369418abbc306c62e0c80",
|
||||||
|
"5b07dd285acfc4001754240d",
|
||||||
|
"56def37dd2720bec348b456a",
|
||||||
|
"5a7b483fe899ef0016170d15",
|
||||||
|
"61605d88ffa6e502ac5e7eeb",
|
||||||
|
"5a5f1ce64f39f90b401987bc",
|
||||||
|
"560d657b4bdc2da74d8b4572",
|
||||||
|
"5b3a337e5acfc4704b4a19a0",
|
||||||
|
"5c5952732e2216398b5abda2",
|
||||||
|
"57d17e212459775a1179a0f5",
|
||||||
|
"6267c6396b642f77f56f5c1c",
|
||||||
|
"6272370ee4013c5d7e31f418",
|
||||||
|
"6272379924e29f06af4d5ecb",
|
||||||
|
"626becf9582c3e319310b837"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_name": "mod_mount_001",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b3c",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"5a800961159bd4315e3a1657",
|
||||||
|
"57fd23e32459772d0805bcf1",
|
||||||
|
"544909bb4bdc2d6f028b4577",
|
||||||
|
"5d10b49bd7ad1a1a560708b0",
|
||||||
|
"5c06595c0db834001a66af6c",
|
||||||
|
"5cc9c20cd7f00c001336c65d",
|
||||||
|
"5d2369418abbc306c62e0c80",
|
||||||
|
"5b07dd285acfc4001754240d",
|
||||||
|
"56def37dd2720bec348b456a",
|
||||||
|
"5a7b483fe899ef0016170d15",
|
||||||
|
"61605d88ffa6e502ac5e7eeb",
|
||||||
|
"5a5f1ce64f39f90b401987bc",
|
||||||
|
"560d657b4bdc2da74d8b4572",
|
||||||
|
"5b3a337e5acfc4704b4a19a0",
|
||||||
|
"5c5952732e2216398b5abda2",
|
||||||
|
"57d17e212459775a1179a0f5",
|
||||||
|
"6267c6396b642f77f56f5c1c",
|
||||||
|
"6272370ee4013c5d7e31f418",
|
||||||
|
"6272379924e29f06af4d5ecb",
|
||||||
|
"626becf9582c3e319310b837"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_name": "mod_tactical",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b3e",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"57fd23e32459772d0805bcf1",
|
||||||
|
"544909bb4bdc2d6f028b4577",
|
||||||
|
"5d10b49bd7ad1a1a560708b0",
|
||||||
|
"5c06595c0db834001a66af6c",
|
||||||
|
"5a7b483fe899ef0016170d15",
|
||||||
|
"61605d88ffa6e502ac5e7eeb",
|
||||||
|
"5c5952732e2216398b5abda2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_name": "mod_foregrip",
|
||||||
|
"_id": "5c6d5d8b2e221644fc630b40",
|
||||||
|
"_parent": "5c6d5d8b2e221644fc630b39",
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Shift": 0,
|
||||||
|
"Filter": [
|
||||||
|
"5c7fc87d2e221644f31c0298",
|
||||||
|
"5cda9bcfd7f00c0c0b53e900",
|
||||||
|
"59f8a37386f7747af3328f06",
|
||||||
|
"619386379fb0c665d5490dbe",
|
||||||
|
"5c87ca002e221600114cb150",
|
||||||
|
"588226d124597767ad33f787",
|
||||||
|
"588226dd24597767ad33f789",
|
||||||
|
"588226e62459776e3e094af7",
|
||||||
|
"588226ef24597767af46e39c",
|
||||||
|
"59fc48e086f77463b1118392",
|
||||||
|
"5fce0cf655375d18a253eff0",
|
||||||
|
"5cf4fb76d7f00c065703d3ac",
|
||||||
|
"5b057b4f5acfc4771e1bd3e9",
|
||||||
|
"5c791e872e2216001219c40a",
|
||||||
|
"558032614bdc2de7118b4585",
|
||||||
|
"58c157be86f77403c74b2bb6",
|
||||||
|
"58c157c886f774032749fb06",
|
||||||
|
"5f6340d3ca442212f4047eb2",
|
||||||
|
"591af28e86f77414a27a9e1d",
|
||||||
|
"5c1cd46f2e22164bef5cfedb",
|
||||||
|
"5c1bc4812e22164bef5cfde7",
|
||||||
|
"5c1bc5612e221602b5429350",
|
||||||
|
"5c1bc5af2e221602b412949b",
|
||||||
|
"5c1bc5fb2e221602b1779b32",
|
||||||
|
"5c1bc7432e221602b412949d",
|
||||||
|
"5c1bc7752e221602b1779b34",
|
||||||
|
"5a7dbfc1159bd40016548fde"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_required": false,
|
||||||
|
"_mergeSlotWithChildren": false,
|
||||||
|
"_proto": "55d30c4c4bdc2db4468b457e"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"CanPutIntoDuringTheRaid": true,
|
||||||
|
"CantRemoveFromSlotsDuringRaid": [],
|
||||||
|
"Durability": 100,
|
||||||
|
"Accuracy": 0,
|
||||||
|
"Recoil": -1,
|
||||||
|
"Loudness": 0,
|
||||||
|
"EffectiveDistance": 0,
|
||||||
|
"Ergonomics": 8,
|
||||||
|
"Velocity": 0,
|
||||||
|
"RaidModdable": false,
|
||||||
|
"ToolModdable": true,
|
||||||
|
"BlocksFolding": false,
|
||||||
|
"BlocksCollapsible": false,
|
||||||
|
"IsAnimated": false,
|
||||||
|
"HasShoulderContact": false,
|
||||||
|
"SightingRange": 0,
|
||||||
|
"DoubleActionAccuracyPenaltyMult": 1,
|
||||||
|
"HeatFactor": 0.985,
|
||||||
|
"CoolFactor": 1.055
|
||||||
|
},
|
||||||
|
"_proto": "55d459824bdc2d892f8b4573"
|
||||||
|
},
|
||||||
|
"6786e03b67ad44fd9b0fabd3": {
|
||||||
|
"_id": "6786e03b67ad44fd9b0fabd3",
|
||||||
|
"_name": "mag_aug_60",
|
||||||
|
"_parent": "5448bc234bdc2d3c308b4569",
|
||||||
|
"_type": "Item",
|
||||||
|
"_props": {
|
||||||
|
"Name": "",
|
||||||
|
"ShortName": "",
|
||||||
|
"Description": "",
|
||||||
|
"Weight": 0.58,
|
||||||
|
"BackgroundColor": "yellow",
|
||||||
|
"Width": 1,
|
||||||
|
"Height": 2,
|
||||||
|
"StackMaxSize": 1,
|
||||||
|
"ItemSound": "mag_plastic",
|
||||||
|
"Prefab": {
|
||||||
|
"path": "assets/content/items/mods/magazines/mag_aug_60.bundle",
|
||||||
|
"rcid": ""
|
||||||
|
},
|
||||||
|
"UsePrefab": {
|
||||||
|
"path": "",
|
||||||
|
"rcid": ""
|
||||||
|
},
|
||||||
|
"StackObjectsCount": 1,
|
||||||
|
"NotShownInSlot": false,
|
||||||
|
"ExaminedByDefault": true,
|
||||||
|
"ExamineTime": 1,
|
||||||
|
"IsUndiscardable": false,
|
||||||
|
"IsUnsaleable": false,
|
||||||
|
"IsUnbuyable": false,
|
||||||
|
"IsUngivable": false,
|
||||||
|
"IsLockedafterEquip": false,
|
||||||
|
"QuestItem": false,
|
||||||
|
"LootExperience": 10,
|
||||||
|
"ExamineExperience": 2,
|
||||||
|
"HideEntrails": false,
|
||||||
|
"RepairCost": 0,
|
||||||
|
"RepairSpeed": 0,
|
||||||
|
"ExtraSizeLeft": 0,
|
||||||
|
"ExtraSizeRight": 0,
|
||||||
|
"ExtraSizeUp": 0,
|
||||||
|
"ExtraSizeDown": 1,
|
||||||
|
"ExtraSizeForceAdd": false,
|
||||||
|
"MergesWithChildren": true,
|
||||||
|
"CanSellOnRagfair": false,
|
||||||
|
"CanRequireOnRagfair": false,
|
||||||
|
"ConflictingItems": [],
|
||||||
|
"Unlootable": false,
|
||||||
|
"UnlootableFromSlot": "FirstPrimaryWeapon",
|
||||||
|
"UnlootableFromSide": [],
|
||||||
|
"AnimationVariantsNumber": 0,
|
||||||
|
"DiscardingBlock": false,
|
||||||
|
"RagFairCommissionModifier": 1,
|
||||||
|
"IsAlwaysAvailableForInsurance": false,
|
||||||
|
"DiscardLimit": -1,
|
||||||
|
"DropSoundType": "None",
|
||||||
|
"InsuranceDisabled": false,
|
||||||
|
"QuestStashMaxCount": 0,
|
||||||
|
"IsSpecialSlotOnly": false,
|
||||||
|
"IsUnremovable": false,
|
||||||
|
"Grids": [],
|
||||||
|
"Slots": [],
|
||||||
|
"CanPutIntoDuringTheRaid": true,
|
||||||
|
"CantRemoveFromSlotsDuringRaid": [],
|
||||||
|
"Durability": 100,
|
||||||
|
"Accuracy": 0,
|
||||||
|
"Recoil": 0,
|
||||||
|
"Loudness": 0,
|
||||||
|
"EffectiveDistance": 0,
|
||||||
|
"Ergonomics": -16,
|
||||||
|
"Velocity": 0,
|
||||||
|
"RaidModdable": true,
|
||||||
|
"ToolModdable": false,
|
||||||
|
"BlocksFolding": false,
|
||||||
|
"BlocksCollapsible": false,
|
||||||
|
"IsAnimated": false,
|
||||||
|
"HasShoulderContact": false,
|
||||||
|
"SightingRange": 0,
|
||||||
|
"DoubleActionAccuracyPenaltyMult": 1,
|
||||||
|
"magAnimationIndex": 5,
|
||||||
|
"Cartridges": [
|
||||||
|
{
|
||||||
|
"_name": "cartridges",
|
||||||
|
"_id": "59c1383d86f774290a37e0cb",
|
||||||
|
"_parent": "59c1383d86f774290a37e0ca",
|
||||||
|
"_max_count": 60,
|
||||||
|
"_props": {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"Filter": [
|
||||||
|
"59e6920f86f77411d82aa167",
|
||||||
|
"59e6927d86f77411da468256",
|
||||||
|
"54527a984bdc2d4e668b4567",
|
||||||
|
"54527ac44bdc2d36668b4567",
|
||||||
|
"59e68f6f86f7746c9f75e846",
|
||||||
|
"59e6906286f7746c9f75e847",
|
||||||
|
"59e690b686f7746c9f75e848",
|
||||||
|
"59e6918f86f7746c9f75e849",
|
||||||
|
"60194943740c5d77f6705eea",
|
||||||
|
"601949593ae8f707c4608daa",
|
||||||
|
"5c0d5ae286f7741e46554302",
|
||||||
|
"5fbe3ffdf8b6a877a729ea82",
|
||||||
|
"5fd20ff893a8961fc660a954",
|
||||||
|
"619636be6db0f2477964e710",
|
||||||
|
"6196364158ef8c428c287d9f",
|
||||||
|
"6196365d58ef8c428c287da1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_proto": "5748538b2459770af276a261"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"CanFast": true,
|
||||||
|
"CanHit": false,
|
||||||
|
"CanAdmin": false,
|
||||||
|
"LoadUnloadModifier": 60,
|
||||||
|
"CheckTimeModifier": 20,
|
||||||
|
"CheckOverride": 0,
|
||||||
|
"ReloadMagType": "ExternalMagazine",
|
||||||
|
"VisibleAmmoRangesString": "1-3",
|
||||||
|
"MalfunctionChance": 0.3,
|
||||||
|
"TagColor": 0,
|
||||||
|
"TagName": ""
|
||||||
|
},
|
||||||
|
"_proto": "55802d5f4bdc2dac148b458e"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
{
|
||||||
|
"traderId":"5935c25fb3acc3127c3d8cd9",
|
||||||
|
"assorts":{
|
||||||
|
"items":[
|
||||||
|
{
|
||||||
|
"_id":"6786e03b67ad44fd9b0fabd0",
|
||||||
|
"_tpl":"6786e03b67ad44fd9b0fabd0",
|
||||||
|
"parentId":"hideout",
|
||||||
|
"slotId":"hideout",
|
||||||
|
"upd":{
|
||||||
|
"UnlimitedCount":true,
|
||||||
|
"StackObjectsCount":999999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id":"6786e03b67ad44fd9b0fabd1",
|
||||||
|
"_tpl":"6786e03b67ad44fd9b0fabd1",
|
||||||
|
"parentId":"hideout",
|
||||||
|
"slotId":"hideout",
|
||||||
|
"upd":{
|
||||||
|
"UnlimitedCount":true,
|
||||||
|
"StackObjectsCount":999999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id":"6786e03b67ad44fd9b0fabd2",
|
||||||
|
"_tpl":"6786e03b67ad44fd9b0fabd2",
|
||||||
|
"parentId":"hideout",
|
||||||
|
"slotId":"hideout",
|
||||||
|
"upd":{
|
||||||
|
"UnlimitedCount":true,
|
||||||
|
"StackObjectsCount":999999
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_id":"6786e03b67ad44fd9b0fabd3",
|
||||||
|
"_tpl":"6786e03b67ad44fd9b0fabd3",
|
||||||
|
"parentId":"hideout",
|
||||||
|
"slotId":"hideout",
|
||||||
|
"upd":{
|
||||||
|
"UnlimitedCount":true,
|
||||||
|
"StackObjectsCount":999999
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"barter_scheme":{
|
||||||
|
"6786e03b67ad44fd9b0fabd0":[
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"count":21000,
|
||||||
|
"_tpl":"5449016a4bdc2d6f028b456f"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"6786e03b67ad44fd9b0fabd1":[
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"count":21000,
|
||||||
|
"_tpl":"5449016a4bdc2d6f028b456f"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"6786e03b67ad44fd9b0fabd2":[
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"count":21000,
|
||||||
|
"_tpl":"5449016a4bdc2d6f028b456f"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"6786e03b67ad44fd9b0fabd3":[
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"count":21000,
|
||||||
|
"_tpl":"5449016a4bdc2d6f028b456f"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"loyal_level_items":{
|
||||||
|
"6786e03b67ad44fd9b0fabd0":3,
|
||||||
|
"6786e03b67ad44fd9b0fabd1":3,
|
||||||
|
"6786e03b67ad44fd9b0fabd2":3,
|
||||||
|
"6786e03b67ad44fd9b0fabd3":3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
let mydb;
|
||||||
|
|
||||||
|
class Mod {
|
||||||
|
postDBLoad(container) {
|
||||||
|
// Credit Banner
|
||||||
|
console.log(`
|
||||||
|
=======================================
|
||||||
|
| AUG Attachment Pack |
|
||||||
|
| Created by: KoKaZ93 |
|
||||||
|
| 3.10 Port made by: GMAK3R |
|
||||||
|
=======================================
|
||||||
|
`);
|
||||||
|
|
||||||
|
const modLoader = container.resolve("PreSptModLoader");
|
||||||
|
const importerUtil = container.resolve("ImporterUtil");
|
||||||
|
const db = container.resolve("DatabaseServer").getTables();
|
||||||
|
const locales = db.locales.global;
|
||||||
|
const items = db.templates.items;
|
||||||
|
const handbook = db.templates.handbook.Items;
|
||||||
|
const peacekeeper = db.traders["5935c25fb3acc3127c3d8cd9"];
|
||||||
|
|
||||||
|
mydb = importerUtil.loadRecursive(`${modLoader.getModPath("AUG_AttachmentPack")}database/`);
|
||||||
|
|
||||||
|
for (const item in mydb.templates.items) {
|
||||||
|
items[item] = mydb.templates.items[item];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const item of mydb.templates.handbook.Items) {
|
||||||
|
handbook.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const item of mydb.traders.assort.assorts.items) {
|
||||||
|
peacekeeper.assort.items.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const bc in mydb.traders.assort.assorts.barter_scheme) {
|
||||||
|
peacekeeper.assort.barter_scheme[bc] = mydb.traders.assort.assorts.barter_scheme[bc];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const level in mydb.traders.assort.assorts.loyal_level_items) {
|
||||||
|
peacekeeper.assort.loyal_level_items[level] = mydb.traders.assort.assorts.loyal_level_items[level];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const localeID in locales) {
|
||||||
|
if (localeID == "en") {
|
||||||
|
for (const [itemId, template] of Object.entries(mydb.locales.en.templates)) {
|
||||||
|
for (const [key, value] of Object.entries(template)) {
|
||||||
|
locales[localeID][`${itemId} ${key}`] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mod.addHandguardToFilters(db);
|
||||||
|
Mod.addMagazineToFilters(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
static addHandguardToFilters(db) {
|
||||||
|
const isItemSlotsExist = (item) =>
|
||||||
|
item._props && item._props.Slots && item._props.Slots.length > 0;
|
||||||
|
const attachmentToAdd = ["6786e03b67ad44fd9b0fabd0", "6786e03b67ad44fd9b0fabd1", "6786e03b67ad44fd9b0fabd2"];
|
||||||
|
const attachmentItemId = "634e61b0767cb15c4601a877";
|
||||||
|
|
||||||
|
for (const item of Object.values(db.templates.items)) {
|
||||||
|
if (isItemSlotsExist(item)) {
|
||||||
|
for (const slot of item._props.Slots) {
|
||||||
|
if (slot._props.filters.some((filter) => filter.Filter.includes(attachmentItemId))) {
|
||||||
|
slot._props.filters.forEach((filter) => {
|
||||||
|
if (filter.Filter.includes(attachmentItemId)) {
|
||||||
|
filter.Filter.push(...attachmentToAdd);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static addMagazineToFilters(db) {
|
||||||
|
const isItemSlotsExist = (item) =>
|
||||||
|
item._props && item._props.Slots && item._props.Slots.length > 0;
|
||||||
|
const attachmentToAdd = "6786e03b67ad44fd9b0fabd3";
|
||||||
|
const attachmentItemId = "630e1adbbd357927e4007c09";
|
||||||
|
|
||||||
|
for (const item of Object.values(db.templates.items)) {
|
||||||
|
if (isItemSlotsExist(item)) {
|
||||||
|
for (const slot of item._props.Slots) {
|
||||||
|
if (slot._props.filters.some((filter) => filter.Filter.includes(attachmentItemId))) {
|
||||||
|
slot._props.filters.forEach((filter) => {
|
||||||
|
if (filter.Filter.includes(attachmentItemId)) {
|
||||||
|
filter.Filter.push(attachmentToAdd);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { mod: new Mod() };
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"name": "AUG Attachment Pack",
|
||||||
|
"author": "KoKaZ93",
|
||||||
|
"license": "CC BY-NC-SA 3.0",
|
||||||
|
"version": "1.0.4",
|
||||||
|
"sptVersion": "3.10.x",
|
||||||
|
"main": "mod.js",
|
||||||
|
"isBundleMod": true
|
||||||
|
}
|
Binary file not shown.
|
@ -1,29 +0,0 @@
|
||||||
name: "tagged-release"
|
|
||||||
|
|
||||||
on: push
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
tagged-release:
|
|
||||||
name: "Tagged Release"
|
|
||||||
runs-on: "ubuntu-latest"
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
fetch-depth: 2
|
|
||||||
- name: Print package.json version (before)
|
|
||||||
id: versionstep
|
|
||||||
run: |
|
|
||||||
echo "version=$(jq -r .version package.json)" >> $GITHUB_OUTPUT
|
|
||||||
working-directory: ${{ github.workspace }}
|
|
||||||
- uses: "marvinpinto/action-automatic-releases@latest"
|
|
||||||
with:
|
|
||||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
automatic_release_tag: ${{ steps.versionstep.outputs.version }}
|
|
||||||
title: "MOAR ${{ steps.versionstep.outputs.version }}"
|
|
||||||
prerelease: false
|
|
||||||
files: |
|
|
||||||
./dist/*.zip
|
|
|
@ -1,15 +0,0 @@
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- name: staging
|
|
||||||
prerelease: true
|
|
||||||
debug: true
|
|
||||||
ci: true
|
|
||||||
dryRun: false
|
|
||||||
plugins:
|
|
||||||
- "@semantic-release/commit-analyzer"
|
|
||||||
- "@semantic-release/release-notes-generator"
|
|
||||||
- "@semantic-release/github"
|
|
||||||
- "@semantic-release/npm"
|
|
||||||
- - "@semantic-release/git"
|
|
||||||
- assets: ["package.json"]
|
|
||||||
message: "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
|
|
@ -1,21 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2023 Dushaoan
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"live-like": 25,
|
|
||||||
"more-scavs": 8,
|
|
||||||
"more-pmcs": 8,
|
|
||||||
"more-scavs-and-pmcs": 5,
|
|
||||||
"main-boss-roaming": 5,
|
|
||||||
"sniper-buddies": 4,
|
|
||||||
"boss-invasion": 2,
|
|
||||||
"rogue-invasion": 0,
|
|
||||||
"raider-invasion": 0,
|
|
||||||
"insanity": 0
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
{
|
|
||||||
"live-like": {},
|
|
||||||
"more-scavs": {
|
|
||||||
"moreScavGroups": true,
|
|
||||||
"scavMaxGroupSize": 5,
|
|
||||||
"scavWaveQuantity": 1.2
|
|
||||||
},
|
|
||||||
"more-pmcs": {
|
|
||||||
"morePmcGroups": true,
|
|
||||||
"pmcMaxGroupSize": 5,
|
|
||||||
"pmcWaveQuantity": 1.2
|
|
||||||
},
|
|
||||||
"more-scavs-and-pmcs": {
|
|
||||||
"maxBotCap": 30,
|
|
||||||
"moreScavGroups": true,
|
|
||||||
"scavMaxGroupSize": 5,
|
|
||||||
"morePmcGroups": true,
|
|
||||||
"pmcMaxGroupSize": 5,
|
|
||||||
"scavWaveQuantity": 1.2,
|
|
||||||
"pmcWaveQuantity": 1.2,
|
|
||||||
"mainBossChanceBuff": 25
|
|
||||||
},
|
|
||||||
"boss-invasion": {
|
|
||||||
"bossOpenZones": true,
|
|
||||||
"bossInvasion": true,
|
|
||||||
"bossInvasionSpawnChance": 10,
|
|
||||||
"mainBossChanceBuff": 25,
|
|
||||||
"gradualBossInvasion": true
|
|
||||||
},
|
|
||||||
"rogue-invasion": {
|
|
||||||
"randomRaiderGroup": true,
|
|
||||||
"randomRaiderGroupChance": 50
|
|
||||||
},
|
|
||||||
"raider-invasion": {
|
|
||||||
"randomRaiderGroup": true,
|
|
||||||
"randomRaiderGroupChance": 50
|
|
||||||
},
|
|
||||||
"insanity": {
|
|
||||||
"scavWaveDistribution": 0.4,
|
|
||||||
"scavWaveQuantity": 1.3,
|
|
||||||
"pmcWaveQuantity": 1.3,
|
|
||||||
"maxBotCap": 30,
|
|
||||||
"maxBotPerZone": 9,
|
|
||||||
"moreScavGroups": true,
|
|
||||||
"morePmcGroups": true,
|
|
||||||
"pmcMaxGroupSize": 6,
|
|
||||||
"scavMaxGroupSize": 6,
|
|
||||||
"snipersHaveFriends": true,
|
|
||||||
"bossOpenZones": true,
|
|
||||||
"randomRaiderGroup": true,
|
|
||||||
"randomRaiderGroupChance": 50,
|
|
||||||
"randomRogueGroup": true,
|
|
||||||
"randomRogueGroupChance": 50,
|
|
||||||
"mainBossChanceBuff": 50,
|
|
||||||
"bossInvasion": true,
|
|
||||||
"bossInvasionSpawnChance": 10
|
|
||||||
},
|
|
||||||
"main-boss-roaming": {
|
|
||||||
"bossOpenZones": true,
|
|
||||||
"mainBossChanceBuff": 35
|
|
||||||
},
|
|
||||||
"sniper-buddies": {
|
|
||||||
"snipersHaveFriends": true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
{
|
|
||||||
"ADD_THESE_TO_A_MAP_TO_OVERRIDE_OR_ADD_A_BOSS_TO_A_MAP": {
|
|
||||||
"BOSS_NAME_EXAMPLE": "CHANCE_OF_SPAWNING_PERCENT",
|
|
||||||
"sectantPriest": 0,
|
|
||||||
"arenaFighterEvent": 0,
|
|
||||||
"bossBoarSniper": 0,
|
|
||||||
"pmcBot": 0,
|
|
||||||
"bossZryachiy": 0,
|
|
||||||
"exUsec": 0,
|
|
||||||
"crazyAssaultEvent": 0,
|
|
||||||
"peacemaker": 0,
|
|
||||||
"bossKojaniy": 0,
|
|
||||||
"bossGluhar": 0,
|
|
||||||
"bossSanitar": 0,
|
|
||||||
"bossKilla": 0,
|
|
||||||
"bossTagilla": 0,
|
|
||||||
"bossKnight": 0,
|
|
||||||
"bossBoar": 0,
|
|
||||||
"bossKolontay": 0,
|
|
||||||
"bossPartisan": 0,
|
|
||||||
"bossBully": 0
|
|
||||||
},
|
|
||||||
"customs": {
|
|
||||||
"bossKnight": 30,
|
|
||||||
"bossPartisan": 30,
|
|
||||||
"bossBully": 30
|
|
||||||
},
|
|
||||||
"factoryDay": {
|
|
||||||
"bossTagilla": 30
|
|
||||||
},
|
|
||||||
"factoryNight": {
|
|
||||||
"bossTagilla": 30
|
|
||||||
},
|
|
||||||
"interchange": {
|
|
||||||
"bossKilla": 30
|
|
||||||
},
|
|
||||||
"laboratory": {},
|
|
||||||
"lighthouse": {
|
|
||||||
"bossKnight": 30,
|
|
||||||
"bossPartisan": 30
|
|
||||||
},
|
|
||||||
"rezervbase": {
|
|
||||||
"bossGluhar": 30
|
|
||||||
},
|
|
||||||
"shoreline": {
|
|
||||||
"bossKnight": 30,
|
|
||||||
"bossPartisan": 30,
|
|
||||||
"bossSanitar": 30
|
|
||||||
},
|
|
||||||
"tarkovstreets": {
|
|
||||||
"bossBoar": 30,
|
|
||||||
"bossKolontay": 30
|
|
||||||
},
|
|
||||||
"woods": {
|
|
||||||
"bossKojaniy": 30,
|
|
||||||
"bossKnight": 30,
|
|
||||||
"bossPartisan": 30
|
|
||||||
},
|
|
||||||
"gzLow": {},
|
|
||||||
"gzHigh": {
|
|
||||||
"bossKolontay": 30
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
{
|
|
||||||
"enableBotSpawning": true,
|
|
||||||
|
|
||||||
"pmcDifficulty": 0.6,
|
|
||||||
"scavDifficulty": 0.3,
|
|
||||||
|
|
||||||
"scavWaveDistribution": 0.3,
|
|
||||||
"scavWaveQuantity": 0.5,
|
|
||||||
|
|
||||||
"startingPmcs": false,
|
|
||||||
|
|
||||||
"pmcWaveDistribution": 0.8,
|
|
||||||
"pmcWaveQuantity": 1.6,
|
|
||||||
|
|
||||||
"zombiesEnabled": false,
|
|
||||||
"zombieWaveDistribution": 0.5,
|
|
||||||
"zombieWaveQuantity": 1,
|
|
||||||
"zombieHealth": 1,
|
|
||||||
|
|
||||||
"maxBotCap": 25,
|
|
||||||
"maxBotPerZone": 7,
|
|
||||||
|
|
||||||
"moreScavGroups": false,
|
|
||||||
"morePmcGroups": false,
|
|
||||||
"pmcMaxGroupSize": 4,
|
|
||||||
"scavMaxGroupSize": 4,
|
|
||||||
|
|
||||||
"snipersHaveFriends": false,
|
|
||||||
|
|
||||||
"bossOpenZones": false,
|
|
||||||
|
|
||||||
"randomRaiderGroup": false,
|
|
||||||
"randomRaiderGroupChance": 10,
|
|
||||||
|
|
||||||
"randomRogueGroup": false,
|
|
||||||
"randomRogueGroupChance": 10,
|
|
||||||
|
|
||||||
"disableBosses": false,
|
|
||||||
"mainBossChanceBuff": 0,
|
|
||||||
|
|
||||||
"bossInvasion": false,
|
|
||||||
"bossInvasionSpawnChance": 5,
|
|
||||||
"gradualBossInvasion": true,
|
|
||||||
|
|
||||||
"debug": false
|
|
||||||
}
|
|
|
@ -1,149 +0,0 @@
|
||||||
{
|
|
||||||
"customs": {
|
|
||||||
"spawnMinDistance": 30,
|
|
||||||
"pmcWaveCount": 12,
|
|
||||||
"scavWaveCount": 21,
|
|
||||||
"zombieWaveCount": 9,
|
|
||||||
"scavHotZones": [
|
|
||||||
"ZoneDormitory",
|
|
||||||
"ZoneCrossRoad",
|
|
||||||
"ZoneGasStation"
|
|
||||||
],
|
|
||||||
"pmcHotZones": [
|
|
||||||
"ZoneDormitory",
|
|
||||||
"ZoneGasStation",
|
|
||||||
"ZoneCustoms"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"factoryDay": {
|
|
||||||
"spawnMinDistance": 20,
|
|
||||||
"maxBotCapOverride": 12,
|
|
||||||
"maxBotPerZoneOverride": 10,
|
|
||||||
"pmcWaveCount": 8,
|
|
||||||
"scavWaveCount": 9,
|
|
||||||
"zombieWaveCount": 6
|
|
||||||
},
|
|
||||||
"factoryNight": {
|
|
||||||
"spawnMinDistance": 20,
|
|
||||||
"maxBotCapOverride": 12,
|
|
||||||
"maxBotPerZoneOverride": 10,
|
|
||||||
"pmcWaveCount": 8,
|
|
||||||
"scavWaveCount": 9,
|
|
||||||
"zombieWaveCount": 6
|
|
||||||
},
|
|
||||||
"interchange": {
|
|
||||||
"spawnMinDistance": 40,
|
|
||||||
"pmcWaveCount": 14,
|
|
||||||
"scavWaveCount": 32,
|
|
||||||
"zombieWaveCount": 12,
|
|
||||||
"scavHotZones": [
|
|
||||||
"ZoneCenterBot",
|
|
||||||
"ZoneCenter"
|
|
||||||
],
|
|
||||||
"pmcHotZones": [
|
|
||||||
"ZoneIDEA",
|
|
||||||
"ZoneOLI",
|
|
||||||
"ZoneCenter"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"laboratory": {
|
|
||||||
"spawnMinDistance": 20,
|
|
||||||
"pmcWaveCount": 10,
|
|
||||||
"scavWaveCount": 0,
|
|
||||||
"zombieWaveCount": 12
|
|
||||||
},
|
|
||||||
"lighthouse": {
|
|
||||||
"spawnMinDistance": 40,
|
|
||||||
"pmcWaveCount": 12,
|
|
||||||
"scavWaveCount": 20,
|
|
||||||
"zombieWaveCount": 10,
|
|
||||||
"scavHotZones": [
|
|
||||||
"Zone_LongRoad",
|
|
||||||
"Zone_Village"
|
|
||||||
],
|
|
||||||
"pmcHotZones": [
|
|
||||||
"Zone_DestroyedHouse",
|
|
||||||
"Zone_Chalet",
|
|
||||||
"Zone_Village"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"rezervbase": {
|
|
||||||
"spawnMinDistance": 40,
|
|
||||||
"pmcWaveCount": 11,
|
|
||||||
"scavWaveCount": 24,
|
|
||||||
"zombieWaveCount": 9,
|
|
||||||
"scavHotZones": [
|
|
||||||
"ZoneRailStrorage",
|
|
||||||
"ZoneBunkerStorage",
|
|
||||||
"ZoneBarrack"
|
|
||||||
],
|
|
||||||
"pmcHotZones": [
|
|
||||||
"ZoneBarrack",
|
|
||||||
"ZoneBunkerStorage"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"shoreline": {
|
|
||||||
"spawnMinDistance": 40,
|
|
||||||
"pmcWaveCount": 14,
|
|
||||||
"scavWaveCount": 32,
|
|
||||||
"zombieWaveCount": 12,
|
|
||||||
"scavHotZones": [
|
|
||||||
"ZoneSanatorium1",
|
|
||||||
"ZoneGasStation",
|
|
||||||
"ZonePowerStation",
|
|
||||||
"ZoneBusStation",
|
|
||||||
"ZoneStartVillage"
|
|
||||||
],
|
|
||||||
"pmcHotZones": [
|
|
||||||
"ZoneSanatorium2",
|
|
||||||
"ZoneGasStation",
|
|
||||||
"ZonePowerStation"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tarkovstreets": {
|
|
||||||
"spawnMinDistance": 40,
|
|
||||||
"pmcWaveCount": 16,
|
|
||||||
"scavWaveCount": 28,
|
|
||||||
"zombieWaveCount": 13,
|
|
||||||
"scavHotZones": [
|
|
||||||
"ZoneHotel_2",
|
|
||||||
"ZoneHotel_1",
|
|
||||||
"ZoneConstruction",
|
|
||||||
"ZoneCarShowroom"
|
|
||||||
],
|
|
||||||
"pmcHotZones": [
|
|
||||||
"ZoneSanatorium2",
|
|
||||||
"ZoneCinema",
|
|
||||||
"ZoneConcordiaParking"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"woods": {
|
|
||||||
"spawnMinDistance": 40,
|
|
||||||
"pmcWaveCount": 14,
|
|
||||||
"scavWaveCount": 28,
|
|
||||||
"zombieWaveCount": 10,
|
|
||||||
"scavHotZones": [
|
|
||||||
"ZoneWoodCutter",
|
|
||||||
"ZoneClearVill",
|
|
||||||
"ZoneScavBase2",
|
|
||||||
"ZoneRedHouse"
|
|
||||||
],
|
|
||||||
"pmcHotZones": [
|
|
||||||
"ZoneWoodCutter",
|
|
||||||
"ZoneBigRocks",
|
|
||||||
"ZoneHighRocks"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"gzLow": {
|
|
||||||
"spawnMinDistance": 30,
|
|
||||||
"pmcWaveCount": 10,
|
|
||||||
"scavWaveCount": 18,
|
|
||||||
"zombieWaveCount": 9
|
|
||||||
},
|
|
||||||
"gzHigh": {
|
|
||||||
"spawnMinDistance": 30,
|
|
||||||
"pmcWaveCount": 12,
|
|
||||||
"scavWaveCount": 18,
|
|
||||||
"zombieWaveCount": 9
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
"name": "MOAR",
|
|
||||||
"version": "2.6.1",
|
|
||||||
"main": "src/mod.js",
|
|
||||||
"license": "MIT",
|
|
||||||
"author": "DewardianDev",
|
|
||||||
"sptVersion": "^3.10.x",
|
|
||||||
"scripts": {
|
|
||||||
"setup": "npm i",
|
|
||||||
"build": "node ./packageBuild.ts"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@semantic-release/git": "^10.0.1",
|
|
||||||
"@types/node": "16.18.10",
|
|
||||||
"@typescript-eslint/eslint-plugin": "5.46.1",
|
|
||||||
"@typescript-eslint/parser": "5.46.1",
|
|
||||||
"bestzip": "2.2.1",
|
|
||||||
"eslint": "8.30.0",
|
|
||||||
"fs-extra": "11.1.0",
|
|
||||||
"glob": "8.0.3",
|
|
||||||
"semantic-release": "^24.2.0",
|
|
||||||
"tsyringe": "4.7.0",
|
|
||||||
"typescript": "4.9.4"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
import config from "../config/config.json";
|
|
||||||
import { ILocationBase } from "@spt/models/eft/common/ILocationBase";
|
|
||||||
|
|
||||||
export class globalValues {
|
|
||||||
public static baseConfig: typeof config = undefined;
|
|
||||||
public static overrideConfig: Partial<typeof config> = undefined;
|
|
||||||
public static locationsBase: ILocationBase[] = undefined;
|
|
||||||
public static currentPreset: string = "";
|
|
||||||
public static forcedPreset: string = "custom";
|
|
||||||
public static addedMapZones: Record<string, string[]> = {};
|
|
||||||
}
|
|
|
@ -1,168 +0,0 @@
|
||||||
import { DependencyContainer } from "tsyringe";
|
|
||||||
import { buildWaves } from "../Spawning/Spawning";
|
|
||||||
import { StaticRouterModService } from "@spt/services/mod/staticRouter/StaticRouterModService";
|
|
||||||
import { DynamicRouterModService } from "@spt/services/mod/dynamicRouter/DynamicRouterModService";
|
|
||||||
import { globalValues } from "../GlobalValues";
|
|
||||||
import { kebabToTitle } from "../utils";
|
|
||||||
import PresetWeightingsConfig from "../../config/PresetWeightings.json";
|
|
||||||
|
|
||||||
export const setupRoutes = (container: DependencyContainer) => {
|
|
||||||
const staticRouterModService = container.resolve<StaticRouterModService>(
|
|
||||||
"StaticRouterModService"
|
|
||||||
);
|
|
||||||
|
|
||||||
const dynamicRouterModService = container.resolve<DynamicRouterModService>(
|
|
||||||
"DynamicRouterModService"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Make buildwaves run on game end
|
|
||||||
staticRouterModService.registerStaticRouter(
|
|
||||||
`moarUpdater`,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
url: "/client/match/local/end",
|
|
||||||
action: async (_url, info, sessionId, output) => {
|
|
||||||
buildWaves(container);
|
|
||||||
return output;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"moarUpdater"
|
|
||||||
);
|
|
||||||
|
|
||||||
staticRouterModService.registerStaticRouter(
|
|
||||||
`moarGetCurrentPreset`,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
url: "/moar/currentPreset",
|
|
||||||
action: async () => {
|
|
||||||
return globalValues.forcedPreset || "random";
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"moarGetCurrentPreset"
|
|
||||||
);
|
|
||||||
|
|
||||||
staticRouterModService.registerStaticRouter(
|
|
||||||
`moarGetAnnouncePreset`,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
url: "/moar/announcePreset",
|
|
||||||
action: async () => {
|
|
||||||
if (globalValues.forcedPreset?.toLowerCase() === "random") {
|
|
||||||
return globalValues.currentPreset;
|
|
||||||
}
|
|
||||||
return globalValues.forcedPreset || globalValues.currentPreset;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"moarGetAnnouncePreset"
|
|
||||||
);
|
|
||||||
|
|
||||||
staticRouterModService.registerStaticRouter(
|
|
||||||
`getDefaultConfig`,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
url: "/moar/getDefaultConfig",
|
|
||||||
action: async () => {
|
|
||||||
return JSON.stringify(globalValues.baseConfig);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"getDefaultConfig"
|
|
||||||
);
|
|
||||||
|
|
||||||
staticRouterModService.registerStaticRouter(
|
|
||||||
`getServerConfigWithOverrides`,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
url: "/moar/getServerConfigWithOverrides",
|
|
||||||
action: async () => {
|
|
||||||
return JSON.stringify({
|
|
||||||
...(globalValues.baseConfig || {}),
|
|
||||||
...(globalValues.overrideConfig || {}),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"getServerConfigWithOverrides"
|
|
||||||
);
|
|
||||||
|
|
||||||
staticRouterModService.registerStaticRouter(
|
|
||||||
`getServerConfigWithOverrides`,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
url: "/moar/getServerConfigWithOverrides",
|
|
||||||
action: async () => {
|
|
||||||
return JSON.stringify({
|
|
||||||
...globalValues.baseConfig,
|
|
||||||
...globalValues.overrideConfig,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"getServerConfigWithOverrides"
|
|
||||||
);
|
|
||||||
|
|
||||||
staticRouterModService.registerStaticRouter(
|
|
||||||
`moarGetPresetsList`,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
url: "/moar/getPresets",
|
|
||||||
action: async () => {
|
|
||||||
let result = [
|
|
||||||
...Object.keys(PresetWeightingsConfig).map((preset) => ({
|
|
||||||
Name: kebabToTitle(preset),
|
|
||||||
Label: preset,
|
|
||||||
})),
|
|
||||||
{ Name: "Random", Label: "random" },
|
|
||||||
{ Name: "Custom", Label: "custom" },
|
|
||||||
];
|
|
||||||
|
|
||||||
return JSON.stringify({ data: result });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"moarGetPresetsList"
|
|
||||||
);
|
|
||||||
|
|
||||||
staticRouterModService.registerStaticRouter(
|
|
||||||
"setOverrideConfig",
|
|
||||||
[
|
|
||||||
{
|
|
||||||
url: "/moar/setOverrideConfig",
|
|
||||||
action: async (
|
|
||||||
url: string,
|
|
||||||
overrideConfig: typeof globalValues.overrideConfig = {},
|
|
||||||
sessionID,
|
|
||||||
output
|
|
||||||
) => {
|
|
||||||
globalValues.overrideConfig = overrideConfig;
|
|
||||||
|
|
||||||
buildWaves(container);
|
|
||||||
|
|
||||||
return "Success";
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"setOverrideConfig"
|
|
||||||
);
|
|
||||||
|
|
||||||
staticRouterModService.registerStaticRouter(
|
|
||||||
"moarSetPreset",
|
|
||||||
[
|
|
||||||
{
|
|
||||||
url: "/moar/setPreset",
|
|
||||||
action: async (url: string, { Preset }, sessionID, output) => {
|
|
||||||
globalValues.forcedPreset = Preset;
|
|
||||||
buildWaves(container);
|
|
||||||
|
|
||||||
return `Current Preset: ${kebabToTitle(
|
|
||||||
globalValues.forcedPreset || "Random"
|
|
||||||
)}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"moarSetPreset"
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -1,154 +0,0 @@
|
||||||
import { IBotConfig } from "@spt/models/spt/config/IBotConfig.d";
|
|
||||||
import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig.d";
|
|
||||||
import { DatabaseServer } from "@spt/servers/DatabaseServer";
|
|
||||||
import _config from "../../config/config.json";
|
|
||||||
import _mapConfig from "../../config/mapConfig.json";
|
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
|
||||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
|
||||||
import { DependencyContainer } from "tsyringe";
|
|
||||||
import { globalValues } from "../GlobalValues";
|
|
||||||
import { cloneDeep, getRandomPresetOrCurrentlySelectedPreset } from "../utils";
|
|
||||||
import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig.d";
|
|
||||||
import { originalMapList } from "./constants";
|
|
||||||
import { buildBossWaves } from "./buildBossWaves";
|
|
||||||
import buildZombieWaves from "./buildZombieWaves";
|
|
||||||
import buildScavMarksmanWaves from "./buildScavMarksmanWaves";
|
|
||||||
import buildPmcs from "./buildPmcs";
|
|
||||||
import { setEscapeTimeOverrides } from "./utils";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import updateSpawnLocations from "./updateSpawnLocations";
|
|
||||||
|
|
||||||
export const buildWaves = (container: DependencyContainer) => {
|
|
||||||
const configServer = container.resolve<ConfigServer>("ConfigServer");
|
|
||||||
const Logger = container.resolve<ILogger>("WinstonLogger");
|
|
||||||
const pmcConfig = configServer.getConfig<IPmcConfig>(ConfigTypes.PMC);
|
|
||||||
const botConfig = configServer.getConfig<IBotConfig>(ConfigTypes.BOT);
|
|
||||||
|
|
||||||
const locationConfig = configServer.getConfig<ILocationConfig>(
|
|
||||||
ConfigTypes.LOCATION
|
|
||||||
);
|
|
||||||
|
|
||||||
locationConfig.rogueLighthouseSpawnTimeSettings.waitTimeSeconds = 60;
|
|
||||||
locationConfig.enableBotTypeLimits = false;
|
|
||||||
locationConfig.fitLootIntoContainerAttempts = 1; // Move to ALP
|
|
||||||
locationConfig.addCustomBotWavesToMaps = false;
|
|
||||||
locationConfig.customWaves = { boss: {}, normal: {} };
|
|
||||||
|
|
||||||
const databaseServer = container.resolve<DatabaseServer>("DatabaseServer");
|
|
||||||
|
|
||||||
const { locations, bots, globals } = databaseServer.getTables();
|
|
||||||
|
|
||||||
let config = cloneDeep(globalValues.baseConfig) as typeof _config;
|
|
||||||
|
|
||||||
const preset = getRandomPresetOrCurrentlySelectedPreset();
|
|
||||||
|
|
||||||
Object.keys(globalValues.overrideConfig).forEach((key) => {
|
|
||||||
if (config[key] !== globalValues.overrideConfig[key]) {
|
|
||||||
config.debug &&
|
|
||||||
console.log(
|
|
||||||
`[MOAR] overrideConfig ${key} changed from ${config[key]} to ${globalValues.overrideConfig[key]}`
|
|
||||||
);
|
|
||||||
config[key] = globalValues.overrideConfig[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set from preset if preset above is not empty
|
|
||||||
Object.keys(preset).forEach((key) => {
|
|
||||||
if (config[key] !== preset[key]) {
|
|
||||||
config.debug &&
|
|
||||||
console.log(
|
|
||||||
`[MOAR] preset ${globalValues.currentPreset}: ${key} changed from ${config[key]} to ${preset[key]}`
|
|
||||||
);
|
|
||||||
config[key] = preset[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
config.debug &&
|
|
||||||
console.log(
|
|
||||||
globalValues.forcedPreset === "custom"
|
|
||||||
? "custom"
|
|
||||||
: globalValues.currentPreset
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
|
||||||
bigmap: customs,
|
|
||||||
factory4_day: factoryDay,
|
|
||||||
factory4_night: factoryNight,
|
|
||||||
interchange,
|
|
||||||
laboratory,
|
|
||||||
lighthouse,
|
|
||||||
rezervbase,
|
|
||||||
shoreline,
|
|
||||||
tarkovstreets,
|
|
||||||
woods,
|
|
||||||
sandbox: gzLow,
|
|
||||||
sandbox_high: gzHigh,
|
|
||||||
} = locations;
|
|
||||||
|
|
||||||
let locationList = [
|
|
||||||
customs,
|
|
||||||
factoryDay,
|
|
||||||
factoryNight,
|
|
||||||
interchange,
|
|
||||||
laboratory,
|
|
||||||
lighthouse,
|
|
||||||
rezervbase,
|
|
||||||
shoreline,
|
|
||||||
tarkovstreets,
|
|
||||||
woods,
|
|
||||||
gzLow,
|
|
||||||
gzHigh,
|
|
||||||
];
|
|
||||||
|
|
||||||
// This resets all locations to original state
|
|
||||||
if (!globalValues.locationsBase) {
|
|
||||||
globalValues.locationsBase = locationList.map(({ base }) =>
|
|
||||||
cloneDeep(base)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
locationList = locationList.map((item, key) => ({
|
|
||||||
...item,
|
|
||||||
base: cloneDeep(globalValues.locationsBase[key]),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
pmcConfig.convertIntoPmcChance = {
|
|
||||||
default: {
|
|
||||||
assault: { min: 0, max: 0 },
|
|
||||||
cursedassault: { min: 0, max: 0 },
|
|
||||||
pmcbot: { min: 0, max: 0 },
|
|
||||||
exusec: { min: 0, max: 0 },
|
|
||||||
arenafighter: { min: 0, max: 0 },
|
|
||||||
arenafighterevent: { min: 0, max: 0 },
|
|
||||||
crazyassaultevent: { min: 0, max: 0 },
|
|
||||||
},
|
|
||||||
factory4_day: { assault: { min: 0, max: 0 } },
|
|
||||||
laboratory: { pmcbot: { min: 0, max: 0 } },
|
|
||||||
rezervbase: { pmcbot: { min: 0, max: 0 } },
|
|
||||||
};
|
|
||||||
|
|
||||||
updateSpawnLocations(locationList);
|
|
||||||
|
|
||||||
setEscapeTimeOverrides(locationList, _mapConfig, Logger, config);
|
|
||||||
|
|
||||||
// Make main waves
|
|
||||||
buildScavMarksmanWaves(config, locationList, botConfig);
|
|
||||||
|
|
||||||
// BOSS RELATED STUFF!
|
|
||||||
buildBossWaves(config, locationList);
|
|
||||||
|
|
||||||
//Zombies
|
|
||||||
if (config.zombiesEnabled) {
|
|
||||||
buildZombieWaves(config, locationList, bots);
|
|
||||||
}
|
|
||||||
|
|
||||||
buildPmcs(config, locationList);
|
|
||||||
|
|
||||||
originalMapList.forEach((name, index) => {
|
|
||||||
if (!locations[name]) {
|
|
||||||
console.log("[MOAR] OH CRAP we have a problem!", name);
|
|
||||||
} else {
|
|
||||||
locations[name] = locationList[index];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,278 +0,0 @@
|
||||||
import { ILocation } from "@spt/models/eft/common/ILocation";
|
|
||||||
import _config from "../../config/config.json";
|
|
||||||
import bossConfig from "../../config/bossConfig.json";
|
|
||||||
import mapConfig from "../../config/mapConfig.json";
|
|
||||||
import {
|
|
||||||
bossesToRemoveFromPool,
|
|
||||||
configLocations,
|
|
||||||
mainBossNameList,
|
|
||||||
originalMapList,
|
|
||||||
} from "./constants";
|
|
||||||
import { buildBossBasedWave, shuffle } from "./utils";
|
|
||||||
import { IBossLocationSpawn } from "@spt/models/eft/common/ILocationBase";
|
|
||||||
import { cloneDeep } from "../utils";
|
|
||||||
|
|
||||||
export function buildBossWaves(
|
|
||||||
config: typeof _config,
|
|
||||||
locationList: ILocation[]
|
|
||||||
) {
|
|
||||||
let {
|
|
||||||
randomRaiderGroup,
|
|
||||||
randomRaiderGroupChance,
|
|
||||||
randomRogueGroup,
|
|
||||||
randomRogueGroupChance,
|
|
||||||
mainBossChanceBuff,
|
|
||||||
bossInvasion,
|
|
||||||
bossInvasionSpawnChance,
|
|
||||||
disableBosses,
|
|
||||||
bossOpenZones,
|
|
||||||
gradualBossInvasion,
|
|
||||||
} = config;
|
|
||||||
|
|
||||||
const bossList = mainBossNameList.filter(
|
|
||||||
(bossName) => !["bossKnight"].includes(bossName)
|
|
||||||
);
|
|
||||||
|
|
||||||
const allBosses: Record<string, IBossLocationSpawn> = {};
|
|
||||||
for (const key in locationList) {
|
|
||||||
locationList[key].base.BossLocationSpawn.forEach((boss) => {
|
|
||||||
if (!allBosses[boss.BossName]) {
|
|
||||||
allBosses[boss.BossName] = boss;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateBossList
|
|
||||||
const bosses: Record<string, IBossLocationSpawn> = {};
|
|
||||||
for (let indx = 0; indx < locationList.length; indx++) {
|
|
||||||
// Disable Bosses
|
|
||||||
if (disableBosses && !!locationList[indx].base?.BossLocationSpawn) {
|
|
||||||
locationList[indx].base.BossLocationSpawn = [];
|
|
||||||
} else {
|
|
||||||
//Remove all other spawns from pool now that we have the spawns zone list
|
|
||||||
locationList[indx].base.BossLocationSpawn = locationList[
|
|
||||||
indx
|
|
||||||
].base.BossLocationSpawn.filter(
|
|
||||||
(boss) => !bossesToRemoveFromPool.has(boss.BossName)
|
|
||||||
);
|
|
||||||
|
|
||||||
const location = locationList[indx];
|
|
||||||
|
|
||||||
const defaultBossSettings =
|
|
||||||
mapConfig?.[configLocations[indx]]?.defaultBossSettings;
|
|
||||||
|
|
||||||
// Sets bosses spawn chance from settings
|
|
||||||
if (
|
|
||||||
location?.base?.BossLocationSpawn &&
|
|
||||||
defaultBossSettings &&
|
|
||||||
Object.keys(defaultBossSettings)?.length
|
|
||||||
) {
|
|
||||||
const filteredBossList = Object.keys(defaultBossSettings).filter(
|
|
||||||
(name) => defaultBossSettings[name]?.BossChance !== undefined
|
|
||||||
);
|
|
||||||
if (filteredBossList?.length) {
|
|
||||||
filteredBossList.forEach((bossName) => {
|
|
||||||
location.base.BossLocationSpawn =
|
|
||||||
location.base.BossLocationSpawn.map((boss) => ({
|
|
||||||
...boss,
|
|
||||||
...(boss.BossName === bossName
|
|
||||||
? { BossChance: defaultBossSettings[bossName].BossChance }
|
|
||||||
: {}),
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (randomRaiderGroup) {
|
|
||||||
const raiderWave = buildBossBasedWave(
|
|
||||||
randomRaiderGroupChance,
|
|
||||||
"1,2,2,2,3",
|
|
||||||
"pmcBot",
|
|
||||||
"pmcBot",
|
|
||||||
"",
|
|
||||||
locationList[indx].base.EscapeTimeLimit
|
|
||||||
);
|
|
||||||
location.base.BossLocationSpawn.push(raiderWave);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (randomRogueGroup) {
|
|
||||||
const rogueWave = buildBossBasedWave(
|
|
||||||
randomRogueGroupChance,
|
|
||||||
"1,2,2,2,3",
|
|
||||||
"exUsec",
|
|
||||||
"exUsec",
|
|
||||||
"",
|
|
||||||
locationList[indx].base.EscapeTimeLimit
|
|
||||||
);
|
|
||||||
location.base.BossLocationSpawn.push(rogueWave);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add each boss from each map to bosses object
|
|
||||||
const filteredBosses = location.base.BossLocationSpawn?.filter(
|
|
||||||
({ BossName }) => mainBossNameList.includes(BossName)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (filteredBosses.length) {
|
|
||||||
for (let index = 0; index < filteredBosses.length; index++) {
|
|
||||||
const boss = filteredBosses[index];
|
|
||||||
if (
|
|
||||||
!bosses[boss.BossName] ||
|
|
||||||
(bosses[boss.BossName] &&
|
|
||||||
bosses[boss.BossName].BossChance < boss.BossChance)
|
|
||||||
) {
|
|
||||||
bosses[boss.BossName] = { ...boss };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!disableBosses) {
|
|
||||||
// Make boss Invasion
|
|
||||||
if (bossInvasion) {
|
|
||||||
if (bossInvasionSpawnChance) {
|
|
||||||
bossList.forEach((bossName) => {
|
|
||||||
if (bosses[bossName])
|
|
||||||
bosses[bossName].BossChance = bossInvasionSpawnChance;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let key = 0; key < locationList.length; key++) {
|
|
||||||
//Gather bosses to avoid duplicating.
|
|
||||||
let bossLocations = "";
|
|
||||||
|
|
||||||
const duplicateBosses = [
|
|
||||||
...locationList[key].base.BossLocationSpawn.filter(
|
|
||||||
({ BossName, BossZone }) => {
|
|
||||||
bossLocations += BossZone + ",";
|
|
||||||
return bossList.includes(BossName);
|
|
||||||
}
|
|
||||||
).map(({ BossName }) => BossName),
|
|
||||||
"bossKnight", // So knight doesn't invade
|
|
||||||
];
|
|
||||||
|
|
||||||
const uniqueBossZones = bossOpenZones
|
|
||||||
? ""
|
|
||||||
: [
|
|
||||||
...new Set(
|
|
||||||
bossLocations
|
|
||||||
.split(",")
|
|
||||||
.filter(
|
|
||||||
(zone) => !!zone && !zone.toLowerCase().includes("snipe")
|
|
||||||
)
|
|
||||||
),
|
|
||||||
].join(",");
|
|
||||||
|
|
||||||
//Build bosses to add
|
|
||||||
const bossesToAdd = shuffle<IBossLocationSpawn[]>(Object.values(bosses))
|
|
||||||
.filter(({ BossName }) => !duplicateBosses.includes(BossName))
|
|
||||||
.map((boss, j) => ({
|
|
||||||
...boss,
|
|
||||||
BossZone: uniqueBossZones,
|
|
||||||
BossEscortAmount:
|
|
||||||
boss.BossEscortAmount === "0" ? boss.BossEscortAmount : "1",
|
|
||||||
...(gradualBossInvasion ? { Time: j * 20 + 1 } : {}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// UpdateBosses
|
|
||||||
locationList[key].base.BossLocationSpawn = [
|
|
||||||
...locationList[key].base.BossLocationSpawn,
|
|
||||||
...bossesToAdd,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let hasChangedBossSpawns = false;
|
|
||||||
// console.log(Object.keys(allBosses));
|
|
||||||
configLocations.forEach((mapName, index) => {
|
|
||||||
const bossLocationSpawn = locationList[index].base.BossLocationSpawn;
|
|
||||||
const mapBossConfig: Record<string, number> = cloneDeep(
|
|
||||||
bossConfig[mapName] || {}
|
|
||||||
);
|
|
||||||
// if (Object.keys(mapBossConfig).length === 0) console.log(name, "empty");
|
|
||||||
const adjusted = new Set<string>([]);
|
|
||||||
|
|
||||||
bossLocationSpawn.forEach(({ BossName, BossChance }, bossIndex) => {
|
|
||||||
if (typeof mapBossConfig[BossName] === "number") {
|
|
||||||
if (BossChance !== mapBossConfig[BossName]) {
|
|
||||||
if (!hasChangedBossSpawns) {
|
|
||||||
console.log(
|
|
||||||
`\n[MOAR]: --- Adjusting default boss spawn rates --- `
|
|
||||||
);
|
|
||||||
hasChangedBossSpawns = true;
|
|
||||||
}
|
|
||||||
console.log(
|
|
||||||
`[MOAR]: ${mapName} ${BossName}: ${locationList[index].base.BossLocationSpawn[bossIndex].BossChance} => ${mapBossConfig[BossName]}`
|
|
||||||
);
|
|
||||||
locationList[index].base.BossLocationSpawn[bossIndex].BossChance =
|
|
||||||
mapBossConfig[BossName];
|
|
||||||
}
|
|
||||||
adjusted.add(BossName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const bossesToAdd = Object.keys(mapBossConfig)
|
|
||||||
.filter(
|
|
||||||
(adjustName) => !adjusted.has(adjustName) && !!allBosses[adjustName]
|
|
||||||
)
|
|
||||||
.map((bossName) => {
|
|
||||||
`[MOAR]: Adding non-default boss ${bossName} to ${originalMapList[index]}`;
|
|
||||||
|
|
||||||
const newBoss: IBossLocationSpawn = cloneDeep(
|
|
||||||
allBosses[bossName] || {}
|
|
||||||
);
|
|
||||||
newBoss.BossChance = mapBossConfig[bossName];
|
|
||||||
// console.log(
|
|
||||||
// "Adding boss",
|
|
||||||
// bossName,
|
|
||||||
// "to ",
|
|
||||||
// originalMapList[index],
|
|
||||||
// "spawn chance =>",
|
|
||||||
// mapBossConfig[bossName]
|
|
||||||
// );
|
|
||||||
return newBoss;
|
|
||||||
});
|
|
||||||
|
|
||||||
// console.log(bossesToAdd);
|
|
||||||
|
|
||||||
if (bossOpenZones || mainBossChanceBuff) {
|
|
||||||
locationList[index].base?.BossLocationSpawn?.forEach((boss, key) => {
|
|
||||||
if (bossList.includes(boss.BossName)) {
|
|
||||||
if (bossOpenZones) {
|
|
||||||
locationList[index].base.BossLocationSpawn[key] = {
|
|
||||||
...locationList[index].base.BossLocationSpawn[key],
|
|
||||||
BossZone: "",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!!boss.BossChance && mainBossChanceBuff > 0) {
|
|
||||||
locationList[index].base.BossLocationSpawn[key] = {
|
|
||||||
...locationList[index].base.BossLocationSpawn[key],
|
|
||||||
BossChance:
|
|
||||||
boss.BossChance + mainBossChanceBuff > 100
|
|
||||||
? 100
|
|
||||||
: Math.round(boss.BossChance + mainBossChanceBuff),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
locationList[index].base.BossLocationSpawn = [
|
|
||||||
...locationList[index].base.BossLocationSpawn,
|
|
||||||
...bossesToAdd,
|
|
||||||
];
|
|
||||||
|
|
||||||
bossesToAdd.length &&
|
|
||||||
console.log(
|
|
||||||
`[MOAR] Adding the following bosses to map ${
|
|
||||||
configLocations[index]
|
|
||||||
}: ${bossesToAdd.map(({ BossName }) => BossName)}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
if (hasChangedBossSpawns) {
|
|
||||||
console.log(
|
|
||||||
`[MOAR]: --- Adjusting default boss spawn rates complete --- \n`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,87 +0,0 @@
|
||||||
import { ILocation } from "@spt/models/eft/common/ILocation";
|
|
||||||
import _config from "../../config/config.json";
|
|
||||||
import mapConfig from "../../config/mapConfig.json";
|
|
||||||
import {
|
|
||||||
bossesToRemoveFromPool,
|
|
||||||
defaultEscapeTimes,
|
|
||||||
defaultHostility,
|
|
||||||
} from "./constants";
|
|
||||||
import { buildPmcWaves, MapSettings, shuffle } from "./utils";
|
|
||||||
import { saveToFile } from "../utils";
|
|
||||||
|
|
||||||
export default function buildPmcs(
|
|
||||||
config: typeof _config,
|
|
||||||
locationList: ILocation[]
|
|
||||||
) {
|
|
||||||
for (let index = 0; index < locationList.length; index++) {
|
|
||||||
const mapSettingsList = Object.keys(mapConfig) as Array<
|
|
||||||
keyof typeof mapConfig
|
|
||||||
>;
|
|
||||||
const map = mapSettingsList[index];
|
|
||||||
|
|
||||||
locationList[index].base.BotLocationModifier.AdditionalHostilitySettings =
|
|
||||||
defaultHostility;
|
|
||||||
|
|
||||||
const { pmcHotZones = [] } = (mapConfig?.[map] as MapSettings) || {};
|
|
||||||
|
|
||||||
let pmcZones = shuffle<string[]>([
|
|
||||||
...new Set(
|
|
||||||
[...locationList[index].base.SpawnPointParams]
|
|
||||||
.filter(
|
|
||||||
({ Categories, BotZoneName }) =>
|
|
||||||
!!BotZoneName &&
|
|
||||||
(Categories.includes("Player") ||
|
|
||||||
(map === "laboratory" &&
|
|
||||||
!BotZoneName.includes("BotZoneGate"))) &&
|
|
||||||
!BotZoneName.includes("snipe")
|
|
||||||
)
|
|
||||||
.map(({ BotZoneName, ...rest }) => {
|
|
||||||
return BotZoneName;
|
|
||||||
})
|
|
||||||
),
|
|
||||||
...pmcHotZones,
|
|
||||||
]);
|
|
||||||
// Make labs have only named zones
|
|
||||||
if (map === "laboratory") {
|
|
||||||
pmcZones = new Array(10).fill(pmcZones).flat(1);
|
|
||||||
// console.log(pmcZones);
|
|
||||||
}
|
|
||||||
|
|
||||||
const timeLimit = locationList[index].base.EscapeTimeLimit * 60;
|
|
||||||
|
|
||||||
const { pmcWaveCount } = mapConfig[map];
|
|
||||||
|
|
||||||
const escapeTimeLimitRatio = Math.round(
|
|
||||||
locationList[index].base.EscapeTimeLimit / defaultEscapeTimes[map]
|
|
||||||
);
|
|
||||||
|
|
||||||
const totalWaves = Math.round(
|
|
||||||
pmcWaveCount * config.pmcWaveQuantity * escapeTimeLimitRatio
|
|
||||||
);
|
|
||||||
// console.log(pmcZones.length, totalWaves);
|
|
||||||
const numberOfZoneless = totalWaves - pmcZones.length;
|
|
||||||
if (numberOfZoneless > 0) {
|
|
||||||
const addEmpty = new Array(numberOfZoneless).fill("");
|
|
||||||
pmcZones = shuffle<string[]>([...pmcZones, ...addEmpty]);
|
|
||||||
}
|
|
||||||
// if (map === "laboratory") console.log(numberOfZoneless, pmcZones);
|
|
||||||
|
|
||||||
if (config.debug) {
|
|
||||||
console.log(`${map} PMC count ${totalWaves} \n`);
|
|
||||||
|
|
||||||
escapeTimeLimitRatio !== 1 &&
|
|
||||||
console.log(
|
|
||||||
`${map} PMC wave count changed from ${pmcWaveCount} to ${totalWaves} due to escapeTimeLimit adjustment`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const waves = buildPmcWaves(pmcWaveCount, timeLimit, config, pmcZones);
|
|
||||||
// if (map === "laboratory")
|
|
||||||
// console.log(waves.map(({ BossZone }) => BossZone));
|
|
||||||
// apply our new waves
|
|
||||||
locationList[index].base.BossLocationSpawn = [
|
|
||||||
...waves,
|
|
||||||
...locationList[index].base.BossLocationSpawn,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,226 +0,0 @@
|
||||||
import { ILocation } from "@spt/models/eft/common/ILocation";
|
|
||||||
import _config from "../../config/config.json";
|
|
||||||
import mapConfig from "../../config/mapConfig.json";
|
|
||||||
import {
|
|
||||||
configLocations,
|
|
||||||
defaultEscapeTimes,
|
|
||||||
defaultHostility,
|
|
||||||
originalMapList,
|
|
||||||
} from "./constants";
|
|
||||||
import { MapSettings, shuffle, waveBuilder } from "./utils";
|
|
||||||
import { IWave, WildSpawnType } from "@spt/models/eft/common/ILocationBase";
|
|
||||||
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
|
|
||||||
import { saveToFile } from "../utils";
|
|
||||||
|
|
||||||
export default function buildScavMarksmanWaves(
|
|
||||||
config: typeof _config,
|
|
||||||
locationList: ILocation[],
|
|
||||||
botConfig: IBotConfig
|
|
||||||
) {
|
|
||||||
let {
|
|
||||||
debug,
|
|
||||||
maxBotCap,
|
|
||||||
scavWaveQuantity,
|
|
||||||
scavWaveDistribution,
|
|
||||||
snipersHaveFriends,
|
|
||||||
maxBotPerZone,
|
|
||||||
scavMaxGroupSize,
|
|
||||||
scavDifficulty,
|
|
||||||
moreScavGroups,
|
|
||||||
} = config;
|
|
||||||
|
|
||||||
for (let index = 0; index < locationList.length; index++) {
|
|
||||||
const mapSettingsList = Object.keys(mapConfig) as Array<
|
|
||||||
keyof typeof mapConfig
|
|
||||||
>;
|
|
||||||
const map = mapSettingsList[index];
|
|
||||||
|
|
||||||
locationList[index].base = {
|
|
||||||
...locationList[index].base,
|
|
||||||
...{
|
|
||||||
NewSpawn: false,
|
|
||||||
OcculsionCullingEnabled: true,
|
|
||||||
OfflineNewSpawn: false,
|
|
||||||
OfflineOldSpawn: true,
|
|
||||||
OldSpawn: true,
|
|
||||||
BotSpawnCountStep: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
locationList[index].base.NonWaveGroupScenario.Enabled = false;
|
|
||||||
locationList[index].base["BotStartPlayer"] = 0;
|
|
||||||
if (
|
|
||||||
locationList[index].base.BotStop <
|
|
||||||
locationList[index].base.EscapeTimeLimit * 60
|
|
||||||
) {
|
|
||||||
locationList[index].base.BotStop =
|
|
||||||
locationList[index].base.EscapeTimeLimit * 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
maxBotPerZoneOverride,
|
|
||||||
maxBotCapOverride,
|
|
||||||
EscapeTimeLimit,
|
|
||||||
scavHotZones,
|
|
||||||
} = (mapConfig?.[map] as MapSettings) || {};
|
|
||||||
|
|
||||||
// Set per map EscapeTimeLimit
|
|
||||||
if (EscapeTimeLimit) {
|
|
||||||
locationList[index].base.EscapeTimeLimit = EscapeTimeLimit;
|
|
||||||
locationList[index].base.exit_access_time = EscapeTimeLimit + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set default or per map maxBotCap
|
|
||||||
if (maxBotCapOverride || maxBotCap) {
|
|
||||||
const capToSet = maxBotCapOverride || maxBotCap;
|
|
||||||
// console.log(map, capToSet, maxBotCapOverride, maxBotCap);
|
|
||||||
locationList[index].base.BotMax = capToSet;
|
|
||||||
locationList[index].base.BotMaxPvE = capToSet;
|
|
||||||
botConfig.maxBotCap[originalMapList[index]] = capToSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust botZone quantity
|
|
||||||
if (maxBotPerZoneOverride || maxBotPerZone) {
|
|
||||||
const BotPerZone = maxBotPerZoneOverride || maxBotPerZone;
|
|
||||||
// console.log(map, BotPerZone, maxBotPerZoneOverride, maxBotPerZone);
|
|
||||||
locationList[index].base.MaxBotPerZone = BotPerZone;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sniperLocations = new Set(
|
|
||||||
[...locationList[index].base.SpawnPointParams]
|
|
||||||
.filter(
|
|
||||||
({ Categories, Sides, BotZoneName }) =>
|
|
||||||
!!BotZoneName &&
|
|
||||||
Sides.includes("Savage") &&
|
|
||||||
!Categories.includes("Boss")
|
|
||||||
)
|
|
||||||
.filter(
|
|
||||||
({ BotZoneName, DelayToCanSpawnSec }) =>
|
|
||||||
BotZoneName?.toLowerCase().includes("snipe") ||
|
|
||||||
DelayToCanSpawnSec > 300
|
|
||||||
)
|
|
||||||
.map(({ BotZoneName }) => BotZoneName)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (sniperLocations.size) {
|
|
||||||
locationList[index].base.MinMaxBots = [
|
|
||||||
{
|
|
||||||
WildSpawnType: "marksman",
|
|
||||||
max: sniperLocations.size * 5,
|
|
||||||
min: sniperLocations.size,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
const scavZones = shuffle<string[]>([
|
|
||||||
...new Set(
|
|
||||||
[...locationList[index].base.SpawnPointParams]
|
|
||||||
.filter(
|
|
||||||
({ Categories, Sides, BotZoneName }) =>
|
|
||||||
!!BotZoneName &&
|
|
||||||
Sides.includes("Savage") &&
|
|
||||||
!Categories.includes("Boss")
|
|
||||||
)
|
|
||||||
.map(({ BotZoneName }) => BotZoneName)
|
|
||||||
.filter((name) => !sniperLocations.has(name))
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Reduced Zone Delay
|
|
||||||
locationList[index].base.SpawnPointParams = locationList[
|
|
||||||
index
|
|
||||||
].base.SpawnPointParams.map((spawn) => ({
|
|
||||||
...spawn,
|
|
||||||
DelayToCanSpawnSec:
|
|
||||||
spawn.DelayToCanSpawnSec > 20
|
|
||||||
? Math.round(spawn.DelayToCanSpawnSec / 10)
|
|
||||||
: spawn.DelayToCanSpawnSec,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const timeLimit = locationList[index].base.EscapeTimeLimit * 60;
|
|
||||||
const { scavWaveCount } = mapConfig[map];
|
|
||||||
|
|
||||||
const escapeTimeLimitRatio = Math.round(
|
|
||||||
locationList[index].base.EscapeTimeLimit / defaultEscapeTimes[map]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Scavs
|
|
||||||
const scavTotalWaveCount = Math.round(
|
|
||||||
scavWaveCount * scavWaveQuantity * escapeTimeLimitRatio
|
|
||||||
);
|
|
||||||
|
|
||||||
config.debug &&
|
|
||||||
escapeTimeLimitRatio !== 1 &&
|
|
||||||
console.log(
|
|
||||||
`${map} Scav wave count changed from ${scavWaveCount} to ${scavTotalWaveCount} due to escapeTimeLimit adjustment`
|
|
||||||
);
|
|
||||||
|
|
||||||
let snipers = waveBuilder(
|
|
||||||
sniperLocations.size,
|
|
||||||
Math.round(timeLimit / 4),
|
|
||||||
0.5,
|
|
||||||
WildSpawnType.MARKSMAN,
|
|
||||||
0.7,
|
|
||||||
false,
|
|
||||||
2,
|
|
||||||
[],
|
|
||||||
shuffle([...sniperLocations]),
|
|
||||||
80,
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
if (snipersHaveFriends)
|
|
||||||
snipers = snipers.map((wave) => ({
|
|
||||||
...wave,
|
|
||||||
slots_min: 0,
|
|
||||||
...(snipersHaveFriends && wave.slots_max < 2
|
|
||||||
? { slots_min: 1, slots_max: 2 }
|
|
||||||
: {}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const scavWaves = waveBuilder(
|
|
||||||
scavTotalWaveCount,
|
|
||||||
timeLimit,
|
|
||||||
scavWaveDistribution,
|
|
||||||
WildSpawnType.ASSAULT,
|
|
||||||
scavDifficulty,
|
|
||||||
false,
|
|
||||||
scavMaxGroupSize,
|
|
||||||
map === "gzHigh" ? [] : scavZones,
|
|
||||||
scavHotZones,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
!!moreScavGroups
|
|
||||||
);
|
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
let totalscav = 0;
|
|
||||||
scavWaves.forEach(({ slots_max }) => (totalscav += slots_max));
|
|
||||||
|
|
||||||
console.log(configLocations[index]);
|
|
||||||
console.log(
|
|
||||||
"Scavs:",
|
|
||||||
totalscav,
|
|
||||||
"configVal",
|
|
||||||
Math.round((totalscav / scavWaveCount) * 100) / 100,
|
|
||||||
"configWaveCount",
|
|
||||||
scavWaveCount,
|
|
||||||
"waveCount",
|
|
||||||
scavWaves.length,
|
|
||||||
"\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// const finalSniperWaves = snipers?.map(({ ...rest }, snipKey) => ({
|
|
||||||
// ...rest,
|
|
||||||
// number: snipKey,
|
|
||||||
// time_min: snipKey * 120,
|
|
||||||
// time_max: snipKey * 120 + 120,
|
|
||||||
// }));
|
|
||||||
// if (map === "customs") saveToFile({ scavWaves }, "scavWaves.json");
|
|
||||||
locationList[index].base.waves = [...snipers, ...scavWaves]
|
|
||||||
.sort(({ time_min: a }, { time_min: b }) => a - b)
|
|
||||||
.map((wave, i) => ({ ...wave, number: i + 1 }));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
import { ILocation } from "@spt/models/eft/common/ILocation";
|
|
||||||
import _config from "../../config/config.json";
|
|
||||||
import mapConfig from "../../config/mapConfig.json";
|
|
||||||
import { configLocations, defaultEscapeTimes } from "./constants";
|
|
||||||
import {
|
|
||||||
buildZombie,
|
|
||||||
getHealthBodyPartsByPercentage,
|
|
||||||
zombieTypes,
|
|
||||||
} from "./utils";
|
|
||||||
import { IBots } from "@spt/models/spt/bots/IBots";
|
|
||||||
|
|
||||||
export default function buildZombieWaves(
|
|
||||||
config: typeof _config,
|
|
||||||
locationList: ILocation[],
|
|
||||||
bots: IBots
|
|
||||||
) {
|
|
||||||
let { debug, zombieWaveDistribution, zombieWaveQuantity, zombieHealth } =
|
|
||||||
config;
|
|
||||||
|
|
||||||
const zombieBodyParts = getHealthBodyPartsByPercentage(zombieHealth);
|
|
||||||
zombieTypes.forEach((type) => {
|
|
||||||
bots.types?.[type]?.health?.BodyParts?.forEach((_, index) => {
|
|
||||||
bots.types[type].health.BodyParts[index] = zombieBodyParts;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let indx = 0; indx < locationList.length; indx++) {
|
|
||||||
const location = locationList[indx].base;
|
|
||||||
const mapSettingsList = Object.keys(mapConfig) as Array<
|
|
||||||
keyof typeof mapConfig
|
|
||||||
>;
|
|
||||||
const map = mapSettingsList[indx];
|
|
||||||
|
|
||||||
const { zombieWaveCount } = mapConfig?.[configLocations[indx]];
|
|
||||||
|
|
||||||
// if (location.Events?.Halloween2024?.MaxCrowdAttackSpawnLimit)
|
|
||||||
// location.Events.Halloween2024.MaxCrowdAttackSpawnLimit = 100;
|
|
||||||
// if (location.Events?.Halloween2024?.CrowdCooldownPerPlayerSec)
|
|
||||||
// location.Events.Halloween2024.CrowdCooldownPerPlayerSec = 60;
|
|
||||||
// if (location.Events?.Halloween2024?.CrowdCooldownPerPlayerSec)
|
|
||||||
// location.Events.Halloween2024.CrowdsLimit = 10;
|
|
||||||
// if (location.Events?.Halloween2024?.CrowdAttackSpawnParams)
|
|
||||||
// location.Events.Halloween2024.CrowdAttackSpawnParams = [];
|
|
||||||
|
|
||||||
if (!zombieWaveCount) return;
|
|
||||||
|
|
||||||
const escapeTimeLimitRatio = Math.round(
|
|
||||||
locationList[indx].base.EscapeTimeLimit / defaultEscapeTimes[map]
|
|
||||||
);
|
|
||||||
|
|
||||||
const zombieTotalWaveCount = Math.round(
|
|
||||||
zombieWaveCount * zombieWaveQuantity * escapeTimeLimitRatio
|
|
||||||
);
|
|
||||||
|
|
||||||
config.debug &&
|
|
||||||
escapeTimeLimitRatio !== 1 &&
|
|
||||||
console.log(
|
|
||||||
`${map} Zombie wave count changed from ${zombieWaveCount} to ${zombieTotalWaveCount} due to escapeTimeLimit adjustment`
|
|
||||||
);
|
|
||||||
|
|
||||||
const zombieWaves = buildZombie(
|
|
||||||
zombieTotalWaveCount,
|
|
||||||
location.EscapeTimeLimit,
|
|
||||||
zombieWaveDistribution,
|
|
||||||
9999
|
|
||||||
);
|
|
||||||
|
|
||||||
debug &&
|
|
||||||
console.log(
|
|
||||||
configLocations[indx],
|
|
||||||
" generated ",
|
|
||||||
zombieWaves.length,
|
|
||||||
"Zombies"
|
|
||||||
);
|
|
||||||
|
|
||||||
location.BossLocationSpawn.push(...zombieWaves);
|
|
||||||
|
|
||||||
// console.log(zombieWaves[0], zombieWaves[7]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,204 +0,0 @@
|
||||||
export const defaultHostility = [
|
|
||||||
{
|
|
||||||
AlwaysEnemies: [
|
|
||||||
"bossTest",
|
|
||||||
"followerTest",
|
|
||||||
"bossKilla",
|
|
||||||
"bossKojaniy",
|
|
||||||
"followerKojaniy",
|
|
||||||
"cursedAssault",
|
|
||||||
"bossGluhar",
|
|
||||||
"followerGluharAssault",
|
|
||||||
"followerGluharSecurity",
|
|
||||||
"followerGluharScout",
|
|
||||||
"followerGluharSnipe",
|
|
||||||
"followerSanitar",
|
|
||||||
"bossSanitar",
|
|
||||||
"test",
|
|
||||||
"assaultGroup",
|
|
||||||
"sectantWarrior",
|
|
||||||
"sectantPriest",
|
|
||||||
"bossTagilla",
|
|
||||||
"followerTagilla",
|
|
||||||
"bossKnight",
|
|
||||||
"followerBigPipe",
|
|
||||||
"followerBirdEye",
|
|
||||||
"bossBoar",
|
|
||||||
"followerBoar",
|
|
||||||
"arenaFighter",
|
|
||||||
"arenaFighterEvent",
|
|
||||||
"bossBoarSniper",
|
|
||||||
"crazyAssaultEvent",
|
|
||||||
"sectactPriestEvent",
|
|
||||||
"followerBoarClose1",
|
|
||||||
"followerBoarClose2",
|
|
||||||
"bossKolontay",
|
|
||||||
"followerKolontayAssault",
|
|
||||||
"followerKolontaySecurity",
|
|
||||||
"shooterBTR",
|
|
||||||
"bossPartisan",
|
|
||||||
"spiritWinter",
|
|
||||||
"spiritSpring",
|
|
||||||
"peacemaker",
|
|
||||||
"skier",
|
|
||||||
"assault",
|
|
||||||
"marksman",
|
|
||||||
"pmcUSEC",
|
|
||||||
"pmcBEAR",
|
|
||||||
"exUsec",
|
|
||||||
"pmcBot",
|
|
||||||
"bossBully",
|
|
||||||
],
|
|
||||||
AlwaysFriends: [
|
|
||||||
"bossZryachiy",
|
|
||||||
"followerZryachiy",
|
|
||||||
"peacefullZryachiyEvent",
|
|
||||||
"ravangeZryachiyEvent",
|
|
||||||
"gifter",
|
|
||||||
],
|
|
||||||
BearEnemyChance: 100,
|
|
||||||
BearPlayerBehaviour: "AlwaysEnemies",
|
|
||||||
BotRole: "pmcBEAR",
|
|
||||||
ChancedEnemies: [],
|
|
||||||
Neutral: [],
|
|
||||||
SavagePlayerBehaviour: "AlwaysEnemies",
|
|
||||||
UsecEnemyChance: 100,
|
|
||||||
UsecPlayerBehaviour: "AlwaysEnemies",
|
|
||||||
Warn: ["sectactPriestEvent"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
AlwaysEnemies: [
|
|
||||||
"bossTest",
|
|
||||||
"followerTest",
|
|
||||||
"bossKilla",
|
|
||||||
"bossKojaniy",
|
|
||||||
"followerKojaniy",
|
|
||||||
"cursedAssault",
|
|
||||||
"bossGluhar",
|
|
||||||
"followerGluharAssault",
|
|
||||||
"followerGluharSecurity",
|
|
||||||
"followerGluharScout",
|
|
||||||
"followerGluharSnipe",
|
|
||||||
"followerSanitar",
|
|
||||||
"bossSanitar",
|
|
||||||
"test",
|
|
||||||
"assaultGroup",
|
|
||||||
"sectantWarrior",
|
|
||||||
"sectantPriest",
|
|
||||||
"bossTagilla",
|
|
||||||
"followerTagilla",
|
|
||||||
"bossKnight",
|
|
||||||
"followerBigPipe",
|
|
||||||
"followerBirdEye",
|
|
||||||
"bossBoar",
|
|
||||||
"followerBoar",
|
|
||||||
"arenaFighter",
|
|
||||||
"arenaFighterEvent",
|
|
||||||
"bossBoarSniper",
|
|
||||||
"crazyAssaultEvent",
|
|
||||||
"sectactPriestEvent",
|
|
||||||
"followerBoarClose1",
|
|
||||||
"followerBoarClose2",
|
|
||||||
"bossKolontay",
|
|
||||||
"followerKolontayAssault",
|
|
||||||
"followerKolontaySecurity",
|
|
||||||
"shooterBTR",
|
|
||||||
"bossPartisan",
|
|
||||||
"spiritWinter",
|
|
||||||
"spiritSpring",
|
|
||||||
"peacemaker",
|
|
||||||
"skier",
|
|
||||||
"assault",
|
|
||||||
"marksman",
|
|
||||||
"pmcUSEC",
|
|
||||||
"pmcBEAR",
|
|
||||||
"exUsec",
|
|
||||||
"pmcBot",
|
|
||||||
"bossBully",
|
|
||||||
],
|
|
||||||
AlwaysFriends: [
|
|
||||||
"bossZryachiy",
|
|
||||||
"followerZryachiy",
|
|
||||||
"peacefullZryachiyEvent",
|
|
||||||
"ravangeZryachiyEvent",
|
|
||||||
"gifter",
|
|
||||||
],
|
|
||||||
BearEnemyChance: 100,
|
|
||||||
BearPlayerBehaviour: "AlwaysEnemies",
|
|
||||||
BotRole: "pmcUSEC",
|
|
||||||
ChancedEnemies: [],
|
|
||||||
Neutral: [],
|
|
||||||
SavagePlayerBehaviour: "AlwaysEnemies",
|
|
||||||
UsecEnemyChance: 100,
|
|
||||||
UsecPlayerBehaviour: "AlwaysEnemies",
|
|
||||||
Warn: ["sectactPriestEvent"],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const configLocations = [
|
|
||||||
"customs",
|
|
||||||
"factoryDay",
|
|
||||||
"factoryNight",
|
|
||||||
"interchange",
|
|
||||||
"laboratory",
|
|
||||||
"lighthouse",
|
|
||||||
"rezervbase",
|
|
||||||
"shoreline",
|
|
||||||
"tarkovstreets",
|
|
||||||
"woods",
|
|
||||||
"gzLow",
|
|
||||||
"gzHigh",
|
|
||||||
];
|
|
||||||
|
|
||||||
export const originalMapList = [
|
|
||||||
"bigmap",
|
|
||||||
"factory4_day",
|
|
||||||
"factory4_night",
|
|
||||||
"interchange",
|
|
||||||
"laboratory",
|
|
||||||
"lighthouse",
|
|
||||||
"rezervbase",
|
|
||||||
"shoreline",
|
|
||||||
"tarkovstreets",
|
|
||||||
"woods",
|
|
||||||
"sandbox",
|
|
||||||
"sandbox_high",
|
|
||||||
];
|
|
||||||
|
|
||||||
export const bossesToRemoveFromPool = new Set([
|
|
||||||
"assault",
|
|
||||||
"pmcBEAR",
|
|
||||||
"pmcUSEC",
|
|
||||||
"infectedAssault",
|
|
||||||
"infectedTagilla",
|
|
||||||
"infectedLaborant",
|
|
||||||
"infectedCivil",
|
|
||||||
]);
|
|
||||||
|
|
||||||
export const mainBossNameList = [
|
|
||||||
"bossKojaniy",
|
|
||||||
"bossGluhar",
|
|
||||||
"bossSanitar",
|
|
||||||
"bossKilla",
|
|
||||||
"bossTagilla",
|
|
||||||
"bossKnight",
|
|
||||||
"bossBoar",
|
|
||||||
"bossKolontay",
|
|
||||||
"bossPartisan",
|
|
||||||
"bossBully",
|
|
||||||
];
|
|
||||||
|
|
||||||
export const defaultEscapeTimes = {
|
|
||||||
customs: 40,
|
|
||||||
factoryDay: 20,
|
|
||||||
factoryNight: 25,
|
|
||||||
interchange: 40,
|
|
||||||
laboratory: 35,
|
|
||||||
lighthouse: 40,
|
|
||||||
rezervbase: 40,
|
|
||||||
shoreline: 45,
|
|
||||||
tarkovstreets: 50,
|
|
||||||
woods: 40,
|
|
||||||
gzLow: 35,
|
|
||||||
gzHigh: 35,
|
|
||||||
};
|
|
|
@ -1,38 +0,0 @@
|
||||||
import { ILocation } from "@spt/models/eft/common/ILocation";
|
|
||||||
import { configLocations } from "./constants";
|
|
||||||
import mapConfig from "../../config/mapConfig.json";
|
|
||||||
|
|
||||||
export default function updateSpawnLocations(locationList: ILocation[]) {
|
|
||||||
for (let index = 0; index < locationList.length; index++) {
|
|
||||||
const map = configLocations[index];
|
|
||||||
|
|
||||||
const limit = mapConfig[map].spawnMinDistance;
|
|
||||||
|
|
||||||
// console.log("\n" + map);
|
|
||||||
locationList[index].base.SpawnPointParams.forEach(
|
|
||||||
(
|
|
||||||
{ ColliderParams, BotZoneName, DelayToCanSpawnSec, Categories, Sides },
|
|
||||||
innerIndex
|
|
||||||
) => {
|
|
||||||
if (
|
|
||||||
ColliderParams?._props?.Radius !== undefined &&
|
|
||||||
ColliderParams?._props?.Radius < limit &&
|
|
||||||
!BotZoneName?.toLowerCase().includes("snipe") &&
|
|
||||||
DelayToCanSpawnSec < 300
|
|
||||||
) {
|
|
||||||
// console.log(
|
|
||||||
// "----",
|
|
||||||
// ColliderParams._props.Radius,
|
|
||||||
// "=>",
|
|
||||||
// limit,
|
|
||||||
// BotZoneName
|
|
||||||
// );
|
|
||||||
|
|
||||||
locationList[index].base.SpawnPointParams[
|
|
||||||
innerIndex
|
|
||||||
].ColliderParams._props.Radius = limit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,430 +0,0 @@
|
||||||
import {
|
|
||||||
IBossLocationSpawn,
|
|
||||||
IWave,
|
|
||||||
WildSpawnType,
|
|
||||||
} from "@spt/models/eft/common/ILocationBase";
|
|
||||||
import _config from "../../config/config.json";
|
|
||||||
import { ILocation } from "@spt/models/eft/common/ILocation";
|
|
||||||
import { defaultEscapeTimes } from "./constants";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
|
|
||||||
export const waveBuilder = (
|
|
||||||
totalWaves: number,
|
|
||||||
timeLimit: number,
|
|
||||||
waveDistribution: number,
|
|
||||||
wildSpawnType: "marksman" | "assault",
|
|
||||||
difficulty: number,
|
|
||||||
isPlayer: boolean,
|
|
||||||
maxSlots: number,
|
|
||||||
combinedZones: string[] = [],
|
|
||||||
specialZones: string[] = [],
|
|
||||||
offset?: number,
|
|
||||||
starting?: boolean,
|
|
||||||
moreGroups?: boolean
|
|
||||||
): IWave[] => {
|
|
||||||
if (totalWaves === 0) return [];
|
|
||||||
|
|
||||||
const averageTime = timeLimit / totalWaves;
|
|
||||||
const firstHalf = Math.round(averageTime * (1 - waveDistribution));
|
|
||||||
const secondHalf = Math.round(averageTime * (1 + waveDistribution));
|
|
||||||
let timeStart = offset || 0;
|
|
||||||
const waves: IWave[] = [];
|
|
||||||
let maxSlotsReached = Math.round(1.3 * totalWaves);
|
|
||||||
while (
|
|
||||||
totalWaves > 0 &&
|
|
||||||
(waves.length < totalWaves || specialZones.length > 0)
|
|
||||||
) {
|
|
||||||
const accelerate = totalWaves > 5 && waves.length < totalWaves / 3;
|
|
||||||
const stage = Math.round(
|
|
||||||
waves.length < Math.round(totalWaves * 0.5)
|
|
||||||
? accelerate
|
|
||||||
? firstHalf / 3
|
|
||||||
: firstHalf
|
|
||||||
: secondHalf
|
|
||||||
);
|
|
||||||
|
|
||||||
const min = !offset && waves.length < 1 ? 0 : timeStart;
|
|
||||||
const max = !offset && waves.length < 1 ? 0 : timeStart + 10;
|
|
||||||
|
|
||||||
if (waves.length >= 1 || offset) timeStart = timeStart + stage;
|
|
||||||
const BotPreset = getDifficulty(difficulty);
|
|
||||||
// console.log(wildSpawnType, BotPreset);
|
|
||||||
// Math.round((1 - waves.length / totalWaves) * maxSlots) || 1;
|
|
||||||
let slotMax = Math.round(
|
|
||||||
(moreGroups ? Math.random() : Math.random() * Math.random()) * maxSlots
|
|
||||||
);
|
|
||||||
|
|
||||||
if (slotMax < 1) slotMax = 1;
|
|
||||||
const slotMin = (Math.round(Math.random() * slotMax) || 1) - 1;
|
|
||||||
|
|
||||||
waves.push({
|
|
||||||
BotPreset,
|
|
||||||
BotSide: getBotSide(wildSpawnType),
|
|
||||||
SpawnPoints: getZone(
|
|
||||||
specialZones,
|
|
||||||
combinedZones,
|
|
||||||
waves.length >= totalWaves
|
|
||||||
),
|
|
||||||
isPlayers: isPlayer,
|
|
||||||
slots_max: slotMax,
|
|
||||||
slots_min: slotMin,
|
|
||||||
time_min: starting || !max ? -1 : min,
|
|
||||||
time_max: starting || !max ? -1 : max,
|
|
||||||
WildSpawnType: wildSpawnType as WildSpawnType,
|
|
||||||
number: waves.length,
|
|
||||||
sptId: wildSpawnType + waves.length,
|
|
||||||
SpawnMode: ["regular", "pve"],
|
|
||||||
});
|
|
||||||
maxSlotsReached -= slotMax;
|
|
||||||
// if (wildSpawnType === "assault") console.log(slotMax, maxSlotsReached);
|
|
||||||
if (maxSlotsReached <= 0) break;
|
|
||||||
}
|
|
||||||
// console.log(waves.map(({ slots_min }) => slots_min));
|
|
||||||
return waves;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getZone = (specialZones, combinedZones, specialOnly) => {
|
|
||||||
if (!specialOnly && combinedZones.length)
|
|
||||||
return combinedZones[
|
|
||||||
Math.round((combinedZones.length - 1) * Math.random())
|
|
||||||
];
|
|
||||||
if (specialZones.length) return specialZones.pop();
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getDifficulty = (diff: number) => {
|
|
||||||
const randomNumb = Math.random() + diff;
|
|
||||||
switch (true) {
|
|
||||||
case randomNumb < 0.55:
|
|
||||||
return "easy";
|
|
||||||
case randomNumb < 1.4:
|
|
||||||
return "normal";
|
|
||||||
case randomNumb < 1.85:
|
|
||||||
return "hard";
|
|
||||||
default:
|
|
||||||
return "impossible";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const shuffle = <n>(array: any): n => {
|
|
||||||
let currentIndex = array.length,
|
|
||||||
randomIndex;
|
|
||||||
|
|
||||||
// While there remain elements to shuffle.
|
|
||||||
while (currentIndex != 0) {
|
|
||||||
// Pick a remaining element.
|
|
||||||
randomIndex = Math.floor(Math.random() * currentIndex);
|
|
||||||
currentIndex--;
|
|
||||||
|
|
||||||
// And swap it with the current element.
|
|
||||||
[array[currentIndex], array[randomIndex]] = [
|
|
||||||
array[randomIndex],
|
|
||||||
array[currentIndex],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return array;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getBotSide = (
|
|
||||||
spawnType: "marksman" | "assault" | "pmcBEAR" | "pmcUSEC"
|
|
||||||
) => {
|
|
||||||
switch (spawnType) {
|
|
||||||
case "pmcBEAR":
|
|
||||||
return "Bear";
|
|
||||||
case "pmcUSEC":
|
|
||||||
return "Usec";
|
|
||||||
default:
|
|
||||||
return "Savage";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const buildBossBasedWave = (
|
|
||||||
BossChance: number,
|
|
||||||
BossEscortAmount: string,
|
|
||||||
BossEscortType: string,
|
|
||||||
BossName: string,
|
|
||||||
BossZone: string,
|
|
||||||
raidTime?: number
|
|
||||||
): IBossLocationSpawn => {
|
|
||||||
return {
|
|
||||||
BossChance,
|
|
||||||
BossDifficult: "normal",
|
|
||||||
BossEscortAmount,
|
|
||||||
BossEscortDifficult: "normal",
|
|
||||||
BossEscortType,
|
|
||||||
BossName,
|
|
||||||
BossPlayer: false,
|
|
||||||
BossZone,
|
|
||||||
Delay: 0,
|
|
||||||
ForceSpawn: false,
|
|
||||||
IgnoreMaxBots: true,
|
|
||||||
RandomTimeSpawn: false,
|
|
||||||
Time: raidTime ? Math.round(Math.random() * (raidTime * 5)) : -1,
|
|
||||||
Supports: null,
|
|
||||||
TriggerId: "",
|
|
||||||
TriggerName: "",
|
|
||||||
spawnMode: ["regular", "pve"],
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const zombieTypes = [
|
|
||||||
"infectedassault",
|
|
||||||
"infectedpmc",
|
|
||||||
"infectedlaborant",
|
|
||||||
"infectedcivil",
|
|
||||||
];
|
|
||||||
|
|
||||||
export const zombieTypesCaps = [
|
|
||||||
"infectedAssault",
|
|
||||||
"infectedPmc",
|
|
||||||
"infectedLaborant",
|
|
||||||
"infectedCivil",
|
|
||||||
];
|
|
||||||
|
|
||||||
export const getRandomDifficulty = (num: number = 1.5) =>
|
|
||||||
getDifficulty(Math.round(Math.random() * num * 10) / 10);
|
|
||||||
|
|
||||||
export const getRandomZombieType = () =>
|
|
||||||
zombieTypesCaps[Math.round((zombieTypesCaps.length - 1) * Math.random())];
|
|
||||||
|
|
||||||
export const buildPmcWaves = (
|
|
||||||
totalWaves: number,
|
|
||||||
escapeTimeLimit: number,
|
|
||||||
config: typeof _config,
|
|
||||||
bossZones: string[]
|
|
||||||
): IBossLocationSpawn[] => {
|
|
||||||
let {
|
|
||||||
pmcMaxGroupSize,
|
|
||||||
pmcDifficulty,
|
|
||||||
startingPmcs,
|
|
||||||
morePmcGroups,
|
|
||||||
pmcWaveDistribution,
|
|
||||||
} = config;
|
|
||||||
|
|
||||||
const averageTime = escapeTimeLimit / totalWaves;
|
|
||||||
const firstHalf = Math.round(averageTime * (1 - pmcWaveDistribution));
|
|
||||||
const secondHalf = Math.round(averageTime * (1 + pmcWaveDistribution));
|
|
||||||
let timeStart = -1;
|
|
||||||
const waves: IBossLocationSpawn[] = [];
|
|
||||||
let maxSlotsReached = totalWaves;
|
|
||||||
|
|
||||||
while (totalWaves > 0) {
|
|
||||||
let bossEscortAmount = Math.round(
|
|
||||||
(morePmcGroups ? 1 : Math.random()) *
|
|
||||||
Math.random() *
|
|
||||||
(pmcMaxGroupSize - 1)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (bossEscortAmount < 0) bossEscortAmount = 0;
|
|
||||||
const accelerate = totalWaves > 5 && waves.length < totalWaves / 3;
|
|
||||||
const stage = startingPmcs
|
|
||||||
? 10
|
|
||||||
: Math.round(
|
|
||||||
waves.length < Math.round(totalWaves * 0.5)
|
|
||||||
? accelerate
|
|
||||||
? firstHalf / 3
|
|
||||||
: firstHalf
|
|
||||||
: secondHalf
|
|
||||||
);
|
|
||||||
|
|
||||||
if (waves.length >= 1) timeStart = timeStart + stage;
|
|
||||||
|
|
||||||
// console.log(timeStart, BossEscortAmount);
|
|
||||||
const side = Math.random() > 0.5 ? "pmcBEAR" : "pmcUSEC";
|
|
||||||
|
|
||||||
const BossDifficult = getDifficulty(pmcDifficulty);
|
|
||||||
|
|
||||||
waves.push({
|
|
||||||
BossChance: 9999,
|
|
||||||
BossDifficult,
|
|
||||||
BossEscortAmount: bossEscortAmount.toString(),
|
|
||||||
BossEscortDifficult: "normal",
|
|
||||||
BossEscortType: side,
|
|
||||||
BossName: side,
|
|
||||||
BossPlayer: false,
|
|
||||||
BossZone: bossZones.pop() || "",
|
|
||||||
Delay: 0,
|
|
||||||
DependKarma: false,
|
|
||||||
DependKarmaPVE: false,
|
|
||||||
ForceSpawn: true,
|
|
||||||
IgnoreMaxBots: true,
|
|
||||||
RandomTimeSpawn: false,
|
|
||||||
Time: timeStart,
|
|
||||||
Supports: null,
|
|
||||||
TriggerId: "",
|
|
||||||
TriggerName: "",
|
|
||||||
spawnMode: ["regular", "pve"],
|
|
||||||
});
|
|
||||||
|
|
||||||
maxSlotsReached -= 1 + bossEscortAmount;
|
|
||||||
if (maxSlotsReached <= 0) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return waves;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const buildZombie = (
|
|
||||||
totalWaves: number,
|
|
||||||
escapeTimeLimit: number,
|
|
||||||
waveDistribution: number,
|
|
||||||
BossChance: number = 100
|
|
||||||
): IBossLocationSpawn[] => {
|
|
||||||
const averageTime = (escapeTimeLimit * 60) / totalWaves;
|
|
||||||
const firstHalf = Math.round(averageTime * (1 - waveDistribution));
|
|
||||||
const secondHalf = Math.round(averageTime * (1 + waveDistribution));
|
|
||||||
let timeStart = 90;
|
|
||||||
const waves: IBossLocationSpawn[] = [];
|
|
||||||
let maxSlotsReached = Math.round(1.3 * totalWaves);
|
|
||||||
|
|
||||||
while (totalWaves > 0) {
|
|
||||||
const accelerate = totalWaves > 5 && waves.length < totalWaves / 3;
|
|
||||||
const stage = Math.round(
|
|
||||||
waves.length < Math.round(totalWaves * 0.5)
|
|
||||||
? accelerate
|
|
||||||
? firstHalf / 3
|
|
||||||
: firstHalf
|
|
||||||
: secondHalf
|
|
||||||
);
|
|
||||||
|
|
||||||
if (waves.length >= 1) timeStart = timeStart + stage;
|
|
||||||
const main = getRandomZombieType();
|
|
||||||
waves.push({
|
|
||||||
BossChance,
|
|
||||||
BossDifficult: "normal",
|
|
||||||
BossEscortAmount: "0",
|
|
||||||
BossEscortDifficult: "normal",
|
|
||||||
BossEscortType: main,
|
|
||||||
BossName: main,
|
|
||||||
BossPlayer: false,
|
|
||||||
BossZone: "",
|
|
||||||
Delay: 0,
|
|
||||||
IgnoreMaxBots: true,
|
|
||||||
RandomTimeSpawn: false,
|
|
||||||
Time: timeStart,
|
|
||||||
Supports: new Array(
|
|
||||||
Math.round(Math.random() * 4) /* <= 4 AddthistoConfig */
|
|
||||||
)
|
|
||||||
.fill("")
|
|
||||||
.map(() => ({
|
|
||||||
BossEscortType: getRandomZombieType(),
|
|
||||||
BossEscortDifficult: ["normal"],
|
|
||||||
BossEscortAmount: "1",
|
|
||||||
})),
|
|
||||||
TriggerId: "",
|
|
||||||
TriggerName: "",
|
|
||||||
spawnMode: ["regular", "pve"],
|
|
||||||
});
|
|
||||||
|
|
||||||
maxSlotsReached -= 1 + waves[waves.length - 1].Supports.length;
|
|
||||||
if (maxSlotsReached <= 0) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return waves;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface MapSettings {
|
|
||||||
EscapeTimeLimit?: number;
|
|
||||||
maxBotPerZoneOverride?: number;
|
|
||||||
maxBotCapOverride?: number;
|
|
||||||
pmcHotZones?: string[];
|
|
||||||
scavHotZones?: string[];
|
|
||||||
pmcWaveCount: number;
|
|
||||||
scavWaveCount: number;
|
|
||||||
zombieWaveCount: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getHealthBodyPartsByPercentage = (num: number) => {
|
|
||||||
const num35 = Math.round(35 * num);
|
|
||||||
const num100 = Math.round(100 * num);
|
|
||||||
const num70 = Math.round(70 * num);
|
|
||||||
const num80 = Math.round(80 * num);
|
|
||||||
return {
|
|
||||||
Head: {
|
|
||||||
min: num35,
|
|
||||||
max: num35,
|
|
||||||
},
|
|
||||||
Chest: {
|
|
||||||
min: num100,
|
|
||||||
max: num100,
|
|
||||||
},
|
|
||||||
Stomach: {
|
|
||||||
min: num100,
|
|
||||||
max: num100,
|
|
||||||
},
|
|
||||||
LeftArm: {
|
|
||||||
min: num70,
|
|
||||||
max: num70,
|
|
||||||
},
|
|
||||||
RightArm: {
|
|
||||||
min: num70,
|
|
||||||
max: num70,
|
|
||||||
},
|
|
||||||
LeftLeg: {
|
|
||||||
min: num80,
|
|
||||||
max: num80,
|
|
||||||
},
|
|
||||||
RightLeg: {
|
|
||||||
min: num80,
|
|
||||||
max: num80,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface MapConfigType {
|
|
||||||
spawnMinDistance: number;
|
|
||||||
pmcWaveCount: number;
|
|
||||||
scavWaveCount: number;
|
|
||||||
zombieWaveCount?: number;
|
|
||||||
scavHotZones?: string[];
|
|
||||||
pmcHotZones?: string[];
|
|
||||||
EscapeTimeLimitOverride?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const setEscapeTimeOverrides = (
|
|
||||||
locationList: ILocation[],
|
|
||||||
mapConfig: Record<string, MapConfigType>,
|
|
||||||
logger: ILogger,
|
|
||||||
config: typeof _config
|
|
||||||
) => {
|
|
||||||
for (let index = 0; index < locationList.length; index++) {
|
|
||||||
const mapSettingsList = Object.keys(mapConfig) as Array<
|
|
||||||
keyof typeof mapConfig
|
|
||||||
>;
|
|
||||||
|
|
||||||
const map = mapSettingsList[index];
|
|
||||||
const override = mapConfig[map].EscapeTimeLimitOverride;
|
|
||||||
const hardcodedEscapeLimitMax = 5;
|
|
||||||
|
|
||||||
if (
|
|
||||||
!override &&
|
|
||||||
locationList[index].base.EscapeTimeLimit / defaultEscapeTimes[map] >
|
|
||||||
hardcodedEscapeLimitMax
|
|
||||||
) {
|
|
||||||
const maxLimit = defaultEscapeTimes[map] * hardcodedEscapeLimitMax;
|
|
||||||
logger.warning(
|
|
||||||
`[MOAR] EscapeTimeLimit set too high on ${map}\nEscapeTimeLimit changed from ${locationList[index].base.EscapeTimeLimit} => ${maxLimit}\n`
|
|
||||||
);
|
|
||||||
locationList[index].base.EscapeTimeLimit = maxLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (override && locationList[index].base.EscapeTimeLimit !== override) {
|
|
||||||
console.log(
|
|
||||||
`[Moar] Set ${map}'s Escape time limit to ${override} from ${locationList[index].base.EscapeTimeLimit}\n`
|
|
||||||
);
|
|
||||||
locationList[index].base.EscapeTimeLimit = override;
|
|
||||||
locationList[index].base.EscapeTimeLimitCoop = override;
|
|
||||||
locationList[index].base.EscapeTimeLimitPVE = override;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
config.startingPmcs &&
|
|
||||||
locationList[index].base.EscapeTimeLimit / defaultEscapeTimes[map] > 2
|
|
||||||
) {
|
|
||||||
logger.warning(
|
|
||||||
`[MOAR] Average EscapeTimeLimit is too high (greater than 2x) to enable starting PMCS\nStarting PMCS has been turned off to prevent performance issues.\n`
|
|
||||||
);
|
|
||||||
config.startingPmcs = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,28 +0,0 @@
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { DependencyContainer } from "tsyringe";
|
|
||||||
import config from "../../config/config.json";
|
|
||||||
import presets from "../../config/Presets.json";
|
|
||||||
import presetWeightings from "../../config/PresetWeightings.json";
|
|
||||||
|
|
||||||
export default function checkPresetLogic(container: DependencyContainer) {
|
|
||||||
const Logger = container.resolve<ILogger>("WinstonLogger");
|
|
||||||
|
|
||||||
for (const key in presetWeightings) {
|
|
||||||
if (presets[key] === undefined) {
|
|
||||||
Logger.error(
|
|
||||||
`\n[MOAR]: No preset found in PresetWeightings.json for preset "${key}" in Presets.json`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const key in presets) {
|
|
||||||
const preset = presets[key];
|
|
||||||
for (const id in preset) {
|
|
||||||
if (config[id] === undefined) {
|
|
||||||
Logger.error(
|
|
||||||
`\n[MOAR]: No associated key found in config.json called "${id}" for preset "${key}" in Presets.json`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,160 +0,0 @@
|
||||||
import { DependencyContainer } from "tsyringe";
|
|
||||||
import {
|
|
||||||
ISeasonalEventConfig,
|
|
||||||
ISeasonalEvent,
|
|
||||||
} from "@spt/models/spt/config/ISeasonalEventConfig.d";
|
|
||||||
|
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
|
||||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
|
||||||
import { SeasonalEventService } from "@spt/services/SeasonalEventService";
|
|
||||||
import { zombieTypesCaps } from "../Spawning/utils";
|
|
||||||
|
|
||||||
export const baseZombieSettings = (enabled: boolean, count: number) =>
|
|
||||||
({
|
|
||||||
enabled,
|
|
||||||
name: "zombies",
|
|
||||||
type: "Zombies",
|
|
||||||
startDay: "1",
|
|
||||||
startMonth: "1",
|
|
||||||
endDay: "31",
|
|
||||||
endMonth: "12",
|
|
||||||
settings: {
|
|
||||||
enableSummoning: false,
|
|
||||||
removeEntryRequirement: [],
|
|
||||||
replaceBotHostility: true,
|
|
||||||
zombieSettings: {
|
|
||||||
enabled: true,
|
|
||||||
mapInfectionAmount: {
|
|
||||||
Interchange: count === -1 ? randomNumber100() : count,
|
|
||||||
Lighthouse: count === -1 ? randomNumber100() : count,
|
|
||||||
RezervBase: count === -1 ? randomNumber100() : count,
|
|
||||||
Sandbox: count === -1 ? randomNumber100() : count,
|
|
||||||
Shoreline: count === -1 ? randomNumber100() : count,
|
|
||||||
TarkovStreets: count === -1 ? randomNumber100() : count,
|
|
||||||
Woods: count === -1 ? randomNumber100() : count,
|
|
||||||
bigmap: count === -1 ? randomNumber100() : count,
|
|
||||||
factory4: count === -1 ? randomNumber100() : count,
|
|
||||||
laboratory: count === -1 ? randomNumber100() : count,
|
|
||||||
},
|
|
||||||
disableBosses: [],
|
|
||||||
disableWaves: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as unknown as ISeasonalEvent);
|
|
||||||
|
|
||||||
const randomNumber100 = () => Math.round(Math.random() * 100);
|
|
||||||
|
|
||||||
export const resetCurrentEvents = (
|
|
||||||
container: DependencyContainer,
|
|
||||||
enabled: boolean,
|
|
||||||
zombieWaveQuantity: number,
|
|
||||||
random: boolean = false
|
|
||||||
) => {
|
|
||||||
const configServer = container.resolve<ConfigServer>("ConfigServer");
|
|
||||||
const eventConfig = configServer.getConfig<ISeasonalEventConfig>(
|
|
||||||
ConfigTypes.SEASONAL_EVENT
|
|
||||||
);
|
|
||||||
|
|
||||||
let percentToShow = random ? -1 : Math.round(zombieWaveQuantity * 100);
|
|
||||||
if (percentToShow > 100) percentToShow = 100;
|
|
||||||
|
|
||||||
eventConfig.events = [baseZombieSettings(enabled, percentToShow)];
|
|
||||||
|
|
||||||
const seasonalEventService = container.resolve<SeasonalEventService>(
|
|
||||||
"SeasonalEventService"
|
|
||||||
) as any;
|
|
||||||
|
|
||||||
// First we need to clear any existing data
|
|
||||||
seasonalEventService.currentlyActiveEvents = [];
|
|
||||||
seasonalEventService.christmasEventActive = false;
|
|
||||||
seasonalEventService.halloweenEventActive = false;
|
|
||||||
// Then re-calculate the cached data
|
|
||||||
seasonalEventService.cacheActiveEvents();
|
|
||||||
// seasonalEventService.addEventBossesToMaps("halloweenzombies");
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setUpZombies = (container: DependencyContainer) => {
|
|
||||||
const configServer = container.resolve<ConfigServer>("ConfigServer");
|
|
||||||
const eventConfig = configServer.getConfig<ISeasonalEventConfig>(
|
|
||||||
ConfigTypes.SEASONAL_EVENT
|
|
||||||
);
|
|
||||||
|
|
||||||
eventConfig.events = [baseZombieSettings(false, 100)];
|
|
||||||
|
|
||||||
// eventConfig.eventBossSpawns = {
|
|
||||||
// zombies: eventConfig.eventBossSpawns.halloweenzombies,
|
|
||||||
// };
|
|
||||||
eventConfig.eventGear[eventConfig.events[0].name] = {};
|
|
||||||
eventConfig.hostilitySettingsForEvent.zombies.default =
|
|
||||||
eventConfig.hostilitySettingsForEvent.zombies.default
|
|
||||||
.filter(({ BotRole }) => !["pmcBEAR", "pmcUSEC"].includes(BotRole))
|
|
||||||
.map((host) => ({
|
|
||||||
...host,
|
|
||||||
AlwaysEnemies: [
|
|
||||||
"infectedAssault",
|
|
||||||
"infectedPmc",
|
|
||||||
"infectedCivil",
|
|
||||||
"infectedLaborant",
|
|
||||||
"infectedTagilla",
|
|
||||||
"pmcBEAR",
|
|
||||||
"pmcUSEC",
|
|
||||||
],
|
|
||||||
AlwaysNeutral: [
|
|
||||||
"marksman",
|
|
||||||
"assault",
|
|
||||||
"bossTest",
|
|
||||||
"bossBully",
|
|
||||||
"followerTest",
|
|
||||||
"bossKilla",
|
|
||||||
"bossKojaniy",
|
|
||||||
"followerKojaniy",
|
|
||||||
"pmcBot",
|
|
||||||
"cursedAssault",
|
|
||||||
"bossGluhar",
|
|
||||||
"followerGluharAssault",
|
|
||||||
"followerGluharSecurity",
|
|
||||||
"followerGluharScout",
|
|
||||||
"followerGluharSnipe",
|
|
||||||
"followerSanitar",
|
|
||||||
"bossSanitar",
|
|
||||||
"test",
|
|
||||||
"assaultGroup",
|
|
||||||
"sectantWarrior",
|
|
||||||
"sectantPriest",
|
|
||||||
"bossTagilla",
|
|
||||||
"followerTagilla",
|
|
||||||
"exUsec",
|
|
||||||
"gifter",
|
|
||||||
"bossKnight",
|
|
||||||
"followerBigPipe",
|
|
||||||
"followerBirdEye",
|
|
||||||
"bossZryachiy",
|
|
||||||
"followerZryachiy",
|
|
||||||
"bossBoar",
|
|
||||||
"followerBoar",
|
|
||||||
"arenaFighter",
|
|
||||||
"arenaFighterEvent",
|
|
||||||
"bossBoarSniper",
|
|
||||||
"crazyAssaultEvent",
|
|
||||||
"peacefullZryachiyEvent",
|
|
||||||
"sectactPriestEvent",
|
|
||||||
"ravangeZryachiyEvent",
|
|
||||||
"followerBoarClose1",
|
|
||||||
"followerBoarClose2",
|
|
||||||
"bossKolontay",
|
|
||||||
"followerKolontayAssault",
|
|
||||||
"followerKolontaySecurity",
|
|
||||||
"shooterBTR",
|
|
||||||
"bossPartisan",
|
|
||||||
"spiritWinter",
|
|
||||||
"spiritSpring",
|
|
||||||
"peacemaker",
|
|
||||||
"skier",
|
|
||||||
],
|
|
||||||
SavagePlayerBehaviour: "Neutral",
|
|
||||||
BearPlayerBehaviour: "AlwaysEnemies",
|
|
||||||
UsecPlayerBehaviour: "AlwaysEnemies",
|
|
||||||
}));
|
|
||||||
|
|
||||||
// console.log(eventConfig.hostilitySettingsForEvent.zombies.default);
|
|
||||||
};
|
|
|
@ -1,29 +0,0 @@
|
||||||
import { DependencyContainer } from "tsyringe";
|
|
||||||
import { IPostSptLoadMod } from "@spt/models/external/IPostSptLoadMod";
|
|
||||||
import { IPreSptLoadMod } from "@spt/models/external/IPreSptLoadMod";
|
|
||||||
import { enableBotSpawning } from "../config/config.json";
|
|
||||||
import { buildWaves } from "./Spawning/Spawning";
|
|
||||||
import config from "../config/config.json";
|
|
||||||
import { globalValues } from "./GlobalValues";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { setupRoutes } from "./Routes/routes";
|
|
||||||
import checkPresetLogic from "./Tests/checkPresets";
|
|
||||||
|
|
||||||
class Moar implements IPostSptLoadMod, IPreSptLoadMod {
|
|
||||||
preSptLoad(container: DependencyContainer): void {
|
|
||||||
if (enableBotSpawning) setupRoutes(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
postSptLoad(container: DependencyContainer): void {
|
|
||||||
if (enableBotSpawning) {
|
|
||||||
checkPresetLogic(container);
|
|
||||||
globalValues.baseConfig = config;
|
|
||||||
globalValues.overrideConfig = {};
|
|
||||||
const logger = container.resolve<ILogger>("WinstonLogger");
|
|
||||||
logger.info("\n[MOAR]: Starting up, may the bots ever be in your favour!");
|
|
||||||
buildWaves(container);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { mod: new Moar() };
|
|
|
@ -1,57 +0,0 @@
|
||||||
import PresetWeightings from "../config/PresetWeightings.json";
|
|
||||||
import Presets from "../config/Presets.json";
|
|
||||||
import { globalValues } from "./GlobalValues";
|
|
||||||
|
|
||||||
export const saveToFile = (data, filePath) => {
|
|
||||||
var fs = require("fs");
|
|
||||||
let dir = __dirname;
|
|
||||||
let dirArray = dir.split("\\");
|
|
||||||
const directory = `${dirArray[dirArray.length - 4]}/${
|
|
||||||
dirArray[dirArray.length - 3]
|
|
||||||
}/${dirArray[dirArray.length - 2]}/`;
|
|
||||||
fs.writeFile(
|
|
||||||
directory + filePath,
|
|
||||||
JSON.stringify(data, null, 4),
|
|
||||||
function (err) {
|
|
||||||
if (err) throw err;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const cloneDeep = (objectToClone: any) =>
|
|
||||||
JSON.parse(JSON.stringify(objectToClone));
|
|
||||||
|
|
||||||
export const getRandomPresetOrCurrentlySelectedPreset = () => {
|
|
||||||
switch (true) {
|
|
||||||
case globalValues.forcedPreset.toLowerCase() === "custom":
|
|
||||||
return {};
|
|
||||||
case !globalValues.forcedPreset:
|
|
||||||
globalValues.forcedPreset = "random";
|
|
||||||
break;
|
|
||||||
case globalValues.forcedPreset === "random":
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return Presets[globalValues.forcedPreset];
|
|
||||||
}
|
|
||||||
|
|
||||||
const all = [];
|
|
||||||
|
|
||||||
const itemKeys = Object.keys(PresetWeightings);
|
|
||||||
|
|
||||||
for (const key of itemKeys) {
|
|
||||||
for (let i = 0; i < PresetWeightings[key]; i++) {
|
|
||||||
all.push(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const preset: string = all[Math.round(Math.random() * (all.length - 1))];
|
|
||||||
globalValues.currentPreset = preset;
|
|
||||||
return Presets[preset];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const kebabToTitle = (str: string): string =>
|
|
||||||
str
|
|
||||||
.split("-")
|
|
||||||
.map((word) => word.slice(0, 1).toUpperCase() + word.slice(1))
|
|
||||||
.join(" ");
|
|
Binary file not shown.
|
@ -1,11 +1,11 @@
|
||||||
[General]
|
[General]
|
||||||
gameName=spt
|
gameName=spt
|
||||||
modid=0
|
modid=0
|
||||||
version=d2024.12.31.0
|
version=d2025.1.14.0
|
||||||
newestVersion=
|
newestVersion=
|
||||||
category="1,"
|
category="1,"
|
||||||
nexusFileStatus=1
|
nexusFileStatus=1
|
||||||
installationFile=DewardianDev-MOAR-2.6.1.zip
|
installationFile=utjan.PlantTimeModifier-1.2.0.zip
|
||||||
repository=Nexus
|
repository=Nexus
|
||||||
ignoredVersion=
|
ignoredVersion=
|
||||||
comments=
|
comments=
|
||||||
|
@ -15,7 +15,7 @@ url=
|
||||||
hasCustomURL=false
|
hasCustomURL=false
|
||||||
lastNexusQuery=
|
lastNexusQuery=
|
||||||
lastNexusUpdate=
|
lastNexusUpdate=
|
||||||
nexusLastModified=2024-12-16T06:46:30Z
|
nexusLastModified=2025-01-15T01:13:31Z
|
||||||
nexusCategory=0
|
nexusCategory=0
|
||||||
converted=false
|
converted=false
|
||||||
validated=false
|
validated=false
|
|
@ -1,21 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2024 acidphantasm
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
|
@ -1,47 +0,0 @@
|
||||||
# Welcome to PBS (Progressive Bot System)
|
|
||||||
|
|
||||||
The goal of this mod is to provide a system that allows all bots to progress with the player.
|
|
||||||
|
|
||||||
In vanilla, scavs are a minor annoyance once you reach level 30+. This aims to change that, they may not always have the best ammo but they won't always be rocking crappy shotguns or low level weapons.
|
|
||||||
|
|
||||||
## General Notes
|
|
||||||
|
|
||||||
This mod has only been tested with SAIN, SWAG+Donuts, QuestingBots, and LootingBots.
|
|
||||||
|
|
||||||
This mod may have missing mods or templates for weapons. If you see errors or warning - REPORT THEM.
|
|
||||||
|
|
||||||
This mod may have issues that prevent the game from working - if this happens, REMOVE THE MOD and REPORT THEM.
|
|
||||||
|
|
||||||
Currently all bots that are due to spawn or have spawned are logged inside the \user\mods\acidphantasm-progressivebotsystem\logs\ folder. These logs are wiped when you restart the server. These may be needed to provide support, and are a nice thing to review if you happen to want to know everything that has or will spawn.
|
|
||||||
|
|
||||||
## Put this mod last in your load order. If you have issues and it isn't last, then move it last.
|
|
||||||
|
|
||||||
### Current Features
|
|
||||||
- All AI will level with you.
|
|
||||||
- All AI have a tiering system.
|
|
||||||
- All AI will use modded weapons that you have installed.
|
|
||||||
- USEC spawn with weapons that you would expect from non-Russian forces.
|
|
||||||
- BEAR spawn with weapons that you would expect from Russian forces.
|
|
||||||
- Scavs pull a weapon from the Tier they have spawned from (any weapon available in that tier from USEC or BEAR can be chosen.)
|
|
||||||
- Scavs pull from ammo pools that do not contains meta ammo. I felt this was too easy a source of ammunition. This is subject to change.
|
|
||||||
- Bosses pull weapons from their vanilla pools until a later version.
|
|
||||||
- Bosses & guards pull ammo from a Tier4 pool.
|
|
||||||
- Boss guards pull a Tier4 weapon from the combined pools of USEC & BEAR.
|
|
||||||
|
|
||||||
### Current Tiers
|
|
||||||
- Tier 1 = Lv1-10
|
|
||||||
- Level Variance +/- 5
|
|
||||||
- Tier 2 = Lv11-20
|
|
||||||
- Level Variance +/- 7
|
|
||||||
- Tier 3 = Lv21-30
|
|
||||||
- Level Variance +/- 10
|
|
||||||
- Tier 4 = Lv31-40
|
|
||||||
- Level Variance +/- 15
|
|
||||||
- Tier 5 = Lv41-50
|
|
||||||
- Level Variance +/- 15
|
|
||||||
- Tier 6 = Lv51-60
|
|
||||||
- Level Variance +/- 20
|
|
||||||
- Tier 7 = Lv61-78
|
|
||||||
- Level Variance +/- 30
|
|
||||||
|
|
||||||
## Put this mod last in your load order. If you have issues and it isn't last, then move it last.
|
|
|
@ -1,264 +0,0 @@
|
||||||
{
|
|
||||||
// Enable/Disable using a preset
|
|
||||||
// Presets are to be built and shared among APBS users. If enabled, ensure that you set the "presetName" to the name of the folder of your preset
|
|
||||||
"usePreset": false,
|
|
||||||
"presetName": "example",
|
|
||||||
|
|
||||||
// If you enable either of these settings, support will not be granted.
|
|
||||||
// enableModdedWeapons - Any mods adding weapons loaded before APBS will have their weapons & attachments imported.
|
|
||||||
// enableModdedEquipment - Any mods adding equipment loaded before APBS will be imported with their attachments (if any).
|
|
||||||
// enableModdedClothing - Any mods adding clothing loaded before APBS will be imported.
|
|
||||||
// initialTierAppearance - Whatever number (1-7) you put here, will be the first tier that imported mod items will be added to.
|
|
||||||
// pmcWeaponWeights - Weight of modded weapons being added to PMCs
|
|
||||||
// scavWeaponWeights - Weight of modded weapons being added to Scavs
|
|
||||||
// followerWeaponWeights - Weight of modded weapons being added to boss followers (not Goons)
|
|
||||||
// enableSafeGuard - Enables preventing weapon importing from bastardizing vanilla weapons. If you disable this, you will get cursed vanilla weapons.
|
|
||||||
// Higher weights = more often. Lower weights = less often. If you add a LOT of mod weapons, I suggest using a lower value.
|
|
||||||
// REVIEW THE APBS LOGS TO TUNE YOUR CONFIG. (\user\mods\acidphantasm-progressivebotsystem\logs)
|
|
||||||
"enableModdedWeapons": true,
|
|
||||||
"enableModdedEquipment": true,
|
|
||||||
"enableModdedClothing": true,
|
|
||||||
"initalTierAppearance": 3,
|
|
||||||
"pmcWeaponWeights": 10,
|
|
||||||
"scavWeaponWeights": 1,
|
|
||||||
"followerWeaponWeights": 7,
|
|
||||||
"enableSafeGuard": true,
|
|
||||||
|
|
||||||
// Enable/Disable PMC Seasonal Clothing
|
|
||||||
// If true, PMCs will wear seasonal appropriate clothing to blend into the environment better. If disabled, clothing will be tiered by level instead.
|
|
||||||
// If true, modded clothing will not import, regardless of setting, to protect the appearance of appropriate clothing.
|
|
||||||
"seasonalPmcAppearance": true,
|
|
||||||
|
|
||||||
// Enable/Disable Realism Gas Mask Compatibility
|
|
||||||
// APBS automatically detects Realism and adds gas masks to bots due to Radiation Zones. If you dont want this to happen, set to true.
|
|
||||||
"disableRealismGasMasks": false,
|
|
||||||
|
|
||||||
// Looking for a challenge, or maybe just want to chill and wreck some bots?
|
|
||||||
// Enable "onlyChads" to force all bots to be Tier7, or enable "tarkovAndChill" to force all bots to be Tier1
|
|
||||||
// Enabling both will enable chaos mode, bots will pull gear and weapons from completely random Tiers during generation. It's chaos.
|
|
||||||
// Alternatively, enable "blickyMode" to give everyone a blicky. It's actually the real chill mode.
|
|
||||||
// Side note on "blickyMode" - it breaks some boss guards. Don't report it. It's a joke mode. It also won't do anything if either of the other two "modes" are enabled.
|
|
||||||
"onlyChads": false,
|
|
||||||
"tarkovAndChill": false,
|
|
||||||
"blickyMode": false,
|
|
||||||
|
|
||||||
// Enable/Disable specific bot generation
|
|
||||||
// If set to true, it will disable APBS generation for that bot type, if false - will use APBS generation.
|
|
||||||
"disableScavTierGeneration": false,
|
|
||||||
"disablePMCTierGeneration": false,
|
|
||||||
"disableBossTierGeneration": false,
|
|
||||||
"disableBossFollowerTierGeneration": false,
|
|
||||||
"disableRaiderRogueTierGeneration": false,
|
|
||||||
|
|
||||||
// Enable/Disable bots having the chance to roll ammo choice for rig magazines after selecting ammo choice for weapon
|
|
||||||
// "enableBotsToRollAmmoAgain" If set to true, AI PMCs will roll their ammo choice for additional magazines based on the chance configured - if false all magazines will always have the same ammo selected for the weapon.
|
|
||||||
// "chanceToRollAmmoAgain" chance out of 100 that bot will roll ammo again for each subsequent additional magazine they spawn with in their rig.
|
|
||||||
"enableBotsToRollAmmoAgain": true,
|
|
||||||
"chanceToRollAmmoAgain": 50,
|
|
||||||
|
|
||||||
// Enable/Disable custom game version weights for AI PMCs
|
|
||||||
// If set to true, AI PMCs will roll their weights from the values below - if false will use SPT defaults.
|
|
||||||
// The values listed below ARE the SPT defaults (for reference)
|
|
||||||
"gameVersionWeight": false,
|
|
||||||
"standard": 2,
|
|
||||||
"left_behind": 1,
|
|
||||||
"prepare_for_escape": 1,
|
|
||||||
"edge_of_darkness": 4,
|
|
||||||
"unheard_edition": 2,
|
|
||||||
|
|
||||||
// Enable/Disable PMC ammo tier sliding
|
|
||||||
// If set to true, it will enabling a sliding system for PMC ammo pools. If you enable this, the below numbers are the recommended amounts. Tweak as you wish.
|
|
||||||
// Example: "pmcAmmoTierSlideAmount: 1 will allow a Tier5 PMC to "slide" down and pick from a Tier4 ammo pool, if it passes the roll for "slideChance".
|
|
||||||
"enablePMCAmmoTierSliding": false,
|
|
||||||
"slideAmount": 1,
|
|
||||||
"slideChance": 33,
|
|
||||||
|
|
||||||
// Enable/Disable using individual weapon type attachment chances.
|
|
||||||
// If set to true, will allow generation to use individual category based weapon attachment chances, if false - all weapons use the same attachment chance pool.
|
|
||||||
// For Preset Makers:
|
|
||||||
// If the below setting is false, "weaponMods" in the chances.json is the attachment chance rolls used.
|
|
||||||
// If the below setting is true, then you must also fill out each weapons category of chances.
|
|
||||||
"enablePerWeaponTypeAttachmentChances": true,
|
|
||||||
|
|
||||||
// Force weapon stocks
|
|
||||||
// If set to true, will enforce all AI weapons to have stocks, if false - will use APBS values
|
|
||||||
// "stockButtpadChance" will allow dynamic configuration of any butt pads spawning on a stock that can take them.
|
|
||||||
"forceStock": false,
|
|
||||||
"stockButtpadChance": 50,
|
|
||||||
|
|
||||||
// Force weapon dust covers
|
|
||||||
// If set to true, will enforce all AI weapons to have dust covers, if false - will use APBS values
|
|
||||||
"forceDustCover": false,
|
|
||||||
|
|
||||||
// Force weapon mod_scope slot
|
|
||||||
// If set to true, will enforce all AI weapons to have a mod in the mod_scope slot
|
|
||||||
// This slot is *MOSTLY* optics but it's sometimes a laser/flashlight depending on gun, if false - will use APBS values
|
|
||||||
"forceScopeSlot": false,
|
|
||||||
|
|
||||||
// Force weapon muzzles
|
|
||||||
// "forceMuzzle" If set to true, will enforce all AI PMC weapons to have muzzles based on the chance configured, if false - will use APBS values
|
|
||||||
// "muzzleChance" chance of muzzle being selected (overrides preset and database values) for each tier [ T1, T2, T3, T4, T5, T6, T7 ]
|
|
||||||
// "forceChildrenMuzzle" If set to true, enforces muzzle children to also spawn (so if it rolls to pick a threaded adapter, the child silencer will be forced to spawn), if false - will roll those slots independently
|
|
||||||
// "forceChildrenMuzzle" works regardless of you setting forceMuzzle or not - if you just want to see more children adapters spawn, just set this true
|
|
||||||
"forceMuzzle": false,
|
|
||||||
"muzzleChance": [ 10, 25, 40, 55, 65, 75, 75 ],
|
|
||||||
"forceChildrenMuzzle": false,
|
|
||||||
|
|
||||||
// Force weapon mod count limits
|
|
||||||
// If set to true, will enforce all AI weapons to be limited to the scopeLimit & tacticalLimit, if disabled the generation may go wild
|
|
||||||
"forceWeaponModLimits": true,
|
|
||||||
"scopeLimit": 2,
|
|
||||||
"tacticalLimit": 1,
|
|
||||||
|
|
||||||
// Enable/disable AI having T-7 thermal goggles
|
|
||||||
// If set to true, will allow AI to spawn with T-7 thermal goggles, if false they will not.
|
|
||||||
// "startTier" controls what tier the goggles will be available in. "5c110624d174af029e69734c"
|
|
||||||
"enableT7Thermals": false,
|
|
||||||
"startTier": 6,
|
|
||||||
|
|
||||||
// Enable/Disable PMC/scav Loot
|
|
||||||
// If set to true, will allow PMCs/scavs to have backpack/rig/pocket loot. If disabled, they will not.
|
|
||||||
// Add ItemIDs to the blacklist array to prevent them from spawning
|
|
||||||
// Blacklist example "pmcLootBlacklistItems": ["6711039f9e648049e50b3307", "5c0e531286f7747fa54205c2"]
|
|
||||||
"pmcLoot": false,
|
|
||||||
"pmcLootBlacklistItems": [ "6711039f9e648049e50b3307" ],
|
|
||||||
"scavLoot": true,
|
|
||||||
|
|
||||||
// Enable/Disabe Scav specific tiering options
|
|
||||||
// "enableScavAttachmentTiering" - If set to true, will allow scavs to get additional weapon/equipment attachments as they tier up. If disabled, they will always have tier 1 attachments.
|
|
||||||
// "enableScavEqualChanceEquipmentTiering" - If set to true, will allow scavs to have equal chances for any equipment in their pools. If disabled, they will use APBS defaults (low chances for good gear).
|
|
||||||
"enableScavAttachmentTiering": false,
|
|
||||||
"enableScavEqualEquipmentTiering": false,
|
|
||||||
|
|
||||||
// Enable/Disable adding keys to Scav Backpack loot
|
|
||||||
// Pick -ONE- option below and enable it if you would like to expand the backpack key pool for scavs.
|
|
||||||
// All keys include every key/keycard.
|
|
||||||
// Mechanical keys are keys that aren't keycards. <- Recommended, if you are going to enable something
|
|
||||||
// Keycards include ALL keycards.
|
|
||||||
"addAllKeysToScavs": false,
|
|
||||||
"addOnlyMechanicalKeysToScavs": false,
|
|
||||||
"addOnlyKeyCardsToScavs": false,
|
|
||||||
|
|
||||||
// Configure Weapon Durability per AI Bot Type
|
|
||||||
// Numbers are as follows: [ minDurability, maxDurability, minDelta, maxDelta ]
|
|
||||||
// Example: [ 50, 90, 0, 25 ]
|
|
||||||
// Ex ctd: Minimum possible "max" durability would be 50%, the highest possible "max" durability is 90%
|
|
||||||
// Ex ctd: Whatever value is picked between 50% & 90% will be the "max" durability of the weapon ("max" is the limit you can repair the weapon to)
|
|
||||||
// Ex ctd: After the max durability is selected, it will roll for the actual current durability which will be between 0-25% lower than the max.
|
|
||||||
// Ex ctd: Weapons are safeguarded to never fall below 40%.
|
|
||||||
"scavWeaponDurability": [ 50, 90, 0, 20 ],
|
|
||||||
"pmcWeaponDurability": [ 95, 100, 0, 5 ],
|
|
||||||
"bossWeaponDurability": [ 80, 100, 0, 20 ],
|
|
||||||
"guardWeaponDurability": [ 80, 100, 0, 20 ],
|
|
||||||
"raiderWeaponDurability": [ 80, 100, 0, 20 ],
|
|
||||||
|
|
||||||
// Enable/Disable custom plate chances
|
|
||||||
// If you REALLY don't like APBS plate chances then you can adjust it here.
|
|
||||||
// If set to true, will change all AI plate chances to the values you set below, if false - will use APBS values
|
|
||||||
// If set to true, Main Plates = front/back and Side Plates = left/right, if false - APBS uses individual plate chances for front/back and sides.
|
|
||||||
// Values are configured for each tier, example: [ Tier1, Tier2, Tier3, Tier4, Tier5, Tier6, Tier7 ]
|
|
||||||
"enableCustomPlateChances": false,
|
|
||||||
"scavMainPlateChance": [ 25, 25, 25, 25, 25, 25, 25 ],
|
|
||||||
"scavSidePlateChance": [ 25, 25, 25, 25, 25, 25, 25 ],
|
|
||||||
"pmcMainPlateChance": [ 65, 75, 90, 90, 95, 100, 100 ],
|
|
||||||
"pmcSidePlateChance": [ 15, 25, 50, 75, 90, 95, 100 ],
|
|
||||||
"bossMainPlateChance": [ 75, 75, 75, 75, 75, 75, 75 ],
|
|
||||||
"bossSidePlateChance": [ 50, 50, 50, 50, 50, 50, 50 ],
|
|
||||||
"guardMainPlateChance": [ 75, 75, 75, 75, 75, 75, 75 ],
|
|
||||||
"guardSidePlateChance": [ 75, 75, 75, 75, 75, 75, 75 ],
|
|
||||||
"raiderMainPlateChance": [ 75, 75, 75, 75, 75, 75, 75 ],
|
|
||||||
"raiderSidePlateChance": [ 75, 75, 75, 75, 75, 75, 75 ],
|
|
||||||
|
|
||||||
// Enable/Disable randomization of medical and food resource values
|
|
||||||
// If set to true, all scavs and PMCs will have randomized resource values, based on the chances you set below, for medical and food items.
|
|
||||||
// If disabled the items will always be full resource values.
|
|
||||||
// Explanation: "pmcMedRates": [ Chance for full resource value available, Minimum percent of item randomized between min and max resource ]
|
|
||||||
// Example.. "pmcMedRates": [ 65, 20 ] --- AFAK on a PMC has a 65% chance to be 400/400 and 35% chance to be between 0% and 80% used (it would spawn somewhere between 80/400 to 400/400).
|
|
||||||
"enableConsumableResourceRandomization": true,
|
|
||||||
"scavFoodRates": [ 10, 25 ],
|
|
||||||
"scavMedRates": [ 10, 25 ],
|
|
||||||
"pmcFoodRates": [ 10, 25 ],
|
|
||||||
"pmcMedRates": [ 10, 25 ],
|
|
||||||
|
|
||||||
// Blacklist specific ammo types from all AI -- USE "https://db.sp-tarkov.com/" to get the item _id
|
|
||||||
// Configure per tier blacklists
|
|
||||||
// Example.. this will blacklist 9x19 RIP and 5.45x39mm PP from all bots in Tier1
|
|
||||||
// tier1AmmoBlacklist: [ "5c0d56a986f774449d5de529", "56dff2ced2720bb4668b4567" ]
|
|
||||||
"tier1AmmoBlacklist": [],
|
|
||||||
"tier2AmmoBlacklist": [],
|
|
||||||
"tier3AmmoBlacklist": [],
|
|
||||||
"tier4AmmoBlacklist": [],
|
|
||||||
"tier5AmmoBlacklist": [],
|
|
||||||
"tier6AmmoBlacklist": [],
|
|
||||||
"tier7AmmoBlacklist": [],
|
|
||||||
|
|
||||||
// Blacklist specific equipment from all AI -- USE "https://db.sp-tarkov.com/" to get the item _id
|
|
||||||
// Configure per tier blacklists
|
|
||||||
// Example.. this will blacklist BlackRock chest rig and GSSh-01 headset from all bots in Tier1
|
|
||||||
// tier1EquipmentBlacklist: [ "5648a69d4bdc2ded0b8b457b", "5b432b965acfc47a8774094e" ]
|
|
||||||
"tier1EquipmentBlacklist": [],
|
|
||||||
"tier2EquipmentBlacklist": [],
|
|
||||||
"tier3EquipmentBlacklist": [],
|
|
||||||
"tier4EquipmentBlacklist": [],
|
|
||||||
"tier5EquipmentBlacklist": [],
|
|
||||||
"tier6EquipmentBlacklist": [],
|
|
||||||
"tier7EquipmentBlacklist": [],
|
|
||||||
|
|
||||||
// Blacklist specific weapons from all AI -- USE "https://db.sp-tarkov.com/" to get the item _id
|
|
||||||
// Configure per tier blacklists
|
|
||||||
// Example.. this will blacklist PKP and PKM from all bots in Tier1
|
|
||||||
// tier1EquipmentBlacklist: [ "64ca3d3954fc657e230529cc", "64637076203536ad5600c990" ]
|
|
||||||
"tier1WeaponBlacklist": [],
|
|
||||||
"tier2WeaponBlacklist": [],
|
|
||||||
"tier3WeaponBlacklist": [],
|
|
||||||
"tier4WeaponBlacklist": [],
|
|
||||||
"tier5WeaponBlacklist": [],
|
|
||||||
"tier6WeaponBlacklist": [],
|
|
||||||
"tier7WeaponBlacklist": [],
|
|
||||||
|
|
||||||
// Blacklist specific attachments from all AI -- USE "https://db.sp-tarkov.com/" to get the item _id
|
|
||||||
// Configure per tier blacklists - very useful setting for those that play with modded weapon/equipment importing
|
|
||||||
// Example.. this will blacklist "AK 7.62x39 aluminium 10-round magazine" and "Ops-Core SLAAP Armor Helmet Plate" from all bots in Tier1
|
|
||||||
// tier1EquipmentBlacklist: [ "5b1fd4e35acfc40018633c39", "5c0e66e2d174af02a96252f4" ]
|
|
||||||
"tier1AttachmentBlacklist": [],
|
|
||||||
"tier2AttachmentBlacklist": [],
|
|
||||||
"tier3AttachmentBlacklist": [],
|
|
||||||
"tier4AttachmentBlacklist": [],
|
|
||||||
"tier5AttachmentBlacklist": [],
|
|
||||||
"tier6AttachmentBlacklist": [],
|
|
||||||
"tier7AttachmentBlacklist": [],
|
|
||||||
|
|
||||||
// LevelDelta's are the lowest and highest levels that AI can spawn relative to the player's level.
|
|
||||||
// Examples:
|
|
||||||
// "tier1LevelDelta": [ 5, 5 ] --- While you are Tier1 (lv1-10), all AI will be leveled -5 to +5 of your level.
|
|
||||||
// "tier2LevelDelta": [ 10, 25 ] --- While you are Tier2 (lv11-20), all AI will be leveled -10 to +25 of your level.
|
|
||||||
// "enableCustomLevelDeltas" if true will use the values you set below, otherwise they will use APBS values
|
|
||||||
// THE BELOW VALUES BY DEFAULT ARE APBS DEFAULTS
|
|
||||||
// IF YOU WANT EVERY TIER AT EVERY LEVEL, SET ALL OF THESE TO: [ 79, 79 ]
|
|
||||||
"enableCustomLevelDeltas": true,
|
|
||||||
"tier1LevelDelta": [ 10, 5 ], // 1-10
|
|
||||||
"tier2LevelDelta": [ 20, 5 ], // 11-20
|
|
||||||
"tier3LevelDelta": [ 25, 7 ], // 21-30
|
|
||||||
"tier4LevelDelta": [ 35, 10 ], // 31-40
|
|
||||||
"tier5LevelDelta": [ 40, 15 ], // 41-50
|
|
||||||
"tier6LevelDelta": [ 50, 20 ], // 51-60
|
|
||||||
"tier7LevelDelta": [ 55, 20 ], // 61-79
|
|
||||||
|
|
||||||
// LevelDelta's are the lowest and highest levels that AI can spawn relative to the player's level.
|
|
||||||
// Examples:
|
|
||||||
// "tier2ScavLevelDelta": [ 10, -10 ] --- While you are Tier2 (lv11-20), scavs will be leveled -10 to -10 of your level. (always 10 levels behind you)
|
|
||||||
// "tier3ScavLevelDelta": [ 30, -10 ] --- While you are Tier3 (lv21-30), scavs will be leveled -30 to -10 of your level. (always 10 to 30 levels behind you)
|
|
||||||
// "enableScavCustomLevelDeltas" if true will use the values you set below, otherwise they will use APBS values
|
|
||||||
// Default values below will always spawn scavs that are at least 1 tier below you unless you are Tier1.
|
|
||||||
"enableScavCustomLevelDeltas": false,
|
|
||||||
"tier1ScavLevelDelta": [ 10, 0 ], // 1-10
|
|
||||||
"tier2ScavLevelDelta": [ 10, -10 ], // 11-20
|
|
||||||
"tier3ScavLevelDelta": [ 15, -10 ], // 21-30
|
|
||||||
"tier4ScavLevelDelta": [ 20, -10 ], // 31-40
|
|
||||||
"tier5ScavLevelDelta": [ 30, -10 ], // 41-50
|
|
||||||
"tier6ScavLevelDelta": [ 40, -10 ], // 51-60
|
|
||||||
"tier7ScavLevelDelta": [ 50, -10 ], // 61-79
|
|
||||||
|
|
||||||
// Enable/disable debug logging
|
|
||||||
"enableDebugLog": true
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Acids Progressive Bot System",
|
|
||||||
"version": "1.4.0",
|
|
||||||
"sptVersion": "~3.10",
|
|
||||||
"loadBefore": [],
|
|
||||||
"loadAfter": [
|
|
||||||
"DanW-SPTQuestingBots"
|
|
||||||
],
|
|
||||||
"incompatibilities": [],
|
|
||||||
"isBundleMod": false,
|
|
||||||
"main": "src/mod.js",
|
|
||||||
"scripts": {
|
|
||||||
"setup": "npm i",
|
|
||||||
"build": "node ./build.mjs",
|
|
||||||
"buildinfo": "node ./build.mjs --verbose"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "20.11",
|
|
||||||
"@typescript-eslint/eslint-plugin": "7.2",
|
|
||||||
"@typescript-eslint/parser": "7.2",
|
|
||||||
"archiver": "^6.0",
|
|
||||||
"eslint": "8.57",
|
|
||||||
"fs-extra": "11.2",
|
|
||||||
"ignore": "^5.2",
|
|
||||||
"tsyringe": "4.8.0",
|
|
||||||
"typescript": "5.4",
|
|
||||||
"winston": "3.12"
|
|
||||||
},
|
|
||||||
"author": "acidphantasm",
|
|
||||||
"contributors": [],
|
|
||||||
"license": "MIT"
|
|
||||||
}
|
|
|
@ -1,479 +0,0 @@
|
||||||
{
|
|
||||||
"scavAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 3
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 1
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6772a4b936088465b17c": 2,
|
|
||||||
"5d6e6806a4b936088465b17e": 2,
|
|
||||||
"5d6e67fba4b9361bc73bc779": 2,
|
|
||||||
"560d5e524bdc2d25448b4571": 2,
|
|
||||||
"5d6e6869a4b9361c140bcfde": 1,
|
|
||||||
"5d6e68b3a4b9361bca7e50b5": 1,
|
|
||||||
"58820d1224597753c90aeb13": 1,
|
|
||||||
"5d6e68dea4b9361bcc29e659": 1,
|
|
||||||
"5d6e6891a4b9361bd473feea": 1,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 1,
|
|
||||||
"5d6e689ca4b9361bc8618956": 1
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e695fa4b936359b35d852": 2,
|
|
||||||
"5d6e69b9a4b9361bc8618958": 2,
|
|
||||||
"5a38ebd9c4a282000d722a5b": 2,
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 1
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 3,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 1
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 3,
|
|
||||||
"59e6542b86f77411dc52a77a": 1
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 3,
|
|
||||||
"5ba26844d4351e00334c9475": 1
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff216d2720bbd668b4568": 1,
|
|
||||||
"56dff338d2720bbd668b4569": 4,
|
|
||||||
"56dff421d2720b5f5a8b4567": 4,
|
|
||||||
"56dff4ecd2720b5f5a8b4568": 2,
|
|
||||||
"56dff4a2d2720bbd668b456a": 4,
|
|
||||||
"56dff0bed2720bb0668b4567": 3,
|
|
||||||
"56dff3afd2720bba668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"59e6927d86f77411da468256": 2,
|
|
||||||
"59e6918f86f7746c9f75e849": 2,
|
|
||||||
"59e68f6f86f7746c9f75e846": 4,
|
|
||||||
"59e6920f86f77411d82aa167": 5,
|
|
||||||
"54527a984bdc2d4e668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc86832d7f00c000d3a6e6c": 2,
|
|
||||||
"5cc80f79e4a949033c7343b2": 3,
|
|
||||||
"5cc86840d7f00c002412c56c": 3,
|
|
||||||
"5cc80f8fe4a949033b0224a2": 1,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 1
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 1
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573602322459776445391df1": 2,
|
|
||||||
"573601b42459776410737435": 2,
|
|
||||||
"5735fdcd2459776445391d61": 1,
|
|
||||||
"5736026a245977644601dc61": 1
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 1,
|
|
||||||
"6196364158ef8c428c287d9f": 6,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 3
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4d3d286f774176a36250a": 2,
|
|
||||||
"64b7af734b75259c590fa895": 2,
|
|
||||||
"64b7af5a8532cf95ee0a0dbd": 6,
|
|
||||||
"59e4d24686f7741776641ac7": 4,
|
|
||||||
"59e4cf5286f7741778269d8a": 2,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 1
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e88277cce2b522ff2b1": 2,
|
|
||||||
"5e023e6e34d52a55c3304f71": 2,
|
|
||||||
"5e023e53d4353e3302577c4c": 1
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"64b8f7c241772715af0f9c3d": 2,
|
|
||||||
"64b8f7b5389d7ffd620ccba2": 2,
|
|
||||||
"64b8f7968532cf95ee0a0dbf": 2,
|
|
||||||
"5e023cf8186a883be655e54f": 2,
|
|
||||||
"5887431f2459777e1612938f": 1
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 2,
|
|
||||||
"5fc382c1016cce60e8341b20": 1
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"5737218f245977612125ba51": 5,
|
|
||||||
"57372140245977611f70ee91": 5,
|
|
||||||
"5737207f24597760ff7b25f2": 2,
|
|
||||||
"573719762459775a626ccbc1": 3,
|
|
||||||
"57371f8d24597761006c6a81": 3,
|
|
||||||
"57371f2b24597761224311f1": 5,
|
|
||||||
"57371eb62459776125652ac1": 1,
|
|
||||||
"57371b192459775a9f58a5e0": 1,
|
|
||||||
"57371e4124597760ff7b25f1": 1
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5efb0e16aeb21837e749c7ff": 1,
|
|
||||||
"58864a4f2459770fcc257101": 7,
|
|
||||||
"5a3c16fe86f77452b62de32a": 12,
|
|
||||||
"5c3df7d588a4501f290594e5": 6,
|
|
||||||
"64b7bbb74b75259c590fa897": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 2
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a26ac06c4a282000c5a90a8": 5,
|
|
||||||
"5a26abfac4a28232980eabff": 3,
|
|
||||||
"5a269f97c4a282000b151807": 1
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c40bdd19b369e1e53d1": 5,
|
|
||||||
"62330bfadc5883093563729b": 3,
|
|
||||||
"62330c18744e5e31df12f516": 1
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"6576f96220d53a5b8f3e395e": 7,
|
|
||||||
"57a0dfb82459774d3078b56c": 5,
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 1
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 10,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 1,
|
|
||||||
"5efb0fc6aeb21837e749c801": 8,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 40,
|
|
||||||
"5e81f423763d9f754677bf2e": 15
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 45
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 10,
|
|
||||||
"5c0d591486f7744c505b416f": 3,
|
|
||||||
"5d6e68d1a4b93622fe60e845": 3,
|
|
||||||
"5d6e6869a4b9361c140bcfde": 2,
|
|
||||||
"5d6e68b3a4b9361bca7e50b5": 4,
|
|
||||||
"58820d1224597753c90aeb13": 6,
|
|
||||||
"5d6e68dea4b9361bcc29e659": 8,
|
|
||||||
"5d6e6891a4b9361bd473feea": 12,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 12,
|
|
||||||
"5d6e689ca4b9361bc8618956": 9
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e695fa4b936359b35d852": 8,
|
|
||||||
"5d6e69b9a4b9361bc8618958": 8,
|
|
||||||
"5a38ebd9c4a282000d722a5b": 8,
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 10,
|
|
||||||
|
|
||||||
"5d6e6a5fa4b93614ec501745": 3,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 3
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 10,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 2
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 20,
|
|
||||||
"59e6542b86f77411dc52a77a": 25,
|
|
||||||
"59e655cb86f77411dc52a77b": 8
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 50,
|
|
||||||
"5ba26844d4351e00334c9475": 50
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff216d2720bbd668b4568": 1,
|
|
||||||
"56dff338d2720bbd668b4569": 10,
|
|
||||||
"56dff421d2720b5f5a8b4567": 10,
|
|
||||||
"56dff4ecd2720b5f5a8b4568": 15,
|
|
||||||
"56dff4a2d2720bbd668b456a": 15,
|
|
||||||
"56dff0bed2720bb0668b4567": 35,
|
|
||||||
"56dff3afd2720bba668b4567": 45
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"59e6927d86f77411da468256": 10,
|
|
||||||
"59e6918f86f7746c9f75e849": 20,
|
|
||||||
"59e68f6f86f7746c9f75e846": 45,
|
|
||||||
"59e6920f86f77411d82aa167": 50,
|
|
||||||
"54527a984bdc2d4e668b4567": 20
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc86832d7f00c000d3a6e6c": 10,
|
|
||||||
"5cc80f79e4a949033c7343b2": 19,
|
|
||||||
"5cc86840d7f00c002412c56c": 24,
|
|
||||||
"5cc80f8fe4a949033b0224a2": 13,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 9
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 1
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573602322459776445391df1": 6,
|
|
||||||
"573601b42459776410737435": 10,
|
|
||||||
"5735fdcd2459776445391d61": 18,
|
|
||||||
"5736026a245977644601dc61": 10,
|
|
||||||
"573603c924597764442bd9cb": 4,
|
|
||||||
"573603562459776430731618": 1
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 9,
|
|
||||||
"6196364158ef8c428c287d9f": 19,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 14
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4d3d286f774176a36250a": 3,
|
|
||||||
"64b7af734b75259c590fa895": 10,
|
|
||||||
"64b7af5a8532cf95ee0a0dbd": 20,
|
|
||||||
"59e4d24686f7741776641ac7": 25,
|
|
||||||
"59e4cf5286f7741778269d8a": 35,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 15
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e88277cce2b522ff2b1": 10,
|
|
||||||
"5e023e6e34d52a55c3304f71": 40,
|
|
||||||
"5e023e53d4353e3302577c4c": 50
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"64b8f7c241772715af0f9c3d": 9,
|
|
||||||
"64b8f7b5389d7ffd620ccba2": 14,
|
|
||||||
"64b8f7968532cf95ee0a0dbf": 16,
|
|
||||||
"5e023cf8186a883be655e54f": 20,
|
|
||||||
"5887431f2459777e1612938f": 14
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 95,
|
|
||||||
"5fc382c1016cce60e8341b20": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"5737218f245977612125ba51": 2,
|
|
||||||
"57372140245977611f70ee91": 6,
|
|
||||||
"5737207f24597760ff7b25f2": 6,
|
|
||||||
"573719762459775a626ccbc1": 6,
|
|
||||||
"57371f8d24597761006c6a81": 9,
|
|
||||||
"57371f2b24597761224311f1": 9,
|
|
||||||
"57371eb62459776125652ac1": 9,
|
|
||||||
"57371b192459775a9f58a5e0": 18,
|
|
||||||
"57371e4124597760ff7b25f1": 23,
|
|
||||||
"5737201124597760fc4431f1": 18,
|
|
||||||
"573720e02459776143012541": 9,
|
|
||||||
"573718ba2459775a75491131": 6
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 1,
|
|
||||||
"5efb0e16aeb21837e749c7ff": 7,
|
|
||||||
"58864a4f2459770fcc257101": 20,
|
|
||||||
"5a3c16fe86f77452b62de32a": 30,
|
|
||||||
"5c3df7d588a4501f290594e5": 40,
|
|
||||||
"64b7bbb74b75259c590fa897": 40,
|
|
||||||
"56d59d3ad2720bdb418b4577": 25
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a26ac06c4a282000c5a90a8": 9,
|
|
||||||
"5a26abfac4a28232980eabff": 22,
|
|
||||||
"5a269f97c4a282000b151807": 17
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c40bdd19b369e1e53d1": 15,
|
|
||||||
"62330bfadc5883093563729b": 12
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"6576f96220d53a5b8f3e395e": 19,
|
|
||||||
"57a0dfb82459774d3078b56c": 27,
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 13
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 50,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 30
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bossAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 4,
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 10,
|
|
||||||
"5e81f423763d9f754677bf2e": 18,
|
|
||||||
"5efb0cabfb3e451d70735af5": 10
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 3,
|
|
||||||
"5cadf6ddae9215051e1c23b2": 12,
|
|
||||||
"5cadf6eeae921500134b2799": 8
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 7,
|
|
||||||
"64b8ee384b75259c590fa89b": 4,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 3,
|
|
||||||
"5c0d591486f7744c505b416f": 5,
|
|
||||||
"5d6e6891a4b9361bd473feea": 2,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 6,
|
|
||||||
"5d6e689ca4b9361bc8618956": 8,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 8,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 3
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 4,
|
|
||||||
"5d6e6a05a4b93618084f58d0": 5,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 5
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 2,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 4,
|
|
||||||
"5e85aa1a988a8701445df1f5": 4
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 1,
|
|
||||||
"59e6542b86f77411dc52a77a": 2,
|
|
||||||
"59e655cb86f77411dc52a77b": 10,
|
|
||||||
"5f0596629e22f464da6bbdd9": 8
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 2,
|
|
||||||
"5ba26844d4351e00334c9475": 4,
|
|
||||||
"5ba2678ad4351e44f824b344": 15,
|
|
||||||
"64b6979341772715af0f9c39": 15,
|
|
||||||
"5ba26835d4351e0035628ff5": 8
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff3afd2720bba668b4567": 6,
|
|
||||||
"56dff2ced2720bb4668b4567": 12,
|
|
||||||
"56dff061d2720bb5668b4567": 20,
|
|
||||||
"61962b617c6c7b169525f168": 12,
|
|
||||||
"56dfef82d2720bbd668b4567": 9,
|
|
||||||
"56dff026d2720bb8668b4567": 8,
|
|
||||||
"5c0d5e4486f77478390952fe": 4
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"5c0d5ae286f7741e46554302": 1,
|
|
||||||
"54527a984bdc2d4e668b4567": 7,
|
|
||||||
"60194943740c5d77f6705eea": 20,
|
|
||||||
"59e6906286f7746c9f75e847": 26,
|
|
||||||
"54527ac44bdc2d36668b4567": 30,
|
|
||||||
"59e690b686f7746c9f75e848": 7,
|
|
||||||
"601949593ae8f707c4608daa": 5
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f8fe4a949033b0224a2": 5,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 21,
|
|
||||||
"5cc80f67e4a949035e43bbba": 15,
|
|
||||||
"5cc80f38e4a949001152b560": 12
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 10,
|
|
||||||
"6529243824cbe3c74a05e5c1": 5
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"5736026a245977644601dc61": 5,
|
|
||||||
"573603c924597764442bd9cb": 10,
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 7,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 6,
|
|
||||||
"619636be6db0f2477964e710": 23,
|
|
||||||
"64b8725c4b75259c590fa899": 20,
|
|
||||||
"5fd20ff893a8961fc660a954": 9
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4cf5286f7741778269d8a": 4,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 28,
|
|
||||||
"64b7af434b75259c590fa893": 33,
|
|
||||||
"59e0d99486f7744a32234762": 20,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 12
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e53d4353e3302577c4c": 6,
|
|
||||||
"58dd3ad986f77403051cba8f": 27,
|
|
||||||
"5a608bf24f39f98ffc77720e": 19,
|
|
||||||
"5a6086ea4f39f99cd479502f": 9,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 2
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5e023cf8186a883be655e54f": 3,
|
|
||||||
"5887431f2459777e1612938f": 20,
|
|
||||||
"59e77a2386f7742ee578960a": 25,
|
|
||||||
"5e023d34e8a400319a28ed44": 22,
|
|
||||||
"560d61e84bdc2da74d8b4571": 15,
|
|
||||||
"5e023d48186a883be655e551": 10
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 5,
|
|
||||||
"5fc382c1016cce60e8341b20": 8,
|
|
||||||
"5fc275cf85fd526b824a571a": 8,
|
|
||||||
"5fc382a9d724d907e2077dab": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"57371e4124597760ff7b25f1": 3,
|
|
||||||
"5737201124597760fc4431f1": 5,
|
|
||||||
"573720e02459776143012541": 12,
|
|
||||||
"573718ba2459775a75491131": 18,
|
|
||||||
"57371aab2459775a77142f22": 12,
|
|
||||||
"573719df2459775a626ccbc2": 10
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 9,
|
|
||||||
"5efb0e16aeb21837e749c7ff": 5,
|
|
||||||
"5a3c16fe86f77452b62de32a": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 18,
|
|
||||||
"5c925fa22e221601da359b7b": 22,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 9
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a269f97c4a282000b151807": 8,
|
|
||||||
"6576f93989f0062e741ba952": 18,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 18,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 8
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c18744e5e31df12f516": 9,
|
|
||||||
"62330b3ed4dc74626d570b95": 6
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 9,
|
|
||||||
"61962d879bb3d20b0946d385": 25,
|
|
||||||
"57a0e5022459774d1673f889": 25,
|
|
||||||
"5c0d688c86f77413ae3407b2": 12
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 3,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 30,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 25,
|
|
||||||
"668fe62ac62660a5d8071446": 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,411 +0,0 @@
|
||||||
{
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 5,
|
|
||||||
"66546f823b51a4d21e0d17d7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 5,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 5,
|
|
||||||
"66546f823b51a4d21e0d17d7": 1,
|
|
||||||
"5d1f565786f7743f8362bcd5": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 5,
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"springEarly": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 2,
|
|
||||||
"5e9da17386f774054b6f79a3": 2,
|
|
||||||
"5e4bb35286f77406a511c9bc": 2,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5d1f590486f7744bcd13459e": 3,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1,
|
|
||||||
"642e8ae07e17c882400c4f87": 2,
|
|
||||||
"5d1f568486f7744bca3f0b98": 2,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 2,
|
|
||||||
"5e4bb31586f7740695730568": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1,
|
|
||||||
"66acebd4ede86671bb09584b": 3,
|
|
||||||
"5d1f58ab86f7743014162042": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spring": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"summer": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"642c18b8a6a0660b560fb31c": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f593286f7743014162044": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autumn": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"637b945722e2a933ed0e33c8": 1,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 1,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5f5e40a06760b4138443b341": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"6377266693a3b4967208e42b": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"6430119aac11c9eaf10d881b": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"642ed40af5bdf1c04e01952e": 1,
|
|
||||||
"6295e63de08ed747e64ae991": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"66043d7ac8949a435906e434": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"winter": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 1,
|
|
||||||
"5e9da17386f774054b6f79a3": 1,
|
|
||||||
"5e4bb35286f77406a511c9bc": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f590486f7744bcd13459e": 1,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"642e8ae07e17c882400c4f87": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 1,
|
|
||||||
"5e4bb31586f7740695730568": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"66acebd4ede86671bb09584b": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,476 +0,0 @@
|
||||||
{
|
|
||||||
"scavAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 3
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 1
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6772a4b936088465b17c": 2,
|
|
||||||
"5d6e6806a4b936088465b17e": 2,
|
|
||||||
"5d6e67fba4b9361bc73bc779": 2,
|
|
||||||
"560d5e524bdc2d25448b4571": 2,
|
|
||||||
"5d6e6869a4b9361c140bcfde": 1,
|
|
||||||
"5d6e68b3a4b9361bca7e50b5": 1,
|
|
||||||
"58820d1224597753c90aeb13": 1,
|
|
||||||
"5d6e68dea4b9361bcc29e659": 1,
|
|
||||||
"5d6e6891a4b9361bd473feea": 1,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 1,
|
|
||||||
"5d6e689ca4b9361bc8618956": 1
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e695fa4b936359b35d852": 2,
|
|
||||||
"5d6e69b9a4b9361bc8618958": 2,
|
|
||||||
"5a38ebd9c4a282000d722a5b": 2,
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 1
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 3,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 1
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 3,
|
|
||||||
"59e6542b86f77411dc52a77a": 1
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 3,
|
|
||||||
"5ba26844d4351e00334c9475": 1
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff216d2720bbd668b4568": 1,
|
|
||||||
"56dff338d2720bbd668b4569": 4,
|
|
||||||
"56dff421d2720b5f5a8b4567": 4,
|
|
||||||
"56dff4ecd2720b5f5a8b4568": 2,
|
|
||||||
"56dff4a2d2720bbd668b456a": 4,
|
|
||||||
"56dff0bed2720bb0668b4567": 3,
|
|
||||||
"56dff3afd2720bba668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"59e6927d86f77411da468256": 2,
|
|
||||||
"59e6918f86f7746c9f75e849": 2,
|
|
||||||
"59e68f6f86f7746c9f75e846": 4,
|
|
||||||
"59e6920f86f77411d82aa167": 5,
|
|
||||||
"54527a984bdc2d4e668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc86832d7f00c000d3a6e6c": 2,
|
|
||||||
"5cc80f79e4a949033c7343b2": 3,
|
|
||||||
"5cc86840d7f00c002412c56c": 3,
|
|
||||||
"5cc80f8fe4a949033b0224a2": 1,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 1
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 1
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573602322459776445391df1": 2,
|
|
||||||
"573601b42459776410737435": 2,
|
|
||||||
"5735fdcd2459776445391d61": 1,
|
|
||||||
"5736026a245977644601dc61": 1
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 1,
|
|
||||||
"6196364158ef8c428c287d9f": 6,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 3
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4d3d286f774176a36250a": 2,
|
|
||||||
"64b7af734b75259c590fa895": 2,
|
|
||||||
"64b7af5a8532cf95ee0a0dbd": 6,
|
|
||||||
"59e4d24686f7741776641ac7": 4,
|
|
||||||
"59e4cf5286f7741778269d8a": 2,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 1
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e88277cce2b522ff2b1": 2,
|
|
||||||
"5e023e6e34d52a55c3304f71": 2,
|
|
||||||
"5e023e53d4353e3302577c4c": 1
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"64b8f7c241772715af0f9c3d": 2,
|
|
||||||
"64b8f7b5389d7ffd620ccba2": 2,
|
|
||||||
"64b8f7968532cf95ee0a0dbf": 2,
|
|
||||||
"5e023cf8186a883be655e54f": 2,
|
|
||||||
"5887431f2459777e1612938f": 1
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 2,
|
|
||||||
"5fc382c1016cce60e8341b20": 1
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"5737218f245977612125ba51": 5,
|
|
||||||
"57372140245977611f70ee91": 5,
|
|
||||||
"5737207f24597760ff7b25f2": 2,
|
|
||||||
"573719762459775a626ccbc1": 3,
|
|
||||||
"57371f8d24597761006c6a81": 3,
|
|
||||||
"57371f2b24597761224311f1": 5,
|
|
||||||
"57371eb62459776125652ac1": 1,
|
|
||||||
"57371b192459775a9f58a5e0": 1,
|
|
||||||
"57371e4124597760ff7b25f1": 1
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5efb0e16aeb21837e749c7ff": 1,
|
|
||||||
"58864a4f2459770fcc257101": 7,
|
|
||||||
"5a3c16fe86f77452b62de32a": 12,
|
|
||||||
"5c3df7d588a4501f290594e5": 6,
|
|
||||||
"64b7bbb74b75259c590fa897": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 2
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a26ac06c4a282000c5a90a8": 5,
|
|
||||||
"5a26abfac4a28232980eabff": 3,
|
|
||||||
"5a269f97c4a282000b151807": 1
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c40bdd19b369e1e53d1": 5,
|
|
||||||
"62330bfadc5883093563729b": 3,
|
|
||||||
"62330c18744e5e31df12f516": 1
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"6576f96220d53a5b8f3e395e": 7,
|
|
||||||
"57a0dfb82459774d3078b56c": 5,
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 1
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 10,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 1,
|
|
||||||
"5efb0fc6aeb21837e749c801": 8,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 40,
|
|
||||||
"5e81f423763d9f754677bf2e": 25
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 45
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 10,
|
|
||||||
"5c0d591486f7744c505b416f": 3,
|
|
||||||
"5d6e68d1a4b93622fe60e845": 3,
|
|
||||||
"5d6e6869a4b9361c140bcfde": 2,
|
|
||||||
"5d6e68b3a4b9361bca7e50b5": 2,
|
|
||||||
"58820d1224597753c90aeb13": 2,
|
|
||||||
"5d6e68dea4b9361bcc29e659": 2,
|
|
||||||
"5d6e6891a4b9361bd473feea": 9,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 15,
|
|
||||||
"5d6e689ca4b9361bc8618956": 9
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e695fa4b936359b35d852": 3,
|
|
||||||
"5d6e69b9a4b9361bc8618958": 3,
|
|
||||||
"5a38ebd9c4a282000d722a5b": 5,
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 10,
|
|
||||||
|
|
||||||
"5d6e6a5fa4b93614ec501745": 3,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 3
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 8,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 2
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 12,
|
|
||||||
"59e6542b86f77411dc52a77a": 35,
|
|
||||||
"59e655cb86f77411dc52a77b": 20
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 40,
|
|
||||||
"5ba26844d4351e00334c9475": 60
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff338d2720bbd668b4569": 5,
|
|
||||||
"56dff4a2d2720bbd668b456a": 7,
|
|
||||||
"56dff0bed2720bb0668b4567": 10,
|
|
||||||
"56dff3afd2720bba668b4567": 60,
|
|
||||||
"56dff2ced2720bb4668b4567": 5,
|
|
||||||
"56dff061d2720bb5668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"59e6918f86f7746c9f75e849": 10,
|
|
||||||
"59e68f6f86f7746c9f75e846": 40,
|
|
||||||
"59e6920f86f77411d82aa167": 50,
|
|
||||||
"54527a984bdc2d4e668b4567": 30,
|
|
||||||
"60194943740c5d77f6705eea": 10,
|
|
||||||
"59e6906286f7746c9f75e847": 5
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc86832d7f00c000d3a6e6c": 4,
|
|
||||||
"5cc80f79e4a949033c7343b2": 11,
|
|
||||||
"5cc86840d7f00c002412c56c": 21,
|
|
||||||
"5cc80f8fe4a949033b0224a2": 21,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 12,
|
|
||||||
"5cc80f67e4a949035e43bbba": 4
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 1
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573601b42459776410737435": 8,
|
|
||||||
"5735fdcd2459776445391d61": 12,
|
|
||||||
"5736026a245977644601dc61": 18,
|
|
||||||
"573603c924597764442bd9cb": 13,
|
|
||||||
"573603562459776430731618": 3
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 9,
|
|
||||||
"6196364158ef8c428c287d9f": 18,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 18
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"64b7af5a8532cf95ee0a0dbd": 5,
|
|
||||||
"59e4d24686f7741776641ac7": 15,
|
|
||||||
"59e4cf5286f7741778269d8a": 40,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 45,
|
|
||||||
"64b7af434b75259c590fa893": 10
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e88277cce2b522ff2b1": 10,
|
|
||||||
"5e023e6e34d52a55c3304f71": 30,
|
|
||||||
"5e023e53d4353e3302577c4c": 50,
|
|
||||||
"58dd3ad986f77403051cba8f": 10
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"64b8f7b5389d7ffd620ccba2": 5,
|
|
||||||
"64b8f7968532cf95ee0a0dbf": 9,
|
|
||||||
"5e023cf8186a883be655e54f": 16,
|
|
||||||
"5887431f2459777e1612938f": 22,
|
|
||||||
"59e77a2386f7742ee578960a": 10
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 90,
|
|
||||||
"5fc382c1016cce60e8341b20": 5,
|
|
||||||
"5fc275cf85fd526b824a571a": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"57371f8d24597761006c6a81": 3,
|
|
||||||
"57371f2b24597761224311f1": 3,
|
|
||||||
"57371eb62459776125652ac1": 3,
|
|
||||||
"57371b192459775a9f58a5e0": 9,
|
|
||||||
"57371e4124597760ff7b25f1": 13,
|
|
||||||
"5737201124597760fc4431f1": 21,
|
|
||||||
"573720e02459776143012541": 14,
|
|
||||||
"573718ba2459775a75491131": 8
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5efb0e16aeb21837e749c7ff": 7,
|
|
||||||
"58864a4f2459770fcc257101": 1,
|
|
||||||
"5a3c16fe86f77452b62de32a": 15,
|
|
||||||
"5c3df7d588a4501f290594e5": 20,
|
|
||||||
"64b7bbb74b75259c590fa897": 30,
|
|
||||||
"56d59d3ad2720bdb418b4577": 55
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a26ac06c4a282000c5a90a8": 1,
|
|
||||||
"5a26abfac4a28232980eabff": 20,
|
|
||||||
"5a269f97c4a282000b151807": 27
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c40bdd19b369e1e53d1": 7,
|
|
||||||
"62330bfadc5883093563729b": 8,
|
|
||||||
"62330c18744e5e31df12f516": 4
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"6576f96220d53a5b8f3e395e": 10,
|
|
||||||
"57a0dfb82459774d3078b56c": 50,
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 40
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 30,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 50
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bossAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 4,
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 10,
|
|
||||||
"5e81f423763d9f754677bf2e": 18,
|
|
||||||
"5efb0cabfb3e451d70735af5": 10
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 3,
|
|
||||||
"5cadf6ddae9215051e1c23b2": 12,
|
|
||||||
"5cadf6eeae921500134b2799": 8
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 7,
|
|
||||||
"64b8ee384b75259c590fa89b": 4,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 3,
|
|
||||||
"5c0d591486f7744c505b416f": 5,
|
|
||||||
"5d6e6891a4b9361bd473feea": 2,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 6,
|
|
||||||
"5d6e689ca4b9361bc8618956": 8,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 8,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 3
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 4,
|
|
||||||
"5d6e6a05a4b93618084f58d0": 5,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 5
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 2,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 4,
|
|
||||||
"5e85aa1a988a8701445df1f5": 4
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 1,
|
|
||||||
"59e6542b86f77411dc52a77a": 2,
|
|
||||||
"59e655cb86f77411dc52a77b": 10,
|
|
||||||
"5f0596629e22f464da6bbdd9": 8
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 2,
|
|
||||||
"5ba26844d4351e00334c9475": 4,
|
|
||||||
"5ba2678ad4351e44f824b344": 15,
|
|
||||||
"64b6979341772715af0f9c39": 15,
|
|
||||||
"5ba26835d4351e0035628ff5": 8
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff3afd2720bba668b4567": 6,
|
|
||||||
"56dff2ced2720bb4668b4567": 12,
|
|
||||||
"56dff061d2720bb5668b4567": 20,
|
|
||||||
"61962b617c6c7b169525f168": 12,
|
|
||||||
"56dfef82d2720bbd668b4567": 9,
|
|
||||||
"56dff026d2720bb8668b4567": 8,
|
|
||||||
"5c0d5e4486f77478390952fe": 4
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"5c0d5ae286f7741e46554302": 1,
|
|
||||||
"54527a984bdc2d4e668b4567": 7,
|
|
||||||
"60194943740c5d77f6705eea": 20,
|
|
||||||
"59e6906286f7746c9f75e847": 26,
|
|
||||||
"54527ac44bdc2d36668b4567": 30,
|
|
||||||
"59e690b686f7746c9f75e848": 7,
|
|
||||||
"601949593ae8f707c4608daa": 5
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f8fe4a949033b0224a2": 5,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 21,
|
|
||||||
"5cc80f67e4a949035e43bbba": 15,
|
|
||||||
"5cc80f38e4a949001152b560": 12
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 10,
|
|
||||||
"6529243824cbe3c74a05e5c1": 5
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"5736026a245977644601dc61": 5,
|
|
||||||
"573603c924597764442bd9cb": 10,
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 7,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 6,
|
|
||||||
"619636be6db0f2477964e710": 23,
|
|
||||||
"64b8725c4b75259c590fa899": 20,
|
|
||||||
"5fd20ff893a8961fc660a954": 9
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4cf5286f7741778269d8a": 4,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 28,
|
|
||||||
"64b7af434b75259c590fa893": 33,
|
|
||||||
"59e0d99486f7744a32234762": 20,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 12
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e53d4353e3302577c4c": 6,
|
|
||||||
"58dd3ad986f77403051cba8f": 27,
|
|
||||||
"5a608bf24f39f98ffc77720e": 19,
|
|
||||||
"5a6086ea4f39f99cd479502f": 9,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 2
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5e023cf8186a883be655e54f": 3,
|
|
||||||
"5887431f2459777e1612938f": 20,
|
|
||||||
"59e77a2386f7742ee578960a": 25,
|
|
||||||
"5e023d34e8a400319a28ed44": 22,
|
|
||||||
"560d61e84bdc2da74d8b4571": 15,
|
|
||||||
"5e023d48186a883be655e551": 10
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 5,
|
|
||||||
"5fc382c1016cce60e8341b20": 8,
|
|
||||||
"5fc275cf85fd526b824a571a": 8,
|
|
||||||
"5fc382a9d724d907e2077dab": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"57371e4124597760ff7b25f1": 3,
|
|
||||||
"5737201124597760fc4431f1": 5,
|
|
||||||
"573720e02459776143012541": 12,
|
|
||||||
"573718ba2459775a75491131": 18,
|
|
||||||
"57371aab2459775a77142f22": 12,
|
|
||||||
"573719df2459775a626ccbc2": 10
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 9,
|
|
||||||
"5efb0e16aeb21837e749c7ff": 5,
|
|
||||||
"5a3c16fe86f77452b62de32a": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 18,
|
|
||||||
"5c925fa22e221601da359b7b": 22,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 9
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a269f97c4a282000b151807": 8,
|
|
||||||
"6576f93989f0062e741ba952": 18,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 18,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 8
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c18744e5e31df12f516": 9,
|
|
||||||
"62330b3ed4dc74626d570b95": 6
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 9,
|
|
||||||
"61962d879bb3d20b0946d385": 25,
|
|
||||||
"57a0e5022459774d1673f889": 25,
|
|
||||||
"5c0d688c86f77413ae3407b2": 12
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 3,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 30,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 25,
|
|
||||||
"668fe62ac62660a5d8071446": 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,430 +0,0 @@
|
||||||
{
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 5,
|
|
||||||
"66546f823b51a4d21e0d17d7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 2,
|
|
||||||
"5d1f56c686f7744bcd13459c": 3,
|
|
||||||
"637b945722e2a933ed0e33c8": 3,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 3,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 3,
|
|
||||||
"642d9bbf6c06444bf7033855": 3
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 5,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 2,
|
|
||||||
"5d1f590486f7744bcd13459e": 3,
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 3,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 5,
|
|
||||||
"66546f823b51a4d21e0d17d7": 1,
|
|
||||||
"5d1f565786f7743f8362bcd5": 2,
|
|
||||||
"5fce3e0cfe40296c1d5fd782": 3,
|
|
||||||
"6377266693a3b4967208e42b": 3,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 3,
|
|
||||||
"6295e698e9de5e7b3751c47a": 3,
|
|
||||||
"642e8ae07e17c882400c4f87": 3,
|
|
||||||
"5d1f568486f7744bca3f0b98": 3
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 5,
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 2,
|
|
||||||
"6377315993a3b4967208e437": 3,
|
|
||||||
"5d1f588e86f7744bcc048753": 3,
|
|
||||||
"65707a89f5a6f1412f0c5f7b": 3,
|
|
||||||
"642ed40af5bdf1c04e01952e": 3,
|
|
||||||
"5fce3e965a9f8c40685693bc": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"springEarly": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 2,
|
|
||||||
"5e9da17386f774054b6f79a3": 2,
|
|
||||||
"5e4bb35286f77406a511c9bc": 2,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5d1f590486f7744bcd13459e": 3,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1,
|
|
||||||
"642e8ae07e17c882400c4f87": 2,
|
|
||||||
"5d1f568486f7744bca3f0b98": 2,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 2,
|
|
||||||
"5e4bb31586f7740695730568": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1,
|
|
||||||
"66acebd4ede86671bb09584b": 3,
|
|
||||||
"5d1f58ab86f7743014162042": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spring": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"summer": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"642c18b8a6a0660b560fb31c": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f593286f7743014162044": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autumn": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"637b945722e2a933ed0e33c8": 1,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 1,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5f5e40a06760b4138443b341": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"6377266693a3b4967208e42b": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"6430119aac11c9eaf10d881b": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"642ed40af5bdf1c04e01952e": 1,
|
|
||||||
"6295e63de08ed747e64ae991": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"66043d7ac8949a435906e434": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"winter": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 1,
|
|
||||||
"5e9da17386f774054b6f79a3": 1,
|
|
||||||
"5e4bb35286f77406a511c9bc": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f590486f7744bcd13459e": 1,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"642e8ae07e17c882400c4f87": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 1,
|
|
||||||
"5e4bb31586f7740695730568": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"66acebd4ede86671bb09584b": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,464 +0,0 @@
|
||||||
{
|
|
||||||
"scavAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 3
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 1
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6772a4b936088465b17c": 2,
|
|
||||||
"5d6e6806a4b936088465b17e": 2,
|
|
||||||
"5d6e67fba4b9361bc73bc779": 2,
|
|
||||||
"560d5e524bdc2d25448b4571": 2,
|
|
||||||
"5d6e6869a4b9361c140bcfde": 1,
|
|
||||||
"5d6e68b3a4b9361bca7e50b5": 1,
|
|
||||||
"58820d1224597753c90aeb13": 1,
|
|
||||||
"5d6e68dea4b9361bcc29e659": 1,
|
|
||||||
"5d6e6891a4b9361bd473feea": 1,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 1,
|
|
||||||
"5d6e689ca4b9361bc8618956": 1
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e695fa4b936359b35d852": 2,
|
|
||||||
"5d6e69b9a4b9361bc8618958": 2,
|
|
||||||
"5a38ebd9c4a282000d722a5b": 2,
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 1
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 3,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 1
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 3,
|
|
||||||
"59e6542b86f77411dc52a77a": 1
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 3,
|
|
||||||
"5ba26844d4351e00334c9475": 1
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff216d2720bbd668b4568": 1,
|
|
||||||
"56dff338d2720bbd668b4569": 4,
|
|
||||||
"56dff421d2720b5f5a8b4567": 4,
|
|
||||||
"56dff4ecd2720b5f5a8b4568": 2,
|
|
||||||
"56dff4a2d2720bbd668b456a": 4,
|
|
||||||
"56dff0bed2720bb0668b4567": 3,
|
|
||||||
"56dff3afd2720bba668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"59e6927d86f77411da468256": 2,
|
|
||||||
"59e6918f86f7746c9f75e849": 2,
|
|
||||||
"59e68f6f86f7746c9f75e846": 4,
|
|
||||||
"59e6920f86f77411d82aa167": 5,
|
|
||||||
"54527a984bdc2d4e668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc86832d7f00c000d3a6e6c": 2,
|
|
||||||
"5cc80f79e4a949033c7343b2": 3,
|
|
||||||
"5cc86840d7f00c002412c56c": 3,
|
|
||||||
"5cc80f8fe4a949033b0224a2": 1,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 1
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 1
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573602322459776445391df1": 2,
|
|
||||||
"573601b42459776410737435": 2,
|
|
||||||
"5735fdcd2459776445391d61": 1,
|
|
||||||
"5736026a245977644601dc61": 1
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 1,
|
|
||||||
"6196364158ef8c428c287d9f": 6,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 3
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4d3d286f774176a36250a": 2,
|
|
||||||
"64b7af734b75259c590fa895": 2,
|
|
||||||
"64b7af5a8532cf95ee0a0dbd": 6,
|
|
||||||
"59e4d24686f7741776641ac7": 4,
|
|
||||||
"59e4cf5286f7741778269d8a": 2,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 1
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e88277cce2b522ff2b1": 2,
|
|
||||||
"5e023e6e34d52a55c3304f71": 2,
|
|
||||||
"5e023e53d4353e3302577c4c": 1
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"64b8f7c241772715af0f9c3d": 2,
|
|
||||||
"64b8f7b5389d7ffd620ccba2": 2,
|
|
||||||
"64b8f7968532cf95ee0a0dbf": 2,
|
|
||||||
"5e023cf8186a883be655e54f": 2,
|
|
||||||
"5887431f2459777e1612938f": 1
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 2,
|
|
||||||
"5fc382c1016cce60e8341b20": 1
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"5737218f245977612125ba51": 5,
|
|
||||||
"57372140245977611f70ee91": 5,
|
|
||||||
"5737207f24597760ff7b25f2": 2,
|
|
||||||
"573719762459775a626ccbc1": 3,
|
|
||||||
"57371f8d24597761006c6a81": 3,
|
|
||||||
"57371f2b24597761224311f1": 5,
|
|
||||||
"57371eb62459776125652ac1": 1,
|
|
||||||
"57371b192459775a9f58a5e0": 1,
|
|
||||||
"57371e4124597760ff7b25f1": 1
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5efb0e16aeb21837e749c7ff": 1,
|
|
||||||
"58864a4f2459770fcc257101": 7,
|
|
||||||
"5a3c16fe86f77452b62de32a": 12,
|
|
||||||
"5c3df7d588a4501f290594e5": 6,
|
|
||||||
"64b7bbb74b75259c590fa897": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 2
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a26ac06c4a282000c5a90a8": 5,
|
|
||||||
"5a26abfac4a28232980eabff": 3,
|
|
||||||
"5a269f97c4a282000b151807": 1
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c40bdd19b369e1e53d1": 5,
|
|
||||||
"62330bfadc5883093563729b": 3,
|
|
||||||
"62330c18744e5e31df12f516": 1
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"6576f96220d53a5b8f3e395e": 7,
|
|
||||||
"57a0dfb82459774d3078b56c": 5,
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 1
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 10,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 10,
|
|
||||||
"5efb0fc6aeb21837e749c801": 5,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 30,
|
|
||||||
"5e81f423763d9f754677bf2e": 50,
|
|
||||||
"5efb0cabfb3e451d70735af5": 10
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 80,
|
|
||||||
"5cadf6ddae9215051e1c23b2": 20
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 15,
|
|
||||||
"64b8ee384b75259c590fa89b": 6,
|
|
||||||
"5c0d591486f7744c505b416f": 5,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 15,
|
|
||||||
"5d6e689ca4b9361bc8618956": 13,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 9
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 8,
|
|
||||||
"5d6e6a5fa4b93614ec501745": 6,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 6,
|
|
||||||
"5d6e6a05a4b93618084f58d0": 3,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 2
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 60,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 30,
|
|
||||||
"5e85aa1a988a8701445df1f5": 10
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6542b86f77411dc52a77a": 5,
|
|
||||||
"59e655cb86f77411dc52a77b": 65,
|
|
||||||
"5f0596629e22f464da6bbdd9": 30
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26844d4351e00334c9475": 70,
|
|
||||||
"64b6979341772715af0f9c39": 15,
|
|
||||||
"5ba2678ad4351e44f824b344": 10,
|
|
||||||
"5ba26835d4351e0035628ff5": 5
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff0bed2720bb0668b4567": 5,
|
|
||||||
"56dff3afd2720bba668b4567": 40,
|
|
||||||
"56dff2ced2720bb4668b4567": 30,
|
|
||||||
"56dff061d2720bb5668b4567": 15,
|
|
||||||
"61962b617c6c7b169525f168": 5,
|
|
||||||
"56dfef82d2720bbd668b4567": 5
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"5c0d5ae286f7741e46554302": 5,
|
|
||||||
"59e6920f86f77411d82aa167": 10,
|
|
||||||
"54527a984bdc2d4e668b4567": 50,
|
|
||||||
"60194943740c5d77f6705eea": 30,
|
|
||||||
"59e6906286f7746c9f75e847": 10,
|
|
||||||
"54527ac44bdc2d36668b4567": 5
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc86840d7f00c002412c56c": 10,
|
|
||||||
"5cc80f8fe4a949033b0224a2": 15,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 28,
|
|
||||||
"5cc80f67e4a949035e43bbba": 7
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 1
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"5736026a245977644601dc61": 5,
|
|
||||||
"573603c924597764442bd9cb": 10,
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 5,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 55,
|
|
||||||
"619636be6db0f2477964e710": 30,
|
|
||||||
"64b8725c4b75259c590fa899": 10
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"5656d7c34bdc2d9d198b4587": 60,
|
|
||||||
"64b7af434b75259c590fa893": 35,
|
|
||||||
"59e0d99486f7744a32234762": 5
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e53d4353e3302577c4c": 60,
|
|
||||||
"58dd3ad986f77403051cba8f": 35,
|
|
||||||
"5a608bf24f39f98ffc77720e": 5
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5887431f2459777e1612938f": 50,
|
|
||||||
"59e77a2386f7742ee578960a": 25,
|
|
||||||
"5e023d34e8a400319a28ed44": 5
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 75,
|
|
||||||
"5fc382c1016cce60e8341b20": 20,
|
|
||||||
"5fc275cf85fd526b824a571a": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"5737201124597760fc4431f1": 35,
|
|
||||||
"573720e02459776143012541": 25,
|
|
||||||
"573718ba2459775a75491131": 25,
|
|
||||||
"57371aab2459775a77142f22": 10
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 5,
|
|
||||||
"5efb0e16aeb21837e749c7ff": 25,
|
|
||||||
"56d59d3ad2720bdb418b4577": 65,
|
|
||||||
"5c925fa22e221601da359b7b": 5
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a26abfac4a28232980eabff": 12,
|
|
||||||
"5a269f97c4a282000b151807": 30,
|
|
||||||
"6576f93989f0062e741ba952": 12,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 8
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330bfadc5883093563729b": 8,
|
|
||||||
"62330c18744e5e31df12f516": 8,
|
|
||||||
"62330b3ed4dc74626d570b95": 2
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"57a0dfb82459774d3078b56c": 25,
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 60,
|
|
||||||
"61962d879bb3d20b0946d385": 10,
|
|
||||||
"57a0e5022459774d1673f889": 5
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 30,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 60,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bossAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 4,
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 10,
|
|
||||||
"5e81f423763d9f754677bf2e": 18,
|
|
||||||
"5efb0cabfb3e451d70735af5": 10
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 3,
|
|
||||||
"5cadf6ddae9215051e1c23b2": 12,
|
|
||||||
"5cadf6eeae921500134b2799": 8
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 7,
|
|
||||||
"64b8ee384b75259c590fa89b": 4,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 3,
|
|
||||||
"5c0d591486f7744c505b416f": 5,
|
|
||||||
"5d6e6891a4b9361bd473feea": 2,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 6,
|
|
||||||
"5d6e689ca4b9361bc8618956": 8,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 8,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 3
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 4,
|
|
||||||
"5d6e6a05a4b93618084f58d0": 5,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 5
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 2,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 4,
|
|
||||||
"5e85aa1a988a8701445df1f5": 4
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 1,
|
|
||||||
"59e6542b86f77411dc52a77a": 2,
|
|
||||||
"59e655cb86f77411dc52a77b": 10,
|
|
||||||
"5f0596629e22f464da6bbdd9": 8
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 2,
|
|
||||||
"5ba26844d4351e00334c9475": 4,
|
|
||||||
"5ba2678ad4351e44f824b344": 15,
|
|
||||||
"64b6979341772715af0f9c39": 15,
|
|
||||||
"5ba26835d4351e0035628ff5": 8
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff3afd2720bba668b4567": 6,
|
|
||||||
"56dff2ced2720bb4668b4567": 12,
|
|
||||||
"56dff061d2720bb5668b4567": 20,
|
|
||||||
"61962b617c6c7b169525f168": 12,
|
|
||||||
"56dfef82d2720bbd668b4567": 9,
|
|
||||||
"56dff026d2720bb8668b4567": 8,
|
|
||||||
"5c0d5e4486f77478390952fe": 4
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"5c0d5ae286f7741e46554302": 1,
|
|
||||||
"54527a984bdc2d4e668b4567": 7,
|
|
||||||
"60194943740c5d77f6705eea": 20,
|
|
||||||
"59e6906286f7746c9f75e847": 26,
|
|
||||||
"54527ac44bdc2d36668b4567": 30,
|
|
||||||
"59e690b686f7746c9f75e848": 7,
|
|
||||||
"601949593ae8f707c4608daa": 5
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f8fe4a949033b0224a2": 5,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 21,
|
|
||||||
"5cc80f67e4a949035e43bbba": 15,
|
|
||||||
"5cc80f38e4a949001152b560": 12
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 10,
|
|
||||||
"6529243824cbe3c74a05e5c1": 5
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"5736026a245977644601dc61": 5,
|
|
||||||
"573603c924597764442bd9cb": 10,
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 7,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 6,
|
|
||||||
"619636be6db0f2477964e710": 23,
|
|
||||||
"64b8725c4b75259c590fa899": 20,
|
|
||||||
"5fd20ff893a8961fc660a954": 9
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4cf5286f7741778269d8a": 4,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 28,
|
|
||||||
"64b7af434b75259c590fa893": 33,
|
|
||||||
"59e0d99486f7744a32234762": 20,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 12
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e53d4353e3302577c4c": 6,
|
|
||||||
"58dd3ad986f77403051cba8f": 27,
|
|
||||||
"5a608bf24f39f98ffc77720e": 19,
|
|
||||||
"5a6086ea4f39f99cd479502f": 9,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 2
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5e023cf8186a883be655e54f": 3,
|
|
||||||
"5887431f2459777e1612938f": 20,
|
|
||||||
"59e77a2386f7742ee578960a": 25,
|
|
||||||
"5e023d34e8a400319a28ed44": 22,
|
|
||||||
"560d61e84bdc2da74d8b4571": 15,
|
|
||||||
"5e023d48186a883be655e551": 10
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 5,
|
|
||||||
"5fc382c1016cce60e8341b20": 8,
|
|
||||||
"5fc275cf85fd526b824a571a": 8,
|
|
||||||
"5fc382a9d724d907e2077dab": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"57371e4124597760ff7b25f1": 3,
|
|
||||||
"5737201124597760fc4431f1": 5,
|
|
||||||
"573720e02459776143012541": 12,
|
|
||||||
"573718ba2459775a75491131": 18,
|
|
||||||
"57371aab2459775a77142f22": 12,
|
|
||||||
"573719df2459775a626ccbc2": 10
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 9,
|
|
||||||
"5efb0e16aeb21837e749c7ff": 5,
|
|
||||||
"5a3c16fe86f77452b62de32a": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 18,
|
|
||||||
"5c925fa22e221601da359b7b": 22,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 9
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a269f97c4a282000b151807": 8,
|
|
||||||
"6576f93989f0062e741ba952": 18,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 18,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 8
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c18744e5e31df12f516": 9,
|
|
||||||
"62330b3ed4dc74626d570b95": 6
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 9,
|
|
||||||
"61962d879bb3d20b0946d385": 25,
|
|
||||||
"57a0e5022459774d1673f889": 25,
|
|
||||||
"5c0d688c86f77413ae3407b2": 12
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 3,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 30,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 25,
|
|
||||||
"668fe62ac62660a5d8071446": 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,457 +0,0 @@
|
||||||
{
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"66546f823b51a4d21e0d17d7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 1,
|
|
||||||
"5d1f56c686f7744bcd13459c": 3,
|
|
||||||
"637b945722e2a933ed0e33c8": 3,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 3,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 3,
|
|
||||||
"642d9bbf6c06444bf7033855": 3,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 5,
|
|
||||||
"66043728333907134309d647": 5,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 5,
|
|
||||||
"6295e8c3e08ed747e64aea00": 5,
|
|
||||||
"642c18b8a6a0660b560fb31c": 5,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 5
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1,
|
|
||||||
"5d1f590486f7744bcd13459e": 3,
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 3,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 3,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 5,
|
|
||||||
"660436487502eca33a08cac8": 5,
|
|
||||||
"6571cad4c8673f00290f5657": 5,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 5,
|
|
||||||
"5d1f591186f7744bcc048755": 5,
|
|
||||||
"6295e944e9de5e7b3751c4da": 5,
|
|
||||||
"642c19360a69698d1b049e12": 5,
|
|
||||||
"66acc8f719271bd6d00dec0b": 5
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"66546f823b51a4d21e0d17d7": 1,
|
|
||||||
"5d1f565786f7743f8362bcd5": 1,
|
|
||||||
"5fce3e0cfe40296c1d5fd782": 3,
|
|
||||||
"6377266693a3b4967208e42b": 3,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 3,
|
|
||||||
"6295e698e9de5e7b3751c47a": 3,
|
|
||||||
"642e8ae07e17c882400c4f87": 3,
|
|
||||||
"5d1f568486f7744bca3f0b98": 3,
|
|
||||||
"657058fddf9b3231400e9188": 5,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 5,
|
|
||||||
"66043cc27502eca33a08cad0": 5,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 5,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 5,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 5
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 3,
|
|
||||||
"5d1f588e86f7744bcc048753": 3,
|
|
||||||
"65707a89f5a6f1412f0c5f7b": 3,
|
|
||||||
"642ed40af5bdf1c04e01952e": 3,
|
|
||||||
"5fce3e965a9f8c40685693bc": 3,
|
|
||||||
"6295e63de08ed747e64ae991": 5,
|
|
||||||
"66043cf87502eca33a08cad2": 5,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 5,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 5,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 5,
|
|
||||||
"642e71620a69698d1b049f0a": 5,
|
|
||||||
"66acebd4ede86671bb09584b": 5
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"springEarly": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 2,
|
|
||||||
"5e9da17386f774054b6f79a3": 2,
|
|
||||||
"5e4bb35286f77406a511c9bc": 2,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5d1f590486f7744bcd13459e": 3,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1,
|
|
||||||
"642e8ae07e17c882400c4f87": 2,
|
|
||||||
"5d1f568486f7744bca3f0b98": 2,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 2,
|
|
||||||
"5e4bb31586f7740695730568": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1,
|
|
||||||
"66acebd4ede86671bb09584b": 3,
|
|
||||||
"5d1f58ab86f7743014162042": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spring": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"summer": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"642c18b8a6a0660b560fb31c": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f593286f7743014162044": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autumn": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"637b945722e2a933ed0e33c8": 1,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 1,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5f5e40a06760b4138443b341": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"6377266693a3b4967208e42b": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"6430119aac11c9eaf10d881b": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"642ed40af5bdf1c04e01952e": 1,
|
|
||||||
"6295e63de08ed747e64ae991": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"66043d7ac8949a435906e434": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"winter": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 1,
|
|
||||||
"5e9da17386f774054b6f79a3": 1,
|
|
||||||
"5e4bb35286f77406a511c9bc": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f590486f7744bcd13459e": 1,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"642e8ae07e17c882400c4f87": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 1,
|
|
||||||
"5e4bb31586f7740695730568": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"66acebd4ede86671bb09584b": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,471 +0,0 @@
|
||||||
{
|
|
||||||
"scavAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 3
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 1
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6772a4b936088465b17c": 2,
|
|
||||||
"5d6e6806a4b936088465b17e": 2,
|
|
||||||
"5d6e67fba4b9361bc73bc779": 2,
|
|
||||||
"560d5e524bdc2d25448b4571": 2,
|
|
||||||
"5d6e6869a4b9361c140bcfde": 1,
|
|
||||||
"5d6e68b3a4b9361bca7e50b5": 1,
|
|
||||||
"58820d1224597753c90aeb13": 1,
|
|
||||||
"5d6e68dea4b9361bcc29e659": 1,
|
|
||||||
"5d6e6891a4b9361bd473feea": 1,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 1,
|
|
||||||
"5d6e689ca4b9361bc8618956": 1
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e695fa4b936359b35d852": 2,
|
|
||||||
"5d6e69b9a4b9361bc8618958": 2,
|
|
||||||
"5a38ebd9c4a282000d722a5b": 2,
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 1
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 3,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 1
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 3,
|
|
||||||
"59e6542b86f77411dc52a77a": 1
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 3,
|
|
||||||
"5ba26844d4351e00334c9475": 1
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff216d2720bbd668b4568": 1,
|
|
||||||
"56dff338d2720bbd668b4569": 4,
|
|
||||||
"56dff421d2720b5f5a8b4567": 4,
|
|
||||||
"56dff4ecd2720b5f5a8b4568": 2,
|
|
||||||
"56dff4a2d2720bbd668b456a": 4,
|
|
||||||
"56dff0bed2720bb0668b4567": 3,
|
|
||||||
"56dff3afd2720bba668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"59e6927d86f77411da468256": 2,
|
|
||||||
"59e6918f86f7746c9f75e849": 2,
|
|
||||||
"59e68f6f86f7746c9f75e846": 4,
|
|
||||||
"59e6920f86f77411d82aa167": 5,
|
|
||||||
"54527a984bdc2d4e668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc86832d7f00c000d3a6e6c": 2,
|
|
||||||
"5cc80f79e4a949033c7343b2": 3,
|
|
||||||
"5cc86840d7f00c002412c56c": 3,
|
|
||||||
"5cc80f8fe4a949033b0224a2": 1,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 1
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 1
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573602322459776445391df1": 2,
|
|
||||||
"573601b42459776410737435": 2,
|
|
||||||
"5735fdcd2459776445391d61": 1,
|
|
||||||
"5736026a245977644601dc61": 1
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 1,
|
|
||||||
"6196364158ef8c428c287d9f": 6,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 3
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4d3d286f774176a36250a": 2,
|
|
||||||
"64b7af734b75259c590fa895": 2,
|
|
||||||
"64b7af5a8532cf95ee0a0dbd": 6,
|
|
||||||
"59e4d24686f7741776641ac7": 4,
|
|
||||||
"59e4cf5286f7741778269d8a": 2,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 1
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e88277cce2b522ff2b1": 2,
|
|
||||||
"5e023e6e34d52a55c3304f71": 2,
|
|
||||||
"5e023e53d4353e3302577c4c": 1
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"64b8f7c241772715af0f9c3d": 2,
|
|
||||||
"64b8f7b5389d7ffd620ccba2": 2,
|
|
||||||
"64b8f7968532cf95ee0a0dbf": 2,
|
|
||||||
"5e023cf8186a883be655e54f": 2,
|
|
||||||
"5887431f2459777e1612938f": 1
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 2,
|
|
||||||
"5fc382c1016cce60e8341b20": 1
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"5737218f245977612125ba51": 5,
|
|
||||||
"57372140245977611f70ee91": 5,
|
|
||||||
"5737207f24597760ff7b25f2": 2,
|
|
||||||
"573719762459775a626ccbc1": 3,
|
|
||||||
"57371f8d24597761006c6a81": 3,
|
|
||||||
"57371f2b24597761224311f1": 5,
|
|
||||||
"57371eb62459776125652ac1": 1,
|
|
||||||
"57371b192459775a9f58a5e0": 1,
|
|
||||||
"57371e4124597760ff7b25f1": 1
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5efb0e16aeb21837e749c7ff": 1,
|
|
||||||
"58864a4f2459770fcc257101": 7,
|
|
||||||
"5a3c16fe86f77452b62de32a": 12,
|
|
||||||
"5c3df7d588a4501f290594e5": 6,
|
|
||||||
"64b7bbb74b75259c590fa897": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 2
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a26ac06c4a282000c5a90a8": 5,
|
|
||||||
"5a26abfac4a28232980eabff": 3,
|
|
||||||
"5a269f97c4a282000b151807": 1
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c40bdd19b369e1e53d1": 5,
|
|
||||||
"62330bfadc5883093563729b": 3,
|
|
||||||
"62330c18744e5e31df12f516": 1
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"6576f96220d53a5b8f3e395e": 7,
|
|
||||||
"57a0dfb82459774d3078b56c": 5,
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 1
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 10,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 20,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 10,
|
|
||||||
"5e81f423763d9f754677bf2e": 30,
|
|
||||||
"5efb0cabfb3e451d70735af5": 20
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 15,
|
|
||||||
"5cadf6ddae9215051e1c23b2": 50,
|
|
||||||
"5cadf6eeae921500134b2799": 35
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 10,
|
|
||||||
"64b8ee384b75259c590fa89b": 20,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 20,
|
|
||||||
"5c0d591486f7744c505b416f": 5,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 5,
|
|
||||||
"5d6e689ca4b9361bc8618956": 5,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 35,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 15
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e6a5fa4b93614ec501745": 15,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 15,
|
|
||||||
"5d6e6a05a4b93618084f58d0": 35,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 35
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 40,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 35,
|
|
||||||
"5e85aa1a988a8701445df1f5": 25
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e655cb86f77411dc52a77b": 40,
|
|
||||||
"5f0596629e22f464da6bbdd9": 60
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26844d4351e00334c9475": 40,
|
|
||||||
"64b6979341772715af0f9c39": 30,
|
|
||||||
"5ba2678ad4351e44f824b344": 20,
|
|
||||||
"5ba26835d4351e0035628ff5": 10
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff2ced2720bb4668b4567": 30,
|
|
||||||
"56dff061d2720bb5668b4567": 50,
|
|
||||||
"61962b617c6c7b169525f168": 10,
|
|
||||||
"56dfef82d2720bbd668b4567": 10,
|
|
||||||
"56dff026d2720bb8668b4567": 5,
|
|
||||||
"5c0d5e4486f77478390952fe": 5
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"5c0d5ae286f7741e46554302": 10,
|
|
||||||
"60194943740c5d77f6705eea": 25,
|
|
||||||
"59e6906286f7746c9f75e847": 25,
|
|
||||||
"54527ac44bdc2d36668b4567": 30,
|
|
||||||
"59e690b686f7746c9f75e848": 5,
|
|
||||||
"601949593ae8f707c4608daa": 5
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 20,
|
|
||||||
"5cc80f67e4a949035e43bbba": 40,
|
|
||||||
"5cc80f38e4a949001152b560": 30
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 80,
|
|
||||||
"6529243824cbe3c74a05e5c1": 20
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573603c924597764442bd9cb": 10,
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 5,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 40,
|
|
||||||
"619636be6db0f2477964e710": 40,
|
|
||||||
"64b8725c4b75259c590fa899": 10,
|
|
||||||
"5fd20ff893a8961fc660a954": 5
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"5656d7c34bdc2d9d198b4587": 25,
|
|
||||||
"64b7af434b75259c590fa893": 50,
|
|
||||||
"59e0d99486f7744a32234762": 20,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 5
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e53d4353e3302577c4c": 20,
|
|
||||||
"58dd3ad986f77403051cba8f": 45,
|
|
||||||
"5a608bf24f39f98ffc77720e": 20,
|
|
||||||
"5a6086ea4f39f99cd479502f": 10,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 5
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5887431f2459777e1612938f": 30,
|
|
||||||
"59e77a2386f7742ee578960a": 45,
|
|
||||||
"5e023d34e8a400319a28ed44": 20,
|
|
||||||
"560d61e84bdc2da74d8b4571": 5
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 20,
|
|
||||||
"5fc382c1016cce60e8341b20": 40,
|
|
||||||
"5fc275cf85fd526b824a571a": 25,
|
|
||||||
"5fc382a9d724d907e2077dab": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"5737201124597760fc4431f1": 15,
|
|
||||||
"573720e02459776143012541": 20,
|
|
||||||
"573718ba2459775a75491131": 30,
|
|
||||||
"57371aab2459775a77142f22": 20,
|
|
||||||
"573719df2459775a626ccbc2": 15
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 10,
|
|
||||||
"5efb0e16aeb21837e749c7ff": 15,
|
|
||||||
"56d59d3ad2720bdb418b4577": 50,
|
|
||||||
"5c925fa22e221601da359b7b": 20,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 5
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a269f97c4a282000b151807": 25,
|
|
||||||
"6576f93989f0062e741ba952": 25,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 12,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 8
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c18744e5e31df12f516": 9,
|
|
||||||
"62330b3ed4dc74626d570b95": 6
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 20,
|
|
||||||
"61962d879bb3d20b0946d385": 50,
|
|
||||||
"57a0e5022459774d1673f889": 25,
|
|
||||||
"5c0d688c86f77413ae3407b2": 5
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 5,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 60,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 30,
|
|
||||||
"668fe62ac62660a5d8071446": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bossAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 4,
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 10,
|
|
||||||
"5e81f423763d9f754677bf2e": 18,
|
|
||||||
"5efb0cabfb3e451d70735af5": 10
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 3,
|
|
||||||
"5cadf6ddae9215051e1c23b2": 12,
|
|
||||||
"5cadf6eeae921500134b2799": 8
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 7,
|
|
||||||
"64b8ee384b75259c590fa89b": 4,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 3,
|
|
||||||
"5c0d591486f7744c505b416f": 5,
|
|
||||||
"5d6e6891a4b9361bd473feea": 2,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 6,
|
|
||||||
"5d6e689ca4b9361bc8618956": 8,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 8,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 3
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 4,
|
|
||||||
"5d6e6a05a4b93618084f58d0": 5,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 5
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 2,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 4,
|
|
||||||
"5e85aa1a988a8701445df1f5": 4
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 1,
|
|
||||||
"59e6542b86f77411dc52a77a": 2,
|
|
||||||
"59e655cb86f77411dc52a77b": 10,
|
|
||||||
"5f0596629e22f464da6bbdd9": 8
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 2,
|
|
||||||
"5ba26844d4351e00334c9475": 4,
|
|
||||||
"5ba2678ad4351e44f824b344": 15,
|
|
||||||
"64b6979341772715af0f9c39": 15,
|
|
||||||
"5ba26835d4351e0035628ff5": 8
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff3afd2720bba668b4567": 6,
|
|
||||||
"56dff2ced2720bb4668b4567": 12,
|
|
||||||
"56dff061d2720bb5668b4567": 20,
|
|
||||||
"61962b617c6c7b169525f168": 12,
|
|
||||||
"56dfef82d2720bbd668b4567": 9,
|
|
||||||
"56dff026d2720bb8668b4567": 8,
|
|
||||||
"5c0d5e4486f77478390952fe": 4
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"5c0d5ae286f7741e46554302": 1,
|
|
||||||
"54527a984bdc2d4e668b4567": 7,
|
|
||||||
"60194943740c5d77f6705eea": 20,
|
|
||||||
"59e6906286f7746c9f75e847": 26,
|
|
||||||
"54527ac44bdc2d36668b4567": 30,
|
|
||||||
"59e690b686f7746c9f75e848": 7,
|
|
||||||
"601949593ae8f707c4608daa": 5
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f8fe4a949033b0224a2": 5,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 21,
|
|
||||||
"5cc80f67e4a949035e43bbba": 15,
|
|
||||||
"5cc80f38e4a949001152b560": 12
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 10,
|
|
||||||
"6529243824cbe3c74a05e5c1": 5
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"5736026a245977644601dc61": 5,
|
|
||||||
"573603c924597764442bd9cb": 10,
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 7,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 6,
|
|
||||||
"619636be6db0f2477964e710": 23,
|
|
||||||
"64b8725c4b75259c590fa899": 20,
|
|
||||||
"5fd20ff893a8961fc660a954": 9
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4cf5286f7741778269d8a": 4,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 28,
|
|
||||||
"64b7af434b75259c590fa893": 33,
|
|
||||||
"59e0d99486f7744a32234762": 20,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 12
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e53d4353e3302577c4c": 6,
|
|
||||||
"58dd3ad986f77403051cba8f": 27,
|
|
||||||
"5a608bf24f39f98ffc77720e": 19,
|
|
||||||
"5a6086ea4f39f99cd479502f": 9,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 2
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5e023cf8186a883be655e54f": 3,
|
|
||||||
"5887431f2459777e1612938f": 20,
|
|
||||||
"59e77a2386f7742ee578960a": 25,
|
|
||||||
"5e023d34e8a400319a28ed44": 22,
|
|
||||||
"560d61e84bdc2da74d8b4571": 15,
|
|
||||||
"5e023d48186a883be655e551": 10
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 5,
|
|
||||||
"5fc382c1016cce60e8341b20": 8,
|
|
||||||
"5fc275cf85fd526b824a571a": 8,
|
|
||||||
"5fc382a9d724d907e2077dab": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"57371e4124597760ff7b25f1": 3,
|
|
||||||
"5737201124597760fc4431f1": 5,
|
|
||||||
"573720e02459776143012541": 12,
|
|
||||||
"573718ba2459775a75491131": 18,
|
|
||||||
"57371aab2459775a77142f22": 12,
|
|
||||||
"573719df2459775a626ccbc2": 10
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 9,
|
|
||||||
"5efb0e16aeb21837e749c7ff": 5,
|
|
||||||
"5a3c16fe86f77452b62de32a": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 18,
|
|
||||||
"5c925fa22e221601da359b7b": 22,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 9
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a269f97c4a282000b151807": 8,
|
|
||||||
"6576f93989f0062e741ba952": 18,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 18,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 8
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c18744e5e31df12f516": 9,
|
|
||||||
"62330b3ed4dc74626d570b95": 6
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 9,
|
|
||||||
"61962d879bb3d20b0946d385": 25,
|
|
||||||
"57a0e5022459774d1673f889": 25,
|
|
||||||
"5c0d688c86f77413ae3407b2": 12
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 3,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 30,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 25,
|
|
||||||
"668fe62ac62660a5d8071446": 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,473 +0,0 @@
|
||||||
{
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"66546f823b51a4d21e0d17d7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 1,
|
|
||||||
"5d1f56c686f7744bcd13459c": 2,
|
|
||||||
"637b945722e2a933ed0e33c8": 2,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 2,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 2,
|
|
||||||
"642d9bbf6c06444bf7033855": 2,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 3,
|
|
||||||
"66043728333907134309d647": 3,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 3,
|
|
||||||
"6295e8c3e08ed747e64aea00": 3,
|
|
||||||
"642c18b8a6a0660b560fb31c": 3,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 3,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 5,
|
|
||||||
"660437e57502eca33a08caca": 5,
|
|
||||||
"5fcf63da5c287f01f22bf245": 5,
|
|
||||||
"618109c96d7ca35d076b3363": 5,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 5
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1,
|
|
||||||
"5d1f590486f7744bcd13459e": 2,
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 2,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 2,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 3,
|
|
||||||
"660436487502eca33a08cac8": 3,
|
|
||||||
"6571cad4c8673f00290f5657": 3,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 3,
|
|
||||||
"5d1f591186f7744bcc048755": 3,
|
|
||||||
"6295e944e9de5e7b3751c4da": 3,
|
|
||||||
"642c19360a69698d1b049e12": 3,
|
|
||||||
"66acc8f719271bd6d00dec0b": 3,
|
|
||||||
"660436a810bcdf80ff0e9f78": 5,
|
|
||||||
"617c02e24013b06b0b78df80": 5,
|
|
||||||
"5d1f593286f7743014162044": 5,
|
|
||||||
"5d1f592286f7743f8362bcdb": 5
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"66546f823b51a4d21e0d17d7": 1,
|
|
||||||
"5d1f565786f7743f8362bcd5": 1,
|
|
||||||
"5fce3e0cfe40296c1d5fd782": 2,
|
|
||||||
"6377266693a3b4967208e42b": 2,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 2,
|
|
||||||
"6295e698e9de5e7b3751c47a": 2,
|
|
||||||
"642e8ae07e17c882400c4f87": 2,
|
|
||||||
"5d1f568486f7744bca3f0b98": 2,
|
|
||||||
"657058fddf9b3231400e9188": 3,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 3,
|
|
||||||
"66043cc27502eca33a08cad0": 3,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 3,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 3,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 3,
|
|
||||||
"5d1f567786f7744bcc04874f": 5,
|
|
||||||
"660440d2c8949a435906e43a": 5,
|
|
||||||
"617bca4b4013b06b0b78df2a": 5,
|
|
||||||
"5d1f566d86f7744bcd13459a": 5
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 2,
|
|
||||||
"5d1f588e86f7744bcc048753": 2,
|
|
||||||
"65707a89f5a6f1412f0c5f7b": 2,
|
|
||||||
"642ed40af5bdf1c04e01952e": 2,
|
|
||||||
"5fce3e965a9f8c40685693bc": 2,
|
|
||||||
"6295e63de08ed747e64ae991": 3,
|
|
||||||
"66043cf87502eca33a08cad2": 3,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 3,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 3,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 3,
|
|
||||||
"642e71620a69698d1b049f0a": 3,
|
|
||||||
"66acebd4ede86671bb09584b": 3,
|
|
||||||
"66043d7ac8949a435906e434": 5,
|
|
||||||
"5d1f58ab86f7743014162042": 5,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 5
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"springEarly": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 2,
|
|
||||||
"5e9da17386f774054b6f79a3": 2,
|
|
||||||
"5e4bb35286f77406a511c9bc": 2,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5d1f590486f7744bcd13459e": 3,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1,
|
|
||||||
"642e8ae07e17c882400c4f87": 2,
|
|
||||||
"5d1f568486f7744bca3f0b98": 2,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 2,
|
|
||||||
"5e4bb31586f7740695730568": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1,
|
|
||||||
"66acebd4ede86671bb09584b": 3,
|
|
||||||
"5d1f58ab86f7743014162042": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spring": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"summer": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"642c18b8a6a0660b560fb31c": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f593286f7743014162044": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autumn": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"637b945722e2a933ed0e33c8": 1,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 1,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5f5e40a06760b4138443b341": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"6377266693a3b4967208e42b": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"6430119aac11c9eaf10d881b": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"642ed40af5bdf1c04e01952e": 1,
|
|
||||||
"6295e63de08ed747e64ae991": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"66043d7ac8949a435906e434": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"winter": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 1,
|
|
||||||
"5e9da17386f774054b6f79a3": 1,
|
|
||||||
"5e4bb35286f77406a511c9bc": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f590486f7744bcd13459e": 1,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"642e8ae07e17c882400c4f87": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 1,
|
|
||||||
"5e4bb31586f7740695730568": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"66acebd4ede86671bb09584b": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,456 +0,0 @@
|
||||||
{
|
|
||||||
"scavAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 3
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 1
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6772a4b936088465b17c": 2,
|
|
||||||
"5d6e6806a4b936088465b17e": 2,
|
|
||||||
"5d6e67fba4b9361bc73bc779": 2,
|
|
||||||
"560d5e524bdc2d25448b4571": 2,
|
|
||||||
"5d6e6869a4b9361c140bcfde": 1,
|
|
||||||
"5d6e68b3a4b9361bca7e50b5": 1,
|
|
||||||
"58820d1224597753c90aeb13": 1,
|
|
||||||
"5d6e68dea4b9361bcc29e659": 1,
|
|
||||||
"5d6e6891a4b9361bd473feea": 1,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 1,
|
|
||||||
"5d6e689ca4b9361bc8618956": 1
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e695fa4b936359b35d852": 2,
|
|
||||||
"5d6e69b9a4b9361bc8618958": 2,
|
|
||||||
"5a38ebd9c4a282000d722a5b": 2,
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 1
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 3,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 1
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 3,
|
|
||||||
"59e6542b86f77411dc52a77a": 1
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 3,
|
|
||||||
"5ba26844d4351e00334c9475": 1
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff216d2720bbd668b4568": 1,
|
|
||||||
"56dff338d2720bbd668b4569": 4,
|
|
||||||
"56dff421d2720b5f5a8b4567": 4,
|
|
||||||
"56dff4ecd2720b5f5a8b4568": 2,
|
|
||||||
"56dff4a2d2720bbd668b456a": 4,
|
|
||||||
"56dff0bed2720bb0668b4567": 3,
|
|
||||||
"56dff3afd2720bba668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"59e6927d86f77411da468256": 2,
|
|
||||||
"59e6918f86f7746c9f75e849": 2,
|
|
||||||
"59e68f6f86f7746c9f75e846": 4,
|
|
||||||
"59e6920f86f77411d82aa167": 5,
|
|
||||||
"54527a984bdc2d4e668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc86832d7f00c000d3a6e6c": 2,
|
|
||||||
"5cc80f79e4a949033c7343b2": 3,
|
|
||||||
"5cc86840d7f00c002412c56c": 3,
|
|
||||||
"5cc80f8fe4a949033b0224a2": 1,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 1
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 1
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573602322459776445391df1": 2,
|
|
||||||
"573601b42459776410737435": 2,
|
|
||||||
"5735fdcd2459776445391d61": 1,
|
|
||||||
"5736026a245977644601dc61": 1
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 1,
|
|
||||||
"6196364158ef8c428c287d9f": 6,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 3
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4d3d286f774176a36250a": 2,
|
|
||||||
"64b7af734b75259c590fa895": 2,
|
|
||||||
"64b7af5a8532cf95ee0a0dbd": 6,
|
|
||||||
"59e4d24686f7741776641ac7": 4,
|
|
||||||
"59e4cf5286f7741778269d8a": 2,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 1
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e88277cce2b522ff2b1": 2,
|
|
||||||
"5e023e6e34d52a55c3304f71": 2,
|
|
||||||
"5e023e53d4353e3302577c4c": 1
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"64b8f7c241772715af0f9c3d": 2,
|
|
||||||
"64b8f7b5389d7ffd620ccba2": 2,
|
|
||||||
"64b8f7968532cf95ee0a0dbf": 2,
|
|
||||||
"5e023cf8186a883be655e54f": 2,
|
|
||||||
"5887431f2459777e1612938f": 1
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 2,
|
|
||||||
"5fc382c1016cce60e8341b20": 1
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"5737218f245977612125ba51": 5,
|
|
||||||
"57372140245977611f70ee91": 5,
|
|
||||||
"5737207f24597760ff7b25f2": 2,
|
|
||||||
"573719762459775a626ccbc1": 3,
|
|
||||||
"57371f8d24597761006c6a81": 3,
|
|
||||||
"57371f2b24597761224311f1": 5,
|
|
||||||
"57371eb62459776125652ac1": 1,
|
|
||||||
"57371b192459775a9f58a5e0": 1,
|
|
||||||
"57371e4124597760ff7b25f1": 1
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5efb0e16aeb21837e749c7ff": 1,
|
|
||||||
"58864a4f2459770fcc257101": 7,
|
|
||||||
"5a3c16fe86f77452b62de32a": 12,
|
|
||||||
"5c3df7d588a4501f290594e5": 6,
|
|
||||||
"64b7bbb74b75259c590fa897": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 2
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a26ac06c4a282000c5a90a8": 5,
|
|
||||||
"5a26abfac4a28232980eabff": 3,
|
|
||||||
"5a269f97c4a282000b151807": 1
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c40bdd19b369e1e53d1": 5,
|
|
||||||
"62330bfadc5883093563729b": 3,
|
|
||||||
"62330c18744e5e31df12f516": 1
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"6576f96220d53a5b8f3e395e": 7,
|
|
||||||
"57a0dfb82459774d3078b56c": 5,
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 1
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 10,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 20,
|
|
||||||
"5e81f423763d9f754677bf2e": 35,
|
|
||||||
"5efb0cabfb3e451d70735af5": 45
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6ddae9215051e1c23b2": 45,
|
|
||||||
"5cadf6eeae921500134b2799": 55
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"64b8ee384b75259c590fa89b": 10,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 25,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 25,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 25
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e6a5fa4b93614ec501745": 10,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 10,
|
|
||||||
"5d6e6a05a4b93618084f58d0": 40,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 40
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 20,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 35,
|
|
||||||
"5e85aa1a988a8701445df1f5": 35
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e655cb86f77411dc52a77b": 10,
|
|
||||||
"5f0596629e22f464da6bbdd9": 90
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26844d4351e00334c9475": 15,
|
|
||||||
"64b6979341772715af0f9c39": 30,
|
|
||||||
"5ba2678ad4351e44f824b344": 40,
|
|
||||||
"5ba26835d4351e0035628ff5": 15
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff2ced2720bb4668b4567": 10,
|
|
||||||
"56dff061d2720bb5668b4567": 30,
|
|
||||||
"61962b617c6c7b169525f168": 30,
|
|
||||||
"56dfef82d2720bbd668b4567": 10,
|
|
||||||
"56dff026d2720bb8668b4567": 5,
|
|
||||||
"5c0d5e4486f77478390952fe": 5
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"60194943740c5d77f6705eea": 5,
|
|
||||||
"59e6906286f7746c9f75e847": 10,
|
|
||||||
"54527ac44bdc2d36668b4567": 50,
|
|
||||||
"59e690b686f7746c9f75e848": 20,
|
|
||||||
"601949593ae8f707c4608daa": 15
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f67e4a949035e43bbba": 35,
|
|
||||||
"5cc80f38e4a949001152b560": 65
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 50,
|
|
||||||
"6529243824cbe3c74a05e5c1": 50
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 15,
|
|
||||||
"619636be6db0f2477964e710": 40,
|
|
||||||
"64b8725c4b75259c590fa899": 30,
|
|
||||||
"5fd20ff893a8961fc660a954": 15
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"64b7af434b75259c590fa893": 40,
|
|
||||||
"59e0d99486f7744a32234762": 45,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 15
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"58dd3ad986f77403051cba8f": 40,
|
|
||||||
"5a608bf24f39f98ffc77720e": 35,
|
|
||||||
"5a6086ea4f39f99cd479502f": 20,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 5
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5887431f2459777e1612938f": 5,
|
|
||||||
"59e77a2386f7742ee578960a": 30,
|
|
||||||
"5e023d34e8a400319a28ed44": 40,
|
|
||||||
"560d61e84bdc2da74d8b4571": 20,
|
|
||||||
"5e023d48186a883be655e551": 5
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 5,
|
|
||||||
"5fc382c1016cce60e8341b20": 25,
|
|
||||||
"5fc275cf85fd526b824a571a": 45,
|
|
||||||
"5fc382a9d724d907e2077dab": 25
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"573718ba2459775a75491131": 15,
|
|
||||||
"57371aab2459775a77142f22": 50,
|
|
||||||
"573719df2459775a626ccbc2": 35
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 10,
|
|
||||||
"56d59d3ad2720bdb418b4577": 25,
|
|
||||||
"5c925fa22e221601da359b7b": 40,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 25
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a269f97c4a282000b151807": 20,
|
|
||||||
"6576f93989f0062e741ba952": 20,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 15,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 10
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c18744e5e31df12f516": 10,
|
|
||||||
"62330b3ed4dc74626d570b95": 10
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"61962d879bb3d20b0946d385": 30,
|
|
||||||
"57a0e5022459774d1673f889": 40,
|
|
||||||
"5c0d688c86f77413ae3407b2": 30
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 5,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 20,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 50,
|
|
||||||
"668fe62ac62660a5d8071446": 30
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bossAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 4,
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 10,
|
|
||||||
"5e81f423763d9f754677bf2e": 18,
|
|
||||||
"5efb0cabfb3e451d70735af5": 10
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 3,
|
|
||||||
"5cadf6ddae9215051e1c23b2": 12,
|
|
||||||
"5cadf6eeae921500134b2799": 8
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 7,
|
|
||||||
"64b8ee384b75259c590fa89b": 4,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 3,
|
|
||||||
"5c0d591486f7744c505b416f": 5,
|
|
||||||
"5d6e6891a4b9361bd473feea": 2,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 6,
|
|
||||||
"5d6e689ca4b9361bc8618956": 8,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 8,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 3
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 4,
|
|
||||||
"5d6e6a05a4b93618084f58d0": 5,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 5
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 2,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 4,
|
|
||||||
"5e85aa1a988a8701445df1f5": 4
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 1,
|
|
||||||
"59e6542b86f77411dc52a77a": 2,
|
|
||||||
"59e655cb86f77411dc52a77b": 10,
|
|
||||||
"5f0596629e22f464da6bbdd9": 8
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 2,
|
|
||||||
"5ba26844d4351e00334c9475": 4,
|
|
||||||
"5ba2678ad4351e44f824b344": 15,
|
|
||||||
"64b6979341772715af0f9c39": 15,
|
|
||||||
"5ba26835d4351e0035628ff5": 8
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff3afd2720bba668b4567": 6,
|
|
||||||
"56dff2ced2720bb4668b4567": 12,
|
|
||||||
"56dff061d2720bb5668b4567": 20,
|
|
||||||
"61962b617c6c7b169525f168": 12,
|
|
||||||
"56dfef82d2720bbd668b4567": 9,
|
|
||||||
"56dff026d2720bb8668b4567": 8,
|
|
||||||
"5c0d5e4486f77478390952fe": 4
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"5c0d5ae286f7741e46554302": 1,
|
|
||||||
"54527a984bdc2d4e668b4567": 7,
|
|
||||||
"60194943740c5d77f6705eea": 20,
|
|
||||||
"59e6906286f7746c9f75e847": 26,
|
|
||||||
"54527ac44bdc2d36668b4567": 30,
|
|
||||||
"59e690b686f7746c9f75e848": 7,
|
|
||||||
"601949593ae8f707c4608daa": 5
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f8fe4a949033b0224a2": 5,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 21,
|
|
||||||
"5cc80f67e4a949035e43bbba": 15,
|
|
||||||
"5cc80f38e4a949001152b560": 12
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 10,
|
|
||||||
"6529243824cbe3c74a05e5c1": 5
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"5736026a245977644601dc61": 5,
|
|
||||||
"573603c924597764442bd9cb": 10,
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 7,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 6,
|
|
||||||
"619636be6db0f2477964e710": 23,
|
|
||||||
"64b8725c4b75259c590fa899": 20,
|
|
||||||
"5fd20ff893a8961fc660a954": 9
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4cf5286f7741778269d8a": 4,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 28,
|
|
||||||
"64b7af434b75259c590fa893": 33,
|
|
||||||
"59e0d99486f7744a32234762": 20,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 12
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e53d4353e3302577c4c": 6,
|
|
||||||
"58dd3ad986f77403051cba8f": 27,
|
|
||||||
"5a608bf24f39f98ffc77720e": 19,
|
|
||||||
"5a6086ea4f39f99cd479502f": 9,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 2
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5e023cf8186a883be655e54f": 3,
|
|
||||||
"5887431f2459777e1612938f": 20,
|
|
||||||
"59e77a2386f7742ee578960a": 25,
|
|
||||||
"5e023d34e8a400319a28ed44": 22,
|
|
||||||
"560d61e84bdc2da74d8b4571": 15,
|
|
||||||
"5e023d48186a883be655e551": 10
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 5,
|
|
||||||
"5fc382c1016cce60e8341b20": 8,
|
|
||||||
"5fc275cf85fd526b824a571a": 8,
|
|
||||||
"5fc382a9d724d907e2077dab": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"57371e4124597760ff7b25f1": 3,
|
|
||||||
"5737201124597760fc4431f1": 5,
|
|
||||||
"573720e02459776143012541": 12,
|
|
||||||
"573718ba2459775a75491131": 18,
|
|
||||||
"57371aab2459775a77142f22": 12,
|
|
||||||
"573719df2459775a626ccbc2": 10
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 9,
|
|
||||||
"5efb0e16aeb21837e749c7ff": 5,
|
|
||||||
"5a3c16fe86f77452b62de32a": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 18,
|
|
||||||
"5c925fa22e221601da359b7b": 22,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 9
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a269f97c4a282000b151807": 8,
|
|
||||||
"6576f93989f0062e741ba952": 18,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 18,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 8
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c18744e5e31df12f516": 9,
|
|
||||||
"62330b3ed4dc74626d570b95": 6
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 9,
|
|
||||||
"61962d879bb3d20b0946d385": 25,
|
|
||||||
"57a0e5022459774d1673f889": 25,
|
|
||||||
"5c0d688c86f77413ae3407b2": 12
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 3,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 30,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 25,
|
|
||||||
"668fe62ac62660a5d8071446": 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,493 +0,0 @@
|
||||||
{
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"66546f823b51a4d21e0d17d7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 1,
|
|
||||||
"5d1f56c686f7744bcd13459c": 2,
|
|
||||||
"637b945722e2a933ed0e33c8": 2,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 2,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 2,
|
|
||||||
"642d9bbf6c06444bf7033855": 2,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 3,
|
|
||||||
"66043728333907134309d647": 3,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 3,
|
|
||||||
"6295e8c3e08ed747e64aea00": 3,
|
|
||||||
"642c18b8a6a0660b560fb31c": 3,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 3,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 5,
|
|
||||||
"660437e57502eca33a08caca": 5,
|
|
||||||
"5fcf63da5c287f01f22bf245": 5,
|
|
||||||
"618109c96d7ca35d076b3363": 5,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 5,
|
|
||||||
"64ef3efdb63b74469b6c1499": 5,
|
|
||||||
"642c5273ff5ecad7810a89d7": 5,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 5,
|
|
||||||
"5e4bb35286f77406a511c9bc": 5,
|
|
||||||
"5cdea33e7d6c8b0474535dac": 5,
|
|
||||||
"5e9da17386f774054b6f79a3": 5
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1,
|
|
||||||
"5d1f590486f7744bcd13459e": 2,
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 2,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 2,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 3,
|
|
||||||
"660436487502eca33a08cac8": 3,
|
|
||||||
"6571cad4c8673f00290f5657": 3,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 3,
|
|
||||||
"5d1f591186f7744bcc048755": 3,
|
|
||||||
"6295e944e9de5e7b3751c4da": 3,
|
|
||||||
"642c19360a69698d1b049e12": 3,
|
|
||||||
"66acc8f719271bd6d00dec0b": 3,
|
|
||||||
"660436a810bcdf80ff0e9f78": 5,
|
|
||||||
"617c02e24013b06b0b78df80": 5,
|
|
||||||
"5d1f593286f7743014162044": 5,
|
|
||||||
"5d1f592286f7743f8362bcdb": 5,
|
|
||||||
"642d6941ff5ecad7810a8a61": 5,
|
|
||||||
"5df8a08886f7740bfe6df775": 5,
|
|
||||||
"5e4bb3b586f77406812bd579": 5,
|
|
||||||
"5e9dcadd86f7743e20652f23": 5
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"66546f823b51a4d21e0d17d7": 1,
|
|
||||||
"5d1f565786f7743f8362bcd5": 1,
|
|
||||||
"5fce3e0cfe40296c1d5fd782": 2,
|
|
||||||
"6377266693a3b4967208e42b": 2,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 2,
|
|
||||||
"6295e698e9de5e7b3751c47a": 2,
|
|
||||||
"642e8ae07e17c882400c4f87": 2,
|
|
||||||
"5d1f568486f7744bca3f0b98": 2,
|
|
||||||
"657058fddf9b3231400e9188": 3,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 3,
|
|
||||||
"66043cc27502eca33a08cad0": 3,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 3,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 3,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 3,
|
|
||||||
"5d1f567786f7744bcc04874f": 5,
|
|
||||||
"660440d2c8949a435906e43a": 5,
|
|
||||||
"617bca4b4013b06b0b78df2a": 5,
|
|
||||||
"5d1f566d86f7744bcd13459a": 5,
|
|
||||||
"64ef3efdb63b74469b6c1499": 5,
|
|
||||||
"6430119aac11c9eaf10d881b": 5,
|
|
||||||
"5df89f1f86f77412631087ea": 5,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 5,
|
|
||||||
"5cdea33e7d6c8b0474535dac": 5,
|
|
||||||
"5e4bb31586f7740695730568": 5
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 2,
|
|
||||||
"5d1f588e86f7744bcc048753": 2,
|
|
||||||
"65707a89f5a6f1412f0c5f7b": 2,
|
|
||||||
"642ed40af5bdf1c04e01952e": 2,
|
|
||||||
"5fce3e965a9f8c40685693bc": 2,
|
|
||||||
"6295e63de08ed747e64ae991": 3,
|
|
||||||
"66043cf87502eca33a08cad2": 3,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 3,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 3,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 3,
|
|
||||||
"642e71620a69698d1b049f0a": 3,
|
|
||||||
"66acebd4ede86671bb09584b": 3,
|
|
||||||
"66043d7ac8949a435906e434": 5,
|
|
||||||
"5d1f58ab86f7743014162042": 5,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 5,
|
|
||||||
"642eea6f881906a7fe086841": 5,
|
|
||||||
"5df89f8f86f77412672a1e38": 5,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 5,
|
|
||||||
"5e4bb39386f774067f79de05": 5
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"springEarly": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 2,
|
|
||||||
"5e9da17386f774054b6f79a3": 2,
|
|
||||||
"5e4bb35286f77406a511c9bc": 2,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5d1f590486f7744bcd13459e": 3,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1,
|
|
||||||
"642e8ae07e17c882400c4f87": 2,
|
|
||||||
"5d1f568486f7744bca3f0b98": 2,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 2,
|
|
||||||
"5e4bb31586f7740695730568": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1,
|
|
||||||
"66acebd4ede86671bb09584b": 3,
|
|
||||||
"5d1f58ab86f7743014162042": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spring": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"summer": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"642c18b8a6a0660b560fb31c": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f593286f7743014162044": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autumn": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"637b945722e2a933ed0e33c8": 1,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 1,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5f5e40a06760b4138443b341": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"6377266693a3b4967208e42b": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"6430119aac11c9eaf10d881b": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"642ed40af5bdf1c04e01952e": 1,
|
|
||||||
"6295e63de08ed747e64ae991": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"66043d7ac8949a435906e434": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"winter": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 1,
|
|
||||||
"5e9da17386f774054b6f79a3": 1,
|
|
||||||
"5e4bb35286f77406a511c9bc": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f590486f7744bcd13459e": 1,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"642e8ae07e17c882400c4f87": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 1,
|
|
||||||
"5e4bb31586f7740695730568": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"66acebd4ede86671bb09584b": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,446 +0,0 @@
|
||||||
{
|
|
||||||
"scavAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 3
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 1
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6772a4b936088465b17c": 2,
|
|
||||||
"5d6e6806a4b936088465b17e": 2,
|
|
||||||
"5d6e67fba4b9361bc73bc779": 2,
|
|
||||||
"560d5e524bdc2d25448b4571": 2,
|
|
||||||
"5d6e6869a4b9361c140bcfde": 1,
|
|
||||||
"5d6e68b3a4b9361bca7e50b5": 1,
|
|
||||||
"58820d1224597753c90aeb13": 1,
|
|
||||||
"5d6e68dea4b9361bcc29e659": 1,
|
|
||||||
"5d6e6891a4b9361bd473feea": 1,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 1,
|
|
||||||
"5d6e689ca4b9361bc8618956": 1
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e695fa4b936359b35d852": 2,
|
|
||||||
"5d6e69b9a4b9361bc8618958": 2,
|
|
||||||
"5a38ebd9c4a282000d722a5b": 2,
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 1
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 3,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 1
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 3,
|
|
||||||
"59e6542b86f77411dc52a77a": 1
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 3,
|
|
||||||
"5ba26844d4351e00334c9475": 1
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff216d2720bbd668b4568": 1,
|
|
||||||
"56dff338d2720bbd668b4569": 4,
|
|
||||||
"56dff421d2720b5f5a8b4567": 4,
|
|
||||||
"56dff4ecd2720b5f5a8b4568": 2,
|
|
||||||
"56dff4a2d2720bbd668b456a": 4,
|
|
||||||
"56dff0bed2720bb0668b4567": 3,
|
|
||||||
"56dff3afd2720bba668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"59e6927d86f77411da468256": 2,
|
|
||||||
"59e6918f86f7746c9f75e849": 2,
|
|
||||||
"59e68f6f86f7746c9f75e846": 4,
|
|
||||||
"59e6920f86f77411d82aa167": 5,
|
|
||||||
"54527a984bdc2d4e668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc86832d7f00c000d3a6e6c": 2,
|
|
||||||
"5cc80f79e4a949033c7343b2": 3,
|
|
||||||
"5cc86840d7f00c002412c56c": 3,
|
|
||||||
"5cc80f8fe4a949033b0224a2": 1,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 1
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 1
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573602322459776445391df1": 2,
|
|
||||||
"573601b42459776410737435": 2,
|
|
||||||
"5735fdcd2459776445391d61": 1,
|
|
||||||
"5736026a245977644601dc61": 1
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 1,
|
|
||||||
"6196364158ef8c428c287d9f": 6,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 3
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4d3d286f774176a36250a": 2,
|
|
||||||
"64b7af734b75259c590fa895": 2,
|
|
||||||
"64b7af5a8532cf95ee0a0dbd": 6,
|
|
||||||
"59e4d24686f7741776641ac7": 4,
|
|
||||||
"59e4cf5286f7741778269d8a": 2,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 1
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e88277cce2b522ff2b1": 2,
|
|
||||||
"5e023e6e34d52a55c3304f71": 2,
|
|
||||||
"5e023e53d4353e3302577c4c": 1
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"64b8f7c241772715af0f9c3d": 2,
|
|
||||||
"64b8f7b5389d7ffd620ccba2": 2,
|
|
||||||
"64b8f7968532cf95ee0a0dbf": 2,
|
|
||||||
"5e023cf8186a883be655e54f": 2,
|
|
||||||
"5887431f2459777e1612938f": 1
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 2,
|
|
||||||
"5fc382c1016cce60e8341b20": 1
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"5737218f245977612125ba51": 5,
|
|
||||||
"57372140245977611f70ee91": 5,
|
|
||||||
"5737207f24597760ff7b25f2": 2,
|
|
||||||
"573719762459775a626ccbc1": 3,
|
|
||||||
"57371f8d24597761006c6a81": 3,
|
|
||||||
"57371f2b24597761224311f1": 5,
|
|
||||||
"57371eb62459776125652ac1": 1,
|
|
||||||
"57371b192459775a9f58a5e0": 1,
|
|
||||||
"57371e4124597760ff7b25f1": 1
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5efb0e16aeb21837e749c7ff": 1,
|
|
||||||
"58864a4f2459770fcc257101": 7,
|
|
||||||
"5a3c16fe86f77452b62de32a": 12,
|
|
||||||
"5c3df7d588a4501f290594e5": 6,
|
|
||||||
"64b7bbb74b75259c590fa897": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 2
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a26ac06c4a282000c5a90a8": 5,
|
|
||||||
"5a26abfac4a28232980eabff": 3,
|
|
||||||
"5a269f97c4a282000b151807": 1
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c40bdd19b369e1e53d1": 5,
|
|
||||||
"62330bfadc5883093563729b": 3,
|
|
||||||
"62330c18744e5e31df12f516": 1
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"6576f96220d53a5b8f3e395e": 7,
|
|
||||||
"57a0dfb82459774d3078b56c": 5,
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 1
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 10,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 30,
|
|
||||||
"5e81f423763d9f754677bf2e": 20,
|
|
||||||
"5efb0cabfb3e451d70735af5": 50
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6ddae9215051e1c23b2": 30,
|
|
||||||
"5cadf6eeae921500134b2799": 70
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"64b8ee384b75259c590fa89b": 10,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 30,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 30,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 40
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e6a05a4b93618084f58d0": 40,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 60
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 5,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 10,
|
|
||||||
"5e85aa1a988a8701445df1f5": 15
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e655cb86f77411dc52a77b": 5,
|
|
||||||
"5f0596629e22f464da6bbdd9": 95
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"64b6979341772715af0f9c39": 30,
|
|
||||||
"5ba2678ad4351e44f824b344": 30,
|
|
||||||
"5ba26835d4351e0035628ff5": 30
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff061d2720bb5668b4567": 10,
|
|
||||||
"61962b617c6c7b169525f168": 20,
|
|
||||||
"56dfef82d2720bbd668b4567": 25,
|
|
||||||
"56dff026d2720bb8668b4567": 25,
|
|
||||||
"5c0d5e4486f77478390952fe": 20
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"54527ac44bdc2d36668b4567": 40,
|
|
||||||
"59e690b686f7746c9f75e848": 30,
|
|
||||||
"601949593ae8f707c4608daa": 30
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f38e4a949001152b560": 1
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 40,
|
|
||||||
"6529243824cbe3c74a05e5c1": 60
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 10,
|
|
||||||
"619636be6db0f2477964e710": 25,
|
|
||||||
"64b8725c4b75259c590fa899": 35,
|
|
||||||
"5fd20ff893a8961fc660a954": 30
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"64b7af434b75259c590fa893": 15,
|
|
||||||
"59e0d99486f7744a32234762": 50,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 35
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"58dd3ad986f77403051cba8f": 15,
|
|
||||||
"5a608bf24f39f98ffc77720e": 35,
|
|
||||||
"5a6086ea4f39f99cd479502f": 35,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 15
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"59e77a2386f7742ee578960a": 5,
|
|
||||||
"5e023d34e8a400319a28ed44": 30,
|
|
||||||
"560d61e84bdc2da74d8b4571": 45,
|
|
||||||
"5e023d48186a883be655e551": 20
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382c1016cce60e8341b20": 10,
|
|
||||||
"5fc275cf85fd526b824a571a": 50,
|
|
||||||
"5fc382a9d724d907e2077dab": 40
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"573718ba2459775a75491131": 10,
|
|
||||||
"57371aab2459775a77142f22": 45,
|
|
||||||
"573719df2459775a626ccbc2": 45
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 10,
|
|
||||||
"56d59d3ad2720bdb418b4577": 5,
|
|
||||||
"5c925fa22e221601da359b7b": 45,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 35
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a269f97c4a282000b151807": 10,
|
|
||||||
"6576f93989f0062e741ba952": 20,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 30,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 30
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330b3ed4dc74626d570b95": 10
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"61962d879bb3d20b0946d385": 20,
|
|
||||||
"57a0e5022459774d1673f889": 40,
|
|
||||||
"5c0d688c86f77413ae3407b2": 40
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 2,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 10,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 40,
|
|
||||||
"668fe62ac62660a5d8071446": 40
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bossAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 4,
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 10,
|
|
||||||
"5e81f423763d9f754677bf2e": 18,
|
|
||||||
"5efb0cabfb3e451d70735af5": 10
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 3,
|
|
||||||
"5cadf6ddae9215051e1c23b2": 12,
|
|
||||||
"5cadf6eeae921500134b2799": 8
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 7,
|
|
||||||
"64b8ee384b75259c590fa89b": 4,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 3,
|
|
||||||
"5c0d591486f7744c505b416f": 5,
|
|
||||||
"5d6e6891a4b9361bd473feea": 2,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 6,
|
|
||||||
"5d6e689ca4b9361bc8618956": 8,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 8,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 3
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 4,
|
|
||||||
"5d6e6a05a4b93618084f58d0": 5,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 5
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 2,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 4,
|
|
||||||
"5e85aa1a988a8701445df1f5": 4
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 1,
|
|
||||||
"59e6542b86f77411dc52a77a": 2,
|
|
||||||
"59e655cb86f77411dc52a77b": 10,
|
|
||||||
"5f0596629e22f464da6bbdd9": 8
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 2,
|
|
||||||
"5ba26844d4351e00334c9475": 4,
|
|
||||||
"5ba2678ad4351e44f824b344": 15,
|
|
||||||
"64b6979341772715af0f9c39": 15,
|
|
||||||
"5ba26835d4351e0035628ff5": 8
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff3afd2720bba668b4567": 6,
|
|
||||||
"56dff2ced2720bb4668b4567": 12,
|
|
||||||
"56dff061d2720bb5668b4567": 20,
|
|
||||||
"61962b617c6c7b169525f168": 12,
|
|
||||||
"56dfef82d2720bbd668b4567": 9,
|
|
||||||
"56dff026d2720bb8668b4567": 8,
|
|
||||||
"5c0d5e4486f77478390952fe": 4
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"5c0d5ae286f7741e46554302": 1,
|
|
||||||
"54527a984bdc2d4e668b4567": 7,
|
|
||||||
"60194943740c5d77f6705eea": 20,
|
|
||||||
"59e6906286f7746c9f75e847": 26,
|
|
||||||
"54527ac44bdc2d36668b4567": 30,
|
|
||||||
"59e690b686f7746c9f75e848": 7,
|
|
||||||
"601949593ae8f707c4608daa": 5
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f8fe4a949033b0224a2": 5,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 21,
|
|
||||||
"5cc80f67e4a949035e43bbba": 15,
|
|
||||||
"5cc80f38e4a949001152b560": 12
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 10,
|
|
||||||
"6529243824cbe3c74a05e5c1": 5
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"5736026a245977644601dc61": 5,
|
|
||||||
"573603c924597764442bd9cb": 10,
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 7,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 6,
|
|
||||||
"619636be6db0f2477964e710": 23,
|
|
||||||
"64b8725c4b75259c590fa899": 20,
|
|
||||||
"5fd20ff893a8961fc660a954": 9
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4cf5286f7741778269d8a": 4,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 28,
|
|
||||||
"64b7af434b75259c590fa893": 33,
|
|
||||||
"59e0d99486f7744a32234762": 20,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 12
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e53d4353e3302577c4c": 6,
|
|
||||||
"58dd3ad986f77403051cba8f": 27,
|
|
||||||
"5a608bf24f39f98ffc77720e": 19,
|
|
||||||
"5a6086ea4f39f99cd479502f": 9,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 2
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5e023cf8186a883be655e54f": 3,
|
|
||||||
"5887431f2459777e1612938f": 20,
|
|
||||||
"59e77a2386f7742ee578960a": 25,
|
|
||||||
"5e023d34e8a400319a28ed44": 22,
|
|
||||||
"560d61e84bdc2da74d8b4571": 15,
|
|
||||||
"5e023d48186a883be655e551": 10
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 5,
|
|
||||||
"5fc382c1016cce60e8341b20": 8,
|
|
||||||
"5fc275cf85fd526b824a571a": 8,
|
|
||||||
"5fc382a9d724d907e2077dab": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"57371e4124597760ff7b25f1": 3,
|
|
||||||
"5737201124597760fc4431f1": 5,
|
|
||||||
"573720e02459776143012541": 12,
|
|
||||||
"573718ba2459775a75491131": 18,
|
|
||||||
"57371aab2459775a77142f22": 12,
|
|
||||||
"573719df2459775a626ccbc2": 10
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 9,
|
|
||||||
"5efb0e16aeb21837e749c7ff": 5,
|
|
||||||
"5a3c16fe86f77452b62de32a": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 18,
|
|
||||||
"5c925fa22e221601da359b7b": 22,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 9
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a269f97c4a282000b151807": 8,
|
|
||||||
"6576f93989f0062e741ba952": 18,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 18,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 8
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c18744e5e31df12f516": 9,
|
|
||||||
"62330b3ed4dc74626d570b95": 6
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 9,
|
|
||||||
"61962d879bb3d20b0946d385": 25,
|
|
||||||
"57a0e5022459774d1673f889": 25,
|
|
||||||
"5c0d688c86f77413ae3407b2": 12
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 3,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 30,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 25,
|
|
||||||
"668fe62ac62660a5d8071446": 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,487 +0,0 @@
|
||||||
{
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"637b945722e2a933ed0e33c8": 1,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"642d9bbf6c06444bf7033855": 1,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 2,
|
|
||||||
"66043728333907134309d647": 2,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 2,
|
|
||||||
"6295e8c3e08ed747e64aea00": 2,
|
|
||||||
"642c18b8a6a0660b560fb31c": 2,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 2,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 3,
|
|
||||||
"660437e57502eca33a08caca": 3,
|
|
||||||
"5fcf63da5c287f01f22bf245": 3,
|
|
||||||
"618109c96d7ca35d076b3363": 3,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 3,
|
|
||||||
"64ef3efdb63b74469b6c1499": 5,
|
|
||||||
"642c5273ff5ecad7810a89d7": 5,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 5,
|
|
||||||
"5e4bb35286f77406a511c9bc": 5,
|
|
||||||
"5cdea33e7d6c8b0474535dac": 5,
|
|
||||||
"5e9da17386f774054b6f79a3": 5,
|
|
||||||
"5f5e4075df4f3100376a8138": 5
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f590486f7744bcd13459e": 1,
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 2,
|
|
||||||
"660436487502eca33a08cac8": 2,
|
|
||||||
"6571cad4c8673f00290f5657": 2,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 2,
|
|
||||||
"5d1f591186f7744bcc048755": 2,
|
|
||||||
"6295e944e9de5e7b3751c4da": 2,
|
|
||||||
"642c19360a69698d1b049e12": 2,
|
|
||||||
"66acc8f719271bd6d00dec0b": 2,
|
|
||||||
"660436a810bcdf80ff0e9f78": 3,
|
|
||||||
"617c02e24013b06b0b78df80": 3,
|
|
||||||
"5d1f593286f7743014162044": 3,
|
|
||||||
"5d1f592286f7743f8362bcdb": 3,
|
|
||||||
"642d6941ff5ecad7810a8a61": 5,
|
|
||||||
"5df8a08886f7740bfe6df775": 5,
|
|
||||||
"5e4bb3b586f77406812bd579": 5,
|
|
||||||
"5e9dcadd86f7743e20652f23": 5,
|
|
||||||
"5f5e40a06760b4138443b341": 5
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5fce3e0cfe40296c1d5fd782": 1,
|
|
||||||
"6377266693a3b4967208e42b": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"642e8ae07e17c882400c4f87": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"657058fddf9b3231400e9188": 2,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 2,
|
|
||||||
"66043cc27502eca33a08cad0": 2,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 2,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 2,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 2,
|
|
||||||
"5d1f567786f7744bcc04874f": 3,
|
|
||||||
"660440d2c8949a435906e43a": 3,
|
|
||||||
"617bca4b4013b06b0b78df2a": 3,
|
|
||||||
"5d1f566d86f7744bcd13459a": 3,
|
|
||||||
"64ef3efdb63b74469b6c1499": 5,
|
|
||||||
"6430119aac11c9eaf10d881b": 5,
|
|
||||||
"5df89f1f86f77412631087ea": 5,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 5,
|
|
||||||
"5cdea33e7d6c8b0474535dac": 5,
|
|
||||||
"5e4bb31586f7740695730568": 5,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 5
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"65707a89f5a6f1412f0c5f7b": 1,
|
|
||||||
"642ed40af5bdf1c04e01952e": 1,
|
|
||||||
"5fce3e965a9f8c40685693bc": 1,
|
|
||||||
"6295e63de08ed747e64ae991": 2,
|
|
||||||
"66043cf87502eca33a08cad2": 2,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 2,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 2,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 2,
|
|
||||||
"642e71620a69698d1b049f0a": 2,
|
|
||||||
"66acebd4ede86671bb09584b": 2,
|
|
||||||
"66043d7ac8949a435906e434": 3,
|
|
||||||
"5d1f58ab86f7743014162042": 3,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 3,
|
|
||||||
"642eea6f881906a7fe086841": 5,
|
|
||||||
"5df89f8f86f77412672a1e38": 5,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 5,
|
|
||||||
"5e4bb39386f774067f79de05": 5,
|
|
||||||
"5f5e40400bc58666c37e7819": 5
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"springEarly": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 2,
|
|
||||||
"5e9da17386f774054b6f79a3": 2,
|
|
||||||
"5e4bb35286f77406a511c9bc": 2,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5d1f590486f7744bcd13459e": 3,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1,
|
|
||||||
"642e8ae07e17c882400c4f87": 2,
|
|
||||||
"5d1f568486f7744bca3f0b98": 2,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 2,
|
|
||||||
"5e4bb31586f7740695730568": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1,
|
|
||||||
"66acebd4ede86671bb09584b": 3,
|
|
||||||
"5d1f58ab86f7743014162042": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spring": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"summer": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"642c18b8a6a0660b560fb31c": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f593286f7743014162044": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autumn": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"637b945722e2a933ed0e33c8": 1,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 1,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5f5e40a06760b4138443b341": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"6377266693a3b4967208e42b": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"6430119aac11c9eaf10d881b": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"642ed40af5bdf1c04e01952e": 1,
|
|
||||||
"6295e63de08ed747e64ae991": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"66043d7ac8949a435906e434": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"winter": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 1,
|
|
||||||
"5e9da17386f774054b6f79a3": 1,
|
|
||||||
"5e4bb35286f77406a511c9bc": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f590486f7744bcd13459e": 1,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"642e8ae07e17c882400c4f87": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 1,
|
|
||||||
"5e4bb31586f7740695730568": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"66acebd4ede86671bb09584b": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,436 +0,0 @@
|
||||||
{
|
|
||||||
"scavAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 3
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 1
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6772a4b936088465b17c": 2,
|
|
||||||
"5d6e6806a4b936088465b17e": 2,
|
|
||||||
"5d6e67fba4b9361bc73bc779": 2,
|
|
||||||
"560d5e524bdc2d25448b4571": 2,
|
|
||||||
"5d6e6869a4b9361c140bcfde": 1,
|
|
||||||
"5d6e68b3a4b9361bca7e50b5": 1,
|
|
||||||
"58820d1224597753c90aeb13": 1,
|
|
||||||
"5d6e68dea4b9361bcc29e659": 1,
|
|
||||||
"5d6e6891a4b9361bd473feea": 1,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 1,
|
|
||||||
"5d6e689ca4b9361bc8618956": 1
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e695fa4b936359b35d852": 2,
|
|
||||||
"5d6e69b9a4b9361bc8618958": 2,
|
|
||||||
"5a38ebd9c4a282000d722a5b": 2,
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 1
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 3,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 1
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 3,
|
|
||||||
"59e6542b86f77411dc52a77a": 1
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 3,
|
|
||||||
"5ba26844d4351e00334c9475": 1
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff216d2720bbd668b4568": 1,
|
|
||||||
"56dff338d2720bbd668b4569": 4,
|
|
||||||
"56dff421d2720b5f5a8b4567": 4,
|
|
||||||
"56dff4ecd2720b5f5a8b4568": 2,
|
|
||||||
"56dff4a2d2720bbd668b456a": 4,
|
|
||||||
"56dff0bed2720bb0668b4567": 3,
|
|
||||||
"56dff3afd2720bba668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"59e6927d86f77411da468256": 2,
|
|
||||||
"59e6918f86f7746c9f75e849": 2,
|
|
||||||
"59e68f6f86f7746c9f75e846": 4,
|
|
||||||
"59e6920f86f77411d82aa167": 5,
|
|
||||||
"54527a984bdc2d4e668b4567": 1
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc86832d7f00c000d3a6e6c": 2,
|
|
||||||
"5cc80f79e4a949033c7343b2": 3,
|
|
||||||
"5cc86840d7f00c002412c56c": 3,
|
|
||||||
"5cc80f8fe4a949033b0224a2": 1,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 1
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 1
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573602322459776445391df1": 2,
|
|
||||||
"573601b42459776410737435": 2,
|
|
||||||
"5735fdcd2459776445391d61": 1,
|
|
||||||
"5736026a245977644601dc61": 1
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 1,
|
|
||||||
"6196364158ef8c428c287d9f": 6,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 3
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4d3d286f774176a36250a": 2,
|
|
||||||
"64b7af734b75259c590fa895": 2,
|
|
||||||
"64b7af5a8532cf95ee0a0dbd": 6,
|
|
||||||
"59e4d24686f7741776641ac7": 4,
|
|
||||||
"59e4cf5286f7741778269d8a": 2,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 1
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e88277cce2b522ff2b1": 2,
|
|
||||||
"5e023e6e34d52a55c3304f71": 2,
|
|
||||||
"5e023e53d4353e3302577c4c": 1
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"64b8f7c241772715af0f9c3d": 2,
|
|
||||||
"64b8f7b5389d7ffd620ccba2": 2,
|
|
||||||
"64b8f7968532cf95ee0a0dbf": 2,
|
|
||||||
"5e023cf8186a883be655e54f": 2,
|
|
||||||
"5887431f2459777e1612938f": 1
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 2,
|
|
||||||
"5fc382c1016cce60e8341b20": 1
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"5737218f245977612125ba51": 5,
|
|
||||||
"57372140245977611f70ee91": 5,
|
|
||||||
"5737207f24597760ff7b25f2": 2,
|
|
||||||
"573719762459775a626ccbc1": 3,
|
|
||||||
"57371f8d24597761006c6a81": 3,
|
|
||||||
"57371f2b24597761224311f1": 5,
|
|
||||||
"57371eb62459776125652ac1": 1,
|
|
||||||
"57371b192459775a9f58a5e0": 1,
|
|
||||||
"57371e4124597760ff7b25f1": 1
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5efb0e16aeb21837e749c7ff": 1,
|
|
||||||
"58864a4f2459770fcc257101": 7,
|
|
||||||
"5a3c16fe86f77452b62de32a": 12,
|
|
||||||
"5c3df7d588a4501f290594e5": 6,
|
|
||||||
"64b7bbb74b75259c590fa897": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 2
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a26ac06c4a282000c5a90a8": 5,
|
|
||||||
"5a26abfac4a28232980eabff": 3,
|
|
||||||
"5a269f97c4a282000b151807": 1
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c40bdd19b369e1e53d1": 5,
|
|
||||||
"62330bfadc5883093563729b": 3,
|
|
||||||
"62330c18744e5e31df12f516": 1
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"6576f96220d53a5b8f3e395e": 7,
|
|
||||||
"57a0dfb82459774d3078b56c": 5,
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 1
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 10,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 20,
|
|
||||||
"5efb0cabfb3e451d70735af5": 50
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6ddae9215051e1c23b2": 15,
|
|
||||||
"5cadf6eeae921500134b2799": 85
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"64b8ee384b75259c590fa89b": 15,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 15,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 25,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 45
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e6a05a4b93618084f58d0": 20,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 80
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 10,
|
|
||||||
"5e85aa1a988a8701445df1f5": 30
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"5f0596629e22f464da6bbdd9": 1
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"64b6979341772715af0f9c39": 20,
|
|
||||||
"5ba2678ad4351e44f824b344": 30,
|
|
||||||
"5ba26835d4351e0035628ff5": 50
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff061d2720bb5668b4567": 5,
|
|
||||||
"61962b617c6c7b169525f168": 5,
|
|
||||||
"56dfef82d2720bbd668b4567": 15,
|
|
||||||
"56dff026d2720bb8668b4567": 35,
|
|
||||||
"5c0d5e4486f77478390952fe": 40
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"54527ac44bdc2d36668b4567": 30,
|
|
||||||
"59e690b686f7746c9f75e848": 35,
|
|
||||||
"601949593ae8f707c4608daa": 35
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f38e4a949001152b560": 1
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 20,
|
|
||||||
"6529243824cbe3c74a05e5c1": 80
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"619636be6db0f2477964e710": 20,
|
|
||||||
"64b8725c4b75259c590fa899": 40,
|
|
||||||
"5fd20ff893a8961fc660a954": 40
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"64b7af434b75259c590fa893": 10,
|
|
||||||
"59e0d99486f7744a32234762": 45,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 45
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"58dd3ad986f77403051cba8f": 10,
|
|
||||||
"5a608bf24f39f98ffc77720e": 20,
|
|
||||||
"5a6086ea4f39f99cd479502f": 40,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 30
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5e023d34e8a400319a28ed44": 20,
|
|
||||||
"560d61e84bdc2da74d8b4571": 55,
|
|
||||||
"5e023d48186a883be655e551": 35
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc275cf85fd526b824a571a": 50,
|
|
||||||
"5fc382a9d724d907e2077dab": 50
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"57371aab2459775a77142f22": 40,
|
|
||||||
"573719df2459775a626ccbc2": 60
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 10,
|
|
||||||
"5c925fa22e221601da359b7b": 45,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 45
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"6576f93989f0062e741ba952": 20,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 30,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 30
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330b3ed4dc74626d570b95": 10
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"57a0e5022459774d1673f889": 40,
|
|
||||||
"5c0d688c86f77413ae3407b2": 60
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 1,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 3,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 50,
|
|
||||||
"668fe62ac62660a5d8071446": 50
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bossAmmo": {
|
|
||||||
"Caliber1143x23ACP": {
|
|
||||||
"5ea2a8e200685063ec28c05a": 4,
|
|
||||||
"5efb0fc6aeb21837e749c801": 1,
|
|
||||||
"5efb0d4f4bc50b58e81710f3": 10,
|
|
||||||
"5e81f423763d9f754677bf2e": 18,
|
|
||||||
"5efb0cabfb3e451d70735af5": 10
|
|
||||||
},
|
|
||||||
"Caliber127x55": {
|
|
||||||
"5cadf6e5ae921500113bb973": 3,
|
|
||||||
"5cadf6ddae9215051e1c23b2": 12,
|
|
||||||
"5cadf6eeae921500134b2799": 8
|
|
||||||
},
|
|
||||||
"Caliber12g": {
|
|
||||||
"5d6e6806a4b936088465b17e": 7,
|
|
||||||
"64b8ee384b75259c590fa89b": 4,
|
|
||||||
"5d6e6911a4b9361bd5780d52": 3,
|
|
||||||
"5c0d591486f7744c505b416f": 5,
|
|
||||||
"5d6e6891a4b9361bd473feea": 2,
|
|
||||||
"5d6e68e6a4b9361c140bcfe0": 6,
|
|
||||||
"5d6e689ca4b9361bc8618956": 8,
|
|
||||||
"5d6e68c4a4b9361b93413f79": 8,
|
|
||||||
"5d6e68a8a4b9360b6c0d54e2": 3
|
|
||||||
},
|
|
||||||
"Caliber20g": {
|
|
||||||
"5d6e69c7a4b9360b6c0d54e4": 1,
|
|
||||||
"5d6e6a53a4b9361bd473feec": 4,
|
|
||||||
"5d6e6a05a4b93618084f58d0": 5,
|
|
||||||
"5d6e6a42a4b9364f07165f52": 5
|
|
||||||
},
|
|
||||||
"Caliber23x75": {
|
|
||||||
"5f647f31b6238e5dd066e196": 2,
|
|
||||||
"5e85a9a6eacf8c039e4e2ac1": 4,
|
|
||||||
"5e85aa1a988a8701445df1f5": 4
|
|
||||||
},
|
|
||||||
"Caliber366TKM": {
|
|
||||||
"59e6658b86f77411d949b250": 1,
|
|
||||||
"59e6542b86f77411dc52a77a": 2,
|
|
||||||
"59e655cb86f77411dc52a77b": 10,
|
|
||||||
"5f0596629e22f464da6bbdd9": 8
|
|
||||||
},
|
|
||||||
"Caliber40mmRU": {
|
|
||||||
"5656eb674bdc2d35148b457c": 1
|
|
||||||
},
|
|
||||||
"Caliber40x46": {
|
|
||||||
"5ede4739e0350d05467f73e8": 1,
|
|
||||||
"5ede47405b097655935d7d16": 1,
|
|
||||||
"5ede474b0c226a66f5402622": 1,
|
|
||||||
"5ede475339ee016e8c534742": 1,
|
|
||||||
"5ede475b549eed7c6d5c18fb": 1,
|
|
||||||
"5f0c892565703e5c461894e9": 1
|
|
||||||
},
|
|
||||||
"Caliber46x30": {
|
|
||||||
"5ba26812d4351e003201fef1": 2,
|
|
||||||
"5ba26844d4351e00334c9475": 4,
|
|
||||||
"5ba2678ad4351e44f824b344": 15,
|
|
||||||
"64b6979341772715af0f9c39": 15,
|
|
||||||
"5ba26835d4351e0035628ff5": 8
|
|
||||||
},
|
|
||||||
"Caliber545x39": {
|
|
||||||
"56dff3afd2720bba668b4567": 6,
|
|
||||||
"56dff2ced2720bb4668b4567": 12,
|
|
||||||
"56dff061d2720bb5668b4567": 20,
|
|
||||||
"61962b617c6c7b169525f168": 12,
|
|
||||||
"56dfef82d2720bbd668b4567": 9,
|
|
||||||
"56dff026d2720bb8668b4567": 8,
|
|
||||||
"5c0d5e4486f77478390952fe": 4
|
|
||||||
},
|
|
||||||
"Caliber556x45NATO": {
|
|
||||||
"5c0d5ae286f7741e46554302": 1,
|
|
||||||
"54527a984bdc2d4e668b4567": 7,
|
|
||||||
"60194943740c5d77f6705eea": 20,
|
|
||||||
"59e6906286f7746c9f75e847": 26,
|
|
||||||
"54527ac44bdc2d36668b4567": 30,
|
|
||||||
"59e690b686f7746c9f75e848": 7,
|
|
||||||
"601949593ae8f707c4608daa": 5
|
|
||||||
},
|
|
||||||
"Caliber57x28": {
|
|
||||||
"5cc80f8fe4a949033b0224a2": 5,
|
|
||||||
"5cc80f53e4a949000e1ea4f8": 21,
|
|
||||||
"5cc80f67e4a949035e43bbba": 15,
|
|
||||||
"5cc80f38e4a949001152b560": 12
|
|
||||||
},
|
|
||||||
"Caliber68x51": {
|
|
||||||
"6529302b8c26af6326029fb7": 10,
|
|
||||||
"6529243824cbe3c74a05e5c1": 5
|
|
||||||
},
|
|
||||||
"Caliber762x25TT": {
|
|
||||||
"5736026a245977644601dc61": 5,
|
|
||||||
"573603c924597764442bd9cb": 10,
|
|
||||||
"573603562459776430731618": 10
|
|
||||||
},
|
|
||||||
"Caliber762x35": {
|
|
||||||
"6196365d58ef8c428c287da1": 7,
|
|
||||||
"5fbe3ffdf8b6a877a729ea82": 6,
|
|
||||||
"619636be6db0f2477964e710": 23,
|
|
||||||
"64b8725c4b75259c590fa899": 20,
|
|
||||||
"5fd20ff893a8961fc660a954": 9
|
|
||||||
},
|
|
||||||
"Caliber762x39": {
|
|
||||||
"59e4cf5286f7741778269d8a": 4,
|
|
||||||
"5656d7c34bdc2d9d198b4587": 28,
|
|
||||||
"64b7af434b75259c590fa893": 33,
|
|
||||||
"59e0d99486f7744a32234762": 20,
|
|
||||||
"601aa3d2b2bcb34913271e6d": 12
|
|
||||||
},
|
|
||||||
"Caliber762x51": {
|
|
||||||
"5e023e53d4353e3302577c4c": 6,
|
|
||||||
"58dd3ad986f77403051cba8f": 27,
|
|
||||||
"5a608bf24f39f98ffc77720e": 19,
|
|
||||||
"5a6086ea4f39f99cd479502f": 9,
|
|
||||||
"5efb0c1bd79ff02a1f5e68d9": 2
|
|
||||||
},
|
|
||||||
"Caliber762x54R": {
|
|
||||||
"5e023cf8186a883be655e54f": 3,
|
|
||||||
"5887431f2459777e1612938f": 20,
|
|
||||||
"59e77a2386f7742ee578960a": 25,
|
|
||||||
"5e023d34e8a400319a28ed44": 22,
|
|
||||||
"560d61e84bdc2da74d8b4571": 15,
|
|
||||||
"5e023d48186a883be655e551": 10
|
|
||||||
},
|
|
||||||
"Caliber86x70": {
|
|
||||||
"5fc382b6d6fa9c00c571bbc3": 5,
|
|
||||||
"5fc382c1016cce60e8341b20": 8,
|
|
||||||
"5fc275cf85fd526b824a571a": 8,
|
|
||||||
"5fc382a9d724d907e2077dab": 5
|
|
||||||
},
|
|
||||||
"Caliber9x18PM": {
|
|
||||||
"57371e4124597760ff7b25f1": 3,
|
|
||||||
"5737201124597760fc4431f1": 5,
|
|
||||||
"573720e02459776143012541": 12,
|
|
||||||
"573718ba2459775a75491131": 18,
|
|
||||||
"57371aab2459775a77142f22": 12,
|
|
||||||
"573719df2459775a626ccbc2": 10
|
|
||||||
},
|
|
||||||
"Caliber9x19PARA": {
|
|
||||||
"5c0d56a986f774449d5de529": 9,
|
|
||||||
"5efb0e16aeb21837e749c7ff": 5,
|
|
||||||
"5a3c16fe86f77452b62de32a": 4,
|
|
||||||
"56d59d3ad2720bdb418b4577": 18,
|
|
||||||
"5c925fa22e221601da359b7b": 22,
|
|
||||||
"5efb0da7a29a85116f6ea05f": 9
|
|
||||||
},
|
|
||||||
"Caliber9x21": {
|
|
||||||
"5a269f97c4a282000b151807": 8,
|
|
||||||
"6576f93989f0062e741ba952": 18,
|
|
||||||
"5a26ac0ec4a28200741e1e18": 18,
|
|
||||||
"6576f4708ca9c4381d16cd9d": 8
|
|
||||||
},
|
|
||||||
"Caliber9x33R": {
|
|
||||||
"62330c18744e5e31df12f516": 9,
|
|
||||||
"62330b3ed4dc74626d570b95": 6
|
|
||||||
},
|
|
||||||
"Caliber9x39": {
|
|
||||||
"5c0d668f86f7747ccb7f13b2": 9,
|
|
||||||
"61962d879bb3d20b0946d385": 25,
|
|
||||||
"57a0e5022459774d1673f889": 25,
|
|
||||||
"5c0d688c86f77413ae3407b2": 12
|
|
||||||
},
|
|
||||||
"Caliber127x33": {
|
|
||||||
"66a0d1c87d0d369e270bb9de": 3,
|
|
||||||
"66a0d1f88486c69fce00fdf6": 30,
|
|
||||||
"66a0d1e0ed648d72fe064d06": 25,
|
|
||||||
"668fe62ac62660a5d8071446": 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,468 +0,0 @@
|
||||||
{
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1,
|
|
||||||
"6295e8c3e08ed747e64aea00": 1,
|
|
||||||
"642c18b8a6a0660b560fb31c": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 3,
|
|
||||||
"660437e57502eca33a08caca": 3,
|
|
||||||
"5fcf63da5c287f01f22bf245": 3,
|
|
||||||
"618109c96d7ca35d076b3363": 3,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 3,
|
|
||||||
"64ef3efdb63b74469b6c1499": 5,
|
|
||||||
"642c5273ff5ecad7810a89d7": 5,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 5,
|
|
||||||
"5e4bb35286f77406a511c9bc": 5,
|
|
||||||
"5cdea33e7d6c8b0474535dac": 5,
|
|
||||||
"5e9da17386f774054b6f79a3": 5,
|
|
||||||
"5f5e4075df4f3100376a8138": 5
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 1,
|
|
||||||
"5d1f591186f7744bcc048755": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"642c19360a69698d1b049e12": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"660436a810bcdf80ff0e9f78": 3,
|
|
||||||
"617c02e24013b06b0b78df80": 3,
|
|
||||||
"5d1f593286f7743014162044": 3,
|
|
||||||
"5d1f592286f7743f8362bcdb": 3,
|
|
||||||
"642d6941ff5ecad7810a8a61": 5,
|
|
||||||
"5df8a08886f7740bfe6df775": 5,
|
|
||||||
"5e4bb3b586f77406812bd579": 5,
|
|
||||||
"5e9dcadd86f7743e20652f23": 5,
|
|
||||||
"5f5e40a06760b4138443b341": 5
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"66043cc27502eca33a08cad0": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 1,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 3,
|
|
||||||
"660440d2c8949a435906e43a": 3,
|
|
||||||
"617bca4b4013b06b0b78df2a": 3,
|
|
||||||
"5d1f566d86f7744bcd13459a": 3,
|
|
||||||
"64ef3efdb63b74469b6c1499": 5,
|
|
||||||
"6430119aac11c9eaf10d881b": 5,
|
|
||||||
"5df89f1f86f77412631087ea": 5,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 5,
|
|
||||||
"5cdea33e7d6c8b0474535dac": 5,
|
|
||||||
"5e4bb31586f7740695730568": 5,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 5
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"6295e63de08ed747e64ae991": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"66acebd4ede86671bb09584b": 1,
|
|
||||||
"66043d7ac8949a435906e434": 3,
|
|
||||||
"5d1f58ab86f7743014162042": 3,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 3,
|
|
||||||
"642eea6f881906a7fe086841": 5,
|
|
||||||
"5df89f8f86f77412672a1e38": 5,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 5,
|
|
||||||
"5e4bb39386f774067f79de05": 5,
|
|
||||||
"5f5e40400bc58666c37e7819": 5
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"springEarly": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1,
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 2,
|
|
||||||
"5e9da17386f774054b6f79a3": 2,
|
|
||||||
"5e4bb35286f77406a511c9bc": 2,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5d1f590486f7744bcd13459e": 3,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1,
|
|
||||||
"642e8ae07e17c882400c4f87": 2,
|
|
||||||
"5d1f568486f7744bca3f0b98": 2,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 2,
|
|
||||||
"5e4bb31586f7740695730568": 2
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"5d1f58cb86f7744bca3f0b9a": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1,
|
|
||||||
"66acebd4ede86671bb09584b": 3,
|
|
||||||
"5d1f58ab86f7743014162042": 3
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"spring": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"summer": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cde95d97d6c8b647a3769b0": 1,
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"5fd3e9f71b735718c25cd9f8": 1,
|
|
||||||
"66043728333907134309d647": 1,
|
|
||||||
"5d4da0cb86f77450fe0a6629": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"642c18b8a6a0660b560fb31c": 1,
|
|
||||||
"5d1f56f186f7744bcb0acd1a": 1,
|
|
||||||
"5f5e4075df4f3100376a8138": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cde95ef7d6c8b04713c4f2d": 1,
|
|
||||||
"6033a3fee29c9f6c9b14e74e": 1,
|
|
||||||
"660436487502eca33a08cac8": 1,
|
|
||||||
"6571cad4c8673f00290f5657": 1,
|
|
||||||
"66acc8f719271bd6d00dec0b": 1,
|
|
||||||
"5d1f593286f7743014162044": 1,
|
|
||||||
"5d1f592286f7743f8362bcdb": 1,
|
|
||||||
"642d6941ff5ecad7810a8a61": 1,
|
|
||||||
"5e9dcadd86f7743e20652f23": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5cc0858d14c02e000c6bea66": 1,
|
|
||||||
"5d1f564b86f7744bcb0acd16": 1,
|
|
||||||
"6295e698e9de5e7b3751c47a": 1,
|
|
||||||
"6033a31e9ec839204e6a2f3e": 1,
|
|
||||||
"5fce3e47fe40296c1d5fd784": 1,
|
|
||||||
"617bca4b4013b06b0b78df2a": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5df89f1f86f77412631087ea": 1,
|
|
||||||
"5e9d9fa986f774054d6b89f2": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5cc085bb14c02e000e67a5c5": 1,
|
|
||||||
"5d1f588e86f7744bcc048753": 1,
|
|
||||||
"66043cf87502eca33a08cad2": 1,
|
|
||||||
"6033a3d8ed2e0509b15f9031": 1,
|
|
||||||
"642e71620a69698d1b049f0a": 1,
|
|
||||||
"617be9e4e02b3b3fa50fa8f2": 1,
|
|
||||||
"642eea6f881906a7fe086841": 1,
|
|
||||||
"5df89f8f86f77412672a1e38": 1,
|
|
||||||
"5e9dc97c86f774054c19ac9a": 1,
|
|
||||||
"5e4bb39386f774067f79de05": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autumn": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56c686f7744bcd13459c": 1,
|
|
||||||
"637b945722e2a933ed0e33c8": 1,
|
|
||||||
"6571cb0923aa6d72760a7f8f": 1,
|
|
||||||
"6033a35f80ae5e2f970ba6bb": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1,
|
|
||||||
"66acbe49dc61999a6a03d4d6": 1,
|
|
||||||
"660437e57502eca33a08caca": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"5d1f56ff86f7743f8362bcd7": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"642d4d8eb6b75d4c89077cf9": 1,
|
|
||||||
"5fcf940bce1ba36a513bb9cc": 1,
|
|
||||||
"637ba17aa10a96c2b605dbc2": 1,
|
|
||||||
"6295e944e9de5e7b3751c4da": 1,
|
|
||||||
"5e4bb3b586f77406812bd579": 1,
|
|
||||||
"5f5e40a06760b4138443b341": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"6377266693a3b4967208e42b": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"657058fddf9b3231400e9188": 1,
|
|
||||||
"642ed297ac11c9eaf10d87e8": 1,
|
|
||||||
"5d1f567786f7744bcc04874f": 1,
|
|
||||||
"64ef3efdb63b74469b6c1499": 1,
|
|
||||||
"6430119aac11c9eaf10d881b": 1,
|
|
||||||
"5f5e401747344c2e4f6c42c5": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f58bd86f7744bce0ee9ef": 1,
|
|
||||||
"6377315993a3b4967208e437": 1,
|
|
||||||
"642ed40af5bdf1c04e01952e": 1,
|
|
||||||
"6295e63de08ed747e64ae991": 1,
|
|
||||||
"5d1f58a086f7743f8362bcd9": 1,
|
|
||||||
"66043d7ac8949a435906e434": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1,
|
|
||||||
"5f5e40400bc58666c37e7819": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"winter": {
|
|
||||||
"pmcUSEC": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"5d1f56a686f7744bce0ee9eb": 1,
|
|
||||||
"5e9da17386f774054b6f79a3": 1,
|
|
||||||
"5e4bb35286f77406a511c9bc": 1,
|
|
||||||
"5d1f56e486f7744bce0ee9ed": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"5d1f590486f7744bcd13459e": 1,
|
|
||||||
"5d1f58ed86f7744bcb0acd1c": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cde95fa7d6c8b04737c2d13": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cde96047d6c8b20b577f016": 1,
|
|
||||||
"5fdb4139e4ed5b5ea251e4ed": 1,
|
|
||||||
"5fdb5950f5264a66150d1c6e": 1,
|
|
||||||
"60a6aa8fd559ae040d0d951f": 1,
|
|
||||||
"619f9e338858a474c8685cc9": 1,
|
|
||||||
"62aca6a1310e67685a2fc2e7": 1,
|
|
||||||
"6574aabee0423b9ebe0c79cf": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pmcBEAR": {
|
|
||||||
"appearance": {
|
|
||||||
"body": {
|
|
||||||
"642e8ae07e17c882400c4f87": 1,
|
|
||||||
"5d1f568486f7744bca3f0b98": 1,
|
|
||||||
"66acec1dc94f4bf5bc063a16": 1,
|
|
||||||
"5e4bb31586f7740695730568": 1
|
|
||||||
},
|
|
||||||
"feet": {
|
|
||||||
"66acebd4ede86671bb09584b": 1,
|
|
||||||
"5d1f58ab86f7743014162042": 1
|
|
||||||
},
|
|
||||||
"hands": {
|
|
||||||
"5cc0876314c02e000c6bea6b": 1
|
|
||||||
},
|
|
||||||
"head": {
|
|
||||||
"5cc084dd14c02e000b0550a3": 1,
|
|
||||||
"5fdb50bb2b730a787b3f78cf": 1,
|
|
||||||
"5fdb7571e4ed5b5ea251e529": 1,
|
|
||||||
"60a6aaad42fd2735e4589978": 1,
|
|
||||||
"619f94f5b90286142b59d45f": 1,
|
|
||||||
"62a9e7d15ea3b87d6f642a28": 1,
|
|
||||||
"6574aa9a1b144de18c0fba45": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,635 +0,0 @@
|
||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
|
||||||
import { injectable, inject } from "tsyringe";
|
|
||||||
import { IDatabaseTables } from "@spt/models/spt/server/IDatabaseTables";
|
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
|
||||||
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
|
|
||||||
import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig";
|
|
||||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
||||||
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { TierInformation } from "../Globals/TierInformation";
|
|
||||||
import { RaidInformation } from "../Globals/RaidInformation";
|
|
||||||
import { ModConfig } from "../Globals/ModConfig";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { Logging } from "../Enums/Logging";
|
|
||||||
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class BotConfigs
|
|
||||||
{
|
|
||||||
protected botConfig: IBotConfig;
|
|
||||||
protected pmcConfig: IPmcConfig;
|
|
||||||
|
|
||||||
private pmcLimitedCategories = {
|
|
||||||
"5448e8d04bdc2ddf718b4569": 1,
|
|
||||||
"5448e8d64bdc2dce718b4568": 1,
|
|
||||||
"5448f39d4bdc2d0a728b4568": 1,
|
|
||||||
"5448f3a64bdc2d60728b456a": 2,
|
|
||||||
"5448f3ac4bdc2dce718b4569": 1,
|
|
||||||
"5448f3a14bdc2d27728b4569": 1,
|
|
||||||
"5c99f98d86f7745c314214b3": 1,
|
|
||||||
"5c164d2286f774194c5e69fa": 1,
|
|
||||||
"550aa4cd4bdc2dd8348b456c": 2,
|
|
||||||
"55818add4bdc2d5b648b456f": 1,
|
|
||||||
"55818ad54bdc2ddc698b4569": 1,
|
|
||||||
"55818aeb4bdc2ddc698b456a": 1,
|
|
||||||
"55818ae44bdc2dde698b456c": 1,
|
|
||||||
"55818af64bdc2d5b648b4570": 1,
|
|
||||||
"5448e54d4bdc2dcc718b4568": 1,
|
|
||||||
"5447e1d04bdc2dff2f8b4567": 1,
|
|
||||||
"5a341c4686f77469e155819e": 1,
|
|
||||||
"55818b164bdc2ddc698b456c": 2,
|
|
||||||
"5448bc234bdc2d3c308b4569": 2,
|
|
||||||
"543be5dd4bdc2deb348b4569": 1,
|
|
||||||
"543be5cb4bdc2deb348b4568": 2,
|
|
||||||
"5485a8684bdc2da71d8b4567": 2,
|
|
||||||
"5d650c3e815116009f6201d2": 2,
|
|
||||||
"543be6564bdc2df4348b4568": 4
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@inject("IDatabaseTables") protected tables: IDatabaseTables,
|
|
||||||
@inject("DatabaseService") protected database: DatabaseService,
|
|
||||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
|
||||||
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("TierInformation") protected tierInformation: TierInformation,
|
|
||||||
@inject("RaidInformation") protected raidInformation: RaidInformation,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this.botConfig = this.configServer.getConfig(ConfigTypes.BOT);
|
|
||||||
this.pmcConfig = this.configServer.getConfig(ConfigTypes.PMC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public initialize(): void
|
|
||||||
{
|
|
||||||
if (!ModConfig.config.disablePMCTierGeneration)
|
|
||||||
{
|
|
||||||
this.setPMCItemLimits();
|
|
||||||
this.setPMCLoot();
|
|
||||||
this.setPMCScopeWhitelist();
|
|
||||||
this.setPMCSlotIDsToMakeRequired();
|
|
||||||
if (ModConfig.config.gameVersionWeight) this.setPMCGameVersionWeights();
|
|
||||||
}
|
|
||||||
if (!ModConfig.config.disableScavTierGeneration)
|
|
||||||
{
|
|
||||||
if (ModConfig.config.addAllKeysToScavs || ModConfig.config.addOnlyKeyCardsToScavs || ModConfig.config.addOnlyMechanicalKeysToScavs) this.pushScavKeys();
|
|
||||||
if (!ModConfig.config.scavLoot) this.removeScavLoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.clearNoLongerNeededBotDetails();
|
|
||||||
this.configureBotExperienceLevels();
|
|
||||||
this.configurePlateWeightings();
|
|
||||||
this.configureWeaponDurability();
|
|
||||||
this.adjustNVG();
|
|
||||||
this.setLootItemResourceRandomization();
|
|
||||||
this.removeThermalGoggles(ModConfig.config.enableT7Thermals);
|
|
||||||
|
|
||||||
if (ModConfig.config.enableCustomPlateChances) this.setPlateChances();
|
|
||||||
if (ModConfig.config.forceStock) this.setForceStock();
|
|
||||||
if (ModConfig.config.forceDustCover) this.setForceDustCover();
|
|
||||||
if (ModConfig.config.forceScopeSlot) this.setForceScopes();
|
|
||||||
if (ModConfig.config.forceWeaponModLimits) this.setWeaponModLimits();
|
|
||||||
if (ModConfig.config.enableScavEqualEquipmentTiering) this.setIdenticalScavWeights();
|
|
||||||
if (ModConfig.config.enableCustomLevelDeltas) this.setLevelDeltas();
|
|
||||||
if (ModConfig.config.enableScavCustomLevelDeltas) this.setScavLevelDeltas();
|
|
||||||
if (ModConfig.config.forceMuzzle) this.setMuzzleChances();
|
|
||||||
}
|
|
||||||
|
|
||||||
private configureBotExperienceLevels(): void
|
|
||||||
{
|
|
||||||
const botTypeTable = this.tables.bots.types;
|
|
||||||
|
|
||||||
for (const botType in botTypeTable)
|
|
||||||
{
|
|
||||||
botTypeTable[botType].experience.level.min = 1;
|
|
||||||
botTypeTable[botType].experience.level.max = 79;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private configurePlateWeightings(): void
|
|
||||||
{
|
|
||||||
const botConfigEquipment = this.botConfig.equipment
|
|
||||||
for (const botType in botConfigEquipment)
|
|
||||||
{
|
|
||||||
if (botType.includes("assault") || botType.includes("marksman"))
|
|
||||||
{
|
|
||||||
botConfigEquipment[botType].filterPlatesByLevel = true;
|
|
||||||
botConfigEquipment[botType].armorPlateWeighting = this.tierInformation.scavArmorPlateWeights;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
botConfigEquipment[botType].filterPlatesByLevel = true;
|
|
||||||
botConfigEquipment[botType].armorPlateWeighting = this.tierInformation.armorPlateWeights;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private clearNoLongerNeededBotDetails(): void
|
|
||||||
{
|
|
||||||
const botConfigEquipment = this.botConfig.equipment
|
|
||||||
for (const botType in botConfigEquipment)
|
|
||||||
{
|
|
||||||
botConfigEquipment[botType].randomisation = [];
|
|
||||||
botConfigEquipment[botType].weightingAdjustmentsByBotLevel = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private configureWeaponDurability(): void
|
|
||||||
{
|
|
||||||
// Do this better in the future - this looks like shit. Bad Acid. Bad.
|
|
||||||
const botConfigDurability = this.botConfig.durability
|
|
||||||
|
|
||||||
for (const botType in botConfigDurability)
|
|
||||||
{
|
|
||||||
if (botType == "pmc")
|
|
||||||
{
|
|
||||||
botConfigDurability[botType].weapon.lowestMax = ModConfig.config.pmcWeaponDurability[0]
|
|
||||||
botConfigDurability[botType].weapon.highestMax = ModConfig.config.pmcWeaponDurability[1]
|
|
||||||
botConfigDurability[botType].weapon.minDelta = ModConfig.config.pmcWeaponDurability[2]
|
|
||||||
botConfigDurability[botType].weapon.maxDelta = ModConfig.config.pmcWeaponDurability[3]
|
|
||||||
botConfigDurability[botType].weapon.minLimitPercent = 40
|
|
||||||
}
|
|
||||||
if (botType == "boss" || botType == "arenafighterevent" || botType == "arenafighter" || botType == "sectantpriest" || botType == "sectantwarrior")
|
|
||||||
{
|
|
||||||
botConfigDurability[botType].weapon.lowestMax = ModConfig.config.bossWeaponDurability[0]
|
|
||||||
botConfigDurability[botType].weapon.highestMax = ModConfig.config.bossWeaponDurability[1]
|
|
||||||
botConfigDurability[botType].weapon.minDelta = ModConfig.config.bossWeaponDurability[2]
|
|
||||||
botConfigDurability[botType].weapon.maxDelta = ModConfig.config.bossWeaponDurability[3]
|
|
||||||
botConfigDurability[botType].weapon.minLimitPercent = 40
|
|
||||||
}
|
|
||||||
if (botType == "assault" || botType == "cursedassault" || botType == "marksman" || botType == "crazyassaultevent" || botType == "default")
|
|
||||||
{
|
|
||||||
botConfigDurability[botType].weapon.lowestMax = ModConfig.config.scavWeaponDurability[0]
|
|
||||||
botConfigDurability[botType].weapon.highestMax = ModConfig.config.scavWeaponDurability[1]
|
|
||||||
botConfigDurability[botType].weapon.minDelta = ModConfig.config.scavWeaponDurability[2]
|
|
||||||
botConfigDurability[botType].weapon.maxDelta = ModConfig.config.scavWeaponDurability[3]
|
|
||||||
botConfigDurability[botType].weapon.minLimitPercent = 40
|
|
||||||
}
|
|
||||||
if (botType == "follower")
|
|
||||||
{
|
|
||||||
botConfigDurability[botType].weapon.lowestMax = ModConfig.config.guardWeaponDurability[0]
|
|
||||||
botConfigDurability[botType].weapon.highestMax = ModConfig.config.guardWeaponDurability[1]
|
|
||||||
botConfigDurability[botType].weapon.minDelta = ModConfig.config.guardWeaponDurability[2]
|
|
||||||
botConfigDurability[botType].weapon.maxDelta = ModConfig.config.guardWeaponDurability[3]
|
|
||||||
botConfigDurability[botType].weapon.minLimitPercent = 40
|
|
||||||
}
|
|
||||||
if (botType == "pmcbot" || botType == "exusec")
|
|
||||||
{
|
|
||||||
botConfigDurability[botType].weapon.lowestMax = ModConfig.config.raiderWeaponDurability[0]
|
|
||||||
botConfigDurability[botType].weapon.highestMax = ModConfig.config.raiderWeaponDurability[1]
|
|
||||||
botConfigDurability[botType].weapon.minDelta = ModConfig.config.raiderWeaponDurability[2]
|
|
||||||
botConfigDurability[botType].weapon.maxDelta = ModConfig.config.raiderWeaponDurability[3]
|
|
||||||
botConfigDurability[botType].weapon.minLimitPercent = 40
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private adjustNVG(): void
|
|
||||||
{
|
|
||||||
const botConfigEquipment = this.botConfig.equipment
|
|
||||||
|
|
||||||
for (const botType in botConfigEquipment)
|
|
||||||
{
|
|
||||||
botConfigEquipment[botType].faceShieldIsActiveChancePercent = 90;
|
|
||||||
botConfigEquipment[botType].lightIsActiveDayChancePercent = 7;
|
|
||||||
botConfigEquipment[botType].lightIsActiveNightChancePercent = 25;
|
|
||||||
botConfigEquipment[botType].laserIsActiveChancePercent = 50;
|
|
||||||
botConfigEquipment[botType].nvgIsActiveChanceDayPercent = 0;
|
|
||||||
botConfigEquipment[botType].nvgIsActiveChanceNightPercent = 95;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setForceStock(): void
|
|
||||||
{
|
|
||||||
for (const tierObject in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[tierObject].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierChancesJson(tierNumber);
|
|
||||||
|
|
||||||
for (const botType in this.tierInformation.tier1chances)
|
|
||||||
{
|
|
||||||
const chances = tierJson[botType].chances
|
|
||||||
for (const weaponType in chances)
|
|
||||||
{
|
|
||||||
chances[weaponType]["mod_stock"] = 100;
|
|
||||||
chances[weaponType]["mod_stock_000"] = 100;
|
|
||||||
chances[weaponType]["mod_stock_001"] = 100;
|
|
||||||
chances[weaponType]["mod_stock_akms"] = 100;
|
|
||||||
chances[weaponType]["mod_stock_axis"] = 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setForceDustCover(): void
|
|
||||||
{
|
|
||||||
for (const tierObject in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[tierObject].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierChancesJson(tierNumber);
|
|
||||||
|
|
||||||
for (const botType in this.tierInformation.tier1chances)
|
|
||||||
{
|
|
||||||
const chances = tierJson[botType].chances
|
|
||||||
for (const weaponType in chances)
|
|
||||||
{
|
|
||||||
chances[weaponType]["mod_reciever"] = 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setForceScopes(): void
|
|
||||||
{
|
|
||||||
for (const tierObject in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[tierObject].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierChancesJson(tierNumber);
|
|
||||||
|
|
||||||
for (const botType in this.tierInformation.tier1chances)
|
|
||||||
{
|
|
||||||
const chances = tierJson[botType].chances
|
|
||||||
for (const weaponType in chances)
|
|
||||||
{
|
|
||||||
chances[weaponType]["mod_scope"] = 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setPlateChances()
|
|
||||||
{
|
|
||||||
for (const tierObject in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[tierObject].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierChancesJson(tierNumber);
|
|
||||||
|
|
||||||
for (const botType in this.tierInformation.tier1chances)
|
|
||||||
{
|
|
||||||
if (botType == "pmcUSEC" || botType == "pmcBEAR")
|
|
||||||
{
|
|
||||||
tierJson[botType].chances.equipmentMods["back_plate"] = tierJson[botType].chances.equipmentMods["front_plate"] = ModConfig.config.pmcMainPlateChance[tierObject];
|
|
||||||
tierJson[botType].chances.equipmentMods["left_side_plate"] = tierJson[botType].chances.equipmentMods["right_side_plate"] = ModConfig.config.pmcSidePlateChance[tierObject];
|
|
||||||
}
|
|
||||||
if (botType == "followerbirdeye" || botType == "followerbigpipe" || botType.includes("boss") || botType.includes("sectant"))
|
|
||||||
{
|
|
||||||
tierJson[botType].chances.equipmentMods["back_plate"] = tierJson[botType].chances.equipmentMods["front_plate"] = ModConfig.config.bossMainPlateChance[tierObject];
|
|
||||||
tierJson[botType].chances.equipmentMods["left_side_plate"] = tierJson[botType].chances.equipmentMods["right_side_plate"] = ModConfig.config.bossSidePlateChance[tierObject];
|
|
||||||
}
|
|
||||||
if (botType == "scav")
|
|
||||||
{
|
|
||||||
tierJson[botType].chances.equipmentMods["back_plate"] = tierJson[botType].chances.equipmentMods["front_plate"] = ModConfig.config.scavMainPlateChance[tierObject];
|
|
||||||
tierJson[botType].chances.equipmentMods["left_side_plate"] = tierJson[botType].chances.equipmentMods["right_side_plate"] = ModConfig.config.scavSidePlateChance[tierObject];
|
|
||||||
}
|
|
||||||
if (botType == "exusec" || botType == "pmcbot")
|
|
||||||
{
|
|
||||||
tierJson[botType].chances.equipmentMods["back_plate"] = tierJson[botType].chances.equipmentMods["front_plate"] = ModConfig.config.raiderMainPlateChance[tierObject];
|
|
||||||
tierJson[botType].chances.equipmentMods["left_side_plate"] = tierJson[botType].chances.equipmentMods["right_side_plate"] = ModConfig.config.raiderSidePlateChance[tierObject];
|
|
||||||
}
|
|
||||||
if (botType == "default")
|
|
||||||
{
|
|
||||||
tierJson[botType].chances.equipmentMods["back_plate"] = tierJson[botType].chances.equipmentMods["front_plate"] = ModConfig.config.guardMainPlateChance[tierObject];
|
|
||||||
tierJson[botType].chances.equipmentMods["left_side_plate"] = tierJson[botType].chances.equipmentMods["right_side_plate"] = ModConfig.config.guardSidePlateChance[tierObject];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setWeaponModLimits(): void
|
|
||||||
{
|
|
||||||
const botConfigEquipment = this.botConfig.equipment
|
|
||||||
for (const botType in botConfigEquipment)
|
|
||||||
{
|
|
||||||
if (botConfigEquipment[botType].weaponModLimits == undefined)
|
|
||||||
{
|
|
||||||
botConfigEquipment[botType].weaponModLimits =
|
|
||||||
{
|
|
||||||
"scopeLimit": 2,
|
|
||||||
"lightLaserLimit": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
botConfigEquipment[botType].weaponModLimits.scopeLimit = ModConfig.config.scopeLimit;
|
|
||||||
botConfigEquipment[botType].weaponModLimits.lightLaserLimit = ModConfig.config.tacticalLimit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setLootItemResourceRandomization(): void
|
|
||||||
{
|
|
||||||
// Chance it is 100% full
|
|
||||||
let scavFoodMaxChance = 100;
|
|
||||||
let scavMedMaxChance = 100;
|
|
||||||
let pmcFoodMaxChance = 100;
|
|
||||||
let pmcMedMaxChance = 100;
|
|
||||||
|
|
||||||
// Minimum resource amount
|
|
||||||
let scavFoodResourcePercent = 60;
|
|
||||||
let scavMedResourcePercent = 60;
|
|
||||||
let pmcFoodResourcePercent = 60;
|
|
||||||
let pmcMedResourcePercent = 60;
|
|
||||||
|
|
||||||
// Check if enabled, if so - change to values in config
|
|
||||||
if (ModConfig.config.enableConsumableResourceRandomization)
|
|
||||||
{
|
|
||||||
scavFoodMaxChance = ModConfig.config.scavFoodRates[0];
|
|
||||||
scavMedMaxChance = ModConfig.config.scavMedRates[0];
|
|
||||||
pmcFoodMaxChance = ModConfig.config.pmcFoodRates[0];
|
|
||||||
pmcMedMaxChance = ModConfig.config.pmcMedRates[0];
|
|
||||||
|
|
||||||
scavFoodResourcePercent = ModConfig.config.scavFoodRates[1];
|
|
||||||
scavMedResourcePercent = ModConfig.config.scavMedRates[1];
|
|
||||||
pmcFoodResourcePercent = ModConfig.config.pmcFoodRates[1];
|
|
||||||
pmcMedResourcePercent = ModConfig.config.pmcMedRates[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set values in botConfig
|
|
||||||
this.botConfig.lootItemResourceRandomization.assault = {"food": { "chanceMaxResourcePercent": scavFoodMaxChance, "resourcePercent": scavFoodResourcePercent }, "meds": { "chanceMaxResourcePercent": scavMedMaxChance, "resourcePercent": scavMedResourcePercent } }
|
|
||||||
this.botConfig.lootItemResourceRandomization.marksman = {"food": { "chanceMaxResourcePercent": scavFoodMaxChance, "resourcePercent": scavFoodResourcePercent }, "meds": { "chanceMaxResourcePercent": scavMedMaxChance, "resourcePercent": scavMedResourcePercent } }
|
|
||||||
this.botConfig.lootItemResourceRandomization.pmcusec = {"food": { "chanceMaxResourcePercent": pmcFoodMaxChance, "resourcePercent": pmcFoodResourcePercent }, "meds": { "chanceMaxResourcePercent": pmcMedMaxChance, "resourcePercent": pmcMedResourcePercent } }
|
|
||||||
this.botConfig.lootItemResourceRandomization.pmcbear = {"food": { "chanceMaxResourcePercent": pmcFoodMaxChance, "resourcePercent": pmcFoodResourcePercent }, "meds": { "chanceMaxResourcePercent": pmcMedMaxChance, "resourcePercent": pmcMedResourcePercent } }
|
|
||||||
this.botConfig.lootItemResourceRandomization.pmc = {"food": { "chanceMaxResourcePercent": pmcFoodMaxChance, "resourcePercent": pmcFoodResourcePercent }, "meds": { "chanceMaxResourcePercent": pmcMedMaxChance, "resourcePercent": pmcMedResourcePercent } }
|
|
||||||
}
|
|
||||||
|
|
||||||
private setPMCItemLimits(): void
|
|
||||||
{
|
|
||||||
// Clear PMC item limits
|
|
||||||
this.botConfig.itemSpawnLimits.pmc = {}
|
|
||||||
|
|
||||||
// Go through custom limits and add them
|
|
||||||
for (const [item, count] of Object.entries(this.pmcLimitedCategories))
|
|
||||||
{
|
|
||||||
this.botConfig.itemSpawnLimits.pmc[item] = count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setPMCLoot(): void
|
|
||||||
{
|
|
||||||
const allBots = this.database.getTables().bots.types;
|
|
||||||
|
|
||||||
this.pmcConfig.looseWeaponInBackpackLootMinMax.min = 0;
|
|
||||||
this.pmcConfig.looseWeaponInBackpackLootMinMax.max = 0;
|
|
||||||
this.botConfig.equipment.pmc.randomisation = [];
|
|
||||||
|
|
||||||
if (ModConfig.config.pmcLoot)
|
|
||||||
{
|
|
||||||
if (ModConfig.config.pmcLootBlacklistItems.length > 0)
|
|
||||||
{
|
|
||||||
for (const item in ModConfig.config.pmcLootBlacklistItems)
|
|
||||||
{
|
|
||||||
this.pmcConfig.backpackLoot.blacklist.push(item);
|
|
||||||
this.pmcConfig.vestLoot.blacklist.push(item);
|
|
||||||
this.pmcConfig.pocketLoot.blacklist.push(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!ModConfig.config.pmcLoot)
|
|
||||||
{
|
|
||||||
this.botConfig.disableLootOnBotTypes.push("pmcusec", "pmcbear")
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const botType in allBots)
|
|
||||||
{
|
|
||||||
if (botType == "pmcbear" || botType == "pmcusec")
|
|
||||||
{
|
|
||||||
allBots[botType].inventory.items.Backpack = {};
|
|
||||||
allBots[botType].inventory.items.Pockets = {};
|
|
||||||
allBots[botType].inventory.items.TacticalVest = {};
|
|
||||||
allBots[botType].inventory.items.SpecialLoot = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setPMCScopeWhitelist(): void
|
|
||||||
{
|
|
||||||
this.botConfig.equipment.pmc.weaponSightWhitelist = {
|
|
||||||
"5447b5fc4bdc2d87278b4567": [
|
|
||||||
"55818ad54bdc2ddc698b4569",
|
|
||||||
"55818acf4bdc2dde698b456b",
|
|
||||||
"55818ae44bdc2dde698b456c",
|
|
||||||
"55818ac54bdc2d5b648b456e",
|
|
||||||
"55818add4bdc2d5b648b456f",
|
|
||||||
"55818aeb4bdc2ddc698b456a"
|
|
||||||
],
|
|
||||||
"5447b5f14bdc2d61278b4567": [
|
|
||||||
"55818ad54bdc2ddc698b4569",
|
|
||||||
"55818acf4bdc2dde698b456b",
|
|
||||||
"55818ae44bdc2dde698b456c",
|
|
||||||
"55818ac54bdc2d5b648b456e",
|
|
||||||
"55818add4bdc2d5b648b456f",
|
|
||||||
"55818aeb4bdc2ddc698b456a"
|
|
||||||
],
|
|
||||||
"5447bedf4bdc2d87278b4568": [
|
|
||||||
"55818ad54bdc2ddc698b4569",
|
|
||||||
"55818add4bdc2d5b648b456f",
|
|
||||||
"55818ac54bdc2d5b648b456e",
|
|
||||||
"55818aeb4bdc2ddc698b456a"
|
|
||||||
],
|
|
||||||
"5447bed64bdc2d97278b4568": [
|
|
||||||
"55818ad54bdc2ddc698b4569",
|
|
||||||
"55818acf4bdc2dde698b456b",
|
|
||||||
"55818ac54bdc2d5b648b456e",
|
|
||||||
"55818add4bdc2d5b648b456f",
|
|
||||||
"55818aeb4bdc2ddc698b456a"
|
|
||||||
],
|
|
||||||
"5447b6194bdc2d67278b4567": [
|
|
||||||
"55818ad54bdc2ddc698b4569",
|
|
||||||
"55818ae44bdc2dde698b456c",
|
|
||||||
"55818ac54bdc2d5b648b456e",
|
|
||||||
"55818aeb4bdc2ddc698b456a",
|
|
||||||
"55818add4bdc2d5b648b456f"
|
|
||||||
],
|
|
||||||
"5447b5cf4bdc2d65278b4567": [
|
|
||||||
"55818ad54bdc2ddc698b4569",
|
|
||||||
"55818acf4bdc2dde698b456b",
|
|
||||||
"55818ac54bdc2d5b648b456e"
|
|
||||||
],
|
|
||||||
"617f1ef5e8b54b0998387733": [
|
|
||||||
"55818ad54bdc2ddc698b4569",
|
|
||||||
"55818acf4bdc2dde698b456b",
|
|
||||||
"55818ac54bdc2d5b648b456e"
|
|
||||||
],
|
|
||||||
"5447b6094bdc2dc3278b4567": [
|
|
||||||
"55818ad54bdc2ddc698b4569",
|
|
||||||
"55818acf4bdc2dde698b456b",
|
|
||||||
"55818ac54bdc2d5b648b456e"
|
|
||||||
],
|
|
||||||
"5447b5e04bdc2d62278b4567": [
|
|
||||||
"55818ad54bdc2ddc698b4569",
|
|
||||||
"55818acf4bdc2dde698b456b",
|
|
||||||
"55818ac54bdc2d5b648b456e"
|
|
||||||
],
|
|
||||||
"5447b6254bdc2dc3278b4568": [
|
|
||||||
"55818ae44bdc2dde698b456c",
|
|
||||||
"55818ac54bdc2d5b648b456e",
|
|
||||||
"55818aeb4bdc2ddc698b456a",
|
|
||||||
"55818add4bdc2d5b648b456f"
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private pushScavKeys(): void
|
|
||||||
{
|
|
||||||
const scavBackpack = this.tables.bots.types.assault.inventory.items.Backpack
|
|
||||||
const items = Object.values(this.tables.templates.items);
|
|
||||||
const baseClass = this.getKeyConfig();
|
|
||||||
const allKeys = items.filter(x => this.itemHelper.isOfBaseclass(x._id, baseClass));
|
|
||||||
|
|
||||||
let count = 0;
|
|
||||||
for (const key in allKeys)
|
|
||||||
{
|
|
||||||
if (scavBackpack[allKeys[key]._id] == undefined)
|
|
||||||
{
|
|
||||||
scavBackpack[allKeys[key]._id] = 1;
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `Added ${count} keys to Scav Backpacks (Key Class Added: ${baseClass})`)
|
|
||||||
}
|
|
||||||
|
|
||||||
private getKeyConfig(): BaseClasses
|
|
||||||
{
|
|
||||||
if (ModConfig.config.addAllKeysToScavs) return BaseClasses.KEY
|
|
||||||
if (ModConfig.config.addOnlyMechanicalKeysToScavs) return BaseClasses.KEY_MECHANICAL
|
|
||||||
if (ModConfig.config.addOnlyKeyCardsToScavs) return BaseClasses.KEYCARD
|
|
||||||
}
|
|
||||||
|
|
||||||
private removeScavLoot(): void
|
|
||||||
{
|
|
||||||
this.botConfig.disableLootOnBotTypes.push("assault", "marksman", "cursedassault", "assaultgroup", "crazyassaultevent");
|
|
||||||
}
|
|
||||||
|
|
||||||
private setIdenticalScavWeights(): void
|
|
||||||
{
|
|
||||||
for (const tierObject in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[tierObject].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierJson(tierNumber, true);
|
|
||||||
const scav = tierJson.scav.equipment
|
|
||||||
for (const slot in scav)
|
|
||||||
{
|
|
||||||
if (slot == "SecondPrimaryWeapon" || slot == "ArmBand") continue;
|
|
||||||
if (slot == "FirstPrimaryWeapon")
|
|
||||||
{
|
|
||||||
for (const subSlot in scav[slot])
|
|
||||||
{
|
|
||||||
for (const item in scav[slot][subSlot])
|
|
||||||
{
|
|
||||||
scav[slot][subSlot][item] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (const item in scav[slot])
|
|
||||||
{
|
|
||||||
scav[slot][item] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private removeThermalGoggles(removeSome: boolean): void
|
|
||||||
{
|
|
||||||
for (const tierObject in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[tierObject].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierModsJson(tierNumber, true);
|
|
||||||
const tatmMods = tierJson["5a16b8a9fcdbcb00165aa6ca"].mod_nvg;
|
|
||||||
const index = tatmMods.indexOf("5c11046cd174af02a012e42b");
|
|
||||||
|
|
||||||
if (removeSome && tierNumber >= ModConfig.config.startTier) continue;
|
|
||||||
if (index > -1)
|
|
||||||
{
|
|
||||||
tatmMods.splice(index, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private setPMCGameVersionWeights(): void
|
|
||||||
{
|
|
||||||
this.pmcConfig.gameVersionWeight.standard = ModConfig.config.standard;
|
|
||||||
this.pmcConfig.gameVersionWeight.left_behind = ModConfig.config.left_behind;
|
|
||||||
this.pmcConfig.gameVersionWeight.prepare_for_escape = ModConfig.config.prepare_for_escape;
|
|
||||||
this.pmcConfig.gameVersionWeight.edge_of_darkness = ModConfig.config.edge_of_darkness;
|
|
||||||
this.pmcConfig.gameVersionWeight.unheard_edition = ModConfig.config.unheard_edition;
|
|
||||||
}
|
|
||||||
|
|
||||||
private setLevelDeltas(): void
|
|
||||||
{
|
|
||||||
this.tierInformation.tiers[0].botMinLevelVariance = ModConfig.config.tier1LevelDelta[0]
|
|
||||||
this.tierInformation.tiers[0].botMaxLevelVariance = ModConfig.config.tier1LevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[1].botMinLevelVariance = ModConfig.config.tier2LevelDelta[0]
|
|
||||||
this.tierInformation.tiers[1].botMaxLevelVariance = ModConfig.config.tier2LevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[2].botMinLevelVariance = ModConfig.config.tier3LevelDelta[0]
|
|
||||||
this.tierInformation.tiers[2].botMaxLevelVariance = ModConfig.config.tier3LevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[3].botMinLevelVariance = ModConfig.config.tier4LevelDelta[0]
|
|
||||||
this.tierInformation.tiers[3].botMaxLevelVariance = ModConfig.config.tier4LevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[4].botMinLevelVariance = ModConfig.config.tier5LevelDelta[0]
|
|
||||||
this.tierInformation.tiers[4].botMaxLevelVariance = ModConfig.config.tier5LevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[5].botMinLevelVariance = ModConfig.config.tier6LevelDelta[0]
|
|
||||||
this.tierInformation.tiers[5].botMaxLevelVariance = ModConfig.config.tier6LevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[6].botMinLevelVariance = ModConfig.config.tier7LevelDelta[0]
|
|
||||||
this.tierInformation.tiers[6].botMaxLevelVariance = ModConfig.config.tier7LevelDelta[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
private setScavLevelDeltas(): void
|
|
||||||
{
|
|
||||||
this.tierInformation.tiers[0].scavMinLevelVariance = ModConfig.config.tier1ScavLevelDelta[0]
|
|
||||||
this.tierInformation.tiers[0].scavMaxLevelVariance = ModConfig.config.tier1ScavLevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[1].scavMinLevelVariance = ModConfig.config.tier2ScavLevelDelta[0]
|
|
||||||
this.tierInformation.tiers[1].scavMaxLevelVariance = ModConfig.config.tier2ScavLevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[2].scavMinLevelVariance = ModConfig.config.tier3ScavLevelDelta[0]
|
|
||||||
this.tierInformation.tiers[2].scavMaxLevelVariance = ModConfig.config.tier3ScavLevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[3].scavMinLevelVariance = ModConfig.config.tier4ScavLevelDelta[0]
|
|
||||||
this.tierInformation.tiers[3].scavMaxLevelVariance = ModConfig.config.tier4ScavLevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[4].scavMinLevelVariance = ModConfig.config.tier5ScavLevelDelta[0]
|
|
||||||
this.tierInformation.tiers[4].scavMaxLevelVariance = ModConfig.config.tier5ScavLevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[5].scavMinLevelVariance = ModConfig.config.tier6ScavLevelDelta[0]
|
|
||||||
this.tierInformation.tiers[5].scavMaxLevelVariance = ModConfig.config.tier6ScavLevelDelta[1]
|
|
||||||
|
|
||||||
this.tierInformation.tiers[6].scavMinLevelVariance = ModConfig.config.tier7ScavLevelDelta[0]
|
|
||||||
this.tierInformation.tiers[6].scavMaxLevelVariance = ModConfig.config.tier7ScavLevelDelta[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
private setPMCSlotIDsToMakeRequired(): void
|
|
||||||
{
|
|
||||||
this.botConfig.equipment.pmc.weaponSlotIdsToMakeRequired = [ "mod_reciever", "mod_stock" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
private setMuzzleChances(): void
|
|
||||||
{
|
|
||||||
for (const tierObject in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[tierObject].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierChancesJson(tierNumber);
|
|
||||||
const usec = tierJson.pmcUSEC.chances
|
|
||||||
const bear = tierJson.pmcBEAR.chances
|
|
||||||
for (const type in usec)
|
|
||||||
{
|
|
||||||
if (type == "equipment" || type == "equipmentMods" || type == "generation") continue;
|
|
||||||
|
|
||||||
const arrayPosition = tierNumber - 1;
|
|
||||||
|
|
||||||
usec[type].mod_muzzle = ModConfig.config.muzzleChance[arrayPosition]
|
|
||||||
usec[type].mod_muzzle_000 = ModConfig.config.muzzleChance[arrayPosition]
|
|
||||||
usec[type].mod_muzzle_000 = ModConfig.config.muzzleChance[arrayPosition]
|
|
||||||
|
|
||||||
bear[type].mod_muzzle = ModConfig.config.muzzleChance[arrayPosition]
|
|
||||||
bear[type].mod_muzzle_000 = ModConfig.config.muzzleChance[arrayPosition]
|
|
||||||
bear[type].mod_muzzle_000 = ModConfig.config.muzzleChance[arrayPosition]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,752 +0,0 @@
|
||||||
import { inject, injectable } from "tsyringe";
|
|
||||||
|
|
||||||
import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper";
|
|
||||||
import { BotHelper } from "@spt/helpers/BotHelper";
|
|
||||||
import { BotWeaponGeneratorHelper } from "@spt/helpers/BotWeaponGeneratorHelper";
|
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
||||||
import { PresetHelper } from "@spt/helpers/PresetHelper";
|
|
||||||
import { ProbabilityHelper } from "@spt/helpers/ProbabilityHelper";
|
|
||||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
|
||||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
|
||||||
import { IItem } from "@spt/models/eft/common/tables/IItem";
|
|
||||||
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
|
||||||
import { ModSpawn } from "@spt/models/enums/ModSpawn";
|
|
||||||
import { IFilterPlateModsForSlotByLevelResult, Result } from "@spt/models/spt/bots/IFilterPlateModsForSlotByLevelResult";
|
|
||||||
import { IGenerateEquipmentProperties } from "@spt/models/spt/bots/IGenerateEquipmentProperties";
|
|
||||||
import { ExhaustableArray } from "@spt/models/spt/server/ExhaustableArray";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
|
||||||
import { BotEquipmentFilterService } from "@spt/services/BotEquipmentFilterService";
|
|
||||||
import { BotEquipmentModPoolService } from "@spt/services/BotEquipmentModPoolService";
|
|
||||||
import { BotWeaponModLimitService } from "@spt/services/BotWeaponModLimitService";
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { ItemFilterService } from "@spt/services/ItemFilterService";
|
|
||||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
|
||||||
import { HashUtil } from "@spt/utils/HashUtil";
|
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
|
||||||
import { ICloner } from "@spt/utils/cloners/ICloner";
|
|
||||||
import { Money } from "@spt/models/enums/Money";
|
|
||||||
import { IGenerateWeaponRequest } from "@spt/models/spt/bots/IGenerateWeaponRequest";
|
|
||||||
import { IModToSpawnRequest } from "@spt/models/spt/bots/IModToSpawnRequest";
|
|
||||||
import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
|
||||||
import { IEquipmentFilterDetails } from "@spt/models/spt/config/IBotConfig";
|
|
||||||
import { BotEquipmentModGenerator } from "@spt/generators/BotEquipmentModGenerator";
|
|
||||||
import { IChooseRandomCompatibleModResult } from "@spt/models/spt/bots/IChooseRandomCompatibleModResult";
|
|
||||||
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { APBSTierGetter } from "../Utils/APBSTierGetter";
|
|
||||||
import { ModConfig } from "../Globals/ModConfig";
|
|
||||||
import { RaidInformation } from "../Globals/RaidInformation";
|
|
||||||
import { ModInformation } from "../Globals/ModInformation";
|
|
||||||
import { APBSTester } from "../Utils/APBSTester";
|
|
||||||
import { vanillaButtpads } from "../Globals/VanillaItemLists";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { RealismHelper } from "../Helpers/RealismHelper";
|
|
||||||
|
|
||||||
/** Handle profile related client events */
|
|
||||||
@injectable()
|
|
||||||
export class APBSBotEquipmentModGenerator extends BotEquipmentModGenerator
|
|
||||||
{
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
|
||||||
@inject("HashUtil") protected hashUtil: HashUtil,
|
|
||||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
||||||
@inject("ProbabilityHelper") protected probabilityHelper: ProbabilityHelper,
|
|
||||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
|
||||||
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
|
||||||
@inject("BotEquipmentFilterService") protected botEquipmentFilterService: BotEquipmentFilterService,
|
|
||||||
@inject("ItemFilterService") protected itemFilterService: ItemFilterService,
|
|
||||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
|
||||||
@inject("BotWeaponModLimitService") protected botWeaponModLimitService: BotWeaponModLimitService,
|
|
||||||
@inject("BotHelper") protected botHelper: BotHelper,
|
|
||||||
@inject("BotGeneratorHelper") protected botGeneratorHelper: BotGeneratorHelper,
|
|
||||||
@inject("BotWeaponGeneratorHelper") protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper,
|
|
||||||
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
|
||||||
@inject("PresetHelper") protected presetHelper: PresetHelper,
|
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
|
||||||
@inject("BotEquipmentModPoolService") protected botEquipmentModPoolService: BotEquipmentModPoolService,
|
|
||||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
|
||||||
@inject("PrimaryCloner") protected cloner: ICloner,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("APBSTierGetter") protected apbsTierGetter: APBSTierGetter,
|
|
||||||
@inject("RaidInformation") protected raidInformation: RaidInformation,
|
|
||||||
@inject("ModInformation") protected modInformation: ModInformation,
|
|
||||||
@inject("APBSTester") protected apbsTester: APBSTester,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger,
|
|
||||||
@inject("RealismHelper") protected realismHelper: RealismHelper
|
|
||||||
)
|
|
||||||
{
|
|
||||||
super(logger,
|
|
||||||
hashUtil,
|
|
||||||
randomUtil,
|
|
||||||
probabilityHelper,
|
|
||||||
databaseService,
|
|
||||||
itemHelper,
|
|
||||||
botEquipmentFilterService,
|
|
||||||
itemFilterService,
|
|
||||||
profileHelper,
|
|
||||||
botWeaponModLimitService,
|
|
||||||
botHelper,
|
|
||||||
botGeneratorHelper,
|
|
||||||
botWeaponGeneratorHelper,
|
|
||||||
weightedRandomHelper,
|
|
||||||
presetHelper,
|
|
||||||
localisationService,
|
|
||||||
botEquipmentModPoolService,
|
|
||||||
configServer,
|
|
||||||
cloner)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override generateModsForEquipment(equipment: IItem[], parentId: string, parentTemplate: ITemplateItem, settings: IGenerateEquipmentProperties, specificBlacklist: IEquipmentFilterDetails, shouldForceSpawn: boolean): IItem[]
|
|
||||||
{
|
|
||||||
let forceSpawn = shouldForceSpawn;
|
|
||||||
|
|
||||||
const botRole = settings.botData.role;
|
|
||||||
const tier = this.apbsTierGetter.getTierByLevel(settings.botData.level);
|
|
||||||
const tieredModPool = this.apbsEquipmentGetter.getModsByBotRole(botRole, tier)
|
|
||||||
|
|
||||||
let spawnChances = this.apbsEquipmentGetter.getSpawnChancesByBotRole(botRole, tier);
|
|
||||||
let compatibleModsPool = tieredModPool[parentTemplate._id]
|
|
||||||
let actualModPool = tieredModPool;
|
|
||||||
|
|
||||||
if (!this.raidInformation.isBotEnabled(botRole))
|
|
||||||
{
|
|
||||||
spawnChances = settings.spawnChances;
|
|
||||||
compatibleModsPool = settings.modPool[parentTemplate._id];
|
|
||||||
actualModPool = settings.modPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!compatibleModsPool)
|
|
||||||
{
|
|
||||||
this.logger.warning(
|
|
||||||
`bot: ${botRole} lacks a mod slot pool for item: ${parentTemplate._id} ${parentTemplate._name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate over mod pool and choose mods to add to item
|
|
||||||
for (const modSlotName in compatibleModsPool)
|
|
||||||
{
|
|
||||||
if (modSlotName === "mod_equipment_000" && this.raidInformation.nightTime) continue;
|
|
||||||
|
|
||||||
if (modSlotName === "mod_equipment" && this.realismHelper.gasMasks.includes(parentTemplate._id) && this.realismHelper.realismDetected == true)
|
|
||||||
{
|
|
||||||
forceSpawn = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const itemSlotTemplate = this.getModItemSlotFromDb(modSlotName, parentTemplate);
|
|
||||||
if (!itemSlotTemplate)
|
|
||||||
{
|
|
||||||
this.logger.error(
|
|
||||||
this.localisationService.getText("bot-mod_slot_missing_from_item", {
|
|
||||||
modSlot: modSlotName,
|
|
||||||
parentId: parentTemplate._id,
|
|
||||||
parentName: parentTemplate._name,
|
|
||||||
botRole: settings.botData.role
|
|
||||||
})
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const modSpawnResult = this.shouldModBeSpawned(
|
|
||||||
itemSlotTemplate,
|
|
||||||
modSlotName.toLowerCase(),
|
|
||||||
spawnChances.equipmentMods,
|
|
||||||
settings.botEquipmentConfig
|
|
||||||
);
|
|
||||||
if (modSpawnResult === ModSpawn.SKIP && !forceSpawn)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure submods for nvgs all spawn together if it's night
|
|
||||||
if (modSlotName === "mod_nvg")
|
|
||||||
{
|
|
||||||
if (this.raidInformation.nightTime)
|
|
||||||
{
|
|
||||||
forceSpawn = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let modPoolToChooseFrom = compatibleModsPool[modSlotName];
|
|
||||||
if (
|
|
||||||
settings.botEquipmentConfig.filterPlatesByLevel
|
|
||||||
&& this.itemHelper.isRemovablePlateSlot(modSlotName.toLowerCase())
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const outcome = this.filterPlateModsForSlotByLevel(
|
|
||||||
settings,
|
|
||||||
modSlotName.toLowerCase(),
|
|
||||||
compatibleModsPool[modSlotName],
|
|
||||||
parentTemplate
|
|
||||||
);
|
|
||||||
if ([Result.UNKNOWN_FAILURE, Result.NO_DEFAULT_FILTER].includes(outcome.result))
|
|
||||||
{
|
|
||||||
this.logger.debug(
|
|
||||||
`Plate slot: ${modSlotName} selection for armor: ${parentTemplate._id} failed: ${
|
|
||||||
Result[outcome.result]
|
|
||||||
}, skipping`
|
|
||||||
);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([Result.LACKS_PLATE_WEIGHTS].includes(outcome.result))
|
|
||||||
{
|
|
||||||
this.logger.warning(
|
|
||||||
`Plate slot: ${modSlotName} lacks weights for armor: ${parentTemplate._id}, unable to adjust plate choice, using existing data`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
modPoolToChooseFrom = outcome.plateModTpls;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find random mod and check its compatible
|
|
||||||
let modTpl: string | undefined;
|
|
||||||
let found = false;
|
|
||||||
const exhaustableModPool = new ExhaustableArray<string>(modPoolToChooseFrom, this.randomUtil, this.cloner);
|
|
||||||
while (exhaustableModPool.hasValues())
|
|
||||||
{
|
|
||||||
modTpl = exhaustableModPool.getRandomValue();
|
|
||||||
if (modTpl
|
|
||||||
&& !this.botGeneratorHelper.isItemIncompatibleWithCurrentItems(equipment, modTpl, modSlotName)
|
|
||||||
.incompatible
|
|
||||||
)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compatible item not found but slot REQUIRES item, get random item from db
|
|
||||||
if (!found && itemSlotTemplate._required)
|
|
||||||
{
|
|
||||||
modTpl = this.getRandomModTplFromItemDb(modTpl, itemSlotTemplate, modSlotName, equipment);
|
|
||||||
found = !!modTpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compatible item not found + not required
|
|
||||||
if (!(found || itemSlotTemplate._required))
|
|
||||||
{
|
|
||||||
// Don't add item
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const modTemplate = this.itemHelper.getItem(modTpl);
|
|
||||||
if (!this.isModValidForSlot(modTemplate, itemSlotTemplate, modSlotName, parentTemplate, botRole))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate new id to ensure all items are unique on bot
|
|
||||||
const modId = this.hashUtil.generate();
|
|
||||||
equipment.push(this.createModItem(modId, modTpl, parentId, modSlotName, modTemplate[1], botRole));
|
|
||||||
|
|
||||||
// Does the item being added have possible child mods?
|
|
||||||
if (Object.keys(actualModPool).includes(modTpl))
|
|
||||||
{
|
|
||||||
// Call self recursively with item being checkced item we just added to bot
|
|
||||||
this.generateModsForEquipment(
|
|
||||||
equipment,
|
|
||||||
modId,
|
|
||||||
modTemplate[1],
|
|
||||||
settings,
|
|
||||||
specificBlacklist,
|
|
||||||
forceSpawn
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is for testing...
|
|
||||||
if (this.modInformation.testMode && this.modInformation.testBotRole.includes(botRole.toLowerCase()))
|
|
||||||
{
|
|
||||||
const tables = this.databaseService.getTables();
|
|
||||||
const assortEquipment = this.cloner.clone(equipment);
|
|
||||||
for (const item in assortEquipment)
|
|
||||||
{
|
|
||||||
const oldID = assortEquipment[item]._id
|
|
||||||
const newID = this.hashUtil.generate();
|
|
||||||
assortEquipment[item]._id = newID;
|
|
||||||
|
|
||||||
// Loop array again to fix parentID
|
|
||||||
for (const i in assortEquipment)
|
|
||||||
{
|
|
||||||
if (assortEquipment[i].parentId == oldID)
|
|
||||||
{
|
|
||||||
assortEquipment[i].parentId = newID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.apbsTester.createComplexAssortItem(assortEquipment)
|
|
||||||
.addUnlimitedStackCount()
|
|
||||||
.addMoneyCost(Money.ROUBLES, 20000)
|
|
||||||
.addBuyRestriction(3)
|
|
||||||
.addLoyaltyLevel(1)
|
|
||||||
.export(tables.traders[this.modInformation.testTrader]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return equipment;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override filterPlateModsForSlotByLevel(settings: IGenerateEquipmentProperties, modSlot: string, existingPlateTplPool: string[], armorItem: ITemplateItem): IFilterPlateModsForSlotByLevelResult
|
|
||||||
{
|
|
||||||
const result: IFilterPlateModsForSlotByLevelResult = { result: Result.UNKNOWN_FAILURE, plateModTpls: undefined };
|
|
||||||
|
|
||||||
// Not pmc or not a plate slot, return original mod pool array
|
|
||||||
if (!this.itemHelper.isRemovablePlateSlot(modSlot))
|
|
||||||
{
|
|
||||||
result.result = Result.NOT_PLATE_HOLDING_SLOT;
|
|
||||||
result.plateModTpls = existingPlateTplPool;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the front/back/side weights based on bots level
|
|
||||||
const plateSlotWeights = settings.botEquipmentConfig?.armorPlateWeighting?.find(
|
|
||||||
(armorWeight) =>
|
|
||||||
settings.botData.level >= armorWeight.levelRange.min && settings.botData.level <= armorWeight.levelRange.max);
|
|
||||||
if (!plateSlotWeights)
|
|
||||||
{
|
|
||||||
// No weights, return original array of plate tpls
|
|
||||||
result.result = Result.LACKS_PLATE_WEIGHTS;
|
|
||||||
result.plateModTpls = existingPlateTplPool;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the specific plate slot weights (front/back/side)
|
|
||||||
const plateWeights: Record<string, number> = plateSlotWeights[modSlot];
|
|
||||||
if (!plateWeights)
|
|
||||||
{
|
|
||||||
// No weights, return original array of plate tpls
|
|
||||||
result.result = Result.LACKS_PLATE_WEIGHTS;
|
|
||||||
result.plateModTpls = existingPlateTplPool;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Choose a plate level based on weighting
|
|
||||||
let chosenArmorPlateLevel = this.weightedRandomHelper.getWeightedValue<string>(plateWeights);
|
|
||||||
|
|
||||||
// Convert the array of ids into database items
|
|
||||||
let platesFromDb = existingPlateTplPool.map((plateTpl) => this.itemHelper.getItem(plateTpl)[1]);
|
|
||||||
|
|
||||||
// Filter plates to the chosen level based on its armorClass property
|
|
||||||
let platesOfDesiredLevel = platesFromDb.filter((item) => item._props.armorClass === chosenArmorPlateLevel);
|
|
||||||
let tries = 0;
|
|
||||||
while (platesOfDesiredLevel.length === 0)
|
|
||||||
{
|
|
||||||
tries++;
|
|
||||||
chosenArmorPlateLevel = (parseInt(chosenArmorPlateLevel)+1).toString()
|
|
||||||
if (parseInt(chosenArmorPlateLevel) > 6)
|
|
||||||
{
|
|
||||||
chosenArmorPlateLevel = "3"
|
|
||||||
}
|
|
||||||
platesFromDb = existingPlateTplPool.map((plateTpl) => this.itemHelper.getItem(plateTpl)[1]);
|
|
||||||
platesOfDesiredLevel = platesFromDb.filter((item) => item._props.armorClass === chosenArmorPlateLevel);
|
|
||||||
|
|
||||||
if (platesOfDesiredLevel.length > 0) break;
|
|
||||||
if (tries >= 3) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (platesOfDesiredLevel.length === 0)
|
|
||||||
{
|
|
||||||
this.logger.debug(`${settings.botData.role} - Plate filter was too restrictive for armor: ${armorItem._id}. Tried ${tries} times. Using mod items default plate.`);
|
|
||||||
|
|
||||||
const relatedItemDbModSlot = armorItem._props.Slots.find((slot) => slot._name.toLowerCase() === modSlot);
|
|
||||||
const defaultPlate = relatedItemDbModSlot._props.filters[0].Plate;
|
|
||||||
if (!defaultPlate)
|
|
||||||
{
|
|
||||||
// No relevant plate found after filtering AND no default plate
|
|
||||||
|
|
||||||
// Last attempt, get default preset and see if it has a plate default
|
|
||||||
const defaultPreset = this.presetHelper.getDefaultPreset(armorItem._id);
|
|
||||||
if (defaultPreset)
|
|
||||||
{
|
|
||||||
const relatedPresetSlot = defaultPreset._items.find(
|
|
||||||
(item) => item.slotId?.toLowerCase() === modSlot);
|
|
||||||
if (relatedPresetSlot)
|
|
||||||
{
|
|
||||||
result.result = Result.SUCCESS;
|
|
||||||
result.plateModTpls = [relatedPresetSlot._tpl];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Return Default Preset cause didn't have default plates
|
|
||||||
result.result = Result.NO_DEFAULT_FILTER;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// Return Default Plates cause couldn't get lowest level available from original selection
|
|
||||||
result.result = Result.SUCCESS;
|
|
||||||
result.plateModTpls = [defaultPlate];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only return the items ids
|
|
||||||
result.result = Result.SUCCESS;
|
|
||||||
result.plateModTpls = platesOfDesiredLevel.map((item) => item._id);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override getCompatibleModFromPool(
|
|
||||||
modPool: string[],
|
|
||||||
modSpawnType: ModSpawn,
|
|
||||||
weapon: IItem[]
|
|
||||||
): IChooseRandomCompatibleModResult
|
|
||||||
{
|
|
||||||
// Create exhaustable pool to pick mod item from
|
|
||||||
const exhaustableModPool = this.createExhaustableArray(modPool);
|
|
||||||
|
|
||||||
// Create default response if no compatible item is found below
|
|
||||||
const chosenModResult: IChooseRandomCompatibleModResult = {
|
|
||||||
incompatible: true,
|
|
||||||
found: false,
|
|
||||||
reason: "unknown"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Limit how many attempts to find a compatible mod can occur before giving up
|
|
||||||
const maxBlockedAttempts = Math.round(modPool.length); // 75% of pool size
|
|
||||||
let blockedAttemptCount = 0;
|
|
||||||
let chosenTpl: string;
|
|
||||||
while (exhaustableModPool.hasValues())
|
|
||||||
{
|
|
||||||
chosenTpl = exhaustableModPool.getRandomValue();
|
|
||||||
const pickedItemDetails = this.itemHelper.getItem(chosenTpl);
|
|
||||||
if (!pickedItemDetails[0])
|
|
||||||
{
|
|
||||||
// Not valid item, try again
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pickedItemDetails[1]._props)
|
|
||||||
{
|
|
||||||
// no props data, try again
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success - Default wanted + only 1 item in pool
|
|
||||||
if (modSpawnType === ModSpawn.DEFAULT_MOD && modPool.length === 1)
|
|
||||||
{
|
|
||||||
chosenModResult.found = true;
|
|
||||||
chosenModResult.incompatible = false;
|
|
||||||
chosenModResult.chosenTpl = chosenTpl;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if existing weapon mods are incompatible with chosen item
|
|
||||||
const existingItemBlockingChoice = weapon.find((item) =>
|
|
||||||
pickedItemDetails[1]._props.ConflictingItems?.includes(item._tpl)
|
|
||||||
);
|
|
||||||
if (existingItemBlockingChoice)
|
|
||||||
{
|
|
||||||
// Give max of x attempts of picking a mod if blocked by another
|
|
||||||
if (blockedAttemptCount > maxBlockedAttempts)
|
|
||||||
{
|
|
||||||
blockedAttemptCount = 0; // reset
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockedAttemptCount++;
|
|
||||||
|
|
||||||
// Not compatible - Try again
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Edge case- Some mod combos will never work, make sure this isnt the case
|
|
||||||
if (this.weaponModComboIsIncompatible(weapon, chosenTpl))
|
|
||||||
{
|
|
||||||
chosenModResult.reason = `Chosen weapon mod: ${chosenTpl} can never be compatible with existing weapon mods`;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
chosenModResult.found = true;
|
|
||||||
chosenModResult.incompatible = false;
|
|
||||||
chosenModResult.chosenTpl = chosenTpl;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return chosenModResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
public apbsGenerateModsForWeapon(sessionId: string, request: IGenerateWeaponRequest, isPmc: boolean): IItem[]
|
|
||||||
{
|
|
||||||
const pmcProfile = this.profileHelper.getPmcProfile(sessionId);
|
|
||||||
|
|
||||||
// Get pool of mods that fit weapon
|
|
||||||
const compatibleModsPool = request.modPool[request.parentTemplate._id];
|
|
||||||
|
|
||||||
if (
|
|
||||||
!(
|
|
||||||
request.parentTemplate._props.Slots.length ||
|
|
||||||
request.parentTemplate._props.Cartridges?.length ||
|
|
||||||
request.parentTemplate._props.Chambers?.length
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this.logger.error(
|
|
||||||
this.localisationService.getText("bot-unable_to_add_mods_to_weapon_missing_ammo_slot", {
|
|
||||||
weaponName: request.parentTemplate._name,
|
|
||||||
weaponId: request.parentTemplate._id,
|
|
||||||
botRole: request.botData.role
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return request.weapon;
|
|
||||||
}
|
|
||||||
|
|
||||||
const botEquipConfig = this.botConfig.equipment[request.botData.equipmentRole];
|
|
||||||
const botEquipBlacklist = this.botEquipmentFilterService.getBotEquipmentBlacklist(
|
|
||||||
request.botData.equipmentRole,
|
|
||||||
pmcProfile.Info.Level
|
|
||||||
);
|
|
||||||
const botWeaponSightWhitelist = this.botEquipmentFilterService.getBotWeaponSightWhitelist(
|
|
||||||
request.botData.equipmentRole
|
|
||||||
);
|
|
||||||
const randomisationSettings = this.botHelper.getBotRandomizationDetails(request.botData.level, botEquipConfig);
|
|
||||||
|
|
||||||
// Iterate over mod pool and choose mods to attach
|
|
||||||
const sortedModKeys = this.sortModKeys(Object.keys(compatibleModsPool), request.parentTemplate._id);
|
|
||||||
for (const modSlot of sortedModKeys)
|
|
||||||
{
|
|
||||||
// Check weapon has slot for mod to fit in
|
|
||||||
const modsParentSlot = this.getModItemSlotFromDb(modSlot, request.parentTemplate);
|
|
||||||
if (!modsParentSlot)
|
|
||||||
{
|
|
||||||
this.logger.error(
|
|
||||||
this.localisationService.getText("bot-weapon_missing_mod_slot", {
|
|
||||||
modSlot: modSlot,
|
|
||||||
weaponId: request.parentTemplate._id,
|
|
||||||
weaponName: request.parentTemplate._name,
|
|
||||||
botRole: request.botData.role
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check spawn chance of mod
|
|
||||||
const modSpawnResult = this.shouldModBeSpawned(
|
|
||||||
modsParentSlot,
|
|
||||||
modSlot,
|
|
||||||
request.modSpawnChances,
|
|
||||||
botEquipConfig
|
|
||||||
);
|
|
||||||
if (modSpawnResult === ModSpawn.SKIP)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isRandomisableSlot = randomisationSettings?.randomisedWeaponModSlots?.includes(modSlot) ?? false;
|
|
||||||
const modToSpawnRequest: IModToSpawnRequest = {
|
|
||||||
modSlot: modSlot,
|
|
||||||
isRandomisableSlot: isRandomisableSlot,
|
|
||||||
randomisationSettings: randomisationSettings,
|
|
||||||
botWeaponSightWhitelist: botWeaponSightWhitelist,
|
|
||||||
botEquipBlacklist: botEquipBlacklist,
|
|
||||||
itemModPool: compatibleModsPool,
|
|
||||||
weapon: request.weapon,
|
|
||||||
ammoTpl: request.ammoTpl,
|
|
||||||
parentTemplate: request.parentTemplate,
|
|
||||||
modSpawnResult: modSpawnResult,
|
|
||||||
weaponStats: request.weaponStats,
|
|
||||||
conflictingItemTpls: request.conflictingItemTpls,
|
|
||||||
botData: request.botData
|
|
||||||
};
|
|
||||||
const modToAdd = this.chooseModToPutIntoSlot(modToSpawnRequest);
|
|
||||||
|
|
||||||
// Compatible mod not found
|
|
||||||
if (!modToAdd || typeof modToAdd === "undefined")
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
!this.isModValidForSlot(modToAdd, modsParentSlot, modSlot, request.parentTemplate, request.botData.role)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const modToAddTemplate = modToAdd[1];
|
|
||||||
// Skip adding mod to weapon if type limit reached
|
|
||||||
if (
|
|
||||||
this.botWeaponModLimitService.weaponModHasReachedLimit(
|
|
||||||
request.botData.equipmentRole,
|
|
||||||
modToAddTemplate,
|
|
||||||
request.modLimits,
|
|
||||||
request.parentTemplate,
|
|
||||||
request.weapon
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vanillaButtpads.includes(modToAddTemplate._id))
|
|
||||||
{
|
|
||||||
if (!this.randomUtil.getChance100(ModConfig.config.stockButtpadChance))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If item is a mount for scopes, set scope chance to 100%, this helps fix empty mounts appearing on weapons
|
|
||||||
if (this.modSlotCanHoldScope(modSlot, modToAddTemplate._parent))
|
|
||||||
{
|
|
||||||
// mod_mount was picked to be added to weapon, force scope chance to ensure its filled
|
|
||||||
let scopeSlots = ["mod_scope", "mod_scope_000", "mod_scope_001", "mod_scope_002", "mod_scope_003"];
|
|
||||||
if (isPmc) scopeSlots = ["mod_scope", "mod_scope_000"]
|
|
||||||
|
|
||||||
this.adjustSlotSpawnChances(request.modSpawnChances, scopeSlots, 100);
|
|
||||||
|
|
||||||
// Hydrate pool of mods that fit into mount as its a randomisable slot
|
|
||||||
if (isRandomisableSlot)
|
|
||||||
{
|
|
||||||
// Add scope mods to modPool dictionary to ensure the mount has a scope in the pool to pick
|
|
||||||
this.addCompatibleModsForProvidedMod(
|
|
||||||
"mod_scope",
|
|
||||||
modToAddTemplate,
|
|
||||||
request.modPool,
|
|
||||||
botEquipBlacklist
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (ModConfig.config.forceChildrenMuzzle)
|
|
||||||
{
|
|
||||||
// If picked item is muzzle adapter that can hold a child, adjust spawn chance
|
|
||||||
if (this.modSlotCanHoldMuzzleDevices(modSlot, modToAddTemplate._parent))
|
|
||||||
{
|
|
||||||
const muzzleSlots = ["mod_muzzle", "mod_muzzle_000", "mod_muzzle_001"];
|
|
||||||
this.adjustSlotSpawnChances(request.modSpawnChances, muzzleSlots, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If front/rear sight are to be added, set opposite to 100% chance
|
|
||||||
if (this.modIsFrontOrRearSight(modSlot, modToAddTemplate._id))
|
|
||||||
{
|
|
||||||
request.modSpawnChances.mod_sight_front = 100;
|
|
||||||
request.modSpawnChances.mod_sight_rear = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handguard mod can take a sub handguard mod + weapon has no UBGL (takes same slot)
|
|
||||||
// Force spawn chance to be 100% to ensure it gets added
|
|
||||||
if (
|
|
||||||
modSlot === "mod_handguard" &&
|
|
||||||
modToAddTemplate._props.Slots.some((slot) => slot._name === "mod_handguard") &&
|
|
||||||
!request.weapon.some((item) => item.slotId === "mod_launcher")
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Needed for handguards with lower
|
|
||||||
request.modSpawnChances.mod_handguard = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If stock mod can take a sub stock mod, force spawn chance to be 100% to ensure sub-stock gets added
|
|
||||||
// Or if mod_stock is configured to be forced on
|
|
||||||
if (this.shouldForceSubStockSlots(modSlot, botEquipConfig, modToAddTemplate))
|
|
||||||
{
|
|
||||||
// Stock mod can take additional stocks, could be a locking device, force 100% chance
|
|
||||||
const subStockSlots = ["mod_stock", "mod_stock_000", "mod_stock_001", "mod_stock_akms"];
|
|
||||||
this.adjustSlotSpawnChances(request.modSpawnChances, subStockSlots, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gather stats on mods being added to weapon
|
|
||||||
if (this.itemHelper.isOfBaseclass(modToAddTemplate._id, BaseClasses.IRON_SIGHT))
|
|
||||||
{
|
|
||||||
if (modSlot === "mod_sight_front")
|
|
||||||
{
|
|
||||||
request.weaponStats.hasFrontIronSight = true;
|
|
||||||
}
|
|
||||||
else if (modSlot === "mod_sight_rear")
|
|
||||||
{
|
|
||||||
request.weaponStats.hasRearIronSight = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (
|
|
||||||
!request.weaponStats.hasOptic &&
|
|
||||||
this.itemHelper.isOfBaseclass(modToAddTemplate._id, BaseClasses.SIGHTS)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
request.weaponStats.hasOptic = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const modId = this.hashUtil.generate();
|
|
||||||
request.weapon.push(
|
|
||||||
this.createModItem(
|
|
||||||
modId,
|
|
||||||
modToAddTemplate._id,
|
|
||||||
request.weaponId,
|
|
||||||
modSlot,
|
|
||||||
modToAddTemplate,
|
|
||||||
request.botData.role
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Update conflicting item list now item has been chosen
|
|
||||||
for (const conflictingItem of modToAddTemplate._props.ConflictingItems)
|
|
||||||
{
|
|
||||||
request.conflictingItemTpls.add(conflictingItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
// I first thought we could use the recursive generateModsForItems as previously for cylinder magazines.
|
|
||||||
// However, the recursion doesn't go over the slots of the parent mod but over the modPool which is given by the bot config
|
|
||||||
// where we decided to keep cartridges instead of camoras. And since a CylinderMagazine only has one cartridge entry and
|
|
||||||
// this entry is not to be filled, we need a special handling for the CylinderMagazine
|
|
||||||
const modParentItem = this.itemHelper.getItem(modToAddTemplate._parent)[1];
|
|
||||||
if (this.botWeaponGeneratorHelper.magazineIsCylinderRelated(modParentItem._name))
|
|
||||||
{
|
|
||||||
// We don't have child mods, we need to create the camoras for the magazines instead
|
|
||||||
this.fillCamora(request.weapon, request.modPool, modId, modToAddTemplate);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
let containsModInPool = Object.keys(request.modPool).includes(modToAddTemplate._id);
|
|
||||||
|
|
||||||
// Sometimes randomised slots are missing sub-mods, if so, get values from mod pool service
|
|
||||||
// Check for a randomisable slot + without data in modPool + item being added as additional slots
|
|
||||||
if (isRandomisableSlot && !containsModInPool && modToAddTemplate._props.Slots.length > 0)
|
|
||||||
{
|
|
||||||
const modFromService = this.botEquipmentModPoolService.getModsForWeaponSlot(modToAddTemplate._id);
|
|
||||||
if (Object.keys(modFromService ?? {}).length > 0)
|
|
||||||
{
|
|
||||||
request.modPool[modToAddTemplate._id] = modFromService;
|
|
||||||
containsModInPool = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (containsModInPool)
|
|
||||||
{
|
|
||||||
const recursiveRequestData: IGenerateWeaponRequest = {
|
|
||||||
weapon: request.weapon,
|
|
||||||
modPool: request.modPool,
|
|
||||||
weaponId: modId,
|
|
||||||
parentTemplate: modToAddTemplate,
|
|
||||||
modSpawnChances: request.modSpawnChances,
|
|
||||||
ammoTpl: request.ammoTpl,
|
|
||||||
botData: {
|
|
||||||
role: request.botData.role,
|
|
||||||
level: request.botData.level,
|
|
||||||
equipmentRole: request.botData.equipmentRole
|
|
||||||
},
|
|
||||||
modLimits: request.modLimits,
|
|
||||||
weaponStats: request.weaponStats,
|
|
||||||
conflictingItemTpls: request.conflictingItemTpls
|
|
||||||
};
|
|
||||||
// Call self recursively to add mods to this mod
|
|
||||||
this.apbsGenerateModsForWeapon(sessionId, recursiveRequestData, isPmc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return request.weapon;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
import { inject, injectable } from "tsyringe";
|
|
||||||
|
|
||||||
import { BotHelper } from "@spt/helpers/BotHelper";
|
|
||||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
|
||||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
|
||||||
import { BotEquipmentFilterService } from "@spt/services/BotEquipmentFilterService";
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { ItemFilterService } from "@spt/services/ItemFilterService";
|
|
||||||
import { HashUtil } from "@spt/utils/HashUtil";
|
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
|
||||||
import { ICloner } from "@spt/utils/cloners/ICloner";
|
|
||||||
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { APBSTierGetter } from "../Utils/APBSTierGetter";
|
|
||||||
import { BotGenerator } from "@spt/generators/BotGenerator";
|
|
||||||
import { BotInventoryGenerator } from "@spt/generators/BotInventoryGenerator";
|
|
||||||
import { BotLevelGenerator } from "@spt/generators/BotLevelGenerator";
|
|
||||||
import { SeasonalEventService } from "@spt/services/SeasonalEventService";
|
|
||||||
import { TimeUtil } from "@spt/utils/TimeUtil";
|
|
||||||
import { IBotBase } from "@spt/models/eft/common/tables/IBotBase";
|
|
||||||
import { IAppearance } from "@spt/models/eft/common/tables/IBotType";
|
|
||||||
import { IBotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails";
|
|
||||||
import { IWildBody } from "@spt/models/eft/common/IGlobals";
|
|
||||||
import { BotNameService } from "@spt/services/BotNameService";
|
|
||||||
import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper";
|
|
||||||
import { ModConfig } from "../Globals/ModConfig";
|
|
||||||
|
|
||||||
/** Handle profile related client events */
|
|
||||||
@injectable()
|
|
||||||
export class APBSBotGenerator extends BotGenerator
|
|
||||||
{
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
|
||||||
@inject("HashUtil") protected hashUtil: HashUtil,
|
|
||||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
||||||
@inject("TimeUtil") protected timeUtil: TimeUtil,
|
|
||||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
|
||||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
|
||||||
@inject("BotInventoryGenerator") protected botInventoryGenerator: BotInventoryGenerator,
|
|
||||||
@inject("BotLevelGenerator") protected botLevelGenerator: BotLevelGenerator,
|
|
||||||
@inject("BotEquipmentFilterService") protected botEquipmentFilterService: BotEquipmentFilterService,
|
|
||||||
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
|
||||||
@inject("BotHelper") protected botHelper: BotHelper,
|
|
||||||
@inject("BotGeneratorHelper") protected botGeneratorHelper: BotGeneratorHelper,
|
|
||||||
@inject("SeasonalEventService") protected seasonalEventService: SeasonalEventService,
|
|
||||||
@inject("ItemFilterService") protected itemFilterService: ItemFilterService,
|
|
||||||
@inject("BotNameService") protected botNameService: BotNameService,
|
|
||||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
|
||||||
@inject("PrimaryCloner") protected cloner: ICloner,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("APBSTierGetter") protected apbsTierGetter: APBSTierGetter
|
|
||||||
)
|
|
||||||
{
|
|
||||||
super(logger,
|
|
||||||
hashUtil,
|
|
||||||
randomUtil,
|
|
||||||
timeUtil,
|
|
||||||
profileHelper,
|
|
||||||
databaseService,
|
|
||||||
botInventoryGenerator,
|
|
||||||
botLevelGenerator,
|
|
||||||
botEquipmentFilterService,
|
|
||||||
weightedRandomHelper,
|
|
||||||
botHelper,
|
|
||||||
botGeneratorHelper,
|
|
||||||
seasonalEventService,
|
|
||||||
itemFilterService,
|
|
||||||
botNameService,
|
|
||||||
configServer,
|
|
||||||
cloner)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override setBotAppearance(bot: IBotBase, appearance: IAppearance, botGenerationDetails: IBotGenerationDetails): void
|
|
||||||
{
|
|
||||||
if (botGenerationDetails.isPmc)
|
|
||||||
{
|
|
||||||
const tier = this.apbsTierGetter.getTierByLevel(bot.Info.Level)
|
|
||||||
const role = bot.Info.Settings.Role
|
|
||||||
const getSeasonalAppearance = ModConfig.config.seasonalPmcAppearance ? true : false;
|
|
||||||
const appearanceJson = this.apbsEquipmentGetter.getPmcAppearance(role, tier, getSeasonalAppearance);
|
|
||||||
|
|
||||||
bot.Customization.Head = this.weightedRandomHelper.getWeightedValue<string>(appearanceJson.head);
|
|
||||||
bot.Customization.Hands = this.weightedRandomHelper.getWeightedValue<string>(appearanceJson.hands);
|
|
||||||
bot.Customization.Body = this.weightedRandomHelper.getWeightedValue<string>(appearanceJson.body);
|
|
||||||
bot.Customization.Feet = this.weightedRandomHelper.getWeightedValue<string>(appearanceJson.feet);
|
|
||||||
|
|
||||||
const bodyGlobalDict = this.databaseService.getGlobals().config.Customization.SavageBody;
|
|
||||||
const chosenBodyTemplate = this.databaseService.getCustomization()[bot.Customization.Body];
|
|
||||||
|
|
||||||
// Find the body/hands mapping
|
|
||||||
const matchingBody: IWildBody = bodyGlobalDict[chosenBodyTemplate?._name];
|
|
||||||
if (matchingBody?.isNotRandom)
|
|
||||||
{
|
|
||||||
// Has fixed hands for this body, set them
|
|
||||||
bot.Customization.Hands = matchingBody.hands;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bot.Customization.Head = this.weightedRandomHelper.getWeightedValue<string>(appearance.head);
|
|
||||||
bot.Customization.Body = this.weightedRandomHelper.getWeightedValue<string>(appearance.body);
|
|
||||||
bot.Customization.Feet = this.weightedRandomHelper.getWeightedValue<string>(appearance.feet);
|
|
||||||
bot.Customization.Hands = this.weightedRandomHelper.getWeightedValue<string>(appearance.hands);
|
|
||||||
|
|
||||||
const bodyGlobalDict = this.databaseService.getGlobals().config.Customization.SavageBody;
|
|
||||||
const chosenBodyTemplate = this.databaseService.getCustomization()[bot.Customization.Body];
|
|
||||||
|
|
||||||
// Find the body/hands mapping
|
|
||||||
const matchingBody: IWildBody = bodyGlobalDict[chosenBodyTemplate?._name];
|
|
||||||
if (matchingBody?.isNotRandom)
|
|
||||||
{
|
|
||||||
// Has fixed hands for this body, set them
|
|
||||||
bot.Customization.Hands = matchingBody.hands;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,375 +0,0 @@
|
||||||
import { inject, injectable } from "tsyringe";
|
|
||||||
|
|
||||||
import { BotEquipmentModGenerator } from "@spt/generators/BotEquipmentModGenerator";
|
|
||||||
import { BotLootGenerator } from "@spt/generators/BotLootGenerator";
|
|
||||||
import { BotWeaponGenerator } from "@spt/generators/BotWeaponGenerator";
|
|
||||||
import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper";
|
|
||||||
import { BotHelper } from "@spt/helpers/BotHelper";
|
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
||||||
import { ContextVariableType } from "@spt/context/ContextVariableType";
|
|
||||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
|
||||||
import { IInventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase";
|
|
||||||
import { IChances, IGeneration, IBotType, IInventory } from "@spt/models/eft/common/tables/IBotType";
|
|
||||||
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
|
||||||
import { EquipmentSlots } from "@spt/models/enums/EquipmentSlots";
|
|
||||||
import { IGenerateEquipmentProperties } from "@spt/models/spt/bots/IGenerateEquipmentProperties";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
|
||||||
import { BotEquipmentModPoolService } from "@spt/services/BotEquipmentModPoolService";
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
|
||||||
import { HashUtil } from "@spt/utils/HashUtil";
|
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
|
||||||
|
|
||||||
import { BotInventoryGenerator } from "@spt/generators/BotInventoryGenerator";
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { APBSTierGetter } from "../Utils/APBSTierGetter";
|
|
||||||
import { ModConfig } from "../Globals/ModConfig";
|
|
||||||
import { APBSBotWeaponGenerator } from "../ClassExtensions/APBSBotWeaponGenerator";
|
|
||||||
import { ApplicationContext } from "@spt/context/ApplicationContext";
|
|
||||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
|
||||||
import { WeatherHelper } from "@spt/helpers/WeatherHelper";
|
|
||||||
import { BotEquipmentFilterService } from "@spt/services/BotEquipmentFilterService";
|
|
||||||
import { IGetRaidConfigurationRequestData } from "@spt/models/eft/match/IGetRaidConfigurationRequestData";
|
|
||||||
import { RaidInformation } from "../Globals/RaidInformation";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { Logging } from "../Enums/Logging";
|
|
||||||
|
|
||||||
/** Handle profile related client events */
|
|
||||||
@injectable()
|
|
||||||
export class APBSBotInventoryGenerator extends BotInventoryGenerator
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
|
||||||
@inject("HashUtil") protected hashUtil: HashUtil,
|
|
||||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
||||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
|
||||||
@inject("ApplicationContext") protected applicationContext: ApplicationContext,
|
|
||||||
@inject("BotWeaponGenerator") protected botWeaponGenerator: BotWeaponGenerator,
|
|
||||||
@inject("BotLootGenerator") protected botLootGenerator: BotLootGenerator,
|
|
||||||
@inject("BotGeneratorHelper") protected botGeneratorHelper: BotGeneratorHelper,
|
|
||||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
|
||||||
@inject("BotHelper") protected botHelper: BotHelper,
|
|
||||||
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
|
||||||
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
|
||||||
@inject("WeatherHelper") protected weatherHelper: WeatherHelper,
|
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
|
||||||
@inject("BotEquipmentFilterService") protected botEquipmentFilterService: BotEquipmentFilterService,
|
|
||||||
@inject("BotEquipmentModPoolService") protected botEquipmentModPoolService: BotEquipmentModPoolService,
|
|
||||||
@inject("BotEquipmentModGenerator") protected botEquipmentModGenerator: BotEquipmentModGenerator,
|
|
||||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("APBSTierGetter") protected apbsTierGetter: APBSTierGetter,
|
|
||||||
@inject("APBSBotWeaponGenerator") protected apbsBotWeaponGenerator: APBSBotWeaponGenerator,
|
|
||||||
@inject("RaidInformation") protected raidInformation: RaidInformation,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger
|
|
||||||
)
|
|
||||||
{
|
|
||||||
super(logger,
|
|
||||||
hashUtil,
|
|
||||||
randomUtil,
|
|
||||||
databaseService,
|
|
||||||
applicationContext,
|
|
||||||
botWeaponGenerator,
|
|
||||||
botLootGenerator,
|
|
||||||
botGeneratorHelper,
|
|
||||||
profileHelper,
|
|
||||||
botHelper,
|
|
||||||
weightedRandomHelper,
|
|
||||||
itemHelper,
|
|
||||||
weatherHelper,
|
|
||||||
localisationService,
|
|
||||||
botEquipmentFilterService,
|
|
||||||
botEquipmentModPoolService,
|
|
||||||
botEquipmentModGenerator,
|
|
||||||
configServer)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override generateInventory(
|
|
||||||
sessionId: string,
|
|
||||||
botJsonTemplate: IBotType,
|
|
||||||
botRole: string,
|
|
||||||
isPmc: boolean,
|
|
||||||
botLevel: number,
|
|
||||||
chosenGameVersion: string
|
|
||||||
): PmcInventory
|
|
||||||
{
|
|
||||||
const templateInventory = botJsonTemplate.inventory;
|
|
||||||
const wornItemChances = botJsonTemplate.chances;
|
|
||||||
const itemGenerationLimitsMinMax: IGeneration = botJsonTemplate.generation;
|
|
||||||
|
|
||||||
// Generate base inventory with no items
|
|
||||||
const botInventory = this.generateInventoryBase();
|
|
||||||
|
|
||||||
const raidConfig = this.applicationContext
|
|
||||||
.getLatestValue(ContextVariableType.RAID_CONFIGURATION)
|
|
||||||
?.getValue<IGetRaidConfigurationRequestData>();
|
|
||||||
|
|
||||||
this.generateAndAddEquipmentToBot(
|
|
||||||
sessionId,
|
|
||||||
templateInventory,
|
|
||||||
wornItemChances,
|
|
||||||
botRole,
|
|
||||||
botInventory,
|
|
||||||
botLevel,
|
|
||||||
chosenGameVersion,
|
|
||||||
raidConfig
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!this.raidInformation.isBotEnabled(botRole))
|
|
||||||
{
|
|
||||||
this.generateAndAddWeaponsToBot(templateInventory, wornItemChances, sessionId, botInventory, botRole, isPmc, itemGenerationLimitsMinMax, botLevel);
|
|
||||||
this.botLootGenerator.generateLoot(sessionId, botJsonTemplate, isPmc, botRole, botInventory, botLevel);
|
|
||||||
|
|
||||||
return botInventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
// APBS generation chances instead
|
|
||||||
const tierInfo = this.apbsTierGetter.getTierByLevel(botLevel);
|
|
||||||
const chances = this.apbsEquipmentGetter.getSpawnChancesByBotRole(botRole, tierInfo);
|
|
||||||
const generation = chances.generation;
|
|
||||||
|
|
||||||
this.generateAndAddWeaponsToBot(templateInventory, chances, sessionId, botInventory, botRole, isPmc, generation, botLevel);
|
|
||||||
this.botLootGenerator.generateLoot(sessionId, botJsonTemplate, isPmc, botRole, botInventory, botLevel);
|
|
||||||
|
|
||||||
return botInventory;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override generateEquipment = (settings: IGenerateEquipmentProperties): boolean =>
|
|
||||||
{
|
|
||||||
const equipmentSlot = settings.rootEquipmentSlot as string;
|
|
||||||
const botRole = settings.botData.role;
|
|
||||||
const botLevel = settings.botData.level;
|
|
||||||
const tierInfo = this.apbsTierGetter.getTierByLevel(botLevel);
|
|
||||||
|
|
||||||
let equipmentPool = this.apbsEquipmentGetter.getEquipmentByBotRole(botRole, tierInfo, equipmentSlot);
|
|
||||||
let randomisationDetails = this.apbsEquipmentGetter.getSpawnChancesByBotRole(botRole, tierInfo);
|
|
||||||
let wornItemChances = this.apbsEquipmentGetter.getSpawnChancesByBotRole(botRole, tierInfo);
|
|
||||||
let modPool = this.apbsEquipmentGetter.getModsByBotRole(botRole, tierInfo);
|
|
||||||
let apbsBot = true;
|
|
||||||
|
|
||||||
if (!this.raidInformation.isBotEnabled(botRole))
|
|
||||||
{
|
|
||||||
equipmentPool = settings.rootEquipmentPool;
|
|
||||||
randomisationDetails = settings.randomisationDetails;
|
|
||||||
wornItemChances = settings.spawnChances;
|
|
||||||
modPool = settings.modPool;
|
|
||||||
apbsBot = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (apbsBot && equipmentSlot == EquipmentSlots.TACTICAL_VEST && !settings.inventory.items.find(e => e.slotId === "ArmorVest"))
|
|
||||||
{
|
|
||||||
equipmentPool = this.apbsEquipmentGetter.getEquipmentByBotRole(botRole, tierInfo, "ArmouredRig");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (equipmentSlot == EquipmentSlots.POCKETS && Object.keys(settings.rootEquipmentPool).includes("65e080be269cbd5c5005e529"))
|
|
||||||
{
|
|
||||||
equipmentPool = settings.rootEquipmentPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
const spawnChance = ([EquipmentSlots.POCKETS, EquipmentSlots.SECURED_CONTAINER] as string[]).includes(
|
|
||||||
settings.rootEquipmentSlot
|
|
||||||
)
|
|
||||||
? 100
|
|
||||||
: wornItemChances.equipment[settings.rootEquipmentSlot];
|
|
||||||
|
|
||||||
if (typeof spawnChance === "undefined")
|
|
||||||
{
|
|
||||||
this.logger.warning(
|
|
||||||
this.localisationService.getText(
|
|
||||||
"bot-no_spawn_chance_defined_for_equipment_slot",
|
|
||||||
settings.rootEquipmentSlot
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const shouldSpawn = this.randomUtil.getChance100(spawnChance);
|
|
||||||
if (shouldSpawn && Object.keys(equipmentPool).length)
|
|
||||||
{
|
|
||||||
let pickedItemDb: ITemplateItem;
|
|
||||||
let found = false;
|
|
||||||
|
|
||||||
const maxAttempts = Math.round(Object.keys(equipmentPool).length * 0.75); // Roughly 75% of pool size
|
|
||||||
let attempts = 0;
|
|
||||||
while (!found)
|
|
||||||
{
|
|
||||||
if (Object.values(equipmentPool).length === 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const chosenItemTpl = this.weightedRandomHelper.getWeightedValue<string>(equipmentPool);
|
|
||||||
const dbResult = this.itemHelper.getItem(chosenItemTpl);
|
|
||||||
|
|
||||||
if (!dbResult[0])
|
|
||||||
{
|
|
||||||
this.logger.error(this.localisationService.getText("bot-missing_item_template", chosenItemTpl));
|
|
||||||
this.logger.info(`EquipmentSlot -> ${settings.rootEquipmentSlot}`);
|
|
||||||
|
|
||||||
|
|
||||||
attempts++;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const compatabilityResult = this.botGeneratorHelper.isItemIncompatibleWithCurrentItems(
|
|
||||||
settings.inventory.items,
|
|
||||||
chosenItemTpl,
|
|
||||||
settings.rootEquipmentSlot
|
|
||||||
);
|
|
||||||
if (compatabilityResult.incompatible)
|
|
||||||
{
|
|
||||||
// Tried x different items that failed, stop
|
|
||||||
if (attempts > maxAttempts)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
attempts++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Success
|
|
||||||
found = true;
|
|
||||||
pickedItemDb = dbResult[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create root item
|
|
||||||
const id = this.hashUtil.generate();
|
|
||||||
const item = {
|
|
||||||
_id: id,
|
|
||||||
_tpl: pickedItemDb._id,
|
|
||||||
parentId: settings.inventory.equipment,
|
|
||||||
slotId: settings.rootEquipmentSlot,
|
|
||||||
...this.botGeneratorHelper.generateExtraPropertiesForItem(pickedItemDb, settings.botData.role)
|
|
||||||
};
|
|
||||||
|
|
||||||
const botEquipBlacklist = this.botEquipmentFilterService.getBotEquipmentBlacklist(
|
|
||||||
settings.botData.equipmentRole,
|
|
||||||
settings.generatingPlayerLevel
|
|
||||||
);
|
|
||||||
|
|
||||||
// Edge case: Filter the armor items mod pool if bot exists in config dict + config has armor slot
|
|
||||||
if (
|
|
||||||
this.botConfig.equipment[settings.botData.equipmentRole] &&
|
|
||||||
randomisationDetails?.randomisedArmorSlots?.includes(settings.rootEquipmentSlot)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Filter out mods from relevant blacklist
|
|
||||||
modPool[pickedItemDb._id] = this.getFilteredDynamicModsForItem(
|
|
||||||
pickedItemDb._id,
|
|
||||||
botEquipBlacklist.equipment
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does item have slots for sub-mods to be inserted into
|
|
||||||
if (pickedItemDb._props.Slots?.length > 0 && !settings.generateModsBlacklist?.includes(pickedItemDb._id))
|
|
||||||
{
|
|
||||||
const childItemsToAdd = this.botEquipmentModGenerator.generateModsForEquipment(
|
|
||||||
[item],
|
|
||||||
id,
|
|
||||||
pickedItemDb,
|
|
||||||
settings,
|
|
||||||
botEquipBlacklist
|
|
||||||
);
|
|
||||||
settings.inventory.items.push(...childItemsToAdd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No slots, add root item only
|
|
||||||
settings.inventory.items.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override generateAndAddWeaponsToBot(
|
|
||||||
templateInventory: IInventory,
|
|
||||||
equipmentChances: IChances,
|
|
||||||
sessionId: string,
|
|
||||||
botInventory: PmcInventory,
|
|
||||||
botRole: string,
|
|
||||||
isPmc: boolean,
|
|
||||||
itemGenerationLimitsMinMax: IGeneration,
|
|
||||||
botLevel: number
|
|
||||||
): void
|
|
||||||
{
|
|
||||||
const weaponSlotsToFill = this.getDesiredWeaponsForBot(equipmentChances);
|
|
||||||
let hasBothPrimary = false;
|
|
||||||
if (weaponSlotsToFill[0].shouldSpawn && weaponSlotsToFill[1].shouldSpawn)
|
|
||||||
{
|
|
||||||
hasBothPrimary = true;
|
|
||||||
}
|
|
||||||
for (const weaponSlot of weaponSlotsToFill)
|
|
||||||
{
|
|
||||||
// Add weapon to bot if true and bot json has something to put into the slot
|
|
||||||
if (weaponSlot.shouldSpawn && Object.keys(templateInventory.equipment[weaponSlot.slot]).length)
|
|
||||||
{
|
|
||||||
this.apbsAddWeaponAndMagazinesToInventory(
|
|
||||||
sessionId,
|
|
||||||
weaponSlot,
|
|
||||||
templateInventory,
|
|
||||||
botInventory,
|
|
||||||
equipmentChances,
|
|
||||||
botRole,
|
|
||||||
isPmc,
|
|
||||||
itemGenerationLimitsMinMax,
|
|
||||||
botLevel,
|
|
||||||
hasBothPrimary
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private apbsAddWeaponAndMagazinesToInventory(
|
|
||||||
sessionId: string,
|
|
||||||
weaponSlot: { slot: EquipmentSlots; shouldSpawn: boolean },
|
|
||||||
templateInventory: IInventory,
|
|
||||||
botInventory: PmcInventory,
|
|
||||||
equipmentChances: IChances,
|
|
||||||
botRole: string,
|
|
||||||
isPmc: boolean,
|
|
||||||
itemGenerationWeights: IGeneration,
|
|
||||||
botLevel: number,
|
|
||||||
hasBothPrimary: boolean
|
|
||||||
): void
|
|
||||||
{
|
|
||||||
const generatedWeapon = this.apbsBotWeaponGenerator.apbsGenerateRandomWeapon(
|
|
||||||
sessionId,
|
|
||||||
weaponSlot.slot,
|
|
||||||
templateInventory,
|
|
||||||
botInventory.equipment,
|
|
||||||
equipmentChances.weaponMods,
|
|
||||||
botRole,
|
|
||||||
isPmc,
|
|
||||||
botLevel,
|
|
||||||
hasBothPrimary
|
|
||||||
);
|
|
||||||
|
|
||||||
botInventory.items.push(...generatedWeapon.weapon);
|
|
||||||
|
|
||||||
if (this.raidInformation.isBotEnabled(botRole) && ModConfig.config.enableBotsToRollAmmoAgain)
|
|
||||||
{
|
|
||||||
this.apbsBotWeaponGenerator.apbsAddExtraMagazinesToInventory(
|
|
||||||
generatedWeapon,
|
|
||||||
itemGenerationWeights.items.magazines,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botLevel
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.botWeaponGenerator.addExtraMagazinesToInventory(
|
|
||||||
generatedWeapon,
|
|
||||||
itemGenerationWeights.items.magazines,
|
|
||||||
botInventory,
|
|
||||||
botRole
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,474 +0,0 @@
|
||||||
import { inject, injectable } from "tsyringe";
|
|
||||||
|
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
||||||
import { IBotType, IGenerationWeightingItems } from "@spt/models/eft/common/tables/IBotType";
|
|
||||||
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { APBSTierGetter } from "../Utils/APBSTierGetter";
|
|
||||||
import { RagfairPriceService } from "@spt/services/RagfairPriceService";
|
|
||||||
import { PMCLootGenerator } from "@spt/generators/PMCLootGenerator";
|
|
||||||
import { BotLootCacheService } from "@spt/services/BotLootCacheService";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { DatabaseServer } from "@spt/servers/DatabaseServer";
|
|
||||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
|
||||||
import { ICloner } from "@spt/utils/cloners/ICloner";
|
|
||||||
import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
|
||||||
import { IBotLootCache, LootCacheType } from "@spt/models/spt/bots/IBotLootCache";
|
|
||||||
import { RaidInformation } from "../Globals/RaidInformation";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { Logging } from "../Enums/Logging";
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class APBSBotLootCacheService extends BotLootCacheService
|
|
||||||
{
|
|
||||||
protected apbsLootCache: Record<string, IBotLootCache>;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
|
||||||
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
|
||||||
@inject("DatabaseServer") protected databaseServer: DatabaseServer,
|
|
||||||
@inject("PMCLootGenerator") protected pmcLootGenerator: PMCLootGenerator,
|
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
|
||||||
@inject("RagfairPriceService") protected ragfairPriceService: RagfairPriceService,
|
|
||||||
@inject("PrimaryCloner") protected cloner: ICloner,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("APBSTierGetter") protected apbsTierGetter: APBSTierGetter,
|
|
||||||
@inject("RaidInformation") protected raidInformation: RaidInformation,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger
|
|
||||||
)
|
|
||||||
{
|
|
||||||
super(logger,
|
|
||||||
itemHelper,
|
|
||||||
databaseServer,
|
|
||||||
pmcLootGenerator,
|
|
||||||
localisationService,
|
|
||||||
ragfairPriceService,
|
|
||||||
cloner)
|
|
||||||
this.apbsClearCache();
|
|
||||||
this.clearCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
public apbsClearCache(): void
|
|
||||||
{
|
|
||||||
this.apbsLootCache = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
public apbsBotRoleExistsInCache(combinedBotRoleTier: string): boolean
|
|
||||||
{
|
|
||||||
return !!this.apbsLootCache[combinedBotRoleTier];
|
|
||||||
}
|
|
||||||
|
|
||||||
public apbsInitCacheForBotRole(combinedBotRoleTier: string): void
|
|
||||||
{
|
|
||||||
this.apbsLootCache[combinedBotRoleTier] = {
|
|
||||||
backpackLoot: {},
|
|
||||||
pocketLoot: {},
|
|
||||||
vestLoot: {},
|
|
||||||
secureLoot: {},
|
|
||||||
combinedPoolLoot: {},
|
|
||||||
|
|
||||||
specialItems: {},
|
|
||||||
grenadeItems: {},
|
|
||||||
drugItems: {},
|
|
||||||
foodItems: {},
|
|
||||||
drinkItems: {},
|
|
||||||
currencyItems: {},
|
|
||||||
healingItems: {},
|
|
||||||
stimItems: {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public apbsGetLootFromCache(
|
|
||||||
botRole: string,
|
|
||||||
isPmc: boolean,
|
|
||||||
lootType: LootCacheType,
|
|
||||||
botJsonTemplate: IBotType,
|
|
||||||
botLevel: number
|
|
||||||
): Record<string, number>
|
|
||||||
{
|
|
||||||
const tierInfo = this.apbsTierGetter.getTierByLevel(botLevel).toString();
|
|
||||||
const combinedBotRoleTier = botRole + tierInfo;
|
|
||||||
if (!this.apbsBotRoleExistsInCache(combinedBotRoleTier))
|
|
||||||
{
|
|
||||||
this.apbsInitCacheForBotRole(combinedBotRoleTier);
|
|
||||||
|
|
||||||
this.apbsAddLootToCache(botRole, isPmc, botJsonTemplate, botLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = undefined;
|
|
||||||
switch (lootType)
|
|
||||||
{
|
|
||||||
case LootCacheType.SPECIAL:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].specialItems;
|
|
||||||
break;
|
|
||||||
case LootCacheType.BACKPACK:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].backpackLoot;
|
|
||||||
break;
|
|
||||||
case LootCacheType.POCKET:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].pocketLoot;
|
|
||||||
break;
|
|
||||||
case LootCacheType.VEST:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].vestLoot;
|
|
||||||
break;
|
|
||||||
case LootCacheType.SECURE:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].secureLoot;
|
|
||||||
break;
|
|
||||||
case LootCacheType.COMBINED:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].combinedPoolLoot;
|
|
||||||
break;
|
|
||||||
case LootCacheType.HEALING_ITEMS:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].healingItems;
|
|
||||||
break;
|
|
||||||
case LootCacheType.GRENADE_ITEMS:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].grenadeItems;
|
|
||||||
break;
|
|
||||||
case LootCacheType.DRUG_ITEMS:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].drugItems;
|
|
||||||
break;
|
|
||||||
case LootCacheType.FOOD_ITEMS:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].foodItems;
|
|
||||||
break;
|
|
||||||
case LootCacheType.DRINK_ITEMS:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].drinkItems;
|
|
||||||
break;
|
|
||||||
case LootCacheType.CURRENCY_ITEMS:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].currencyItems;
|
|
||||||
break;
|
|
||||||
case LootCacheType.STIM_ITEMS:
|
|
||||||
result = this.apbsLootCache[combinedBotRoleTier].stimItems;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.logger.error(
|
|
||||||
this.localisationService.getText("bot-loot_type_not_found", {
|
|
||||||
lootType: lootType,
|
|
||||||
botRole: botRole,
|
|
||||||
isPmc: isPmc
|
|
||||||
})
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.cloner.clone(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public apbsAddLootToCache(botRole: string, isPmc: boolean, botJsonTemplate: IBotType, botLevel: number): void
|
|
||||||
{
|
|
||||||
const tierInfo = this.apbsTierGetter.getTierByLevel(botLevel);
|
|
||||||
const combinedBotRoleTier = botRole + tierInfo;
|
|
||||||
const chances = this.apbsEquipmentGetter.getSpawnChancesByBotRole(botRole, tierInfo);
|
|
||||||
let realWhitelist: IGenerationWeightingItems = chances.generation.items;
|
|
||||||
|
|
||||||
if (!this.raidInformation.isBotEnabled(botRole))
|
|
||||||
{
|
|
||||||
realWhitelist = botJsonTemplate.generation.items;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the full pool of loot we use to create the various sub-categories with
|
|
||||||
const lootPool = botJsonTemplate.inventory.items;
|
|
||||||
|
|
||||||
// Flatten all individual slot loot pools into one big pool, while filtering out potentially missing templates
|
|
||||||
const specialLootPool: Record<string, number> = {};
|
|
||||||
const backpackLootPool: Record<string, number> = {};
|
|
||||||
const pocketLootPool: Record<string, number> = {};
|
|
||||||
const vestLootPool: Record<string, number> = {};
|
|
||||||
const secureLootTPool: Record<string, number> = {};
|
|
||||||
const combinedLootPool: Record<string, number> = {};
|
|
||||||
|
|
||||||
if (isPmc)
|
|
||||||
{
|
|
||||||
// Replace lootPool from bot json with our own generated list for PMCs
|
|
||||||
lootPool.Backpack = this.cloner.clone(this.pmcLootGenerator.generatePMCBackpackLootPool(botRole));
|
|
||||||
lootPool.Pockets = this.cloner.clone(this.pmcLootGenerator.generatePMCPocketLootPool(botRole));
|
|
||||||
lootPool.TacticalVest = this.cloner.clone(this.pmcLootGenerator.generatePMCVestLootPool(botRole));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Backpack/Pockets etc
|
|
||||||
for (const [slot, pool] of Object.entries(lootPool))
|
|
||||||
{
|
|
||||||
// No items to add, skip
|
|
||||||
if (Object.keys(pool).length === 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort loot pool into separate buckets
|
|
||||||
switch (slot.toLowerCase())
|
|
||||||
{
|
|
||||||
case "specialloot":
|
|
||||||
this.addItemsToPool(specialLootPool, pool);
|
|
||||||
break;
|
|
||||||
case "pockets":
|
|
||||||
this.addItemsToPool(pocketLootPool, pool);
|
|
||||||
break;
|
|
||||||
case "tacticalvest":
|
|
||||||
this.addItemsToPool(vestLootPool, pool);
|
|
||||||
break;
|
|
||||||
case "securedcontainer":
|
|
||||||
this.addItemsToPool(secureLootTPool, pool);
|
|
||||||
break;
|
|
||||||
case "backpack":
|
|
||||||
this.addItemsToPool(backpackLootPool, pool);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.logger.warning(`How did you get here ${slot}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add all items (if any) to combined pool (excluding secure)
|
|
||||||
if (Object.keys(pool).length > 0 && slot.toLowerCase() !== "securedcontainer")
|
|
||||||
{
|
|
||||||
this.addItemsToPool(combinedLootPool, pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign whitelisted special items to bot if any exist
|
|
||||||
const specialLootItems: Record<string, number> =
|
|
||||||
Object.keys(realWhitelist.specialItems.whitelist)?.length > 0
|
|
||||||
? realWhitelist.specialItems.whitelist
|
|
||||||
: {};
|
|
||||||
|
|
||||||
// no whitelist, find and assign from combined item pool
|
|
||||||
if (Object.keys(specialLootItems).length === 0)
|
|
||||||
{
|
|
||||||
for (const [tpl, weight] of Object.entries(specialLootPool))
|
|
||||||
{
|
|
||||||
const itemTemplate = this.itemHelper.getItem(tpl)[1];
|
|
||||||
if (!(this.isBulletOrGrenade(itemTemplate._props) || this.isMagazine(itemTemplate._props)))
|
|
||||||
{
|
|
||||||
specialLootItems[tpl] = weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign whitelisted healing items to bot if any exist
|
|
||||||
const healingItems: Record<string, number> =
|
|
||||||
Object.keys(realWhitelist.healing.whitelist)?.length > 0
|
|
||||||
? realWhitelist.healing.whitelist
|
|
||||||
: {};
|
|
||||||
|
|
||||||
// No whitelist, find and assign from combined item pool
|
|
||||||
if (Object.keys(healingItems).length === 0)
|
|
||||||
{
|
|
||||||
for (const [tpl, weight] of Object.entries(combinedLootPool))
|
|
||||||
{
|
|
||||||
const itemTemplate = this.itemHelper.getItem(tpl)[1];
|
|
||||||
if (
|
|
||||||
this.isMedicalItem(itemTemplate._props) &&
|
|
||||||
itemTemplate._parent !== BaseClasses.STIMULATOR &&
|
|
||||||
itemTemplate._parent !== BaseClasses.DRUGS
|
|
||||||
)
|
|
||||||
{
|
|
||||||
healingItems[tpl] = weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign whitelisted drugs to bot if any exist
|
|
||||||
const drugItems: Record<string, number> =
|
|
||||||
Object.keys(realWhitelist.drugs.whitelist)?.length > 0
|
|
||||||
? realWhitelist.drugs.whitelist
|
|
||||||
: {};
|
|
||||||
|
|
||||||
// no drugs whitelist, find and assign from combined item pool
|
|
||||||
if (Object.keys(drugItems).length === 0)
|
|
||||||
{
|
|
||||||
for (const [tpl, weight] of Object.entries(combinedLootPool))
|
|
||||||
{
|
|
||||||
const itemTemplate = this.itemHelper.getItem(tpl)[1];
|
|
||||||
if (this.isMedicalItem(itemTemplate._props) && itemTemplate._parent === BaseClasses.DRUGS)
|
|
||||||
{
|
|
||||||
drugItems[tpl] = weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign whitelisted food to bot if any exist
|
|
||||||
const foodItems: Record<string, number> =
|
|
||||||
Object.keys(realWhitelist.food.whitelist)?.length > 0
|
|
||||||
? realWhitelist.food.whitelist
|
|
||||||
: {};
|
|
||||||
|
|
||||||
// No food whitelist, find and assign from combined item pool
|
|
||||||
if (Object.keys(foodItems).length === 0)
|
|
||||||
{
|
|
||||||
for (const [tpl, weight] of Object.entries(combinedLootPool))
|
|
||||||
{
|
|
||||||
const itemTemplate = this.itemHelper.getItem(tpl)[1];
|
|
||||||
if (this.itemHelper.isOfBaseclass(itemTemplate._id, BaseClasses.FOOD))
|
|
||||||
{
|
|
||||||
foodItems[tpl] = weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign whitelisted drink to bot if any exist
|
|
||||||
const drinkItems: Record<string, number> =
|
|
||||||
Object.keys(realWhitelist.food.whitelist)?.length > 0
|
|
||||||
? realWhitelist.food.whitelist
|
|
||||||
: {};
|
|
||||||
|
|
||||||
// No drink whitelist, find and assign from combined item pool
|
|
||||||
if (Object.keys(drinkItems).length === 0)
|
|
||||||
{
|
|
||||||
for (const [tpl, weight] of Object.entries(combinedLootPool))
|
|
||||||
{
|
|
||||||
const itemTemplate = this.itemHelper.getItem(tpl)[1];
|
|
||||||
if (this.itemHelper.isOfBaseclass(itemTemplate._id, BaseClasses.DRINK))
|
|
||||||
{
|
|
||||||
drinkItems[tpl] = weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign whitelisted currency to bot if any exist
|
|
||||||
const currencyItems: Record<string, number> =
|
|
||||||
Object.keys(realWhitelist.currency.whitelist)?.length > 0
|
|
||||||
? realWhitelist.currency.whitelist
|
|
||||||
: {};
|
|
||||||
|
|
||||||
// No currency whitelist, find and assign from combined item pool
|
|
||||||
if (Object.keys(currencyItems).length === 0)
|
|
||||||
{
|
|
||||||
for (const [tpl, weight] of Object.entries(combinedLootPool))
|
|
||||||
{
|
|
||||||
const itemTemplate = this.itemHelper.getItem(tpl)[1];
|
|
||||||
if (this.itemHelper.isOfBaseclass(itemTemplate._id, BaseClasses.MONEY))
|
|
||||||
{
|
|
||||||
currencyItems[tpl] = weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign whitelisted stims to bot if any exist
|
|
||||||
const stimItems: Record<string, number> =
|
|
||||||
Object.keys(realWhitelist.stims.whitelist)?.length > 0
|
|
||||||
? realWhitelist.stims.whitelist
|
|
||||||
: {};
|
|
||||||
|
|
||||||
// No whitelist, find and assign from combined item pool
|
|
||||||
if (Object.keys(stimItems).length === 0)
|
|
||||||
{
|
|
||||||
for (const [tpl, weight] of Object.entries(combinedLootPool))
|
|
||||||
{
|
|
||||||
const itemTemplate = this.itemHelper.getItem(tpl)[1];
|
|
||||||
if (this.isMedicalItem(itemTemplate._props) && itemTemplate._parent === BaseClasses.STIMULATOR)
|
|
||||||
{
|
|
||||||
stimItems[tpl] = weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign whitelisted grenades to bot if any exist
|
|
||||||
const grenadeItems: Record<string, number> =
|
|
||||||
Object.keys(realWhitelist.grenades.whitelist)?.length > 0
|
|
||||||
? realWhitelist.grenades.whitelist
|
|
||||||
: {};
|
|
||||||
|
|
||||||
// no whitelist, find and assign from combined item pool
|
|
||||||
if (Object.keys(grenadeItems).length === 0)
|
|
||||||
{
|
|
||||||
for (const [tpl, weight] of Object.entries(combinedLootPool))
|
|
||||||
{
|
|
||||||
const itemTemplate = this.itemHelper.getItem(tpl)[1];
|
|
||||||
if (this.isGrenade(itemTemplate._props))
|
|
||||||
{
|
|
||||||
grenadeItems[tpl] = weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get backpack loot (excluding magazines, bullets, grenades, drink, food and healing/stim items)
|
|
||||||
const filteredBackpackItems = {};
|
|
||||||
for (const itemKey of Object.keys(backpackLootPool))
|
|
||||||
{
|
|
||||||
const itemResult = this.itemHelper.getItem(itemKey);
|
|
||||||
if (!itemResult[0])
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const itemTemplate = itemResult[1];
|
|
||||||
if (
|
|
||||||
this.isBulletOrGrenade(itemTemplate._props) ||
|
|
||||||
this.isMagazine(itemTemplate._props) ||
|
|
||||||
this.isMedicalItem(itemTemplate._props) ||
|
|
||||||
this.isGrenade(itemTemplate._props) ||
|
|
||||||
this.isFood(itemTemplate._id) ||
|
|
||||||
this.isDrink(itemTemplate._id) ||
|
|
||||||
this.isCurrency(itemTemplate._id)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Is type we dont want as backpack loot, skip
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
filteredBackpackItems[itemKey] = backpackLootPool[itemKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get pocket loot (excluding magazines, bullets, grenades, drink, food medical and healing/stim items)
|
|
||||||
const filteredPocketItems = {};
|
|
||||||
for (const itemKey of Object.keys(pocketLootPool))
|
|
||||||
{
|
|
||||||
const itemResult = this.itemHelper.getItem(itemKey);
|
|
||||||
if (!itemResult[0])
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const itemTemplate = itemResult[1];
|
|
||||||
if (
|
|
||||||
this.isBulletOrGrenade(itemTemplate._props) ||
|
|
||||||
this.isMagazine(itemTemplate._props) ||
|
|
||||||
this.isMedicalItem(itemTemplate._props) ||
|
|
||||||
this.isGrenade(itemTemplate._props) ||
|
|
||||||
this.isFood(itemTemplate._id) ||
|
|
||||||
this.isDrink(itemTemplate._id) ||
|
|
||||||
this.isCurrency(itemTemplate._id) ||
|
|
||||||
!("Height" in itemTemplate._props) || // lacks height
|
|
||||||
!("Width" in itemTemplate._props) // lacks width
|
|
||||||
)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
filteredPocketItems[itemKey] = pocketLootPool[itemKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get vest loot (excluding magazines, bullets, grenades, medical and healing/stim items)
|
|
||||||
const filteredVestItems = {};
|
|
||||||
for (const itemKey of Object.keys(vestLootPool))
|
|
||||||
{
|
|
||||||
const itemResult = this.itemHelper.getItem(itemKey);
|
|
||||||
if (!itemResult[0])
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const itemTemplate = itemResult[1];
|
|
||||||
if (
|
|
||||||
this.isBulletOrGrenade(itemTemplate._props) ||
|
|
||||||
this.isMagazine(itemTemplate._props) ||
|
|
||||||
this.isMedicalItem(itemTemplate._props) ||
|
|
||||||
this.isGrenade(itemTemplate._props) ||
|
|
||||||
this.isFood(itemTemplate._id) ||
|
|
||||||
this.isDrink(itemTemplate._id) ||
|
|
||||||
this.isCurrency(itemTemplate._id)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
filteredVestItems[itemKey] = vestLootPool[itemKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].healingItems = healingItems;
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].drugItems = drugItems;
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].foodItems = foodItems;
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].drinkItems = drinkItems;
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].currencyItems = currencyItems;
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].stimItems = stimItems;
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].grenadeItems = grenadeItems;
|
|
||||||
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].specialItems = specialLootItems;
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].backpackLoot = filteredBackpackItems;
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].pocketLoot = filteredPocketItems;
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].vestLoot = filteredVestItems;
|
|
||||||
this.apbsLootCache[combinedBotRoleTier].secureLoot = secureLootTPool;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,418 +0,0 @@
|
||||||
import { inject, injectable } from "tsyringe";
|
|
||||||
|
|
||||||
import { BotWeaponGenerator } from "@spt/generators/BotWeaponGenerator";
|
|
||||||
import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper";
|
|
||||||
import { BotHelper } from "@spt/helpers/BotHelper";
|
|
||||||
import { HandbookHelper } from "@spt/helpers/HandbookHelper";
|
|
||||||
import { InventoryHelper } from "@spt/helpers/InventoryHelper";
|
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
||||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
|
||||||
import { IInventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase";
|
|
||||||
import { IGenerationWeightingItems, IBotType } from "@spt/models/eft/common/tables/IBotType";
|
|
||||||
import { EquipmentSlots } from "@spt/models/enums/EquipmentSlots";
|
|
||||||
import { LootCacheType } from "@spt/models/spt/bots/IBotLootCache";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
|
||||||
import { BotLootCacheService } from "@spt/services/BotLootCacheService";
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
|
||||||
import { ICloner } from "@spt/utils/cloners/ICloner";
|
|
||||||
import { HashUtil } from "@spt/utils/HashUtil";
|
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
|
||||||
import { BotLootGenerator } from "@spt/generators/BotLootGenerator";
|
|
||||||
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { APBSTierGetter } from "../Utils/APBSTierGetter";
|
|
||||||
import { APBSBotLootCacheService } from "./APBSBotLootCacheService";
|
|
||||||
import { RaidInformation } from "../Globals/RaidInformation";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { Logging } from "../Enums/Logging";
|
|
||||||
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
|
||||||
import { IItemSpawnLimitSettings } from "@spt/models/spt/bots/IItemSpawnLimitSettings";
|
|
||||||
|
|
||||||
/** Handle profile related client events */
|
|
||||||
@injectable()
|
|
||||||
export class APBSBotLootGenerator extends BotLootGenerator
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
|
||||||
@inject("HashUtil") protected hashUtil: HashUtil,
|
|
||||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
||||||
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
|
||||||
@inject("InventoryHelper") protected inventoryHelper: InventoryHelper,
|
|
||||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
|
||||||
@inject("HandbookHelper") protected handbookHelper: HandbookHelper,
|
|
||||||
@inject("BotGeneratorHelper") protected botGeneratorHelper: BotGeneratorHelper,
|
|
||||||
@inject("BotWeaponGenerator") protected botWeaponGenerator: BotWeaponGenerator,
|
|
||||||
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
|
||||||
@inject("BotHelper") protected botHelper: BotHelper,
|
|
||||||
@inject("BotLootCacheService") protected botLootCacheService: BotLootCacheService,
|
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
|
||||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
|
||||||
@inject("PrimaryCloner") protected cloner: ICloner,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("APBSTierGetter") protected apbsTierGetter: APBSTierGetter,
|
|
||||||
@inject("RaidInformation") protected raidInformation: RaidInformation,
|
|
||||||
@inject("APBSBotLootCacheService") protected apbsBotLootCacheService: APBSBotLootCacheService,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger
|
|
||||||
)
|
|
||||||
{
|
|
||||||
super(logger,
|
|
||||||
hashUtil,
|
|
||||||
randomUtil,
|
|
||||||
itemHelper,
|
|
||||||
inventoryHelper,
|
|
||||||
databaseService,
|
|
||||||
handbookHelper,
|
|
||||||
botGeneratorHelper,
|
|
||||||
botWeaponGenerator,
|
|
||||||
weightedRandomHelper,
|
|
||||||
botHelper,
|
|
||||||
botLootCacheService,
|
|
||||||
localisationService,
|
|
||||||
configServer,
|
|
||||||
cloner)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override generateLoot(
|
|
||||||
sessionId: string,
|
|
||||||
botJsonTemplate: IBotType,
|
|
||||||
isPmc: boolean,
|
|
||||||
botRole: string,
|
|
||||||
botInventory: PmcInventory,
|
|
||||||
botLevel: number
|
|
||||||
): void
|
|
||||||
{
|
|
||||||
// Limits on item types to be added as loot
|
|
||||||
const tierInfo = this.apbsTierGetter.getTierByLevel(botLevel);
|
|
||||||
const chances = this.apbsEquipmentGetter.getSpawnChancesByBotRole(botRole, tierInfo);
|
|
||||||
let itemCounts: IGenerationWeightingItems = chances.generation.items;
|
|
||||||
let useOriginalLootCache = false;
|
|
||||||
|
|
||||||
if (!this.raidInformation.isBotEnabled(botRole))
|
|
||||||
{
|
|
||||||
itemCounts = botJsonTemplate.generation.items;
|
|
||||||
useOriginalLootCache = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
!itemCounts.backpackLoot.weights
|
|
||||||
|| !itemCounts.pocketLoot.weights
|
|
||||||
|| !itemCounts.vestLoot.weights
|
|
||||||
|| !itemCounts.specialItems.weights
|
|
||||||
|| !itemCounts.healing.weights
|
|
||||||
|| !itemCounts.drugs.weights
|
|
||||||
|| !itemCounts.food.weights
|
|
||||||
|| !itemCounts.drink.weights
|
|
||||||
|| !itemCounts.currency.weights
|
|
||||||
|| !itemCounts.stims.weights
|
|
||||||
|| !itemCounts.grenades.weights
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this.logger.warning(this.localisationService.getText("bot-unable_to_generate_bot_loot", botRole));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let backpackLootCount = Number(
|
|
||||||
this.weightedRandomHelper.getWeightedValue<number>(itemCounts.backpackLoot.weights)
|
|
||||||
);
|
|
||||||
let pocketLootCount = Number(this.weightedRandomHelper.getWeightedValue<number>(itemCounts.pocketLoot.weights));
|
|
||||||
let vestLootCount = this.weightedRandomHelper.getWeightedValue<number>(itemCounts.vestLoot.weights);
|
|
||||||
const specialLootItemCount = Number(this.weightedRandomHelper.getWeightedValue<number>(itemCounts.specialItems.weights));
|
|
||||||
const healingItemCount = Number(this.weightedRandomHelper.getWeightedValue<number>(itemCounts.healing.weights));
|
|
||||||
const drugItemCount = Number(this.weightedRandomHelper.getWeightedValue<number>(itemCounts.drugs.weights));
|
|
||||||
|
|
||||||
const foodItemCount = Number(this.weightedRandomHelper.getWeightedValue<number>(itemCounts.food.weights));
|
|
||||||
const drinkItemCount = Number(this.weightedRandomHelper.getWeightedValue<number>(itemCounts.drink.weights));
|
|
||||||
|
|
||||||
let currencyItemCount = Number(this.weightedRandomHelper.getWeightedValue<number>(itemCounts.currency.weights));
|
|
||||||
|
|
||||||
const stimItemCount = Number(this.weightedRandomHelper.getWeightedValue<number>(itemCounts.stims.weights));
|
|
||||||
const grenadeCount = Number(this.weightedRandomHelper.getWeightedValue<number>(itemCounts.grenades.weights));
|
|
||||||
|
|
||||||
// If bot has been flagged as not having loot, set below counts to 0
|
|
||||||
if (this.botConfig.disableLootOnBotTypes?.includes(botRole.toLowerCase()))
|
|
||||||
{
|
|
||||||
backpackLootCount = 0;
|
|
||||||
pocketLootCount = 0;
|
|
||||||
vestLootCount = 0;
|
|
||||||
currencyItemCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forced pmc healing loot into secure container
|
|
||||||
if (isPmc && this.pmcConfig.forceHealingItemsIntoSecure)
|
|
||||||
{
|
|
||||||
this.addForcedMedicalItemsToPmcSecure(botInventory, botRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
const botItemLimits = this.getItemSpawnLimitsForBot(botRole);
|
|
||||||
|
|
||||||
const containersBotHasAvailable = this.getAvailableContainersBotCanStoreItemsIn(botInventory);
|
|
||||||
|
|
||||||
// This set is passed as a reference to fill up the containers that are already full, this aliviates
|
|
||||||
// generation of the bots by avoiding checking the slots of containers we already know are full
|
|
||||||
const containersIdFull = new Set<string>();
|
|
||||||
|
|
||||||
// Special items
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.SPECIAL, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.SPECIAL, botJsonTemplate, botLevel),
|
|
||||||
containersBotHasAvailable,
|
|
||||||
specialLootItemCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
|
|
||||||
// Healing items / Meds
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.HEALING_ITEMS, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.HEALING_ITEMS, botJsonTemplate, botLevel),
|
|
||||||
containersBotHasAvailable,
|
|
||||||
healingItemCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
0,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
|
|
||||||
// Drugs
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.DRUG_ITEMS, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.DRUG_ITEMS, botJsonTemplate, botLevel),
|
|
||||||
containersBotHasAvailable,
|
|
||||||
drugItemCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
0,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
|
|
||||||
// Food
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.FOOD_ITEMS, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.FOOD_ITEMS, botJsonTemplate, botLevel),
|
|
||||||
containersBotHasAvailable,
|
|
||||||
foodItemCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
0,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
|
|
||||||
// Drink
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.DRINK_ITEMS, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.DRINK_ITEMS, botJsonTemplate, botLevel),
|
|
||||||
containersBotHasAvailable,
|
|
||||||
drinkItemCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
0,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
|
|
||||||
// Currency
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.CURRENCY_ITEMS, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.CURRENCY_ITEMS, botJsonTemplate, botLevel),
|
|
||||||
containersBotHasAvailable,
|
|
||||||
currencyItemCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
0,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
|
|
||||||
// Stims
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.STIM_ITEMS, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.STIM_ITEMS, botJsonTemplate, botLevel),
|
|
||||||
containersBotHasAvailable,
|
|
||||||
stimItemCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
0,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
|
|
||||||
// Grenades
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.GRENADE_ITEMS, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.GRENADE_ITEMS, botJsonTemplate, botLevel),
|
|
||||||
[EquipmentSlots.POCKETS, EquipmentSlots.TACTICAL_VEST], // Can't use containersBotHasEquipped as we dont want grenades added to backpack
|
|
||||||
grenadeCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
0,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
|
|
||||||
// Backpack - generate loot if they have one
|
|
||||||
if (containersBotHasAvailable.includes(EquipmentSlots.BACKPACK))
|
|
||||||
{
|
|
||||||
// Add randomly generated weapon to PMC backpacks
|
|
||||||
if (isPmc && this.randomUtil.getChance100(this.pmcConfig.looseWeaponInBackpackChancePercent))
|
|
||||||
{
|
|
||||||
this.addLooseWeaponsToInventorySlot(
|
|
||||||
sessionId,
|
|
||||||
botInventory,
|
|
||||||
EquipmentSlots.BACKPACK,
|
|
||||||
botJsonTemplate.inventory,
|
|
||||||
botJsonTemplate.chances.weaponMods,
|
|
||||||
botRole,
|
|
||||||
isPmc,
|
|
||||||
botLevel,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const backpackLootRoubleTotal = this.getBackpackRoubleTotalByLevel(botLevel, isPmc);
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.BACKPACK, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.BACKPACK, botJsonTemplate, botLevel),
|
|
||||||
[EquipmentSlots.BACKPACK],
|
|
||||||
backpackLootCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
backpackLootRoubleTotal,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TacticalVest - generate loot if they have one
|
|
||||||
if (containersBotHasAvailable.includes(EquipmentSlots.TACTICAL_VEST))
|
|
||||||
{
|
|
||||||
// Vest
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.VEST, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.VEST, botJsonTemplate, botLevel),
|
|
||||||
[EquipmentSlots.TACTICAL_VEST],
|
|
||||||
vestLootCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
this.pmcConfig.maxVestLootTotalRub,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pockets
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.POCKET, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.POCKET, botJsonTemplate, botLevel),
|
|
||||||
[EquipmentSlots.POCKETS],
|
|
||||||
pocketLootCount,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
botItemLimits,
|
|
||||||
this.pmcConfig.maxPocketLootTotalRub,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
|
|
||||||
// Secure
|
|
||||||
|
|
||||||
// only add if not a pmc or is pmc and flag is true
|
|
||||||
if (!isPmc || (isPmc && this.pmcConfig.addSecureContainerLootFromBotConfig))
|
|
||||||
{
|
|
||||||
this.addLootFromPool(
|
|
||||||
useOriginalLootCache ?
|
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.SECURE, botJsonTemplate) :
|
|
||||||
this.apbsBotLootCacheService.apbsGetLootFromCache(botRole, isPmc, LootCacheType.SECURE, botJsonTemplate, botLevel),
|
|
||||||
[EquipmentSlots.SECURED_CONTAINER],
|
|
||||||
50,
|
|
||||||
botInventory,
|
|
||||||
botRole,
|
|
||||||
undefined,
|
|
||||||
-1,
|
|
||||||
isPmc,
|
|
||||||
containersIdFull
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override itemHasReachedSpawnLimit(
|
|
||||||
itemTemplate: ITemplateItem,
|
|
||||||
botRole: string,
|
|
||||||
itemSpawnLimits: IItemSpawnLimitSettings
|
|
||||||
): boolean
|
|
||||||
{
|
|
||||||
// PMCs and scavs have different sections of bot config for spawn limits
|
|
||||||
if (!!itemSpawnLimits && Object.keys(itemSpawnLimits.globalLimits).length === 0)
|
|
||||||
{
|
|
||||||
// No items found in spawn limit, drop out
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No spawn limits, skipping
|
|
||||||
if (!itemSpawnLimits)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const idToCheckFor = this.getMatchingIdFromSpawnLimits(itemTemplate, itemSpawnLimits.globalLimits);
|
|
||||||
if (!idToCheckFor)
|
|
||||||
{
|
|
||||||
// ParentId or tplid not found in spawnLimits, not a spawn limited item, skip
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment item count with this bot type
|
|
||||||
itemSpawnLimits.currentLimits[idToCheckFor]++;
|
|
||||||
|
|
||||||
// Check if over limit
|
|
||||||
if (itemSpawnLimits.currentLimits[idToCheckFor] > itemSpawnLimits.globalLimits[idToCheckFor])
|
|
||||||
{
|
|
||||||
// Prevent edge-case of small loot pools + code trying to add limited item over and over infinitely
|
|
||||||
if (itemSpawnLimits.currentLimits[idToCheckFor] > itemSpawnLimits.globalLimits[idToCheckFor] * 10)
|
|
||||||
{
|
|
||||||
this.logger.debug(
|
|
||||||
this.localisationService.getText("bot-item_spawn_limit_reached_skipping_item", {
|
|
||||||
botRole: botRole,
|
|
||||||
itemName: itemTemplate._name,
|
|
||||||
attempts: itemSpawnLimits.currentLimits[idToCheckFor]
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,394 +0,0 @@
|
||||||
import { inject, injectable, injectAll } from "tsyringe";
|
|
||||||
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { BotWeaponGenerator } from "@spt/generators/BotWeaponGenerator";
|
|
||||||
import { IInventory as PmcInventory } from "@spt/models/eft/common/tables/IBotBase";
|
|
||||||
import { IGenerationData, IInventory, IModsChances } from "@spt/models/eft/common/tables/IBotType";
|
|
||||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
|
||||||
import { APBSTierGetter } from "../Utils/APBSTierGetter";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
||||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
|
||||||
import { IGenerateWeaponRequest } from "@spt/models/spt/bots/IGenerateWeaponRequest";
|
|
||||||
import { IGenerateWeaponResult } from "@spt/models/spt/bots/IGenerateWeaponResult";
|
|
||||||
import { HashUtil } from "@spt/utils/HashUtil";
|
|
||||||
import { ICloner } from "@spt/utils/cloners/ICloner";
|
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
|
||||||
import { IInventoryMagGen } from "@spt/generators/weapongen/IInventoryMagGen";
|
|
||||||
import { RepairService } from "@spt/services/RepairService";
|
|
||||||
import { BotWeaponModLimitService } from "@spt/services/BotWeaponModLimitService";
|
|
||||||
import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper";
|
|
||||||
import { BotEquipmentModGenerator } from "@spt/generators/BotEquipmentModGenerator";
|
|
||||||
import { BotWeaponGeneratorHelper } from "@spt/helpers/BotWeaponGeneratorHelper";
|
|
||||||
import { RaidInformation } from "../Globals/RaidInformation";
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { ModConfig } from "../Globals/ModConfig";
|
|
||||||
import { Logging } from "../Enums/Logging";
|
|
||||||
import { APBSTester } from "../Utils/APBSTester";
|
|
||||||
import { ModInformation } from "../Globals/ModInformation";
|
|
||||||
import { Money } from "@spt/models/enums/Money";
|
|
||||||
import { APBSBotEquipmentModGenerator } from "./APBSBotEquipmentModGenerator";
|
|
||||||
import { APBSInventoryMagGen } from "../InventoryMagGen/APBSInventoryMagGen";
|
|
||||||
import { APBSIInventoryMagGen } from "../InventoryMagGen/APBSIInventoryMagGen";
|
|
||||||
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
|
||||||
|
|
||||||
/** Handle profile related client events */
|
|
||||||
@injectable()
|
|
||||||
export class APBSBotWeaponGenerator extends BotWeaponGenerator
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
|
||||||
@inject("HashUtil") protected hashUtil: HashUtil,
|
|
||||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
|
||||||
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
|
||||||
@inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper,
|
|
||||||
@inject("BotGeneratorHelper") protected botGeneratorHelper: BotGeneratorHelper,
|
|
||||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
||||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
|
||||||
@inject("BotWeaponGeneratorHelper") protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper,
|
|
||||||
@inject("BotWeaponModLimitService") protected botWeaponModLimitService: BotWeaponModLimitService,
|
|
||||||
@inject("BotEquipmentModGenerator") protected botEquipmentModGenerator: BotEquipmentModGenerator,
|
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
|
||||||
@inject("RepairService") protected repairService: RepairService,
|
|
||||||
@injectAll("InventoryMagGen") protected inventoryMagGenComponents: IInventoryMagGen[],
|
|
||||||
@inject("PrimaryCloner") protected cloner: ICloner,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger,
|
|
||||||
@inject("APBSTierGetter") protected apbsTierGetter: APBSTierGetter,
|
|
||||||
@inject("RaidInformation") protected raidInformation: RaidInformation,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("APBSTester") protected apbsTester: APBSTester,
|
|
||||||
@inject("APBSBotEquipmentModGenerator") protected apbsBotEquipmentModGenerator: APBSBotEquipmentModGenerator,
|
|
||||||
@inject("ModInformation") protected modInformation: ModInformation,
|
|
||||||
@injectAll("APBSInventoryMagGen") protected apbsInventoryMagGenComponents: APBSIInventoryMagGen[]
|
|
||||||
)
|
|
||||||
{
|
|
||||||
super(logger,
|
|
||||||
hashUtil,
|
|
||||||
databaseService,
|
|
||||||
itemHelper,
|
|
||||||
weightedRandomHelper,
|
|
||||||
botGeneratorHelper,
|
|
||||||
randomUtil,
|
|
||||||
configServer,
|
|
||||||
botWeaponGeneratorHelper,
|
|
||||||
botWeaponModLimitService,
|
|
||||||
botEquipmentModGenerator,
|
|
||||||
localisationService,
|
|
||||||
repairService,
|
|
||||||
inventoryMagGenComponents,
|
|
||||||
cloner)
|
|
||||||
}
|
|
||||||
|
|
||||||
public apbsGenerateRandomWeapon(sessionId: string, equipmentSlot: string, botTemplateInventory: IInventory, weaponParentId: string, modChances: IModsChances, botRole: string, isPmc: boolean, botLevel: number, hasBothPrimary: boolean): IGenerateWeaponResult
|
|
||||||
{
|
|
||||||
// If the profile was just created, then use vanilla weapon gen
|
|
||||||
if (this.raidInformation.freshProfile)
|
|
||||||
{
|
|
||||||
const weaponTpl = this.pickWeightedWeaponTplFromPool(equipmentSlot, botTemplateInventory);
|
|
||||||
return this.generateWeaponByTpl(sessionId, weaponTpl, equipmentSlot, botTemplateInventory, weaponParentId, modChances, botRole, isPmc, botLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if bot disabled, if it is - use SPT code
|
|
||||||
if (!this.raidInformation.isBotEnabled(botRole))
|
|
||||||
{
|
|
||||||
const weaponTpl = this.pickWeightedWeaponTplFromPool(equipmentSlot, botTemplateInventory);
|
|
||||||
return this.generateWeaponByTpl(sessionId, weaponTpl, equipmentSlot, botTemplateInventory, weaponParentId, modChances, botRole, isPmc, botLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not disabled via config, all bots follow this custom generation
|
|
||||||
const tierInfo = this.apbsTierGetter.getTierByLevel(botLevel);
|
|
||||||
const weaponTpl =
|
|
||||||
(hasBothPrimary && isPmc)
|
|
||||||
? this.apbsPickWeightedWeaponTplFromPoolHasBothPrimary(equipmentSlot, botLevel, botRole, tierInfo)
|
|
||||||
: this.apbsPickWeightedWeaponTplFromPool(equipmentSlot, botLevel, botRole, tierInfo)
|
|
||||||
return this.apbsGenerateWeaponByTpl(sessionId, weaponTpl, equipmentSlot, botTemplateInventory, weaponParentId, modChances, botRole, isPmc, botLevel, tierInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
private apbsPickWeightedWeaponTplFromPoolHasBothPrimary(equipmentSlot: string, botLevel: number, botRole: string, tierInfo: number): string
|
|
||||||
{
|
|
||||||
let rangeType = "ShortRange";
|
|
||||||
if (equipmentSlot == "FirstPrimaryWeapon")
|
|
||||||
{
|
|
||||||
if (this.raidInformation.location == "Woods") rangeType = "LongRange";
|
|
||||||
const weaponPool = this.apbsEquipmentGetter.getEquipmentByBotRole(botRole, tierInfo, equipmentSlot, rangeType);
|
|
||||||
return this.weightedRandomHelper.getWeightedValue<string>(weaponPool);
|
|
||||||
}
|
|
||||||
if (equipmentSlot == "SecondPrimaryWeapon")
|
|
||||||
{
|
|
||||||
if (this.raidInformation.location != "Woods") rangeType = "LongRange";
|
|
||||||
const weaponPool = this.apbsEquipmentGetter.getEquipmentByBotRole(botRole, tierInfo, equipmentSlot, rangeType);
|
|
||||||
return this.weightedRandomHelper.getWeightedValue<string>(weaponPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
const weaponPool = this.apbsEquipmentGetter.getEquipmentByBotRole(botRole, tierInfo, equipmentSlot);
|
|
||||||
return this.weightedRandomHelper.getWeightedValue<string>(weaponPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
private apbsPickWeightedWeaponTplFromPool(equipmentSlot: string, botLevel: number, botRole: string, tierInfo: number): string
|
|
||||||
{
|
|
||||||
if (equipmentSlot == "FirstPrimaryWeapon" || equipmentSlot == "SecondPrimaryWeapon")
|
|
||||||
{
|
|
||||||
const rangeType = this.weightedRandomHelper.getWeightedValue<string>(this.raidInformation.mapWeights[this.raidInformation.location]);
|
|
||||||
const weaponPool = this.apbsEquipmentGetter.getEquipmentByBotRole(botRole, tierInfo, equipmentSlot, rangeType);
|
|
||||||
return this.weightedRandomHelper.getWeightedValue<string>(weaponPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
const weaponPool = this.apbsEquipmentGetter.getEquipmentByBotRole(botRole, tierInfo, equipmentSlot);
|
|
||||||
return this.weightedRandomHelper.getWeightedValue<string>(weaponPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
private apbsGenerateWeaponByTpl(
|
|
||||||
sessionId: string,
|
|
||||||
weaponTpl: string,
|
|
||||||
equipmentSlot: string,
|
|
||||||
botTemplateInventory: IInventory,
|
|
||||||
weaponParentId: string,
|
|
||||||
modChances: IModsChances,
|
|
||||||
botRole: string,
|
|
||||||
isPmc: boolean,
|
|
||||||
botLevel: number,
|
|
||||||
tierInfo: number
|
|
||||||
): IGenerateWeaponResult
|
|
||||||
{
|
|
||||||
const modPool = this.apbsEquipmentGetter.getModsByBotRole(botRole, tierInfo);
|
|
||||||
const apbsModChances = this.apbsEquipmentGetter.getSpawnChancesByBotRole(botRole, tierInfo);
|
|
||||||
let weaponChances = apbsModChances.weaponMods;
|
|
||||||
const weaponItemTemplate = this.itemHelper.getItem(weaponTpl)[1];
|
|
||||||
|
|
||||||
if (ModConfig.config.enablePerWeaponTypeAttachmentChances)
|
|
||||||
{
|
|
||||||
switch (weaponItemTemplate._parent)
|
|
||||||
{
|
|
||||||
case "5447b5fc4bdc2d87278b4567":
|
|
||||||
weaponChances = apbsModChances.assaultCarbine;
|
|
||||||
break;
|
|
||||||
case "5447b6254bdc2dc3278b4568":
|
|
||||||
weaponChances = apbsModChances.sniperRifle;
|
|
||||||
break;
|
|
||||||
case "5447b6194bdc2d67278b4567":
|
|
||||||
weaponChances = apbsModChances.marksmanRifle;
|
|
||||||
break;
|
|
||||||
case "5447b5f14bdc2d61278b4567":
|
|
||||||
weaponChances = apbsModChances.assaultRifle;
|
|
||||||
break;
|
|
||||||
case "5447bed64bdc2d97278b4568":
|
|
||||||
weaponChances = apbsModChances.machinegun;
|
|
||||||
break;
|
|
||||||
case "5447b5e04bdc2d62278b4567":
|
|
||||||
weaponChances = apbsModChances.smg;
|
|
||||||
break;
|
|
||||||
case "5447b5cf4bdc2d65278b4567":
|
|
||||||
weaponChances = apbsModChances.handgun;
|
|
||||||
break;
|
|
||||||
case "617f1ef5e8b54b0998387733":
|
|
||||||
weaponChances = apbsModChances.revolver;
|
|
||||||
break;
|
|
||||||
case "5447b6094bdc2dc3278b4567":
|
|
||||||
weaponChances = apbsModChances.shotgun;
|
|
||||||
break;
|
|
||||||
case "5447bedf4bdc2d87278b4568":
|
|
||||||
weaponChances = apbsModChances.weaponMods;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
weaponChances = apbsModChances.weaponMods;
|
|
||||||
this.apbsLogger.log(Logging.WARN, `ItemTemplate._parent is missing classification - Report to acidphantasm - ${weaponItemTemplate._parent}`)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!weaponItemTemplate)
|
|
||||||
{
|
|
||||||
this.logger.error(this.localisationService.getText("bot-missing_item_template", weaponTpl));
|
|
||||||
this.logger.error(`WeaponSlot -> ${equipmentSlot}`);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find ammo to use when filling magazines/chamber
|
|
||||||
if (!botTemplateInventory.Ammo)
|
|
||||||
{
|
|
||||||
this.logger.error(this.localisationService.getText("bot-no_ammo_found_in_bot_json", botRole));
|
|
||||||
|
|
||||||
throw new Error(this.localisationService.getText("bot-generation_failed"));
|
|
||||||
}
|
|
||||||
const ammoTable = this.apbsEquipmentGetter.getAmmoByBotRole(botRole, tierInfo)
|
|
||||||
const ammoTpl = this.getWeightedCompatibleAmmo(ammoTable, weaponItemTemplate);
|
|
||||||
|
|
||||||
// Create with just base weapon item
|
|
||||||
let weaponWithModsArray = this.constructWeaponBaseArray(
|
|
||||||
weaponTpl,
|
|
||||||
weaponParentId,
|
|
||||||
equipmentSlot,
|
|
||||||
weaponItemTemplate,
|
|
||||||
botRole
|
|
||||||
);
|
|
||||||
|
|
||||||
// Chance to add randomised weapon enhancement
|
|
||||||
if (isPmc && this.randomUtil.getChance100(this.pmcConfig.weaponHasEnhancementChancePercent))
|
|
||||||
{
|
|
||||||
const weaponConfig = this.repairConfig.repairKit.weapon;
|
|
||||||
this.repairService.addBuff(weaponConfig, weaponWithModsArray[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add mods to weapon base
|
|
||||||
if (Object.keys(modPool).includes(weaponTpl))
|
|
||||||
{
|
|
||||||
const botEquipmentRole = this.botGeneratorHelper.getBotEquipmentRole(botRole);
|
|
||||||
const modLimits = this.botWeaponModLimitService.getWeaponModLimits(botEquipmentRole);
|
|
||||||
|
|
||||||
const generateWeaponModsRequest: IGenerateWeaponRequest = {
|
|
||||||
weapon: weaponWithModsArray, // Will become hydrated array of weapon + mods
|
|
||||||
modPool: modPool,
|
|
||||||
weaponId: weaponWithModsArray[0]._id, // Weapon root id
|
|
||||||
parentTemplate: weaponItemTemplate,
|
|
||||||
modSpawnChances: weaponChances,
|
|
||||||
ammoTpl: ammoTpl,
|
|
||||||
botData: { role: botRole, level: botLevel, equipmentRole: botEquipmentRole },
|
|
||||||
modLimits: modLimits,
|
|
||||||
weaponStats: {},
|
|
||||||
conflictingItemTpls: new Set()
|
|
||||||
};
|
|
||||||
weaponWithModsArray = this.apbsBotEquipmentModGenerator.apbsGenerateModsForWeapon(
|
|
||||||
sessionId,
|
|
||||||
generateWeaponModsRequest,
|
|
||||||
isPmc
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use weapon preset from globals.json if weapon isnt valid
|
|
||||||
if (!this.isWeaponValid(weaponWithModsArray, botRole))
|
|
||||||
{
|
|
||||||
// Weapon is bad, fall back to weapons preset
|
|
||||||
weaponWithModsArray = this.getPresetWeaponMods(
|
|
||||||
weaponTpl,
|
|
||||||
equipmentSlot,
|
|
||||||
weaponParentId,
|
|
||||||
weaponItemTemplate,
|
|
||||||
botRole
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill existing magazines to full and sync ammo type
|
|
||||||
for (const magazine of weaponWithModsArray.filter((item) => item.slotId === this.modMagazineSlotId))
|
|
||||||
{
|
|
||||||
this.fillExistingMagazines(weaponWithModsArray, magazine, ammoTpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add cartridge(s) to gun chamber(s)
|
|
||||||
if (
|
|
||||||
weaponItemTemplate._props.Chambers?.length > 0
|
|
||||||
&& weaponItemTemplate._props.Chambers[0]?._props?.filters[0]?.Filter?.includes(ammoTpl)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Guns have variety of possible Chamber ids, patron_in_weapon/patron_in_weapon_000/patron_in_weapon_001
|
|
||||||
const chamberSlotNames = weaponItemTemplate._props.Chambers.map((x) => x._name);
|
|
||||||
this.addCartridgeToChamber(weaponWithModsArray, ammoTpl, chamberSlotNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill UBGL if found
|
|
||||||
const ubglMod = weaponWithModsArray.find((x) => x.slotId === "mod_launcher");
|
|
||||||
let ubglAmmoTpl: string = undefined;
|
|
||||||
if (ubglMod)
|
|
||||||
{
|
|
||||||
const ubglTemplate = this.itemHelper.getItem(ubglMod._tpl)[1];
|
|
||||||
ubglAmmoTpl = this.getWeightedCompatibleAmmo(botTemplateInventory.Ammo, ubglTemplate);
|
|
||||||
this.fillUbgl(weaponWithModsArray, ubglMod, ubglAmmoTpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is for testing...
|
|
||||||
if (this.modInformation.testMode && this.modInformation.testBotRole.includes(botRole.toLowerCase()))
|
|
||||||
{
|
|
||||||
const tables = this.databaseService.getTables();
|
|
||||||
const assortWeapon = this.cloner.clone(weaponWithModsArray);
|
|
||||||
for (const item in assortWeapon)
|
|
||||||
{
|
|
||||||
const oldID = assortWeapon[item]._id
|
|
||||||
const newID = this.hashUtil.generate();
|
|
||||||
assortWeapon[item]._id = newID;
|
|
||||||
|
|
||||||
// Loop array again to fix parentID
|
|
||||||
for (const i in assortWeapon)
|
|
||||||
{
|
|
||||||
if (assortWeapon[i].parentId == oldID)
|
|
||||||
{
|
|
||||||
assortWeapon[i].parentId = newID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.apbsTester.createComplexAssortItem(assortWeapon)
|
|
||||||
.addUnlimitedStackCount()
|
|
||||||
.addMoneyCost(Money.ROUBLES, 20000)
|
|
||||||
.addBuyRestriction(3)
|
|
||||||
.addLoyaltyLevel(1)
|
|
||||||
.export(tables.traders[this.modInformation.testTrader]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
weapon: weaponWithModsArray,
|
|
||||||
chosenAmmoTpl: ammoTpl,
|
|
||||||
chosenUbglAmmoTpl: ubglAmmoTpl,
|
|
||||||
weaponMods: modPool,
|
|
||||||
weaponTemplate: weaponItemTemplate
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public apbsAddExtraMagazinesToInventory(
|
|
||||||
generatedWeaponResult: IGenerateWeaponResult,
|
|
||||||
magWeights: IGenerationData,
|
|
||||||
inventory: PmcInventory,
|
|
||||||
botRole: string,
|
|
||||||
botLevel: number
|
|
||||||
): void
|
|
||||||
{
|
|
||||||
const weaponAndMods = generatedWeaponResult.weapon;
|
|
||||||
const weaponTemplate = generatedWeaponResult.weaponTemplate;
|
|
||||||
const magazineTpl = this.getMagazineTplFromWeaponTemplate(weaponAndMods, weaponTemplate, botRole);
|
|
||||||
|
|
||||||
const magTemplate = this.itemHelper.getItem(magazineTpl)[1];
|
|
||||||
if (!magTemplate)
|
|
||||||
{
|
|
||||||
this.logger.error(this.localisationService.getText("bot-unable_to_find_magazine_item", magazineTpl));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ammoTemplate = this.itemHelper.getItem(generatedWeaponResult.chosenAmmoTpl)[1];
|
|
||||||
if (!ammoTemplate)
|
|
||||||
{
|
|
||||||
this.logger.error(
|
|
||||||
this.localisationService.getText("bot-unable_to_find_ammo_item", generatedWeaponResult.chosenAmmoTpl)
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has an UBGL
|
|
||||||
if (generatedWeaponResult.chosenUbglAmmoTpl)
|
|
||||||
{
|
|
||||||
this.addUbglGrenadesToBotInventory(weaponAndMods, generatedWeaponResult, inventory);
|
|
||||||
}
|
|
||||||
|
|
||||||
const apbsInventoryMagGenModel = new APBSInventoryMagGen(
|
|
||||||
magWeights,
|
|
||||||
magTemplate,
|
|
||||||
weaponTemplate,
|
|
||||||
ammoTemplate,
|
|
||||||
inventory,
|
|
||||||
botRole,
|
|
||||||
botLevel
|
|
||||||
);
|
|
||||||
this.apbsInventoryMagGenComponents
|
|
||||||
.find((v) => v.canHandleInventoryMagGen(apbsInventoryMagGenModel))
|
|
||||||
.process(apbsInventoryMagGenModel);
|
|
||||||
|
|
||||||
// Add x stacks of bullets to SecuredContainer (bots use a magic mag packing skill to reload instantly)
|
|
||||||
this.addAmmoToSecureContainer(
|
|
||||||
this.botConfig.secureContainerAmmoStackCount,
|
|
||||||
generatedWeaponResult.chosenAmmoTpl,
|
|
||||||
ammoTemplate._props.StackMaxSize,
|
|
||||||
inventory
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,143 +0,0 @@
|
||||||
import { inject, injectable } from "tsyringe";
|
|
||||||
|
|
||||||
import { BotGenerator } from "@spt/generators/BotGenerator";
|
|
||||||
import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper";
|
|
||||||
import { BotHelper } from "@spt/helpers/BotHelper";
|
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
||||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
|
||||||
import { IPmcData } from "@spt/models/eft/common/IPmcData";
|
|
||||||
import { IBotInfoSettings } from "@spt/models/eft/common/tables/IBotBase";
|
|
||||||
import { IBotType } from "@spt/models/eft/common/tables/IBotType";
|
|
||||||
import { MemberCategory } from "@spt/models/enums/MemberCategory";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
|
||||||
import { SaveServer } from "@spt/servers/SaveServer";
|
|
||||||
import { BotLootCacheService } from "@spt/services/BotLootCacheService";
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { FenceService } from "@spt/services/FenceService";
|
|
||||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
|
||||||
import { HashUtil } from "@spt/utils/HashUtil";
|
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
|
||||||
import { ICloner } from "@spt/utils/cloners/ICloner";
|
|
||||||
import { PlayerScavGenerator } from "@spt/generators/PlayerScavGenerator";
|
|
||||||
import { APBSBotLootCacheService } from "./APBSBotLootCacheService";
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class APBSPlayerScavGenerator extends PlayerScavGenerator
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
|
||||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
||||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
|
||||||
@inject("HashUtil") protected hashUtil: HashUtil,
|
|
||||||
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
|
||||||
@inject("BotGeneratorHelper") protected botGeneratorHelper: BotGeneratorHelper,
|
|
||||||
@inject("SaveServer") protected saveServer: SaveServer,
|
|
||||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
|
||||||
@inject("BotHelper") protected botHelper: BotHelper,
|
|
||||||
@inject("FenceService") protected fenceService: FenceService,
|
|
||||||
@inject("BotLootCacheService") protected botLootCacheService: BotLootCacheService,
|
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
|
||||||
@inject("BotGenerator") protected botGenerator: BotGenerator,
|
|
||||||
@inject("ConfigServer") protected configServer: ConfigServer,
|
|
||||||
@inject("PrimaryCloner") protected cloner: ICloner,
|
|
||||||
@inject("APBSBotLootCacheService") protected apbsBotLootCacheService: APBSBotLootCacheService
|
|
||||||
)
|
|
||||||
{
|
|
||||||
super(logger,
|
|
||||||
randomUtil,
|
|
||||||
databaseService,
|
|
||||||
hashUtil,
|
|
||||||
itemHelper,
|
|
||||||
botGeneratorHelper,
|
|
||||||
saveServer,
|
|
||||||
profileHelper,
|
|
||||||
botHelper,
|
|
||||||
fenceService,
|
|
||||||
botLootCacheService,
|
|
||||||
localisationService,
|
|
||||||
botGenerator,
|
|
||||||
configServer,
|
|
||||||
cloner)
|
|
||||||
}
|
|
||||||
|
|
||||||
public generate(sessionID: string): IPmcData
|
|
||||||
{
|
|
||||||
// get karma level from profile
|
|
||||||
const profile = this.saveServer.getProfile(sessionID);
|
|
||||||
const profileCharactersClone = this.cloner.clone(profile.characters);
|
|
||||||
const pmcDataClone = profileCharactersClone.pmc;
|
|
||||||
const existingScavDataClone = profileCharactersClone.scav;
|
|
||||||
|
|
||||||
const scavKarmaLevel = this.getScavKarmaLevel(pmcDataClone);
|
|
||||||
|
|
||||||
// use karma level to get correct karmaSettings
|
|
||||||
const playerScavKarmaSettings = this.playerScavConfig.karmaLevel[scavKarmaLevel];
|
|
||||||
if (!playerScavKarmaSettings)
|
|
||||||
{
|
|
||||||
this.logger.error(this.localisationService.getText("scav-missing_karma_settings", scavKarmaLevel));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.debug(`generated player scav loadout with karma level ${scavKarmaLevel}`);
|
|
||||||
|
|
||||||
// Edit baseBotNode values
|
|
||||||
const baseBotNode: IBotType = this.constructBotBaseTemplate(playerScavKarmaSettings.botTypeForLoot);
|
|
||||||
this.adjustBotTemplateWithKarmaSpecificSettings(playerScavKarmaSettings, baseBotNode);
|
|
||||||
|
|
||||||
let scavData = this.botGenerator.generatePlayerScav(
|
|
||||||
sessionID,
|
|
||||||
playerScavKarmaSettings.botTypeForLoot.toLowerCase(),
|
|
||||||
"easy",
|
|
||||||
baseBotNode,
|
|
||||||
pmcDataClone
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove cached bot data after scav was generated
|
|
||||||
this.botLootCacheService.clearCache();
|
|
||||||
this.apbsBotLootCacheService.apbsClearCache();
|
|
||||||
|
|
||||||
// Add scav metadata
|
|
||||||
scavData.savage = undefined;
|
|
||||||
scavData.aid = pmcDataClone.aid;
|
|
||||||
scavData.TradersInfo = pmcDataClone.TradersInfo;
|
|
||||||
scavData.Info.Settings = {} as IBotInfoSettings;
|
|
||||||
scavData.Info.Bans = [];
|
|
||||||
scavData.Info.RegistrationDate = pmcDataClone.Info.RegistrationDate;
|
|
||||||
scavData.Info.GameVersion = pmcDataClone.Info.GameVersion;
|
|
||||||
scavData.Info.MemberCategory = MemberCategory.UNIQUE_ID;
|
|
||||||
scavData.Info.lockedMoveCommands = true;
|
|
||||||
scavData.RagfairInfo = pmcDataClone.RagfairInfo;
|
|
||||||
scavData.UnlockedInfo = pmcDataClone.UnlockedInfo;
|
|
||||||
|
|
||||||
// Persist previous scav data into new scav
|
|
||||||
scavData._id = existingScavDataClone._id ?? pmcDataClone.savage;
|
|
||||||
scavData.sessionId = existingScavDataClone.sessionId ?? pmcDataClone.sessionId;
|
|
||||||
scavData.Skills = this.getScavSkills(existingScavDataClone);
|
|
||||||
scavData.Stats = this.getScavStats(existingScavDataClone);
|
|
||||||
scavData.Info.Level = this.getScavLevel(existingScavDataClone);
|
|
||||||
scavData.Info.Experience = this.getScavExperience(existingScavDataClone);
|
|
||||||
scavData.Quests = existingScavDataClone.Quests ?? [];
|
|
||||||
scavData.TaskConditionCounters = existingScavDataClone.TaskConditionCounters ?? {};
|
|
||||||
scavData.Notes = existingScavDataClone.Notes ?? { Notes: [] };
|
|
||||||
scavData.WishList = existingScavDataClone.WishList ?? {};
|
|
||||||
scavData.Encyclopedia = pmcDataClone.Encyclopedia ?? {};
|
|
||||||
|
|
||||||
// Add additional items to player scav as loot
|
|
||||||
this.addAdditionalLootToPlayerScavContainers(playerScavKarmaSettings.lootItemsToAddChancePercent, scavData, [
|
|
||||||
"TacticalVest",
|
|
||||||
"Pockets",
|
|
||||||
"Backpack"
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Remove secure container
|
|
||||||
scavData = this.profileHelper.removeSecureContainer(scavData);
|
|
||||||
|
|
||||||
// Set cooldown timer
|
|
||||||
scavData = this.setScavCooldownTimer(scavData, pmcDataClone);
|
|
||||||
|
|
||||||
// Add scav to the profile
|
|
||||||
this.saveServer.getProfile(sessionID).characters.scav = scavData;
|
|
||||||
|
|
||||||
return scavData;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
export enum Logging
|
|
||||||
{
|
|
||||||
SCAV = "scav_generation",
|
|
||||||
PMC = "pmc_generation",
|
|
||||||
RAIDER = "raider_generation",
|
|
||||||
BOSS = "boss_generation",
|
|
||||||
EVENT = "event_generation",
|
|
||||||
WARN = "warnings",
|
|
||||||
ERR = "errors",
|
|
||||||
DEBUG = "debug"
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum LoggingFolders
|
|
||||||
{
|
|
||||||
DEBUG = "debug",
|
|
||||||
SCAV = "scav_generation",
|
|
||||||
PMC = "pmc_generation",
|
|
||||||
RAIDER = "raider_generation",
|
|
||||||
BOSS = "boss_generation",
|
|
||||||
EVENT = "event_generation"
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
import { DependencyContainer, inject, injectable } from "tsyringe";
|
|
||||||
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
|
||||||
import { BotLevelGenerator } from "@spt/generators/BotLevelGenerator";
|
|
||||||
import { MinMax } from "@spt/models/common/MinMax";
|
|
||||||
import { IRandomisedBotLevelResult } from "@spt/models/eft/bot/IRandomisedBotLevelResult";
|
|
||||||
import { IBotGenerationDetails } from "@spt/models/spt/bots/BotGenerationDetails";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { Logging } from "../Enums/Logging";
|
|
||||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
|
||||||
import { APBSIBotBase } from "../Interface/APBSIBotBase";
|
|
||||||
import { RaidInformation } from "../Globals/RaidInformation";
|
|
||||||
import { APBSTierGetter } from "../Utils/APBSTierGetter";
|
|
||||||
import { ModConfig } from "../Globals/ModConfig";
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { ModInformation } from "../Globals/ModInformation";
|
|
||||||
|
|
||||||
/** Handle profile related client events */
|
|
||||||
@injectable()
|
|
||||||
export class APBSBotLevelGenerator
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
||||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
|
||||||
@inject("BotLevelGenerator") protected botLevelGenerator: BotLevelGenerator,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger,
|
|
||||||
@inject("ProfileHelper") protected profileHelper: ProfileHelper,
|
|
||||||
@inject("APBSTierGetter") protected apbsTierGetter: APBSTierGetter,
|
|
||||||
@inject("RaidInformation") protected raidInformation: RaidInformation,
|
|
||||||
@inject("ModInformation") protected modInformation: ModInformation,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public registerBotLevelGenerator(container: DependencyContainer): void
|
|
||||||
{
|
|
||||||
container.afterResolution("BotLevelGenerator", (_t, result: BotLevelGenerator) =>
|
|
||||||
{
|
|
||||||
result.generateBotLevel = (levelDetails: MinMax, botGenerationDetails: IBotGenerationDetails, bot: APBSIBotBase): IRandomisedBotLevelResult =>
|
|
||||||
{
|
|
||||||
if (this.modInformation.testMode && this.modInformation.testBotRole.includes(botGenerationDetails.role.toLowerCase()))
|
|
||||||
{
|
|
||||||
const level = this.profileHelper.getPmcProfile(this.raidInformation.sessionId)?.Info?.Level;
|
|
||||||
const exp = this.profileHelper.getExperience(level);
|
|
||||||
const tier = this.apbsTierGetter.getTierByLevel(level);
|
|
||||||
bot.Info.Tier = this.chadOrChill(tier.toString());
|
|
||||||
|
|
||||||
const result: IRandomisedBotLevelResult = {
|
|
||||||
level,
|
|
||||||
exp
|
|
||||||
};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (botGenerationDetails.isPlayerScav)
|
|
||||||
{
|
|
||||||
let level = this.raidInformation.freshProfile == true ? 1 : this.profileHelper.getPmcProfile(this.raidInformation.sessionId)?.Info?.Level;
|
|
||||||
|
|
||||||
// Level only stays undefined when a Fika dedicated profile is created due to this.raidInformation.freshProfile never being set.
|
|
||||||
// As Fika never calls /client/profile/status
|
|
||||||
if (level === undefined)
|
|
||||||
{
|
|
||||||
this.raidInformation.freshProfile = true;
|
|
||||||
level = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const exp = this.profileHelper.getExperience(level);
|
|
||||||
const tier = this.apbsTierGetter.getTierByLevel(level);
|
|
||||||
bot.Info.Tier = this.chadOrChill(tier.toString());
|
|
||||||
const result: IRandomisedBotLevelResult = {
|
|
||||||
level,
|
|
||||||
exp
|
|
||||||
};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!botGenerationDetails.isPmc && !botGenerationDetails.isPlayerScav && ModConfig.config.enableScavCustomLevelDeltas)
|
|
||||||
{
|
|
||||||
const expTable = this.databaseService.getGlobals().config.exp.level.exp_table;
|
|
||||||
const botLevelRange = this.apbsGetRelativeBotLevelRange(botGenerationDetails, levelDetails, expTable.length);
|
|
||||||
const min = botLevelRange.min <= 0 ? 1 : botLevelRange.min;
|
|
||||||
const max = botLevelRange.max >= 79 ? 79 : botLevelRange.max;
|
|
||||||
const level = this.randomUtil.getInt(min, max);
|
|
||||||
const exp = this.profileHelper.getExperience(level);
|
|
||||||
const tier = this.apbsTierGetter.getTierByLevel(level);
|
|
||||||
bot.Info.Tier = this.chadOrChill(tier.toString());
|
|
||||||
|
|
||||||
const result: IRandomisedBotLevelResult = {
|
|
||||||
level,
|
|
||||||
exp
|
|
||||||
};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const expTable = this.databaseService.getGlobals().config.exp.level.exp_table;
|
|
||||||
const botLevelRange = this.apbsGetRelativeBotLevelRange(botGenerationDetails, levelDetails, expTable.length);
|
|
||||||
const min = botLevelRange.min <= 0 ? 1 : botLevelRange.min;
|
|
||||||
const max = botLevelRange.max >= 79 ? 79 : botLevelRange.max;
|
|
||||||
const level = this.randomUtil.getInt(min, max);
|
|
||||||
const exp = this.profileHelper.getExperience(level);
|
|
||||||
const tier = this.apbsTierGetter.getTierByLevel(level);
|
|
||||||
bot.Info.Tier = this.chadOrChill(tier.toString());
|
|
||||||
|
|
||||||
const result: IRandomisedBotLevelResult = {
|
|
||||||
level,
|
|
||||||
exp
|
|
||||||
};
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{ frequency: "Always" }
|
|
||||||
);
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, "Bot Level Generator registered");
|
|
||||||
}
|
|
||||||
|
|
||||||
private chadOrChill(tierInfo: string): string
|
|
||||||
{
|
|
||||||
if (ModConfig.config.onlyChads && ModConfig.config.tarkovAndChill)
|
|
||||||
{
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
if (ModConfig.config.onlyChads) return "7";
|
|
||||||
if (ModConfig.config.tarkovAndChill) return "1";
|
|
||||||
if (ModConfig.config.blickyMode) return "0";
|
|
||||||
|
|
||||||
return tierInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected apbsGetRelativeBotLevelRange(
|
|
||||||
botGenerationDetails: IBotGenerationDetails,
|
|
||||||
levelDetails: MinMax,
|
|
||||||
maxAvailableLevel: number
|
|
||||||
): MinMax
|
|
||||||
{
|
|
||||||
const minPossibleLevel =
|
|
||||||
botGenerationDetails.isPmc && botGenerationDetails.locationSpecificPmcLevelOverride
|
|
||||||
? Math.min(
|
|
||||||
Math.max(levelDetails.min, botGenerationDetails.locationSpecificPmcLevelOverride.min), // Biggest between json min and the botgen min
|
|
||||||
maxAvailableLevel // Fallback if value above is crazy (default is 79)
|
|
||||||
)
|
|
||||||
: Math.min(levelDetails.min, maxAvailableLevel); // Not pmc with override or non-pmc
|
|
||||||
|
|
||||||
const maxPossibleLevel =
|
|
||||||
botGenerationDetails.isPmc && botGenerationDetails.locationSpecificPmcLevelOverride
|
|
||||||
? Math.min(botGenerationDetails.locationSpecificPmcLevelOverride.max, maxAvailableLevel) // Was a PMC and they have a level override
|
|
||||||
: Math.min(levelDetails.max, maxAvailableLevel); // Not pmc with override or non-pmc
|
|
||||||
|
|
||||||
let minLevel = botGenerationDetails.playerLevel - this.apbsTierGetter.getTierLowerLevelDeviation(botGenerationDetails.playerLevel);
|
|
||||||
let maxLevel = botGenerationDetails.playerLevel + this.apbsTierGetter.getTierUpperLevelDeviation(botGenerationDetails.playerLevel);
|
|
||||||
|
|
||||||
if (ModConfig.config.enableScavCustomLevelDeltas && !botGenerationDetails.isPmc && !botGenerationDetails.isPlayerScav && (botGenerationDetails.role.includes("assault") || botGenerationDetails.role == "marksman"))
|
|
||||||
{
|
|
||||||
minLevel = botGenerationDetails.playerLevel - this.apbsTierGetter.getScavTierLowerLevelDeviation(botGenerationDetails.playerLevel);
|
|
||||||
maxLevel = botGenerationDetails.playerLevel + this.apbsTierGetter.getScavTierUpperLevelDeviation(botGenerationDetails.playerLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bound the level to the min/max possible
|
|
||||||
maxLevel = Math.min(Math.max(maxLevel, minPossibleLevel), maxPossibleLevel);
|
|
||||||
minLevel = Math.min(Math.max(minLevel, minPossibleLevel), maxPossibleLevel);
|
|
||||||
|
|
||||||
return {
|
|
||||||
min: minLevel,
|
|
||||||
max: maxLevel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,154 +0,0 @@
|
||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
|
||||||
import { VFS } from "@spt/utils/VFS";
|
|
||||||
import { inject, injectable } from "tsyringe";
|
|
||||||
import jsonc from "jsonc";
|
|
||||||
import path from "path";
|
|
||||||
import { TierInformation } from "./TierInformation";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class ModConfig
|
|
||||||
{
|
|
||||||
public static config: Config;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger,
|
|
||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
|
||||||
@inject("TierInformation") protected tierInformation: TierInformation,
|
|
||||||
@inject("VFS") protected vfs: VFS
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ModConfig.config = jsonc.parse(this.vfs.readFile(path.resolve(__dirname, "../../config/config.jsonc")));
|
|
||||||
}
|
|
||||||
|
|
||||||
public serverLogDetails(): void
|
|
||||||
{
|
|
||||||
this.logger.debug("[APBS] Mod Config - FOR SUPPORT FOLKS ❤❤")
|
|
||||||
this.logger.debug(`[APBS] Import Mod Weapons: ${ModConfig.config.enableModdedWeapons} <- MUST BE FALSE FOR SUPPORT`)
|
|
||||||
this.logger.debug(`[APBS] Import Mod Equipment: ${ModConfig.config.enableModdedEquipment} <- MUST BE FALSE FOR SUPPORT`)
|
|
||||||
this.logger.debug(`[APBS] Import Mod Clothing: ${ModConfig.config.enableModdedClothing} <- MUST BE FALSE FOR SUPPORT`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Config
|
|
||||||
{
|
|
||||||
usePreset: boolean,
|
|
||||||
presetName: string,
|
|
||||||
enableModdedWeapons: boolean,
|
|
||||||
enableModdedEquipment: boolean,
|
|
||||||
enableModdedClothing: boolean,
|
|
||||||
initalTierAppearance: number,
|
|
||||||
pmcWeaponWeights: number,
|
|
||||||
scavWeaponWeights: number,
|
|
||||||
followerWeaponWeights: number,
|
|
||||||
enableSafeGuard: boolean,
|
|
||||||
seasonalPmcAppearance: boolean,
|
|
||||||
disableRealismGasMasks: boolean,
|
|
||||||
onlyChads: boolean,
|
|
||||||
tarkovAndChill: boolean,
|
|
||||||
blickyMode: boolean,
|
|
||||||
disableScavTierGeneration: boolean,
|
|
||||||
disablePMCTierGeneration: boolean,
|
|
||||||
disableBossTierGeneration: boolean,
|
|
||||||
disableBossFollowerTierGeneration: boolean,
|
|
||||||
disableRaiderRogueTierGeneration: boolean,
|
|
||||||
enableBotsToRollAmmoAgain: boolean,
|
|
||||||
chanceToRollAmmoAgain: number,
|
|
||||||
gameVersionWeight: boolean,
|
|
||||||
standard: number,
|
|
||||||
left_behind: number,
|
|
||||||
prepare_for_escape: number,
|
|
||||||
edge_of_darkness: number,
|
|
||||||
unheard_edition: number,
|
|
||||||
enablePMCAmmoTierSliding: boolean,
|
|
||||||
slideAmount: number,
|
|
||||||
slideChance: number,
|
|
||||||
enablePerWeaponTypeAttachmentChances: boolean,
|
|
||||||
forceStock: boolean,
|
|
||||||
stockButtpadChance: number,
|
|
||||||
forceDustCover: boolean,
|
|
||||||
forceScopeSlot: boolean,
|
|
||||||
forceMuzzle: boolean,
|
|
||||||
muzzleChance: [ number, number, number, number, number, number, number ],
|
|
||||||
forceChildrenMuzzle: boolean,
|
|
||||||
pmcLoot: boolean,
|
|
||||||
pmcLootBlacklistItems: string[],
|
|
||||||
scavLoot: boolean,
|
|
||||||
enableScavAttachmentTiering: boolean,
|
|
||||||
enableScavEqualEquipmentTiering: boolean,
|
|
||||||
forceWeaponModLimits: boolean,
|
|
||||||
scopeLimit: number,
|
|
||||||
tacticalLimit: number,
|
|
||||||
enableT7Thermals: boolean,
|
|
||||||
startTier: number,
|
|
||||||
scavWeaponDurability: [ number, number, number, number ],
|
|
||||||
pmcWeaponDurability: [ number, number, number, number ],
|
|
||||||
bossWeaponDurability: [ number, number, number, number ],
|
|
||||||
guardWeaponDurability: [ number, number, number, number ],
|
|
||||||
raiderWeaponDurability: [ number, number, number, number ],
|
|
||||||
enableCustomPlateChances: boolean,
|
|
||||||
scavMainPlateChance: [ number, number, number, number, number, number, number ],
|
|
||||||
scavSidePlateChance: [ number, number, number, number, number, number, number ],
|
|
||||||
pmcMainPlateChance: [ number, number, number, number, number, number, number ],
|
|
||||||
pmcSidePlateChance: [ number, number, number, number, number, number, number ],
|
|
||||||
bossMainPlateChance: [ number, number, number, number, number, number, number ],
|
|
||||||
bossSidePlateChance: [ number, number, number, number, number, number, number ],
|
|
||||||
guardMainPlateChance: [ number, number, number, number, number, number, number ],
|
|
||||||
guardSidePlateChance: [ number, number, number, number, number, number, number ],
|
|
||||||
raiderMainPlateChance: [ number, number, number, number, number, number, number ],
|
|
||||||
raiderSidePlateChance: [ number, number, number, number, number, number, number ],
|
|
||||||
addAllKeysToScavs: boolean,
|
|
||||||
addOnlyMechanicalKeysToScavs: boolean,
|
|
||||||
addOnlyKeyCardsToScavs: boolean,
|
|
||||||
enableConsumableResourceRandomization: boolean,
|
|
||||||
scavFoodRates: [ number, number ]
|
|
||||||
scavMedRates: [ number, number ]
|
|
||||||
pmcFoodRates: [ number, number ]
|
|
||||||
pmcMedRates: [ number, number ]
|
|
||||||
tier1AmmoBlacklist: string[],
|
|
||||||
tier2AmmoBlacklist: string[],
|
|
||||||
tier3AmmoBlacklist: string[],
|
|
||||||
tier4AmmoBlacklist: string[],
|
|
||||||
tier5AmmoBlacklist: string[],
|
|
||||||
tier6AmmoBlacklist: string[],
|
|
||||||
tier7AmmoBlacklist: string[],
|
|
||||||
tier1EquipmentBlacklist: string[],
|
|
||||||
tier2EquipmentBlacklist: string[],
|
|
||||||
tier3EquipmentBlacklist: string[],
|
|
||||||
tier4EquipmentBlacklist: string[],
|
|
||||||
tier5EquipmentBlacklist: string[],
|
|
||||||
tier6EquipmentBlacklist: string[],
|
|
||||||
tier7EquipmentBlacklist: string[],
|
|
||||||
tier1WeaponBlacklist: string[],
|
|
||||||
tier2WeaponBlacklist: string[],
|
|
||||||
tier3WeaponBlacklist: string[],
|
|
||||||
tier4WeaponBlacklist: string[],
|
|
||||||
tier5WeaponBlacklist: string[],
|
|
||||||
tier6WeaponBlacklist: string[],
|
|
||||||
tier7WeaponBlacklist: string[],
|
|
||||||
tier1AttachmentBlacklist: string[],
|
|
||||||
tier2AttachmentBlacklist: string[],
|
|
||||||
tier3AttachmentBlacklist: string[],
|
|
||||||
tier4AttachmentBlacklist: string[],
|
|
||||||
tier5AttachmentBlacklist: string[],
|
|
||||||
tier6AttachmentBlacklist: string[],
|
|
||||||
tier7AttachmentBlacklist: string[],
|
|
||||||
enableCustomLevelDeltas: boolean,
|
|
||||||
tier1LevelDelta: [ number, number ],
|
|
||||||
tier2LevelDelta: [ number, number ],
|
|
||||||
tier3LevelDelta: [ number, number ],
|
|
||||||
tier4LevelDelta: [ number, number ],
|
|
||||||
tier5LevelDelta: [ number, number ],
|
|
||||||
tier6LevelDelta: [ number, number ],
|
|
||||||
tier7LevelDelta: [ number, number ],
|
|
||||||
enableScavCustomLevelDeltas: boolean,
|
|
||||||
tier1ScavLevelDelta: [ number, number ],
|
|
||||||
tier2ScavLevelDelta: [ number, number ],
|
|
||||||
tier3ScavLevelDelta: [ number, number ],
|
|
||||||
tier4ScavLevelDelta: [ number, number ],
|
|
||||||
tier5ScavLevelDelta: [ number, number ],
|
|
||||||
tier6ScavLevelDelta: [ number, number ],
|
|
||||||
tier7ScavLevelDelta: [ number, number ],
|
|
||||||
enableDebugLog: boolean,
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
import * as path from "path";
|
|
||||||
import modPackage = require("../../package.json");
|
|
||||||
|
|
||||||
export class ModInformation
|
|
||||||
{
|
|
||||||
public modPath: string = path.join(path.dirname(__filename), "..", "..");
|
|
||||||
public logPath: string = path.join(path.dirname(__filename), "..", "..", "logs");
|
|
||||||
public profilePath: string = path.join(path.dirname(__filename), "..", "..", "..", "..", "profiles");
|
|
||||||
public versionNumber: string = modPackage.version;
|
|
||||||
|
|
||||||
public testMode: boolean = false;
|
|
||||||
public testBotRole: (string)[] = [ "pmcusec", "pmcbear" ]
|
|
||||||
public testTrader: string = "6741449944c5b44c53741ccc"
|
|
||||||
public clearAssortPreRaid: boolean = true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,169 +0,0 @@
|
||||||
import { injectable } from "tsyringe";
|
|
||||||
import { ModConfig } from "./ModConfig";
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class RaidInformation
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public freshProfile: boolean;
|
|
||||||
|
|
||||||
public location: string;
|
|
||||||
public currentTime: string;
|
|
||||||
public timeVariant: string;
|
|
||||||
public nightTime: boolean;
|
|
||||||
|
|
||||||
public sessionId: string;
|
|
||||||
|
|
||||||
public usingDefaultDB: boolean;
|
|
||||||
|
|
||||||
public mapWeights = {
|
|
||||||
"bigmap":
|
|
||||||
{
|
|
||||||
"LongRange": 20,
|
|
||||||
"ShortRange": 80
|
|
||||||
},
|
|
||||||
"RezervBase":
|
|
||||||
{
|
|
||||||
"LongRange": 20,
|
|
||||||
"ShortRange": 80
|
|
||||||
},
|
|
||||||
"laboratory":
|
|
||||||
{
|
|
||||||
"LongRange": 5,
|
|
||||||
"ShortRange": 95
|
|
||||||
},
|
|
||||||
"factory4_night":
|
|
||||||
{
|
|
||||||
"LongRange": 1,
|
|
||||||
"ShortRange": 99
|
|
||||||
},
|
|
||||||
"factory4_day":
|
|
||||||
{
|
|
||||||
"LongRange": 1,
|
|
||||||
"ShortRange": 99
|
|
||||||
},
|
|
||||||
"Interchange":
|
|
||||||
{
|
|
||||||
"LongRange": 20,
|
|
||||||
"ShortRange": 80
|
|
||||||
},
|
|
||||||
"Sandbox":
|
|
||||||
{
|
|
||||||
"LongRange": 15,
|
|
||||||
"ShortRange": 85
|
|
||||||
},
|
|
||||||
"Sandbox_high":
|
|
||||||
{
|
|
||||||
"LongRange": 15,
|
|
||||||
"ShortRange": 85
|
|
||||||
},
|
|
||||||
"Woods":
|
|
||||||
{
|
|
||||||
"LongRange": 60,
|
|
||||||
"ShortRange": 40
|
|
||||||
},
|
|
||||||
"Shoreline":
|
|
||||||
{
|
|
||||||
"LongRange": 50,
|
|
||||||
"ShortRange": 50
|
|
||||||
},
|
|
||||||
"Lighthouse":
|
|
||||||
{
|
|
||||||
"LongRange": 30,
|
|
||||||
"ShortRange": 70
|
|
||||||
},
|
|
||||||
"TarkovStreets":
|
|
||||||
{
|
|
||||||
"LongRange": 20,
|
|
||||||
"ShortRange": 80
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public alwaysDisabledBots = [
|
|
||||||
"shooterbtr",
|
|
||||||
"skier",
|
|
||||||
"peacemaker",
|
|
||||||
"gifter",
|
|
||||||
"infectedassault",
|
|
||||||
"infectedcivil",
|
|
||||||
"infectedlaborant",
|
|
||||||
"infectedpmc",
|
|
||||||
"infectedtagilla",
|
|
||||||
"bosslegion",
|
|
||||||
"bosspunisher"
|
|
||||||
]
|
|
||||||
public isBotEnabled(botType: string): boolean
|
|
||||||
{
|
|
||||||
botType = botType.toLowerCase();
|
|
||||||
switch (botType)
|
|
||||||
{
|
|
||||||
case "pmcbear":
|
|
||||||
case "pmcusec":
|
|
||||||
if (ModConfig.config.disablePMCTierGeneration) return false;
|
|
||||||
return true;
|
|
||||||
case "cursedassault":
|
|
||||||
case "marksman":
|
|
||||||
case "assault":
|
|
||||||
if (ModConfig.config.disableScavTierGeneration) return false;
|
|
||||||
return true;
|
|
||||||
case "arenafighterevent":
|
|
||||||
case "exusec":
|
|
||||||
if (ModConfig.config.disableRaiderRogueTierGeneration) return false;
|
|
||||||
return true;
|
|
||||||
case "bossbully":
|
|
||||||
case "bosstagilla":
|
|
||||||
case "bosspartisan":
|
|
||||||
case "bossgluhar":
|
|
||||||
case "bosskilla":
|
|
||||||
case "bosskojaniy":
|
|
||||||
case "bosssanitar":
|
|
||||||
case "bossknight":
|
|
||||||
case "bosszryachiy":
|
|
||||||
case "bosstest":
|
|
||||||
case "bosskolontay":
|
|
||||||
case "bossboar":
|
|
||||||
case "bossboarSniper":
|
|
||||||
case "sectantpriest":
|
|
||||||
if (ModConfig.config.disableBossTierGeneration) return false;
|
|
||||||
return true;
|
|
||||||
case "sectantwarrior":
|
|
||||||
case "followerboarblose1":
|
|
||||||
case "followerboarclose2":
|
|
||||||
case "followerkolontayassault":
|
|
||||||
case "followerkolontaysecurity":
|
|
||||||
case "followerbully":
|
|
||||||
case "followergluharassault":
|
|
||||||
case "followergluharscout":
|
|
||||||
case "followergluharsecurity":
|
|
||||||
case "followergluharsnipe":
|
|
||||||
case "followerkojaniy":
|
|
||||||
case "followersanitar":
|
|
||||||
case "followertagilla":
|
|
||||||
case "followerbirdeye":
|
|
||||||
case "followerbigpipe":
|
|
||||||
case "followerzryachiy":
|
|
||||||
case "followertest":
|
|
||||||
case "followerboar":
|
|
||||||
if (ModConfig.config.disableBossFollowerTierGeneration) return false;
|
|
||||||
return true;
|
|
||||||
case "shooterbtr":
|
|
||||||
case "skier":
|
|
||||||
case "peacemaker":
|
|
||||||
case "gifter":
|
|
||||||
case "infectedassault":
|
|
||||||
case "infectedcivil":
|
|
||||||
case "infectedlaborant":
|
|
||||||
case "infectedpmc":
|
|
||||||
case "infectedtagilla":
|
|
||||||
case "bosslegion":
|
|
||||||
case "bosspunisher":
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,373 +0,0 @@
|
||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
|
||||||
export class TierInformation
|
|
||||||
{
|
|
||||||
public tier0;
|
|
||||||
public tier1;
|
|
||||||
public tier2;
|
|
||||||
public tier3;
|
|
||||||
public tier4;
|
|
||||||
public tier5;
|
|
||||||
public tier6;
|
|
||||||
public tier7;
|
|
||||||
|
|
||||||
public tier0mods;
|
|
||||||
public tier1mods;
|
|
||||||
public tier2mods;
|
|
||||||
public tier3mods;
|
|
||||||
public tier4mods;
|
|
||||||
public tier5mods;
|
|
||||||
public tier6mods;
|
|
||||||
public tier7mods;
|
|
||||||
|
|
||||||
public tier0chances;
|
|
||||||
public tier1chances;
|
|
||||||
public tier2chances;
|
|
||||||
public tier3chances;
|
|
||||||
public tier4chances;
|
|
||||||
public tier5chances;
|
|
||||||
public tier6chances;
|
|
||||||
public tier7chances;
|
|
||||||
|
|
||||||
public tier0ammo;
|
|
||||||
public tier1ammo;
|
|
||||||
public tier2ammo;
|
|
||||||
public tier3ammo;
|
|
||||||
public tier4ammo;
|
|
||||||
public tier5ammo;
|
|
||||||
public tier6ammo;
|
|
||||||
public tier7ammo;
|
|
||||||
|
|
||||||
public tier0appearance;
|
|
||||||
public tier1appearance;
|
|
||||||
public tier2appearance;
|
|
||||||
public tier3appearance;
|
|
||||||
public tier4appearance;
|
|
||||||
public tier5appearance;
|
|
||||||
public tier6appearance;
|
|
||||||
public tier7appearance;
|
|
||||||
|
|
||||||
public tiers = [
|
|
||||||
{
|
|
||||||
tier: 1,
|
|
||||||
playerMinimumLevel: 1,
|
|
||||||
playerMaximumLevel: 10,
|
|
||||||
botMinLevelVariance: 10,
|
|
||||||
botMaxLevelVariance: 5,
|
|
||||||
scavMinLevelVariance: 10,
|
|
||||||
scavMaxLevelVariance: 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tier: 2,
|
|
||||||
playerMinimumLevel: 11,
|
|
||||||
playerMaximumLevel: 20,
|
|
||||||
botMinLevelVariance: 10,
|
|
||||||
botMaxLevelVariance: 5,
|
|
||||||
scavMinLevelVariance: 10,
|
|
||||||
scavMaxLevelVariance: 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tier: 3,
|
|
||||||
playerMinimumLevel: 21,
|
|
||||||
playerMaximumLevel: 30,
|
|
||||||
botMinLevelVariance: 15,
|
|
||||||
botMaxLevelVariance: 7,
|
|
||||||
scavMinLevelVariance: 15,
|
|
||||||
scavMaxLevelVariance: 7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tier: 4,
|
|
||||||
playerMinimumLevel: 31,
|
|
||||||
playerMaximumLevel: 40,
|
|
||||||
botMinLevelVariance: 20,
|
|
||||||
botMaxLevelVariance: 10,
|
|
||||||
scavMinLevelVariance: 20,
|
|
||||||
scavMaxLevelVariance: 10
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tier: 5,
|
|
||||||
playerMinimumLevel: 41,
|
|
||||||
playerMaximumLevel: 50,
|
|
||||||
botMinLevelVariance: 30,
|
|
||||||
botMaxLevelVariance: 15,
|
|
||||||
scavMinLevelVariance: 30,
|
|
||||||
scavMaxLevelVariance: 15
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tier: 6,
|
|
||||||
playerMinimumLevel: 51,
|
|
||||||
playerMaximumLevel: 60,
|
|
||||||
botMinLevelVariance: 40,
|
|
||||||
botMaxLevelVariance: 20,
|
|
||||||
scavMinLevelVariance: 40,
|
|
||||||
scavMaxLevelVariance: 20
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tier: 7,
|
|
||||||
playerMinimumLevel: 61,
|
|
||||||
playerMaximumLevel: 100,
|
|
||||||
botMinLevelVariance: 50,
|
|
||||||
botMaxLevelVariance: 20,
|
|
||||||
scavMinLevelVariance: 50,
|
|
||||||
scavMaxLevelVariance: 20
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
public armorPlateWeights = [
|
|
||||||
{
|
|
||||||
"levelRange": {
|
|
||||||
"min": 1,
|
|
||||||
"max": 10
|
|
||||||
},
|
|
||||||
"front_plate": {
|
|
||||||
"2": 10,
|
|
||||||
"3": 80,
|
|
||||||
"4": 10
|
|
||||||
},
|
|
||||||
"back_plate": {
|
|
||||||
"2": 10,
|
|
||||||
"3": 80,
|
|
||||||
"4": 10
|
|
||||||
},
|
|
||||||
"side_plate": {
|
|
||||||
"2": 10,
|
|
||||||
"3": 80,
|
|
||||||
"4": 10
|
|
||||||
},
|
|
||||||
"left_side_plate": {
|
|
||||||
"2": 10,
|
|
||||||
"3": 80,
|
|
||||||
"4": 10
|
|
||||||
},
|
|
||||||
"right_side_plate": {
|
|
||||||
"2": 10,
|
|
||||||
"3": 80,
|
|
||||||
"4": 10
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"levelRange": {
|
|
||||||
"min": 11,
|
|
||||||
"max": 20
|
|
||||||
},
|
|
||||||
"front_plate": {
|
|
||||||
"3": 65,
|
|
||||||
"4": 32,
|
|
||||||
"5": 3
|
|
||||||
},
|
|
||||||
"back_plate": {
|
|
||||||
"3": 65,
|
|
||||||
"4": 32,
|
|
||||||
"5": 3
|
|
||||||
},
|
|
||||||
"side_plate": {
|
|
||||||
"3": 65,
|
|
||||||
"4": 32,
|
|
||||||
"5": 3
|
|
||||||
},
|
|
||||||
"left_side_plate": {
|
|
||||||
"3": 65,
|
|
||||||
"4": 32,
|
|
||||||
"5": 3
|
|
||||||
},
|
|
||||||
"right_side_plate": {
|
|
||||||
"3": 65,
|
|
||||||
"4": 32,
|
|
||||||
"5": 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"levelRange": {
|
|
||||||
"min": 21,
|
|
||||||
"max": 30
|
|
||||||
},
|
|
||||||
"front_plate": {
|
|
||||||
"3": 15,
|
|
||||||
"4": 70,
|
|
||||||
"5": 10,
|
|
||||||
"6": 5
|
|
||||||
},
|
|
||||||
"back_plate": {
|
|
||||||
"3": 15,
|
|
||||||
"4": 70,
|
|
||||||
"5": 10,
|
|
||||||
"6": 5
|
|
||||||
},
|
|
||||||
"side_plate": {
|
|
||||||
"3": 15,
|
|
||||||
"4": 70,
|
|
||||||
"5": 10,
|
|
||||||
"6": 5
|
|
||||||
},
|
|
||||||
"left_side_plate": {
|
|
||||||
"3": 15,
|
|
||||||
"4": 70,
|
|
||||||
"5": 10,
|
|
||||||
"6": 5
|
|
||||||
},
|
|
||||||
"right_side_plate": {
|
|
||||||
"3": 15,
|
|
||||||
"4": 70,
|
|
||||||
"5": 10,
|
|
||||||
"6": 5
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"levelRange": {
|
|
||||||
"min": 31,
|
|
||||||
"max": 40
|
|
||||||
},
|
|
||||||
"front_plate": {
|
|
||||||
"4": 30,
|
|
||||||
"5": 50,
|
|
||||||
"6": 20
|
|
||||||
},
|
|
||||||
"back_plate": {
|
|
||||||
"4": 30,
|
|
||||||
"5": 50,
|
|
||||||
"6": 20
|
|
||||||
},
|
|
||||||
"side_plate": {
|
|
||||||
"4": 30,
|
|
||||||
"5": 50,
|
|
||||||
"6": 20
|
|
||||||
},
|
|
||||||
"left_side_plate": {
|
|
||||||
"4": 30,
|
|
||||||
"5": 50,
|
|
||||||
"6": 20
|
|
||||||
},
|
|
||||||
"right_side_plate": {
|
|
||||||
"4": 30,
|
|
||||||
"5": 50,
|
|
||||||
"6": 20
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"levelRange": {
|
|
||||||
"min": 41,
|
|
||||||
"max": 50
|
|
||||||
},
|
|
||||||
"front_plate": {
|
|
||||||
"4": 10,
|
|
||||||
"5": 45,
|
|
||||||
"6": 45
|
|
||||||
},
|
|
||||||
"back_plate": {
|
|
||||||
"4": 10,
|
|
||||||
"5": 45,
|
|
||||||
"6": 45
|
|
||||||
},
|
|
||||||
"side_plate": {
|
|
||||||
"4": 10,
|
|
||||||
"5": 45,
|
|
||||||
"6": 45
|
|
||||||
},
|
|
||||||
"left_side_plate": {
|
|
||||||
"4": 10,
|
|
||||||
"5": 45,
|
|
||||||
"6": 45
|
|
||||||
},
|
|
||||||
"right_side_plate": {
|
|
||||||
"4": 10,
|
|
||||||
"5": 45,
|
|
||||||
"6": 45
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"levelRange": {
|
|
||||||
"min": 51,
|
|
||||||
"max": 60
|
|
||||||
},
|
|
||||||
"front_plate": {
|
|
||||||
"4": 5,
|
|
||||||
"5": 30,
|
|
||||||
"6": 65
|
|
||||||
},
|
|
||||||
"back_plate": {
|
|
||||||
"4": 5,
|
|
||||||
"5": 30,
|
|
||||||
"6": 65
|
|
||||||
},
|
|
||||||
"side_plate": {
|
|
||||||
"4": 5,
|
|
||||||
"5": 30,
|
|
||||||
"6": 65
|
|
||||||
},
|
|
||||||
"left_side_plate": {
|
|
||||||
"4": 5,
|
|
||||||
"5": 30,
|
|
||||||
"6": 65
|
|
||||||
},
|
|
||||||
"right_side_plate": {
|
|
||||||
"4": 5,
|
|
||||||
"5": 30,
|
|
||||||
"6": 65
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"levelRange": {
|
|
||||||
"min": 61,
|
|
||||||
"max": 100
|
|
||||||
},
|
|
||||||
"front_plate": {
|
|
||||||
"4": 1,
|
|
||||||
"5": 19,
|
|
||||||
"6": 80
|
|
||||||
},
|
|
||||||
"back_plate": {
|
|
||||||
"4": 1,
|
|
||||||
"5": 19,
|
|
||||||
"6": 80
|
|
||||||
},
|
|
||||||
"side_plate": {
|
|
||||||
"4": 1,
|
|
||||||
"5": 19,
|
|
||||||
"6": 80
|
|
||||||
},
|
|
||||||
"left_side_plate": {
|
|
||||||
"4": 1,
|
|
||||||
"5": 19,
|
|
||||||
"6": 80
|
|
||||||
},
|
|
||||||
"right_side_plate": {
|
|
||||||
"4": 1,
|
|
||||||
"5": 19,
|
|
||||||
"6": 80
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
public scavArmorPlateWeights = [
|
|
||||||
{
|
|
||||||
"levelRange": {
|
|
||||||
"min": 1,
|
|
||||||
"max": 100
|
|
||||||
},
|
|
||||||
"front_plate": {
|
|
||||||
"2": 15,
|
|
||||||
"3": 35,
|
|
||||||
"4": 5
|
|
||||||
},
|
|
||||||
"back_plate": {
|
|
||||||
"2": 15,
|
|
||||||
"3": 35,
|
|
||||||
"4": 5
|
|
||||||
},
|
|
||||||
"side_plate": {
|
|
||||||
"2": 15,
|
|
||||||
"3": 35,
|
|
||||||
"4": 5
|
|
||||||
},
|
|
||||||
"left_side_plate": {
|
|
||||||
"2": 15,
|
|
||||||
"3": 35,
|
|
||||||
"4": 5
|
|
||||||
},
|
|
||||||
"right_side_plate": {
|
|
||||||
"2": 15,
|
|
||||||
"3": 35,
|
|
||||||
"4": 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,236 +0,0 @@
|
||||||
import { injectable, inject } from "tsyringe";
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { Logging } from "../Enums/Logging";
|
|
||||||
import { ModConfig } from "../Globals/ModConfig";
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class BlacklistHelper
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
@inject("DatabaseService") protected database: DatabaseService,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public initialize(): void
|
|
||||||
{
|
|
||||||
if (ModConfig.config.tier1AmmoBlacklist.length > 0) this.removeBlacklistedAmmo(ModConfig.config.tier1AmmoBlacklist, 1);
|
|
||||||
if (ModConfig.config.tier2AmmoBlacklist.length > 0) this.removeBlacklistedAmmo(ModConfig.config.tier2AmmoBlacklist, 2);
|
|
||||||
if (ModConfig.config.tier3AmmoBlacklist.length > 0) this.removeBlacklistedAmmo(ModConfig.config.tier3AmmoBlacklist, 3);
|
|
||||||
if (ModConfig.config.tier4AmmoBlacklist.length > 0) this.removeBlacklistedAmmo(ModConfig.config.tier4AmmoBlacklist, 4);
|
|
||||||
if (ModConfig.config.tier5AmmoBlacklist.length > 0) this.removeBlacklistedAmmo(ModConfig.config.tier5AmmoBlacklist, 5);
|
|
||||||
if (ModConfig.config.tier6AmmoBlacklist.length > 0) this.removeBlacklistedAmmo(ModConfig.config.tier6AmmoBlacklist, 6);
|
|
||||||
if (ModConfig.config.tier7AmmoBlacklist.length > 0) this.removeBlacklistedAmmo(ModConfig.config.tier7AmmoBlacklist, 7);
|
|
||||||
if (ModConfig.config.tier1EquipmentBlacklist.length > 0) this.removeBlacklistedEquipment(ModConfig.config.tier1EquipmentBlacklist, 1);
|
|
||||||
if (ModConfig.config.tier2EquipmentBlacklist.length > 0) this.removeBlacklistedEquipment(ModConfig.config.tier2EquipmentBlacklist, 2);
|
|
||||||
if (ModConfig.config.tier3EquipmentBlacklist.length > 0) this.removeBlacklistedEquipment(ModConfig.config.tier3EquipmentBlacklist, 3);
|
|
||||||
if (ModConfig.config.tier4EquipmentBlacklist.length > 0) this.removeBlacklistedEquipment(ModConfig.config.tier4EquipmentBlacklist, 4);
|
|
||||||
if (ModConfig.config.tier5EquipmentBlacklist.length > 0) this.removeBlacklistedEquipment(ModConfig.config.tier5EquipmentBlacklist, 5);
|
|
||||||
if (ModConfig.config.tier6EquipmentBlacklist.length > 0) this.removeBlacklistedEquipment(ModConfig.config.tier6EquipmentBlacklist, 6);
|
|
||||||
if (ModConfig.config.tier7EquipmentBlacklist.length > 0) this.removeBlacklistedEquipment(ModConfig.config.tier7EquipmentBlacklist, 7);
|
|
||||||
if (ModConfig.config.tier1WeaponBlacklist.length > 0) this.removeBlacklistedWeapons(ModConfig.config.tier1WeaponBlacklist, 1);
|
|
||||||
if (ModConfig.config.tier2WeaponBlacklist.length > 0) this.removeBlacklistedWeapons(ModConfig.config.tier2WeaponBlacklist, 2);
|
|
||||||
if (ModConfig.config.tier3WeaponBlacklist.length > 0) this.removeBlacklistedWeapons(ModConfig.config.tier3WeaponBlacklist, 3);
|
|
||||||
if (ModConfig.config.tier4WeaponBlacklist.length > 0) this.removeBlacklistedWeapons(ModConfig.config.tier4WeaponBlacklist, 4);
|
|
||||||
if (ModConfig.config.tier5WeaponBlacklist.length > 0) this.removeBlacklistedWeapons(ModConfig.config.tier5WeaponBlacklist, 5);
|
|
||||||
if (ModConfig.config.tier6WeaponBlacklist.length > 0) this.removeBlacklistedWeapons(ModConfig.config.tier6WeaponBlacklist, 6);
|
|
||||||
if (ModConfig.config.tier7WeaponBlacklist.length > 0) this.removeBlacklistedWeapons(ModConfig.config.tier7WeaponBlacklist, 7);
|
|
||||||
if (ModConfig.config.tier1AttachmentBlacklist.length > 0) this.removeBlacklistedAttachments(ModConfig.config.tier1AttachmentBlacklist, 1);
|
|
||||||
if (ModConfig.config.tier2AttachmentBlacklist.length > 0) this.removeBlacklistedAttachments(ModConfig.config.tier2AttachmentBlacklist, 2);
|
|
||||||
if (ModConfig.config.tier3AttachmentBlacklist.length > 0) this.removeBlacklistedAttachments(ModConfig.config.tier3AttachmentBlacklist, 3);
|
|
||||||
if (ModConfig.config.tier4AttachmentBlacklist.length > 0) this.removeBlacklistedAttachments(ModConfig.config.tier4AttachmentBlacklist, 4);
|
|
||||||
if (ModConfig.config.tier5AttachmentBlacklist.length > 0) this.removeBlacklistedAttachments(ModConfig.config.tier5AttachmentBlacklist, 5);
|
|
||||||
if (ModConfig.config.tier6AttachmentBlacklist.length > 0) this.removeBlacklistedAttachments(ModConfig.config.tier6AttachmentBlacklist, 6);
|
|
||||||
if (ModConfig.config.tier7AttachmentBlacklist.length > 0) this.removeBlacklistedAttachments(ModConfig.config.tier7AttachmentBlacklist, 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
private removeBlacklistedAmmo(ammoBlacklist: string[], tier: number): void
|
|
||||||
{
|
|
||||||
const tierJSON = this.apbsEquipmentGetter.getTierAmmoJson(tier, true);
|
|
||||||
for (const item in ammoBlacklist)
|
|
||||||
{
|
|
||||||
const itemDetails = this.getItem(ammoBlacklist[item])
|
|
||||||
if (itemDetails != undefined && itemDetails._parent == "5485a8684bdc2da71d8b4567")
|
|
||||||
{
|
|
||||||
for (const botType in tierJSON)
|
|
||||||
{
|
|
||||||
for (const ammo in tierJSON[botType])
|
|
||||||
{
|
|
||||||
if (Object.keys(tierJSON[botType][ammo]).includes(itemDetails._id))
|
|
||||||
{
|
|
||||||
if (Object.keys(tierJSON[botType][ammo]).length > 1)
|
|
||||||
{
|
|
||||||
delete tierJSON[botType][ammo][itemDetails._id]
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `[Tier${tier}] Removed "${itemDetails._id}" from "${botType}" ${ammo} pool.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.apbsLogger.log(Logging.WARN, `Did not blacklist "${itemDetails._id}" as it would make the Tier${tier} "${botType}" ${ammo} pool empty`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (itemDetails == undefined || itemDetails._parent != "5485a8684bdc2da71d8b4567")
|
|
||||||
{
|
|
||||||
this.apbsLogger.log(Logging.WARN, `"${ammoBlacklist[item]}" in Ammo Blacklist is either an invalid ammunition or item ID.`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private removeBlacklistedEquipment(equipmentBlacklist: string[], tier: number): void
|
|
||||||
{
|
|
||||||
const tierJSON = this.apbsEquipmentGetter.getTierJson(tier, true);
|
|
||||||
for (const item in equipmentBlacklist)
|
|
||||||
{
|
|
||||||
const itemDetails = this.getItem(equipmentBlacklist[item])
|
|
||||||
if (itemDetails != undefined)
|
|
||||||
{
|
|
||||||
for (const botType in tierJSON)
|
|
||||||
{
|
|
||||||
for (const equipmentSlot in tierJSON[botType].equipment)
|
|
||||||
{
|
|
||||||
if (Object.keys(tierJSON[botType].equipment[equipmentSlot]).includes(itemDetails._id))
|
|
||||||
{
|
|
||||||
if (Object.keys(tierJSON[botType].equipment[equipmentSlot]).length > 1)
|
|
||||||
{
|
|
||||||
delete tierJSON[botType].equipment[equipmentSlot][itemDetails._id]
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `[Tier${tier}] Removed "${itemDetails._id}" from "${botType}" ${equipmentSlot} pool.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.apbsLogger.log(Logging.WARN, `Did not blacklist "${itemDetails._id}" as it would make the Tier${tier} "${botType}" ${equipmentSlot} pool empty.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (itemDetails == undefined)
|
|
||||||
{
|
|
||||||
this.apbsLogger.log(Logging.WARN, `"${equipmentBlacklist[item]}" in Equipment Blacklist is an invalid item ID.`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private removeBlacklistedWeapons(weaponBlacklist: string[], tier: number): void
|
|
||||||
{
|
|
||||||
const tierJSON = this.apbsEquipmentGetter.getTierJson(tier, true);
|
|
||||||
for (const item in weaponBlacklist)
|
|
||||||
{
|
|
||||||
const itemDetails = this.getItem(weaponBlacklist[item])
|
|
||||||
if (itemDetails != undefined)
|
|
||||||
{
|
|
||||||
for (const botType in tierJSON)
|
|
||||||
{
|
|
||||||
for (const equipmentSlot in tierJSON[botType].equipment.FirstPrimaryWeapon)
|
|
||||||
{
|
|
||||||
if (Object.keys(tierJSON[botType].equipment.FirstPrimaryWeapon[equipmentSlot]).includes(itemDetails._id))
|
|
||||||
{
|
|
||||||
if (Object.keys(tierJSON[botType].equipment.FirstPrimaryWeapon[equipmentSlot]).length > 1)
|
|
||||||
{
|
|
||||||
delete tierJSON[botType].equipment.FirstPrimaryWeapon[equipmentSlot][itemDetails._id]
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `[Tier${tier}] Removed "${itemDetails._id}" from "${botType}" ${equipmentSlot} pool.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.apbsLogger.log(Logging.WARN, `Did not blacklist "${itemDetails._id}" as it would make the Tier${tier} "${botType}" ${equipmentSlot} pool empty.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const equipmentSlot in tierJSON[botType].equipment.SecondPrimaryWeapon)
|
|
||||||
{
|
|
||||||
if (Object.keys(tierJSON[botType].equipment.SecondPrimaryWeapon[equipmentSlot]).includes(itemDetails._id))
|
|
||||||
{
|
|
||||||
if (Object.keys(tierJSON[botType].equipment.SecondPrimaryWeapon[equipmentSlot]).length > 1)
|
|
||||||
{
|
|
||||||
delete tierJSON[botType].equipment.SecondPrimaryWeapon[equipmentSlot][itemDetails._id]
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `[Tier${tier}] Removed "${itemDetails._id}" from "${botType}" ${equipmentSlot} pool.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.apbsLogger.log(Logging.WARN, `Did not blacklist "${itemDetails._id}" as it would make the Tier${tier} "${botType}" ${equipmentSlot} pool empty.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Object.keys(tierJSON[botType].equipment.Holster).includes(itemDetails._id))
|
|
||||||
{
|
|
||||||
if (Object.keys(tierJSON[botType].equipment.Holster).length > 1)
|
|
||||||
{
|
|
||||||
delete tierJSON[botType].equipment.Holster[itemDetails._id]
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `[Tier${tier}] Removed "${itemDetails._id}" from "${botType}" Holster pool.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.apbsLogger.log(Logging.WARN, `Did not blacklist "${itemDetails._id}" as it would make the Tier${tier} "${botType}" Holster pool empty.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (Object.keys(tierJSON[botType].equipment.Scabbard).includes(itemDetails._id))
|
|
||||||
{
|
|
||||||
if (Object.keys(tierJSON[botType].equipment.Scabbard).length > 1)
|
|
||||||
{
|
|
||||||
delete tierJSON[botType].equipment.Scabbard[itemDetails._id]
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `[Tier${tier}] Removed "${itemDetails._id}" from "${botType}" Scabbard pool.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.apbsLogger.log(Logging.WARN, `Did not blacklist "${itemDetails._id}" as it would make the Tier${tier} "${botType}" Scabbard pool empty.`)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (itemDetails == undefined)
|
|
||||||
{
|
|
||||||
this.apbsLogger.log(Logging.WARN, `"${weaponBlacklist[item]}" in Weapon Blacklist is an invalid item ID.`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private removeBlacklistedAttachments(attachmentBlacklist: string[], tier: number): void
|
|
||||||
{
|
|
||||||
const tierJSON = this.apbsEquipmentGetter.getTierModsJson(tier, true);
|
|
||||||
for (const item in attachmentBlacklist)
|
|
||||||
{
|
|
||||||
const itemDetails = this.getItem(attachmentBlacklist[item])
|
|
||||||
if (itemDetails != undefined)
|
|
||||||
{
|
|
||||||
for (const parentID in tierJSON)
|
|
||||||
{
|
|
||||||
const parentItemName = this.getItem(parentID);
|
|
||||||
const parentItemID = tierJSON[parentID]
|
|
||||||
for (const slotName in parentItemID)
|
|
||||||
{
|
|
||||||
const itemSlotName = tierJSON[parentID][slotName]
|
|
||||||
if (itemSlotName.includes(itemDetails._id))
|
|
||||||
{
|
|
||||||
if (itemSlotName.length == 1)
|
|
||||||
{
|
|
||||||
delete tierJSON[parentID][slotName];
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `[Tier${tier}] Removed slot "${slotName}" from "${parentItemName._name}" because array is now empty.`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const index = itemSlotName.indexOf(itemDetails._id);
|
|
||||||
if (index > -1)
|
|
||||||
{
|
|
||||||
itemSlotName.splice(index, 1)
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `[Tier${tier}] Removed "${itemDetails._id}" from "${parentItemName._name}" slot "${slotName}".`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (itemDetails == undefined)
|
|
||||||
{
|
|
||||||
this.apbsLogger.log(Logging.WARN, `"${attachmentBlacklist[item]}" in Attachment Blacklist is either an invalid attachment or item ID.`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getItem(tpl: string): ITemplateItem
|
|
||||||
{
|
|
||||||
if (tpl in this.database.getItems())
|
|
||||||
{
|
|
||||||
return this.database.getItems()[tpl];
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,328 +0,0 @@
|
||||||
import { injectable, inject } from "tsyringe";
|
|
||||||
import * as path from "path";
|
|
||||||
import * as fs from "fs";
|
|
||||||
|
|
||||||
import { TierInformation } from "../Globals/TierInformation";
|
|
||||||
import { RaidInformation } from "../Globals/RaidInformation";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { Logging } from "../Enums/Logging";
|
|
||||||
|
|
||||||
import Tier0equipment = require("../db/Tier0_equipment.json");
|
|
||||||
import Tier1equipment = require("../db/Tier1_equipment.json");
|
|
||||||
import Tier2equipment = require("../db/Tier2_equipment.json");
|
|
||||||
import Tier3equipment = require("../db/Tier3_equipment.json");
|
|
||||||
import Tier4equipment = require("../db/Tier4_equipment.json");
|
|
||||||
import Tier5equipment = require("../db/Tier5_equipment.json");
|
|
||||||
import Tier6equipment = require("../db/Tier6_equipment.json");
|
|
||||||
import Tier7equipment = require("../db/Tier7_equipment.json");
|
|
||||||
|
|
||||||
import Tier0mods = require("../db/Tier0_mods.json");
|
|
||||||
import Tier1mods = require("../db/Tier1_mods.json");
|
|
||||||
import Tier2mods = require("../db/Tier2_mods.json");
|
|
||||||
import Tier3mods = require("../db/Tier3_mods.json");
|
|
||||||
import Tier4mods = require("../db/Tier4_mods.json");
|
|
||||||
import Tier5mods = require("../db/Tier5_mods.json");
|
|
||||||
import Tier6mods = require("../db/Tier6_mods.json");
|
|
||||||
import Tier7mods = require("../db/Tier7_mods.json");
|
|
||||||
|
|
||||||
import Tier0chances = require("../db/Tier0_chances.json");
|
|
||||||
import Tier1chances = require("../db/Tier1_chances.json");
|
|
||||||
import Tier2chances = require("../db/Tier2_chances.json");
|
|
||||||
import Tier3chances = require("../db/Tier3_chances.json");
|
|
||||||
import Tier4chances = require("../db/Tier4_chances.json");
|
|
||||||
import Tier5chances = require("../db/Tier5_chances.json");
|
|
||||||
import Tier6chances = require("../db/Tier6_chances.json");
|
|
||||||
import Tier7chances = require("../db/Tier7_chances.json");
|
|
||||||
|
|
||||||
import Tier0ammo = require("../db/Tier0_ammo.json");
|
|
||||||
import Tier1ammo = require("../db/Tier1_ammo.json");
|
|
||||||
import Tier2ammo = require("../db/Tier2_ammo.json");
|
|
||||||
import Tier3ammo = require("../db/Tier3_ammo.json");
|
|
||||||
import Tier4ammo = require("../db/Tier4_ammo.json");
|
|
||||||
import Tier5ammo = require("../db/Tier5_ammo.json");
|
|
||||||
import Tier6ammo = require("../db/Tier6_ammo.json");
|
|
||||||
import Tier7ammo = require("../db/Tier7_ammo.json");
|
|
||||||
|
|
||||||
import Tier0appearance = require("../db/Tier0_appearance.json");
|
|
||||||
import Tier1appearance = require("../db/Tier1_appearance.json");
|
|
||||||
import Tier2appearance = require("../db/Tier2_appearance.json");
|
|
||||||
import Tier3appearance = require("../db/Tier3_appearance.json");
|
|
||||||
import Tier4appearance = require("../db/Tier4_appearance.json");
|
|
||||||
import Tier5appearance = require("../db/Tier5_appearance.json");
|
|
||||||
import Tier6appearance = require("../db/Tier6_appearance.json");
|
|
||||||
import Tier7appearance = require("../db/Tier7_appearance.json");
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class JSONHelper
|
|
||||||
{
|
|
||||||
count: number;
|
|
||||||
constructor(
|
|
||||||
@inject("TierInformation") protected tierInformation: TierInformation,
|
|
||||||
@inject("RaidInformation") protected raidInformation: RaidInformation,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this.count = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
public buildTierJson(): void
|
|
||||||
{
|
|
||||||
this.tierInformation.tier0 = Tier0equipment;
|
|
||||||
this.tierInformation.tier1 = Tier1equipment;
|
|
||||||
this.tierInformation.tier2 = Tier2equipment;
|
|
||||||
this.tierInformation.tier3 = Tier3equipment;
|
|
||||||
this.tierInformation.tier4 = Tier4equipment;
|
|
||||||
this.tierInformation.tier5 = Tier5equipment;
|
|
||||||
this.tierInformation.tier6 = Tier6equipment;
|
|
||||||
this.tierInformation.tier7 = Tier7equipment;
|
|
||||||
|
|
||||||
this.tierInformation.tier0mods = Tier0mods;
|
|
||||||
this.tierInformation.tier1mods = Tier1mods;
|
|
||||||
this.tierInformation.tier2mods = Tier2mods;
|
|
||||||
this.tierInformation.tier3mods = Tier3mods;
|
|
||||||
this.tierInformation.tier4mods = Tier4mods;
|
|
||||||
this.tierInformation.tier5mods = Tier5mods;
|
|
||||||
this.tierInformation.tier6mods = Tier6mods;
|
|
||||||
this.tierInformation.tier7mods = Tier7mods;
|
|
||||||
|
|
||||||
this.tierInformation.tier0chances = Tier0chances;
|
|
||||||
this.tierInformation.tier1chances = Tier1chances;
|
|
||||||
this.tierInformation.tier2chances = Tier2chances;
|
|
||||||
this.tierInformation.tier3chances = Tier3chances;
|
|
||||||
this.tierInformation.tier4chances = Tier4chances;
|
|
||||||
this.tierInformation.tier5chances = Tier5chances;
|
|
||||||
this.tierInformation.tier6chances = Tier6chances;
|
|
||||||
this.tierInformation.tier7chances = Tier7chances;
|
|
||||||
|
|
||||||
this.tierInformation.tier0ammo = Tier0ammo;
|
|
||||||
this.tierInformation.tier1ammo = Tier1ammo;
|
|
||||||
this.tierInformation.tier2ammo = Tier2ammo;
|
|
||||||
this.tierInformation.tier3ammo = Tier3ammo;
|
|
||||||
this.tierInformation.tier4ammo = Tier4ammo;
|
|
||||||
this.tierInformation.tier5ammo = Tier5ammo;
|
|
||||||
this.tierInformation.tier6ammo = Tier6ammo;
|
|
||||||
this.tierInformation.tier7ammo = Tier7ammo;
|
|
||||||
|
|
||||||
this.tierInformation.tier0appearance = Tier0appearance;
|
|
||||||
this.tierInformation.tier1appearance = Tier1appearance;
|
|
||||||
this.tierInformation.tier2appearance = Tier2appearance;
|
|
||||||
this.tierInformation.tier3appearance = Tier3appearance;
|
|
||||||
this.tierInformation.tier4appearance = Tier4appearance;
|
|
||||||
this.tierInformation.tier5appearance = Tier5appearance;
|
|
||||||
this.tierInformation.tier6appearance = Tier6appearance;
|
|
||||||
this.tierInformation.tier7appearance = Tier7appearance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public usePreset(presetName: string): void
|
|
||||||
{
|
|
||||||
const folderName = presetName;
|
|
||||||
const presetFolder = path.join(path.dirname(__filename), "..", "..", "presets");
|
|
||||||
const folderPath = path.join(presetFolder, folderName);
|
|
||||||
|
|
||||||
if (!fs.existsSync(folderPath))
|
|
||||||
{
|
|
||||||
this.missingPresetFolder(folderName, presetFolder);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const files = fs.readdirSync(folderPath);
|
|
||||||
if (files.length < 35)
|
|
||||||
{
|
|
||||||
this.missingFileCount(folderName, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (files.length > 35)
|
|
||||||
{
|
|
||||||
this.missingFileCount(folderName, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.raidInformation.usingDefaultDB = false;
|
|
||||||
for (const item of files)
|
|
||||||
{
|
|
||||||
const filePath = path.join(folderPath, item);
|
|
||||||
this.mapFileToTierType(filePath, folderName, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.count == 35) this.apbsLogger.log(Logging.WARN, `"${folderName}" preset loaded...`);
|
|
||||||
}
|
|
||||||
|
|
||||||
private mapFileToTierType(filePath: string, folderName: string, item: string): void
|
|
||||||
{
|
|
||||||
let tier = 0;
|
|
||||||
let type = "none";
|
|
||||||
if (item.includes("1")) tier = 1;
|
|
||||||
if (item.includes("2")) tier = 2;
|
|
||||||
if (item.includes("3")) tier = 3;
|
|
||||||
if (item.includes("4")) tier = 4;
|
|
||||||
if (item.includes("5")) tier = 5;
|
|
||||||
if (item.includes("6")) tier = 6;
|
|
||||||
if (item.includes("7")) tier = 7;
|
|
||||||
|
|
||||||
if (tier == 0)
|
|
||||||
{
|
|
||||||
this.invalidFileName(folderName, item);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.includes("equipment")) type = "equipment";
|
|
||||||
if (item.includes("mods")) type = "mods";
|
|
||||||
if (item.includes("chances")) type = "chances";
|
|
||||||
if (item.includes("ammo")) type = "ammo";
|
|
||||||
if (item.includes("appearance")) type = "appearance";
|
|
||||||
|
|
||||||
if (type == "none")
|
|
||||||
{
|
|
||||||
this.invalidFileName(folderName, item);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.configureTierType(filePath, tier, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
private configureTierType(filePath: string, tier: number, type: string):void
|
|
||||||
{
|
|
||||||
this.count++;
|
|
||||||
this.tierInformation.tier0 = Tier0equipment;
|
|
||||||
this.tierInformation.tier0mods = Tier0mods;
|
|
||||||
this.tierInformation.tier0chances = Tier0chances;
|
|
||||||
this.tierInformation.tier0ammo = Tier0ammo;
|
|
||||||
this.tierInformation.tier0appearance = Tier0appearance;
|
|
||||||
|
|
||||||
switch (true)
|
|
||||||
{
|
|
||||||
case tier == 1 && type == "equipment":
|
|
||||||
this.tierInformation.tier1 = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 2 && type == "equipment":
|
|
||||||
this.tierInformation.tier2 = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 3 && type == "equipment":
|
|
||||||
this.tierInformation.tier3 = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 4 && type == "equipment":
|
|
||||||
this.tierInformation.tier4 = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 5 && type == "equipment":
|
|
||||||
this.tierInformation.tier5 = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 6 && type == "equipment":
|
|
||||||
this.tierInformation.tier6 = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 7 && type == "equipment":
|
|
||||||
this.tierInformation.tier7 = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 1 && type == "mods":
|
|
||||||
this.tierInformation.tier1mods = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 2 && type == "mods":
|
|
||||||
this.tierInformation.tier2mods = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 3 && type == "mods":
|
|
||||||
this.tierInformation.tier3mods = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 4 && type == "mods":
|
|
||||||
this.tierInformation.tier4mods = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 5 && type == "mods":
|
|
||||||
this.tierInformation.tier5mods = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 6 && type == "mods":
|
|
||||||
this.tierInformation.tier6mods = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 7 && type == "mods":
|
|
||||||
this.tierInformation.tier7mods = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 1 && type == "chances":
|
|
||||||
this.tierInformation.tier1chances = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 2 && type == "chances":
|
|
||||||
this.tierInformation.tier2chances = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 3 && type == "chances":
|
|
||||||
this.tierInformation.tier3chances = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 4 && type == "chances":
|
|
||||||
this.tierInformation.tier4chances = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 5 && type == "chances":
|
|
||||||
this.tierInformation.tier5chances = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 6 && type == "chances":
|
|
||||||
this.tierInformation.tier6chances = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 7 && type == "chances":
|
|
||||||
this.tierInformation.tier7chances = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 1 && type == "ammo":
|
|
||||||
this.tierInformation.tier1ammo = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 2 && type == "ammo":
|
|
||||||
this.tierInformation.tier2ammo = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 3 && type == "ammo":
|
|
||||||
this.tierInformation.tier3ammo = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 4 && type == "ammo":
|
|
||||||
this.tierInformation.tier4ammo = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 5 && type == "ammo":
|
|
||||||
this.tierInformation.tier5ammo = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 6 && type == "ammo":
|
|
||||||
this.tierInformation.tier6ammo = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 7 && type == "ammo":
|
|
||||||
this.tierInformation.tier7ammo = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 1 && type == "appearance":
|
|
||||||
this.tierInformation.tier1appearance = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 2 && type == "appearance":
|
|
||||||
this.tierInformation.tier2appearance = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 3 && type == "appearance":
|
|
||||||
this.tierInformation.tier3appearance = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 4 && type == "appearance":
|
|
||||||
this.tierInformation.tier4appearance = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 5 && type == "appearance":
|
|
||||||
this.tierInformation.tier5appearance = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 6 && type == "appearance":
|
|
||||||
this.tierInformation.tier6appearance = require(filePath);
|
|
||||||
return;
|
|
||||||
case tier == 7 && type == "appearance":
|
|
||||||
this.tierInformation.tier7appearance = require(filePath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private missingFileCount(folderName: string, errorType: number): void
|
|
||||||
{
|
|
||||||
const error = errorType == 0 ? "Missing files" : "Extra files found";
|
|
||||||
this.raidInformation.usingDefaultDB = true;
|
|
||||||
this.apbsLogger.log(Logging.ERR, `Preset name "${folderName}" is invalid.`);
|
|
||||||
this.apbsLogger.log(Logging.ERR, `${error}. Report issue to author of preset.`);
|
|
||||||
this.apbsLogger.log(Logging.WARN, "Using APBS database instead of preset...");
|
|
||||||
this.buildTierJson();
|
|
||||||
}
|
|
||||||
|
|
||||||
private invalidFileName(folderName: string, item: string): void
|
|
||||||
{
|
|
||||||
this.raidInformation.usingDefaultDB = true;
|
|
||||||
this.apbsLogger.log(Logging.ERR, `Preset name "${folderName}" is invalid.`);
|
|
||||||
this.apbsLogger.log(Logging.ERR, `"${item}" is incorrectly named. Report issue to author of preset.`);
|
|
||||||
this.apbsLogger.log(Logging.WARN, "Using APBS database instead of preset...");
|
|
||||||
this.buildTierJson();
|
|
||||||
}
|
|
||||||
|
|
||||||
private missingPresetFolder(folderName: string, presetFolder: string): void
|
|
||||||
{
|
|
||||||
this.raidInformation.usingDefaultDB = true;
|
|
||||||
this.apbsLogger.log(Logging.ERR, `Preset name "${folderName}" is invalid.`);
|
|
||||||
this.apbsLogger.log(Logging.ERR, `Verify the preset folder exists in "${presetFolder}" and is named properly.`);
|
|
||||||
this.apbsLogger.log(Logging.WARN, "Using APBS database instead of preset...");
|
|
||||||
this.buildTierJson();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,672 +0,0 @@
|
||||||
/* eslint-disable @typescript-eslint/quotes */
|
|
||||||
import { injectable, inject } from "tsyringe";
|
|
||||||
|
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
||||||
import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
|
||||||
import { IDatabaseTables } from "@spt/models/spt/server/IDatabaseTables";
|
|
||||||
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { ICustomizationItem } from "@spt/models/eft/common/tables/ICustomizationItem";
|
|
||||||
|
|
||||||
import { ModConfig } from "../Globals/ModConfig";
|
|
||||||
import { vanillaItemList, vanillaClothingList } from "../Globals/VanillaItemLists";
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { Logging } from "../Enums/Logging";
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { TierInformation } from "../Globals/TierInformation";
|
|
||||||
import { APBSAttachmentChecker } from "../Utils/APBSAttachmentChecker";
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class ModdedImportHelper
|
|
||||||
{
|
|
||||||
private blacklist: any[];
|
|
||||||
private attachmentBlacklist: any[];
|
|
||||||
private clothingBlacklist: any[];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
@inject("IDatabaseTables") protected tables: IDatabaseTables,
|
|
||||||
@inject("DatabaseService") protected databaseService: DatabaseService,
|
|
||||||
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
|
||||||
@inject("TierInformation") protected tierInformation: TierInformation,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("APBSAttachmentChecker") protected apbsAttachmentChecker: APBSAttachmentChecker,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger
|
|
||||||
)
|
|
||||||
{
|
|
||||||
this.blacklist = [
|
|
||||||
"5ae083b25acfc4001a5fc702", //weapons
|
|
||||||
"5e81ebcd8e146c7080625e15",
|
|
||||||
"6217726288ed9f0845317459",
|
|
||||||
"5d52cc5ba4b9367408500062",
|
|
||||||
"620109578d82e67e7911abf2",
|
|
||||||
"639af924d0446708ee62294e",
|
|
||||||
"657857faeff4c850222dff1b",
|
|
||||||
"639c3fbbd0446708ee622ee9",
|
|
||||||
"62178be9d0050232da3485d9",
|
|
||||||
"62178c4d4ecf221597654e3d",
|
|
||||||
"624c0b3340357b5f566e8766",
|
|
||||||
"5cdeb229d7f00c000e7ce174",
|
|
||||||
"579204f224597773d619e051",
|
|
||||||
"6275303a9f372d6ea97f9ec7",
|
|
||||||
"66015072e9f84d5680039678",
|
|
||||||
"59f9cabd86f7743a10721f46",
|
|
||||||
"5abccb7dd8ce87001773e277",
|
|
||||||
"5b3b713c5acfc4330140bd8d",
|
|
||||||
"66d98233302686954b0c6f81",
|
|
||||||
"66d9f1abb16d9aacf5068468",
|
|
||||||
"56e33634d2720bd8058b456b", //backpacks
|
|
||||||
"5e4abc6786f77406812bd572",
|
|
||||||
"5e997f0b86f7741ac73993e2",
|
|
||||||
"61b9e1aaef9a1b5d6a79899a",
|
|
||||||
"61c18db6dfd64163ea78fbb4", //headwear
|
|
||||||
"66bdc28a0b603c26902b2011",
|
|
||||||
"65749cb8e0423b9ebe0c79c9",
|
|
||||||
"60a7acf20c5cb24b01346648",
|
|
||||||
"636270263f2495c26f00b007",
|
|
||||||
"5a43943586f77416ad2f06e2",
|
|
||||||
"5a43957686f7742a2c2f11b0",
|
|
||||||
"65749ccf33fdc9c0cf06d3ca",
|
|
||||||
"5a16bb52fcdbcb001a3b00dc",
|
|
||||||
"628e4dd1f477aa12234918aa",
|
|
||||||
"5c066ef40db834001966a595",
|
|
||||||
"59ef13ca86f77445fd0e2483",
|
|
||||||
"6531119b9afebff7ff0a1769"
|
|
||||||
]
|
|
||||||
|
|
||||||
this.attachmentBlacklist = [
|
|
||||||
"5c110624d174af029e69734c",
|
|
||||||
"5d1b5e94d7ad1a2b865a96b0",
|
|
||||||
"6478641c19d732620e045e17",
|
|
||||||
"5a1eaa87fcdbcb001865f75e",
|
|
||||||
"609bab8b455afd752b2e6138",
|
|
||||||
"63fc44e2429a8a166c7f61e6",
|
|
||||||
"5a1ead28fcdbcb001912fa9f",
|
|
||||||
"63fc449f5bd61c6cf3784a88",
|
|
||||||
"5b3b6dc75acfc47a8773fb1e",
|
|
||||||
"5c11046cd174af02a012e42b",
|
|
||||||
"544a3f024bdc2d1d388b4568",
|
|
||||||
"544a3d0a4bdc2d1b388b4567",
|
|
||||||
"5648b62b4bdc2d9d488b4585",
|
|
||||||
"5c0e2ff6d174af02a1659d4a",
|
|
||||||
"5c0e2f5cd174af02a012cfc9",
|
|
||||||
"5c6592372e221600133e47d7",
|
|
||||||
"544a378f4bdc2d30388b4567",
|
|
||||||
"5d1340bdd7ad1a0e8d245aab",
|
|
||||||
"671d85439ae8365d69117ba6",
|
|
||||||
"670e8eab8c1bb0e5a7075acf",
|
|
||||||
"671d8617a3e45c1f5908278c",
|
|
||||||
"671d8ac8a3e45c1f59082799",
|
|
||||||
"671d8b38b769f0d88c0950f8",
|
|
||||||
"671d8b8c0959c721a50ca838"
|
|
||||||
]
|
|
||||||
|
|
||||||
this.clothingBlacklist = [
|
|
||||||
"668bc5cd834c88e06b08b645", // All of this is Artem hands, because they are being configured as Body instead...Crackboooonnneee!!
|
|
||||||
"668bc5cd834c88e06b08b64a",
|
|
||||||
"668bc5cd834c88e06b08b64d",
|
|
||||||
"668bc5cd834c88e06b08b650",
|
|
||||||
"668bc5cd834c88e06b08b652",
|
|
||||||
"668bc5cd834c88e06b08b655",
|
|
||||||
"668bc5cd834c88e06b08b658",
|
|
||||||
"668bc5cd834c88e06b08b65b",
|
|
||||||
"668bc5cd834c88e06b08b65e",
|
|
||||||
"668bc5cd834c88e06b08b662",
|
|
||||||
"668bc5cd834c88e06b08b665",
|
|
||||||
"668bc5cd834c88e06b08b668",
|
|
||||||
"668bc5cd834c88e06b08b66b",
|
|
||||||
"668bc5cd834c88e06b08b66e",
|
|
||||||
"668bc5cd834c88e06b08b671",
|
|
||||||
"668bc5cd834c88e06b08b674",
|
|
||||||
"668bc5cd834c88e06b08b677",
|
|
||||||
"668bc5cd834c88e06b08b67a",
|
|
||||||
"668bc5cd834c88e06b08b67d"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
public tiersTable = [];
|
|
||||||
|
|
||||||
public initialize():void
|
|
||||||
{
|
|
||||||
if (ModConfig.config.initalTierAppearance < 1 || ModConfig.config.initalTierAppearance > 7)
|
|
||||||
{
|
|
||||||
this.apbsLogger.log(Logging.WARN, `Config value for "initialTierAppearance" is invalid. Must be 1-7. Currently configured for ${ModConfig.config.initalTierAppearance}`)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (ModConfig.config.enableModdedWeapons) this.buildVanillaWeaponList();
|
|
||||||
if (ModConfig.config.enableModdedEquipment) this.buildVanillaEquipmentList();
|
|
||||||
if (ModConfig.config.enableModdedClothing && !ModConfig.config.seasonalPmcAppearance) this.buildVanillaClothingList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private buildVanillaWeaponList(): void
|
|
||||||
{
|
|
||||||
this.apbsLogger.log(Logging.WARN, "Checking & importing Modded Weapons...Support not granted for this feature...")
|
|
||||||
|
|
||||||
// Build the joined list for every weapon used in APBS
|
|
||||||
const weapons: ITemplateItem = {};
|
|
||||||
vanillaItemList.equipment.LongRange.forEach(element => weapons[element] = this.getItem(element))
|
|
||||||
vanillaItemList.equipment.ShortRange.forEach(element => weapons[element] = this.getItem(element))
|
|
||||||
vanillaItemList.equipment.Holster.forEach(element => weapons[element] = this.getItem(element))
|
|
||||||
vanillaItemList.equipment.Scabbard.forEach(element => weapons[element] = this.getItem(element))
|
|
||||||
|
|
||||||
// Push this list to the function to filter and import
|
|
||||||
this.getModdedItems(weapons, BaseClasses.WEAPON, "Weapons");
|
|
||||||
}
|
|
||||||
|
|
||||||
private buildVanillaEquipmentList(): void
|
|
||||||
{
|
|
||||||
this.apbsLogger.log(Logging.WARN, "Checking & importing Modded Equipment...Support not granted for this feature...")
|
|
||||||
|
|
||||||
// Build the joined list for every armour type used in APBS
|
|
||||||
const armours: ITemplateItem = {};
|
|
||||||
vanillaItemList.equipment.ArmorVest.forEach(element => armours[element] = this.getItem(element))
|
|
||||||
|
|
||||||
const headwear: ITemplateItem = {};
|
|
||||||
vanillaItemList.equipment.Headwear.forEach(element => headwear[element] = this.getItem(element))
|
|
||||||
|
|
||||||
const tacticalVests: ITemplateItem = {};
|
|
||||||
vanillaItemList.equipment.TacticalVest.forEach(element => tacticalVests[element] = this.getItem(element))
|
|
||||||
|
|
||||||
// Push these lists to the function to filter and import
|
|
||||||
this.getModdedItems(armours, BaseClasses.ARMOR, "Armours");
|
|
||||||
this.getModdedItems(headwear, BaseClasses.HEADWEAR, "Helmets");
|
|
||||||
this.getModdedItems(tacticalVests, BaseClasses.VEST, "Vests");
|
|
||||||
}
|
|
||||||
|
|
||||||
private buildVanillaClothingList(): void
|
|
||||||
{
|
|
||||||
this.apbsLogger.log(Logging.WARN, "Checking & importing Modded Clothing...Support not granted for this feature...")
|
|
||||||
|
|
||||||
// Build the joined list for every body & feet type used in APBS
|
|
||||||
const body: ICustomizationItem = {};
|
|
||||||
vanillaClothingList.appearance.body.forEach(element => body[element] = this.getCustomization(element))
|
|
||||||
|
|
||||||
const feet: ICustomizationItem = {};
|
|
||||||
vanillaClothingList.appearance.feet.forEach(element => feet[element] = this.getCustomization(element))
|
|
||||||
|
|
||||||
// Push these lists to the function to filter and import
|
|
||||||
this.getModdedClothing(body, "Body");
|
|
||||||
this.getModdedClothing(feet, "Feet");
|
|
||||||
}
|
|
||||||
|
|
||||||
private getModdedClothing(clothingList: ICustomizationItem, className: string): void
|
|
||||||
{
|
|
||||||
// Compare SPT database values to APBS values, filter down to the difference (assuming they are either modded, or not in the APBS database).
|
|
||||||
const databaseClothing = Object.values(this.databaseService.getTables().templates.customization);
|
|
||||||
const allClothing = databaseClothing.filter(x => this.isCustomization(x._id, className));
|
|
||||||
const moddedClothing = Object.values(clothingList);
|
|
||||||
const allApbsClothing = moddedClothing.filter(x => this.isCustomization(x._id, className));
|
|
||||||
|
|
||||||
let clothingToBeImported = allClothing.filter(x => !allApbsClothing.includes(x));
|
|
||||||
|
|
||||||
// Filter out blacklisted items
|
|
||||||
for (const item of clothingToBeImported)
|
|
||||||
{
|
|
||||||
if (this.clothingBlacklist.includes(item._id)) clothingToBeImported = clothingToBeImported.filter(id => id._id != item._id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push clothing to APBS database
|
|
||||||
if (clothingToBeImported.length > 0)
|
|
||||||
{
|
|
||||||
this.apbsLogger.log(Logging.WARN, `Importing ${clothingToBeImported.length} Modded ${className}...`)
|
|
||||||
this.pushClothing(clothingToBeImported);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private pushClothing(clothingList: ICustomizationItem[]): void
|
|
||||||
{
|
|
||||||
// Loop each tier to add clothing to every tier
|
|
||||||
for (const object in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[object].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getAppearanceJson(tierNumber, true);
|
|
||||||
|
|
||||||
// Skip tiers based on configuration
|
|
||||||
if (tierNumber < ModConfig.config.initalTierAppearance) continue;
|
|
||||||
|
|
||||||
// Add each item from the clothing list to each tier JSON - this completes the import
|
|
||||||
for (const item in clothingList)
|
|
||||||
{
|
|
||||||
if (clothingList[item]._props.Side.includes("Bear"))
|
|
||||||
{
|
|
||||||
if (clothingList[item]._props.BodyPart == "Feet") tierJson.pmcBEAR.appearance.feet[clothingList[item]._id] = 1
|
|
||||||
if (clothingList[item]._props.BodyPart == "Body") tierJson.pmcBEAR.appearance.body[clothingList[item]._id] = 1
|
|
||||||
}
|
|
||||||
if (clothingList[item]._props.Side.includes("Usec"))
|
|
||||||
{
|
|
||||||
if (clothingList[item]._props.BodyPart == "Feet") tierJson.pmcUSEC.appearance.feet[clothingList[item]._id] = 1
|
|
||||||
if (clothingList[item]._props.BodyPart == "Body") tierJson.pmcUSEC.appearance.body[clothingList[item]._id] = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getModdedItems(equipmentList: ITemplateItem, baseClass: BaseClasses, className: string): void
|
|
||||||
{
|
|
||||||
// Compare SPT database values to APBS values, filter down to the difference (assuming they are either modded, or not in the APBS database).
|
|
||||||
const items = Object.values(this.tables.templates.items);
|
|
||||||
const allItems = items.filter(x => this.itemHelper.isOfBaseclass(x._id, baseClass));
|
|
||||||
const tieredItems = Object.values(equipmentList);
|
|
||||||
const allTieredItems = tieredItems.filter(x => this.itemHelper.isOfBaseclass(x._id, baseClass));
|
|
||||||
|
|
||||||
let itemsToBeImported = allItems.filter(x => !allTieredItems.includes(x));
|
|
||||||
|
|
||||||
// Filter out blacklisted items
|
|
||||||
for (const item of itemsToBeImported)
|
|
||||||
{
|
|
||||||
if (this.blacklist.includes(item._id)) itemsToBeImported = itemsToBeImported.filter(id => id._id != item._id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push items to APBS database depending on if they are weapons or equipment
|
|
||||||
if (itemsToBeImported.length > 0)
|
|
||||||
{
|
|
||||||
this.apbsLogger.log(Logging.WARN, `Importing ${itemsToBeImported.length} Modded ${className}...`)
|
|
||||||
if (baseClass == BaseClasses.WEAPON) this.getSetModdedWeaponDetails(itemsToBeImported);
|
|
||||||
if (baseClass != BaseClasses.WEAPON) this.getSetModdedEquipmentDetails(itemsToBeImported);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getSetModdedWeaponDetails(weaponPool: ITemplateItem[]): void
|
|
||||||
{
|
|
||||||
// Loop each weapon in the pool of weapons to be imported - push them individually
|
|
||||||
for (const weapon in weaponPool)
|
|
||||||
{
|
|
||||||
const weaponParent = weaponPool[weapon]._parent;
|
|
||||||
const weaponId = weaponPool[weapon]._id;
|
|
||||||
const weaponSlots = weaponPool[weapon]?._props?.Slots;
|
|
||||||
const weaponType = weaponPool[weapon]?._props?.weapUseType;
|
|
||||||
|
|
||||||
// Push Weapon details to relevant pools
|
|
||||||
this.pushCalibersToAmmoPools(weaponId)
|
|
||||||
this.pushWeaponToTiers(weaponId, weaponType, weaponParent);
|
|
||||||
this.pushItemAndPrimaryMods(weaponId, weaponSlots);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getSetModdedEquipmentDetails(equipmentPool: ITemplateItem[]): void
|
|
||||||
{
|
|
||||||
// Loop each equipment in the pool of equipment to be imported - push them individually
|
|
||||||
for (const equipment in equipmentPool)
|
|
||||||
{
|
|
||||||
const equipmentParent = equipmentPool[equipment]._parent;
|
|
||||||
const equipmentId = equipmentPool[equipment]._id;
|
|
||||||
const equipmentSlots = equipmentPool[equipment]?._props?.Slots;
|
|
||||||
const equipmentSlotsLength = equipmentPool[equipment]?._props?.Slots.length;
|
|
||||||
const gridLength = equipmentPool[equipment]?._props?.Grids.length;
|
|
||||||
let equipmentSlot: string;
|
|
||||||
|
|
||||||
// Set equipmentSlot string to the proper value - this is only done to separate TacticalVests & ArmouredRigs
|
|
||||||
if (equipmentParent == "5448e5284bdc2dcb718b4567" && (equipmentSlots.length == 0 || equipmentSlots == undefined)) equipmentSlot = "TacticalVest"
|
|
||||||
if (equipmentParent == "5448e5284bdc2dcb718b4567" && equipmentSlots.length >= 1) equipmentSlot = "ArmouredRig"
|
|
||||||
if (equipmentParent == "5448e54d4bdc2dcc718b4568") equipmentSlot = "ArmorVest"
|
|
||||||
if (equipmentParent == "5a341c4086f77401f2541505") equipmentSlot = "Headwear"
|
|
||||||
|
|
||||||
// Push Equipment details to relevant pools
|
|
||||||
this.pushEquipmentToTiers(equipmentId, equipmentSlot, gridLength, equipmentSlotsLength);
|
|
||||||
this.pushItemAndPrimaryMods(equipmentId, equipmentSlots);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private pushWeaponToTiers(weaponId: string, weaponType: string, parentClass: string): void
|
|
||||||
{
|
|
||||||
// Define weights to use, and which range they go to (for logging).
|
|
||||||
let range = "";
|
|
||||||
const pmcWeight = ModConfig.config.pmcWeaponWeights <= 0 ? 1 : ModConfig.config.pmcWeaponWeights;
|
|
||||||
const scavWeight = ModConfig.config.scavWeaponWeights <= 0 ? 1 : ModConfig.config.scavWeaponWeights;
|
|
||||||
const defaultWeight = ModConfig.config.followerWeaponWeights <= 0 ? 1 : ModConfig.config.followerWeaponWeights;
|
|
||||||
|
|
||||||
// Loop over each tier to easily use the proper tierJSON
|
|
||||||
for (const object in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[object].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierJson(tierNumber, true);
|
|
||||||
|
|
||||||
// Skip tiers based on configuration
|
|
||||||
if (tierNumber < ModConfig.config.initalTierAppearance) continue;
|
|
||||||
|
|
||||||
// Use multiple variable switch to set specific weapon "types" to the correct pool
|
|
||||||
switch (true)
|
|
||||||
{
|
|
||||||
case parentClass == "5447b5fc4bdc2d87278b4567" && weaponType == "primary":
|
|
||||||
tierJson.pmcUSEC.equipment.FirstPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcUSEC.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcUSEC.equipment.SecondPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcUSEC.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.FirstPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.SecondPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.scav.equipment.FirstPrimaryWeapon.LongRange[weaponId] = scavWeight
|
|
||||||
tierJson.scav.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = scavWeight
|
|
||||||
tierJson.scav.equipment.SecondPrimaryWeapon.LongRange[weaponId] = scavWeight
|
|
||||||
tierJson.scav.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = scavWeight
|
|
||||||
tierJson.default.equipment.FirstPrimaryWeapon.LongRange[weaponId] = defaultWeight
|
|
||||||
tierJson.default.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = defaultWeight
|
|
||||||
tierJson.default.equipment.SecondPrimaryWeapon.LongRange[weaponId] = defaultWeight
|
|
||||||
tierJson.default.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = defaultWeight
|
|
||||||
range = "Long & Short range";
|
|
||||||
continue;
|
|
||||||
case parentClass == "5447b6254bdc2dc3278b4568" && weaponType == "primary":
|
|
||||||
case parentClass == "5447b6194bdc2d67278b4567" && weaponType == "primary":
|
|
||||||
tierJson.pmcUSEC.equipment.FirstPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcUSEC.equipment.SecondPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.FirstPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.SecondPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.scav.equipment.FirstPrimaryWeapon.LongRange[weaponId] = scavWeight
|
|
||||||
tierJson.scav.equipment.SecondPrimaryWeapon.LongRange[weaponId] = scavWeight
|
|
||||||
tierJson.default.equipment.FirstPrimaryWeapon.LongRange[weaponId] = defaultWeight
|
|
||||||
tierJson.default.equipment.SecondPrimaryWeapon.LongRange[weaponId] = defaultWeight
|
|
||||||
range = "Long range"
|
|
||||||
continue;
|
|
||||||
case parentClass == "5447b5f14bdc2d61278b4567" && weaponType == "primary":
|
|
||||||
case parentClass == "5447bed64bdc2d97278b4568" && weaponType == "primary":
|
|
||||||
case parentClass == "5447b5e04bdc2d62278b4567" && weaponType == "primary":
|
|
||||||
case parentClass == "5447b5cf4bdc2d65278b4567" && weaponType == "primary":
|
|
||||||
case parentClass == "617f1ef5e8b54b0998387733" && weaponType == "primary":
|
|
||||||
case parentClass == "5447b6094bdc2dc3278b4567" && weaponType == "primary":
|
|
||||||
tierJson.pmcUSEC.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcUSEC.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.scav.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = scavWeight
|
|
||||||
tierJson.scav.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = scavWeight
|
|
||||||
tierJson.default.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = defaultWeight
|
|
||||||
tierJson.default.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = defaultWeight
|
|
||||||
range = "Short range"
|
|
||||||
continue;
|
|
||||||
case parentClass == "5447b5cf4bdc2d65278b4567" && weaponType == "secondary":
|
|
||||||
case parentClass == "617f1ef5e8b54b0998387733" && weaponType == "secondary":
|
|
||||||
case parentClass == "5447b6094bdc2dc3278b4567" && weaponType == "secondary":
|
|
||||||
tierJson.pmcUSEC.equipment.Holster[weaponId] = 5
|
|
||||||
tierJson.pmcBEAR.equipment.Holster[weaponId] = 5
|
|
||||||
tierJson.scav.equipment.Holster[weaponId] = 1
|
|
||||||
tierJson.default.equipment.Holster[weaponId] = 3
|
|
||||||
range = "Holster"
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
if (weaponType == "primary")
|
|
||||||
{
|
|
||||||
tierJson.pmcUSEC.equipment.FirstPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcUSEC.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcUSEC.equipment.SecondPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcUSEC.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.FirstPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.SecondPrimaryWeapon.LongRange[weaponId] = pmcWeight
|
|
||||||
tierJson.pmcBEAR.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = pmcWeight
|
|
||||||
tierJson.scav.equipment.FirstPrimaryWeapon.LongRange[weaponId] = scavWeight
|
|
||||||
tierJson.scav.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = scavWeight
|
|
||||||
tierJson.scav.equipment.SecondPrimaryWeapon.LongRange[weaponId] = scavWeight
|
|
||||||
tierJson.scav.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = scavWeight
|
|
||||||
tierJson.default.equipment.SecondPrimaryWeapon.LongRange[weaponId] = defaultWeight
|
|
||||||
tierJson.default.equipment.SecondPrimaryWeapon.ShortRange[weaponId] = defaultWeight
|
|
||||||
tierJson.default.equipment.FirstPrimaryWeapon.LongRange[weaponId] = defaultWeight
|
|
||||||
tierJson.default.equipment.FirstPrimaryWeapon.ShortRange[weaponId] = defaultWeight
|
|
||||||
range = "Long & Short range"
|
|
||||||
}
|
|
||||||
if (weaponType == "secondary")
|
|
||||||
{
|
|
||||||
tierJson.pmcUSEC.equipment.Holster[weaponId] = 5
|
|
||||||
tierJson.pmcBEAR.equipment.Holster[weaponId] = 5
|
|
||||||
tierJson.scav.equipment.Holster[weaponId] = 1
|
|
||||||
tierJson.default.equipment.Holster[weaponId] = 3
|
|
||||||
range = "Holster"
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `[Tier${ModConfig.config.initalTierAppearance}+] Added ${weaponId} to ${range} weapons.`)
|
|
||||||
}
|
|
||||||
|
|
||||||
private pushEquipmentToTiers(itemID: string, equipmentSlot: string, gridLength: number, equipmentSlotsLength: number): void
|
|
||||||
{
|
|
||||||
// Loop over each tier to easily use the proper tierJSON
|
|
||||||
for (const object in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[object].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierJson(tierNumber, true);
|
|
||||||
|
|
||||||
// Skip tiers based on configuration
|
|
||||||
if (tierNumber < ModConfig.config.initalTierAppearance) continue;
|
|
||||||
|
|
||||||
// Set weights based on witch slot they are in. Check TacticalVests for belts (low grid count) and check Helmets to see if armoured or decorative
|
|
||||||
let weight;
|
|
||||||
if (equipmentSlot == "TacticalVest" && gridLength > 10) weight = 10;
|
|
||||||
if (equipmentSlot == "TacticalVest" && gridLength <= 10) weight = 1;
|
|
||||||
if (equipmentSlot == "ArmouredRig") weight = 7;
|
|
||||||
if (equipmentSlot == "ArmorVest") weight = 10;
|
|
||||||
if (equipmentSlot == "Headwear" && equipmentSlotsLength > 0) weight = 6;
|
|
||||||
if (equipmentSlot == "Headwear" && equipmentSlotsLength == 0) weight = 1;
|
|
||||||
|
|
||||||
// Add the equipment to the proper slot and correct weight
|
|
||||||
tierJson.pmcUSEC.equipment[equipmentSlot][itemID] = weight
|
|
||||||
tierJson.pmcBEAR.equipment[equipmentSlot][itemID] = weight
|
|
||||||
tierJson.scav.equipment[equipmentSlot][itemID] = 1
|
|
||||||
tierJson.default.equipment[equipmentSlot][itemID] = weight
|
|
||||||
}
|
|
||||||
this.apbsLogger.log(Logging.DEBUG, `[Tier${ModConfig.config.initalTierAppearance}+] Added ${itemID} to ${equipmentSlot}.`)
|
|
||||||
}
|
|
||||||
|
|
||||||
private pushItemAndPrimaryMods(itemID, itemSlots): void
|
|
||||||
{
|
|
||||||
// Loop over all slots of the item
|
|
||||||
for (const slot in itemSlots)
|
|
||||||
{
|
|
||||||
const slotName = itemSlots[slot]?._name;
|
|
||||||
const slotFilter = itemSlots[slot]?._props?.filters[0]?.Filter
|
|
||||||
|
|
||||||
// Loop over all items in the filter for the slot
|
|
||||||
for (const item in slotFilter)
|
|
||||||
{
|
|
||||||
const slotFilterItem = slotFilter[item];
|
|
||||||
|
|
||||||
// Check if the item is actually a valid item, or is on the blacklist
|
|
||||||
// WTT puts itemIDs in their mods that don't exist in the database for some reason (probably unreleased mods)
|
|
||||||
const itemExistsCheck = this.itemHelper.getItem(slotFilterItem)
|
|
||||||
if (this.attachmentBlacklist.includes(slotFilterItem) || !itemExistsCheck[0]) continue;
|
|
||||||
|
|
||||||
// Check if the itemID already exists in the tierJsons, if not - create it in them all.
|
|
||||||
if (this.tierInformation.tier1mods[itemID] == undefined)
|
|
||||||
{
|
|
||||||
this.tierInformation.tier1mods[itemID] = {};
|
|
||||||
this.tierInformation.tier2mods[itemID] = {};
|
|
||||||
this.tierInformation.tier3mods[itemID] = {};
|
|
||||||
this.tierInformation.tier4mods[itemID] = {};
|
|
||||||
this.tierInformation.tier5mods[itemID] = {};
|
|
||||||
this.tierInformation.tier6mods[itemID] = {};
|
|
||||||
this.tierInformation.tier7mods[itemID] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the itemID's slot already exists in the tierJsons, if not - create it in them all.
|
|
||||||
if (this.tierInformation.tier1mods[itemID][slotName] == undefined)
|
|
||||||
{
|
|
||||||
this.tierInformation.tier1mods[itemID][slotName] = [];
|
|
||||||
this.tierInformation.tier2mods[itemID][slotName] = [];
|
|
||||||
this.tierInformation.tier3mods[itemID][slotName] = [];
|
|
||||||
this.tierInformation.tier4mods[itemID][slotName] = [];
|
|
||||||
this.tierInformation.tier5mods[itemID][slotName] = [];
|
|
||||||
this.tierInformation.tier6mods[itemID][slotName] = [];
|
|
||||||
this.tierInformation.tier7mods[itemID][slotName] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the itemID's slot doesn't already contain the item to import, if it doesn't - add it
|
|
||||||
if (!this.tierInformation.tier1mods[itemID][slotName].includes(slotFilterItem))
|
|
||||||
{
|
|
||||||
this.tierInformation.tier1mods[itemID][slotName].push(slotFilterItem);
|
|
||||||
this.tierInformation.tier2mods[itemID][slotName].push(slotFilterItem);
|
|
||||||
this.tierInformation.tier3mods[itemID][slotName].push(slotFilterItem);
|
|
||||||
this.tierInformation.tier4mods[itemID][slotName].push(slotFilterItem);
|
|
||||||
this.tierInformation.tier5mods[itemID][slotName].push(slotFilterItem);
|
|
||||||
this.tierInformation.tier6mods[itemID][slotName].push(slotFilterItem);
|
|
||||||
this.tierInformation.tier7mods[itemID][slotName].push(slotFilterItem);
|
|
||||||
|
|
||||||
// Push any children mods
|
|
||||||
this.recursivePushChildrenMods(slotFilterItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private recursivePushChildrenMods(parentSlotFilterItem)
|
|
||||||
{
|
|
||||||
const parentSlotItemData = this.getItem(parentSlotFilterItem);
|
|
||||||
const parentSlotItemID = parentSlotItemData?._id;
|
|
||||||
const parentSlotSlots = parentSlotItemData?._props?.Slots;
|
|
||||||
|
|
||||||
// Exit if there are no children
|
|
||||||
if (parentSlotSlots == undefined || parentSlotSlots.length == 0) return;
|
|
||||||
|
|
||||||
// Loop over all slots of the parent
|
|
||||||
for (const slot in parentSlotSlots)
|
|
||||||
{
|
|
||||||
const slotName = parentSlotSlots[slot]?._name;
|
|
||||||
let slotFilter = parentSlotSlots[slot]?._props?.filters[0]?.Filter;
|
|
||||||
// If a slot's filters contain the canted sight mount, remove all other items from the filter - this ensures ONLY the canted sight is added
|
|
||||||
if (slotFilter.includes("5649a2464bdc2d91118b45a8"))
|
|
||||||
{
|
|
||||||
slotFilter = [ "5649a2464bdc2d91118b45a8" ];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop over each item in the slot's filters
|
|
||||||
for (const item in slotFilter)
|
|
||||||
{
|
|
||||||
const slotFilterItem = parentSlotSlots[slot]?._props?.filters[0]?.Filter[item];
|
|
||||||
const itemExistsCheck = this.itemHelper.getItem(slotFilterItem)
|
|
||||||
|
|
||||||
// Check if the item is actually a valid item, or is on the blacklist
|
|
||||||
// WTT puts itemIDs in their mods that don't exist in the database for some reason (probably unreleased mods)
|
|
||||||
if (this.attachmentBlacklist.includes(slotFilterItem) || !itemExistsCheck[0]) continue;
|
|
||||||
|
|
||||||
// Check if the parent mod & the child mod are vanilla or modded
|
|
||||||
// This allows preventing mods adding vanilla mods to vanilla weapons
|
|
||||||
const isVanillaParent = this.apbsAttachmentChecker.isVanillaItem(parentSlotItemID);
|
|
||||||
const isVanillaItem = this.apbsAttachmentChecker.isVanillaItem(slotFilterItem);
|
|
||||||
|
|
||||||
// Check if the PARENT itemID already exists in the tierJsons, if not - create it in all tierJSONs.
|
|
||||||
if (this.tierInformation.tier1mods[parentSlotItemID] == undefined)
|
|
||||||
{
|
|
||||||
this.tierInformation.tier1mods[parentSlotItemID] = {};
|
|
||||||
this.tierInformation.tier2mods[parentSlotItemID] = {};
|
|
||||||
this.tierInformation.tier3mods[parentSlotItemID] = {};
|
|
||||||
this.tierInformation.tier4mods[parentSlotItemID] = {};
|
|
||||||
this.tierInformation.tier5mods[parentSlotItemID] = {};
|
|
||||||
this.tierInformation.tier6mods[parentSlotItemID] = {};
|
|
||||||
this.tierInformation.tier7mods[parentSlotItemID] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the PARENT itemID already exists with the slotName, if not - create it in all tierJSONs
|
|
||||||
if (this.tierInformation.tier1mods[parentSlotItemID][slotName] == undefined)
|
|
||||||
{
|
|
||||||
this.tierInformation.tier1mods[parentSlotItemID][slotName] = [];
|
|
||||||
this.tierInformation.tier2mods[parentSlotItemID][slotName] = [];
|
|
||||||
this.tierInformation.tier3mods[parentSlotItemID][slotName] = [];
|
|
||||||
this.tierInformation.tier4mods[parentSlotItemID][slotName] = [];
|
|
||||||
this.tierInformation.tier5mods[parentSlotItemID][slotName] = [];
|
|
||||||
this.tierInformation.tier6mods[parentSlotItemID][slotName] = [];
|
|
||||||
this.tierInformation.tier7mods[parentSlotItemID][slotName] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the PARENT itemID's slot doesn't already contain the item to import
|
|
||||||
if (!this.tierInformation.tier1mods[parentSlotItemID][slotName].includes(slotFilterItem))
|
|
||||||
{
|
|
||||||
// Additionally, check if the parent mod & child mod are vanilla as well as checking the config safeguard
|
|
||||||
if (isVanillaParent && isVanillaItem && ModConfig.config.enableSafeGuard) continue;
|
|
||||||
|
|
||||||
// Finally push the child mod to the proper tierJSONs
|
|
||||||
this.tierInformation.tier1mods[parentSlotItemID][slotName].push(slotFilterItem)
|
|
||||||
this.tierInformation.tier2mods[parentSlotItemID][slotName].push(slotFilterItem)
|
|
||||||
this.tierInformation.tier3mods[parentSlotItemID][slotName].push(slotFilterItem)
|
|
||||||
this.tierInformation.tier4mods[parentSlotItemID][slotName].push(slotFilterItem)
|
|
||||||
this.tierInformation.tier5mods[parentSlotItemID][slotName].push(slotFilterItem)
|
|
||||||
this.tierInformation.tier6mods[parentSlotItemID][slotName].push(slotFilterItem)
|
|
||||||
this.tierInformation.tier7mods[parentSlotItemID][slotName].push(slotFilterItem)
|
|
||||||
|
|
||||||
// Push any children mods
|
|
||||||
this.recursivePushChildrenMods(slotFilterItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private pushCalibersToAmmoPools(itemID: string): void
|
|
||||||
{
|
|
||||||
const itemDetails = this.itemHelper.getItem(itemID)
|
|
||||||
const itemCaliber = itemDetails[1]?._props?.ammoCaliber
|
|
||||||
|
|
||||||
// Check if the Caliber exists on tierJSON or is valid
|
|
||||||
if (!Object.keys(this.tierInformation.tier1ammo.scavAmmo).includes(itemCaliber) && itemCaliber != undefined)
|
|
||||||
{
|
|
||||||
const chamberFilter = itemDetails[1]?._props?.Chambers[0]?._props?.filters[0]?.Filter
|
|
||||||
|
|
||||||
// If the chamber is valid and has items, add them to the tierJSONs
|
|
||||||
if (chamberFilter && chamberFilter.length > 0)
|
|
||||||
{
|
|
||||||
for (const botPool in this.tierInformation.tier1ammo)
|
|
||||||
{
|
|
||||||
// Since the Caliber doesn't exist, create them empty to prevent undefined error below
|
|
||||||
this.tierInformation.tier1ammo[botPool][itemCaliber] = {};
|
|
||||||
this.tierInformation.tier2ammo[botPool][itemCaliber] = {};
|
|
||||||
this.tierInformation.tier3ammo[botPool][itemCaliber] = {};
|
|
||||||
this.tierInformation.tier4ammo[botPool][itemCaliber] = {};
|
|
||||||
this.tierInformation.tier5ammo[botPool][itemCaliber] = {};
|
|
||||||
this.tierInformation.tier6ammo[botPool][itemCaliber] = {};
|
|
||||||
this.tierInformation.tier7ammo[botPool][itemCaliber] = {};
|
|
||||||
|
|
||||||
// Push each item in the filter to the tierJSON
|
|
||||||
for (const item in chamberFilter)
|
|
||||||
{
|
|
||||||
const ammo = chamberFilter[item]
|
|
||||||
this.tierInformation.tier1ammo[botPool][itemCaliber][ammo] = 1;
|
|
||||||
this.tierInformation.tier2ammo[botPool][itemCaliber][ammo] = 1;
|
|
||||||
this.tierInformation.tier3ammo[botPool][itemCaliber][ammo] = 1;
|
|
||||||
this.tierInformation.tier4ammo[botPool][itemCaliber][ammo] = 1;
|
|
||||||
this.tierInformation.tier5ammo[botPool][itemCaliber][ammo] = 1;
|
|
||||||
this.tierInformation.tier6ammo[botPool][itemCaliber][ammo] = 1;
|
|
||||||
this.tierInformation.tier7ammo[botPool][itemCaliber][ammo] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getItem(tpl: string): ITemplateItem
|
|
||||||
{
|
|
||||||
if (tpl in this.databaseService.getItems())
|
|
||||||
{
|
|
||||||
return this.databaseService.getItems()[tpl];
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getCustomization(tpl: string): ICustomizationItem
|
|
||||||
{
|
|
||||||
if (tpl in this.databaseService.getCustomization())
|
|
||||||
{
|
|
||||||
return this.databaseService.getCustomization()[tpl];
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
private isCustomization(tpl: string, type: string): boolean
|
|
||||||
{
|
|
||||||
if (tpl in this.databaseService.getCustomization())
|
|
||||||
{
|
|
||||||
const item = this.databaseService.getCustomization()[tpl];
|
|
||||||
if (item._props.Side == undefined)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (item._props.Side.includes("Bear") || item._props.Side.includes("Usec"))
|
|
||||||
{
|
|
||||||
if (item._props.BodyPart == type)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
/* eslint-disable @typescript-eslint/quotes */
|
|
||||||
import { injectable, inject } from "tsyringe";
|
|
||||||
|
|
||||||
import { APBSLogger } from "../Utils/APBSLogger";
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { TierInformation } from "../Globals/TierInformation";
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class RealismHelper
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
@inject("TierInformation") protected tierInformation: TierInformation,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("APBSLogger") protected apbsLogger: APBSLogger
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public realismDetected: boolean = false;
|
|
||||||
|
|
||||||
public gasMasks = [
|
|
||||||
"5b432c305acfc40019478128",
|
|
||||||
"60363c0c92ec1c31037959f5"
|
|
||||||
];
|
|
||||||
|
|
||||||
public initialize():void
|
|
||||||
{
|
|
||||||
this.realismDetected = true;
|
|
||||||
this.addGasMasksToBots();
|
|
||||||
}
|
|
||||||
|
|
||||||
private addGasMasksToBots()
|
|
||||||
{
|
|
||||||
for (const tierObject in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[tierObject].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierJson(tierNumber, true);
|
|
||||||
for (const botType in tierJson)
|
|
||||||
{
|
|
||||||
let weight = 22;
|
|
||||||
if (botType == "bossTagilla" || botType == "bossKilla") continue;
|
|
||||||
if (botType == "pmcUSEC" || botType == "pmcUSEC" ) weight = 40;
|
|
||||||
if (botType == "scav") weight = 26;
|
|
||||||
tierJson[botType].equipment.FaceCover["5b432c305acfc40019478128"] = weight;
|
|
||||||
tierJson[botType].equipment.FaceCover["60363c0c92ec1c31037959f5"] = weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.addGasMasksFiltersToMasks();
|
|
||||||
}
|
|
||||||
|
|
||||||
private addGasMasksFiltersToMasks()
|
|
||||||
{
|
|
||||||
for (const tierObject in this.tierInformation.tiers)
|
|
||||||
{
|
|
||||||
const tierNumber = this.tierInformation.tiers[tierObject].tier
|
|
||||||
const tierJson = this.apbsEquipmentGetter.getTierModsJson(tierNumber, true);
|
|
||||||
|
|
||||||
tierJson["5b432c305acfc40019478128"] = {
|
|
||||||
"mod_equipment": [
|
|
||||||
"590c595c86f7747884343ad7"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
tierJson["60363c0c92ec1c31037959f5"] = {
|
|
||||||
"mod_equipment": [
|
|
||||||
"590c595c86f7747884343ad7"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,265 +0,0 @@
|
||||||
import * as fs from "fs";
|
|
||||||
import * as path from "path";
|
|
||||||
|
|
||||||
// SPT
|
|
||||||
import { DependencyContainer, Lifecycle } from "tsyringe";
|
|
||||||
import { PreSptModLoader } from "@spt/loaders/PreSptModLoader";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { StaticRouterModService } from "@spt/services/mod/staticRouter/StaticRouterModService";
|
|
||||||
import { DynamicRouterModService } from "@spt/services/mod/dynamicRouter/DynamicRouterModService";
|
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
|
||||||
import { IDatabaseTables } from "@spt/models/spt/server/IDatabaseTables";
|
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
|
||||||
import { WeatherGenerator } from "@spt/generators/WeatherGenerator";
|
|
||||||
import { BotLevelGenerator } from "@spt/generators/BotLevelGenerator";
|
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
|
||||||
import { ProfileHelper } from "@spt/helpers/ProfileHelper";
|
|
||||||
import { BotGenerator } from "@spt/generators/BotGenerator";
|
|
||||||
import { BotWeaponGenerator } from "@spt/generators/BotWeaponGenerator";
|
|
||||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
|
||||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
|
||||||
import { HashUtil } from "@spt/utils/HashUtil";
|
|
||||||
import { InventoryMagGen } from "@spt/generators/weapongen/InventoryMagGen";
|
|
||||||
import { ICloner } from "@spt/utils/cloners/ICloner";
|
|
||||||
import { BotEquipmentModGenerator } from "@spt/generators/BotEquipmentModGenerator";
|
|
||||||
import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper";
|
|
||||||
import { BotWeaponGeneratorHelper } from "@spt/helpers/BotWeaponGeneratorHelper";
|
|
||||||
import { BotWeaponModLimitService } from "@spt/services/BotWeaponModLimitService";
|
|
||||||
import { RepairService } from "@spt/services/RepairService";
|
|
||||||
import { SeasonalEventService } from "@spt/services/SeasonalEventService";
|
|
||||||
import { VFS } from "@spt/utils/VFS";
|
|
||||||
|
|
||||||
// Custom
|
|
||||||
import { APBSLogger } from "./Utils/APBSLogger";
|
|
||||||
import { APBSStaticRouterHooks } from "./RouterHooks/APBSStaticRouterHooks";
|
|
||||||
import { RaidInformation } from "./Globals/RaidInformation";
|
|
||||||
import { ModInformation } from "./Globals/ModInformation";
|
|
||||||
import { TierInformation } from "./Globals/TierInformation";
|
|
||||||
import { APBSBotLevelGenerator } from "./Generators/ABPSBotLevelGenerator";
|
|
||||||
import { BotConfigs } from "./Alterations/BotConfigs";
|
|
||||||
import { APBSBotWeaponGenerator } from "./ClassExtensions/APBSBotWeaponGenerator";
|
|
||||||
import { APBSTierGetter } from "./Utils/APBSTierGetter";
|
|
||||||
import { APBSEquipmentGetter } from "./Utils/APBSEquipmentGetter";
|
|
||||||
import { ModdedImportHelper } from "./Helpers/ModdedImportHelper";
|
|
||||||
import { APBSBotGenerator } from "./ClassExtensions/APBSBotGenerator";
|
|
||||||
import { APBSDynamicRouterHooks } from "./RouterHooks/APBSDynamicRouterHooks";
|
|
||||||
import { APBSBotEquipmentModGenerator } from "./ClassExtensions/APBSBotEquipmentModGenerator";
|
|
||||||
import { APBSBotInventoryGenerator } from "./ClassExtensions/APBSBotInventoryGenerator";
|
|
||||||
import { APBSBotLootGenerator } from "./ClassExtensions/APBSBotLootGenerator";
|
|
||||||
import { ModConfig } from "./Globals/ModConfig";
|
|
||||||
import { JSONHelper } from "./Helpers/JSONHelper";
|
|
||||||
import { BlacklistHelper } from "./Helpers/BlacklistHelper";
|
|
||||||
import { RealismHelper } from "./Helpers/RealismHelper";
|
|
||||||
import { APBSTester } from "./Utils/APBSTester";
|
|
||||||
import { APBSAttachmentChecker } from "./Utils/APBSAttachmentChecker";
|
|
||||||
import { APBSBotLootCacheService } from "./ClassExtensions/APBSBotLootCacheService";
|
|
||||||
import { APBSPlayerScavGenerator } from "./ClassExtensions/APBSPlayerScavGenerator";
|
|
||||||
import { APBSExternalInventoryMagGen } from "./InventoryMagGen/APBSExternalInventoryMagGen";
|
|
||||||
import { APBSMethodHolder } from "./InventoryMagGen/APBSMethodHolder";
|
|
||||||
import { APBSBarrelInventoryMagGen } from "./InventoryMagGen/APBSBarrelInventoryMagGen";
|
|
||||||
import { APBSInternalMagazineInventoryMagGen } from "./InventoryMagGen/APBSInternalMagazineInventoryMagGen";
|
|
||||||
import { APBSUbglExternalMagGen } from "./InventoryMagGen/APBSUbglExternalMagGen";
|
|
||||||
|
|
||||||
export class InstanceManager
|
|
||||||
{
|
|
||||||
//#region accessible in or after preAkiLoad
|
|
||||||
public modName: string;
|
|
||||||
public debug: boolean;
|
|
||||||
public database: DatabaseService;
|
|
||||||
public container: DependencyContainer;
|
|
||||||
public preSptModLoader: PreSptModLoader;
|
|
||||||
public configServer: ConfigServer;
|
|
||||||
public itemHelper: ItemHelper;
|
|
||||||
public logger: ILogger;
|
|
||||||
public staticRouter: StaticRouterModService;
|
|
||||||
public dynamicRouter: DynamicRouterModService;
|
|
||||||
public weatherGenerator: WeatherGenerator;
|
|
||||||
public modInformation: ModInformation;
|
|
||||||
public raidInformation: RaidInformation;
|
|
||||||
public randUtil: RandomUtil;
|
|
||||||
public profileHelper: ProfileHelper;
|
|
||||||
public botLevelGenerator: BotLevelGenerator;
|
|
||||||
public botGenerator: BotGenerator;
|
|
||||||
public tierInformation: TierInformation;
|
|
||||||
public botWeaponGenerator: BotWeaponGenerator;
|
|
||||||
public weightedRandomHelper: WeightedRandomHelper;
|
|
||||||
public localisationService: LocalisationService;
|
|
||||||
public hashUtil: HashUtil;
|
|
||||||
public inventoryMagGen: InventoryMagGen;
|
|
||||||
public cloner: ICloner;
|
|
||||||
public botWeaponGeneratorHelper: BotWeaponGeneratorHelper;
|
|
||||||
public botWeaponModLimitService: BotWeaponModLimitService;
|
|
||||||
public botEquipmentModGenerator: BotEquipmentModGenerator;
|
|
||||||
public botGeneratorHelper: BotGeneratorHelper;
|
|
||||||
public repairService: RepairService;
|
|
||||||
public vfs: VFS;
|
|
||||||
public seasonalEventService: SeasonalEventService;
|
|
||||||
|
|
||||||
public apbsLogger: APBSLogger;
|
|
||||||
public apbsTierGetter: APBSTierGetter;
|
|
||||||
public apbsBotGenerator: APBSBotGenerator;
|
|
||||||
public apbsBotLevelGenerator: APBSBotLevelGenerator;
|
|
||||||
public apbsEquipmentGetter: APBSEquipmentGetter;
|
|
||||||
public apbsStaticRouterHooks: APBSStaticRouterHooks;
|
|
||||||
public apbsDynamicRouterHooks: APBSDynamicRouterHooks;
|
|
||||||
public apbsBotInventoryGenerator: APBSBotInventoryGenerator;
|
|
||||||
public apbsAttachmentChecker: APBSAttachmentChecker;
|
|
||||||
public jsonHelper: JSONHelper;
|
|
||||||
public modConfig: ModConfig;
|
|
||||||
public apbsTester: APBSTester;
|
|
||||||
public apbsExternalInventoryMagGen: APBSExternalInventoryMagGen;
|
|
||||||
public apbsMethodHolder: APBSMethodHolder;
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region accessible in or after postDBLoad
|
|
||||||
public tables: IDatabaseTables;
|
|
||||||
public botConfigs: BotConfigs;
|
|
||||||
public moddedImportHelper: ModdedImportHelper;
|
|
||||||
public realismHelper: RealismHelper;
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region accessible in or after PostSptLoad
|
|
||||||
public blacklistHelper: BlacklistHelper;
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
// Call at the start of the mods postDBLoad method
|
|
||||||
public preSptLoad(container: DependencyContainer, mod: string): void
|
|
||||||
{
|
|
||||||
this.modName = mod;
|
|
||||||
|
|
||||||
// SPT Classes
|
|
||||||
this.container = container;
|
|
||||||
this.preSptModLoader = container.resolve<PreSptModLoader>("PreSptModLoader");
|
|
||||||
this.logger = container.resolve<ILogger>("WinstonLogger");
|
|
||||||
this.staticRouter = container.resolve<StaticRouterModService>("StaticRouterModService");
|
|
||||||
this.dynamicRouter = container.resolve<DynamicRouterModService>("DynamicRouterModService");
|
|
||||||
this.weatherGenerator = container.resolve<WeatherGenerator>("WeatherGenerator");
|
|
||||||
this.configServer = container.resolve<ConfigServer>("ConfigServer");
|
|
||||||
this.itemHelper = container.resolve<ItemHelper>("ItemHelper");
|
|
||||||
this.database = container.resolve<DatabaseService>("DatabaseService");
|
|
||||||
this.randUtil = container.resolve<RandomUtil>("RandomUtil");
|
|
||||||
this.profileHelper = container.resolve<ProfileHelper>("ProfileHelper");
|
|
||||||
this.botLevelGenerator = container.resolve<BotLevelGenerator>("BotLevelGenerator");
|
|
||||||
this.botGenerator = container.resolve<BotGenerator>("BotGenerator");
|
|
||||||
this.botWeaponGenerator = container.resolve<BotWeaponGenerator>("BotWeaponGenerator");
|
|
||||||
this.weightedRandomHelper = container.resolve<WeightedRandomHelper>("WeightedRandomHelper");
|
|
||||||
this.localisationService = container.resolve<LocalisationService>("LocalisationService")
|
|
||||||
this.hashUtil = container.resolve<HashUtil>("HashUtil");
|
|
||||||
this.inventoryMagGen = container.resolve<InventoryMagGen>("InventoryMagGen");
|
|
||||||
this.botWeaponGeneratorHelper = container.resolve<BotWeaponGeneratorHelper>("BotWeaponGeneratorHelper");
|
|
||||||
this.botWeaponModLimitService = container.resolve<BotWeaponModLimitService>("BotWeaponModLimitService");
|
|
||||||
this.botEquipmentModGenerator = container.resolve<BotEquipmentModGenerator>("BotEquipmentModGenerator");
|
|
||||||
this.botGeneratorHelper = container.resolve<BotGeneratorHelper>("BotGeneratorHelper");
|
|
||||||
this.repairService = container.resolve<RepairService>("RepairService");
|
|
||||||
this.cloner = container.resolve<ICloner>("PrimaryCloner");
|
|
||||||
this.vfs = container.resolve<VFS>("VFS");
|
|
||||||
this.seasonalEventService = container.resolve<SeasonalEventService>("SeasonalEventService");
|
|
||||||
|
|
||||||
// Custom Classes
|
|
||||||
this.container.register<ModInformation>("ModInformation", ModInformation, { lifecycle: Lifecycle.Singleton })
|
|
||||||
this.modInformation = container.resolve<ModInformation>("ModInformation");
|
|
||||||
this.container.register<APBSLogger>("APBSLogger", APBSLogger, { lifecycle: Lifecycle.Singleton });
|
|
||||||
this.apbsLogger = container.resolve<APBSLogger>("APBSLogger");
|
|
||||||
this.container.register<APBSTester>("APBSTester", APBSTester, { lifecycle: Lifecycle.Singleton })
|
|
||||||
this.apbsTester = container.resolve<APBSTester>("APBSTester");
|
|
||||||
this.container.register<RaidInformation>("RaidInformation", RaidInformation, { lifecycle: Lifecycle.Singleton });
|
|
||||||
this.raidInformation = container.resolve<RaidInformation>("RaidInformation");
|
|
||||||
this.container.register<TierInformation>("TierInformation", TierInformation, { lifecycle: Lifecycle.Singleton });
|
|
||||||
this.tierInformation = container.resolve<TierInformation>("TierInformation");
|
|
||||||
this.container.register<APBSTierGetter>("APBSTierGetter", APBSTierGetter, { lifecycle: Lifecycle.Singleton })
|
|
||||||
this.apbsTierGetter = container.resolve<APBSTierGetter>("APBSTierGetter");
|
|
||||||
this.container.register<APBSEquipmentGetter>("APBSEquipmentGetter", APBSEquipmentGetter, { lifecycle: Lifecycle.Singleton })
|
|
||||||
this.apbsEquipmentGetter = container.resolve<APBSEquipmentGetter>("APBSEquipmentGetter");
|
|
||||||
|
|
||||||
// Custom Special
|
|
||||||
this.container.register<APBSDynamicRouterHooks>("APBSDynamicRouterHooks", APBSDynamicRouterHooks, { lifecycle: Lifecycle.Singleton });
|
|
||||||
this.apbsDynamicRouterHooks = container.resolve<APBSDynamicRouterHooks>("APBSDynamicRouterHooks");
|
|
||||||
this.container.register<APBSStaticRouterHooks>("APBSStaticRouterHooks", APBSStaticRouterHooks, { lifecycle: Lifecycle.Singleton });
|
|
||||||
this.apbsStaticRouterHooks = container.resolve<APBSStaticRouterHooks>("APBSStaticRouterHooks");
|
|
||||||
this.container.register<APBSBotLevelGenerator>("APBSBotLevelGenerator", APBSBotLevelGenerator, { lifecycle: Lifecycle.Singleton });
|
|
||||||
this.apbsBotLevelGenerator = container.resolve<APBSBotLevelGenerator>("APBSBotLevelGenerator");
|
|
||||||
this.container.register<JSONHelper>("JSONHelper", JSONHelper, { lifecycle: Lifecycle.Singleton });
|
|
||||||
this.jsonHelper = container.resolve<JSONHelper>("JSONHelper");
|
|
||||||
this.container.register<APBSAttachmentChecker>("APBSAttachmentChecker", APBSAttachmentChecker, { lifecycle: Lifecycle.Singleton })
|
|
||||||
this.apbsAttachmentChecker = container.resolve<APBSAttachmentChecker>("APBSAttachmentChecker");
|
|
||||||
this.container.register<APBSMethodHolder>("APBSMethodHolder", APBSMethodHolder, { lifecycle: Lifecycle.Singleton });
|
|
||||||
this.apbsMethodHolder = container.resolve<APBSMethodHolder>("APBSMethodHolder");
|
|
||||||
|
|
||||||
|
|
||||||
this.container.register<RealismHelper>("RealismHelper", { useClass: RealismHelper })
|
|
||||||
|
|
||||||
this.container.register<APBSBotWeaponGenerator>("APBSBotWeaponGenerator", APBSBotWeaponGenerator);
|
|
||||||
this.container.register<APBSBarrelInventoryMagGen>("APBSBarrelInventoryMagGen", { useClass: APBSBarrelInventoryMagGen })
|
|
||||||
this.container.register<APBSExternalInventoryMagGen>("APBSExternalInventoryMagGen", { useClass: APBSExternalInventoryMagGen })
|
|
||||||
this.container.register<APBSInternalMagazineInventoryMagGen>("APBSInternalMagazineInventoryMagGen", { useClass: APBSInternalMagazineInventoryMagGen })
|
|
||||||
this.container.register<APBSUbglExternalMagGen>("APBSUbglExternalMagGen", { useClass: APBSUbglExternalMagGen })
|
|
||||||
this.container.registerType("APBSInventoryMagGen", "APBSBarrelInventoryMagGen");
|
|
||||||
this.container.registerType("APBSInventoryMagGen", "APBSExternalInventoryMagGen");
|
|
||||||
this.container.registerType("APBSInventoryMagGen", "APBSInternalMagazineInventoryMagGen");
|
|
||||||
this.container.registerType("APBSInventoryMagGen", "APBSUbglExternalMagGen");
|
|
||||||
|
|
||||||
|
|
||||||
// Class Extension Override
|
|
||||||
this.container.register<APBSBotGenerator>("APBSBotGenerator", APBSBotGenerator);
|
|
||||||
this.container.register("BotGenerator", { useToken: "APBSBotGenerator" });
|
|
||||||
this.container.register<APBSBotInventoryGenerator>("APBSBotInventoryGenerator", APBSBotInventoryGenerator);
|
|
||||||
this.container.register("BotInventoryGenerator", { useToken: "APBSBotInventoryGenerator" });
|
|
||||||
this.container.register<APBSBotEquipmentModGenerator>("APBSBotEquipmentModGenerator", APBSBotEquipmentModGenerator);
|
|
||||||
this.container.register("BotEquipmentModGenerator", { useToken: "APBSBotEquipmentModGenerator" });
|
|
||||||
this.container.register<APBSPlayerScavGenerator>("APBSPlayerScavGenerator", APBSPlayerScavGenerator);
|
|
||||||
this.container.register("PlayerScavGenerator", { useToken: "APBSPlayerScavGenerator" });
|
|
||||||
this.container.register<APBSBotLootCacheService>("APBSBotLootCacheService", APBSBotLootCacheService);
|
|
||||||
this.container.register("BotLootCacheService", { useToken: "APBSBotLootCacheService" });
|
|
||||||
this.container.register<APBSBotLootGenerator>("APBSBotLootGenerator", APBSBotLootGenerator);
|
|
||||||
this.container.register("BotLootGenerator", { useToken: "APBSBotLootGenerator" });
|
|
||||||
|
|
||||||
this.container.register("BotWeaponGenerator", { useToken: "APBSBotWeaponGenerator" });
|
|
||||||
|
|
||||||
|
|
||||||
// Resolve this last to set mod configs
|
|
||||||
this.container.register<ModConfig>("ModConfig", ModConfig, { lifecycle: Lifecycle.Singleton })
|
|
||||||
this.modConfig = container.resolve<ModConfig>("ModConfig");
|
|
||||||
|
|
||||||
this.getPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
public postDBLoad(container: DependencyContainer): void
|
|
||||||
{
|
|
||||||
// SPT Classes
|
|
||||||
this.tables = container.resolve<DatabaseService>("DatabaseService").getTables();
|
|
||||||
|
|
||||||
// Custom Classes
|
|
||||||
this.botConfigs = new BotConfigs(this.tables, this.database, this.configServer, this.itemHelper, this.apbsEquipmentGetter, this.tierInformation, this.raidInformation, this.apbsLogger);
|
|
||||||
this.moddedImportHelper = new ModdedImportHelper(this.tables, this.database, this.itemHelper, this.tierInformation, this.apbsEquipmentGetter, this.apbsAttachmentChecker, this.apbsLogger);
|
|
||||||
this.realismHelper = new RealismHelper(this.tierInformation, this.apbsEquipmentGetter, this.apbsLogger);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public postSptLoad(container: DependencyContainer): void
|
|
||||||
{
|
|
||||||
// SPT Classes
|
|
||||||
this.tables = container.resolve<DatabaseService>("DatabaseService").getTables();
|
|
||||||
|
|
||||||
// Custom Classes
|
|
||||||
this.blacklistHelper = new BlacklistHelper(this.database, this.apbsEquipmentGetter, this.apbsLogger);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public getPath(): boolean
|
|
||||||
{
|
|
||||||
const dirPath: string = path.dirname(__filename);
|
|
||||||
const modDir: string = path.join(dirPath, "..", "..");
|
|
||||||
|
|
||||||
const key = "V2F5ZmFyZXI=";
|
|
||||||
const keyDE = Buffer.from(key, "base64")
|
|
||||||
|
|
||||||
const contents = fs.readdirSync(modDir).includes(keyDE.toString());
|
|
||||||
|
|
||||||
if (contents)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { IBotBase, IInfo } from "@spt/models/eft/common/tables/IBotBase";
|
|
||||||
|
|
||||||
export interface APBSIBotBase extends IBotBase
|
|
||||||
{
|
|
||||||
Info: APBSIBotBaseInfo;
|
|
||||||
}
|
|
||||||
export interface APBSIBotBaseInfo extends IInfo
|
|
||||||
{
|
|
||||||
Tier: string
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
import { IInventoryMagGen } from "@spt/generators/weapongen/IInventoryMagGen";
|
|
||||||
import { InventoryMagGen } from "@spt/generators/weapongen/InventoryMagGen";
|
|
||||||
import { BotWeaponGeneratorHelper } from "@spt/helpers/BotWeaponGeneratorHelper";
|
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
|
||||||
import { inject, injectable } from "tsyringe";
|
|
||||||
import { APBSIInventoryMagGen } from "./APBSIInventoryMagGen";
|
|
||||||
import { APBSInventoryMagGen } from "./APBSInventoryMagGen";
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class APBSBarrelInventoryMagGen implements APBSIInventoryMagGen
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
||||||
@inject("BotWeaponGeneratorHelper") protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
getPriority(): number
|
|
||||||
{
|
|
||||||
return 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
canHandleInventoryMagGen(inventoryMagGen: APBSInventoryMagGen): boolean
|
|
||||||
{
|
|
||||||
return inventoryMagGen.getWeaponTemplate()._props.ReloadMode === "OnlyBarrel";
|
|
||||||
}
|
|
||||||
|
|
||||||
process(inventoryMagGen: APBSInventoryMagGen): void
|
|
||||||
{
|
|
||||||
// Can't be done by _props.ammoType as grenade launcher shoots grenades with ammoType of "buckshot"
|
|
||||||
let randomisedAmmoStackSize: number;
|
|
||||||
if (inventoryMagGen.getAmmoTemplate()._props.StackMaxRandom === 1)
|
|
||||||
{
|
|
||||||
// doesnt stack
|
|
||||||
randomisedAmmoStackSize = this.randomUtil.getInt(3, 6);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
randomisedAmmoStackSize = this.randomUtil.getInt(
|
|
||||||
inventoryMagGen.getAmmoTemplate()._props.StackMinRandom,
|
|
||||||
inventoryMagGen.getAmmoTemplate()._props.StackMaxRandom
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.botWeaponGeneratorHelper.addAmmoIntoEquipmentSlots(
|
|
||||||
inventoryMagGen.getAmmoTemplate()._id,
|
|
||||||
randomisedAmmoStackSize,
|
|
||||||
inventoryMagGen.getPmcInventory()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,203 +0,0 @@
|
||||||
import { IInventoryMagGen } from "@spt/generators/weapongen/IInventoryMagGen";
|
|
||||||
import { InventoryMagGen } from "@spt/generators/weapongen/InventoryMagGen";
|
|
||||||
import { BotGeneratorHelper } from "@spt/helpers/BotGeneratorHelper";
|
|
||||||
import { BotWeaponGeneratorHelper } from "@spt/helpers/BotWeaponGeneratorHelper";
|
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
||||||
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
|
||||||
import { EquipmentSlots } from "@spt/models/enums/EquipmentSlots";
|
|
||||||
import { ItemAddedResult } from "@spt/models/enums/ItemAddedResult";
|
|
||||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
||||||
import { LocalisationService } from "@spt/services/LocalisationService";
|
|
||||||
import { RandomUtil } from "@spt/utils/RandomUtil";
|
|
||||||
import { inject, injectable } from "tsyringe";
|
|
||||||
import { APBSIInventoryMagGen } from "./APBSIInventoryMagGen";
|
|
||||||
import { APBSInventoryMagGen } from "./APBSInventoryMagGen";
|
|
||||||
import { APBSEquipmentGetter } from "../Utils/APBSEquipmentGetter";
|
|
||||||
import { APBSTierGetter } from "../Utils/APBSTierGetter";
|
|
||||||
import { APBSMethodHolder } from "./APBSMethodHolder";
|
|
||||||
import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
|
||||||
import { ModConfig } from "../Globals/ModConfig";
|
|
||||||
|
|
||||||
@injectable()
|
|
||||||
export class APBSExternalInventoryMagGen implements APBSIInventoryMagGen
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
@inject("PrimaryLogger") protected logger: ILogger,
|
|
||||||
@inject("ItemHelper") protected itemHelper: ItemHelper,
|
|
||||||
@inject("LocalisationService") protected localisationService: LocalisationService,
|
|
||||||
@inject("BotWeaponGeneratorHelper") protected botWeaponGeneratorHelper: BotWeaponGeneratorHelper,
|
|
||||||
@inject("BotGeneratorHelper") protected botGeneratorHelper: BotGeneratorHelper,
|
|
||||||
@inject("RandomUtil") protected randomUtil: RandomUtil,
|
|
||||||
@inject("APBSEquipmentGetter") protected apbsEquipmentGetter: APBSEquipmentGetter,
|
|
||||||
@inject("APBSTierGetter") protected apbsTierGetter: APBSTierGetter,
|
|
||||||
@inject("APBSMethodHolder") protected apbsMethodHolder: APBSMethodHolder
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
getPriority(): number
|
|
||||||
{
|
|
||||||
return 99;
|
|
||||||
}
|
|
||||||
|
|
||||||
canHandleInventoryMagGen(inventoryMagGen: APBSInventoryMagGen): boolean
|
|
||||||
{
|
|
||||||
if (inventoryMagGen.getWeaponTemplate()._props.ReloadMode === "OnlyBarrel") return false;
|
|
||||||
if (inventoryMagGen.getMagazineTemplate()._props.ReloadMagType === "InternalMagazine") return false;
|
|
||||||
if (inventoryMagGen.getWeaponTemplate()._parent === BaseClasses.UBGL) return false;
|
|
||||||
return true; // Fallback, if code reaches here it means no other implementation can handle this type of magazine
|
|
||||||
}
|
|
||||||
|
|
||||||
process(inventoryMagGen: APBSInventoryMagGen): void
|
|
||||||
{
|
|
||||||
// Cout of attempts to fit a magazine into bot inventory
|
|
||||||
let fitAttempts = 0;
|
|
||||||
|
|
||||||
// Magazine Db template
|
|
||||||
let magTemplate = inventoryMagGen.getMagazineTemplate();
|
|
||||||
let magazineTpl = magTemplate._id;
|
|
||||||
const weapon = inventoryMagGen.getWeaponTemplate();
|
|
||||||
const attemptedMagBlacklist: string[] = [];
|
|
||||||
const defaultMagazineTpl = this.botWeaponGeneratorHelper.getWeaponsDefaultMagazineTpl(weapon);
|
|
||||||
const randomizedMagazineCount = Number(
|
|
||||||
this.botWeaponGeneratorHelper.getRandomizedMagazineCount(inventoryMagGen.getMagCount())
|
|
||||||
);
|
|
||||||
|
|
||||||
const tierInfo = this.apbsTierGetter.getTierByLevel(inventoryMagGen.getBotLevel());
|
|
||||||
const ammoTable = this.apbsEquipmentGetter.getAmmoByBotRole(inventoryMagGen.getBotRole(), tierInfo)
|
|
||||||
|
|
||||||
for (let i = 0; i < randomizedMagazineCount; i++)
|
|
||||||
{
|
|
||||||
let selectedAmmoForMag = inventoryMagGen.getAmmoTemplate()._id;
|
|
||||||
if (ModConfig.config.enableBotsToRollAmmoAgain && this.randomUtil.getChance100(ModConfig.config.chanceToRollAmmoAgain))
|
|
||||||
{
|
|
||||||
selectedAmmoForMag = this.apbsMethodHolder.getWeightedCompatibleAmmo(ammoTable, weapon);
|
|
||||||
}
|
|
||||||
|
|
||||||
const magazineWithAmmo = this.botWeaponGeneratorHelper.createMagazineWithAmmo(
|
|
||||||
magazineTpl,
|
|
||||||
selectedAmmoForMag,
|
|
||||||
magTemplate
|
|
||||||
);
|
|
||||||
|
|
||||||
const fitsIntoInventory = this.botGeneratorHelper.addItemWithChildrenToEquipmentSlot(
|
|
||||||
[EquipmentSlots.TACTICAL_VEST, EquipmentSlots.POCKETS],
|
|
||||||
magazineWithAmmo[0]._id,
|
|
||||||
magazineTpl,
|
|
||||||
magazineWithAmmo,
|
|
||||||
inventoryMagGen.getPmcInventory()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (fitsIntoInventory === ItemAddedResult.NO_CONTAINERS)
|
|
||||||
{
|
|
||||||
// No containers to fit magazines, stop trying
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No space for magazine and we haven't reached desired magazine count
|
|
||||||
if (fitsIntoInventory === ItemAddedResult.NO_SPACE && i < randomizedMagazineCount)
|
|
||||||
{
|
|
||||||
// Prevent infinite loop by only allowing 5 attempts at fitting a magazine into inventory
|
|
||||||
if (fitAttempts > 5)
|
|
||||||
{
|
|
||||||
this.logger.debug(
|
|
||||||
`Failed ${fitAttempts} times to add magazine ${magazineTpl} to bot inventory, stopping`
|
|
||||||
);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We were unable to fit at least the minimum amount of magazines,
|
|
||||||
* so we fallback to default magazine and try again.
|
|
||||||
* Temporary workaround to Killa spawning with no extra mags if he spawns with a drum mag */
|
|
||||||
|
|
||||||
if (magazineTpl === defaultMagazineTpl)
|
|
||||||
{
|
|
||||||
// We were already on default - stop here to prevent infinite looping
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add failed magazine tpl to blacklist
|
|
||||||
attemptedMagBlacklist.push(magazineTpl);
|
|
||||||
|
|
||||||
// Set chosen magazine tpl to the weapons default magazine tpl and try to fit into inventory next loop
|
|
||||||
magazineTpl = defaultMagazineTpl;
|
|
||||||
magTemplate = this.itemHelper.getItem(magazineTpl)[1];
|
|
||||||
if (!magTemplate)
|
|
||||||
{
|
|
||||||
this.logger.error(
|
|
||||||
this.localisationService.getText("bot-unable_to_find_default_magazine_item", magazineTpl)
|
|
||||||
);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Edge case - some weapons (SKS) have an internal magazine as default, choose random non-internal magazine to add to bot instead
|
|
||||||
if (magTemplate._props.ReloadMagType === "InternalMagazine")
|
|
||||||
{
|
|
||||||
const result = this.getRandomExternalMagazineForInternalMagazineGun(
|
|
||||||
inventoryMagGen.getWeaponTemplate()._id,
|
|
||||||
attemptedMagBlacklist
|
|
||||||
);
|
|
||||||
if (!result?._id)
|
|
||||||
{
|
|
||||||
this.logger.debug(
|
|
||||||
`Unable to add additional magazine into bot inventory for weapon: ${weapon._name}, attempted: ${fitAttempts} times`
|
|
||||||
);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
magazineTpl = result._id;
|
|
||||||
magTemplate = result;
|
|
||||||
fitAttempts++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reduce loop counter by 1 to ensure we get full cout of desired magazines
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fitsIntoInventory === ItemAddedResult.SUCCESS)
|
|
||||||
{
|
|
||||||
// Reset fit counter now it succeeded
|
|
||||||
fitAttempts = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a random compatible external magazine for a weapon, exclude internal magazines from possible pool
|
|
||||||
* @param weaponTpl Weapon to get mag for
|
|
||||||
* @returns tpl of magazine
|
|
||||||
*/
|
|
||||||
protected getRandomExternalMagazineForInternalMagazineGun(
|
|
||||||
weaponTpl: string,
|
|
||||||
magazineBlacklist: string[]
|
|
||||||
): ITemplateItem | undefined
|
|
||||||
{
|
|
||||||
// The mag Slot data for the weapon
|
|
||||||
const magSlot = this.itemHelper.getItem(weaponTpl)[1]._props.Slots.find((x) => x._name === "mod_magazine");
|
|
||||||
if (!magSlot)
|
|
||||||
{
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// All possible mags that fit into the weapon excluding blacklisted
|
|
||||||
const magazinePool = magSlot._props.filters[0].Filter.filter((x) => !magazineBlacklist.includes(x)).map(
|
|
||||||
(x) => this.itemHelper.getItem(x)[1]
|
|
||||||
);
|
|
||||||
if (!magazinePool)
|
|
||||||
{
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Non-internal magazines that fit into the weapon
|
|
||||||
const externalMagazineOnlyPool = magazinePool.filter((x) => x._props.ReloadMagType !== "InternalMagazine");
|
|
||||||
if (!externalMagazineOnlyPool || externalMagazineOnlyPool?.length === 0)
|
|
||||||
{
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Randomly chosen external magazine
|
|
||||||
return this.randomUtil.getArrayValue(externalMagazineOnlyPool);
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue