Tick

From ZDoom Wiki
Jump to navigation Jump to search


Thinker

virtual void Tick()

Usage

A basic virtual function used by Thinker. It's called every game tick (35 times/second). Whether it gets called automatically or not is determined by the type of thinker. Actors call it automatically to perform movement, animation, collision, and all the other key behaviors.

This function can be overridden to add new looped behaviors to actors. When doing that, it's important to remember to call Super.Tick(), otherwise the actor will not be able to move, animate or otherwise meaningfully interact with the world.

For actors it's also important to check the value of IsFrozen(), to make sure the contents of the override do not run while the actor is frozen by some kind of an effect (like the freeze console cheat or PowerTimeFreezer), unless desired.

Error.gif
Warning: On PlayerPawn actors, weird quirks can occur if voodoo dolls are present and Tick is overridden without proper handling, because both the original PlayerPawn and its voodoo doll will execute the override at the same time. See the Voodoo doll page for information on how to check if a PlayerPawn is a voodoo doll or not.


Examples

This version of the Imp's fireball will spawn a trail every tic. The trail will fade out and become smaller while it exists, before disappearing:

class FireBallWithTrail : DoomImpBall
{
	override void Tick()
	{
		super.Tick();
		if (!IsFrozen())
		{
			Spawn("FireBallTrail", pos);
		}
	}
}

class FireBallTrail : Actor
{
	Default
	{
		+BRIGHT
		+NOINTERACTION
		+NOBLOCKMAP
		Renderstyle 'Add';
	}

	States 
	{
	Spawn:
		BAL1 A 1 
		{
			A_FadeOut(0.05);
			scale *= 0.95;
		}
		loop;
	}
}

This version of the Zombieman will spawn explosive barrels every 70 tics while it's alive. The barrels are put into a dynamic array. Once the monster is killed, all those barrels will explode with the help of a Die() override:

class BarrelZombie : Zombieman
{
	array <Actor> barrels;

	override void Tick()
	{
		super.Tick();
		if (health > 0 && !isFrozen() && GetAge() % 70 == 0)
		{
			let bar = Spawn("ExplosiveBarrel", pos, ALLOW_REPLACE);
			if (bar)
			{
				barrels.Push(bar);
			}
		}
	}

	override void Die(Actor source, Actor inflictor, int dmgflags, Name MeansOfDeath)
	{
		for (int i = 0; i < barrels.Size(); i++)
		{
			let bar = barrels[i];
			if (bar && bar.health > 0)
			{
				bar.DamageMobj(self, self, bar.health, 'normal');
			}
		}
		super.Die(source, inflictor, dmgflags, MeansOfDeath);
	}
}