Page 1 of 1

CanResurrect virtual

Posted: Sun Oct 14, 2018 7:52 am
by Major Cooke
Pull Request

CanResurrect(Actor other, bool passive)

Coded similarly to CanCollideWith, meaning it comes after all the other checks: a Raise state and either -1 tics or CanRaise keyword are still required.

Unlike CanCollideWith, other CAN be null, or it can be self (active only - the code doesn't even bother with pointlessly running twice).

This zombieman will print stuff based on who raised it. It will lay dead for five seconds before resurrecting itself so you can summon an archvile and have it resurrect to print something else.

Code: Select all

Class RZ : Zombieman
{
	override bool CanResurrect(Actor other, bool passive)
	{
		if (!passive)
		{
			if (other == null || other == self)
				Console.Printf("Actively reviving self");
			else
				Console.Printf("Reviving someone else");
		}
		else
		{
			if (other == null)
				Console.Printf("Being revived by The Powers That May Be!");
			else
				Console.Printf("Being revived by a monster");
		}
		return true;
	}
	
	Default
	{
		Health 1;
	}
	
	States
	{
	XDeath:
	Death:
		POSS H 5;
		POSS I 5 A_Scream;
		POSS J 5 A_NoBlocking;
		POSS K 5 CanRaise;
		POSS L 175 CanRaise;
		POSS L -1 A_RaiseSelf(RF_NOCHECKPOSITION);
		Stop;
	}
}
Spoiler: Old post

Re: CanResurrect virtual

Posted: Sun Oct 14, 2018 7:54 am
by phantombeta
Wouldn't it be better for it to have a "passive" bool argument like CanCollideWith, so it can be defined either in the monster being resurrected, or in the healer?

Re: CanResurrect virtual

Posted: Tue Nov 06, 2018 11:28 am
by Major Cooke
Done.

Also I just pushed two more commits, adding A_RaiseActor and fixing an inconsistency. Whenever no raise state is found, P_Thing_Raise returned true while P_Thing_CanRaise returned false.

Now they both return false for that condition.

Re: CanResurrect virtual

Posted: Tue Nov 06, 2018 12:45 pm
by Blue Shadow
Major Cooke wrote:adding A_RaiseActor
Can't you just use [wiki]A_RaiseSelf[/wiki]?

Re: CanResurrect virtual

Posted: Tue Nov 06, 2018 3:40 pm
by Major Cooke
No. The 'other' actor in CanResurrect will always either be null or self if using A_RaiseSelf. This will not suffice.

Re: CanResurrect virtual

Posted: Tue Nov 06, 2018 5:24 pm
by Blue Shadow
Oh, I see, for that.

Re: CanResurrect virtual

Posted: Wed Nov 07, 2018 2:26 pm
by Major Cooke
Graf, I changed the name as you requested to just RaiseActor.

Re: CanResurrect virtual

Posted: Tue Nov 13, 2018 11:14 am
by Lord Misfit
Hopefully this can work out. I've been trying to find a good way to make options for controlling what certain monsters can and can't resurrect without having to resort to possibly more hacky methods. I'd like to have the option to make Archviles/their ilk more challenging for those who want the option, yet not outright force it on those who don't like it either. :P

Re: CanResurrect virtual

Posted: Tue Nov 13, 2018 12:04 pm
by Major Cooke
Well, it's in now! :mrgreen:

Re: CanResurrect virtual

Posted: Sat Nov 17, 2018 9:11 am
by Blue Shadow
I don't know if this is an oversight or intended, but here goes:

In P_CheckForResurrection(), P_CanResurrect() is called like this:

Code: Select all

if (!check || !P_CanResurrect(self, corpsehit)) continue;
In P_Thing_Raise(), however, it's called like this:

Code: Select all

if (!P_CanResurrect(thing, raiser))
Notice the different order between the two calls in which the raiser and resurrectee are passed to the function. This creates an inconsistency when it comes to the meaning of passive vs. non-passive depending on which calling function is used (P_CheckForResurrection() or P_Thing_Raise()).

Re: CanResurrect virtual

Posted: Sat Nov 17, 2018 9:16 am
by Graf Zahl
This stuff happens if people name their variables 'thing' and 'tmthing'. It defeats the concept of self-documenting code...
Doom is full of such misdeeds and many have carried over until now.

Re: CanResurrect virtual

Posted: Sat Nov 17, 2018 9:43 am
by Major Cooke
I just realized something.

Code: Select all

P_Thing_Raise(self->master, copy ? self : NULL, (flags & RF_NOCHECKPOSITION));
ACTION_RETURN_BOOL(P_Thing_Raise(self, NULL, (flags & RF_NOCHECKPOSITION)));
So now those functions (A_RaiseMaster, A_RaiseSelf, etc.) might not work anymore, because if there's no raiser, P_CanResurrect returns false.

Code: Select all

if (raiser == nullptr)
	return false;
Because of stuff like this:

Code: Select all

auto clss = raiser->GetClass();
I'll make changes to the action functions to ensure raiser always points to the calling actor, and I'll change the flags so they're checked in P_Thing_Raise.