AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Snippets and Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=112)
-   -   Proper way to deal damage without extensions (https://forums.alliedmods.net/showthread.php?t=111684)

API 12-13-2009 00:42

Proper way to deal damage without extensions
 
Because I love you.

Code:

#define DMG_GENERIC                        0
#define DMG_CRUSH                        (1 << 0)
#define DMG_BULLET                        (1 << 1)
#define DMG_SLASH                        (1 << 2)
#define DMG_BURN                        (1 << 3)
#define DMG_VEHICLE                        (1 << 4)
#define DMG_FALL                        (1 << 5)
#define DMG_BLAST                        (1 << 6)
#define DMG_CLUB                        (1 << 7)
#define DMG_SHOCK                        (1 << 8)
#define DMG_SONIC                        (1 << 9)
#define DMG_ENERGYBEAM                        (1 << 10)
#define DMG_PREVENT_PHYSICS_FORCE        (1 << 11)
#define DMG_NEVERGIB                        (1 << 12)
#define DMG_ALWAYSGIB                        (1 << 13)
#define DMG_DROWN                        (1 << 14)
#define DMG_TIMEBASED                        (DMG_PARALYZE | DMG_NERVEGAS | DMG_POISON | DMG_RADIATION | DMG_DROWNRECOVER | DMG_ACID | DMG_SLOWBURN)
#define DMG_PARALYZE                        (1 << 15)
#define DMG_NERVEGAS                        (1 << 16)
#define DMG_POISON                        (1 << 17)
#define DMG_RADIATION                        (1 << 18)
#define DMG_DROWNRECOVER                (1 << 19)
#define DMG_ACID                        (1 << 20)
#define DMG_SLOWBURN                        (1 << 21)
#define DMG_REMOVENORAGDOLL                (1 << 22)
#define DMG_PHYSGUN                        (1 << 23)
#define DMG_PLASMA                        (1 << 24)
#define DMG_AIRBOAT                        (1 << 25)
#define DMG_DISSOLVE                        (1 << 26)
#define DMG_BLAST_SURFACE                (1 << 27)
#define DMG_DIRECT                        (1 << 28)
#define DMG_BUCKSHOT                        (1 << 29)

DealDamage(victim,damage,attacker=0,dmg_type=DMG_GENERIC,String:weapon[]="")
{
        if(victim>0 && IsValidEdict(victim) && IsClientInGame(victim) && IsPlayerAlive(victim) && damage>0)
        {
                new String:dmg_str[16];
                IntToString(damage,dmg_str,16);
                new String:dmg_type_str[32];
                IntToString(dmg_type,dmg_type_str,32);
                new pointHurt=CreateEntityByName("point_hurt");
                if(pointHurt)
                {
                        DispatchKeyValue(victim,"targetname","war3_hurtme");
                        DispatchKeyValue(pointHurt,"DamageTarget","war3_hurtme");
                        DispatchKeyValue(pointHurt,"Damage",dmg_str);
                        DispatchKeyValue(pointHurt,"DamageType",dmg_type_str);
                        if(!StrEqual(weapon,""))
                        {
                                DispatchKeyValue(pointHurt,"classname",weapon);
                        }
                        DispatchSpawn(pointHurt);
                        AcceptEntityInput(pointHurt,"Hurt",(attacker>0)?attacker:-1);
                        DispatchKeyValue(pointHurt,"classname","point_hurt");
                        DispatchKeyValue(victim,"targetname","war3_donthurtme");
                        RemoveEdict(pointHurt);
                }
        }
}

Example usage:
Code:

DealDamage(victim_index,50,attacker_index,DMG_BULLET,"weapon_ak47");
Works for CSS and TF2, should work for all games.

Downtown1 12-13-2009 01:14

Re: Proper way to deal damage without extensions
 
war3_hurtme ?

API 12-13-2009 01:17

Re: Proper way to deal damage without extensions
 
Its the targetname I use because of war3source... point_hurt works by looking up a target name. You can make it whatever you want really.

Dragonshadow 12-13-2009 09:18

Re: Proper way to deal damage without extensions
 
Oooh cool :D

exvel 12-13-2009 10:17

Re: Proper way to deal damage without extensions
 
Pretty useful. Thank you!

TerroriZe 12-13-2009 10:34

Re: Proper way to deal damage without extensions
 
Dang I was so close ^_^ Anyways ty so much..thats gonna help..

Damizean 12-13-2009 12:24

Re: Proper way to deal damage without extensions
 
Quote:

Originally Posted by pimpinjuice (Post 1015440)
Its the targetname I use because of war3source... point_hurt works by looking up a target name. You can make it whatever you want really.

What if you use !activator and pass that to the activator in the AcceptEntityInput? Does that work?

API 12-13-2009 12:53

Re: Proper way to deal damage without extensions
 
I'm not sure, I'm assuming your using EventScripts. Give it a try.

Wazz 12-14-2009 17:21

Re: Proper way to deal damage without extensions
 
Quote:

Originally Posted by Damizean (Post 1015852)
What if you use !activator and pass that to the activator in the AcceptEntityInput? Does that work?

I have been doing that in alot of scenarios; it works fine.

TerroriZe 12-14-2009 17:31

Re: Proper way to deal damage without extensions
 
I got 2 questions :shock::

1.) Can you fake headshot damage as well? I basically want to create fake damage which kills somebody with a headshot...

