Added test plugin for dumping damage information.

This commit is contained in:
Richard Helgeby 2012-08-20 17:55:47 +02:00
parent 58a1d6dcdf
commit 2c68af4d84
2 changed files with 509 additions and 0 deletions

345
env/include/sdkhooks-2.2.inc vendored Normal file
View File

@ -0,0 +1,345 @@
#if defined _sdkhooks_included
#endinput
#endif
#define _sdkhooks_included
// this is obviously _not_ a robust check, but it will solve most conflict and is clean
#if !defined DMG_GENERIC
#define DMG_GENERIC 0 // generic damage was done
#define DMG_CRUSH (1 << 0) // crushed by falling or moving object.
// NOTE: It's assumed crush damage is occurring as a result of physics collision, so no extra physics force is generated by crush damage.
// DON'T use DMG_CRUSH when damaging entities unless it's the result of a physics collision. You probably want DMG_CLUB instead.
#define DMG_BULLET (1 << 1) // shot
#define DMG_SLASH (1 << 2) // cut, clawed, stabbed
#define DMG_BURN (1 << 3) // heat burned
#define DMG_VEHICLE (1 << 4) // hit by a vehicle
#define DMG_FALL (1 << 5) // fell too far
#define DMG_BLAST (1 << 6) // explosive blast damage
#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt
#define DMG_SHOCK (1 << 8) // electric shock
#define DMG_SONIC (1 << 9) // sound pulse shockwave
#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam
#define DMG_PREVENT_PHYSICS_FORCE (1 << 11) // Prevent a physics force
#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death
#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death.
#define DMG_DROWN (1 << 14) // Drowning
#define DMG_PARALYZE (1 << 15) // slows affected creature down
#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad
#define DMG_POISON (1 << 17) // blood poisoning - heals over time like drowning damage
#define DMG_RADIATION (1 << 18) // radiation exposure
#define DMG_DROWNRECOVER (1 << 19) // drowning recovery
#define DMG_ACID (1 << 20) // toxic chemicals or acid burns
#define DMG_SLOWBURN (1 << 21) // in an oven
#define DMG_REMOVENORAGDOLL (1 << 22) // with this bit OR'd in, no ragdoll will be created, and the target will be quietly removed.
// use this to kill an entity that you've already got a server-side ragdoll for
#define DMG_PHYSGUN (1 << 23) // Hit by manipulator. Usually doesn't do any damage.
#define DMG_PLASMA (1 << 24) // Shot by Cremator
#define DMG_AIRBOAT (1 << 25) // Hit by the airboat's gun
#define DMG_DISSOLVE (1 << 26) // Dissolving!
#define DMG_BLAST_SURFACE (1 << 27) // A blast on the surface of water that cannot harm things underwater
#define DMG_DIRECT (1 << 28)
#define DMG_BUCKSHOT (1 << 29) // not quite a bullet. Little, rounder, different.
#endif
#if !defined DMG_CRIT
// TF2 crits and minicrits
#define DMG_CRIT DMG_ACID
#endif
enum SDKHookType
{
SDKHook_EndTouch,
SDKHook_FireBulletsPost,
SDKHook_OnTakeDamage,
SDKHook_OnTakeDamagePost,
SDKHook_PreThink,
SDKHook_PostThink,
SDKHook_SetTransmit,
SDKHook_Spawn,
SDKHook_StartTouch,
SDKHook_Think,
SDKHook_Touch,
SDKHook_TraceAttack,
SDKHook_TraceAttackPost,
SDKHook_WeaponCanSwitchTo,
SDKHook_WeaponCanUse,
SDKHook_WeaponDrop,
SDKHook_WeaponEquip,
SDKHook_WeaponSwitch,
SDKHook_ShouldCollide,
SDKHook_PreThinkPost,
SDKHook_PostThinkPost,
SDKHook_ThinkPost,
SDKHook_EndTouchPost,
SDKHook_GroundEntChangedPost,
SDKHook_SpawnPost,
SDKHook_StartTouchPost,
SDKHook_TouchPost,
SDKHook_VPhysicsUpdate,
SDKHook_VPhysicsUpdatePost,
SDKHook_WeaponCanSwitchToPost,
SDKHook_WeaponCanUsePost,
SDKHook_WeaponDropPost,
SDKHook_WeaponEquipPost,
SDKHook_WeaponSwitchPost,
SDKHook_Use,
SDKHook_UsePost
};
/*
Alphabetized for easy readability
SDKHook_EndTouch,
SDKHook_EndTouchPost,
SDKHook_FireBulletsPost,
SDKHook_GroundEntChangedPost,
SDKHook_OnTakeDamage,
SDKHook_OnTakeDamagePost,
SDKHook_PreThink,
SDKHook_PreThinkPost,
SDKHook_PostThink,
SDKHook_PostThinkPost,
SDKHook_SetTransmit,
SDKHook_ShouldCollide,
SDKHook_Spawn,
SDKHook_SpawnPost,
SDKHook_StartTouch,
SDKHook_StartTouchPost,
SDKHook_Think,
SDKHook_ThinkPost,
SDKHook_Touch,
SDKHook_TouchPost,
SDKHook_TraceAttack,
SDKHook_TraceAttackPost,
SDKHook_Use,
SDKHook_UsePost,
SDKHook_VPhysicsUpdate,
SDKHook_VPhysicsUpdatePost,
SDKHook_WeaponCanSwitchTo,
SDKHook_WeaponCanSwitchToPost,
SDKHook_WeaponCanUse,
SDKHook_WeaponCanUsePost,
SDKHook_WeaponDrop,
SDKHook_WeaponDropPost,
SDKHook_WeaponEquip,
SDKHook_WeaponEquipPost,
SDKHook_WeaponSwitch,
SDKHook_WeaponSwitchPost
*/
enum UseType
{
Use_Off,
Use_On,
Use_Set,
Use_Toggle
};
funcenum SDKHookCB
{
// PreThink/Post
// PostThink/Post
public(client),
// GroundEntChanged
// Spawn/Post
// Think/Post
// VPhysicsUpdate/Post
public(entity),
// EndTouch
// StartTouch
// Touch
Action:public(entity, other),
// EndTouchPost
// StartTouchPost
// TouchPost
public(entity, other),
// SetTransmit
Action:public(entity, client),
// WeaponCanSwitchTo
// WeaponCanUse
// WeaponDrop
// WeaponEquip
// WeaponSwitch
Action:public(client, weapon),
// WeaponCanSwitchToPost
// WeaponCanUsePost
// WeaponDropPost
// WeaponEquipPost
// WeaponSwitchPost
public(client, weapon),
// OnTakeDamage
// Note: Force application is dependent on game and damage type(s)
Action:public(victim, &attacker, &inflictor, &Float:damage, &damagetype),
Action:public(victim, &attacker, &inflictor, &Float:damage, &damagetype, &weapon, Float:damageForce[3], Float:damagePosition[3]),
// OnTakeDamagePost
public(victim, attacker, inflictor, Float:damage, damagetype),
public(victim, attacker, inflictor, Float:damage, damagetype, weapon, const Float:damageForce[3], const Float:damagePosition[3]),
// FireBulletsPost
public(client, shots, const String:weaponname[]),
// TraceAttack
Action:public(victim, &attacker, &inflictor, &Float:damage, &damagetype, &ammotype, hitbox, hitgroup),
// TraceAttackPost
public(victim, attacker, inflictor, Float:damage, damagetype, ammotype, hitbox, hitgroup),
// ShouldCollide
bool:public(entity, collisiongroup, contentsmask, bool:originalResult),
// Use
Action:public(entity, activator, caller, UseType:type, Float:value),
// UsePost
public(entity, activator, caller, UseType:type, Float:value)
};
/**
* @brief When an entity is created
*
* @param entity Entity index
* @param classname Class name
* @noreturn
*/
forward OnEntityCreated(entity, const String:classname[]);
/**
* @brief When an entity is destroyed
*
* @param entity Entity index
* @noreturn
*/
forward OnEntityDestroyed(entity);
/**
* @brief When the game description is retrieved
*
* @param gameDesc Game description
* @noreturn
*/
forward Action:OnGetGameDescription(String:gameDesc[64]);
/**
* @brief When the level is initialized
*
* @param mapName Name of the map
* @param mapEntities Entities of the map
* @noreturn
*/
forward Action:OnLevelInit(const String:mapName[], String:mapEntities[2097152]);
/**
* @brief Hooks an entity
*
* @param entity Entity index
* @param type Type of function to hook
* @param callback Function to call when hook is called
* @noreturn
*/
native SDKHook(entity, SDKHookType:type, SDKHookCB:callback);
/**
* @brief Hooks an entity
*
* @param entity Entity index
* @param type Type of function to hook
* @param callback Function to call when hook is called
* @return bool Hook Successful
*/
native bool:SDKHookEx(entity, SDKHookType:type, SDKHookCB:callback);
/**
* @brief Unhooks an entity
*
* @param entity Entity index
* @param type Type of function to unhook
* @param callback Callback function to unhook
* @noreturn
*/
native SDKUnhook(entity, SDKHookType:type, SDKHookCB:callback);
/**
* @brief Applies damage to an entity
*
* @note Force application is dependent on game and damage type(s)
*
* @param entity Entity index taking damage
* @param inflictor Inflictor entity index
* @param attacker Attacker entity index
* @param damage Amount of damage
* @param damageType Bitfield of damage types
* @param weapon Weapon index (orangebox and later) or -1 for unspecified
* @param damageForce Velocity of damage force
* @param damagePosition Origin of damage
* @noreturn
*/
native SDKHooks_TakeDamage(entity, inflictor, attacker, Float:damage, damageType=DMG_GENERIC, weapon=-1, const Float:damageForce[3]=NULL_VECTOR, const Float:damagePosition[3]=NULL_VECTOR);
/**
* @brief Forces a client to drop the specified weapon
*
* @param client Client index.
* @param weapon Weapon entity index.
* @param vecTarget Location to toss weapon to, or NULL_VECTOR for default.
* @param vecVelocity Velocity at which to toss weapon, or NULL_VECTOR for default.
* @noreturn
* @error Invalid client or weapon entity, weapon not owned by client.
*/
native SDKHooks_DropWeapon(client, weapon, const Float:vecTarget[3]=NULL_VECTOR, const Float:vecVelocity[3]=NULL_VECTOR);
/** Do Not Edit Below This Line **/
public Extension:__ext_sdkhooks =
{
name = "sdkhooks",
file = "sdkhooks.ext",
#if defined AUTOLOAD_EXTENSIONS
autoload = 1,
#else
autoload = 0,
#endif
#if defined REQUIRE_EXTENSIONS
required = 1,
#else
required = 0,
#endif
};
#if !defined REQUIRE_EXTENSIONS
public __ext_sdkhooks_SetNTVOptional()
{
MarkNativeAsOptional("SDKHook");
MarkNativeAsOptional("SDKHookEx");
MarkNativeAsOptional("SDKUnhook");
MarkNativeAsOptional("SDKHooks_TakeDamage");
MarkNativeAsOptional("SDKHooks_DropWeapon");
}
#endif

