[still present in r3568] Incorrect pain conditions
Moderator: GZDoom Developers
Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
[still present in r3568] Incorrect pain conditions
Victim-flag NOPAIN takes precedence over FORCEPAIN (wiki states that the actor never enters pain state, and it is true for all positive damage). This is properly observed unless damage is reduced to 0 in such a manner that damage processing checks FORCEPAIN and either returns or triggers pain. When it does that, NOPAIN-checking is skipped. (I'm pretty sure this one is a bug.)
Is an attack that does 0 damage (declared, not modified) supposed to be able to cause pain without FORCEPAIN? Sometimes it looks that way, for most damage it would probably not happen. Especially not if damage factors are applied, since they goto forcepain/return if they result in 0 damage, even if there was 0 damage before and the damage factor was 1.0.
Also - and this might just be by design - entering pain-state has a post-processing that does not occur for the wound state. Since a wounded peasant is bound to die, it may be completely irrelevant to all original use, but if it is ever used for anything else than an extended death state, I'd expect it to work more like pain. (Wake up, try to target the perpetrator, basically everything pain does, just with the woundstate instead of a painstate.)
- The cleanest behaviour would seem to be that 0 damage does not cause pain without special flags, but is that compatible with previous behaviour?
- Does a pain threshold of 0 mean that more than 0 damage is required, or that at least 0 damage is required?
- NeuralStunner suggested (feature) a flag like ALWAYSPAIN to have painchances applying regardless of the amount of damage, without forcing pain. That would be nice, reliable and explicit.
(forcepain to cause pain always, alwayspain to process painchance always, painless never to cause pain, unspecified to process painchance for damage overcoming the pain threshold.)
Is an attack that does 0 damage (declared, not modified) supposed to be able to cause pain without FORCEPAIN? Sometimes it looks that way, for most damage it would probably not happen. Especially not if damage factors are applied, since they goto forcepain/return if they result in 0 damage, even if there was 0 damage before and the damage factor was 1.0.
Also - and this might just be by design - entering pain-state has a post-processing that does not occur for the wound state. Since a wounded peasant is bound to die, it may be completely irrelevant to all original use, but if it is ever used for anything else than an extended death state, I'd expect it to work more like pain. (Wake up, try to target the perpetrator, basically everything pain does, just with the woundstate instead of a painstate.)
- The cleanest behaviour would seem to be that 0 damage does not cause pain without special flags, but is that compatible with previous behaviour?
- Does a pain threshold of 0 mean that more than 0 damage is required, or that at least 0 damage is required?
- NeuralStunner suggested (feature) a flag like ALWAYSPAIN to have painchances applying regardless of the amount of damage, without forcing pain. That would be nice, reliable and explicit.
(forcepain to cause pain always, alwayspain to process painchance always, painless never to cause pain, unspecified to process painchance for damage overcoming the pain threshold.)
Re: [still present in r3568] Incorrect pain conditions
Unfortunately, that would not be compatible with previous behaviour. No-damage attacks have always been able to cause pain states (I think perhaps even going back to vanilla Doom) and this ability has been used in a number of mods for special effects of one type or another. I've used it myself. I'm sure that it was discussed some years ago, and at some length, and the outcome was that 0 damage attacks needed to be able to continue to cause pain and when no pain was required, the appropriate modifications by the mod author would have to be made to avoid the pain states being called in those circumstances.FDARI wrote:- The cleanest behaviour would seem to be that 0 damage does not cause pain without special flags, but is that compatible with previous behaviour?
- 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: [still present in r3568] Incorrect pain conditions
I've never seen a 0-damage attack cause pain, without using FORCEPAIN on the ainstigating attack. 
Re: [still present in r3568] Incorrect pain conditions
I've done a bit of digging around and I think I may have been remembering the discussion incorrectly. Both The Ultimate Doomer and myself had used 0 damage projectiles: TUD to force specific pain states and I used ripping projectiles (which caused pain states with 0 damage even though other projectiles did not) to force any actor into its pain state regardless of damage type. There may be other instances of it too. In fact, I'm sure that there was. However, the threads I found seem to indicate that the discussions did not turn out as I remembered them and the upshot of them was that such situations should have the +FORCEPAIN flag used.
This last post by Randy in one of the following threads is interesting however:
http://forum.zdoom.org/viewtopic.php?f=2&t=23982
I'm sure it was discussed elsewhere but that's all I'm coming up with ATM.
However, for all instances that I have just tried without FORCEPAIN, pain states were not caused by 0 damage attacks.
At one point, the "MonsterRail" BEX pointer could be given to enemies, set for 0 damage and still cause pain states. I'm absolutely certain of that. [edit] I just checked - it did way back in ZDoom 1.23 but doesn't any more.
[/edit]
I don't know if other 0 damage hitscan attacks could cause pain states in the past (I'm pretty sure they could) but I just tried a 0 damage custom hitscan attack fired by ZombieMen and they did not cause pain in each other or me, even though they are hitting each other many times with the attack that I defined.
So, to revise my earlier statement, I think that FDARI's desired "cleanest" behaviour of 0 damage attacks not causing pain unless they have the FORCEPAIN flag is how things seem to be working ATM and it is probably how it is meant to be working too.
This last post by Randy in one of the following threads is interesting however:
http://forum.zdoom.org/viewtopic.php?f=7&t=23981randy wrote:Referencing the original id Source, it should. I probably introduced this bug myself when I made negative missile damage do healing.Enjay wrote:From memory, being struck by a 0 damage projectile did not cause pain states.
http://forum.zdoom.org/viewtopic.php?f=2&t=23982
I'm sure it was discussed elsewhere but that's all I'm coming up with ATM.
However, for all instances that I have just tried without FORCEPAIN, pain states were not caused by 0 damage attacks.
At one point, the "MonsterRail" BEX pointer could be given to enemies, set for 0 damage and still cause pain states. I'm absolutely certain of that. [edit] I just checked - it did way back in ZDoom 1.23 but doesn't any more.
Code: Select all
#BEX
[CODEPTR]
FRAME 185 = MonsterRailI don't know if other 0 damage hitscan attacks could cause pain states in the past (I'm pretty sure they could) but I just tried a 0 damage custom hitscan attack fired by ZombieMen and they did not cause pain in each other or me, even though they are hitting each other many times with the attack that I defined.
So, to revise my earlier statement, I think that FDARI's desired "cleanest" behaviour of 0 damage attacks not causing pain unless they have the FORCEPAIN flag is how things seem to be working ATM and it is probably how it is meant to be working too.
- 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: [still present in r3568] Incorrect pain conditions
I would agree, though the occasional older mod might get stuck with non-functional features because of it. Might be wise to include some sort of compat flag...
Re: [still present in r3568] Incorrect pain conditions
Aaaand, I have found something in one of my projects that gets a (minor) break from this. In my Burghead mod there are sonic grenades that spew out invisible zero damage +forcepain projectiles in all directions for about 30 seconds. Any actor coming within the range of these projectiles is put in to their pain state so frequently that they are effectively immobilised. However, I didn't want the player to be constantly yelling in pain when he was near his own sonic grenades so I gave the projectiles a custom damage type and set the player to be immune to this kind of damage. It worked and the player didn't yell in pain when he was near the sonic grenade effect. Now he does. OK, it's only a minor aesthetic point and I'm not that bothered by it, but it's there.
I know that I could fix it by removing +forcepain from the projectiles and then giving every monster a very high susceptibility to sonic damage and the player very low susceptibility. However, editing every enemy just to make one actor (the player) behave differently does seem to be the wrong way around.
What I would suggest then is something like the +foilinvul flag but for +forcepain (+foilforcepain ?). I don't know if flags can work this way but being able to set this flag for different damage types would be even better. That way an actor could be immune to one type of forcepain missile but not any others that may exist.
Anyway, such a flag would be a much better solution to my (minor) problem. Instead of editing the projectile and every enemy in the game, I could just give the player the +foilforcepain flag and be done with it. Any chance?
I know that I could fix it by removing +forcepain from the projectiles and then giving every monster a very high susceptibility to sonic damage and the player very low susceptibility. However, editing every enemy just to make one actor (the player) behave differently does seem to be the wrong way around.
What I would suggest then is something like the +foilinvul flag but for +forcepain (+foilforcepain ?). I don't know if flags can work this way but being able to set this flag for different damage types would be even better. That way an actor could be immune to one type of forcepain missile but not any others that may exist.
Anyway, such a flag would be a much better solution to my (minor) problem. Instead of editing the projectile and every enemy in the game, I could just give the player the +foilforcepain flag and be done with it. Any chance?
- Graf Zahl
- Lead GZDoom+Raze Developer