2.) Im a bit confused... why is this method failing? ->

Code:

new Handle:event_hurt = CreateEvent("player_hurt");
SetEventInt(event_hurt, "userid", GetClientUserId(victim));
SetEventInt(event_hurt, "attacker", GetClientUserId(client));
SetEventInt(event_hurt, "dmg_health", health+1);
SetEventString(event_hurt, "weapon", weapon);
SetEventBool(event_hurt, "headshot", headshot);
FireEvent(event_hurt);

And how to use it, if not like that?

API 12-14-2009 17:35

Re: Proper way to deal damage without extensions
 
Why are you creating the event? It will automatically occur if you use DealDamage()
Also, I don't think you can make it headshot unfortunately, maybe a hook inside player_hurt to force a headshot might?

psychonic 12-14-2009 17:39

Re: Proper way to deal damage without extensions
 
Quote:

Originally Posted by TerroriZe (Post 1017134)
I got 2 questions :shock::

1.) Can you fake headshot damage as well? I basically want to create fake damage which kills somebody with a headshot...

Probably not. Most games rely on hitgroup for that from a trace. There does not appear to be any hitgroup key to set on the point_hurt entity.
http://developer.valvesoftware.com/wiki/Point_hurt

Quote:

Originally Posted by TerroriZe (Post 1017134)
I got 2 questions :shock::
2.) Im a bit confused... why is this method failing? ->

Code:

new Handle:event_hurt = CreateEvent("player_hurt");
SetEventInt(event_hurt, "userid", GetClientUserId(victim));
SetEventInt(event_hurt, "attacker", GetClientUserId(client));
SetEventInt(event_hurt, "dmg_health", health+1);
SetEventString(event_hurt, "weapon", weapon);
SetEventBool(event_hurt, "headshot", headshot);
FireEvent(event_hurt);

And how to use it, if not like that?

Events are just notifications. They get fired after the event actually happens and only exist to notify the server, client, and/or any plugins with event listeners that the event occurred. Firing the player_hurt event manually would lie that the player was hurt, but they would not actually take damage or lose health.

TerroriZe 12-14-2009 17:58

Re: Proper way to deal damage without extensions
 
ah ok thanks both of you.. that helped alot ^_^

This got me confused: http://wiki.alliedmods.net/Events_%2...d_Scripting%29

voogru 12-17-2009 19:30

Re: Proper way to deal damage without extensions
 
Quote:

Originally Posted by pimpinjuice (Post 1015426)
Because I love you.

Code:

#define DMG_GENERIC                        0
#define DMG_CRUSH                        (1 << 0)
#define DMG_BULLET                        (1 << 1)
#define DMG_SLASH                        (1 << 2)
#define DMG_BURN                        (1 << 3)
#define DMG_VEHICLE                        (1 << 4)
#define DMG_FALL                        (1 << 5)
#define DMG_BLAST                        (1 << 6)
#define DMG_CLUB                        (1 << 7)
#define DMG_SHOCK                        (1 << 8)
#define DMG_SONIC                        (1 << 9)
#define DMG_ENERGYBEAM                        (1 << 10)
#define DMG_PREVENT_PHYSICS_FORCE        (1 << 11)
#define DMG_NEVERGIB                        (1 << 12)
#define DMG_ALWAYSGIB                        (1 << 13)
#define DMG_DROWN                        (1 << 14)
#define DMG_TIMEBASED                        (DMG_PARALYZE | DMG_NERVEGAS | DMG_POISON | DMG_RADIATION | DMG_DROWNRECOVER | DMG_ACID | DMG_SLOWBURN)
#define DMG_PARALYZE                        (1 << 15)
#define DMG_NERVEGAS                        (1 << 16)
#define DMG_POISON                        (1 << 17)
#define DMG_RADIATION                        (1 << 18)
#define DMG_DROWNRECOVER                (1 << 19)
#define DMG_ACID                        (1 << 20)
#define DMG_SLOWBURN                        (1 << 21)
#define DMG_REMOVENORAGDOLL                (1 << 22)
#define DMG_PHYSGUN                        (1 << 23)
#define DMG_PLASMA                        (1 << 24)
#define DMG_AIRBOAT                        (1 << 25)
#define DMG_DISSOLVE                        (1 << 26)
#define DMG_BLAST_SURFACE                (1 << 27)
#define DMG_DIRECT                        (1 << 28)
#define DMG_BUCKSHOT                        (1 << 29)

