Custom CVARs with DECORATE

From ZDoom Wiki
Jump to navigation Jump to search

This will show you how to control behaviour of actors in DECORATE using custom CVARs. This way you can easily add options to your level or mod. For this example, we'll make it so that Zombiemen explode when they become active, but only if a custom CVAR is set to equal 1.

This tutorial assumes at least a basic understanding of WAD editing and ACS compiling.

Custom variable

The first thing that is needed is a CVARINFO lump that defines the CVARs that we're going to use. With only one CVAR, the file will only be one line:

server int explodey_zombies = 1;

The server scope should be used for CVARs which can affect any player; for player-specific CVARs use user instead.

Scripting

Now we need a script to read the CVAR, since we cannot do it in DECORATE directly.

#library "exploder"
#include "zcommon.acs"

script "ExplodeZombie" (void)
{
    SetResultValue(GetCVar("explodey_zombies"));
}

Compile this script and make sure the compiled lump is named EXPLODER (the same name as given by the #library directive.) Make sure it is between A_START and A_END markers in a WAD, or in the acs folder of a PK3. (There should not be any other lumps between these markers, in this example.)

This gets the value of our explodey_zombies CVAR and returns it as the result value. Now we will be able to call this script from DECORATE and get the value stored in the CVAR. But first we need to make sure the script loads.

Then make a new lump called LOADACS. This is needed to load the script, since it's not part of a map. Without this lump you will get the message P_StartScript : Unknown Script when trying to access your script. Again it is only one line here, the line of the library to load:

exploder

Note that you don't need a new library for each script; in most cases you will only need one #library directive in your entire project, and only one line in LOADACS.

Now we can finally use this in DECORATE.

Actor code

There are many ways to implement exploding Zombiemen. Here is one possibility.

ACTOR ZombiemanBoom : Zombieman replaces Zombieman
{
    States
    {
    See:
        POSS A 0 A_JumpIf(CallACS("ExplodeZombie")==1, "Explode")
        goto Super::See
    Pain:
        POSS A 0 A_JumpIf(CallACS("ExplodeZombie")==1, "Explode")
        goto Super::Pain
    Death:
        POSS A 0 A_JumpIf(CallACS("ExplodeZombie")==1, "Super::XDeath")
        goto Super::Death
    Explode:
        POSS A 0 A_Die
    }
}

In the replacement Zombieman, we preempt the See and Pain states to first check the result of the ExplodeZombie script (which gives the value of the explodey_zombies CVAR), and if it's equal to 1, cause the Zombieman to die right away. We also make sure that his Death state always results in gibs, when the CVAR is 1. If the CVAR is 0, the Zombieman will behave as normal.

Now Zombiemen will explode on sight when you start up a map, but you can stop this by typing explodey_zombies 0 in the console. To set this value to the default, you must type archive explodey_zombies after setting the CVAR to 0.

Links