Virtualize all canonical monster-specific attacks
Moderator: GZDoom Developers
- Matt
- 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
- Contact:
Virtualize all canonical monster-specific attacks
e.g., A_CPosAttack, A_TroopAttack, A_SargAttack, etc.
It's kind of a pain to redefine a vanilla monster's entire missile state if all you want to do is make it shoot a different kind of missile (or a missile at all if you're editing a hitscanner). It also creates more room for bloat or error in case you copypasted from an obsolete source or misremembered the timing or something.
Way back in the day this was partially possible with the projectile monsters where you'd use "missiletype" to get the imp to shoot a baron ball without redefining the state.
It's kind of a pain to redefine a vanilla monster's entire missile state if all you want to do is make it shoot a different kind of missile (or a missile at all if you're editing a hitscanner). It also creates more room for bloat or error in case you copypasted from an obsolete source or misremembered the timing or something.
Way back in the day this was partially possible with the projectile monsters where you'd use "missiletype" to get the imp to shoot a baron ball without redefining the state.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49067
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Virtualize all canonical monster-specific attacks
Cannot be done, these functions are off limits due to Dehacked.
Re: Virtualize all canonical monster-specific attacks
I was wondering about this too, it did used to be much easier to swap an enemy's missile type out with another.
Instead of hard-coding the missile type in the various attack functions, couldn't they refer to some class member instead, which could be easily changed?
In fact, couldn't missiletype be un-deprecated, and instead of having things like `SpawnMissile(targ, "DoomImpBall")` in gzdoom.pk3, you'd have `SpawnMissile(targ, missiletype)`?
Or, if it's not wanted in Actor, maybe it could be done on the individual monsters, following a convention where the same name (projectiletype?) would be used across all monsters who fire projectiles.
Instead of hard-coding the missile type in the various attack functions, couldn't they refer to some class member instead, which could be easily changed?
In fact, couldn't missiletype be un-deprecated, and instead of having things like `SpawnMissile(targ, "DoomImpBall")` in gzdoom.pk3, you'd have `SpawnMissile(targ, missiletype)`?
Or, if it's not wanted in Actor, maybe it could be done on the individual monsters, following a convention where the same name (projectiletype?) would be used across all monsters who fire projectiles.
- Arctangent
- Posts: 1235
- Joined: Thu Nov 06, 2014 1:53 pm
- Contact:
Re: Virtualize all canonical monster-specific attacks
That'd not only be far worse for DeHackEd support, but also mod support for mods made for literally every prior version of ZDoom ever.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49067
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Virtualize all canonical monster-specific attacks
Because it'd break pretty much everything out there that thinks that the projectile type is an explicit parameter. An option would be to allow passing some placeholder parameter to projectile attack functions that falls back on the MissileType property.
Re: Virtualize all canonical monster-specific attacks
I guess I'd need to see an example of something like that. I'd imagine if you changed a DoomImpBall to, say, a PlasmaBall, via MissileType, in the doom imp's missile-throwing function, and also a dehacked mod switched, say, cacodemon's missile codepointer out for the doom imp's, then the caco would throw PlasmaBalls, right? So both mods got the behavior they wanted, in a way; I'd think that's expected behavior?
Or do you mean it would break individual dehacked mods, just by virtue of it not being hard-coded, even if no other mod changed that value to something else? If so, I don't really understand why.
Just to be clear, I'm not talking about bringing the *old* MissileType behavior back for all calls to those functions somehow, I'm just talking about using it (or something new, with a new name) for the calls in those functions in question in the OP.
Or do you mean it would break individual dehacked mods, just by virtue of it not being hard-coded, even if no other mod changed that value to something else? If so, I don't really understand why.
Just to be clear, I'm not talking about bringing the *old* MissileType behavior back for all calls to those functions somehow, I'm just talking about using it (or something new, with a new name) for the calls in those functions in question in the OP.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49067
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Virtualize all canonical monster-specific attacks
The default actors are entirely off limits here. I will not change how they work.
Re: Virtualize all canonical monster-specific attacks
Just to be clear, this is all I'm suggesting:
Not to press the issue, but I'm not entirely sure I was clear about what I'm suggesting here.
I suppose on the dehacked end, you'd need something akin to bound functions, where the dehacked version of A_TroopAttack is inherently bound to a default DoomImp. But I assume that's not outside the realm of possibility?
Code: Select all
--- doomimp.zs
+++ doomimp2.zs
@@ -22,6 +22,7 @@
HitObituary "$OB_IMPHIT";
Obituary "$OB_IMP";
Tag "$FN_IMP";
+ MissileType "DoomImpBall"; // or call it ProjectileType?
}
States
{
@@ -118,7 +119,7 @@
else
{
// launch a missile
- SpawnMissile (targ, "DoomImpBall");
+ SpawnMissile (targ, MissileType);
}
}
}
I suppose on the dehacked end, you'd need something akin to bound functions, where the dehacked version of A_TroopAttack is inherently bound to a default DoomImp. But I assume that's not outside the realm of possibility?
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49067
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Virtualize all canonical monster-specific attacks
I understand what you are suggesting, but that doesn't work. What about the case where you give this code pointer to an Arachnotron or (god beware!) to a torch?
Re: Virtualize all canonical monster-specific attacks
Hmm, I was sort of hoping something like `invoker.MissileType` might work, where invoker could be set to a default DoomImp for dehacked, but would be the same as `self` during the normal course of events, but I just checked and `invoker` isn't recognized there... so I guess this isn't as easy as I hoped.
- Arctangent
- Posts: 1235
- Joined: Thu Nov 06, 2014 1:53 pm
- Contact:
Re: Virtualize all canonical monster-specific attacks
There's also the issue that this would break any DeHackEd patch or early DECORATE lump that, say, gives the arachnotron attack pointer to an imp to make it launch plasma instead of a fireball. If all regular attack functions instead just used MissileType, then the imp would have a MissileType of DoomImpBall, causing A_BspiAttack to launch that instead of the arachotron's plasma.
Re: Virtualize all canonical monster-specific attacks
But isn't that the issue you were referring to in the first place?
I guess this is my misunderstanding of the language. I thought we had, in effect, two different `this` keywords/pointers: `self` and `invoker`.
I thought this could be leveraged to partially bind a function to two different objects... in other words, that `invoker.MissileType` would mean the same thing as `self.missileType` in the general case, but that `invoker` could be bound to a default DoomImp (for example) in the dehacked case. But I see now that invoker is something other than a regular keyword, since it doesn't work at all there. So I'm not sure if this is actually possible at all, or how much trouble it would be to get it working.
One thing's for sure, it used to be a lot easier to switch out missile types. What has to happen now is the attack function needs to be copied entirely, just to change that one string, and part of the state block needs to be copied as well, in order to call the new function. The old way of simply setting `missiletype "plasmaball"` seemed much cleaner, and it would be nice to be able to have something like that again.
I guess this is my misunderstanding of the language. I thought we had, in effect, two different `this` keywords/pointers: `self` and `invoker`.
I thought this could be leveraged to partially bind a function to two different objects... in other words, that `invoker.MissileType` would mean the same thing as `self.missileType` in the general case, but that `invoker` could be bound to a default DoomImp (for example) in the dehacked case. But I see now that invoker is something other than a regular keyword, since it doesn't work at all there. So I'm not sure if this is actually possible at all, or how much trouble it would be to get it working.
One thing's for sure, it used to be a lot easier to switch out missile types. What has to happen now is the attack function needs to be copied entirely, just to change that one string, and part of the state block needs to be copied as well, in order to call the new function. The old way of simply setting `missiletype "plasmaball"` seemed much cleaner, and it would be nice to be able to have something like that again.
- Matt
- 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
- Contact:
Re: Virtualize all canonical monster-specific attacks
My original suggestion had been in hopes of making something simpler and intuitively consistent with how a lot of other ZS stuff works, but this is all starting to sound awfully complicated and arbitrary-exception-reliant - and based on stuff that, in my opinion as a modder, was deprecated for some very good reasons.
In particular:
In particular:
It stops being remotely clean the instant you have a monster capable of multiple projectile types.The old way of simply setting `missiletype "plasmaball"` seemed much cleaner
Re: Virtualize all canonical monster-specific attacks
Well, it stops being useful altogether, and you have to go back to hardcoding string literals into your attack function. I don't see why it becomes any less clean for the single-projectile monsters (which basically all vanilla monsters are, as far as I know).
I think you'd concede that, for single-missile monsters, it's more clean than copying a usually 50+ line function, renaming it, changing one string, and copying part of a state block so you can call your copied function, no?
I think you'd concede that, for single-missile monsters, it's more clean than copying a usually 50+ line function, renaming it, changing one string, and copying part of a state block so you can call your copied function, no?