Jump to content

I've got the wierdest script looping bug...


gigantibyte

Recommended Posts

So I've been having issues with this mod I'm building. After several hours of bug testing, I narrowed down where the problem was, and a created a new test script to eliminate the rest of my code as a variable. The test mod consists of a quest that loads on game start and has the following script attached:

scn TestMessageEx

int DoOnce

Begin GameMode

    if DoOnce != 1

        player.additem TinCan01 1 ;to verify the mod has been loaded
        let DoOnce := 1

    endif

    if IsControlPressed 5 ;when player taps the activate key

        if player.IsSneaking

            MessageEx "You Sneaky Devil!"
            player.additem caps001 2

        else

            player.additem caps001 1

        endif

    endif

End

The script works as expected when not sneaking. The player gets a free cap each time the activate key is pressed. However, if I press the activate key while sneaking, the script to go into a loop of displaying the "You Sneaky Devil!" message and giving the player 2 caps, between 6 to 9 times. Coming out of sneak mode does not break the loop. IsSneaking probably not at fault, because I can replicate the problem by using IsWeaponOut, and my original script uses a completely different trigger.

 

Now here's the weird part. If I comment out either

;   MessageEx "You Sneaky Devil!"

or

;   player.additem caps001 2

the looping problem goes away! I get 1 message or 2 caps.

 

As a final note, I still get this bug if I deactivate all other mods and DLCs to the point where only FalloutNV.esm and my test mod are running.

 

Does anybody know what's going on? If not, can you test this script out to see if you get the same bug so I'll know I'm not going crazy?

 

Edit: More info (if it helps). MessageEx is not the problem. The same extra loops happen if I use ShowMessage with a message form in "fly" mode (message appears in the top left corner). 'Message box' mode functions without issue. It's like the activate control is being triggered by the fly message. Is there a way to clear the control buffer before using IsControlPressed or something? I'm stumped.

 

 

Edit 2: Ok, so it's not IsControlPressed 5 in particular, Using IsControlPressed 0 (forward) instead results in the same extra loops. I would suspect the script is running so fast that the Control buffer doesn't have time to clear before IsControlPressed is called a second time, only there's no problem when I don't display a fly message. In fact, with 1 less command, the second half of my IF block should run just a little bit faster. Help me internet. You're my only hope...

Edited by gigantibyte
Link to comment
Share on other sites

This is a GameMode script, so it will run in every frame (except if it's tied to a quest and you have set a script delay.) In cases like this, you need to use a control variable to prevent the code from running multiple times. I'd say the lack of this is causing your problems, although the problem should be present even when you're not sneaking. Are you sure you're keeping correct track of your cap amount?

 

Anyway, when you check if the control button is pressed, you need to check the value on a variable as well. If the variable is unset, then you do whatever you need to do and set the variable to prevent running the section again. When the button is released, you unset the variable.

scn TestMessageEx

int DoOnce
int bButtonPressed

Begin GameMode

    if DoOnce != 1

        player.additem TinCan01 1 ;to verify the mod has been loaded
        let DoOnce := 1

    endif

    if IsControlPressed 5 && bButtonPressed == 0 ;when player taps the activate key

        Set bButtonPressed to 1
    
        if player.IsSneaking

            MessageEx "You Sneaky Devil!"
            player.additem caps001 2

        else

            player.additem caps001 1

        endif
    
    ElseIf IsControlPressed 5 == 0 && bButtonPressed
        Set bButtonPressed to 0
    endif

End
Link to comment
Share on other sites

 

 

Are you sure you're keeping correct track of your cap amount?

 

OMG. I am an idiot for not checking that. Thank you. I was just relying on the audio cue. The script was also looping in non-sneak mode.

 

Now I just need to figure out how to apply your working solution to my original script. I am in fact using a control variable in it, but it's set by another script. The control variable is meant to stop things from running in the calling script before the second script is complete. I may need to redesign my script flow...

Link to comment
Share on other sites

Sorry for the double post, but I just need to thank you again. It all seems so simple now. While I was using a control variable in my original script, I should have used a second one like you have above, and a check for IsControlPressed 5 == 0. This is what my script looked like before:

if (IsControlPressed 5)  && uMainQuest.pStage == 1
     let uMainQuest.pStage := 2
endif
if uMainQuest.pStage == 2 ; do stuff until done, then set uMainQuest.pStage to 1

Here's what I'm using now:

    if (IsControlPressed 5)  && bButtonPressed == 0

        set bButtonPressed to 1

        if uMainQuest.pStage == 1
            let uMainQuest.pStage := 2
        endif

        
    ElseIf IsControlPressed 5 == 0 && bButtonPressed

        Set bButtonPressed to 0

    endif

I need to add you to the author credits or something for this. :thumbsup:

Edited by gigantibyte
Link to comment
Share on other sites

  • Recently Browsing   0 members

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