ZItemKnockback: WIP

This commit is contained in:
BotoX 2019-09-05 19:45:20 +02:00
parent 68fd7f5f59
commit 550524cda4
3 changed files with 749 additions and 506 deletions

View File

@ -0,0 +1,72 @@
"Games"
{
"cstrike"
{
"Signatures"
{
"CCSPlayer::FireBullet"
{
"library" "server"
"linux" "@_ZN9CCSPlayer10FireBulletE6VectorRK6QAnglefiiifP11CBaseEntitybff"
}
}
"Functions"
{
"CCSPlayer__FireBullet"
{
"signature" "CCSPlayer::FireBullet"
"callconv" "thiscall"
"return" "int"
"this" "entity"
"arguments"
{
"vecSrc"
{
"type" "vectorptr"
}
"shootAngles"
{
"type" "objectptr"
}
"vecSpread"
{
"type" "float"
}
"iPenetration"
{
"type" "int"
}
"iBulletType"
{
"type" "int"
}
"iDamage"
{
"type" "int"
}
"flRangeModifier"
{
"type" "float"
}
"pevAttacker"
{
"type" "cbaseentity"
}
"bDoEffects"
{
"type" "bool"
}
"x"
{
"type" "float"
}
"y"
{
"type" "float"
}
}
}
}
}
}

View File

@ -5,7 +5,7 @@
#include <sourcemod>
#include <sdkhooks>
#include <sdktools>
#include <dhooks>
public Plugin myinfo =
{
@ -16,8 +16,30 @@ public Plugin myinfo =
url = ""
};
Handle hFireBulletDetour;
int g_LastAttacker = 0;
int g_LastVictim = 0;
public void OnPluginStart()
{
Handle hGameData = LoadGameConfigFile("ZItemKnockback.games");
if(!hGameData)
SetFailState("Failed to load ZItemKnockback gamedata.");
hFireBulletDetour = DHookCreateFromConf(hGameData, "CCSPlayer__FireBullet");
if(!hFireBulletDetour)
SetFailState("Failed to setup detour for CCSPlayer__FireBullet");
delete hGameData;
if(!DHookEnableDetour(hFireBulletDetour, false, Detour_OnFireBullet))
SetFailState("Failed to detour CCSPlayer__FireBullet.");
for(int client = 1; client <= MaxClients; client++)
{
if(IsClientInGame(client))
OnClientPutInServer(client);
}
}
public void OnClientPutInServer(int client)
@ -39,13 +61,10 @@ public Action OnWeaponEquip(int client, int entity)
if(!HammerID)
return;
char sTargetname[64];
GetEntPropString(entity, Prop_Data, "m_iName", sTargetname, sizeof(sTargetname));
CheckWeaponChildren(client, entity);
CheckChildren(client, entity);
}
void CheckWeaponChildren(int client, int parent)
void CheckChildren(int client, int parent)
{
int entity = INVALID_ENT_REFERENCE;
while((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE)
@ -56,30 +75,64 @@ void CheckWeaponChildren(int client, int parent)
char sClassname[64];
GetEntityClassname(entity, sClassname, sizeof(sClassname));
char sTargetname[64];
GetEntPropString(entity, Prop_Data, "m_iName", sTargetname, sizeof(sTargetname));
PrintToChatAll("%d child: \"%s\" %d (%s)", client, sClassname, entity, sTargetname);
if(!strncmp(sClassname, "func_physbox", 12, false) || !strcmp(sClassname, "func_breakable", false))
{
SDKHook(entity, SDKHook_OnTakeDamagePost, OnTakeDamagePost);
SDKHook(entity, SDKHook_OnTakeDamage, OnTakeDamage);
PrintToChatAll("Hooking \"%s\" %d (%s) OnTakeDamage", sClassname, entity, sTargetname);
}
else if(!strcmp(sClassname, "trigger_push", false))
{
AcceptEntityInput(entity, "Kill");
PrintToChatAll("Killing \"%s\" %d (%s)", sClassname, entity, sTargetname);
}
else
{
CheckChildren(client, entity);
}
}
}
public void OnTakeDamagePost(int victim, int attacker, int inflictor, float damage, int damagetype, int weapon, const float damageForce[3], const float damagePosition[3])
public MRESReturn Detour_OnFireBullet(int pThis, Handle hParams)
{
if(attacker <= 0 || attacker > MAXPLAYERS)
return;
int iKnife = GetEntPropEnt(victim, Prop_Data, "m_pParent");
if(iKnife <= 0)
return;
int client = GetEntPropEnt(iKnife, Prop_Data, "m_hOwnerEntity");
if(client <= 0 || client > MAXPLAYERS)
return;
SDKHooks_TakeDamage(client, inflictor, attacker, damage, damagetype, weapon, damageForce, damagePosition);
PrintToServer("OnFireBullet called on entity %d!", pThis);
g_LastAttacker = 0;
g_LastVictim = 0;
return MRES_Handled;
}
public Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3])
{
PrintToChatAll("OnTakeDamage(%d, %d, %d, %f, %d, %d)", victim, attacker, inflictor, damage, damagetype, weapon);
if(attacker <= 0 || attacker > MAXPLAYERS)
return Plugin_Continue;
int client = victim;
while((client = GetEntPropEnt(client, Prop_Data, "m_pParent")) != INVALID_ENT_REFERENCE)
{
if(client >= 1 && client <= MAXPLAYERS)
break;
}
PrintToChatAll("\tclient = %d", client);
if(client <= 0)
return Plugin_Handled;
// TODO: Fix for knife
if(g_LastAttacker == attacker && g_LastVictim == client)
return Plugin_Handled;
g_LastAttacker = attacker;
g_LastVictim = client;
victim = client;
PrintToChatAll("\tvictim = %d", victim);
SDKHooks_TakeDamage(victim, inflictor, attacker, damage, damagetype, weapon, damageForce, damagePosition);
return Plugin_Handled;
}

File diff suppressed because it is too large Load Diff