Page 1 of 1
Limit Damage On Player Per Tic?
Posted: Sat Sep 23, 2023 7:50 pm
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.
Re: Limit Damage On Player Per Tic?
Posted: Sun Sep 24, 2023 5:42 am
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.
Re: Limit Damage On Player Per Tic?
Posted: Mon Sep 25, 2023 9:27 am
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.
Re: Limit Damage On Player Per Tic?
Posted: Sat Oct 07, 2023 2:45 pm
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
Re: Limit Damage On Player Per Tic?
Posted: Sat Oct 07, 2023 3:45 pm
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.
Re: Limit Damage On Player Per Tic?
Posted: Sat Oct 07, 2023 5:33 pm
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
}
}