Forced damagefactor for a specific damagetype

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
Grey-Wolf
Posts: 179
Joined: Sun Jul 15, 2018 4:59 pm
Graphics Processor: nVidia (Modern GZDoom)

Forced damagefactor for a specific damagetype

Post by Grey-Wolf »

Hello!
I have a "bleeding" damagetype, and I want that all damage coming from it are always dealt at damagefactor 1.0 no matter what.
So I've put the "replacefactor" property into its definition, but the thing is, it is still affected by the global damagefactor of the difficulty level, so it ends up dealing more damage in those cases
What am I doing wrong?
User avatar
Grey-Wolf
Posts: 179
Joined: Sun Jul 15, 2018 4:59 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Forced damagefactor for a specific damagetype

Post by Grey-Wolf »

Uhhh, can I bump this? I'm still having this problem...
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Forced damagefactor for a specific damagetype

Post by Player701 »

I think no one's answered this yet because your use case is unclear. Global damage factor is called that for a reason: it is intended to affect everything (in regards to player-received damage anyway). Why are you trying to bypass it?

If you're using ZScript, from the source code it looks like you can pass a flag called DMG_FORCED to DamageMobj when applying your damage to ignore all damage factors, even the global one. If you're not using DamageMobj, I guess you could divide your damage by G_SkillPropertyFloat(SKILLP_DamageFactor) before applying it, although since the damage is an int, it may not work as intended in all cases. For example, if the damage is 1 and the factor is 2, the resulting damage will be 0 because int(1/2) == 0, and 0 multiplied back by 2 is still 0.

Upd: Example player class to override global damage factor for a specific damage type using DMG_FORCED, tested in GZDoom 4.4.2

Code: Select all

class MyPlayer : DoomPlayer
{
    override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle)
    {
        if (mod == 'Bleeding') // <- Replace with the name of your damage type if it's called differently
        {
            flags |= DMG_FORCED;
        }
        
        return Super.DamageMobj(inflictor, source, damage, mod, flags, angle);
    }
}
User avatar
Grey-Wolf
Posts: 179
Joined: Sun Jul 15, 2018 4:59 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Forced damagefactor for a specific damagetype

Post by Grey-Wolf »

I'm using ACS, through the DamageActor command.
Now, this is the damagetype definition:
Spoiler:
And even though I won't post the whole bleeding script because it's very long, basically it should inflict damage on the player if some conditions are met, through this command:
Damageactor(0,0,1,0,3,"bleeding");

Thing is, if set my difficulty level at, let's say 200% damage taken, each proc of the bleeding will deal 6 damage instead of 3.
Since I'm not exactly well versed in zScript and I don't want to rewrite a very long script just because of this, is there some way to achieve this in ACS?
Last edited by Grey-Wolf on Thu Oct 08, 2020 9:37 am, edited 1 time in total.
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Forced damagefactor for a specific damagetype

Post by Player701 »

As far as I'm aware, there is no way to pass DamageMobj flags via ACS. It is also not possible to retireve the values of skill properties in either ACS or DECORATE.

However, to make use of the above example, you don't have to rewrite your script. Just add the DamageMobj override to your player class and you should be all set... mostly. The thing is, DMG_FORCED also has some side effects, like bypassing invulnerability, so the example code should be slightly modified to account for that. If you are willing to use it, I believe I will be able to provide a more complete version tomorrow (it's 11 PM where I am, don't want to stay up late :P), or maybe someone else could do that while I'm unavailable.
Grey-Wolf wrote:Thing is, if set my difficulty level at, let's say 200% damage taken, each proc of the bleeding will deal 6 damage instead of 3.
But what's wrong with that? Just curious. IMO, it should work exactly like you're describing.

Upd: Here's the updated code

Code: Select all

class MyPlayer : DoomPlayer
{
    override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle)
    {
        if (mod == 'Bleeding' && !((player.cheats & CF_GODMODE) || bInvulnerable))
        {
            flags |= DMG_FORCED;
        }
       
        return Super.DamageMobj(inflictor, source, damage, mod, flags, angle);
    }
}
I may have failed to account for some more specific conditions, because the original DamageMobj code is huge and not easily understandable... Sorry about that. But at least this won't damage the player when they are in god mode or have an invulnerability powerup. Please let me know if you have any issues with it.
User avatar
Grey-Wolf
Posts: 179
Joined: Sun Jul 15, 2018 4:59 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Forced damagefactor for a specific damagetype

