Skip to content

KAI_Chase()

inkoalawetrust edited this page Jun 16, 2025 · 2 revisions

KAI_Chase ([StateLabel Melee = Null, StateLabel Missile = Null, StateLabel Wait = Null, Int Flags = 0, Int FlagsEx= 0, Double RetreatRange = 0, Double StrafeDist = 64*10, String Voice = "", KAIMoveParams Extra = Null])

Parameters

  • Melee: The specific state sequence that the actor will go to for melee, by default actors just use their MeleeState in the stock ShouldAttack() code. Default is just the actors "Melee" state sequence.
  • Missile: Ditto, but for the "Missile" state.
  • Wait: The state sequence that the actor will go to when they encounter a delayed patrol point. By default they just call SetIdle() to decide what state to wait in. Note: You should be calling one of the native look functions or KAI_Look() in whatever custom state you want, so that the NPC can eventually stop waiting and continue along the path!
  • Flags: The A_Chase() flags to use, in addition to supporting the flags KAI_MoveTowards() does, it also supports CHF_RESURRECT and CHF_FASTCHASE.
  • FlagsEX: KAI_Chase() specific flags.
    • KAIC_FRIENDSIDLE: Makes even friendly actors eventually go to their idle state (Call SetIdle()) without a target, like hostile actors do. Default behavior is for friendlies to just wander from within KAI_Chase(), just like A_Chase().
    • KAIC_ZIGZAG: Slightly zigzag on your way to the target instead of moving straight at it, is passed to KAI_MoveTowards() as KMT_ZIGZAG. This flag is ignored if the function is making the NPC run away however.
    • KAIC_IGNOREHAZARDS: Ignore generic sector hazards and KAI hazards even if +AVOIDHAZARDS is on.
  • RetreatRange: If the callers' target is over their ThreatLevelThreshold, and they are within this range, the caller will begin moving away from the target. This can be used to make NPCs keep a distance from powerful threats. Default is 0, which turns off the feature.
  • StrafeDist: Used when CHF_FASTCHASE is enabled, if the target is within this range, the caller will begin the Hexen-style strafing.
  • Voice: The name of the voice pack to use, if it's a valid voice pack, the actor will be able to comment on specific events from within KAI_Chase() itself, though this is not a substitute for using SayVoiceLine() more broadly. Default is no voice pack.
  • Extra: A KAIMoveParams struct for controlling the specifics of the actors' movement during KAI_Chase(), and enabling additional features like retreating behind corners.

Function

A simple, generic drop-in replacement for GZDoom's stock A_Chase(). This function handles most of the biggest features of A_Chase(), such as moving towards the callers' target and attacking. More specifically, it supports the following:

Movement

The function uses KAI's movement functions for moving the actor towards and away from the target, which allow for smooth movement that can be fine tuned with the Extra parameter (See below).

Retreating

The function supports:

  • The stock ZDoom fright logic (Moving away from +FRIGHTENING actors or players with CF_FRIGHTENING, and also moving away if the monster itself is +FRIGHTENINED).
  • Avoiding melee attackers (Such as players currently with a melee weapon) if they have +AVOIDMELEE or the equivalent map flag is on.
  • Keeping a distance from powerful targets, the distance can be set through RetreatRange, and the actors needs a ThreatLevelThreshold passed, if the target is at or beyond that threat level, the caller will move away until out of range.
  • If +AVOIDHAZARDS is on (And KAIC_IGNOREHAZARDS isn't), the caller will try to run away from generic sector hazards like crushers and hurtfloors that can affect them, and will also run away from any KAI hazard zones they are in range of, which allows them to also react to hazards from other KAI actors, such as a hazard-emitting attack aimed at them.
Patrolling, strafing, and resurrection

KAI_Chase() works with ZDoom patrol routes similar to A_Chase(), supports Hexen's player boss strafing, and also supports CHF_RESURRECT, which makes the actor revive any revivable corpses it comes across.

Speaking

If a valid Voice is passed. KAI_Chase() can make the NPC use the following voice types:

  • VOICE_PLAYERSEE, VOICE_SEE: Whenever the NPC sees a new enemy from within the function. Also supports player-specific lines if available.
  • VOICE_ALLYREVIE: Whenever the NPC resurrects a corpse with CHF_RESURRECT.
  • VOICE_HAZARD: Occasionally spoken when running away from any kind of hazard.
  • VOICE_PLAYERFEAR, VOICE_FEAR: Occasionally spoken when the NPC retreats from their target, also supports player-specific lines if available. NPCs don't speak if they're just avoiding melee attackers.
KAIMoveParams

The function supports defining a KAIMoveParams struct and passing it. It can be used to fine tune exactly how the actor moves, such as its' horizontal (And for flyers, vertical) turn speed. All of KAIMoveParams' parameters except for TargetPos are supported. Which also means that the support for obstacle avoiding and retreating behind corners of KAI_MoveAway() can also be enabled.

Examples

This Imp moves around with KAI_Chase, can resurrect corpses, has custom detailed movement parameters, stays at least 768 map units away from any target that is THREAT_DANGEROUS or above, avoids melee attacks. And also tries to avoid hitting obstacles, and will run behind corners when retreating, from where his' target can't see him.

Class KAI_TestImp : KAI_Humanoid
{
	Default
	{
		Health 60;
		Radius 20;
		Height 56;
		Mass 100;
		Speed 8;
		PainChance 200;
		Monster;
		+FLOORCLIP
		SeeSound "imp/sight";
		PainSound "imp/pain";
		DeathSound "imp/death";
		ActiveSound "imp/active";
		HitObituary "$OB_IMPHIT";
		Obituary "$OB_IMP";
		Tag "$FN_IMP";
		+AvoidMelee;
		+AvoidHazards; //All KAI_Actors have this on by default but whatever.
		KAI_Actor.ThreatLevelThreshold THREAT_DANGEROUS;
	}
	States
	{
		Spawn:
			TROO AB 10 KAI_Look(ExtraFlags:KAIL_CHASETARGET);
			Loop;
		See:
			TROO AABBCCDD 3
			{
				KAIMoveParams Params;
				Params.DetourFactor = 1;
				Params.AngleLimit = 45;
				Params.PitchLimit = 0;
				
				Params.Attempts = 8;
				Params.RunRad = Radius+64;
				Params.MaxSteps = 16;
				Params.KMAFlags = 0;
				
				Params.CornerDist = 192;
				Params.CornerDiv = 8;
				
				Params.ObstacleDist = 128;
				Params.ObstacleDiv = 6;
				Params.ObstacleSlices = 8;
				
				KAI_Chase(flags:CHF_RESURRECT,flagsex:KAIC_ZIGZAG,retreatrange:768,extra:params);
			}
			Loop;
		Melee:
		Missile:
			TROO EF 8 A_FaceTarget();
			TROO G 6 A_TroopAttack();
			Goto See;
		Pain:
			TROO H 2;
			TROO H 2 A_Pain;
			Goto See;
		Death:
			TROO I 8;
			TROO J 8 A_Scream;
			TROO K 6;
			TROO L 6 A_NoBlocking;
			TROO M -1;
			Stop;
		XDeath:
			TROO N 5;
			TROO O 5 A_XScream;
			TROO P 5;
			TROO Q 5 A_NoBlocking;
			TROO RST 5;
			TROO U -1;
			Stop;
		Raise:
			TROO ML 8;
			TROO KJI 6;
			Goto See;
	}
}

See also

Clone this wiki locally