Hexen Afrit Idle State - Possible?

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

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!)
Post Reply
User avatar
Enjay
 
 
Posts: 26534
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Hexen Afrit Idle State - Possible?

Post by Enjay »

Is there something that prevents the Hexen Afrit (and possibly other Hexen enemies?) from going into an idle state sequence when they have lost their targets?

I have tried the following:

Code: Select all

Actor NJFireDemon : FireDemon replaces Firedemon
{
	States
	{
		Idle:
		SPOS ABCD 4 A_Wander
		Loop
	}
}
The sprites have been exported to Doom so, in Doom, I can summon a bunch of afrits [njfiredemon]. They work perfectly but if I allow myself to get killed by them, I would expect the afrits to take on the appearance of Doom shotgunners and just wander around. They don't. They seem to go back to their chase state sequence and just floatbob around on the spot still looking like afrits. I can't see anything obvious in their code that forces this behaviour, but they seem to just ignore the idle state label entirely.

If I do the same with a Doom zombieman

Code: Select all

Actor NJZombieman : Zombieman replaces Zombieman
{
	States
	{
		Idle:
		SPOS ABCD 4 A_Wander
		Loop
	}
}
it works perfectly: the zombiemen change to look like shotgunners and wander around when I die.

The above is all in DECORATE BTW, simply because it's for an existing project that was started in DECORATE.


[edit]
Hmmm... I wonder if it's something to do with this bit of the afrit's zscript code:

Code: Select all

		if(!target || !target.bShootable)
		{	// Invalid target
			LookForPlayers (true);
			return;
		}
:?:
[/edit]

[edit2]
Nope, I don't *think* so. The above code is part of the A_FireDChase pointer code and if I replace all instances of A_FireDChase with A_Chase in a copy of the FireDemon code (still in DECORATE), it still ignores the idle label.
[/Edit2]
User avatar
Enjay
 
 
Posts: 26534
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Hexen Afrit Idle State - Possible?

Post by Enjay »

I just realised that this is not just ignoring the idle state label. Enemies usually go back to their spawn sequence once all valid targets have gone, but the afrit clearly doesn't. It stays in its chase sequence. I don't see any special handling of this though. It must be there somewhere- but where?

[edit]I assume that it has something to prevent it returning to its spawn state because the spawn state is it curled up into an invulnerable ball, and it would look weird suddenly switching to that when it has run out of targets.[/edit]
User avatar
Enjay
 
 
Posts: 26534
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Hexen Afrit Idle State - Possible?

Post by Enjay »

Well, I've narrowed it down a bit. If I replace both A_FiredAttack (in the missile sequence) and A_FireDChase (in the chase sequence) with generic near-equivallents, the enemy can go into idle mode. If I leave either of those in the actor's code, it stays in the chase sequence when al targets are gone.

I don't really understand the zscript well enough to identify what it is about those pointers that have this effect though.
Blue Shadow
Posts: 4949
Joined: Sun Nov 14, 2010 12:59 am

Re: Hexen Afrit Idle State - Possible?

Post by Blue Shadow »

I could be wrong, but I don't think LookForPlayers() changes the actor's state if there's no target, so it makes sense the demon stays in its chase sequence.
Enjay wrote:[edit2]
Nope, I don't *think* so. The above code is part of the A_FireDChase pointer code and if I replace all instances of A_FireDChase with A_Chase in a copy of the FireDemon code (still in DECORATE), it still ignores the idle label.
[/Edit2]
When you did that, did you override the Chase state sequence alone without overriding the other states? If that's the case, then what you experienced there is normal. When the demon decides to attack, it'll use the original class's Missile state, and since that state ends with a Goto Chase as opposed to A_Jump(256, "Chase"), then it'll jump to the original class's Chase state instead of the child class's.
User avatar
Enjay
 
 
Posts: 26534
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Hexen Afrit Idle State - Possible?

Post by Enjay »

Ahh, quite right. It's just the A_FiredChase pointer that causes this. Now to figure out a suitable way to address this...
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49067
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Hexen Afrit Idle State - Possible?

Post by Graf Zahl »

You'll have to rewrite that function. There was really little point in extending that for handling the Idle state, considering that it's class specific.
User avatar
Arctangent
Posts: 1235
Joined: Thu Nov 06, 2014 1:53 pm
Contact:

Re: Hexen Afrit Idle State - Possible?

Post by Arctangent »

For reference, that section looks like in A_DoChase - aka, what most A_Chase-type functions call.

The main important part is this:

Code: Select all

			else
			{
				actor->SetIdle();
				actor->flags &= ~MF_INCHASE;
				return;
			}
though since A_FiredChase doesn't seem to use the INCHASE flag, the only two lines are a. the actor calling SetIdle(), bring it back to its appropriate state and b. returning the function so it doesn't execute further.

SetIdle() is available natively to all ZScript actors, so it's just a matter of including those two parts in a rewritten A_FiredChase ( or, more likely, a copy-pasted A_FiredChase with those added afterwards ) where they'll do what you want 'em to ( i.e., if you want to more closely emulate the regular A_DoChase sequence, if LookForPlayers() fails to find a target - heck, you could reuse the same return statement and just shove a if statement that contains SetIdle() inbetween it and LookForPlayers() ).
User avatar
Enjay
 
 
Posts: 26534
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Hexen Afrit Idle State - Possible?

Post by Enjay »

Thanks, I'll have a look at this properly later. The weather was too good today to ignore, so I went outside. [shock horror] ;)
Post Reply

Return to “Scripting”