View File

@ -0,0 +1,164 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: damageinfo.sp
* Type: Test plugin
* Description: Dumps damage information.
*
* Copyright (C) 2009-2012 Greyscale, Richard Helgeby
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ============================================================================
*/
#pragma semicolon 1
#include <sourcemod>
#include <sdkhooks-2.2>
public Plugin:myinfo =
{
name = "Damage information",
author = "Greyscale | Richard Helgeby",
description = "Dumps damage information.",
version = "1.0.0",
url = "http://code.google.com/p/zombiereloaded/"
};
new Handle:hBlockOnTakeDamage;
new Handle:hBlockTraceAttack;
public OnPluginStart()
{
hBlockOnTakeDamage = CreateConVar("zrtest_blockontakedamage", "0", "Block OnTakeDamage.");
hBlockTraceAttack = CreateConVar("zrtest_blocktraceattack", "0", "Block TraceAttack.");
if (!HookEventEx("player_hurt", Event_PlayerHurt))
{
LogError("Failed to hook event player_hurt.");
}
}
public OnClientPutInServer(client)
{
SDKHook(client, SDKHook_TraceAttack, TraceAttack);
SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
}
public OnClientDisconnect(client)
{
SDKUnhook(client, SDKHook_TraceAttack, TraceAttack);
SDKUnhook(client, SDKHook_OnTakeDamage, OnTakeDamage);
}
public Action:Event_PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
{
new victim = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
new hitgroup = GetEventInt(event, "hitgroup");
new damage = GetEventInt(event, "dmg_health");
new damageArmor = GetEventInt(event, "dmg_armor");
decl String:weapon[64];
weapon[0] = 0;
GetEventString(event, "weapon", weapon, sizeof(weapon));
decl String:msg[128];
msg[0] = 0;
Format(msg, sizeof(msg), "victim:%d | attacker:%d | hitgroup:%d | dmg:%d | dmg armor:%d | weapon:%s", victim, attacker, hitgroup, damage, damageArmor, weapon);
PrintToChat(victim, "Receive hurt event -- %s", msg);
PrintToConsole(victim, "Receive hurt event -- %s", msg);
if (attacker > 0 && attacker < MaxClients)
{
PrintToChat(attacker, "Send hurt event -- %s", msg);
PrintToConsole(attacker, "Send hurt event -- %s", msg);
}
}
public Action:OnTakeDamage(victim, &attacker, &inflictor, &Float:damage, &damagetype, &weapon, Float:damageForce[3], Float:damagePosition[3])
{
/*
Here we can control whether bullets or other damage that hits the
victim's body should be allowed.
If TraceAttack is blocked, bullets will go through the body and the
attacker can't deal any damage to the victim.
By blocking OnTakeDamage we can use this to allow players to actually
hit a player without giving damage to him. This can be used as a simple
trace, for example healing the victim instead of damaging him.
*/
decl String:msg[128];
msg[0] = 0;
Format(msg, sizeof(msg), "victim:%d | attacker:%d | inflictor:%d | dmg:%0.2f | dmg type:%d | weapon ent:%d | force:%0.2f | dmg pos:%0.2f", victim, attacker, inflictor, damage, damagetype, weapon, damageForce, damagePosition);
PrintToChat(victim, "Damage taken -- %s", msg);
PrintToConsole(victim, "Damage taken -- %s", msg);
if (attacker > 0 && attacker < MaxClients)
{
PrintToChat(attacker, "Damage given -- %s", msg);
PrintToConsole(attacker, "Damage given -- %s", msg);
}
if (GetConVarBool(hBlockOnTakeDamage))
{
return Plugin_Handled;
}
else
{
return Plugin_Continue;
}
}
public Action:TraceAttack(victim, &attacker, &inflictor, &Float:damage, &damagetype, &ammotype, hitbox, hitgroup)
{
/*
Here we can control whether bullets or other damage is allowed to hit
the player's body.
If blocked, bullets will go through the body.
OnTakeDamage decides whether damage is actually allowed.
*/
decl String:msg[128];
msg[0] = 0;
Format(msg, sizeof(msg), "victim:%d | attacker:%d | inflictor:%d | dmg:%0.2f | dmg type:%d | ammo type:%d | hitbox:%d | hitgroup: %d", victim, attacker, inflictor, damage, damagetype, ammotype, hitbox, hitgroup);
PrintToChat(victim, "Receive attack -- %s", msg);
PrintToConsole(victim, "Receive attack -- %s", msg);
if (attacker > 0 && attacker < MaxClients)
{
PrintToChat(attacker, "Attacking -- %s", msg);
PrintToConsole(attacker, "Attacking -- %s", msg);
}
if (GetConVarBool(hBlockTraceAttack))
{
return Plugin_Handled;
}
else
{
return Plugin_Continue;
}
}