ZScript enemy deletes himself when target out of attack range

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
User avatar
TIIKKETMASTER
Posts: 34
Joined: Thu Jul 29, 2021 2:02 pm

ZScript enemy deletes himself when target out of attack range

Post by TIIKKETMASTER »

This is my code:

Code: Select all

class TestGuy : Actor
{
	int cooldown;
	property cooldown : cooldown;
	
	override void Tick()
	{
		Super.Tick();

		//decrement once per tic till you reach 0
		if (cooldown > 0)
			cooldown--;
	}
	
	Default
	{
		TestGuy.cooldown 39; //define default cooldown for the unit
		Health 100;
		Radius 20;
		Height 30;
		MeleeRange 50;
		Speed 5;
		PainChance 0;
		PainChance "Hammer", 256;
		Monster;
		+FLOORCLIP
		+THRUACTORS
		//+DONTTHRUST
		+NOBOUNCESOUND
		SeeSound "guy/spawn";
		//PainSound "guy/attack"; 
			//attack sound will be called in attack state
		DeathSound "guy/die";
		//ActiveSound "imp/active";
		Tag "TestGuy";
	}
	States
	{
	Spawn:
		TNT1 A 1; //A_PlaySound("guy/spawn")
		Goto See;
	See:
		POSS AABBCCDD 4 A_Chase("Coolcheck","null", CHF_NOPLAYACTIVE|CHF_NORANDOMTURN|CHF_NOPOSTATTACKTURN);
		Loop;
	Coolcheck:
		POSS B 1
		{
			//check cooldown
			if (cooldown < 1) //check if the integer is 0
			{
				return ResolveState("Attackin"); //go to state Attackin
			}
			return ResolveState("See");
		}
		Loop;
	Attackin:
		POSS E 10
		{
			cooldown += 49; //increase cooldown to max
		}
		POSS F 10 A_CustomMeleeAttack(8,"guy/attack","");
		Goto See;
	Pain.Hammer:
		TNT1 A 0 ThrustThing(angle * 256 / 360 + 128, 6, 0, 0);
		POSS H 2;
		POSS H 2 A_Pain;
		Goto See;
	Death:
		POSS H 50
		{
			ThrustThingZ(0, 50, 0, 1);
			ThrustThing(angle * 256 / 360 + 128, 6, 0, 0);
			A_ChangeFlag("BOUNCEONFLOORS", true);
			A_NoBlocking;
		}
		TNT1 A 0 A_Scream;
		Stop;
	}
}
While testing, I realized that the problematic code was this:

Code: Select all

POSS AABBCCDD 4 A_Chase("Coolcheck","null", CHF_NOPLAYACTIVE|CHF_NORANDOMTURN|CHF_NOPOSTATTACKTURN);
Which, if I turn it to 'A_Chase', with no added parameters, and rename the 'Coolcheck:' state to 'Melee:', the problem seems to go away.

However, this removes my ability to add the flags I need for proper functionality, namely 'CHF_NOPLAYACTIVE|CHF_NORANDOMTURN|CHF_NOPOSTATTACKTURN'.

May I get some help with this, namely, fixing A_Chase so that it doesn't delete the character out of nowhere? Many thanks. This is my first time with ZScript.
Kan3x
Posts: 85
Joined: Tue Nov 08, 2022 4:19 pm

Re: ZScript enemy deletes himself when target out of attack range

Post by Kan3x »

This happens because you set "null" as the missile state in A_Chase, which basically forces the actor to enter the Null state deleting him out of existence since it's not defined.
Just remove the quotation marks and leave null and you're done (same rule is applied in other functions like jump functions etc. It explains it here
User avatar
phantombeta
Posts: 2225
Joined: Thu May 02, 2013 1:27 am
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support
Location: Brazil

Re: ZScript enemy deletes himself when target out of attack range

Post by phantombeta »

Kan3x wrote: Tue Nov 18, 2025 2:38 am This happens because you set "null" as the missile state in A_Chase, which basically forces the actor to enter the Null state deleting him out of existence since it's not defined.
Just remove the quotation marks and leave null and you're done (same rule is applied in other functions like jump functions etc. It explains it here
This isn't why putting in "null" instead of null removes the actor. A_Chase checks whether the state label is valid to determine whether to try using that attack, if it's invalid, it doesn't even try to use that attack. So if "null" was actually an invalid state label, it'd just do nothing.
The real reason it removes the actor if you put in "Null" as one of the attack state labels is because the base Actor class actually does define a "Null" state label, as this:

Code: Select all

	Null:
		TNT1 A 1;
		Stop;
User avatar
TIIKKETMASTER
Posts: 34
Joined: Thu Jul 29, 2021 2:02 pm

Re: ZScript enemy deletes himself when target out of attack range

Post by TIIKKETMASTER »

Thank you so much, it works. I spent so much time debugging and I guess I read the wiki wrong. Props to both.

Return to “Scripting”