Limit Damage On Player Per Tic?

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
StankyTree
Posts: 13
Joined: Sun Nov 03, 2019 8:17 am
Graphics Processor: nVidia (Modern GZDoom)

Limit Damage On Player Per Tic?

Post by StankyTree »

Okay so I am making a mod that has a damage system functionally identical to Sonic the Hedgehog, and the way I do it involved ACS constantly keeping the player's health between 1 and 2 (1 is when nothing is protecting you) and (2 is when you're protected by rings or a shield)

And through this all damage sources deal only 1 damage with a brief invulnerability period, but that's where my problem arises.

If the you're hit by two damage sources the same tic, then its an immediate instakill.

How could I possibly make sure the player can only take ONE damage within a tic? OR only take damage from one source at a time no matter what.
Jarewill
 
 
Posts: 1853
Joined: Sun Jul 21, 2019 8:54 am

Re: Limit Damage On Player Per Tic?

Post by Jarewill »

If you don't mind using ZScript, you can override Tick and DamageMobj to keep track of damage every tic:

Code: Select all

	bool damaged; //Keep track of damage this tic in this variable
	Override void Tick(){
		Super.Tick();
		damaged=0; //Every tic reset it
	}
	Override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle){
		If(damaged){Return 0;} //If damage happened this tic, deal no damage
		damaged=1; //Otherwise mark this tic as damage
		Return Super.DamageMobj(inflictor,source,damage,mod,flags,angle); //And do normal damage
	}
It's a bit hard to test this, due to the very small time window where it can trigger, but I tried it with rockets and I didn't get hurt by the splash damage if I got a direct hit.
StankyTree
Posts: 13
Joined: Sun Nov 03, 2019 8:17 am
Graphics Processor: nVidia (Modern GZDoom)

Re: Limit Damage On Player Per Tic?

Post by StankyTree »

Jarewill wrote: Sun Sep 24, 2023 5:42 am If you don't mind using ZScript, you can override Tick and DamageMobj to keep track of damage every tic:

Code: Select all

	bool damaged; //Keep track of damage this tic in this variable
	Override void Tick(){
		Super.Tick();
		damaged=0; //Every tic reset it
	}
	Override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle){
		If(damaged){Return 0;} //If damage happened this tic, deal no damage
		damaged=1; //Otherwise mark this tic as damage
		Return Super.DamageMobj(inflictor,source,damage,mod,flags,angle); //And do normal damage
	}
It's a bit hard to test this, due to the very small time window where it can trigger, but I tried it with rockets and I didn't get hurt by the splash damage if I got a direct hit.
Thank you, ill mess around with this. I don't use much zscript other than for the HUD and my player movement but I feel like I can learn something from this.

Plus testing wont be hard, I already have projectile traps made so I can just have two at the same distance.
StankyTree
Posts: 13
Joined: Sun Nov 03, 2019 8:17 am
Graphics Processor: nVidia (Modern GZDoom)

Re: Limit Damage On Player Per Tic?

Post by StankyTree »

Jarewill wrote: Sun Sep 24, 2023 5:42 am If you don't mind using ZScript, you can override Tick and DamageMobj to keep track of damage every tic:

Code: Select all

	bool damaged; //Keep track of damage this tic in this variable
	Override void Tick(){
		Super.Tick();
		damaged=0; //Every tic reset it
	}
	Override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle){
		If(damaged){Return 0;} //If damage happened this tic, deal no damage
		damaged=1; //Otherwise mark this tic as damage
		Return Super.DamageMobj(inflictor,source,damage,mod,flags,angle); //And do normal damage
	}
It's a bit hard to test this, due to the very small time window where it can trigger, but I tried it with rockets and I didn't get hurt by the splash damage if I got a direct hit.
I apologize but I don't know too much about Zscript, i'm not sure how i'm supposed implement the code. I've looked at some other code i've borrowed for my project and tried to reverse engineer it from there, but I simply don't see any difference in anything when testing. I don't get any errors either, any idea why?

Code: Select all

class DamageLimiterHandler : EventHandler
{
	override void PlayerEntered(PlayerEvent e)
	{
		players[e.PlayerNumber].mo.A_GiveInventory("DamageLimiter", 1);
	}
}

class DamageLimiter : CustomInventory
{
	Default
	{
		Inventory.MaxAmount 1;
		+INVENTORY.UNDROPPABLE
		+INVENTORY.UNTOSSABLE
		+INVENTORY.AUTOACTIVATE
	}
	    bool damaged; //Keep track of damage this tic in this variable
		Override void Tick()
		{
			Super.Tick();
			damaged=0; //Every tic reset it
		}
		Override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags, double angle)
		{
			If(damaged){Return 0;} //If damage happened this tic, deal no damage
			damaged=1; //Otherwise mark this tic as damage
			Return Super.DamageMobj(inflictor,source,damage,mod,flags,angle); //And do normal damage
		}
}
heres my code
StankyTree
Posts: 13
Joined: Sun Nov 03, 2019 8:17 am
Graphics Processor: nVidia (Modern GZDoom)

Re: Limit Damage On Player Per Tic?

Post by StankyTree »

okay nevermind, i figured it out.

I simply made the player's health set to 50 when they have rings or a shield, but if they have nothing its set to 1.

so just as long as the player doesn't get hit by 50 projectiles within the same tic, they're fine.
Jarewill
 
 
Posts: 1853
Joined: Sun Jul 21, 2019 8:54 am

Re: Limit Damage On Player Per Tic?

Post by Jarewill »

The code I provided should be placed within the player class for it to work, as putting DamageMobj inside an inventory item won't take effect when the player takes damage.
For inventory items you want to use ModifyDamage instead, for example:

Code: Select all

class DamageLimiter : Inventory //I don't recommend using CustomInventory in ZScript
{
	Default
	{
		Inventory.MaxAmount 1;
		+INVENTORY.UNDROPPABLE
		+INVENTORY.UNTOSSABLE
		+INVENTORY.AUTOACTIVATE
	}
	    bool damaged; //Keep track of damage this tic in this variable
		Override void DoEffect()
		{
			Super.DoEffect();
			damaged=0; //Every tic reset it
		}
		Override void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags)
		{
			If(!passive){Return;} //If the player is dealing damage instead of taking damage, don't do anything
			If(damaged){newdamage = 0;} //If damage happened this tic, deal no damage
			damaged=1; //Otherwise mark this tic as damage
		}
}
Post Reply

Return to “Scripting”