MantisBT - Zandronum
View Issue Details
0001798Zandronum[All Projects] Suggestionpublic2014-05-09 08:132024-03-01 17:50
Hypnotoad 
Kaminsky 
normalfeaturehave not tried
resolvedfixed 
 
3.13.1 
0001798: Method to track when damage is dealt from players to other players (and monsters?)
Water and Tor suggested I make a new ticket for this in the EVENT script type thread, so here I am. As I said in the thread, something like this could be very useful for various mods as there is currently no reliable way to track which player inflicted damage on another player. I gave the example of my freezetag mod, where players are frozen when they are damaged by the freezegun rifle, but since I cannot reliably track which player shot him I cannot award frags or points based on this, therefore the gamemode is without a frag count causing gameplay to suffer. It was mentioned in the EVENT script thread as a possible other event type called each time a player is damaged which sends arguments about the attacker, but there was concern over spam as the event would be called incredibly often. Still, I cannot think of a better/more straightforward way of implementing this than via an event type.
No tags attached.
related to 0001794closed Torr Samaho New script type EVENT 
related to 0001330feedback  When you die in TLMS, any projectile that was yours becomes server's 
Issue History
2014-05-09 08:13HypnotoadNew Issue
2014-05-09 09:08DuskRelationship addedrelated to 0001794
2014-05-09 13:38WatermelonNote Added: 0008753
2014-05-09 13:38WatermelonRelationship addedrelated to 0001330
2014-05-09 13:39WatermelonNote Edited: 0008753bug_revision_view_page.php?bugnote_id=8753#r4738
2014-05-09 15:06ZzZomboNote Added: 0008760
2014-06-15 16:38WatermelonStatusnew => acknowledged
2014-06-27 21:21Ijon TichyNote Added: 0009764
2014-12-12 03:33DuskAssigned To => Dusk
2014-12-12 03:33DuskStatusacknowledged => assigned
2014-12-12 03:37DuskNote Added: 0011053
2014-12-12 03:38DuskNote Edited: 0011053bug_revision_view_page.php?bugnote_id=11053#r6138
2014-12-12 16:17DuskNote Edited: 0011053bug_revision_view_page.php?bugnote_id=11053#r6139
2014-12-12 16:18DuskNote Edited: 0011053bug_revision_view_page.php?bugnote_id=11053#r6140
2014-12-12 16:19DuskNote Edited: 0011053bug_revision_view_page.php?bugnote_id=11053#r6141
2015-03-22 17:35HypnotoadNote Added: 0011870
2015-03-22 18:27Konar6Note Added: 0011873
2015-03-22 19:06StrikerMan780Note Added: 0011874
2015-03-22 19:10StrikerMan780Note Edited: 0011874bug_revision_view_page.php?bugnote_id=11874#r6821
2015-12-05 15:16Torr SamahoNote Added: 0013933
2015-12-05 15:17Torr SamahoAssigned ToDusk => Torr Samaho
2015-12-05 15:17Torr SamahoStatusassigned => feedback
2015-12-05 15:30HypnotoadNote Added: 0013934
2015-12-05 15:30HypnotoadStatusfeedback => assigned
2015-12-05 15:37Torr SamahoNote Added: 0013935
2015-12-08 23:23StrikerMan780Note Added: 0013948
2015-12-08 23:24StrikerMan780Note Edited: 0013948bug_revision_view_page.php?bugnote_id=13948#r8300
2015-12-09 07:27Torr SamahoNote Added: 0013949
2015-12-09 16:36HypnotoadNote Added: 0013950
2015-12-09 16:41HypnotoadNote Edited: 0013950bug_revision_view_page.php?bugnote_id=13950#r8302
2015-12-09 16:53HypnotoadNote Added: 0013951
2015-12-09 16:54HypnotoadNote Deleted: 0013951
2015-12-09 17:09HypnotoadNote Added: 0013952
2015-12-29 02:17StrikerMan780Note Added: 0014024
2015-12-29 02:19StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8360
2015-12-29 18:12StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8361
2015-12-29 18:14StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8362
2015-12-29 18:15StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8363
2015-12-29 18:35StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8364
2015-12-29 18:40StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8365
2015-12-29 18:49StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8366
2015-12-29 18:50StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8367
2015-12-29 18:51StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8368
2015-12-29 18:52StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8369
2015-12-29 19:01StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8370
2015-12-29 19:02StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8371
2015-12-29 19:05StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8372
2015-12-29 19:07StrikerMan780Note Edited: 0014024bug_revision_view_page.php?bugnote_id=14024#r8373
2015-12-30 19:27Torr SamahoNote Added: 0014025
2015-12-30 19:28Torr SamahoNote Edited: 0014025bug_revision_view_page.php?bugnote_id=14025#r8375
2015-12-30 19:38CatastropheNote Added: 0014026
2015-12-30 19:39CatastropheNote Edited: 0014026bug_revision_view_page.php?bugnote_id=14026#r8377
2015-12-30 19:57Torr SamahoNote Added: 0014027
2015-12-30 21:15StrikerMan780Note Added: 0014030
2015-12-30 21:18StrikerMan780Note Edited: 0014030bug_revision_view_page.php?bugnote_id=14030#r8379
2015-12-30 23:51HypnotoadNote Added: 0014031
2016-02-22 04:37StrikerMan780Note Added: 0014474
2016-02-22 11:48DuskNote Deleted: 0014474
2016-06-14 01:11StrikerMan780Note Added: 0015080
2016-06-14 01:14StrikerMan780Note Edited: 0015080bug_revision_view_page.php?bugnote_id=15080#r9135
2016-06-14 01:20StrikerMan780Note Edited: 0015080bug_revision_view_page.php?bugnote_id=15080#r9136
2016-06-14 01:25StrikerMan780Note Edited: 0015080bug_revision_view_page.php?bugnote_id=15080#r9137
2016-06-14 01:25StrikerMan780Note Edited: 0015080bug_revision_view_page.php?bugnote_id=15080#r9138
2016-06-14 01:28StrikerMan780Note Edited: 0015080bug_revision_view_page.php?bugnote_id=15080#r9139
2016-06-14 01:28StrikerMan780Note Edited: 0015080bug_revision_view_page.php?bugnote_id=15080#r9140
2016-06-14 01:29StrikerMan780Note Edited: 0015080bug_revision_view_page.php?bugnote_id=15080#r9141
2016-06-14 01:29StrikerMan780Note Edited: 0015080bug_revision_view_page.php?bugnote_id=15080#r9142
2016-06-14 01:32StrikerMan780Note Edited: 0015080bug_revision_view_page.php?bugnote_id=15080#r9143
2021-12-05 14:26KaminskyNote Added: 0021851
2021-12-05 14:26KaminskyAssigned ToTorr Samaho => Kaminsky
2021-12-05 14:26KaminskyStatusassigned => needs testing
2024-03-01 17:50Ru5tK1ngNote Added: 0023178
2024-03-01 17:50Ru5tK1ngStatusneeds testing => resolved
2024-03-01 17:50Ru5tK1ngResolutionopen => fixed
2024-03-01 17:50Ru5tK1ngFixed in Version => 3.1
2024-03-01 17:50Ru5tK1ngTarget Version => 3.1