DealDamage(victim,damage,attacker=0,dmg_type=DMG_GENERIC,String:weapon[]="")
{
        if(victim>0 && IsValidEdict(victim) && IsClientInGame(victim) && IsPlayerAlive(victim) && damage>0)
        {
                new String:dmg_str[16];
                IntToString(damage,dmg_str,16);
                new String:dmg_type_str[32];
                IntToString(dmg_type,dmg_type_str,32);
                new pointHurt=CreateEntityByName("point_hurt");
                if(pointHurt)
                {
                        DispatchKeyValue(victim,"targetname","war3_hurtme");
                        DispatchKeyValue(pointHurt,"DamageTarget","war3_hurtme");
                        DispatchKeyValue(pointHurt,"Damage",dmg_str);
                        DispatchKeyValue(pointHurt,"DamageType",dmg_type_str);
                        if(!StrEqual(weapon,""))
                        {
                                DispatchKeyValue(pointHurt,"classname",weapon);
                        }
                        DispatchSpawn(pointHurt);
                        AcceptEntityInput(pointHurt,"Hurt",(attacker>0)?attacker:-1);
                        DispatchKeyValue(pointHurt,"classname","point_hurt");
                        DispatchKeyValue(victim,"targetname","war3_donthurtme");
                        RemoveEdict(pointHurt);
                }
        }
}

Example usage:
Code:

DealDamage(victim_index,50,attacker_index,DMG_BULLET,"weapon_ak47");
Works for CSS and TF2, should work for all games.

Creating and deleting an entity every time you do a damage call is a little inefficient IMO.

If you really wanted to use this method, I'd spawn a point_hurt one time at map start and then always use that entity rather than constantly respawning them.

And even then, I'd only do that in the absence of the extension that does it properly.

Just my opinion dont mind me :)

Sammy-ROCK! 12-17-2009 20:56

Re: Proper way to deal damage without extensions
 
Then it would need to be integrated with your plugin and not a simple snippet.

Darkimmortal 12-23-2009 00:32

Re: Proper way to deal damage without extensions
 
I take it there's no way to deal damage from the client to themselves with this?

Specifically in conjunction with pyro flamethrower to create a jetpack effect in PropHunt.

CrancK 12-23-2009 11:43

Re: Proper way to deal damage without extensions
 
if you kill people using damage like this, making the attacker another client, what kill-message would come up (tf2 particularly?)

the weapon the attacker is currently holding? or a world kill message?

also, i'm guessing this way painsounds automatically play?
(my previous method of dealing damage made use of SetEntityHealth, and thus had no sound, which i had to provide for it :shock:)

edit: ohw, also... does this damage push a player?

Sammy-ROCK! 12-23-2009 16:07

Re: Proper way to deal damage without extensions
 
A suicide message like when a soldier kills himself with a rocket?

Dragonshadow 12-24-2009 09:39

Re: Proper way to deal damage without extensions
 
Quote:

Originally Posted by Darkimmortal (Post 1027857)
I take it there's no way to deal damage from the client to themselves with this?

Specifically in conjunction with pyro flamethrower to create a jetpack effect in PropHunt.


When I kill myself with damage from myself to myself with the demoman bottle it gives me a kill message like this:

|Bottle Icon| |My name|

API 12-24-2009 15:14

Re: Proper way to deal damage without extensions
 
Quote:

Originally Posted by CrancK (Post 1028328)
if you kill people using damage like this, making the attacker another client, what kill-message would come up (tf2 particularly?)

the weapon the attacker is currently holding? or a world kill message?

also, i'm guessing this way painsounds automatically play?
(my previous method of dealing damage made use of SetEntityHealth, and thus had no sound, which i had to provide for it :shock:)

edit: ohw, also... does this damage push a player?

