Anti-Lag Shoot Problem
#1

I use this script for anti-lag system:
Код:
public OnPlayerGiveDamage(playerid, damagedid, Float:amount)
{
	new Float:health, Float:armour;
	GetPlayerHealth(damagedid, health);
	GetPlayerArmour(damagedid, armour);

	if(armour == 0.0) // No armour, just take health
	{
	    health -= amount;
	    if(health < 0.0) health = 0;
	}
	else // There is armour, take what is needed
	{
	    if(armour-amount < 0.0) // Health needs to be taken
	    {
	        health -= (amount - armour);
	        armour = 0;
	    }
	    else armour -= amount;
	}

	SetPlayerHealth(damagedid, health);
	SetPlayerArmour(damagedid, armour);
	return 1;
}
When i kill somebody with Deagle it takes 2x damage, i read as I need to put on OnPlayerSpawn :
Код:
SetPlayerTeam(playerid, 4);
Ok, i put this and when i kill somebody damage is good but the CallBack OnPlayerDeath doesn't call. In server log when i kill show like that:
Код:
[death] Awesome. died 255
instead of
Код:
[kill] Awesome. killed Jadooze Desert Eagle
Reply
#2

Bump.
Reply
#3

pawn Код:
if(health < 0.0) health = 0;
Well i dunno, it seems like server is setting victim health to 0 when he is killed so server will detect like player died .. not killed..
Reply
#4

If you really want normal kill prints use this

pawn Код:
public OnPlayerGiveDamage(playerid, damagedid, Float:amount)
{
    if(!(0 <= damagedid < MAX_PLAYERS)) return; // small anti against cheaters

    new Float:health, Float:armour;
    GetPlayerArmour(damagedid, armour);

    if( armour < 0.1 ) // No armour, just take health
    {
        GetPlayerHealth(damagedid, health);
        health -= amount;
        if(health < 0.0)
        {
            OnPlayerDeath(damagedid, playerid, GetPlayerWeapon(playerid)); // if you want call OnPlayerDeath only in GM ( Example 1 )
            CallLocalFunction("OnPlayerDeath", "iii", damagedid, playerid, GetPlayerWeapon(playerid)); // if you want call OnPlayerDeath only in GM ( Example 2 )
            CallRemoteFunction("OnPlayerDeath", "iii", damagedid, playerid, GetPlayerWeapon(playerid)); // if you want call OnPlayerDeath in all FS and GM
            // Choose one method
            return;
        }

        SetPlayerHealth(damagedid, health);
        return;
    }
    else // There is armour, take what is needed
    {
        health = ( armour - amount );
        if( health < 0.0 ) // Health needs to be taken
        {
            GetPlayerHealth(damagedid, health);
            health -= ( amount - armour );
            SetPlayerHealth(damagedid, health);
            SetPlayerArmour(damagedid, 0.0);
        }
        else
            SetPlayerArmour(damagedid, health);
    }
    return;
}
but i dont know is this a good idea
Reply
#5

Not really a good idea Jefff, this is a problem with using OnPlayerGiveDamage() when you actually kill the player OnPlayerDeath() picks it up. What I did and is very effective but takes some more coding in other places is to not even use OnPlayerDeath() but make your own OnPlayerDeath() callback then call it directly when a player is killed. There is another issue all players must be on the same team otherwise you'll take double hits I do have a way around this and implement a mixed-mode where you can skin hit or lead aim but you need to delay each skin hit to make sure OnPlayerTakeDamage() is not called.

@Edit - I think your way could possible work now Jefff but you would need to call OnPlayerDeath() before killing the player and remove SetPlayerHealth() from OnPlayerGiveDamage() then put in these lines in on the top of OnPlayerDeath()


pawn Код:
if(PlayerIsDead[playerid]) return 1;
PlayerIsDead[playerid] = true;
SetPlayerHealth(playerid, 0.0);
That would prevent OnPlayerDeath() from being executed fully until the player is marked alive which would be set in OnPlayerSpawn() although I don't recommend this way using your own callback is the most effective way to deal with fake killing.

Lastly...... make sure you put this in OnPlayerGiveDamage()

pawn Код:
if(IsPlayerStreamedIn(playerid, damagedid) && IsPlayerStreamedIn(damagedid, playerid))
You need to make sure each player is streamed in for the other otherwise someone with packetloss will be able to kill players without that player being even streamed in! We also had another issue with fake OnPlayerGiveDamage() messages being sent although it would still be possible to do this if the other player was streamed in we never had any problems after I made the change.
Reply
#6

Yup the best way should be own OnPlayerDeathEx, but this method works too if players are in the same team we dont use SetPlayerHealth and if we calls OnPlayerDeath player is automaticly dead.
Reply
#7

The trick like I said is to mark the player as dead before setting their health to 0 this way OnPlayerDeath() can not be called multiple times but this does nothing for fake killing and would likely introduce unique problems.
Reply
#8

We gave him a lot of clues now let he combines ;p
Reply
#9

Well Anti-Lag systems are more of an art than coding
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)