Notes
(0008753)
Watermelon   
2014-05-09 13:38   
(edited on: 2014-05-09 13:39)
I like the idea, there's a few things that need discussing:



- There is always a worry of EVENT being spammed. One mod for example would maybe shoot 200 pellets per tic and against a 15000+ health opponent would generate a ton of ACS scripts on the stack to manage. I have no idea if that'd drag the engine to a crawl or not.

One possible solution would be to have each player record the damage taken overtime, the damage taken in the last tic, and the damage in the last tic for each player. This however doesn't solve the 'who shot me'.

Therefore: a solution for that without going through events is to push a player/damageamount into a stack that is wiped every tic, and ACS could access that.


- Reflection needs to be handled better. Right now there is no reliable way (unless zdoom upgrades did something or there was an update I missed) to see who originally fired it. I ran into this problem when checking if a Sjas in GVH reflected a projectile to kill an enemy team member.


- What happens in this case?
'http://zandronum.com/tracker/view.php?id=1330 [^]'



Will need thoughts on that before continuing, this is a cool idea I'd want to do.

(0008760)
ZzZombo   
2014-05-09 15:06   
How to handle indirect attacks? Projectiles and explosions from exploded barrels come in mind. I propose to set the attacker to the latest attacker in the chain because mod can check then if it's a projectile, then treat it as damage dealt by its owner, and if it was a barrel when we must preserve its attacker somewhere in the script and then check it, however, I'm not sure how to actually to save such information, because TIDs aren't useful to represent attackers, because there are possibilities of having duplicate TIDs. Perhaps utilize "net ID" of the thing somehow? It is unique for each thing.
(0009764)
Ijon Tichy   
2014-06-27 21:21   
Copypasting from the forum and elaborating:
"An event that fires whenever a player deals damage, running on the actor taking damage with the player number being passed as an argument, along with the damage done, would be much more useful, and would allow for much more accurate damage tracking - perfect for all the RPG mods that crop up.