Yes, with this function proper death messages occur, as well as stat plugin compatibility.
DealDamage(victim_index,50,attacker_index,DMG _BULLET,"weapon_ak47");

That would make the engine think victim_index was shot for 50 damage (armor distribution works too) with an AK47 used by attacker_index. You can have alot of fun experimenting with Damage type as well.

Dragonshadow 12-24-2009 15:48

Re: Proper way to deal damage without extensions
 
I wish the time based damages worked on tf2.

Downtown1 12-24-2009 16:39

Re: Proper way to deal damage without extensions
 
Is there a way to use something like this to -cancel- damage being given?

psychonic 12-24-2009 16:49

Re: Proper way to deal damage without extensions
 
Quote:

Originally Posted by Downtown1 (Post 1030033)
Is there a way to use something like this to -cancel- damage being given?

No. You would need to hook and block the damage with an extension.

meng 12-24-2009 17:29

Re: Proper way to deal damage without extensions
 
one thing worth mentioning, a while ago i tried something like this to "modify" damage. you cant use it inside a player_hurt event and try and deal damage with the weapon used by the attacker, since it fires the same event before handling the first one. i hope that makes sense :|. maybe you guys know a way around this?

Dragonshadow 12-24-2009 21:57

Re: Proper way to deal damage without extensions
 
Quote:

Originally Posted by meng (Post 1030098)
one thing worth mentioning, a while ago i tried something like this to "modify" damage. you cant use it inside a player_hurt event and try and deal damage with the weapon used by the attacker, since it fires the same event before handling the first one. i hope that makes sense :|. maybe you guys know a way around this?

You'd need a hook to block the damage and then use this to give the kind you want.

CrancK 12-25-2009 11:49

Re: Proper way to deal damage without extensions
 
Quote:

Originally Posted by pimpinjuice (Post 1029955)
Yes, with this function proper death messages occur, as well as stat plugin compatibility.
DealDamage(victim_index,50,attacker_index,DMG _BULLET,"weapon_ak47");

That would make the engine think victim_index was shot for 50 damage (armor distribution works too) with an AK47 used by attacker_index. You can have alot of fun experimenting with Damage type as well.

ok, thx...

erm, quick question though, that means i need a weapon name, which i can easily find... but, what if i want to make like a new weapon, then use this code to make it do damage?

of course, i can make it use a weapon name thats already used, but then people will get confused as to which weapon actually killed/hurt/whatevered them...

so, i guess my question(s) is/are:

are there unused weapons? if so, how to find them? (tf2 this case)

or

can i somehow extend the list of possible choices?

Dragonshadow 12-25-2009 14:29

Re: Proper way to deal damage without extensions
 
Is there a way to change the origin or direction the damage is delt from? When I kill someone with this they always fly a certain direction, its never random (like its always north->south damage, making their body fly south)

meng 12-25-2009 15:06

Re: Proper way to deal damage without extensions
 
yea, just teleport the point_hurt to the attacker position.

CrancK 12-28-2009 07:08

Re: Proper way to deal damage without extensions
 
i've slightly altered it so i could use it on multiple people at the same time,
but it seems to not be working as in it doesn't damage people.

it doesn't error out however as server console logthingy is clean

can anyone spot where i've gone wrong?

PHP Code:

SetupPointHurt()
{
    for(new 
i=0;i<MAX_PLAYERS;i++)
    {
        
pointHurt[i] = CreateEntityByName("point_hurt");
        
DispatchSpawn(pointHurt[i]);
        
TeleportEntity(pointHurt[i], gHoldingAreaNULL_VECTORNULL_VECTOR);
    }
}

DealDamage(victim,damage,attacker=0,dmg_type=DMG_GENERIC,String:weapon[]="")
{
    if(
victim>&& IsValidEdict(victim) && IsClientInGame(victim) && IsPlayerAlive(victim) && damage>0)
    {
        new 
String:dmg_str[16];
        
IntToString(damage,dmg_str,16);
        new 
String:dmg_type_str[32];
        
IntToString(dmg_type,dmg_type_str,32);
        
//new pointHurt=CreateEntityByName("point_hurt");
        
if(pointHurt[victim])
        {
            new 
Float:vicOri[3];
            
GetClientAbsOrigin(victimvicOri);
            
TeleportEntity(pointHurt[victim], vicOriNULL_VECTORNULL_VECTOR);
            
DispatchKeyValue(victim,"targetname","hurtme");
            
DispatchKeyValue(pointHurt[victim],"DamageTarget","hurtme");
            
DispatchKeyValue(pointHurt[victim],"Damage",dmg_str);
            
DispatchKeyValue(pointHurt[victim],"DamageType",dmg_type_str);
            if(!
StrEqual(weapon,""))
            {
                
DispatchKeyValue(pointHurt[victim],"classname",weapon);
            }
            
//DispatchSpawn(pointHurt);
            
AcceptEntityInput(pointHurt[victim],"Hurt",(attacker>0)?attacker:-1);
            
DispatchKeyValue(pointHurt[victim],"classname","point_hurt");
            
DispatchKeyValue(victim,"targetname","donthurtme");
            
CreateTimer(0.01TPHurtvictim);
            
//RemoveEdict(pointHurt);
        
}
    }
}

