ThoraldGM

DCS Quest Script (WIP)

Sep 26th, 2017
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.78 KB | None | 0 0
  1. Scriptname DCS_Quest_Script extends Quest
  2. { It just works. }
  3.  
  4. ; DIAMOND CITY SWAT VERSION 2.0: https://www.nexusmods.com/fallout4/mods/10893/
  5. ; A FALLOUT 4 MOD BY @THORALDGM | THORALDGM.COM | SCRIPT UPDATED 20170919
  6. ;
  7. ; PERMISSIONS:
  8. ;
  9. ; - Do not repost my mod. If you want to tweak minor changes, send me the esp and I will post it in Files.
  10. ; - Language translations are allowed only on same platforms where I posted mod. Please mail link when done.
  11. ; - This mod may not be folded entirely into a larger work without my written permission and collaboration.
  12. ; - Please ask if you want to use parts of my code to improve other mods. Must be unique and credit source.
  13. ;
  14. ; - If you have any questions, or see a better way to do something, please let me know.
  15. ;
  16. ; SCRIPT SECTIONS:
  17. ;
  18. ; LINE 025: PROPERTIES
  19. ; LINE 094: ON INIT
  20. ; LINE 236: ON ITEM ADDED
  21. ; LINE 750: ON ITEM REMOVED
  22. ; LINE 790: GET RANDOM GEAR
  23.  
  24. ; ------------------------------------------------------------------------------------------------------------
  25. ; PROPERTIES
  26. ; ------------------------------------------------------------------------------------------------------------
  27.  
  28. ReferenceAlias Property raGearContainer Auto Mandatory ; Gear container RefAlias
  29. ObjectReference obGearContainer ; Gear container ObjRef
  30.  
  31. Faction Property pPlayerFaction Auto Const Mandatory ; Player faction
  32.  
  33. FormList Property flHeadgearArmo Auto Const Mandatory ; Vanilla headgear armors
  34. FormList Property flHeadgearKywd Auto Const Mandatory ; Vanilla headgear keywords
  35.  
  36. FormList Property flEyewearArmo Auto Const Mandatory ; Vanilla eyewear armors
  37. FormList Property flEyewearKywd Auto Const Mandatory ; Vanilla eyewear keywords
  38.  
  39. FormList Property flNeckwearArmo Auto Const Mandatory ; Vanilla neckwear armors
  40. FormList Property flNeckwearKywd Auto Const Mandatory ; Vanilla neckwear keywords
  41.  
  42. FormList Property flGlovesArmo Auto Const Mandatory ; Vanilla gloves/rings armors
  43. FormList Property flGlovesKywd Auto Const Mandatory ; Vanilla gloves/rings keywords
  44.  
  45. FormList Property flLeftArmArmo Auto Const Mandatory ; Vanilla left arm armors
  46. FormList Property flLeftArmKywd Auto Const Mandatory ; Vanilla left arm keywords
  47.  
  48. FormList Property flRightArmArmo Auto Const Mandatory ; Vanilla right arm armors
  49. FormList Property flRightArmKywd Auto Const Mandatory ; Vanilla right arm keywords
  50.  
  51. FormList Property flLeftLegArmo Auto Const Mandatory ; Vanilla left leg armors
  52. FormList Property flLeftLegKywd Auto Const Mandatory ; Vanilla left leg keywords
  53.  
  54. FormList Property flRightLegArmo Auto Const Mandatory ; Vanilla right leg armors
  55. FormList Property flRightLegKywd Auto Const Mandatory ; Vanilla right leg keywords
  56.  
  57. FormList Property flChestArmo Auto Const Mandatory ; Vanilla chest armors
  58. FormList Property flChestKywd Auto Const Mandatory ; Vanilla chest keywords
  59.  
  60. FormList Property flClothingArmo Auto Const Mandatory ; Vanilla clothing/outfit armors
  61. FormList Property flClothingKywd Auto Const Mandatory ; Vanilla clothing/outfit keywords
  62.  
  63. FormList Property flStorageList Auto ; FormList of FormLists
  64. FormList Property flStorageUnknown Auto ; Catch-all for sorts with no slot kywd
  65.  
  66. GlobalVariable Property gvChanceNoHeadgear Auto Mandatory ; Chance of guard not wearing headgear
  67. GlobalVariable Property gvChanceNoEyewear Auto Mandatory ; Chance of guard not wearing eyewear
  68. GlobalVariable Property gvNumOtherItems Auto Mandatory ; How many other items do guards choose
  69.  
  70. GlobalVariable Property gvDevTracking Auto Mandatory ; Are dev messages turned on
  71.  
  72. String[] strSortedItems ; Array of slot strings for dev messages
  73.  
  74. Bool bModInstalled ; Is AWKCR mod installed
  75.  
  76. Keyword[] ArmorKywds ; Array of AWKCR mod slot keywords
  77.  
  78. Keyword AK_Slot30_Hat ; AWKCR keywords competing for slots
  79. Keyword AK_Slot36_Bracelet
  80. Keyword AK_Slot46_Headband
  81. Keyword AK_Slot46_MaskFull
  82. Keyword AK_Slot49_Mouth
  83. Keyword AK_Slot50_Scarf
  84. Keyword AK_Slot54_Pack
  85. Keyword AK_Slot55_GunOnHip
  86. Keyword AK_Slot55_Satchel
  87. Keyword AK_Slot56_Harness
  88. Keyword AK_Slot58_Piercing
  89.  
  90. ; None of the AWKCR properties were created/linked in Creation Kit because that would create a mod dependency!
  91. ; AWKCR mod recommended, but not required: https://www.nexusmods.com/fallout4/mods/6091/
  92.  
  93. ; ------------------------------------------------------------------------------------------------------------
  94. ; EVENT: ON INIT
  95. ; ------------------------------------------------------------------------------------------------------------
  96.  
  97. Event OnInit()
  98.  
  99. ; ********************************************************************************************************
  100. ; SET OWNERSHIP OF GUARD GEAR CONTAINER SO PLAYER DOESN'T STEAL ITEMS AND GET ATTACKED
  101. ; ********************************************************************************************************
  102.  
  103. obGearContainer = raGearContainer.GetReference() ; Grab ObjRef of the RefAlias
  104. Cell GearContainerCell = obGearContainer.GetParentCell() ; Grab parent cell of the ObjRef
  105. GearContainerCell.SetFactionOwner(pPlayerFaction) ; Remove stolen flag from cell/container
  106.  
  107. ; This method makes everything in Security Office belong to the player, including the jail key.
  108. ; I would rather change flag on the container only, but obGearContainer.SetActorOwner(NONE) didn't work.
  109. ; I may also look into making player ownership of the Security Office a MCM option that can be toggled.
  110.  
  111. ; ********************************************************************************************************
  112. ; WARN PLAYER IF CONTAINER IS STILL DANGEROUS
  113. ; ********************************************************************************************************
  114.  
  115. Bool bPlayerOwns = (GearContainerCell.GetFactionOwner() == pPlayerFaction)
  116.  
  117. If !bPlayerOwns
  118. ; This first notification is a critical warning, so display even if player doesn't want dev messages.
  119. ; Criticals are rare. Dev messages are spammy. Dev messages default to off in final version.
  120.  
  121. Debug.Notification("DCS: SET FACTION FAILED!") ; Show notice on top left screen corner
  122. Debug.Trace("DIAMOND CITY SWAT: SET FACTION FAILED!") ; Write warning in log file
  123. Else
  124. If gvDevTracking.GetValue() == 1 ; If player wants developer messages
  125. Debug.Notification("DCS: Player owns cell.") ; inform player that faction updated
  126. EndIf
  127. EndIf
  128.  
  129. ; ********************************************************************************************************
  130. ; POPULATE LIST OF SLOT NAME STRINGS FOR DEV MESSAGES
  131. ; ********************************************************************************************************
  132.  
  133. strSortedItems = new string[24]
  134. strSortedItems[0] = "headgear"
  135. strSortedItems[1] = "outfit"
  136. strSortedItems[2] = "gloves"
  137. strSortedItems[3] = "bracelet"
  138. strSortedItems[4] = "jacket"
  139. strSortedItems[5] = "top"
  140. strSortedItems[6] = "leg addon"
  141. strSortedItems[7] = "bottom"
  142. strSortedItems[8] = "chestplate"
  143. strSortedItems[9] = "left arm"
  144. strSortedItems[10] = "right arm"
  145. strSortedItems[11] = "left leg"
  146. strSortedItems[12] = "right leg"
  147. strSortedItems[13] = "full mask"
  148. strSortedItems[14] = "eyewear"
  149. strSortedItems[15] = "partial mask"
  150. strSortedItems[16] = "neckwear"
  151. strSortedItems[17] = "ring"
  152. strSortedItems[18] = "cloak or pack"
  153. strSortedItems[19] = "satchel"
  154. strSortedItems[20] = "bandolier"
  155. strSortedItems[21] = "cargo"
  156. strSortedItems[22] = "gun on back"
  157. strSortedItems[23] = "left hand item"
  158.  
  159. If gvDevTracking.GetValue() == 1
  160. Debug.Notification("DCS: Strings filled.")
  161. EndIf
  162.  
  163. ; ********************************************************************************************************
  164. ; IF PLAYER HAS AWKCR MOD INSTALLED, START INTER-MOD COMMUNICATION AND GRAB NECESSARY FORMS
  165. ; ********************************************************************************************************
  166.  
  167. ArmorKywds = new keyword[24] ; There are 24 biped slots that are most relevant to armors.
  168.  
  169. bModInstalled = Game.IsPluginInstalled("ArmorKeywords.esm")
  170. Utility.Wait(0.1) ; Give stack a moment to find mod before I start grabbing forms.
  171.  
  172. If bModInstalled
  173.  
  174. ; AWKCR keyword IDs for biped armor slots are from Gambit77's Armorsmith Extended tutorial:
  175. ; https://forums.nexusmods.com/index.php?showtopic=3687915
  176.  
  177. ; See also:
  178. ; https://www.creationkit.com/fallout4/index.php?title=Biped_Slots
  179. ; https://www.creationkit.com/fallout4/index.php?title=Inter-mod_Communication
  180.  
  181. ArmorKywds[0] = Game.GetFormFromFile(0x01000813, "ArmorKeywords.esm") as Keyword
  182. ArmorKywds[1] = Game.GetFormFromFile(0x0100081E, "ArmorKeywords.esm") as Keyword
  183. ArmorKywds[2] = Game.GetFormFromFile(0x0100081D, "ArmorKeywords.esm") as Keyword
  184. ArmorKywds[3] = Game.GetFormFromFile(0x01000831, "ArmorKeywords.esm") as Keyword
  185. ArmorKywds[4] = Game.GetFormFromFile(0x01000832, "ArmorKeywords.esm") as Keyword
  186. ArmorKywds[5] = Game.GetFormFromFile(0x0100081B, "ArmorKeywords.esm") as Keyword
  187. ArmorKywds[6] = Game.GetFormFromFile(0x01000833, "ArmorKeywords.esm") as Keyword
  188. ArmorKywds[7] = Game.GetFormFromFile(0x0100081C, "ArmorKeywords.esm") as Keyword
  189. ArmorKywds[8] = Game.GetFormFromFile(0x0100080E, "ArmorKeywords.esm") as Keyword
  190. ArmorKywds[9] = Game.GetFormFromFile(0x01000803, "ArmorKeywords.esm") as Keyword
  191. ArmorKywds[10] = Game.GetFormFromFile(0x01000804, "ArmorKeywords.esm") as Keyword
  192. ArmorKywds[11] = Game.GetFormFromFile(0x01000805, "ArmorKeywords.esm") as Keyword
  193. ArmorKywds[12] = Game.GetFormFromFile(0x01000806, "ArmorKeywords.esm") as Keyword
  194. ArmorKywds[13] = Game.GetFormFromFile(0x0100080F, "ArmorKeywords.esm") as Keyword
  195. ArmorKywds[14] = Game.GetFormFromFile(0x0100080C, "ArmorKeywords.esm") as Keyword
  196. ArmorKywds[15] = Game.GetFormFromFile(0x01000801, "ArmorKeywords.esm") as Keyword
  197. ArmorKywds[16] = Game.GetFormFromFile(0x01000810, "ArmorKeywords.esm") as Keyword
  198. ArmorKywds[17] = Game.GetFormFromFile(0x0100081F, "ArmorKeywords.esm") as Keyword
  199. ArmorKywds[18] = Game.GetFormFromFile(0x01000839, "ArmorKeywords.esm") as Keyword
  200. ArmorKywds[19] = Game.GetFormFromFile(0x01000834, "ArmorKeywords.esm") as Keyword
  201. ArmorKywds[20] = Game.GetFormFromFile(0x01000838, "ArmorKeywords.esm") as Keyword
  202. ArmorKywds[21] = Game.GetFormFromFile(0x01000836, "ArmorKeywords.esm") as Keyword
  203. ArmorKywds[22] = Game.GetFormFromFile(0x0100083E, "ArmorKeywords.esm") as Keyword
  204. ArmorKywds[23] = Game.GetFormFromFile(0x01000837, "ArmorKeywords.esm") as Keyword
  205.  
  206. AK_Slot30_Hat = Game.GetFormFromFile(0x0100080D, "ArmorKeywords.esm") as Keyword
  207. AK_Slot36_Bracelet = Game.GetFormFromFile(0x01000811, "ArmorKeywords.esm") as Keyword
  208. AK_Slot46_Headband = Game.GetFormFromFile(0x0100083F, "ArmorKeywords.esm") as Keyword
  209. AK_Slot46_MaskFull = Game.GetFormFromFile(0x0100083A, "ArmorKeywords.esm") as Keyword
  210. AK_Slot49_Mouth = Game.GetFormFromFile(0x0100083B, "ArmorKeywords.esm") as Keyword
  211. AK_Slot50_Scarf = Game.GetFormFromFile(0x0100083D, "ArmorKeywords.esm") as Keyword
  212. AK_Slot54_Pack = Game.GetFormFromFile(0x01000824, "ArmorKeywords.esm") as Keyword
  213. AK_Slot55_GunOnHip = Game.GetFormFromFile(0x0100083C, "ArmorKeywords.esm") as Keyword
  214. AK_Slot55_Satchel = Game.GetFormFromFile(0x01000861, "ArmorKeywords.esm") as Keyword
  215. AK_Slot56_Harness = Game.GetFormFromFile(0x01000835, "ArmorKeywords.esm") as Keyword
  216. AK_Slot58_Piercing = Game.GetFormFromFile(0x01000812, "ArmorKeywords.esm") as Keyword
  217.  
  218. If gvDevTracking.GetValue() == 1
  219. Debug.Notification("DCS: AWKCR handled.")
  220. EndIf
  221.  
  222. EndIf
  223.  
  224. ; ********************************************************************************************************
  225. ; REGISTER (START LISTENING) FOR REMOTE EVENTS, SO SCRIPT CAN REACT WITH BADASSERY
  226. ; ********************************************************************************************************
  227.  
  228. AddInventoryEventFilter(None) ; Required filter for OnItemAdded and OnItemRemoved
  229. Utility.Wait(0.1) ; Give stack a moment to set up required filter before I register events.
  230.  
  231. RegisterForRemoteEvent(raGearContainer, "OnItemAdded") ; Do something when items added to gear container
  232. RegisterForRemoteEvent(raGearContainer, "OnItemRemoved") ; Do something when items removed from gear container
  233. EndEvent
  234.  
  235. ; ------------------------------------------------------------------------------------------------------------
  236. ; EVENT: ON ITEM ADDED
  237. ; ------------------------------------------------------------------------------------------------------------
  238.  
  239. Event ReferenceAlias.OnItemAdded(ReferenceAlias akSender, Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
  240. String WhatIsIt
  241. Bool bSorted = False
  242. bModInstalled = Game.IsPluginInstalled("ArmorKeywords.esm")
  243. int i = 0 ; AWKCR array iteration
  244.  
  245. int arSize = ArmorKywds.Length ; I don't plan on changing array size. Checking length is best practice.
  246. ; Plus assigning length outside of While loop condition is more efficient.
  247.  
  248. ; Since I am using 35 AWKCR keywords to sort into 24 biped armor slots,
  249. ; there are 9 overlaps to condense, which contain 11 records. (35 - 11 = 24)
  250. ; The 9 competing slots are at array indexes: 0, 3, 13, 15, 16, 18, 19, 20, 22.
  251.  
  252. ; ********************************************************************************************************
  253. ; WHILE LOOP STARTS HERE!
  254. ;
  255. ; ARRAY ALGORITHM:
  256. ;
  257. ; 0: IS THE ITEM HEADGEAR?
  258. ; 1: IS THE ITEM AN OUTFIT?
  259. ; 2: IS THE ITEM GLOVES?
  260. ; 3: IS THE ITEM A BRACELET?
  261. ; 4: IS THE ITEM A JACKET?
  262. ; 5: IS THE ITEM A TOP?
  263. ; 6: IS THE ITEM A LEG ADDON?
  264. ; 7: IS THE ITEM A BOTTOM?
  265. ; 8: IS THE ITEM A CHESTPLATE?
  266. ; 9: IS THE ITEM A LEFT ARM?
  267. ; 10: IS THE ITEM A RIGHT ARM?
  268. ; 11: IS THE ITEM A LEFT LEG?
  269. ; 12: IS THE ITEM A RIGHT LEG?
  270. ; 13: IS THE ITEM A FULL MASK?
  271. ; 14: IS THE ITEM EYEWEAR?
  272. ; 15: IS THE ITEM A PARTIAL MASK?
  273. ; 16: IS THE ITEM NECKWEAR?
  274. ; 17: IS THE ITEM A RING?
  275. ; 18: IS THE ITEM A CLOAK OR PACK?
  276. ; 19: IS THE ITEM A SATCHEL?
  277. ; 20: IS THE ITEM A BANDOLIER?
  278. ; 21: IS THE ITEM A CARGO VEST?
  279. ; 22: IS THE ITEM A GUN ON BACK?
  280. ; 23: IS THE ITEM A LEFT HAND DECORATIVE EFFECT?
  281. ; ********************************************************************************************************
  282.  
  283. While (i < arSize) && !bSorted ; While iterating array elements and item unsorted...
  284.  
  285. ; ****************************************************************************************************
  286. ; IS THE ITEM HEADGEAR?
  287. ; ****************************************************************************************************
  288.  
  289. If i == 0 ; IS THE ITEM VANILLA?
  290. If flHeadgearArmo.HasForm(akBaseItem) || akBaseItem.HasKeywordInFormList(flHeadgearKywd)
  291. bSorted = True
  292. EndIf
  293.  
  294. If !bSorted ; IF NOT VANILLA...
  295. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  296. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  297. bSorted = True
  298. EndIf
  299.  
  300. If !bSorted ; IF STILL UNSORTED, CHECK AWKCR COMPETING SLOTS
  301. If AK_Slot30_Hat && akBaseItem.HasKeyword(AK_Slot30_Hat)
  302. bSorted = True
  303. EndIf
  304. EndIf
  305. EndIf
  306. EndIf
  307. EndIf
  308.  
  309. ; ****************************************************************************************************
  310. ; IS THE ITEM AN OUTFIT?
  311. ; ****************************************************************************************************
  312.  
  313. If i == 1 ; IS THE ITEM VANILLA?
  314. If flClothingArmo.HasForm(akBaseItem) || akBaseItem.HasKeywordInFormList(flClothingKywd)
  315. bSorted = True
  316. EndIf
  317.  
  318. If !bSorted ; IF NOT VANILLA...
  319. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  320. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  321. bSorted = True
  322. EndIf
  323.  
  324. ; AWKCR: NO COMPETING SLOTS
  325. EndIf
  326. EndIf
  327. EndIf
  328.  
  329. ; ****************************************************************************************************
  330. ; IS THE ITEM GLOVES?
  331. ; ****************************************************************************************************
  332.  
  333. If i == 2 ; IS THE ITEM VANILLA?
  334. If flGlovesArmo.HasForm(akBaseItem) || akBaseItem.HasKeywordInFormList(flGlovesKywd)
  335. bSorted = True
  336. EndIf
  337.  
  338. If !bSorted ; IF NOT VANILLA...
  339. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  340. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  341. bSorted = True
  342. EndIf
  343.  
  344. ; AWKCR: NO COMPETING SLOTS
  345. EndIf
  346. EndIf
  347.  
  348. ; Disorderly vanilla keyword system in Creation Kit causes left/right arms to sort as gloves.
  349. ; This is unwanted behavior, so check if it just happened and fix it.
  350.  
  351. If flLeftArmArmo.HasForm(akBaseItem) || flRightArmArmo.HasForm(akBaseItem)
  352. bSorted = False ; UNDO SORTED FLAG AND LET LATER ITERATIONS SORT INTO LEFT/RIGHT ARM
  353. EndIf ; Why later? Because i needs to be 9 (left) or 10 (right) when sorted!
  354.  
  355. EndIf
  356.  
  357. ; ****************************************************************************************************
  358. ; IS THE ITEM A BRACELET?
  359. ; ****************************************************************************************************
  360.  
  361. If i == 3 ; IS THE ITEM VANILLA?
  362. ; NO VANILLA LISTS
  363.  
  364. If !bSorted ; IF NOT VANILLA...
  365. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  366. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  367. bSorted = True
  368. EndIf
  369.  
  370. If !bSorted ; IF STILL UNSORTED, CHECK AWKCR COMPETING SLOTS
  371. If AK_Slot36_Bracelet && akBaseItem.HasKeyword(AK_Slot36_Bracelet)
  372. bSorted = True
  373. EndIf
  374. EndIf
  375. EndIf
  376. EndIf
  377. EndIf
  378.  
  379. ; ****************************************************************************************************
  380. ; IS THE ITEM A JACKET? TOP? LEG ADDON? BOTTOM? RING? CARGO VEST? LEFT HAND DECORATIVE EFFECT?
  381. ; ****************************************************************************************************
  382.  
  383. ; All of these items share the same code in my While loop.
  384.  
  385. If ((i > 3) && (i < 8)) || (i == 17) || (i == 21) || (i == 23) ; IS THE ITEM VANILLA?
  386.  
  387. ; NO VANILLA LISTS
  388.  
  389. ; NO RINGS? BUT THERE ARE WEDDING RINGS IN THE GAME...
  390. ; Wedding ring and spouse's ring have vanilla keyword ArmorBodyPartHands, but not ClothingRing.
  391. ; So I currently lump them into my vanilla gloves formlist, and they are the only entries in it.
  392. ; I chose gloves over rings because I have seen more gloves in mods. Will change this if needed.
  393.  
  394. ; AWKCR has keywords for gloves and rings, so I check for them in the array.
  395. ; This is one reason players will get a better experience over vanilla if they use AWKCR mod.
  396.  
  397. If !bSorted ; IF NOT VANILLA...
  398. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  399. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  400. bSorted = True
  401. EndIf
  402.  
  403. ; AWKCR: NO COMPETING SLOTS
  404. EndIf
  405. EndIf
  406. EndIf
  407.  
  408. ; ****************************************************************************************************
  409. ; IS THE ITEM A CHESTPLATE?
  410. ; ****************************************************************************************************
  411.  
  412. If i == 8 ; IS THE ITEM VANILLA?
  413. If flChestArmo.HasForm(akBaseItem) || akBaseItem.HasKeywordInFormList(flChestKywd)
  414. bSorted = True
  415. EndIf
  416.  
  417. If !bSorted ; IF NOT VANILLA...
  418. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  419. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  420. bSorted = True
  421. EndIf
  422.  
  423. ; AWKCR: NO COMPETING SLOTS
  424. EndIf
  425. EndIf
  426. EndIf
  427.  
  428. ; ****************************************************************************************************
  429. ; IS THE ITEM A LEFT ARM?
  430. ; ****************************************************************************************************
  431.  
  432. If i == 9 ; IS THE ITEM VANILLA?
  433. If flLeftArmArmo.HasForm(akBaseItem) || akBaseItem.HasKeywordInFormList(flLeftArmKywd)
  434. bSorted = True
  435. EndIf
  436.  
  437. If !bSorted ; IF NOT VANILLA...
  438. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  439. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  440. bSorted = True
  441. EndIf
  442.  
  443. ; AWKCR: NO COMPETING SLOTS
  444. EndIf
  445. EndIf
  446. EndIf
  447.  
  448. ; ****************************************************************************************************
  449. ; IS THE ITEM A RIGHT ARM?
  450. ; ****************************************************************************************************
  451.  
  452. If i == 10 ; IS THE ITEM VANILLA?
  453. If flRightArmArmo.HasForm(akBaseItem) || akBaseItem.HasKeywordInFormList(flRightArmKywd)
  454. bSorted = True
  455. EndIf
  456.  
  457. If !bSorted ; IF NOT VANILLA...
  458. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  459. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  460. bSorted = True
  461. EndIf
  462.  
  463. ; AWKCR: NO COMPETING SLOTS
  464. EndIf
  465. EndIf
  466. EndIf
  467.  
  468. ; ****************************************************************************************************
  469. ; IS THE ITEM A LEFT LEG?
  470. ; ****************************************************************************************************
  471.  
  472. If i == 11 ; IS THE ITEM VANILLA?
  473. If flLeftLegArmo.HasForm(akBaseItem) || akBaseItem.HasKeywordInFormList(flLeftLegKywd)
  474. bSorted = True
  475. EndIf
  476.  
  477. If !bSorted ; IF NOT VANILLA...
  478. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  479. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  480. bSorted = True
  481. EndIf
  482.  
  483. ; AWKCR: NO COMPETING SLOTS
  484. EndIf
  485. EndIf
  486. EndIf
  487.  
  488. ; ****************************************************************************************************
  489. ; IS THE ITEM A RIGHT LEG?
  490. ; ****************************************************************************************************
  491.  
  492. If i == 12 ; IS THE ITEM VANILLA?
  493. If flRightLegArmo.HasForm(akBaseItem) || akBaseItem.HasKeywordInFormList(flRightLegKywd)
  494. bSorted = True
  495. EndIf
  496.  
  497. If !bSorted ; IF NOT VANILLA...
  498. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  499. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  500. bSorted = True
  501. EndIf
  502.  
  503. ; AWKCR: NO COMPETING SLOTS
  504. EndIf
  505. EndIf
  506. EndIf
  507.  
  508. ; ****************************************************************************************************
  509. ; IS THE ITEM A FULL MASK?
  510. ; ****************************************************************************************************
  511.  
  512. If i == 13 ; IS THE ITEM VANILLA?
  513. ; NO VANILLA LISTS
  514.  
  515. If !bSorted ; IF NOT VANILLA...
  516. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  517. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  518. bSorted = True
  519. EndIf
  520.  
  521. If !bSorted ; IF STILL UNSORTED, CHECK AWKCR COMPETING SLOTS
  522. If (AK_Slot46_Headband && akBaseItem.HasKeyword(AK_Slot46_Headband)) || (AK_Slot46_MaskFull && akBaseItem.HasKeyword(AK_Slot46_MaskFull))
  523. bSorted = True
  524. EndIf
  525. EndIf
  526. EndIf
  527. EndIf
  528. EndIf
  529.  
  530. ; ****************************************************************************************************
  531. ; IS THE ITEM EYEWEAR?
  532. ; ****************************************************************************************************
  533.  
  534. If i == 14 ; IS THE ITEM VANILLA?
  535. If flEyewearArmo.HasForm(akBaseItem) || akBaseItem.HasKeywordInFormList(flEyewearKywd)
  536. bSorted = True
  537. EndIf
  538.  
  539. If !bSorted ; IF NOT VANILLA...
  540. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  541. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  542. bSorted = True
  543. EndIf
  544.  
  545. ; AWKCR: NO COMPETING SLOTS
  546. EndIf
  547. EndIf
  548. EndIf
  549.  
  550. ; ****************************************************************************************************
  551. ; IS THE ITEM A PARTIAL MASK?
  552. ; ****************************************************************************************************
  553.  
  554. If i == 15 ; IS THE ITEM VANILLA?
  555. ; NO VANILLA LISTS
  556.  
  557. If !bSorted ; IF NOT VANILLA...
  558. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  559. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  560. bSorted = True
  561. EndIf
  562.  
  563. If !bSorted ; IF STILL UNSORTED, CHECK AWKCR COMPETING SLOTS
  564. If AK_Slot49_Mouth && akBaseItem.HasKeyword(AK_Slot49_Mouth)
  565. bSorted = True
  566. EndIf
  567. EndIf
  568. EndIf
  569. EndIf
  570. EndIf
  571.  
  572. ; ****************************************************************************************************
  573. ; IS THE ITEM NECKWEAR?
  574. ; ****************************************************************************************************
  575.  
  576. If i == 16 ; IS THE ITEM VANILLA?
  577. If flNeckwearArmo.HasForm(akBaseItem) || akBaseItem.HasKeywordInFormList(flNeckwearKywd)
  578. bSorted = True
  579. EndIf
  580.  
  581. If !bSorted ; IF NOT VANILLA...
  582. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  583. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  584. bSorted = True
  585. EndIf
  586.  
  587. If !bSorted ; IF STILL UNSORTED, CHECK AWKCR COMPETING SLOTS
  588. If AK_Slot50_Scarf && akBaseItem.HasKeyword(AK_Slot50_Scarf)
  589. bSorted = True
  590. EndIf
  591. EndIf
  592. EndIf
  593. EndIf
  594. EndIf
  595.  
  596. ; ****************************************************************************************************
  597. ; IS THE ITEM A CLOAK OR PACK?
  598. ; ****************************************************************************************************
  599.  
  600. If i == 18 ; IS THE ITEM VANILLA?
  601. ; NO VANILLA LISTS
  602.  
  603. If !bSorted ; IF NOT VANILLA...
  604. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  605. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  606. bSorted = True
  607. EndIf
  608.  
  609. If !bSorted ; IF STILL UNSORTED, CHECK AWKCR COMPETING SLOTS
  610. If AK_Slot54_Pack && akBaseItem.HasKeyword(AK_Slot54_Pack)
  611. bSorted = True
  612. EndIf
  613. EndIf
  614. EndIf
  615. EndIf
  616. EndIf
  617.  
  618. ; ****************************************************************************************************
  619. ; IS THE ITEM A SATCHEL?
  620. ; ****************************************************************************************************
  621.  
  622. If i == 19 ; IS THE ITEM VANILLA?
  623. ; NO VANILLA LISTS
  624.  
  625. If !bSorted ; IF NOT VANILLA...
  626. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  627. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  628. bSorted = True
  629. EndIf
  630.  
  631. If !bSorted ; IF STILL UNSORTED, CHECK AWKCR COMPETING SLOTS
  632. If (AK_Slot55_GunOnHip && akBaseItem.HasKeyword(AK_Slot55_GunOnHip)) || (AK_Slot55_Satchel && akBaseItem.HasKeyword(AK_Slot55_Satchel))
  633. bSorted = True
  634. EndIf
  635. EndIf
  636. EndIf
  637. EndIf
  638. EndIf
  639.  
  640. ; ****************************************************************************************************
  641. ; IS THE ITEM A BANDOLIER?
  642. ; ****************************************************************************************************
  643.  
  644. If i == 20 ; IS THE ITEM VANILLA?
  645. ; NO VANILLA LISTS
  646.  
  647. If !bSorted ; IF NOT VANILLA...
  648. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  649. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  650. bSorted = True
  651. EndIf
  652.  
  653. If !bSorted ; IF STILL UNSORTED, CHECK AWKCR COMPETING SLOTS
  654. If AK_Slot56_Harness && akBaseItem.HasKeyword(AK_Slot56_Harness)
  655. bSorted = True
  656. EndIf
  657. EndIf
  658. EndIf
  659. EndIf
  660. EndIf
  661.  
  662. ; ****************************************************************************************************
  663. ; IS THE ITEM A GUN ON BACK?
  664. ; ****************************************************************************************************
  665.  
  666. If i == 22 ; IS THE ITEM VANILLA?
  667. ; NO VANILLA LISTS
  668.  
  669. If !bSorted ; IF NOT VANILLA...
  670. If bModInstalled ; IF AWKCR INSTALLED, IS ITEM AWKCR?
  671. If ArmorKywds[i] && akBaseItem.HasKeyword(ArmorKywds[i]) ; CHECK AWKCR ARRAY ELEMENT
  672. bSorted = True
  673. EndIf
  674.  
  675. If !bSorted ; IF STILL UNSORTED, CHECK AWKCR COMPETING SLOTS
  676. If AK_Slot58_Piercing && akBaseItem.HasKeyword(AK_Slot58_Piercing)
  677. bSorted = True
  678. EndIf
  679. EndIf
  680. EndIf
  681. EndIf
  682. EndIf
  683.  
  684. ; ****************************************************************************************************
  685. ; IF ITEM HAS BEEN SORTED, ADD FORM TO CORRECT LIST SO GUARDS CAN CHOOSE GEAR STOCKED BY PLAYER.
  686. ; ****************************************************************************************************
  687.  
  688. If bSorted
  689. WhatIsIt = strSortedItems[i] as String
  690. FormList NestedList = flStorageList.GetAt(i) as FormList
  691.  
  692. Bool bInListAlready = NestedList.HasForm(akBaseItem)
  693.  
  694. If !bInListAlready
  695. NestedList.AddForm(akBaseItem) ; YO DAWG. Add form to formlist inside formlist array!
  696.  
  697. If gvDevTracking.GetValue() == 1
  698. Debug.Notification("DCS: " + WhatIsIt + " sorted.")
  699. EndIf
  700.  
  701. Else
  702. If gvDevTracking.GetValue() == 1
  703. Debug.Notification("DCS: " + WhatIsIt + " is a duplicate.")
  704. EndIf
  705.  
  706. EndIf
  707. EndIf
  708.  
  709. ; ****************************************************************************************************
  710. ; IF THIS IS THE LAST ITERATION OF THE LOOP AND ITEM STILL HAS NOT BEEN SORTED, SORT INTO CATCH-ALL.
  711. ;
  712. ; This robust script casts a pretty wide net to identify items and sort them.
  713. ;
  714. ; Each slot comparison includes armor formlists and keyword formlists for that slot,
  715. ; to minimize the number of items that make it all the way to the end unidentified.
  716. ;
  717. ; The items that fail to armor sort will be available to guards as other category inventory.
  718. ; (ammo, weapons, aid, mods, misc, junk)
  719. ;
  720. ; Which can be considered a mod feature if you want every guard to have dog tags or a Nuka Cola.
  721. ;
  722. ; Remind me to include a MCM option... Gear container ignores non-armors: YES | NO (default)
  723. ;
  724. ; Because players could mass duplicate items if they want to farm guard spawns for inventory.
  725. ; It's not my job to police the player's play style, so MCM will let player decide if available.
  726. ;
  727. ; ****************************************************************************************************
  728.  
  729. If (i == (arSize - 1)) && !bSorted
  730. flStorageUnknown.AddForm(akBaseItem) ; Put item in catch-all list for extra inventory
  731. bSorted = True
  732.  
  733. If gvDevTracking.GetValue() == 1
  734. Debug.Notification("DCS: other item sorted.")
  735. EndIf
  736.  
  737. EndIf
  738.  
  739. i += 1 ; Increment by one
  740.  
  741. EndWhile
  742.  
  743. ; ********************************************************************************************************
  744. ; WHILE LOOP ENDS HERE!
  745. ; ********************************************************************************************************
  746.  
  747. EndEvent
  748.  
  749. ; ------------------------------------------------------------------------------------------------------------
  750. ; EVENT: ON ITEM REMOVED
  751. ; ------------------------------------------------------------------------------------------------------------
  752.  
  753. Event ReferenceAlias.OnItemRemoved(ReferenceAlias akSender, Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
  754. Int i = 0
  755. Int arSize = flStorageList.GetSize()
  756.  
  757. FormList NestedList
  758. String WhatIsIt
  759.  
  760. ; Removing is much easier than adding because item was previously sorted!
  761.  
  762. While i < arSize
  763. NestedList = flStorageList.GetAt(i) as FormList
  764.  
  765. If NestedList.HasForm(akBaseItem)
  766. NestedList.RemoveAddedForm(akBaseItem)
  767.  
  768. If gvDevTracking.GetValue() == 1
  769. WhatIsIt = strSortedItems[i] as String
  770. Debug.Notification("DCS: " + WhatIsIt + " removed.")
  771. EndIf
  772. EndIf
  773.  
  774. i += 1 ; Increment by one
  775.  
  776. EndWhile
  777.  
  778. If flStorageUnknown.HasForm(akBaseItem)
  779. flStorageUnknown.RemoveAddedForm(akBaseItem)
  780.  
  781. If gvDevTracking.GetValue() == 1
  782. Debug.Notification("DCS: other item removed.")
  783. EndIf
  784.  
  785. EndIf
  786.  
  787. EndEvent
  788.  
  789. ; ------------------------------------------------------------------------------------------------------------
  790. ; CUSTOM FUNCTION: GET RANDOM GEAR
  791. ; ------------------------------------------------------------------------------------------------------------
  792.  
  793. FormList Function GetRandomGear()
  794.  
  795. ; ********************************************************************************************************
  796. ; GUARDS LOADING WILL CALL FUNCTION TO GET A LIST OF ITEMS RANDOMLY CHOSEN FROM PLAYER-STOCKED GEAR LOCKER
  797. ;
  798. ; Players can control the amount of randomness by stocking a variety of wearables, or just a few uniforms.
  799. ; ********************************************************************************************************
  800.  
  801. Form ChosenItem
  802. FormList ChosenGearList
  803. FormList NestedList
  804.  
  805. Int arSize = flStorageList.GetSize()
  806. Int i = 0
  807. Int RandMax
  808. Int RandIndex
  809.  
  810. String WhatIsIt
  811. Bool bSkipSlot
  812.  
  813. ; ********************************************************************************************************
  814. ; WHILE LOOP STARTS HERE! GUARDS CHOOSE ONE RANDOM ITEM TO WEAR FROM EACH OF THE 24 ARMOR SLOT LISTS
  815. ; ********************************************************************************************************
  816.  
  817. While i < arSize ; Start while loop
  818. bSkipSlot = False
  819.  
  820. If i == 0 ; If list is headgear
  821. If Utility.RandomInt(1, 100) <= gvChanceNoHeadgear.GetValue() ; and roll is <= chance none (MCM default: 40%)
  822. bSkipSlot = True ; skip headgear slot
  823.  
  824. If gvDevTracking.GetValue() == 1
  825. Debug.Notification("DCS: Guard refused headgear.") ; notify dev tracker
  826. EndIf
  827. EndIf
  828. EndIf
  829.  
  830. If i == 14 ; If list is eyewear
  831. If Utility.RandomInt(1, 100) <= gvChanceNoEyewear.GetValue() ; and roll is <= chance none (MCM default: 40%)
  832. bSkipSlot = True ; skip eyewear slot
  833.  
  834. If gvDevTracking.GetValue() == 1
  835. Debug.Notification("DCS: Guard refused eyewear.") ; notify dev tracker
  836. EndIf
  837. EndIf
  838. EndIf
  839.  
  840. If !bSkipSlot ; If not skipping slot
  841. NestedList = flStorageList.GetAt(i) as FormList ; grab list for this index
  842.  
  843. If NestedList.GetSize() > 0 ; If list has items
  844. RandMax = NestedList.GetSize() - 1 ; set upper bound
  845. RandIndex = Utility.RandomInt(0, RandMax) ; roll random index
  846.  
  847. ChosenItem = NestedList.GetAt(RandIndex) ; get form from rolled index
  848. ChosenGearList.AddForm(ChosenItem) ; add form to chosen gear list
  849.  
  850. If gvDevTracking.GetValue() == 1
  851. WhatIsIt = strSortedItems[i] as String
  852. Debug.Notification("DCS: Guard chose " + WhatIsIt + ".") ; notify dev tracker
  853. EndIf
  854. EndIf
  855. EndIf
  856.  
  857. i += 1 ; Increment by one
  858.  
  859. EndWhile ; End while loop
  860.  
  861. ; ********************************************************************************************************
  862. ; WHILE LOOP ENDS HERE!
  863. ; ********************************************************************************************************
  864.  
  865. i = 0
  866. arSize = gvNumOtherItems.GetValue() as Int ; MCM default: 5 other items.
  867.  
  868. ; ********************************************************************************************************
  869. ; WHILE LOOP STARTS HERE! GUARDS CHOOSE A NUMBER OF OTHER RANDOM ITEMS TO CARRY. (MCM DEFAULT = 5)
  870. ; ********************************************************************************************************
  871.  
  872. While i < arSize ; Start while loop
  873. If flStorageUnknown.GetSize() > 0 ; If list has items
  874. RandMax = flStorageUnknown.GetSize() - 1 ; set upper bound
  875. RandIndex = Utility.RandomInt(0, RandMax) ; roll random index
  876.  
  877. ChosenItem = flStorageUnknown.GetAt(RandIndex) ; get form from rolled index
  878. ChosenGearList.AddForm(ChosenItem) ; add form to chosen gear list
  879.  
  880. If gvDevTracking.GetValue() == 1
  881. WhatIsIt = strSortedItems[i] as String
  882. Debug.Notification("DCS: Guard chose " + WhatIsIt + ".") ; notify dev tracker
  883. EndIf
  884. EndIf
  885.  
  886. i += 1 ; Increment by one
  887.  
  888. EndWhile ; End while loop
  889.  
  890. ; ********************************************************************************************************
  891. ; WHILE LOOP ENDS HERE!
  892. ; ********************************************************************************************************
  893.  
  894. Return ChosenGearList ; Send gear list to caller!
  895.  
  896. EndFunction
Add Comment
Please, Sign In to add comment