Advertisement
ThoraldGM

Scavver 2016

Oct 28th, 2017
687
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.58 KB | None | 0 0
  1. Scriptname Scavver extends Actor
  2. { It just works. }
  3.  
  4. ; SCAVVER MOD BY @THORALDGM | [email protected] | SCRIPT UPDATED 20160620
  5.  
  6. ; -----------------------------------------------------------------------------
  7. ; PROPERTIES
  8. ; -----------------------------------------------------------------------------
  9.  
  10. ObjectReference Property pScavver Auto Const Mandatory ; Scavver ObjRef
  11. Actor Property pScavverActor Auto Const Mandatory ; Scavver ActorRef
  12.  
  13. GlobalVariable Property pgvScavverStatusSniffer Auto Mandatory ; Toggle tracking on/off
  14.  
  15. GlobalVariable Property pgvScavverWeaponValue Auto Mandatory ; Best weapon found stat
  16. Form Property pScavverPreferredWeapon Auto ; Best weapon found form
  17. Ammo Property pScavverWeaponAmmo Auto ; Ammo for current weapon
  18.  
  19. GlobalVariable Property pgvScavverArmorValue Auto Mandatory ; Best armor found stat
  20. FormList Property pScavverArmorAllowed Auto Const Mandatory ; Outfits Scavver can wear (45)
  21. Armor Property pRoadGoggles Auto Const Mandatory ; Radstorm goggles
  22. Armor Property pSurgicalMask Auto Const Mandatory ; Radstorm mask
  23. Weather Property pRadstorm Auto Const Mandatory ; Radstorm weather
  24.  
  25. Keyword Property pObjectTypeAmmo Auto Const Mandatory ; Is looted item ammo?
  26. Keyword Property pObjectTypeArmor Auto Const Mandatory ; Is looted item armor?
  27. Keyword Property pObjectTypeWeapon Auto Const Mandatory ; Is looted item weapon?
  28.  
  29. GlobalVariable Property pgvScavverStartedRemoveAll Auto Mandatory ; Is RemoveAllItems loop active?
  30. GlobalVariable Property pgvScavverRemoveAllRestartPkg Auto Mandatory
  31.  
  32. GlobalVariable Property pgvScavverScruffStage Auto Mandatory ; Current facial hair
  33. FormList Property pScavverScruffList Auto Const Mandatory ; List of facial hair growth parts
  34.  
  35. ObjectReference Property pScavverVendorContainer Auto Const Mandatory ; Scavver vendor container
  36. ObjectReference Property pScavverMarker Auto Const Mandatory ; Alert system for stuck NPCs
  37. ObjectReference Property pScavverTriggerVolume Auto Const Mandatory ; Trigger volume is stuck path failsafe
  38.  
  39. GlobalVariable Property pgvScavverWasStuck Auto Mandatory ; Is Scavver on a difficult path?
  40. GlobalVariable Property pgvScavverIsIndoors Auto Mandatory ; Is Scavver indoors? (vault, etc)
  41.  
  42. ; ----------------------------------------------------------------------------
  43. ; EVENT: ON INIT
  44. ; -----------------------------------------------------------------------------
  45.  
  46. Event OnInit()
  47. AddInventoryEventFilter(None) ; Required filter for OnItemAdded
  48. RegisterForRadiationDamageEvent(Game.GetPlayer()) ; Enables OnRadiationDamage event
  49. pScavverMarker.MoveTo(pScavver) ; Place marker at Scavver
  50. pScavverTriggerVolume.MoveTo(pScavver) ; Place trigger volume at Scavver
  51. CancelTimer(3) ; This is the 3rd event in my timer
  52. Utility.Wait(1) ; Wait a second
  53. StartTimer(10, 3) ; Fire timer code in 10 seconds
  54. EndEvent
  55.  
  56. ; -----------------------------------------------------------------------------
  57. ; EVENT: ON ITEM ADDED (CHOOSE BEST EQUIPS FOR SELF, LOOT CONTAINER, BROADCAST)
  58. ;
  59. ; SCAVVER HAS SWEEP AI PACKAGE IN CREATION KIT WITH FIND & ACQUIRE PROCEDURES FOR:
  60. ; WEAPONS, AMMO, ARMOR, FOOD, & RADAWAY.
  61. ;
  62. ; IMPORTANT:
  63. ;
  64. ; REMOVEALLITEMS PIGGYBACKS OFF OF THE ACQUIRE PROCEDURE TO LOOT REST OF CONTAINER.
  65. ; THE STATE CHANGE IS THERE TO AVOID OVERLAPPING CALLS TO REMOVEALLITEMS FUNCTION.
  66. ; -----------------------------------------------------------------------------
  67.  
  68. Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
  69. string StuffAndThangs = "stuff and thangs"
  70. string FromWhere = "somewhere"
  71. int NumItemsLeft
  72. float WeaponValue
  73. float WeaponGlobal
  74. float ArmorValue
  75. float ArmorGlobal
  76. bool IsEquipSilent = true
  77.  
  78. ; UNLOCK LOOTED CONTAINER SO IT DOESN'T DISPLAY (UNLOCK - EMPTY) PROMPT
  79. If akSourceContainer
  80. If akSourceContainer.IsLocked()
  81. akSourceContainer.Lock(false)
  82. EndIf
  83. EndIf
  84.  
  85. ; DISPLAY NOTIFICATION IF TRACKING
  86. If pgvScavverStatusSniffer.GetValue() == 1
  87.  
  88. ; Assign item name for notification
  89. If akBaseItem.HasKeyword(pObjectTypeAmmo)
  90. StuffAndThangs = "ammo"
  91. ElseIf akBaseItem.HasKeyword(pObjectTypeArmor)
  92. StuffAndThangs = "armor"
  93. ElseIf pScavverArmorAllowed.HasForm(akBaseItem)
  94. StuffAndThangs = "outfit"
  95. ElseIf akBaseItem.HasKeyword(pObjectTypeWeapon)
  96. StuffAndThangs = "weapon"
  97. Else
  98. StuffAndThangs = "an item"
  99. EndIf
  100.  
  101. ; Assign container name for notification
  102. If !akSourceContainer
  103. FromWhere = "the world"
  104. ElseIf akSourceContainer == Game.GetPlayer()
  105. FromWhere = "the player"
  106. ; ElseIf (akSourceContainer as Actor).IsDead()
  107. ; FromWhere = "a corpse"
  108. Else
  109. FromWhere = "a container"
  110. EndIf
  111.  
  112. Debug.Notification("Scavver took " + StuffAndThangs + " from " + FromWhere + ".")
  113. EndIf
  114.  
  115. ; PROCESS ADDED WEAPON
  116. If akBaseItem.HasKeyword(pObjectTypeWeapon)
  117. WeaponValue = akBaseItem.GetGoldValue() ; Get value of added weapon
  118. WeaponGlobal = pgvScavverWeaponValue.GetValue() ; Get current value of weapon global
  119.  
  120. Utility.Wait(1)
  121. ; Debug.MessageBox("WeaponV: " + WeaponValue + ". WeaponG: " + WeaponGlobal)
  122.  
  123. If pgvScavverStatusSniffer.GetValue() == 1
  124. IsEquipSilent = false
  125. Else
  126. IsEquipSilent = true
  127. EndIf
  128.  
  129. If(WeaponValue >= WeaponGlobal)
  130. ; Debug.MessageBox("WEAPON VALUE >= WEAPON GLOBAL")
  131. pScavverActor.EquipItem(akBaseItem, true, IsEquipSilent) ; Scavver uses best weapon found
  132. pScavverPreferredWeapon = akBaseItem ; Save weapon form so can restore as needed (fix combat AI chaos)
  133. pgvScavverWeaponValue.SetValue(WeaponValue) ; Update global with new higher value!!!
  134. ; Debug.MessageBox("NEW WEAPON GLOBAL IS: " + pgvScavverWeaponValue.GetValue())
  135. Utility.Wait(1)
  136. pScavverActor.DrawWeapon() ; Quick visual confirmation of weapon change
  137. EndIf
  138. EndIf
  139.  
  140. ; PROCESS ADDED ARMOR
  141. If pScavverArmorAllowed.HasForm(akBaseItem) ; If armor is on the list
  142. ArmorValue = akBaseItem.GetGoldValue() ; Get value of added armor
  143. ArmorGlobal = pgvScavverArmorValue.GetValue() ; Get current value of armor global
  144.  
  145. Utility.Wait(1)
  146. ; Debug.MessageBox("ArmorV: " + ArmorValue + ". ArmorG: " + ArmorGlobal)
  147.  
  148. If pgvScavverStatusSniffer.GetValue() == 1
  149. IsEquipSilent = false
  150. Else
  151. IsEquipSilent = true
  152. EndIf
  153.  
  154. If ArmorValue >= ArmorGlobal
  155. ; Debug.MessageBox("ARMOR VALUE >= ARMOR GLOBAL")
  156. pScavverActor.EquipItem(akBaseItem, true, IsEquipSilent) ; Scavver uses best armor found
  157. pgvScavverArmorValue.SetValue(ArmorValue) ; Update global with new higher value!!!
  158. ; Debug.MessageBox("NEW ARMOR GLOBAL IS: " + pgvScavverArmorValue.GetValue())
  159. EndIf
  160. EndIf
  161.  
  162. ; PIGGYBACK CK PROCEDURE TREE TO TAKE REST OF ITEMS IN CONTAINER (INCREASES LOOT AMOUNT & VARIETY)
  163. If akSourceContainer
  164. NumItemsLeft = akSourceContainer.GetItemCount()
  165.  
  166. If (akSourceContainer != Game.GetPlayer()) && (akSourceContainer != pScavverVendorContainer) && (NumItemsLeft > 0)
  167. If pgvScavverStartedRemoveAll.GetValue() == 0 ; If started flag not set
  168. pgvScavverStartedRemoveAll.SetValue(1) ; Set started flag
  169. akSourceContainer.RemoveAllItems(pScavver, false) ; Loot container
  170. CancelTimer(1)
  171. Utility.Wait(1)
  172. StartTimer(5, 1) ; Reset started flag to 0 in 5 seconds
  173. pgvScavverRemoveAllRestartPkg.SetValue(1) ; Inform sweep package that my code is restarting package
  174. pScavverActor.EvaluatePackage() ; Stop Scavver from returning to looted containers
  175. EndIf
  176. EndIf
  177. EndIf
  178. EndEvent
  179.  
  180. ; -----------------------------------------------------------------------------
  181. ; EVENT: ON COMBAT STATE CHANGED
  182. ; -----------------------------------------------------------------------------
  183.  
  184. Event OnCombatStateChanged(Actor akTarget, int aeCombatState)
  185. If pgvScavverStatusSniffer.GetValue() == 1
  186. If aeCombatState == 0
  187. Debug.Notification("Scavver is no longer fighting.")
  188. ElseIf aeCombatState == 1
  189. Debug.Notification("Scavver is fighting.")
  190. ElseIf aeCombatState == 2
  191. Debug.Notification("Scavver is hunting his attacker.")
  192. EndIf
  193. EndIf
  194. EndEvent
  195.  
  196. ; -----------------------------------------------------------------------------
  197. ; EVENT: ON KILL (LOOT CORPSE)
  198. ; -----------------------------------------------------------------------------
  199.  
  200. Event OnKill(Actor akVictim)
  201. If pgvScavverStatusSniffer.GetValue() == 1
  202. Debug.Notification("Scavver killed his attacker.")
  203. EndIf
  204.  
  205. pgvScavverStartedRemoveAll.SetValue(0) ; Reset started flag now just to be sure
  206. akVictim.RemoveAllItems(pScavver, false) ; Loot corpse
  207. EndEvent
  208.  
  209. ; -----------------------------------------------------------------------------
  210. ; EVENT: ON LOCATION CHANGE
  211. ; -----------------------------------------------------------------------------
  212.  
  213. Event OnLocationChange(Location akOldLoc, Location akNewLoc)
  214. int MaxAmmo = 50
  215. int AmmoCount
  216. float NowIndex = pgvScavverScruffStage.GetValue()
  217. float NextIndex = NowIndex + 1
  218.  
  219. If pgvScavverStatusSniffer.GetValue() == 1
  220. Debug.Notification("Scavver changed location.")
  221. Utility.Wait(1)
  222. EndIf
  223.  
  224. If pScavver.IsInInterior()
  225. pgvScavverIsIndoors.SetValue(1)
  226. pgvScavverWasStuck.SetValue(1)
  227. GetScavverUnstuck()
  228. EndIf
  229.  
  230. If NowIndex == 6 ; If current facial hair is last in the list (of 7 entries) ...
  231. NextIndex = 0 ; Set next facial hair to the first entry
  232. EndIf
  233.  
  234. pScavverActor.ChangeHeadPart((pScavverScruffList.GetAt((NowIndex as Int)) as HeadPart), true, true) ; Remove current facial hair
  235. pScavverActor.ChangeHeadPart((pScavverScruffList.GetAt((NextIndex as Int))) as HeadPart) ; Add the next facial hair
  236. pgvScavverScruffStage.SetValue(NextIndex) ; Update global to new facial hair
  237. ; Debug.MessageBox("BEARD IS NOW: " + NextIndex)
  238.  
  239. If !(pScavverActor.IsEquipped(pScavverPreferredWeapon))
  240. pScavverActor.EquipItem(pScavverPreferredWeapon, true, true) ; Fix for combat AI chaos
  241. EndIf
  242.  
  243. If (pScavverPreferredWeapon as Weapon).GetAmmo()
  244. pScavverWeaponAmmo = (pScavverPreferredWeapon as Weapon).GetAmmo()
  245. AmmoCount = pScavver.GetItemCount(pScavverWeaponAmmo)
  246.  
  247. ; Debug.Notification("Scavver ammo count start: " + AmmoCount)
  248.  
  249. While AmmoCount < MaxAmmo
  250. pScavver.AddItem(pScavverWeaponAmmo) ; Give Scavver ammo for wielded weapon
  251. AmmoCount += 1
  252. EndWhile
  253.  
  254. ; Utility.Wait(1)
  255. ; Debug.Notification("Scavver ammo count end: " + AmmoCount)
  256. ; Utility.Wait(1)
  257. EndIf
  258.  
  259. EndEvent
  260.  
  261. ; -----------------------------------------------------------------------------
  262. ; EVENT: ON RADIATION DAMAGE (EQUIP GOGGLES & MASK)
  263. ; -----------------------------------------------------------------------------
  264.  
  265. Event OnRadiationDamage(ObjectReference akTarget, bool abIngested)
  266. If (!abIngested && !(pScavverActor.IsEquipped(pSurgicalMask)))
  267. String RadSource = "radiation"
  268. pScavverActor.EquipItem(pRoadGoggles, true, true)
  269. pScavverActor.EquipItem(pSurgicalMask, true, true)
  270. CancelTimer(2)
  271. Utility.Wait(1)
  272.  
  273. If Weather.GetCurrentWeather() == pRadstorm
  274. StartTimer(240, 2) ; Rad storm is ~4 real minutes
  275. RadSource = "radstorm"
  276. ; Debug.MessageBox("RAD STORM TIMER STARTED")
  277. Else
  278. StartTimer(30, 2) ; Check if roaches/barrels gone in 30 seconds
  279. RadSource = "rad objects"
  280. ; Debug.MessageBox("RAD EXPOSURE TIMER STARTED")
  281. EndIf
  282.  
  283. If pgvScavverStatusSniffer.GetValue() == 1
  284. Debug.Notification("Scavver put on " + RadSource + " gear.")
  285. EndIf
  286. Else
  287. RegisterForRadiationDamageEvent(Game.GetPlayer()) ; Catch the next radiation event
  288. EndIf
  289. EndEvent
  290.  
  291. ; ------------------------------------------------------------------------------------------
  292. ; EVENT: ON TIMER (1 = RESET STARTED FLAG, 2 = REMOVE GOGGLES & MASK, 3 = MOVE NPC IF STUCK)
  293. ; ------------------------------------------------------------------------------------------
  294.  
  295. Event OnTimer(int aiTimerID) ; Cancel timer
  296. If aiTimerID == 1
  297. pgvScavverStartedRemoveAll.SetValue(0)
  298. ElseIf aiTimerID == 2
  299. ; Debug.MessageBox("RAD TIMER CLEANUP")
  300. pScavverActor.UnequipItem(pRoadGoggles, true, true)
  301. pScavverActor.UnequipItem(pSurgicalMask, true, true)
  302.  
  303. If pScavver.GetItemCount(pRoadGoggles) > 1 ; Limit Scavver to having one extra to sell
  304. pScavver.RemoveItem(pRoadGoggles, 1, true)
  305. EndIf
  306.  
  307. If pScavver.GetItemCount(pSurgicalMask) > 1 ; Limit Scavver to having one extra to sell
  308. pScavver.RemoveItem(pSurgicalMask, 1, true)
  309. EndIf
  310.  
  311. If pgvScavverStatusSniffer.GetValue() == 1
  312. Debug.Notification("Scavver removed radiation gear.")
  313. EndIf
  314.  
  315. RegisterForRadiationDamageEvent(Game.GetPlayer()) ; Catch the next radiation event
  316. ElseIf aiTimerID == 3
  317. float MovedDistance = pScavver.GetDistance(pScavverMarker)
  318.  
  319. If pScavver.IsInInterior()
  320. pgvScavverIsIndoors.SetValue(1)
  321. pgvScavverWasStuck.SetValue(1)
  322. GetScavverUnstuck()
  323. EndIf
  324.  
  325. If pgvScavverStatusSniffer.GetValue() == 1
  326. Debug.Notification("Scavver 10-second distance: " + MovedDistance)
  327. EndIf
  328.  
  329. Utility.Wait(1)
  330. pgvScavverWasStuck.SetValue(0)
  331.  
  332. If MovedDistance <= 100
  333. If !Utility.IsInMenuMode()
  334. If !pScavver.IsInDialogueWithPlayer()
  335. If pgvScavverStatusSniffer.GetValue() == 1
  336. Debug.Notification("SCAVVER IS STUCK... FIXING")
  337. pgvScavverWasStuck.SetValue(1)
  338. EndIf
  339.  
  340. GetScavverUnstuck()
  341. EndIf
  342. EndIf
  343. EndIf
  344.  
  345. If (pgvScavverWasStuck.GetValue() == 0) && (pgvScavverIsIndoors.GetValue() == 0)
  346. pScavverMarker.MoveTo(pScavver)
  347. pScavverTriggerVolume.MoveTo(pScavver)
  348. EndIf
  349.  
  350. StartTimer(10, 3) ; Check the distance again in 10 seconds
  351.  
  352. Else
  353. ; Timer ID is not 1-3, so do nothing
  354. EndIf
  355. EndEvent
  356.  
  357. ; -----------------------------------------------------------------------------
  358. ; EVENT: ON ITEM EQUIPPED
  359. ; -----------------------------------------------------------------------------
  360.  
  361. Event OnItemEquipped(Form akBaseObject, ObjectReference akReference)
  362. string DevMsg = ""
  363.  
  364. If akBaseObject as Weapon
  365. DevMsg = "Scavver equipped a weapon."
  366. pScavverActor.DrawWeapon() ; Quick visual confirmation of weapon change (second draw in script)
  367. Else
  368. DevMsg = "Scavver equipped an outfit."
  369. EndIf
  370.  
  371. If pgvScavverStatusSniffer.GetValue() == 1
  372. Debug.Notification(DevMsg)
  373. EndIf
  374. EndEvent
  375.  
  376. Function GetScavverUnstuck()
  377. float BumpDistance = 100
  378. float MinDistance = 100
  379. float MovedDistance = pScavver.GetDistance(pScavverMarker)
  380. float NowX = pScavver.GetPositionX()
  381. float NowY = pScavver.GetPositionY()
  382. float NowZ = pScavver.GetPositionZ()
  383. float ThenX = pScavverMarker.GetPositionX()
  384. float ThenY = pScavverMarker.GetPositionY()
  385. float ThenZ = pScavverMarker.GetPositionZ()
  386. float BumpX
  387. float BumpY
  388. float BumpZ
  389. float i = -1
  390.  
  391. If Math.Abs(NowX - ThenX) > 0 ; If x axis movement before stuck
  392. If NowX > ThenX ; If x movement was positive
  393. BumpX = BumpDistance ; assign positive direction bump
  394. Else
  395. BumpX = i * BumpDistance ; else assign negative direction bump
  396. EndIf
  397. EndIf
  398.  
  399. If Math.Abs(NowY - ThenY) > 0 ; If y axis movement before stuck
  400. If NowY > ThenY ; If y movement was positive
  401. BumpY = BumpDistance ; assign positive direction bump
  402. Else
  403. BumpY = i * BumpDistance ; else assign negative direction bump
  404. EndIf
  405. EndIf
  406.  
  407. If pgvScavverIsIndoors.GetValue() == 1 ; If Scavver is in interior cell (vault)
  408. If pgvScavverStatusSniffer.GetValue() == 1
  409. Debug.Notification("SCAVVER IS INDOORS... FIXING")
  410. EndIf
  411.  
  412. BumpZ = 1000 ; shoot him up out of the ground for handling
  413. pgvScavverIsIndoors.SetValue(0) ; and update the IsInterior global
  414. Else
  415. BumpZ = 60 ; else Z bump is balance between houses & hills
  416. EndIf
  417.  
  418. pScavverMarker.MoveTo(pScavver, BumpX, BumpY, BumpZ) ; Move xmarker with offsets
  419. pScavverMarker.MoveToNearestNavmeshLocation() ; Move xmarker to nearest navmesh
  420. pScavver.MoveTo(pScavverMarker) ; Move Scavver to xmarker
  421. pScavverTriggerVolume.MoveTo(pScavver) ; Move trigger volume to Scavver
  422. EndFunction
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement