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)
Virtual for when a monster first acquires a target
Moderator: GZDoom Developers
-
- Posts: 9696
- Joined: Sun Jan 04, 2004 5:37 pm
- Preferred Pronouns: They/Them
- Operating System Version (Optional): Debian Bullseye
- Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia
-
- Posts: 1606
- Joined: Mon Jun 12, 2017 12:57 am
Re: Virtual for when a monster first acquires a target
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();
}
}
-
- Posts: 1321
- Joined: Tue Dec 06, 2016 11:25 am
Re: Virtual for when a monster first acquires a target
^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).
-
- Posts: 1606
- Joined: Mon Jun 12, 2017 12:57 am
Re: Virtual for when a monster first acquires a target
JUst change the order in tick toCherno wrote:This would not let me "interrupt" entering the See state
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"
}
}
-
- Lead GZDoom+Raze Developer
- Posts: 49182
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Virtual for when a monster first acquires a target
That would trigger too late in most cases.
-
- Posts: 1606
- Joined: Mon Jun 12, 2017 12:57 am
Re: Virtual for when a monster first acquires a target
Maybe then, instead of "virtual void OnTargetAcquiring() = 0;", it have more sense to split tick into separate functions, exposed to zscript? Something like, unordered,
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?
Code: Select all
AActor::Tick()
{
//exposed to zscript
AdvanceState();
HandleCollision();
HandlePowerups();
BotThink();
other stuff
//still internal
UpdateRenderList();
}
Or performance degradation will be too big in this case?
-
- Lead GZDoom+Raze Developer
- Posts: 49182
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Virtual for when a monster first acquires a target
AActor::Tick() is not the correct place for this. You would want to have the callback somewhere in A_Look.
-
- Posts: 13789
- Joined: Tue Jan 13, 2004 1:31 pm
- Preferred Pronouns: She/Her
Re: Virtual for when a monster first acquires a target
@ 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.
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.
-
- Posts: 9696
- Joined: Sun Jan 04, 2004 5:37 pm
- Preferred Pronouns: They/Them
- Operating System Version (Optional): Debian Bullseye
- 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
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.
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.