public 
Action:TPHurt(Handle:timerany:client)
{
    
TeleportEntity(pointHurt[client], gHoldingAreaNULL_VECTORNULL_VECTOR);


SetupPointHurt is called at mapstart, and makes all the point hurts i'll ever need (probably too many, but for the moment it'll do)
TPHurt is probably not needed, since i don't think its possible to see point hurts ingame, but ahwell..
also a slight change in DealDamage aswell, as i teleport it to the victim, so it should damage it from the right direction(?)

and i call the DealDamage with:

PHP Code:

DealDamage(jdamageclientDMG_GENERIC"n_rocketlauncher"); 

so... where have i gone wrong?

edit: also, slight sidequestion, can this also damage buildings? or destroyable entities?

edit2: it is! possible to see point hurts...(i tried it without the TPHurt function) so yes, the point hurt is even teleported to the right position... it still doesn't do damage though...

API 12-28-2009 15:05

Re: Proper way to deal damage without extensions
 
You could do this:

Code:

stock MultiDealDamage(Handle:hVictims,victimCount,damage,attacker=0,dmg_type=DMG_GENERIC,String:weapon[]="")
{
    ResetPack(hVictims);
    for(new x=0;x<victimCount;x++)
    {
        new victim=ReadPackCell(hVictims);
        DealDamage(victim,damage,attacker,dmg_type,weapon);
    }
}

You'd call it like this:
Code:

new Handle:hPack=CreateDataPack();
WritePackCell(hPack,victim1);
WritePackCell(hPack,victim2);
MultiDealDamage(hPack,2,70,attacker,DMG_BULLET,"weapon_rocket");
CloseHandle(hPack);

Thats using datapacks, you can use an array if you want.

CrancK 12-29-2009 03:58

Re: Proper way to deal damage without extensions
 
ok, interesting idea, i'll try it out

i see you use "weapon_rocket" as weapon name, and i can't really find any reference as to where you got that name from, is there a list with all the tf2 weapon names somewhere perhaps?

edit: nvm, just found it on the wikithing, its the entity name, not the classname as i thought, right? (nvm, tried all names, classnames&entitynames, even modelnames, nothing works)

edit2: alright, i've tried every name i could find for weapons in tf2, tried it without a weaponname, and still, the pointhurt doesn't hurt anyone.

i've checked, it's got the right victim&attacker, the right weaponname, the right damage, it goes through every line of code, yet somehow when it does: AcceptEntityInput(pointHurt[victim],"Hurt",(attacker>0)?attacker:-1);
it doesn't hurt anyone... :(

i mean... why?

(though, it can't be just because i might have a wrong weaponname, right? since it only applies if it has one, right? though then.... it's even more strange, since there isn't a reason why it shouldn't work...)

