Global & Per-Actor (inheritable) Death Scripts

Moderator: GZDoom Developers

User avatar
StrikerMan780
Posts: 486
Joined: Tue Nov 29, 2005 2:15 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Global & Per-Actor (inheritable) Death Scripts

Post by StrikerMan780 »

I've finally implemented Death Scripts. They allow a modder to specify global and per-actor ACS scripts that fire on death of killable actors (both monsters and shootable non-monsters). This allows several new possibilities, such as universal (compatible with nearly any mod) EXP systems, mutators, and guaranteeing that a script will fire on death regardless of how they die or what death state they entered. Death scripts are also inherited from parent actors, allowing one to have multiple enemies that share the same script without having to call a script in every single enemy's death state.

https://github.com/coelckers/gzdoom/pull/59

Here's a Build with this feature and a test PK3 showing how each function is used (prepare for chaos!): http://www.mediafire.com/download/caix4 ... s_Test.zip

Here's some information on the properties and flags.
Decorate:

Code: Select all

Properties:
DeathScript "Script Name", arg1, arg2, arg3, arg4 // Death script for actor and it's args.

Setting the script name to "Default" forces the actor to use the default death script, useful when inheriting from an actor that uses a non-default death script.
Setting the script name to "None" makes the actor not fire any death scripts whatsoever, as long as +BOTHDEATHSCRIPTS hasn't been defined.

Action Functions:
A_SetDeathScript("Script Name") // Sets the actor's death script
A_SetDeathScriptArg(int pos, int value) // Sets the actor's death script args
A_SetDefaultDeathScriptArg(int pos, int value, bool clear) // Overrides the default death script args, if clear is true, value is ignored and the override is removed.

Flags:
+BOTHDEATHSCRIPTS // Makes the actor fire both it's own death script, and the global default.
MapInfo (GameInfo block):

Code: Select all

DefaultDeathScript = "Script Name", arg1, arg2, arg3, arg4 // Sets a default death script to fire for killable objects (monsters/shootables) without a death script defined.
Currently only supports named scripts, because I couldn't figure out how to have it take either a string or integer interchangeably without making a mess. Named scripts should be used for something like this anyway, and if one *really* needs to fire a numbered script, they can do it from their named script.

The default death script fires for all objects that can be shot and killed. Not just monsters. If you want to have your script not do anything for non-monsters, do a CheckFlag(0, "ISMONSTER"); check in your ACS Script.
Last edited by StrikerMan780 on Mon Jul 18, 2016 1:47 pm, edited 1 time in total.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49230
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Global & Per-Actor (inheritable) Death Scripts

Post by Graf Zahl »

A_SetDeathScript("Script Name") // Sets the actor's death script
A_SetDeathScriptArg(int pos, int value) // Sets the actor's death script args
A_SetDefaultDeathScriptArg(int pos, int value, bool clear) // Overrides the default death script args, if clear is true, value is ignored and the override is removed.
Isn't that a bit too much micromanagement or do you have a clear use case where you may want to change a single arg at runtime? Normally a single

A_SetDeathScript("name", arg1, arg2, arg3) should be enough, I think.
User avatar
arookas
Posts: 265
Joined: Mon Jan 24, 2011 6:04 pm
Contact:

Re: Global & Per-Actor (inheritable) Death Scripts

Post by arookas »

Since there is no map number specified for any of these scripts, would it be possible for the parameter count be bumped up to four (a la ExecuteWithResult)?
Gez
 
 
Posts: 17943
Joined: Fri Jul 06, 2007 3:22 pm

Re: Global & Per-Actor (inheritable) Death Scripts

Post by Gez »

Can't script have up to five args?
User avatar
StrikerMan780
Posts: 486
Joined: Tue Nov 29, 2005 2:15 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Global & Per-Actor (inheritable) Death Scripts

Post by StrikerMan780 »

Graf Zahl wrote:
A_SetDeathScript("Script Name") // Sets the actor's death script
A_SetDeathScriptArg(int pos, int value) // Sets the actor's death script args
A_SetDefaultDeathScriptArg(int pos, int value, bool clear) // Overrides the default death script args, if clear is true, value is ignored and the override is removed.
Isn't that a bit too much micromanagement or do you have a clear use case where you may want to change a single arg at runtime? Normally a single