It would probably be better if the events got batched up into one call (eg. an SSG blast only sends one damage event per monster hit, rather than one per pellet), rather than every single projectile, explosion, hitscan, etc getting its own event."

The arguments for this event would be (GAMEEVENT_DAMAGEDEALT, playerNumber, damageDealt).

So, in other words, what would happen in a fairly complex example (SSG is fired, and two rockets hit a monster, in the same tic) is:

1. Player 2 fires SSG at monster.
2. Monster gets hit with, say, 12 pellets because player 2 can't aim. Or the monster was in medium range. Whatever.
3. Monster takes 95 damage, with the pellets doing {5, 5, 15, 10, 10, 5, 10, 5, 10, 5, 5, 10} damage.
4. In the same tic, for some reason, a rocket from player 2 and a rocket from player 1 hits the monster. Rocket 2 does 148 damage, rocket 1 does 268 damage.
5. At the end of the tic, event scripts for damage get fired off. This monster has taken a total of 243 damage from player 2, and a total of 268 damage from player 1, so two events get fired off - one with argument set (GAMEEVENT_DAMAGEDEALT, 2, 243), and one with argument set (GAMEEVENT_DAMAGEDEALT, 1, 268).
6. The event scripts are fired off, both of them running on the monster that was damaged, and they handle them as they will.

This way, we know both that X damage was dealt, that player N did the damage, and to which actor the damage was dealt. It's also batched up, keeping script calls at a minimum.
(0011053)
Dusk   
2014-12-12 03:37   
(edited on: 2014-12-12 16:19)
This was discussed on IRC and the following points were made:
- the system described in ijon's post is not what we want. The new event is to fire whenever damage is dealt (i.e. whenever P_DamageMobj is called and not negated)
- is to happen for all actors, not just for players but for non-players too
- if the damage source was null (e.g. slime), the activator shalt be the world
- the source shall be the activator, the victim shall be accessible in the script through some other means, possibly through an AAPTR_ static selector which is only valid in this script type. I have no idea what to do with the inflictor though, would it be a good idea to expose it? Is ACS currently capable enough to do anything useful with the inflictor field, e.g. able to tell is an actor an exploding missile or puff, etc..?
- if we REALLY are concerned about optimization, perhaps this should be a new script type entirely, however there's no reason to only report cumulated damage

(0011870)
Hypnotoad   
2015-03-22 17:35   
Any news on this?
(0011873)
Konar6   
2015-03-22 18:27   
No, just your bump.
(0011874)
StrikerMan780   
2015-03-22 19:06   
(edited on: 2015-03-22 19:10)
I strongly support this, this would allow my damage counter mod to be improved greatly. (Such as displaying damage only to the inflicter, rather than everyone, etc.)