are certain damagetype maybe not available in tf2? (i'm just guessing by now)

API 12-29-2009 11:40

Re: Proper way to deal damage without extensions
 
Paste your exact code. Weapon name only effects death messages.

CrancK 12-29-2009 15:12

Re: Proper way to deal damage without extensions
 
well, my code is basically what i posted earlier, or do you mean the whole plugin i'm making?

anyway, atm i'm trying this:

PHP Code:

DealDamage(jdamagecenterclientDMG_CRUSH"tf_weapon_rocketlauncher"); 

where j = entity index(though in this case limited to only client indexes), damage = integer range from 20-100, client = client index range from 1-GetMaxClients()

PHP Code:

SetupPointHurt()
{
    for(new 
i=0;i<MAX_PLAYERS;i++)
    {
        
pointHurt[i] = CreateEntityByName("point_hurt");
        
DispatchSpawn(pointHurt[i]);
        
TeleportEntity(pointHurt[i], gHoldingAreaNULL_VECTORNULL_VECTOR);
    }
}

DealDamage(victimdamageFloat:loc[3],attacker=0,dmg_type=DMG_GENERIC,String:weapon[]="")
{
    if(
victim>&& IsValidEdict(victim) && IsClientInGame(victim) && IsPlayerAlive(victim) && damage>0)
    {
        new 
String:dmg_str[16];
        
IntToString(damage,dmg_str,16);
        new 
String:dmg_type_str[32];
        
IntToString(dmg_type,dmg_type_str,32);
        
PrintToChat(victim"victim %i is valid and hit by attacker %i"victimattacker);
        if(
pointHurt[victim])
        {
            
TeleportEntity(pointHurt[victim], locNULL_VECTORNULL_VECTOR);
            
DispatchKeyValue(victim,"targetname","hurtme");
            
DispatchKeyValue(pointHurt[victim],"DamageTarget","hurtme");
            
DispatchKeyValue(pointHurt[victim],"Damage",dmg_str);
            
DispatchKeyValue(pointHurt[victim],"DamageType",dmg_type_str);
            if(!
StrEqual(weapon,""))
            {
                
PrintToChat(victim"weaponname = %s"weapon);
                
DispatchKeyValue(pointHurt[victim],"classname",weapon);
            }
            
AcceptEntityInput(pointHurt[victim],"Hurt",(attacker>0)?attacker:-1);
            
DispatchKeyValue(pointHurt[victim],"classname","point_hurt");
            
DispatchKeyValue(victim,"targetname","donthurtme");
            
CreateTimer(0.01TPHurtvictim);
        }
    }
}

public 
Action:TPHurt(Handle:timerany:client)
{
    
TeleportEntity(pointHurt[client], gHoldingAreaNULL_VECTORNULL_VECTOR);


the printtochat's were for checking

edit: i've now also tried giving each victim an unique targetname, to see wether it might have been caused by that, but no luck, still no damage

Greyscale 12-29-2009 21:04

Re: Proper way to deal damage without extensions
 
That's pretty awesome. Could come in handy :)

CrancK 12-30-2009 09:58

Re: Proper way to deal damage without extensions
 
ok i've tested it proper now, simply your code, but then with a command so i can use it ingame:

PHP Code:

#pragma semicolon 1

#include <sourcemod>
#include <sdktools>
#include <tf2>
#include <tf2_stocks>
#define PLUGIN_VERSION "0.0.1"

#define MAX_PLAYERS 33

#define DMG_GENERIC            0
#define DMG_CRUSH            (1 << 0)
#define DMG_BULLET            (1 << 1)
#define DMG_SLASH            (1 << 2)
#define DMG_BURN            (1 << 3)
#define DMG_VEHICLE            (1 << 4)
#define DMG_FALL            (1 << 5)
#define DMG_BLAST            (1 << 6)
#define DMG_CLUB            (1 << 7)
#define DMG_SHOCK            (1 << 8)
#define DMG_SONIC            (1 << 9)
#define DMG_ENERGYBEAM            (1 << 10)
#define DMG_PREVENT_PHYSICS_FORCE    (1 << 11)
#define DMG_NEVERGIB            (1 << 12)
#define DMG_ALWAYSGIB            (1 << 13)
#define DMG_DROWN            (1 << 14)
#define DMG_TIMEBASED            (DMG_PARALYZE | DMG_NERVEGAS | DMG_POISON | DMG_RADIATION | DMG_DROWNRECOVER | DMG_ACID | DMG_SLOWBURN)
#define DMG_PARALYZE            (1 << 15)
#define DMG_NERVEGAS            (1 << 16)
#define DMG_POISON            (1 << 17)
#define DMG_RADIATION            (1 << 18)
#define DMG_DROWNRECOVER        (1 << 19)
#define DMG_ACID            (1 << 20)
#define DMG_SLOWBURN            (1 << 21)
#define DMG_REMOVENORAGDOLL        (1 << 22)
#define DMG_PHYSGUN            (1 << 23)
#define DMG_PLASMA            (1 << 24)
#define DMG_AIRBOAT            (1 << 25)
#define DMG_DISSOLVE            (1 << 26)
#define DMG_BLAST_SURFACE        (1 << 27)
#define DMG_DIRECT            (1 << 28)
#define DMG_BUCKSHOT            (1 << 29)

public Plugin:myinfo = {
    
name "TF2 ...",
    
author "CrancK",
    
description "...",
    
version PLUGIN_VERSION,
    
url ""
};

new 
Handle:pEnabled;


public 
OnPluginStart()
{
    
RegConsoleCmd("sm_damage"Command_Damage"Damage a person.");
    
pEnabled CreateConVar("sm_damage_enabled""1""...");
}


public 
Action:Command_Damage(clientargs
{
    if(
GetConVarInt(pEnabled) == 1) {
        if(
args>0) {
            new 
String:arg[32];
            
GetCmdArg(1argsizeof(arg));
            for(new 
i=0;i<strlen(arg);i++) {
                if(!
IsCharNumeric(arg[i])) {
                    
ReplyToCommand(client"Value must be an integer.");
                    return 
Plugin_Handled;
                }
            }
            if(
StringToInt(arg)<=|| StringToInt(arg)>GetMaxClients()) {
                
ReplyToCommand(client"Value must be between 1 and %i."GetMaxClients());
                return 
Plugin_Handled;
            }
            new 
victim StringToInt(arg);
            
DealDamage(victim25clientDMG_GENERIC"tf_weapon_rocketlauncher");
            
ReplyToCommand(client"damaged.");
        } else {
            
ReplyToCommand(client"damaged");
        }
        return 
Plugin_Handled;
    }
    return 
Plugin_Continue;
}



DealDamage(victim,damage,attacker=0,dmg_type=DMG_GENERIC,String:weapon[]="")
{
    if(
victim>&& IsValidEdict(victim) && IsClientInGame(victim) && IsPlayerAlive(victim) && damage>0)
    {
        new 
String:dmg_str[16];
        
IntToString(damage,dmg_str,16);
        new 
String:dmg_type_str[32];
        
IntToString(dmg_type,dmg_type_str,32);
        new 
pointHurt=CreateEntityByName("point_hurt");
        if(
pointHurt)
        {
            
DispatchKeyValue(victim,"targetname","war3_hurtme");
            
DispatchKeyValue(pointHurt,"DamageTarget","war3_hurtme");
            
DispatchKeyValue(pointHurt,"Damage",dmg_str);
            
DispatchKeyValue(pointHurt,"DamageType",dmg_type_str);
            if(!
StrEqual(weapon,""))
            {
                
DispatchKeyValue(pointHurt,"classname",weapon);
            }
            
DispatchSpawn(pointHurt);
            
AcceptEntityInput(pointHurt,"Hurt",(attacker>0)?attacker:-1);
            
DispatchKeyValue(pointHurt,"classname","point_hurt");
            
DispatchKeyValue(victim,"targetname","war3_donthurtme");
            
RemoveEdict(pointHurt);
        }
    }


this works, though only limited

it does hurt people, although people don't scream of pain when hit with this (or do people need a certain amount of damage before painsounds start being used? since atm i'm using amounts of 25)

and when it kills people, console gives out the right kill message, but the message that shows up ingame is always a skull, instead of the weapon i told it :S

am i doing something wrong to not get the killmessages/painsounds?

also still don't understand why my alteration(post before) doesn't work though, it basically does the exact same thing, except for the fact that i create them at start, and teleport them round a bit, the damaging part is identical, yet non-functioning :(



edit1:ahh eff it, i'll just keep making and deleting pointhurts, if thats what it takes to make this working (which it did btw)
only having some problem with killmessages but that was because i was using projectile weapons, and obviously i didn't think of a rocket being the killer instead of the rocketlauncher (it worked with tf_projectile_rocket)

anyway, thanks for the code and the help

edit2:btw, anyone perhaps know how to get this kill-message: http://www.mzzt.net/tf2/dark/unusedexplosion.png ?
or rather, know the weaponname/classname?

API 12-31-2009 16:52

Re: Proper way to deal damage without extensions
 
Sorry, not sure about that death message. By the way, reusing an entity is probably no different than the method I provided. The reason being I remove the entity when I am finished.

blodia 01-04-2010 13:59

Re: Proper way to deal damage without extensions
 
you can fake a headshot in css easily

for the weapon name to pass to the DealDamage function make a unique name with the weapon_ prefix e.g weapon_testgun then.

PHP Code:

public OnPluginStart()
{
    
HookEvent("player_death"Event_PlayerDeathPreEventHookMode_Pre);
}

public 
Action:Event_PlayerDeathPre(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
String:getweapon[50];
    
GetEventString(event"weapon"getweaponsizeof(getweapon));
    if (
StrEqual(getweapon"testgun"false))
    {
        
SetEventString(event"weapon""ak47");
        
SetEventBool(event"headshot"true);
    }
    return 
Plugin_Continue;


that will change the death notice for anyone killed by testgun to an ak headshot.

some info on death notices in css. if you change the weapon name in pre death event to a weapon that doesn't exist or to a weapon that doesn't have an icon the skull icon is used. you can set the weapon to "headshot" to get just the headshot icon as the weapon used. there is an unused icon for killing someone with a shield called "shieldgun". you can also use hl1 weapon names although it only gives partial kill icons.

most death icons that are available are inside scripts/mod_textures.txt so for any unused icons that would be the first place to check. i tried to get custom death icons working last summer through eventscripts and partially got it working. you can't get players to download files they have so i embedded a modified mod_textures.txt into a test map and managed to get the custom kill icons working only when a player minimised then maximised the game which causes most files to be reloaded, in that case the files embedded in the map get priority over the clients files.

dirtyminuth 04-10-2010 01:03

Re: Proper way to deal damage without extensions
 
For more information, I've included a modified version of this feature. It's intended for TF2, simplified, includes some assumptions, but more importantly fixes a potential infinite loop issue. Code first, then explanation!

applyDamage()
PHP Code:

stock applyDamage(damagevictimattacker=0)

  new 
Handle:dataPack CreateDataPack();
  
WritePackCell(dataPackdamage);  
  
WritePackCell(dataPackvictim);
  
WritePackCell(dataPackattacker);

  
// Delay damage event by a small amount.
  // Prevents infinite [damage > death > damage > ...] loops.
  
CreateTimer(0.10timer_applyDamagedataPack);


timer_applyDamage()
PHP Code:

public Action:timer_applyDamage(Handle:timerHandle:dataPack)
{    
  
ResetPack(dataPack);
  new 
damage ReadPackCell(dataPack);  
  new 
victim ReadPackCell(dataPack);
  new 
attacker ReadPackCell(dataPack);
  
CloseHandle(dataPack);   

  if((
damage 0) && IsClientInGame(victim) && IsPlayerAlive(victim))
  {
    
decl Float:victimPos[3];
    
decl String:strDamage[16];
    
decl String:strDamageTarget[16];
  
    
getClientPos(victimvictimPos);
    
IntToString(damagestrDamage16);
    
Format(strDamageTarget16"hurtme%d"victim);  

    new 
entPointHurt CreateEntityByName("point_hurt");
    if(
entPointHurt)
    {
      
// Config, create point_hurt
      
DispatchKeyValue(victim"targetname"strDamageTarget);
      
DispatchKeyValue(entPointHurt"DamageTarget"strDamageTarget);
      
DispatchKeyValue(entPointHurt"Damage"strDamage);
      
DispatchKeyValue(entPointHurt"DamageType""0"); // DMG_GENERIC
      
DispatchSpawn(entPointHurt);
      
      
// Teleport, activate point_hurt
      
TeleportEntity(entPointHurtvictimPosNULL_VECTORNULL_VECTOR);
      
AcceptEntityInput(entPointHurt"Hurt", (attacker 0) ? attacker : -1);
      
      
// Config, delete point_hurt
      
DispatchKeyValue(entPointHurt"classname""point_hurt");
      
DispatchKeyValue(victim"targetname""null");
      
RemoveEdict(entPointHurt);
    }
  }
  
  return 
Plugin_Continue;


Now, given the logic of the mod I'm working on, when a player dies, he can cause damage to all nearby enemies. What could happen (in the non delayed damage code) is this:

1) Client X dies (player_death event fires).
2) Client X death causes damage to nearby enemy, client Y.
3) Damage to client Y is sufficient to kill them.
4) Thus, client Y dies (player_death event fires).
5) Client Y death causes damage to nearby enemy, client X.
6) See step 1. Repeat until SM stack overflow.

You'll notice that, in that loop, client X dies multiple times resulting from a single death event. Tracking debugging output in SM indicates that yes, a client can die multiple times under such circumstances, and the player_death event can even be called for clients with negative health!

Either way, for those interested in this feature, I hope this helps.

bl4nk 04-10-2010 09:56

Re: Proper way to deal damage without extensions
 
It seems like it would be easier to just track if you've "killed" a target rather than going through timers and such. Thanks for the stocks though. :up:

blodia 04-10-2010 10:20

Re: Proper way to deal damage without extensions
 
you don't need to teleport the point_hurt if you use a target entity to hurt.

if you want to hurt people within a radius of a person who dies its easier to use the none target method. teleport the point_hurt to the coords of the player who died, set radius to the radius you want to injure near by players, leave the damagetarget part blank then fire the hurt input and all players within the radius will take damage.


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

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