Jump to content

Why is this script failing?


PAPVAFS11

Recommended Posts

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 by PAPVAFS11
Link to comment
Share on other sites

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

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 by dubiousintent
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...