- Posts: 49252
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: [still present in r3568] Incorrect pain conditions
... and here we have the proof why I think that the entire pain/damage system should not be tinkered with - just because some person thinks it doesn't work like they want to.
Tell me what you want, but I think it's stupid to make the damaged actor feel pain if all the damage gets protected away. IMO this particular change should be reverted and 0-damage to cause pain only be allowed when it comes from ripping projectiles - because those have been handling it incorrectly forever.
Anyway, the proper fix in your case should be to give the player a custom painchance of 0 for the specific damage type and not rely on hacks that he doesn't get subjected to anything uncontrollable.
Tell me what you want, but I think it's stupid to make the damaged actor feel pain if all the damage gets protected away. IMO this particular change should be reverted and 0-damage to cause pain only be allowed when it comes from ripping projectiles - because those have been handling it incorrectly forever.
Anyway, the proper fix in your case should be to give the player a custom painchance of 0 for the specific damage type and not rely on hacks that he doesn't get subjected to anything uncontrollable.
Re: [still present in r3568] Incorrect pain conditions
I haven't actually tried that because when read the Wiki, it said:Graf Zahl wrote:Anyway, the proper fix in your case should be to give the player a custom painchance of 0 for the specific damage type and not rely on hacks that he doesn't get subjected to anything uncontrollable.
So I figured it wouldn't work. In fact, I had a few ideas that I was going to try but every idea that I had, according to the Wiki, would not work because +forcepain would override the setting that I was planning on using. That's why I suggested a way to ignore +forcepain because, as far as I can tell, there is no longer any method by which an actor can be made immune to a +forcepain attack. I would imagine that boss actors and other enemies that are supposed to be tough for whatever reason could really do with such an ability.The Wiki painchance entry wrote:Sources of damage that have the FORCEPAIN flag ignore this property.
For my particular situation, I suppose that I could create a silent custom pain state for the player but that's not ideal (and I'm guessing wouldn't suit all mods) so I do feel that there should be a better way of making an actor able to ignore a +forcepain attack somehow.
Re: [still present in r3568] Incorrect pain conditions
The problem here is that we get an arms' race.
+NOPAIN -> +FORCEPAIN -> +FOILFORCEPAIN -> +FORCEPAINDESPITEFOILFORCEPAIN -> +NOIREALLYMEANNOPAINATALLNOTEVENWITHFORCEPAINDESPITEFOILFORCEPAIN -> +SUDOFORCEPAINSLASHYESTOALL -> +NANANANOTLISTENINGANDNOTPAINED -> ...
All that for unreliable and glitchy pain hacks. Pretty much what motivated [wiki]A_RadiusGive[/wiki] to come into being.
+NOPAIN -> +FORCEPAIN -> +FOILFORCEPAIN -> +FORCEPAINDESPITEFOILFORCEPAIN -> +NOIREALLYMEANNOPAINATALLNOTEVENWITHFORCEPAINDESPITEFOILFORCEPAIN -> +SUDOFORCEPAINSLASHYESTOALL -> +NANANANOTLISTENINGANDNOTPAINED -> ...
All that for unreliable and glitchy pain hacks. Pretty much what motivated [wiki]A_RadiusGive[/wiki] to come into being.
Re: [still present in r3568] Incorrect pain conditions
I take your arms race point but all I'm saying is that there is now no way for any actor to be excluded from the effects of a forcepain missile and it feels to me like there should be.
Presumably the A_RadiusGive idea would be to define an inventory item that puts any actor that has it into their pain state (how would such an item look? - can monsters have inventory items activate in their own inventory?) and then have another actor (in my case the sonic grenade) repeatedly give out the inventory item to any actor within the specified range, using the RGF_MONSTERS flag?
Presumably the A_RadiusGive idea would be to define an inventory item that puts any actor that has it into their pain state (how would such an item look? - can monsters have inventory items activate in their own inventory?) and then have another actor (in my case the sonic grenade) repeatedly give out the inventory item to any actor within the specified range, using the RGF_MONSTERS flag?
Re: [still present in r3568] Incorrect pain conditions
Don't give it a pain state? Force pain should force pain. Finer-tuned controls should be done with damage-specific pain chances.Enjay wrote:I take your arms race point but all I'm saying is that there is now no way for any actor to be excluded from the effects of a forcepain missile and it feels to me like there should be.
In the broad lines, yeah. You can give CustomInventory items to monsters and they will perform the actions there. However, you can't use an A_Jump or Goto in the custom inventory Use code since it will not actually change the actor's state. If I were coding the sonic grenade effect from scratch, I'd probably use some sort of timed powerup, like maybe PowerIronFeet which won't affect the monster otherwise. Then have in the monster's states A_JumpIfInventory checks for the presence of that token powerup.Enjay wrote:Presumably the A_RadiusGive idea would be to define an inventory item that puts any actor that has it into their pain state (how would such an item look? - can monsters have inventory items activate in their own inventory?) and then have another actor (in my case the sonic grenade) repeatedly give out the inventory item to any actor within the specified range, using the RGF_MONSTERS flag?
Though I understand not wanting to update a ton of already-existing actors with rewritten sonic grenade code. It's just that I don't see a 100% satisfying way to solve your problem. Piling up new complexity to the already nigh-incomprehensible pain code doesn't appeal to me.
Spoiler:Argh! Can you follow that code?
Re: [still present in r3568] Incorrect pain conditions
Which would mean that it wouldn't be able to ever to go into a pain state - from any damage source. The kind of situation that I am thinking about where +foilforcepain would be useful is a missile that always puts lesser enemies into the pain state (and thereby buys the player a bit of time) but it doesn't have the same effect on a boss/much tougher enemy. However, that enemy should still have the possibility of occasionally going in to a pain state from most attack so removing its pain state would not be appropriate.Gez wrote:Don't give it a pain state?
Agreed, but, for my sonic effect, that takes us back to having to edit every monster in the game to be very susceptible to the sonic pain and one actor to not be. Having to change the code for every single actor just to make one of them behave differently seems inefficient to me.Gez wrote:Force pain should force pain. Finer-tuned controls should be done with damage-specific pain chances.
I had considered the "give them an inventory item and use A_Jump" method but, as you said, that would involve updating a ton of actors.
And thanks for that code snippet. All those conditions and sub conditions do illustrate the complexity of the relevant code.
Re: [still present in r3568] Incorrect pain conditions
Thinking aloud here, would it be possible to create an inventory item that had [wiki]SetActorState[/wiki] in its decorate definition to send an actor into its pain state and, if so, would setting the tid argument to 0 mean that the inventory item would affect itself or the actor that had the item in its inventory?Gez wrote:However, you can't use an A_Jump or Goto in the custom inventory Use code since it will not actually change the actor's state.
Re: [still present in r3568] Incorrect pain conditions
Well, [wiki]SetActorState[/wiki] is an ACS function. But you could have some [wiki]named script[/wiki] and have the item run [wiki]CallACS[/wiki]. That would probably work.

