[ZScript] Check if damage is from Melee/Hitscan/Projectile

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
Virathas
Posts: 249
Joined: Thu Aug 10, 2017 9:38 am

[ZScript] Check if damage is from Melee/Hitscan/Projectile

Post by Virathas »

Hey all!

I have lately been redesigning my damage systems, and have stumbled upon a problem. I need to figure out, when damage is applied, how to check if an attack is Melee, Hitscan or its a projectile.

Long Story: I am redesigning my damage system to have several new layers of complexity. Flat bonus damage, afterwards multiplicative (all bonuses are additive), and then a post multiplication bonus damage. Furthermore, i want to have the actual attacks to have the bonuses in them, so if a missile flies towards an opponent, it will get bonuses/penalties when fired, not when they hit (so no more quad damage ending right before a rocket hits an enemy).
Not only missiles, but i also have separate bonuses for melee attacks. While i know by default damage types could handle this detection, i am using already many times, so i would have to have additional ones for each damage type i.e "Fire" and "FireMelee" - and i feel that is prone to user error.

Currently i am doing all this in "ModifyDamage" in an inventory item that is held by each actor.

Any of you have an idea how to best approach this conundrum?

Bonus Question!
What would be a good way to add additional (damage) effects on already defined attacks without changing them? For example, adding bonus fire damage to marine's fist, or adding additional ice damage to each pellet of a SSG blast.
Jarewill
 
 
Posts: 1766
Joined: Sun Jul 21, 2019 8:54 am

Re: [ZScript] Check if damage is from Melee/Hitscan/Projectile

Post by Jarewill »

If you are using either the DamageMobj virtual function or WorldThingDamaged event handler, you can do this by comparing inflictor and source for melee damage and checking if the inflictor has the MISSILE flag for projectiles, otherwise it's a hitscan.
Example using a DamageMobj override:

Code: Select all

	Override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle){
		If(inflictor==source){console.printf("Melee damage");}
		Else If(inflictor.bMISSILE){console.printf("Projectile damage");}
		Else{console.printf("Hitscan damage");}
		Return Super.DamageMobj(inflictor,source,damage,mod,flags,angle);
	}
As for the bonus question, one way to do it would be to override DamageMobj in each monster and check if the player's current weapon is the SSG to change the damage type.
It's not a good way and you are better off just changing your weapon damage types, but here it is:
Spoiler:
User avatar
MartinHowe
Posts: 2022
Joined: Mon Aug 11, 2003 1:50 pm
Location: Waveney, United Kingdom
Contact:

Re: [ZScript] Check if damage is from Melee/Hitscan/Projectile

Post by MartinHowe »

I've been looking into this recently; the issue I have is custom damage types. The above suggestion seems OK, but what about when the damage is poison? Would that register as "hitscan" then? Maybe the function would have to check the standard damage types too. What I want to do is give centaurs not invulnerability but have their shield reduce weapons damage, without affecting poison, lava, and so on.
Jarewill
 
 
Posts: 1766
Joined: Sun Jul 21, 2019 8:54 am

Re: [ZScript] Check if damage is from Melee/Hitscan/Projectile

Post by Jarewill »

I have completely forgot that poison damage even exists. :shock:
After messing with pointers, turns out poison damage, as well as environment damage, has no inflictor, meaning that it will cause a VM abort with the code I provided above.
This code will however work:

Code: Select all

	If(!source){console.printf("Environmental damage");}
	Else If(!inflictor){console.printf("Poison damage");}
	Else If(inflictor==source){console.printf("Melee damage");}
	Else If(inflictor.bMISSILE){console.printf("Projectile damage");}
	Else{console.printf("Hitscan damage");}
You can still check damage types to make more custom logic or exceptions and such.

Also I have completely missed the mention of ModifyDamage in the opening post and in general forgot about that virtual function.
That will be an even better way to do it than the DamageMobj override if you don't want to replace monster classes.
User avatar
phantombeta
Posts: 2088
Joined: Thu May 02, 2013 1:27 am
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support
Location: Brazil

Re: [ZScript] Check if damage is from Melee/Hitscan/Projectile

Post by phantombeta »

Jarewill wrote: Fri May 19, 2023 12:16 pm [snip]
Keep in mind the inflictor == source thing is only true for monster melee attacks, which do only a range check. Weapons use hitscans for melee instead.
I believe you can also more accurately check for hitscans with the DMG_INFLICTOR_IS_PUFF flag. And while not explicitly asked, you can differentiate A_Explode and such from direct hits with the DMG_EXPLOSION flag.
User avatar
inkoalawetrust
Posts: 70
Joined: Mon Aug 26, 2019 9:18 pm
Graphics Processor: nVidia with Vulkan support
Contact:

Re: [ZScript] Check if damage is from Melee/Hitscan/Projectile

Post by inkoalawetrust »

Jarewill wrote: Sat May 20, 2023 5:56 am meaning that it will cause a VM abort with the code I provided above.
This is why you should null check absolutely everything in ZScript. Since ZScript doesn't do it on its' own, so there's always a chance of a VM abort caused by a null pointer.
User avatar
Virathas
Posts: 249
Joined: Thu Aug 10, 2017 9:38 am

Re: [ZScript] Check if damage is from Melee/Hitscan/Projectile

Post by Virathas »

Thanks all!

Those are all really helpful (And yes, i did find the VM abort with poison damage :P)
phantombeta wrote: Sat May 20, 2023 6:36 am
Keep in mind the inflictor == source thing is only true for monster melee attacks, which do only a range check. Weapons use hitscans for melee instead.
I believe you can also more accurately check for hitscans with the DMG_INFLICTOR_IS_PUFF flag. And while not explicitly asked, you can differentiate A_Explode and such from direct hits with the DMG_EXPLOSION flag.
Now this is very important for me, since in most cases i would need to check hitscan vs Melee is when player attacks (To provide different buffs).

I still am trying to decide which approach to use (Damagemobj vs ModifyDamage), mostly because ModifyDamage in GZDoom 3.7.2 does not have inflictor/source fields, and updating reduces compatibility... and my dev-station is an old laptop that can only handle 4.5.0 on software renderer :P.
Post Reply

Return to “Scripting”