Knowledge Base - Force Fields

Force Fields

Force Field In Action
Figure 1: Force Field In Action

One of the main features of any good science fiction movie that takes place in space is the ubiquitous force field. Never mind that the amount of energy actually required to produce an energy field strong enough to keep things out would probably melt the ship and everyone in it. No self-respecting ZDoom level that takes place on a space ship should be without the force field. Thanks to ACS, it is quite easy to do. Figure one illustrates a force field in action (using a set of cheesy animated graphics), that you can examine in frcfld.wad.

The way I have implemented force fields (and there are other ways) is quite simple. The force field itself is simply a linedef that has the appropriate graphics and the impassible flag set, with a second line to simulate the repulsion of the force field. The map layout is illustrated in Figure 2.

Map Layout
Figure 2: Map Layout

The linedef marked impassible has the special Line_SetLineIdentification set to 1. This number will be used to reference the line when the force field is turned off.

The repulsion line calls an ACS script (script 1) that is listed below. The line is marked repeatable and player crosses.

The switch calls another ACS script (script 2) that clears the texture and turns off the blocking flag so the player can pass through the force field. The switch must also deactivate the repulsion generated by the repulsion linedef. The easiest way to do this is to simply create a map level variable that is set when the player uses the switch.

Here is a listing of the ACS scripts:

#include "zcommon.acs"

// Field on/off flag.
int foff;

script 1 (void)
    // If field is on, then repulse player.
    if (!foff)
        // Shove the player and do a bit of damage.
        ThrustThing(random(160, 224), 8);

script 2 (int line)
    // Set the flag.
    foff = 1;


    // Get rid of the textures.
    SetLineTexture(line, SIDE_FRONT, TEXTURE_MIDDLE, "-");
    SetLineTexture(line, SIDE_BACK, TEXTURE_MIDDLE, "-");

    // Turn off the impassible flag.
    SetLineBlocking(line, OFF);

The variable foff indicates that the force field is on (foff=0) or is off, (foff=1). This variable has map scope so is visible to all scripts within this map.

Script 1 checks to see if the player has switched off the force field using a simple if statement: if (!foff). This reads if foff is not true then..., where TRUE is any value except zero. The script then uses two thing specials to thrust the player away from the force field and to damage the player a bit for being foolish enough to run into a force field.

Script 2 "deactivates" the force field and sets the flag so that script 1 will not execute the thing specials when the player crosses the line. The force field linedef has the Line_SetLineIdentification special active so that ID number is used in this script to change the textures to NULL "-", and to turn off the blocking of the line.

This special effect is both simple to make and can really enhance the interaction of your level for the player.


ZDoom reference by Marisa Heit.
3D Game Alchemy by Steve Benner, et al. Copyright © 1996 By Sams Publishing