From ZDoom Wiki
Jump to navigation Jump to search
Note: This feature is for ZScript only.

A Thinker class is derived from Object, and is used as the base for an Actor and more. Unlike actors, thinkers are not physically present in the game at all.

Thinkers are generally used to 'run the game' -- movement, shooting, performing functions, etc.

Thinkers do not possess the many properties and functions an actor has, drastically cutting down on the amount of overhead generated from creating an actor. As such, these make excellent candidates for replacing dummy actors used to monitor and modify primary actors.

To create a new instance of a Thinker, use the following:

 new("<your thinker class name>");


The engine utilizes stat numbers on thinkers to organize thinkers and whether to call their Tick() functions or not.

Some have special use cases such as the STAT_CORPSEPOINTER, invoked by A_QueueCorpse, which creates a thinker for the calling actor, utilizing internal code to eliminate corpses as the queue when filled.

Because of the aforementioned internal handling, take caution when changing a stat number. The engine may manipulate them at any time and cause issues. Thinkers also can only belong to one stat category at any time.

The safest ranges to use are anywhere under 127, and the unmentioned numbers not defined in the list below (i.e. 99, 98, etc -- so long as they are not defined internally).

NOTE: Not all thinkers will actually use their Tick() virtuals based on their stat numbers (see below under the comment 'Thinkers that don't actually think'). It's possible to have another thinker manually call the non-ticking thinker's Tick function inside its own.

Internal Code

class Thinker : Object native play
    enum EStatnums
        // Thinkers that don't actually think
        STAT_INFO,							// An info queue
        STAT_DECAL,							// A decal
        STAT_AUTODECAL,						        // A decal that can be automatically deleted
        STAT_CORPSEPOINTER,						// An entry in Hexen's corpse queue
        STAT_TRAVELLING,						// An actor temporarily travelling to a new map
        STAT_STATIC,							// persistent across maps.

        // Thinkers that do think
        STAT_SCROLLER=STAT_FIRST_THINKING,		                // A DScroller thinker
        STAT_PLAYER,					                // A player actor
        STAT_BOSSTARGET,				                // A boss brain target
        STAT_LIGHTNING,				                        // The lightning thinker
        STAT_DECALTHINKER,				                // An object that thinks for a decal
        STAT_INVENTORY,				                        // An inventory item
        STAT_LIGHT,							// A sector light effect
        STAT_LIGHTTRANSFER,						// A sector light transfer. These must be ticked after the light effects.
        STAT_EARTHQUAKE,						// Earthquake actors
        STAT_MAPMARKER,						        // Map marker actors
        STAT_DLIGHT,							// Dynamic lights

        STAT_USER = 70,
        STAT_USER_MAX = 90,
        STAT_DEFAULT = 100,						// Thinkers go here unless specified otherwise.
        STAT_SECTOREFFECT,						// All sector effects that cause floor and ceiling movement
        STAT_ACTORMOVER,						// actor movers
        STAT_SCRIPTS,							// The ACS thinker. This is to ensure that it can't tick before all actors called PostBeginPlay
        STAT_BOT,							// Bot thinker
        MAX_STATNUM = 127

    const TICRATE = 35;

    native LevelLocals Level;

    virtual native void Tick();
    virtual native void PostBeginPlay();
    native void ChangeStatNum(int stat);

    static clearscope int Tics2Seconds(int tics)
        return int(tics / TICRATE);