(0013933)
Torr Samaho   
2015-12-05 15:16   
Here is a first shot at this. The event GAMEEVENT_ACTOR_DAMAGED is triggered when an actor receives damage. The activator is the source of the damage, dataOne is amount of damage received (may exceed the remaining health of the target), dataTwo is the tid of the target. The current version is mainly intended as a test to see whether the performance hit of the event spam is negligible or not. Please let me know how it performs.
(0013934)
Hypnotoad   
2015-12-05 15:30   
Awesome, I will test this when I get time (might not be able to test for a few days though I'm afraid). Do I need a special version of ACC?
(0013935)
Torr Samaho   
2015-12-05 15:37   
No, GAMEEVENT_ACTOR_DAMAGED triggers EVENT scripts exactly like the existing events. Looking forward to your feedback!
(0013948)
StrikerMan780   
2015-12-08 23:23   
(edited on: 2015-12-08 23:24)
Does it trigger for every pellet that hits the target, or does it fire once for that tic? (Showing total damage caused) And by the source of the damage, do you mean it's the player who did the damage, the projectile, or the actor being damaged?

(0013949)
Torr Samaho   
2015-12-09 07:27   
It follows closely the results dev meeting results summarized in 0001798:0011053, i.e. it fires every time P_DamageMobj is called. So, in your example, it fires for every pellet. The source is what P_DamageMobj calls the source, not the inflictor. Here is ZDoom's source comment on P_DamageMobj:

/*
=================
=
= P_DamageMobj
=
= Damages both enemies and players
= inflictor is the thing that caused the damage
= creature or missile, can be NULL (slime, etc)
= source is the thing to target after taking damage
= creature or NULL
= Source and inflictor are the same for melee attacks
= source can be null for barrel explosions and other environmental stuff
==================
*/
(0013950)
Hypnotoad   
2015-12-09 16:36   
(edited on: 2015-12-09 16:41)
I've just remembered that I've always been using BCC to use event scripts, so I need to update its files with the value for the constant GAMEEVENT_ACTOR_DAMAGED. Incidentally I can't find anywhere in your ACC source where these values are defined:'https://bitbucket.org/Torr_Samaho/acc/overview [^]'

edit: well I seem to have figured out its value is 8

(0013952)
Hypnotoad   
2015-12-09 17:09   
Testing and everything seems to work well so far with no noticeable performance hit, but my testing has been limited to offline bot deathmatches, where I'm just printing to console every instance of damage and all the data associated. I haven't tested this online yet.

Would it be possible to have a third variable, which gives data about the target which isn't a tid for actors which don't have an assigned tid (for instance for monsters, it could give the name of the actor, or its spawn ID, or its DoomED number or some other kind identification)?
(0014024)
StrikerMan780   
2015-12-29 02:17   
(edited on: 2015-12-29 19:07)
Fires for every pellet? Damn... so it's impossible to tally up total damage for a shotgun blast. (For the purposes of showing the damage you done in your last shot on the HUD.)

How about have P_DamageMobj push the data for each damaged target to an array/struct that's wiped each tic of the gameloop. (Storing the sources and the total damage they dealt that tic) Just before wiping the values, have the game check if the data isn't null, and fire ACS Events for each valid source source if so. It would stop EVENT spam for sure, and would already tally up the damage done for that tic. I imagine this would be much faster too.

Also, set the activator to the damaged thing. (Which would allow people to get data on monsters that lack TIDs) Then, replace the TID parameter with a pointer to the source. A new ACS function to set the activator to said pointer would allow people to get info on the shooter. (Such a thing could be useful for future event types too.)

(0014025)
Torr Samaho   
2015-12-30 19:27   
(edited on: 2015-12-30 19:28)
Quote from Hypnotoad
Would it be possible to have a third variable, which gives data about the target which isn't a tid for actors which don't have an assigned tid (for instance for monsters, it could give the name of the actor, or its spawn ID, or its DoomED number or some other kind identification)?

So far EVENT scripts are limited to two arguments and I'd like to keep it that way if possible.

Quote from StrikerMan780

Damn... so it's impossible to tally up total damage for a shotgun blast. (For the purposes of showing the damage you done in your last shot on the HUD.)

Why can't you sum the damage up yourself in ACS?

Quote from StrikerMan780

How about have P_DamageMobj push the data for each damaged target to an array/struct that's wiped each tic of the gameloop.

This was discussed above, cf. 0001798:0009764. With the current way, you get much more information.

Quote from StrikerMan780

Also, set the activator to the damaged thing. (Which would allow people to get data on monsters that lack TIDs) Then, replace the TID parameter with a pointer to the source. A new ACS function to set the activator to said pointer would allow people to get info on the shooter. (Such a thing could be useful for future event types too.)

I see the point in replacing the TID with a pointer (do you have any similar ZDoom function in mind that already does something like this?), but why should the activator be switched? What you gain on the damaged thing, you'll lose on the source.

(0014026)
Catastrophe   
2015-12-30 19:38   
(edited on: 2015-12-30 19:39)
>Why can't you sum the damage up yourself in ACS?

What if a player fires a rocket, switches to the SSG, and fires it at the same time the rocket explodes on the same target (ie a Cyberdemon) resulting in the SSG damage being done in the exact same tic as the Rocket damage? Wouldn't that make it impossible to check the damage done for the entire shotgun blast in that occurrence?

(0014027)
Torr Samaho   
2015-12-30 19:57   
Yes, to distinguish the rocket damage from the SSG damage under these rare circumstances, you would also need access to the inflictor. But this won't be possible without having a third argument.
(0014030)
StrikerMan780   
2015-12-30 21:15   
(edited on: 2015-12-30 21:18)
"What you gain on the damaged thing, you'll lose on the source."

Not if it's a pointer to the source that you could set as the activator with a function.

There's currently a similar function called SetActivatorToTarget, but perhaps we need something like SetActivatorToThing. The first parameter being a unique reference to a "thing" on the map. (Regardless of TID)

People in IRC were suggesting this ought to be a new "DAMAGE" acs script, to prevent spam and clogging of whatever main EVENT script that may be in a mod. Both for performance and management reasons. It'd also free up an argument.

(0014031)
Hypnotoad   
2015-12-30 23:51   
>So far EVENT scripts are limited to two arguments and I'd like to keep it that way if possible.

I see, hopefully Striker's pointer suggestion will work then. I think to get the most use out of this function it's important to be able to get more than just the tid of the target (so it can be used with monsters), but I'm not too fussed on how it is implemented technically.

As for information on the inflcitor, I imagine that too would be important for RPG mods.
(0015080)
StrikerMan780   
2016-06-14 01:11   
(edited on: 2016-06-14 01:32)
I agree with the others in IRC and strongly suggest going with the DAMAGE script type idea, simply for the sake of code cleanliness/performance, the extra available argument, and less confusion. Hopefully development of this feature will continue, the incredible usefulness of this could open up new possibilities in mods.

First argument: name of inflictor as a string. Usually the classname of a weapon, projectile, or monster, depending on the source.
Second argument: pointer to victim.
Third argument: pointer to attacker.

And as suggested before, in P_DamageMobj, queue up the damage per-inflictor in a struct, to be processed and flushed at the end of the tic.

I hope this is a viable way of doing it.

(0021851)
Kaminsky   
2021-12-05 14:26   
3.1 adds the EVENT types GAMEEVENT_ACTOR_DAMAGED and GAMEEVENT_ACTOR_ARMORDAMAGED, giving modders ways to track damage dealt with any actor including players and monsters. More information on their use can be found here:'https://wiki.zandronum.com/EVENT_scripts [^]'
(0023178)
Ru5tK1ng   
2024-03-01 17:50   
As far as I know these have been working as intended since 3.1