From 78993cbc70849b37828a0e6db2b33d970fb2dde2 Mon Sep 17 00:00:00 2001 From: BotoX Date: Fri, 27 Sep 2019 17:40:51 +0200 Subject: [PATCH] Add support for DamageProxy plugin. --- env/include/sdkhooks.inc | 3 +- src/include/zombiereloaded.inc | 4 ++ src/include/zr/knockback.zr.inc | 42 +++++++++++++++ src/zombiereloaded.sp | 1 + src/zr/api/api.inc | 2 + src/zr/api/knockback.api.inc | 68 +++++++++++++++++++++++ src/zr/event.inc | 1 + src/zr/immunityhandler.inc | 2 +- src/zr/knockback.inc | 95 +++++++++++++++++++++++++++++++-- 9 files changed, 211 insertions(+), 7 deletions(-) create mode 100644 src/include/zr/knockback.zr.inc create mode 100644 src/zr/api/knockback.api.inc diff --git a/env/include/sdkhooks.inc b/env/include/sdkhooks.inc index 07c8d9c..cd0aec2 100644 --- a/env/include/sdkhooks.inc +++ b/env/include/sdkhooks.inc @@ -408,10 +408,11 @@ native void SDKUnhook(int entity, SDKHookType type, SDKHookCB callback); * @param weapon Weapon index (orangebox and later) or -1 for unspecified * @param damageForce Velocity of damage force * @param damagePosition Origin of damage + * @param damageCustom User custom */ native void SDKHooks_TakeDamage(int entity, int inflictor, int attacker, float damage, int damageType=DMG_GENERIC, int weapon=-1, - const float damageForce[3]=NULL_VECTOR, const float damagePosition[3]=NULL_VECTOR); + const float damageForce[3]=NULL_VECTOR, const float damagePosition[3]=NULL_VECTOR, int damageCustom=0); /** * Forces a client to drop the specified weapon diff --git a/src/include/zombiereloaded.inc b/src/include/zombiereloaded.inc index 797e831..861a280 100644 --- a/src/include/zombiereloaded.inc +++ b/src/include/zombiereloaded.inc @@ -35,6 +35,7 @@ #include #include #include +#include public SharedPlugin __pl_zombiereloaded = { @@ -64,5 +65,8 @@ public void __pl_zombiereloaded_SetNTVOptional() MarkNativeAsOptional("ZR_RespawnClient"); MarkNativeAsOptional("ZR_SetKilledByWorld"); MarkNativeAsOptional("ZR_GetKilledByWorld"); + + MarkNativeAsOptional("ZR_SetClientKnockbackMaxVelocity"); + MarkNativeAsOptional("ZR_SetClientKnockbackScale"); } #endif diff --git a/src/include/zr/knockback.zr.inc b/src/include/zr/knockback.zr.inc new file mode 100644 index 0000000..929ff7f --- /dev/null +++ b/src/include/zr/knockback.zr.inc @@ -0,0 +1,42 @@ +/* + * ============================================================================ + * + * Zombie:Reloaded + * + * File: knockback.zr.inc + * Type: Include + * Description: Knockback-related natives/forwards. + * + * Copyright (C) 2009-2013 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 . + * + * ============================================================================ + */ + +/** + * Set a maximum knockback velocity. + * + * @param client The client. + * @param fVelocity Maximum knockback velocity / force. + */ +native void ZR_SetClientKnockbackMaxVelocity(int client, float fVelocity); + +/** + * Set a custom knockback scale. + * + * @param client The client. + * @param fScale Custom knockback scale. + */ +native void ZR_SetClientKnockbackScale(int client, float fScale); diff --git a/src/zombiereloaded.sp b/src/zombiereloaded.sp index 00e7d3f..9ffaf2c 100644 --- a/src/zombiereloaded.sp +++ b/src/zombiereloaded.sp @@ -417,4 +417,5 @@ public OnEntitySpawned(entity, const String:classname[]) */ public void OnGameFrame() { + KnockbackOnGameFrame(); } diff --git a/src/zr/api/api.inc b/src/zr/api/api.inc index 1b160b9..84a7e7a 100644 --- a/src/zr/api/api.inc +++ b/src/zr/api/api.inc @@ -45,6 +45,7 @@ #include "zr/api/respawn.api" #include "zr/api/class.api" #include "zr/api/napalm.api" +#include "zr/api/knockback.api" /** * Initializes all main natives and forwards. @@ -56,6 +57,7 @@ APIInit() APIRespawnInit(); APIClassInit(); APINapalmInit(); + APIKnockbackInit(); } /** diff --git a/src/zr/api/knockback.api.inc b/src/zr/api/knockback.api.inc new file mode 100644 index 0000000..8fa9daf --- /dev/null +++ b/src/zr/api/knockback.api.inc @@ -0,0 +1,68 @@ +/* + * ============================================================================ + * + * Zombie:Reloaded + * + * File: knockback.api.inc + * Type: Core + * Description: Native handlers for the ZR API. (Knockback module) + * + * Copyright (C) 2009-2013 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 . + * + * ============================================================================ + */ + +/** + * Initializes all natives and forwards related to infection. + */ +APIKnockbackInit() +{ + // Class module natives/forwards (knockback.zr.inc) + + // Natives + CreateNative("ZR_SetClientKnockbackMaxVelocity", APISetClientKnockbackMaxVelocity); + CreateNative("ZR_SetClientKnockbackScale", APISetClientKnockbackScale); +} + +/** + * Native call function (ZR_SetClientKnockbackMaxVelocity) + * + * int ZR_SetClientKnockbackMaxVelocity(int client, float fVelocity); + */ +public int APISetClientKnockbackMaxVelocity(Handle plugin, int numParams) +{ + int client = GetNativeCell(1); + float fVelocity = view_as(GetNativeCell(2)); + + APIValidateClientIndex(client); + + KnockbackSetClientMaxVelocity(client, fVelocity); +} + +/** + * Native call function (ZR_SetClientKnockbackScale) + * + * int ZR_SetClientKnockbackScale(int client, float fScale); + */ +public int APISetClientKnockbackScale(Handle plugin, int numParams) +{ + int client = GetNativeCell(1); + float fScale = view_as(GetNativeCell(2)); + + APIValidateClientIndex(client); + + KnockbackSetClientScale(client, fScale); +} diff --git a/src/zr/event.inc b/src/zr/event.inc index 84b4b38..3bbe94e 100644 --- a/src/zr/event.inc +++ b/src/zr/event.inc @@ -287,6 +287,7 @@ public Action:EventPlayerDeath(Handle:event, const String:name[], bool:dontBroad VolOnPlayerDeath(index); RoundEndOnClientDeath(); ImmunityOnClientDeath(index); + KnockbackOnClientDeath(index); } /** diff --git a/src/zr/immunityhandler.inc b/src/zr/immunityhandler.inc index 7157631..2e9f91f 100644 --- a/src/zr/immunityhandler.inc +++ b/src/zr/immunityhandler.inc @@ -225,7 +225,7 @@ bool ImmunityOnClientTraceAttack(int client, int &attacker, int &inflictor, floa } // Since damage is blocked, trigger knock back hurt event manually. - DamageOnTakeDamageAlivePost(client, attacker, inflictor, damage, damagetype, -1, NULL_VECTOR, NULL_VECTOR, 0); + KnockbackOnTakeDamageAlivePost(client, attacker, inflictor, damage, damagetype, -1, NULL_VECTOR, NULL_VECTOR, 0); // Block damage from attacker. return true; diff --git a/src/zr/knockback.inc b/src/zr/knockback.inc index 0566d72..7ffeea0 100644 --- a/src/zr/knockback.inc +++ b/src/zr/knockback.inc @@ -25,6 +25,11 @@ * ============================================================================ */ +bool g_bKnockbackFrame[MAXPLAYERS + 1]; +float g_fKnockbackVelLimit[MAXPLAYERS + 1]; +float g_fKnockbackVectors[MAXPLAYERS + 1][3]; +float g_fKnockbackScale[MAXPLAYERS + 1]; + /** * Minimum upwards boost that is required to push zombies off the ground. */ @@ -36,8 +41,15 @@ * * @param client The client index. */ -KnockbackClientInit(client) +void KnockbackClientInit(int client) { + g_bKnockbackFrame[client] = false; + g_fKnockbackVelLimit[client] = 0.0; + g_fKnockbackVectors[client][0] = 0.0; + g_fKnockbackVectors[client][1] = 0.0; + g_fKnockbackVectors[client][2] = 0.0; + g_fKnockbackScale[client] = 1.0; + SDKHook(client, SDKHook_OnTakeDamageAlivePost, KnockbackOnTakeDamageAlivePost); } @@ -46,11 +58,63 @@ KnockbackClientInit(client) * * @param client The client index. */ -KnockbackOnClientDisconnect(client) +void KnockbackOnClientDisconnect(int client) { + g_bKnockbackFrame[client] = false; + g_fKnockbackVelLimit[client] = 0.0; + SDKUnhook(client, SDKHook_OnTakeDamageAlivePost, KnockbackOnTakeDamageAlivePost); } +/** + * Client died. + */ +void KnockbackOnClientDeath(int client) +{ + g_bKnockbackFrame[client] = false; + g_fKnockbackVelLimit[client] = 0.0; + g_fKnockbackVectors[client][0] = 0.0; + g_fKnockbackVectors[client][1] = 0.0; + g_fKnockbackVectors[client][2] = 0.0; + g_fKnockbackScale[client] = 1.0; +} + +void KnockbackSetClientMaxVelocity(int client, float fVelocity) +{ + g_fKnockbackVelLimit[client] = fVelocity; +} + +void KnockbackSetClientScale(int client, float fScale) +{ + g_fKnockbackScale[client] = fScale; +} + +/** + * Called before every server frame. Note that you should avoid + * doing expensive computations or declaring large local arrays. + */ +void KnockbackOnGameFrame() +{ + for(int client = 1; client <= MaxClients; client++) + { + if (g_bKnockbackFrame[client] && g_fKnockbackVelLimit[client] > 0.0) + { + float magnitude = GetVectorLength(g_fKnockbackVectors[client]); + if(magnitude > g_fKnockbackVelLimit[client]) + { + ScaleVector(g_fKnockbackVectors[client], g_fKnockbackVelLimit[client] / magnitude); + } + + KnockbackApplyVector(client, g_fKnockbackVectors[client]); + + g_bKnockbackFrame[client] = false; + g_fKnockbackVectors[client][0] = 0.0; + g_fKnockbackVectors[client][1] = 0.0; + g_fKnockbackVectors[client][2] = 0.0; + } + } +} + /** * Hook: KnockbackOnTakeDamageAlivePost * Called after client has been hurt. @@ -109,6 +173,8 @@ public void KnockbackOnTakeDamageAlivePost(int victim, int attacker, int inflict ReplaceString(weaponname, sizeof(weaponname), "weapon_", ""); ReplaceString(weaponname, sizeof(weaponname), "_projectile", ""); + bool knife = StrEqual(weaponname, "knife"); + // Check if a grenade was thrown. if (StrEqual(weaponname, "hegrenade")) { @@ -145,9 +211,12 @@ public void KnockbackOnTakeDamageAlivePost(int victim, int attacker, int inflict } int hitgroup = HITGROUP_GENERIC; - if (!(damagetype & DMG_BLAST)) + if (!(damagetype & DMG_BLAST) && !damagecustom) hitgroup = ToolsGetClientLastHitGroup(victim); + if (damagecustom) + ToolsSetClientLastHitGroup(victim, HITGROUP_GENERIC); + new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]); if (hitgroups) { @@ -162,8 +231,12 @@ public void KnockbackOnTakeDamageAlivePost(int victim, int attacker, int inflict // Apply damage knockback multiplier. knockback *= damage; + // Custom knockback scale. + if (!knife) + knockback *= g_fKnockbackScale[victim]; + // Apply knockback. - KnockbackSetVelocity(victim, attackerloc, clientloc, knockback); + KnockbackSetVelocity(victim, attackerloc, clientloc, knockback, damagecustom && !knife); } /** @@ -174,7 +247,7 @@ public void KnockbackOnTakeDamageAlivePost(int victim, int attacker, int inflict * @param endpoint The ending coordinate to push towards. * @param magnitude Magnitude of the push. */ -KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3], Float:magnitude) +KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3], Float:magnitude, int custom) { // Create vector from the given starting and ending points. new Float:vector[3]; @@ -186,6 +259,18 @@ KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3], // Apply the magnitude by scaling the vector (multiplying each of its components). ScaleVector(vector, magnitude); + if (custom && g_fKnockbackVelLimit[client]) + { + AddVectors(g_fKnockbackVectors[client], vector, g_fKnockbackVectors[client]); + g_bKnockbackFrame[client] = true; + return; + } + + KnockbackApplyVector(client, vector); +} + +void KnockbackApplyVector(int client, float vector[3]) +{ // CS: GO workaround. Apply knock back boost if enabled. if (g_Game == Game_CSGO && GetConVarBool(g_hCvarsList[CVAR_CLASSES_CSGO_KNOCKBACK_BOOST])) {