Virtual for when a monster first acquires a target

Remember, just because you request it, that doesn't mean you'll get it.

Moderator: GZDoom Developers

User avatar
Matt
Posts: 9687
Joined: Sun Jan 04, 2004 5:37 pm
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Virtual for when a monster first acquires a target

Post by Matt »

I want a clean way to have a monster do things other than/along with it making its seesound and going into see state, that shouldn't be done repeatedly but only when the monster first acquires its target.

Use cases can include:
- Playing a seesound at a different pitch (this is what I was trying to do - each individual monster would have a slightly different voice pitch, which is fairly easy to do for idle, pain and death but not sight)
- Playing a different seesound depending on other circumstances (e.g., multiple pronoun options for "It's ___! Get ___!" depending on player settings, or different responses depending on whether a certain quest item is in the player's possession)
- Summoning an ally, shield, etc. that's only supposed to happen once per fight
- A different opening attack that isn't repeated again (good for characters with very limited ammo like throwing axes or whatnot)
- A flying monster launching itself into the air if it's on the ground


Something equivalent for when a monster loses/defeats its target and goes into spawn/idle would be great too.


Workarounds I'm trying to avoid include:
- constantly comparing the monster's current and immediately preceding target (can be done as a last resort)
- inserting all this stuff into the spawn/idle/see states of each monster (there are quite a few so it gets unmaintainable quickly compared to having them all inherit from another monster)
User avatar
Apeirogon
Posts: 1603
Joined: Mon Jun 12, 2017 12:57 am

Re: Virtual for when a monster first acquires a target

Post by Apeirogon »

So

Code: Select all

class dummy : actor
{
	private bool first_time_target;

	override void tick()
	{
		if(first_time_target == false && target)
		{
			first_time_target = true;
			stuff that actor should do on target "aquariuming"
		}

		super.tick();
	}
}
User avatar
Cherno
Posts: 1297
Joined: Tue Dec 06, 2016 11:25 am

Re: Virtual for when a monster first acquires a target

Post by Cherno »

^This would not let me "interrupt" entering the See state. A virtual that returns a bool would be be nice, where true would result in the usual behavior of entering the See state (or other state as defined in A_LookEx), and false cancels the state change. Parameters of the virtual could be wether the monster saw the target or not (not means that it "heard" the target or was affected by Thing_Hate or similar).
User avatar
Apeirogon
Posts: 1603
Joined: Mon Jun 12, 2017 12:57 am

Re: Virtual for when a monster first acquires a target

Post by Apeirogon »

Cherno wrote:This would not let me "interrupt" entering the See state
JUst change the order in tick to

Code: Select all

   override void tick()
   {
      super.tick();

      if(first_time_target == false && target)
      {
         first_time_target = true;
         stuff that actor should do on target "aquariuming"
      }
   }
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 48537
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Virtual for when a monster first acquires a target

Post by Graf Zahl »

That would trigger too late in most cases.
User avatar
Apeirogon
Posts: 1603
Joined: Mon Jun 12, 2017 12:57 am

Re: Virtual for when a monster first acquires a target

Post by Apeirogon »

Maybe then, instead of "virtual void OnTargetAcquiring() = 0;", it have more sense to split tick into separate functions, exposed to zscript? Something like, unordered,

Code: Select all

AActor::Tick()
{
//exposed to zscript
AdvanceState();
HandleCollision();
HandlePowerups();
BotThink();
other stuff

//still internal
UpdateRenderList();
}
Point is, this makes tick extension/custom implementation much easier. With this you can copy/paste all unchanged functions as is, and focus effort on new custom features.

Or performance degradation will be too big in this case?
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 48537
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Virtual for when a monster first acquires a target

Post by Graf Zahl »

AActor::Tick() is not the correct place for this. You would want to have the callback somewhere in A_Look.
User avatar
Rachael
Admin
Posts: 13208
Joined: Tue Jan 13, 2004 1:31 pm
Preferred Pronouns: She/Her

Re: Virtual for when a monster first acquires a target

Post by Rachael »

@ Apeirogon:

The whole point of the "Feature Requests" subforum is not for you to suggest hacky workarounds for ideas that are posted here. If something is posted here then chances are the author (probably for good reason) wants a more direct approach to something that logically and naturally ties into an existing workflow and hopefully without creating a convoluted mess on the author's end.

The workarounds you've posted here don't really do that. So please understand that before you go suggesting more workarounds.
User avatar
Matt
Posts: 9687
Joined: Sun Jan 04, 2004 5:37 pm
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: Virtual for when a monster first acquires a target

Post by Matt »

For what it's worth, I got the effect I wanted by using a function that checks the contents of the target pointer, calls A_Look and then compares the old target value to the new value, and calling the virtual if the target has in fact been newly acquired. Then I just use that function instead of A_Look every time.

This seems to do it cleanly enough that I'm not sure if this suggestion is even needed anymore, though I'm pretty sure there's an edge case that could still mess this up.

Return to “Feature Suggestions [GZDoom]”