From ZDoom Wiki
Jump to navigation Jump to search

84:ACS_ExecuteWithResult (script, s_arg1, s_arg2, s_arg3, s_arg4)


This is like ACS_ExecuteAlways, except the script is always run on the current map, and the return value is whatever the script sets with SetResultValue.


  • script: Script to execute
  • s_arg1: First argument passed to the script
  • s_arg2: Second argument passed to the script
  • s_arg3: Third argument passed to the script
  • s_arg4: Fourth argument passed to the script


This special has a slightly unusual behaviour as most scripts are not designed to functionally return a value. It is possible, however. The syntax fits together like this:

script 1 (void)
    Print(d:ACS_ExecuteWithResult(2, 0, 0, 0)); //prints 667

script 2 (void)

The point of creating a script like this is slightly overlooked by the use of functions. Functions cannot use Delay or other waiting commands. ACS_ExecuteWithResult can use them, but the result has to be decided before they are used. This means that ACS_ExecuteWithResult is sort of like a hybrid between a normal script and a function.

The purpose of this special would be to have other time-dependent events happen after the result is determined.

Another notable use of ACS_ExecuteWithResult is with switch animations. If the result value of the executed script is FALSE, the switch animation and sound will not play when the switch is hit. If the result is TRUE, the switch will animate. One example might be a switch which only responds to a specific weapon. Normally, any line marked as projectile activated will play a switch animation when hit by any weapon. Setting up a script like the following allows for more pleasing behavior. The switch only animates when it is hit with the pistol:

script 1 (void)
    if( CheckWeapon("Pistol") ) {
        Print(s:"You shot me with the pistol.");
        SetResultValue( TRUE ); // Cause the switch to animate
    } else {
        SetResultValue( FALSE ); // The switch will not animate if you use another weapon

ACS_ExecuteWithResult can also be used in DECORATE expressions:

actor ReloadingPistol : Weapon
    PISG A 0 A_JumpIfInventory ("PistolClip", 0, 2)
    PISG A 0 A_JumpIf(1 == (ACS_ExecuteWithResult(999,0,0,0)), "Reload")
    PISG A 1 A_WeaponReady

Return values in ZScript

Similar to DECORATE, this function can also be used in ZScript and returns an integer. There are a few ways to convert this integer to different types making it less limiting than it may appear.


Booleans are, internally, just an integer that can be a value of 0 or 1. In this case, setting the result value to TRUE or FALSE will handle it.

// In ACS
// In ZScript
bool result = ACS_ExecuteWithResult(/*..*/);

Floating points

Floating point values in ACS are stored as 16-bit fixed point integers. What this means is that the actual number is multiplied by 216, reserving 16 bits for the whole portion and 16 bits for the fractional portion. Returning a floating point value from ACS will return it as a 16-bit fixed point integer, so to convert it, all that needs to be done is dividing it by 216.

// In ACS
// In ZScript
// Make sure the number you're dividing by is a floating point number to prevent
// integer division which will remove the fractional portion
double result = ACS_ExecuteWithResult(/*..*/) / 65536.0;


Strings are returned as their index in the global ACS string table. Using LookupString() they can be converted back to the string and then implicitly converted to Names and Sounds as well.

// In ACS
// In ZScript
string result = level.LookupString(ACS_ExecuteWithResult(/*..*/));

// Implicit conversions
Name result = level.LookupString(ACS_ExecuteWithResult(/*..*/));
Sound result = level.LookupString(ACS_ExecuteWithResult(/*..*/));


While texture ids cannot be returned directly, a string holding the texture name can, which can then be converted.

// In ACS
// In ZScript
TextureID result = TexMan.CheckForTexture(level.LookupString(ACS_ExecuteWithResult(/*..*/)));


In ZScript, a color is treated very similarly to an integer. Hex values in particular are useful for setting colors since each ARGB channel refers to 8 bits in the integer:

0x  00   00   00   00
  alpha red green blue
// In ACS
SetResultValue(0xFFFF0000); // Returns fully opaque red
// In ZScript
Color result = ACS_ExecuteWithResult(/*..*/);

Also, unlike the other ACS specials, ACS_ExecuteWithResult can pass a fourth script parameter, making it useful as a line special.

Script functions
ACS_Execute ACS_NamedExecute
ACS_ExecuteWait ACS_NamedExecuteWait
ACS_ExecuteAlways ACS_NamedExecuteAlways
ACS_ExecuteWithResult ACS_NamedExecuteWithResult
ACS_LockedExecute ACS_NamedLockedExecute
ACS_LockedExecuteDoor ACS_NamedLockedExecuteDoor
ACS_Suspend ACS_NamedSuspend
ACS_Terminate ACS_NamedTerminate
ScriptWait NamedScriptWait
FS_Execute UsePuzzleItem