Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
revan1141

(UDMF) Make a script execute only once?

Recommended Posts

So in order to get a feel for UDMF and GZDoom Builder, I'm making a bunch of small maps, but I've run into a scripting issue that I can't seem to resolve without resorting to global variables.

Basically, I have linedefs facing the direction the player is running, and when he moves over one of these linedefs, Script 1 Executes which causes monsters to spawn in the room.


#include "zcommon.acs"

script 1 (void)
{
   Thing_Spawn(4, T_CHAINGUY, 0, 0);
   Thing_Spawn(3, T_SHOTGUY, 0, 0);
}
Now the problem is - The player runs over one of the linedefs executing Script 1, and everything works... But, if the player runs over any of the other linedefs, it executes the script again!

One of the ways I've managed to solve this is to have a global boolean. When the player runs over a linedef, script 1 check if this boolean is true or false. If false, it spawns in the monsters and sets the boolean to true. if the boolean is true, it doesn't spawn anything.
#include "zcommon.acs"

bool HasExecutedOnce = false;
script 1 (void)
{
   if (HasExecutedOnce == false)
   {
    Thing_Spawn(4, T_CHAINGUY, 0, 0);
    Thing_Spawn(3, T_SHOTGUY, 0, 0);
    HasExecutedOnce = true;
   }
   else
   {
    //Do nothing.
   }
}
Is this the best way to solve this issue? I've always been told that global state is a very bad programming practice. Keep in mind, I'm still new to programming.

Share this post


Link to post
revan1141 said:

Is this the best way to solve this issue? I've always been told that global state is a very bad programming practice. Keep in mind, I'm still new to programming.

Keep in mind that you're talking about scripting with ACS here, not programming with C# or whatever is the hypest programming language nowadays.

In this case, the method you've used is the simplest and most commonly used method. Another method you can use if you want to get rid of the global bool is this:
1. Give an ID to the lines that trigger the script (they can all share the same ID)
2. In your script, clear the lines' special, with SetLineSpecial(id, 0, 0, 0, 0, 0, 0)

Another way to get rid of the global is to instead use a static variable in script score, see here. If instead of a bool you use an int to, for example, only do something after a switch has been hit three times or whatever, this can be the approach you use. Regardless, clearing lines that will no longer do anything can be a good idea anyway, because they can appear on the automap.

Also, you don't need the "else { /* do nothing */ }" part.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×