PAPVAFS11 Posted June 1, 2016 Share Posted June 1, 2016 (edited) RESOLVED:See following post. The following script is bound to an NPC and is intended to allow them to intermittently disable mechanical enemies (with extra functionality to make them call out kills they've made). if (GetCombatTarget != 0) set rTarget to GetCombatTarget if (rTarget.GetDead == 1) && (IsTalking != 1) Say CYCKillTarget endif elseif (GetCombatTarget == 0) && (rTarget != 0) set rTarget to 0 endif if (GetQC CYCLONEUpgradeTask == 1) if (fRecharge > 0) set fRecharge to (fRecharge - GetSecondsPassed) elseif (fRecharge <= 0) && (rTarget != 0) && (IsInCombat == 1) if (rTarget.GetEquipped AllPowerArmor == 1) || (rTarget.GetIsCreatureType 6) if (rTarget.HasPerk Stonewall != 1) PushActorAway rTarget 1 endif rTarget.CIOS PulseDisableSpell if (rTarget.GetEquipped AllPowerArmor == 1) rTarget.PlaceAtMe 25mmGrenadeExplosion 1 endif if (rTarget.GetIsCreatureType 6) rTarget.DamageActorValue BrainCondition 1000 endif set fRecharge to 20 if (IsTalking != 1) Say CYCHackTarget endif elseif (rTarget.GetInFaction CreatureHitDeathClaw == 1) && (rTarget.GetInFaction EnclaveFaction) rTarget.DamageActorValue BrainCondition 1000 set fRecharge to 15 if (IsTalking != 1) Say CYCHackTarget endif endif endif endif The problem here is that the script is silently crashing in the background and I have no idea how to fix it. The character can successfully fire off a hack on a living target, but, once that target is dead, the script hits an error somewhere and ceases to function in entirety. The game itself doesn't crash, but the script stops working. Can anyone tell me what I'm missing? Edited June 1, 2016 by PAPVAFS11 Link to comment Share on other sites More sharing options...
PAPVAFS11 Posted June 1, 2016 Author Share Posted June 1, 2016 It turns out that there was nothing wrong with that script at all. It was actually part of an OnCombatEnd block that was failing and tossing the whole script. I'm not entirely certain why the part in question was failing, but it's certainly reminded me that the answer isn't always obvious. Link to comment Share on other sites More sharing options...
dubiousintent Posted June 1, 2016 Share Posted June 1, 2016 (edited) Good to hear you figured out the cause of your script failing. While I am not a FNV mod creator, I do have many years experience with scripts in general and was interested in figuring out the logic of your script. As a result I have some tips and suggestions to increase efficiency to pass along. I put them as comments into the code, along those I made deciphering your logic. ; In six months are you going to remember your thought processes for each conditional decision? ; Documentation in comments is cheap insurance. ; Avoid compound conditions (AND/OR) and "ElseIf" whenever possible as they MUST be evaluated ; even when a previous conditional test has proven part of them false. ; For every "If"/"ElseIf" you need to consider the simple "Else" condition as well. ; A simple "Else" is ignored unless the previous "If" condition was false. if (GetCombatTarget != 0) ; Are >0 and <0 really equivalent? No distinction; not even an error? Why not? Document it. ; A simple '>' is faster than a '!=". set rTarget to GetCombatTarget if (rTarget.GetDead == 1) && (IsTalking != 1) Say CYCKillTarget ; else "not Dead" or "IsTalking" are equivalent result of "do nothing". endif ; ElseIf (GetCombatTarget == 0) Redundent. This MUST be the case if the previous test is false. ; Put it in a comment if you need reminding. ; elseif (rTarget != 0) can be recast as the more efficient: else if (rTarget != 0) ; Are >0 and <0 really equivalent? No distinction; not even an error? set rTarget to 0 ; else ; (rTarget = 0) Do nothing. A comment to this effect says you did consider it instead of ; overlooked it. endif ; of 'if (rTarget != 0)' endif ; of 'if (GetCombatTarget != 0)' if (GetQC CYCLONEUpgradeTask == 1) if (fRecharge > 0) set fRecharge to (fRecharge - GetSecondsPassed) ; elseif (fRecharge <= 0) Redundent. This MUST be the case if the previous test is false. ; Put it in a comment if you need reminding. else if (rTarget != 0) && (IsInCombat == 1) ; So, only if both are true is anything further done. The "Else" condition of ; '(rTarget = 0) or (IsInCombat != 1)' is then "do nothing". ; An 'AND' requires both conditions to be tested. An 'OR' fails when the first of either ; test fails. An 'OR' compound can be recast as an "If"/"ElseIf" if suitable. if (rTarget.GetEquipped AllPowerArmor == 1) || (rTarget.GetIsCreatureType 6) ; Only If rTarget is either full PowerArmor or CreatureType 6 is anything further done. ; Otherwise check faction. ; Assumes it is Not possible to have 'CreatureType 6' in full PowerArmor. if (rTarget.HasPerk Stonewall != 1) PushActorAway rTarget 1 endif rTarget.CIOS PulseDisableSpell if (rTarget.GetEquipped AllPowerArmor == 1) ; This is a redundent test already performed as an 'OR' conditional earlier. ; As rTarget can't be both, it's more efficient to have a simple conditional test ; for each type of rTarget with other tests under each rTarget type. rTarget.PlaceAtMe 25mmGrenadeExplosion 1 endif if (rTarget.GetIsCreatureType 6) ; This is a redundent test already performed as an 'OR' conditional earlier. ; As rTarget can't be both, it's more efficient to have a simple conditional test ; for each type of rTarget with other tests under each rTarget type. rTarget.DamageActorValue BrainCondition 1000 endif set fRecharge to 20 if (IsTalking != 1) ; This test is the same for both rTarget types, so it can be moved outside of both ; 'type' procedures. Say CYCHackTarget endif else ; of 'if (rTarget.GetEquipped AllPowerArmor == 1) || ; (rTarget.GetIsCreatureType 6)' test. ; If that test is split into separate tests, then these can be split into the ; appropriate 'else'/'elseif' conditions for each. if (rTarget.GetInFaction CreatureHitDeathClaw == 1) && (rTarget.GetInFaction EnclaveFaction) rTarget.DamageActorValue BrainCondition 1000 set fRecharge to 15 if (IsTalking != 1) Say CYCHackTarget endif endif ; of 'if (rTarget.GetInFaction CreatureHitDeathClaw == 1) && ; (rTarget.GetInFaction EnclaveFaction)' endif ; of 'if (rTarget.GetEquipped AllPowerArmor == 1) || ; (rTarget.GetIsCreatureType 6)' ; else of 'if (rTarget != 0) && (IsInCombat == 1)' is "do nothing|". endif ; of 'if (rTarget != 0) && (IsInCombat == 1)' endif ; of 'if (fRecharge > 0)' endif ; of 'if (GetQC CYCLONEUpgradeTask == 1)' Best of luck with your mod. -Dubious- Edited June 1, 2016 by dubiousintent Link to comment Share on other sites More sharing options...
Recommended Posts