Post by Grey-Wolf »

I already have an actor replacing "doomplayer", won't this class mess with it?
But what's wrong with that? Just curious. IMO, it should work exactly like you're describing.
I just want bleeding damage to stay unaffected, I have good reasons for it, I swear XD
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Forced damagefactor for a specific damagetype

Post by Player701 »

Grey-Wolf wrote:I already have an actor replacing "doomplayer", won't this class mess with it?
If you already have a player class, you should convert it to ZScript and add the DamageMobj override there.
User avatar
Grey-Wolf
Posts: 179
Joined: Sun Jul 15, 2018 4:59 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Forced damagefactor for a specific damagetype

Post by Grey-Wolf »

Hmm... as I already mentioned, I'm utterly terrible at Zscript, so I'd rather avoid that. On another note, I could have found a solution working for ACS, kind of a weird workaround, not gonna lie:
Spoiler:
This removes exactly 1 point of health at each proc. The only problem with this is that if the player dies because of this, it won't show the proper obituary message, but a really inappropriate "suicide" one (like "%o killed himself"). If I were to find a way to replace this obituary message, I would settle with that. Any ideas?
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Forced damagefactor for a specific damagetype

Post by Player701 »

Grey-Wolf wrote:Hmm... as I already mentioned, I'm utterly terrible at Zscript, so I'd rather avoid that.
If you read the guide, and especially the examples, you'll see that the syntax is mostly the same, except that you have to put Default { ... } around the property values and add some semicolons. If you posted your code here, I'd probably be able to provide a converted version for you.
Grey-Wolf wrote:I could have found a solution working for ACS, kind of a weird workaround, not gonna lie:
Spoiler:
Note that this ignores whether the player is invulnerable or using the godmode cheat. While the former can be checked for with GetActorProperty(0, APROP_Invulnerable), I'm not sure if you can check for cheat usage in ACS.
Grey-Wolf wrote:The only problem with this is that if the player dies because of this, it won't show the proper obituary message, but a really inappropriate "suicide" one (like "%o killed himself").
From the source code, it looks like the engine considers the activator of the script as the damage inflictor. If the script is activated by the player, it's only logical that it will produce the suicide obituary. If you can change it so that the script is activated by something else, I suppose it will use the obituary of that something instead.
User avatar
Grey-Wolf
Posts: 179
Joined: Sun Jul 15, 2018 4:59 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Forced damagefactor for a specific damagetype

Post by Grey-Wolf »

Uh... are you sure? It's REAAALLY long.

https://pastebin.com/Mj21nj6P

And changing the activator of the script is not really an option because it would mess up various "giveinventory" and whatnot in that same script...

EDIT: what if the class just inherits from the current one while adding that commands you mentioned
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Forced damagefactor for a specific damagetype

Post by Player701 »

Grey-Wolf wrote:Uh... are you sure? It's REAAALLY long.
Right.

So there is an even better solution that doesn't involve rewriting your DECORATE code. Use this ZScript code as your base class:

Code: Select all

class MyPlayer : PlayerPawn
{
    override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle)
    {
        if (mod == 'Bleeding' && !((player.cheats & CF_GODMODE) || bInvulnerable))
        {
            flags |= DMG_FORCED;
        }
       
        return Super.DamageMobj(inflictor, source, damage, mod, flags, angle);
    }
}
and then in your DECORATE code, inherit your player class from MyPlayer, like this:

Code: Select all

actor Doomer : MyPlayer
{
    // Your overly long player class code goes here
}
As far as I'm aware, this should work because DECORATE is parsed after ZScript.

BTW, your player class does not need to replace DoomPlayer, because player classes aren't replaced this way. Adding it to MAPINFO is sufficient.
User avatar
Grey-Wolf
Posts: 179
Joined: Sun Jul 15, 2018 4:59 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Forced damagefactor for a specific damagetype

Post by Grey-Wolf »

Worked like a charm! Thank you !
Post Reply

Return to “Scripting”