New EVENT script types
I added some new EVENT types that people have requested in the past, and that modders could find useful.
1. GAMEEVENT_PLAYERCONNECT - Triggered when a client or bot joins the server. The activator is the world, arg1 is the ID of the player that connected, and arg2 is a boolean that indicates whether the client had previously connected to the server. This event is not triggered if the user starts a new singleplayer game (they should use OPEN scripts in those cases).
2. GAMEEVENT_ACTOR_SPAWNED - Triggered when an actor is spawned, strictly speaking, immediately before their first tic. The activator is the actor that spawned, no additional arguments passed. Note that due to the concern of potential performance drops of calling this event repeatedly, this event is disabled by default and modders will to enable it themselves, either by enabling the USESPAWNEVENTSCRIPT DECORATE flag on an actor (there's also a NOSPAWNEVENTSCRIPT flag if they want to force it off) or by adding "ForceSpawnEventScripts = true" in the GameInfo block in MAPINFO.
3. GAMEEVENT_ACTOR_DAMAGED - Triggered when an actor takes damage (i.e. when P_DamageMobj is called). This is my take on this old ticket on the tracker: https://zandronum.com/tracker/view.php?id=1798 with a few differences. The activator is the thing that received the damage and arg1 is the amount of damage received. Much like GAMEEVENT_ACTOR_SPAWNED, this event is disabled by default for performance reasons, so modders need to enable it by enabling the USEDAMAGEEVENTSCRIPT DECORATE flag on an actor (there's also a NODAMAGEEVENTSCRIPT flag) or by adding "ForceDamageEventScripts = true" in the GameInfo block.
I wanted there to be an easy way of accessing the source, inflictor, and target actors with GAMEEVENT_ACTOR_DAMAGED, in order to get all the information on each actor. Sending the source's TID as arg2 didn't seem useful enough, considering more likely than not the source's TID could be 0, and there wouldn't be a clear way of distinguishing whether the source was a thing or the world. Therefore, I added some new AAPTR_ constants that are only usable within the event script itself. The new constants are: AAPTR_DAMAGE_SOURCE, AAPTR_DAMAGE_INFLICTOR, and AAPTR_DAMAGE_TARGET.
The pointer method doesn't work in a CLIENTSIDE EVENT script, but I think it's reasonable to assume that modders aren't going to define such a script and use GAMEEVENT_ACTOR_SPAWNED or GAMEEVENT_ACTOR_DAMAGED at the same time, considering the server has to tell the clients to execute the script - that could cause spikes in network traffic.
EDIT: The AAPTR_ system is obsolete in the current GZDoom, but just in case I intentionally reserved the last three bits of a 32-bit integer for these new constants to leave plenty of room for additional constants. In fact, the only constant that's missing in Zandronum is AAPTR_GET_LINETARGET which was added to ZDoom about seven years ago.
Thanks for the patches! I'm very glad that you take performance precautions. Without those, I would have been very skeptical about the spawn and damage events. With your precautions, this looks viable. So I went ahead and added the patches.
I added some new patches. Particularly, GAMEEVENT_ACTOR_DAMAGED now uses arg2 to store a dynamic ACS string containing the damage type the target received.
Thanks! Both patches look good and I just added them.
I made one last change (10566.patch) with GAMEEVENT_ACTOR_DAMAGED, based on somebody's suggestion:
1. The event is now triggered JUST BEFORE the actor receives damage, rather than AFTER. This could be useful to modders who want to manipulate the actor before they take the damage.
2. It's now possible to modify how much damage the actor actually receives by changing the result value of the script during the first tic that it's run.
Basically, the damage amount can be overridden by the modder if they explicitly change the result value of the event script with SetResultValue. This only works for event scripts in which GAMEEVENT_ACTOR_DAMAGED is the event type. The result value is initialized to whatever the original damage amount was, and if there's more than one event script that changes the result value, whichever script that's executed last decides what the final damage is. This could be useful for mods that want to handle damage in their own unique ways, beyond the use of the damagefactor actor property or "PowerupProtection" items.
Thanks! I added the updated patch.