A_SetDeathScript("name", arg1, arg2, arg3) should be enough, I think.
The micromanagement is in-case if someone wants to change one arg without altering the others, in cases of inheritance, or if the modder wants to track a single stat while keeping other information intact. It also matches the syntax of A_SetArg.
Being able to override the default args is if you want to send some different information to the script you have globally defined. (Say if you use the default script for handling experience points, but want to override the amount of EXP for a single monster, or tell the script this monster is in a special kind of state and perform actions based on such. It's also useful if your mod doesn't have a default script of it's own, but is an add-on for another mod that does, and you want to change something without affecting the other args.)

I want this to be as flexible as possible so people can use it in whatever way they please. For basic stuff, those functions can mostly be ignored, but they are there if someone wants to make more complex mechanics.
Arookas wrote:Since there is no map number specified for any of these scripts, would it be possible for the parameter count be bumped up to four (a la ExecuteWithResult)?
No, because the function still still takes a map number internally, which is set to 0. See: http://puu.sh/q5PUz/1ce112f76f.png
Gez wrote:Can't script have up to five args?
No, it's always been three. You're thinking of action specials. Script name and map are already two args, leaving 3 for the script.
Last edited by StrikerMan780 on Mon Jul 18, 2016 11:16 am, edited 5 times in total.
Gez
 
 
Posts: 17943
Joined: Fri Jul 06, 2007 3:22 pm

Re: Global & Per-Actor (inheritable) Death Scripts

Post by Gez »

As Arookas said, [wiki]ACS_ExecuteWithResult[/wiki] allows to pass four arguments to the script. The limit of three arguments that can be passed through ACS_Execute is not the limit that a script can receive, since that limit is at least four.
User avatar
StrikerMan780
Posts: 486
Joined: Tue Nov 29, 2005 2:15 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Global & Per-Actor (inheritable) Death Scripts

Post by StrikerMan780 »

Gez wrote:As Arookas said, [wiki]ACS_ExecuteWithResult[/wiki] allows to pass four arguments to the script. The limit of three arguments that can be passed through ACS_Execute is not the limit that a script can receive, since that limit is at least four.
See: http://puu.sh/q5PUz/1ce112f76f.png

The limit is three. Unless someone is willing to create a new ACS command that is essentially ACS_ExecuteAlways without a map parameter, this is all I can do.

(ACS_ExecuteWithResult is useless here, since we're not retrieving a result, and creating a new function requires modifying both (G)ZDoom and ACC.)
User avatar
NeuralStunner
 
 
Posts: 12328
Joined: Tue Jul 21, 2009 12:04 pm
Preferred Pronouns: No Preference
Operating System Version (Optional): Windows 11
Graphics Processor: nVidia with Vulkan support
Location: capital N, capital S, no space
Contact:

Re: Global & Per-Actor (inheritable) Death Scripts

Post by NeuralStunner »

Still, this feature is specifically for running a script, not a special. You might be better off using P_StartScript. (This is all ACS_Execute* are doing to begin with, why go through the extra step that's only reducing capabilities?) You can also force the activator to the thing that's dying in all circumstances, because it makes the most sense for the feature. (Activator's target would always be the killer, as well.)
User avatar
StrikerMan780
Posts: 486
Joined: Tue Nov 29, 2005 2:15 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Global & Per-Actor (inheritable) Death Scripts

Post by StrikerMan780 »

P_StartScript doesn't exist according to Visual Studio.

Which file must I #include to get access to it?

EDIT: p_spec.h.

Working on changing to it.

Done, just need to test before committing it. It'll take 4 arguments now. Couldn't go any higher since ACC errors if you have more than 4 args for a script. That's a hard limit.
User avatar
StrikerMan780
Posts: 486
Joined: Tue Nov 29, 2005 2:15 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Global & Per-Actor (inheritable) Death Scripts

Post by StrikerMan780 »

Updated the pull request. Switched from P_ExecuteSpecial to P_StartScript, and added a fourth argument.

EDIT: Fixed a bug where you'd get undefined behavior/crazy numbers for args if you left them out in the DeathScript property.

Penny for anyone's thoughts now that I've made said adjustments?
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49230
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Global & Per-Actor (inheritable) Death Scripts

Post by Graf Zahl »

StrikerMan780 wrote: The micromanagement is in-case if someone wants to change one arg without altering the others, in cases of inheritance, or if the modder wants to track a single stat while keeping other information intact. It also matches the syntax of A_SetArg.
Being able to override the default args is if you want to send some different information to the script you have globally defined. (Say if you use the default script for handling experience points, but want to override the amount of EXP for a single monster, or tell the script this monster is in a special kind of state and perform actions based on such. It's also useful if your mod doesn't have a default script of it's own, but is an add-on for another mod that does, and you want to change something without affecting the other args.)
Well, sorry, but I call this clunky, not flexible.
If you need this kind of flexibility, there's better methods to use, e.g. actor variables that get passed to the script.
User avatar
StrikerMan780
Posts: 486
Joined: Tue Nov 29, 2005 2:15 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Global & Per-Actor (inheritable) Death Scripts

Post by StrikerMan780 »

Then do you suggest having it so you only specify the script, but no args, then getting rid of A_SetDeathScriptArgs? Then leave it up to the modder to check user variables?
User avatar
Xaser
 
 
Posts: 10774
Joined: Sun Jul 20, 2003 12:15 pm
Contact:

Re: Global & Per-Actor (inheritable) Death Scripts

Post by Xaser »

Removing the ability to specify args entirely doesn't make sense.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49230
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Global & Per-Actor (inheritable) Death Scripts

Post by Graf Zahl »

Graf Zahl wrote:Normally a single

A_SetDeathScript("name", arg1, arg2, arg3) should be enough, I think.
User avatar
NeuralStunner
 
 
Posts: 12328
Joined: Tue Jul 21, 2009 12:04 pm
Preferred Pronouns: No Preference
Operating System Version (Optional): Windows 11
Graphics Processor: nVidia with Vulkan support
Location: capital N, capital S, no space
Contact:

Re: Global & Per-Actor (inheritable) Death Scripts

Post by NeuralStunner »

Unless it also exposes the script & arguments as Decorate expressions, there's no way to change a single one without modifying the others.
Locked

Return to “Closed Feature Suggestions [GZDoom]”