Raised This Month: $ Target: $400
 0% 

TF2 Health Modding Snippet


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
labelmaker
Member
Join Date: Mar 2009
Location: Kentucky USA
Old 05-15-2009 , 08:53   TF2 Health Modding Snippet
Reply With Quote #1

PHP Code:
#include <sourcemod>
#include <sdktools>
#include <damage>

new g_playerAttacking[MAXPLAYERS 1];
new 
bool:g_alreadykilled[MAXPLAYERS 1];

public 
Plugin:myinfo 
{
    
name "Health Modding",
    
author "LabelMaker",
    
description "Double Damage and Health Modding Example",
    
version "1.0",
    
url "<- URL ->"
}

public 
OnPluginStart()
{
    
HookEvent("player_hurt"EventDamageEventHookMode_Pre);
}

public 
OnEventShutdown()
{
    
UnhookEvent("player_spawn"PlayerSpawnEvent);
}

public 
OnGameFrame()
{
    
SaveAllHealth();
}

public 
PlayerSpawnEvent(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
client GetClientOfUserId(GetEventInt(event"userid"));
    if (
client 0)
    {    
        
SaveHealth(client);
        
g_alreadykilled[client] = false;
    }
}

public 
EventDamage(Handle:Event, const String:Name[], bool:dontBroadcast)
{
    new 
victim GetClientOfUserId(GetEventInt(Event"userid"));
    
    if (
g_alreadykilled[victim])//this will prevent players gaining multiple kills for a single kill
    
{
        
g_alreadykilled[victim] = false;
        return;
    }
    
    new 
attacker GetClientOfUserId(GetEventInt(Event"attacker"));
    new 
bool:self false;
    new 
v_health GetEntProp(victimProp_Send"m_iHealth");
    
//new a_health = GetEntProp(attacker, Prop_Send, "m_iHealth");
    
new damage GetDamage(Eventvictimattacker, -1, -1);
    new 
victimFlags GetEntProp(victimProp_Data"m_fFlags"victimFlags);
    
    if (
attacker == victimself true;
    if (!
self && attacker != && IsClientConnected(attacker))
    {
        
v_health -= damage// this will double the damage done by subtracting again whats already been done.
    
}
    
    
//is victim or attacker dead?
    
if (v_health != GetEntProp(victimProp_Send"m_iHealth"))
    {
        if (
v_health 1)
        {
            
g_playerAttacking[attacker] = victim;
            
CreateTimer(0.1checkDeathvictim);// wait a frame to prevent invincible exploit
        
}
        else
        {
            
SetEntityHealth(victimv_health);
            
SaveHealth(victim);
        }
    }
    
/* this section is only needed if you apply anything health related to your attacker//
    if (a_health != GetEntProp(attacker, Prop_Send, "m_iHealth"))
    {
        if (a_health < 1)
        {
            g_playerAttacking[victim] = attacker;
            CreateTimer(0.01, checkDeath, attacker);
        }
        else
        {
            SetEntityHealth(attacker, a_health);
            SaveHealth(attacker);
        }
    }
    ///////////////////////////////////////////////////////////////////////////////////////*/
}

public 
Action:checkDeath(Handle:timerany:client)
{
    new 
attacker;
    new 
fFlags GetEntProp(clientProp_Data"m_fFlags"fFlags);
    for(new 
1<= MaxClients; ++i
    { 
        if (
IsClientConnected(i) && g_playerAttacking[i] == client
        { 
            
g_playerAttacking[i] = 0
            
attacker i
            break; 
        } 
    }  
    if (
IsPlayerAlive(client) && !(fFlags FL_KILLME)) KillPlayer(clientattacker); //if the game engine hasnt assigned the player for death, kill them.
}

KillPlayer(clientattacker)
{
    new 
ent CreateEntityByName("env_explosion");
    if (
IsValidEntity(ent))
    {
        
g_alreadykilled[client] = true;//tell the damage event to halt, and let the game engine do the work.
        
        
DispatchKeyValue(ent"iMagnitude""1000");
        
DispatchKeyValue(ent"iRadiusOverride""2");
        
SetEntPropEnt(entProp_Data"m_hInflictor"attacker);
        
SetEntPropEnt(entProp_Data"m_hOwnerEntity"attacker);
        
DispatchKeyValue(ent"spawnflags""3964");
        
DispatchSpawn(ent);
        new 
Float:pos[3];
        
GetClientAbsOrigin(clientpos);
        
TeleportEntity(entposNULL_VECTORNULL_VECTOR);
        
AcceptEntityInput(ent"explode"clientclient);
        
CreateTimer(0.2RemoveExplosionent);
    }
}

public 
Action:RemoveExplosion(Handle:timerany:ent)
{
    if (
IsValidEntity(ent))
    {
        
RemoveEdict(ent);
    }

Source: healthmod.sp
include file used in the snippet: damage.inc
__________________

Come Check Out the Popcorn Mod Yourself!!

Last edited by labelmaker; 05-17-2009 at 04:20. Reason: -fixed coding errors-
labelmaker is offline
Send a message via Skype™ to labelmaker
p3tsin
Senior Member
Join Date: Sep 2005
Location: Finland
Old 05-15-2009 , 10:30   Re: TF2 Health Modding Snippet
Reply With Quote #2

Hmm, interesting. Noticed a few oddities though

1) Theres no such forward as OnEventShutdown(), not in SourceMod at least. Also, you dont need to unhook events, SourceMod does that for you when the plugin is unloaded.

2)
Quote:
Originally Posted by labelmaker View Post
PHP Code:
new bool:g_alreadykilled[MAXPLAYERS 1];

KillPlayer(clientattacker)
{
    
//...
    
g_alreadykilled true;//tell the damage event to halt, and let the game engine do the work.
    //...

Variable not indexed?

3)
Quote:
Originally Posted by labelmaker View Post
PHP Code:
if (IsPlayerAlive(client) && !(fFlags FL_KILLME)) KillPlayer(clientattacker); //if the game engine hasnt assigned the player for death, kill them. 
Are you sure thats what FL_KILLME is used for? I know its used to tell the engine to delete an entity next time it thinks, but I guess it could be used for that too. How did you come up with it?

4)
Quote:
Originally Posted by labelmaker View Post
PHP Code:
CreateTimer(0.01checkDeathvictim);// wait a frame to prevent invincible exploit 
Minimum interval for timers is 0.1 seconds, everything lower than that will be clamped up to the min value.

5)
Quote:
Originally Posted by labelmaker View Post
PHP Code:
if (IsClientConnected(attacker) && attacker != && !self
The conditions should probably be in the opposite order (!self && attacker != 0 && IsClientConnected(attacker)) or else IsClientConnected will spit out an error if you pass it an invalid client index, 0 in this case.

6)
Quote:
Originally Posted by labelmaker View Post
PHP Code:
for(new 1<= MAXPLAYERS; ++i)
{
    if (
IsValidEdict(i))
    {
        if (
IsClientConnected(i))
        {
            if (
g_playerAttacking[i] == client)
            {
                
g_playerAttacking[i] = 0;
                
attacker i;
                break;
            }
        }
    }

The IsValidEdict() check isnt needed, you probably added that because IsClientConnected was complaining about invalid client indexes again. The magic MaxClients variable holds the current maxplayers limit at all times.

PHP Code:
for(new 1<= MaxClients; ++i)
{
    if (
IsClientConnected(i) && g_playerAttacking[i] == client)
    {
        
g_playerAttacking[i] = 0;
        
attacker i;
        break;
    }

Sorry if this seems Im being too hard on you, but most of those mistakes are pretty common and it can be hard to tell whats the correct way to do it. I just wanted to clear them up so that others wouldnt end up with the same flaws.
__________________
plop
p3tsin is offline
labelmaker
Member
Join Date: Mar 2009
Location: Kentucky USA
Old 05-17-2009 , 03:55   Re: TF2 Health Modding Snippet
Reply With Quote #3

thanx for those helpful bits of advice. ++karma for you the FL_KILLME check is to prevent players from getting multiple kill points for only having a single kill. Most of my playtesters had to reset their stats (including me) because we had unrealistic results of like 100 or 200 points per life, LOL! -EDIT- What no karma anymore! well kudos man, if I could give ya karma, id give you some!
__________________

Come Check Out the Popcorn Mod Yourself!!

Last edited by labelmaker; 05-17-2009 at 03:57. Reason: No karma to give! :(
labelmaker is offline
Send a message via Skype™ to labelmaker
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 18:44.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode