Updated antistick to be much more accurate.
Removed eyeangles offset from gamedata file. Removed old code in commands.inc.
This commit is contained in:
parent
85e39dda5a
commit
879a31e8d6
@ -9,13 +9,6 @@
|
|||||||
|
|
||||||
"Offsets"
|
"Offsets"
|
||||||
{
|
{
|
||||||
|
|
||||||
"EyeAngles"
|
|
||||||
{
|
|
||||||
"windows" "206"
|
|
||||||
"linux" "207"
|
|
||||||
}
|
|
||||||
|
|
||||||
"TraceAttack"
|
"TraceAttack"
|
||||||
{
|
{
|
||||||
"windows" "58"
|
"windows" "58"
|
||||||
|
@ -848,6 +848,46 @@
|
|||||||
"en" "Force ZTele"
|
"en" "Force ZTele"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===========================
|
||||||
|
// AntiStick (module)
|
||||||
|
// ===========================
|
||||||
|
|
||||||
|
// Commands
|
||||||
|
|
||||||
|
"AntiStick command set width syntax"
|
||||||
|
{
|
||||||
|
"en" "Sets the width of a model's hull. (See zr_antistick_list_models) Usage: zr_antistick_set_width <model/player> <width>"
|
||||||
|
}
|
||||||
|
|
||||||
|
"AntiStick command list models list"
|
||||||
|
{
|
||||||
|
"en" "Showing all players' model data...\n------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
"AntiStick command list models name"
|
||||||
|
{
|
||||||
|
"#format" "{1:s},{2:s},{3:f}"
|
||||||
|
"en" "Player Name: {1} | Model Name: {2} | Model Hull Width: {3}"
|
||||||
|
}
|
||||||
|
|
||||||
|
"AntiStick command set width successful"
|
||||||
|
{
|
||||||
|
"#format" "{1:s},{2:f}"
|
||||||
|
"en" "Model hull width for model \"{1}\" has been changed to \"{2}.\""
|
||||||
|
}
|
||||||
|
|
||||||
|
"AntiStick command set width invalid model"
|
||||||
|
{
|
||||||
|
"#format" "{1:s}"
|
||||||
|
"en" "Invalid model/player specified: \"{1}\""
|
||||||
|
}
|
||||||
|
|
||||||
|
"AntiStick command set width invalid width"
|
||||||
|
{
|
||||||
|
"#format" "{1:f}"
|
||||||
|
"en" "Invalid model hull width specified: \"{1}\""
|
||||||
|
}
|
||||||
|
|
||||||
// ===========================
|
// ===========================
|
||||||
// Spawn Protect (module)
|
// Spawn Protect (module)
|
||||||
// ===========================
|
// ===========================
|
||||||
|
@ -507,9 +507,9 @@ zr_ambientsounds_volume "0.8"
|
|||||||
// Default: "1"
|
// Default: "1"
|
||||||
zr_antistick "1"
|
zr_antistick "1"
|
||||||
|
|
||||||
// Time between each check for stuck players. [Dependency: zr_antistick]
|
// File to store antistick model hull data. [Dependency: zr_antistick]
|
||||||
// Default: "0.5"
|
// Default: "data/antistick.dat"
|
||||||
zr_antistick_interval "0.5"
|
zr_antistick_file_path "data/antistick.dat"
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -135,7 +135,6 @@ public OnMapStart()
|
|||||||
RoundEndOnMapStart();
|
RoundEndOnMapStart();
|
||||||
InfectOnMapStart();
|
InfectOnMapStart();
|
||||||
SEffectsOnMapStart();
|
SEffectsOnMapStart();
|
||||||
AntiStickOnMapStart();
|
|
||||||
ZSpawnOnMapStart();
|
ZSpawnOnMapStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +160,7 @@ public OnConfigsExecuted()
|
|||||||
InfectLoad();
|
InfectLoad();
|
||||||
VEffectsLoad();
|
VEffectsLoad();
|
||||||
SEffectsLoad();
|
SEffectsLoad();
|
||||||
|
AntiStickLoad();
|
||||||
ClassLoad();
|
ClassLoad();
|
||||||
VolLoad();
|
VolLoad();
|
||||||
|
|
||||||
@ -183,6 +183,7 @@ public OnClientPutInServer(client)
|
|||||||
InfectClientInit(client);
|
InfectClientInit(client);
|
||||||
DamageClientInit(client);
|
DamageClientInit(client);
|
||||||
SEffectsClientInit(client);
|
SEffectsClientInit(client);
|
||||||
|
AntiStickClientInit(client);
|
||||||
SpawnProtectClientInit(client);
|
SpawnProtectClientInit(client);
|
||||||
RespawnClientInit(client);
|
RespawnClientInit(client);
|
||||||
ZTeleClientInit(client);
|
ZTeleClientInit(client);
|
||||||
@ -201,6 +202,7 @@ public OnClientDisconnect(client)
|
|||||||
WeaponsOnClientDisconnect(client);
|
WeaponsOnClientDisconnect(client);
|
||||||
InfectOnClientDisconnect(client);
|
InfectOnClientDisconnect(client);
|
||||||
DamageOnClientDisconnect(client);
|
DamageOnClientDisconnect(client);
|
||||||
|
AntiStickOnClientDisconnect(client);
|
||||||
ZSpawnOnClientDisconnect(client);
|
ZSpawnOnClientDisconnect(client);
|
||||||
VolOnPlayerDisconnect(client);
|
VolOnPlayerDisconnect(client);
|
||||||
}
|
}
|
||||||
|
@ -35,58 +35,58 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @section Offsets relating to player hull dimensions.
|
* Default player hull width.
|
||||||
*/
|
*/
|
||||||
#define ANTISTICK_PLAYER_HULL_XY_OFFSET 32
|
#define ANTISTICK_DEFAULT_HULL_WIDTH 32.0
|
||||||
#define ANTISTICK_PLAYER_HULL_Z_OFFSET 12
|
|
||||||
#define ANTISTICK_PLAYER_HULL_STACK_OFFSET 14
|
|
||||||
/**
|
|
||||||
* @endsection
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable to store antistick offset value.
|
* Handle to keyvalue structure where data is stored.
|
||||||
*/
|
*/
|
||||||
new g_iToolsCollisionGroup;
|
new Handle:g_kvAntiStick = INVALID_HANDLE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle to keep track of AntiStickTimer.
|
* Stores "StartTouch" HookID's for each client.
|
||||||
*/
|
*/
|
||||||
new Handle:tAntiStick = INVALID_HANDLE;
|
new g_iStartTouchHookID[MAXPLAYERS + 1] = {-1, ...};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find antistick-specific offsets here.
|
* List of components that make up the model's rectangular boundaries.
|
||||||
|
*
|
||||||
|
* F = Front
|
||||||
|
* B = Back
|
||||||
|
* L = Left
|
||||||
|
* R = Right
|
||||||
|
* U = Upper
|
||||||
|
* D = Down
|
||||||
*/
|
*/
|
||||||
AntiStickOnOffsetsFound()
|
enum AntiStickBoxBound
|
||||||
{
|
{
|
||||||
// If offset "m_CollisionGroup" can't be found, then stop the plugin.
|
BoxBound_FUR = 0, /** Front upper right */
|
||||||
g_iToolsCollisionGroup = FindSendPropInfo("CBaseEntity", "m_CollisionGroup");
|
BoxBound_FUL, /** etc.. */
|
||||||
if (g_iToolsCollisionGroup == -1)
|
BoxBound_FDR,
|
||||||
{
|
BoxBound_FDL,
|
||||||
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Antistick, "Offsets", "Offset \"CBaseEntity::m_CollisionGroup\" was not found.");
|
BoxBound_BUR,
|
||||||
}
|
BoxBound_BUL,
|
||||||
|
BoxBound_BDR,
|
||||||
|
BoxBound_BDL,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map is starting.
|
* Create commands related to antistick here.
|
||||||
*/
|
*/
|
||||||
AntiStickOnMapStart()
|
AntiStickOnCommandsCreate()
|
||||||
{
|
{
|
||||||
// Reset timer handle.
|
// Create public command to list model data.
|
||||||
tAntiStick = INVALID_HANDLE;
|
RegConsoleCmd("zr_antistick_list_models", AntiStickListModelsCommand, "Lists all players and their model data in console. Usage: zr_antistick_list_models");
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The round is starting.
|
|
||||||
*/
|
|
||||||
AntiStickOnRoundStart()
|
|
||||||
{
|
|
||||||
// If timer is running, kill it.
|
|
||||||
if (tAntiStick != INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
KillTimer(tAntiStick);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Create admin command to set model hull width.
|
||||||
|
RegAdminCmd("zr_antistick_set_width", AntiStickSetWidthCommand, ADMFLAG_GENERIC, "Sets the width of a model's hull. (See zr_antistick_list_models) Usage: zr_antistick_set_width <model/player> <width>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates/loads antistick data file.
|
||||||
|
*/
|
||||||
|
AntiStickLoad()
|
||||||
|
{
|
||||||
// If antistick is disabled, then stop.
|
// If antistick is disabled, then stop.
|
||||||
new bool:antistick = GetConVarBool(g_hCvarsList[CVAR_ANTISTICK]);
|
new bool:antistick = GetConVarBool(g_hCvarsList[CVAR_ANTISTICK]);
|
||||||
if (!antistick)
|
if (!antistick)
|
||||||
@ -94,118 +94,441 @@ AntiStickOnRoundStart()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new Float:interval = GetConVarFloat(g_hCvarsList[CVAR_ANTISTICK_INTERVAL]);
|
// Create antistick keyvalues if it hasn't been created yet.
|
||||||
tAntiStick = CreateTimer(interval, AntiStickTimer, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
|
if (g_kvAntiStick == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
g_kvAntiStick = CreateKeyValues("antistick");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize keyvalues.
|
||||||
|
if (!AntiStickLoadData())
|
||||||
|
{
|
||||||
|
AntiStickSaveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client is joining the server.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
*/
|
||||||
|
AntiStickClientInit(client)
|
||||||
|
{
|
||||||
|
// Hook "StartTouch" and "EndTouch" on client.
|
||||||
|
g_iStartTouchHookID[client] = ZRTools_HookStartTouch(client, AntiStickStartTouch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unhook StartTouch and EndTouch function on a client.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
*/
|
||||||
|
AntiStickOnClientDisconnect(client)
|
||||||
|
{
|
||||||
|
// Unhook "StartTouch" callback, and reset variable.
|
||||||
|
if (g_iStartTouchHookID[client] != -1)
|
||||||
|
{
|
||||||
|
ZRTools_UnhookStartTouch(g_iStartTouchHookID[client]);
|
||||||
|
g_iStartTouchHookID[client] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load antistick data from file.
|
||||||
|
*
|
||||||
|
* @return True if loaded successfully, false if file wasn't found.
|
||||||
|
*/
|
||||||
|
stock bool:AntiStickLoadData()
|
||||||
|
{
|
||||||
|
// Get cvar's path.
|
||||||
|
decl String:filepath[PLATFORM_MAX_PATH];
|
||||||
|
GetConVarString(g_hCvarsList[CVAR_ANTISTICK_FILE_PATH], filepath, sizeof(filepath));
|
||||||
|
|
||||||
|
// Build full path in return string.
|
||||||
|
decl String:fullpath[PLATFORM_MAX_PATH];
|
||||||
|
BuildPath(Path_SM, fullpath, PLATFORM_MAX_PATH, filepath);
|
||||||
|
|
||||||
|
// Log action to game events.
|
||||||
|
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_AntiStick, "Loaded Data", "Antistick data has been loaded from \"%s\"", fullpath);
|
||||||
|
|
||||||
|
// Retrieve keyvalue data from a file, and store in server's memory.
|
||||||
|
KvRewind(g_kvAntiStick);
|
||||||
|
return FileToKeyValues(g_kvAntiStick, fullpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save antistick data to file.
|
||||||
|
*/
|
||||||
|
stock AntiStickSaveData()
|
||||||
|
{
|
||||||
|
// Get cvar's path.
|
||||||
|
decl String:filepath[PLATFORM_MAX_PATH];
|
||||||
|
GetConVarString(g_hCvarsList[CVAR_ANTISTICK_FILE_PATH], filepath, sizeof(filepath));
|
||||||
|
|
||||||
|
// Build full path in return string.
|
||||||
|
decl String:fullpath[PLATFORM_MAX_PATH];
|
||||||
|
BuildPath(Path_SM, fullpath, PLATFORM_MAX_PATH, filepath);
|
||||||
|
|
||||||
|
// Log action to game events.
|
||||||
|
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_AntiStick, "Saved Data", "Antistick data has been saved to \"%s\"", fullpath);
|
||||||
|
|
||||||
|
// Dump keyvalue structure into a file from the server's memory.
|
||||||
|
KvRewind(g_kvAntiStick);
|
||||||
|
KeyValuesToFile(g_kvAntiStick, fullpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get hull width on a client's model. (or return default)
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
* @param model If a client index of 0 is given, this model is used.
|
||||||
|
*/
|
||||||
|
stock Float:AntiStickGetModelHullWidth(client, const String:model[] = "")
|
||||||
|
{
|
||||||
|
decl String:clientmodel[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
|
if (ZRIsClientValid(client))
|
||||||
|
{
|
||||||
|
// Get client's model.
|
||||||
|
GetClientModel(client, clientmodel, sizeof(clientmodel));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Copy given model to 'clientmodel.'
|
||||||
|
strcopy(clientmodel, sizeof(clientmodel), model);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find model in antistick data.
|
||||||
|
KvRewind(g_kvAntiStick);
|
||||||
|
if (KvJumpToKey(g_kvAntiStick, clientmodel))
|
||||||
|
{
|
||||||
|
// Return value from file.
|
||||||
|
return KvGetFloat(g_kvAntiStick, "hull_width", ANTISTICK_DEFAULT_HULL_WIDTH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Return default CS:S hull width.
|
||||||
|
return ANTISTICK_DEFAULT_HULL_WIDTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set hull width on a client's model.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
* @param model If a client index of 0 is given, this model is used.
|
||||||
|
* @param hull_width The width of the model hull.
|
||||||
|
*/
|
||||||
|
stock AntiStickSetModelHullWidth(client, const String:model[] = "", Float:hull_width)
|
||||||
|
{
|
||||||
|
decl String:clientmodel[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
|
if (ZRIsClientValid(client))
|
||||||
|
{
|
||||||
|
// Get client's model.
|
||||||
|
GetClientModel(client, clientmodel, sizeof(clientmodel));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Copy given model to 'clientmodel.'
|
||||||
|
strcopy(clientmodel, sizeof(clientmodel), model);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace "/" with "-" because a slash indicates a new level in keyvalues.
|
||||||
|
ReplaceString(clientmodel, sizeof(clientmodel), "/", "-");
|
||||||
|
|
||||||
|
// Find model in antistick data.
|
||||||
|
KvRewind(g_kvAntiStick);
|
||||||
|
|
||||||
|
// Create key if it doesn't already exist.
|
||||||
|
KvJumpToKey(g_kvAntiStick, clientmodel, true);
|
||||||
|
|
||||||
|
// Set value.
|
||||||
|
KvSetFloat(g_kvAntiStick, "hull_width", hull_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function for StartTouch.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
* @param entity The entity index of the entity being touched.
|
||||||
|
*/
|
||||||
|
public ZRTools_Action:AntiStickStartTouch(client, entity)
|
||||||
|
{
|
||||||
|
// If client isn't in-game, then stop.
|
||||||
|
if (!IsClientInGame(client))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If client is touching themselves, then leave them alone :P
|
||||||
|
if (client == entity)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If touched entity isn't a valid client, then stop.
|
||||||
|
if (!ZRIsClientValid(entity))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the clients aren't colliding, then stop.
|
||||||
|
if (!AntiStickIsModelBoxColliding(client, entity))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable collisions to unstick, and start timers to re-solidify.
|
||||||
|
if (AntiStickClientCollisionGroup(client) == ANTISTICK_COLLISIONS_ON)
|
||||||
|
{
|
||||||
|
AntiStickClientCollisionGroup(client, true, ANTISTICK_COLLISIONS_OFF);
|
||||||
|
CreateTimer(0.0, AntiStickSolidifyTimer, client, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AntiStickClientCollisionGroup(entity) == ANTISTICK_COLLISIONS_ON)
|
||||||
|
{
|
||||||
|
AntiStickClientCollisionGroup(entity, true, ANTISTICK_COLLISIONS_OFF);
|
||||||
|
CreateTimer(0.0, AntiStickSolidifyTimer, entity, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function for EndTouch.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
* @param entity The entity index of the entity being touched.
|
||||||
|
*/
|
||||||
|
public Action:AntiStickSolidifyTimer(Handle:timer, any:client)
|
||||||
|
{
|
||||||
|
// If client has left, then stop the timer.
|
||||||
|
if (!IsClientInGame(client))
|
||||||
|
{
|
||||||
|
return Plugin_Stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the client's collisions are already on, then stop.
|
||||||
|
if (AntiStickClientCollisionGroup(client) == ANTISTICK_COLLISIONS_ON)
|
||||||
|
{
|
||||||
|
return Plugin_Stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through all client's and check if client is stuck in them.
|
||||||
|
for (new x = 1; x <= MaxClients; x++)
|
||||||
|
{
|
||||||
|
// Don't compare the same clients.
|
||||||
|
if (client == x)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If client isn't in-game, then stop.
|
||||||
|
if (!IsClientInGame(x))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the client is colliding with a client, then allow timer to continue.
|
||||||
|
if (AntiStickIsModelBoxColliding(client, x))
|
||||||
|
{
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change collisions back to normal.
|
||||||
|
AntiStickClientCollisionGroup(client, true, ANTISTICK_COLLISIONS_ON);
|
||||||
|
|
||||||
|
return Plugin_Stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the model box by finding all vertices.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
* @param boundaries Array with 'AntiStickBoxBounds' for indexes to return bounds into.
|
||||||
|
* @param width The width of the model box.
|
||||||
|
*/
|
||||||
|
stock AntiStickBuildModelBox(client, Float:boundaries[AntiStickBoxBound][3], Float:width)
|
||||||
|
{
|
||||||
|
new Float:clientloc[3];
|
||||||
|
new Float:twistang[3];
|
||||||
|
new Float:cornerang[3];
|
||||||
|
new Float:sideloc[3];
|
||||||
|
new Float:finalloc[4][3];
|
||||||
|
|
||||||
|
// Get needed vector info.
|
||||||
|
GetClientAbsOrigin(client, clientloc);
|
||||||
|
|
||||||
|
// Set the pitch to 0.
|
||||||
|
twistang[1] = 90.0;
|
||||||
|
cornerang[1] = 0.0;
|
||||||
|
|
||||||
|
for (new x = 0; x < 4; x++)
|
||||||
|
{
|
||||||
|
// Jump to point on player's left side.
|
||||||
|
AntiStickJumpToPoint(clientloc, twistang, width / 2, sideloc);
|
||||||
|
|
||||||
|
// From this point, jump to the corner, which would be half the width from the middle of a side.
|
||||||
|
AntiStickJumpToPoint(sideloc, cornerang, width / 2, finalloc[x]);
|
||||||
|
|
||||||
|
// Twist 90 degrees to find next side/corner.
|
||||||
|
twistang[1] += 90.0;
|
||||||
|
cornerang[1] += 90.0;
|
||||||
|
|
||||||
|
// Fix angles.
|
||||||
|
if (twistang[1] > 180.0)
|
||||||
|
{
|
||||||
|
twistang[1] -= 360.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cornerang[1] > 180.0)
|
||||||
|
{
|
||||||
|
cornerang[1] -= 360.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy all horizontal model box data to array.
|
||||||
|
boundaries[BoxBound_FUR][0] = finalloc[3][0];
|
||||||
|
boundaries[BoxBound_FUR][1] = finalloc[3][1];
|
||||||
|
boundaries[BoxBound_FUL][0] = finalloc[0][0];
|
||||||
|
boundaries[BoxBound_FUL][1] = finalloc[0][1];
|
||||||
|
boundaries[BoxBound_FDR][0] = finalloc[3][0];
|
||||||
|
boundaries[BoxBound_FDR][1] = finalloc[3][1];
|
||||||
|
boundaries[BoxBound_FDL][0] = finalloc[0][0];
|
||||||
|
boundaries[BoxBound_FDL][1] = finalloc[0][1];
|
||||||
|
boundaries[BoxBound_BUR][0] = finalloc[2][0];
|
||||||
|
boundaries[BoxBound_BUR][1] = finalloc[2][1];
|
||||||
|
boundaries[BoxBound_BUL][0] = finalloc[1][0];
|
||||||
|
boundaries[BoxBound_BUL][1] = finalloc[1][1];
|
||||||
|
boundaries[BoxBound_BDR][0] = finalloc[2][0];
|
||||||
|
boundaries[BoxBound_BDR][1] = finalloc[2][1];
|
||||||
|
boundaries[BoxBound_BDL][0] = finalloc[1][0];
|
||||||
|
boundaries[BoxBound_BDL][1] = finalloc[1][1];
|
||||||
|
|
||||||
|
// Set Z bounds.
|
||||||
|
new Float:eyeloc[3];
|
||||||
|
GetClientEyePosition(client, eyeloc);
|
||||||
|
|
||||||
|
boundaries[BoxBound_FUR][2] = eyeloc[2] / 1.1; // Scale box down a bit to prevent weird false triggers.
|
||||||
|
boundaries[BoxBound_FUL][2] = eyeloc[2] / 1.1;
|
||||||
|
boundaries[BoxBound_FDR][2] = clientloc[2] + 3.0; // Raise this a hair up to be safe.
|
||||||
|
boundaries[BoxBound_FDL][2] = clientloc[2] + 3.0;
|
||||||
|
boundaries[BoxBound_BUR][2] = eyeloc[2] / 1.1;
|
||||||
|
boundaries[BoxBound_BUL][2] = eyeloc[2] / 1.1;
|
||||||
|
boundaries[BoxBound_BDR][2] = clientloc[2] + 3.0;
|
||||||
|
boundaries[BoxBound_BDL][2] = clientloc[2] + 3.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jumps from a point to another based off angle and distance.
|
||||||
|
*
|
||||||
|
* @param vec Point to jump from.
|
||||||
|
* @param ang Angle to base jump off of.
|
||||||
|
* @param distance Distance to jump
|
||||||
|
* @param result Resultant point.
|
||||||
|
*/
|
||||||
|
stock AntiStickJumpToPoint(const Float:vec[3], const Float:ang[3], Float:distance, Float:result[3])
|
||||||
|
{
|
||||||
|
new Float:viewvec[3];
|
||||||
|
|
||||||
|
// Turn client angle, into a vector.
|
||||||
|
GetAngleVectors(ang, viewvec, NULL_VECTOR, NULL_VECTOR);
|
||||||
|
|
||||||
|
// Normalize vector.
|
||||||
|
NormalizeVector(viewvec, viewvec);
|
||||||
|
|
||||||
|
// Scale to the given distance.
|
||||||
|
ScaleVector(viewvec, distance);
|
||||||
|
|
||||||
|
// Add the vectors together.
|
||||||
|
AddVectors(vec, viewvec, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the max/min value of a 3D box on any axis.
|
||||||
|
*
|
||||||
|
* @param axis The axis to check.
|
||||||
|
* @param boundaries The boundaries to check.
|
||||||
|
* @param min Return the min value instead.
|
||||||
|
*/
|
||||||
|
stock Float:AntiStickGetBoxMaxBoundary(axis, Float:boundaries[AntiStickBoxBound][3], bool:min = false)
|
||||||
|
{
|
||||||
|
// Create 'outlier' with initial value of first boundary.
|
||||||
|
new Float:outlier = boundaries[0][axis];
|
||||||
|
|
||||||
|
// x = Boundary index. (Start at 1 because we initialized 'outlier' with the 0 index's value)
|
||||||
|
new size = sizeof(boundaries);
|
||||||
|
for (new x = 1; x < size; x++)
|
||||||
|
{
|
||||||
|
if (!min && boundaries[x][axis] > outlier)
|
||||||
|
{
|
||||||
|
outlier = boundaries[x][axis];
|
||||||
|
}
|
||||||
|
else if (min && boundaries[x][axis] < outlier)
|
||||||
|
{
|
||||||
|
outlier = boundaries[x][axis];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return value.
|
||||||
|
return outlier;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a player is currently stuck within another player.
|
* Checks if a player is currently stuck within another player.
|
||||||
*
|
*
|
||||||
* @param client The client index.
|
* @param client1 The first client index.
|
||||||
* @return The client index of the other stuck player, -1 when
|
* @param client2 The second client index.
|
||||||
* player is not stuck.
|
* @return True if they are stuck together, false if not.
|
||||||
*/
|
*/
|
||||||
AntiStickIsStuck(client)
|
stock bool:AntiStickIsModelBoxColliding(client1, client2)
|
||||||
{
|
{
|
||||||
new Float:clientloc[3];
|
new Float:client1modelbox[AntiStickBoxBound][3];
|
||||||
new Float:stuckloc[3];
|
new Float:client2modelbox[AntiStickBoxBound][3];
|
||||||
|
|
||||||
GetClientAbsOrigin(client, clientloc);
|
// Get model hull widths.
|
||||||
|
new Float:hull_width1 = AntiStickGetModelHullWidth(client1);
|
||||||
|
new Float:hull_width2 = AntiStickGetModelHullWidth(client2);
|
||||||
|
|
||||||
// x = client index.
|
// Build model boxes for each client.
|
||||||
for (new x = 1; x <= MaxClients; x++)
|
AntiStickBuildModelBox(client1, client1modelbox, hull_width1);
|
||||||
|
AntiStickBuildModelBox(client2, client2modelbox, hull_width2);
|
||||||
|
|
||||||
|
// Compare x values.
|
||||||
|
new Float:max1x = AntiStickGetBoxMaxBoundary(0, client1modelbox);
|
||||||
|
new Float:max2x = AntiStickGetBoxMaxBoundary(0, client2modelbox);
|
||||||
|
new Float:min1x = AntiStickGetBoxMaxBoundary(0, client1modelbox, true);
|
||||||
|
new Float:min2x = AntiStickGetBoxMaxBoundary(0, client2modelbox, true);
|
||||||
|
|
||||||
|
if (max1x < min2x || min1x > max2x)
|
||||||
{
|
{
|
||||||
// Validate player is in-game, alive, and isn't the player being checked. ('client')
|
return false;
|
||||||
if (!IsClientInGame(x) || !IsPlayerAlive(x) || x == client)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetClientAbsOrigin(x, stuckloc);
|
|
||||||
|
|
||||||
// x-y plane distance formula: sqrt((x2-x1)^2 + (y2-y1)^2)
|
|
||||||
new Float:xydistance = SquareRoot(Pow(stuckloc[0] - clientloc[0], 2.0) + Pow(stuckloc[1] - clientloc[1], 2.0));
|
|
||||||
if (xydistance < ANTISTICK_PLAYER_HULL_XY_OFFSET)
|
|
||||||
{
|
|
||||||
if (clientloc[2] <= stuckloc[2])
|
|
||||||
{
|
|
||||||
new Float:eyeloc[3];
|
|
||||||
GetClientEyePosition(client, eyeloc);
|
|
||||||
|
|
||||||
// Get the distance between the eyes and feet and subtract the stack "view crush."
|
|
||||||
new Float:eyedistance = FloatAbs(eyeloc[2] - clientloc[2]) - ANTISTICK_PLAYER_HULL_STACK_OFFSET;
|
|
||||||
new Float:zdistance = FloatAbs(stuckloc[2] - clientloc[2]);
|
|
||||||
|
|
||||||
if (zdistance <= eyedistance + ANTISTICK_PLAYER_HULL_Z_OFFSET)
|
|
||||||
{
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
// Compare y values.
|
||||||
}
|
new Float:max1y = AntiStickGetBoxMaxBoundary(1, client1modelbox);
|
||||||
|
new Float:max2y = AntiStickGetBoxMaxBoundary(1, client2modelbox);
|
||||||
/**
|
new Float:min1y = AntiStickGetBoxMaxBoundary(1, client1modelbox, true);
|
||||||
* Timer callback, automatically unsticks players that are stuck together.
|
new Float:min2y = AntiStickGetBoxMaxBoundary(1, client2modelbox, true);
|
||||||
*/
|
|
||||||
public Action:AntiStickTimer(Handle:timer)
|
if (max1y < min2y || min1y > max2y)
|
||||||
{
|
|
||||||
// x = client index
|
|
||||||
for (new x = 1; x <= MaxClients; x++)
|
|
||||||
{
|
{
|
||||||
// Validate player is in-game and alive.
|
return false;
|
||||||
if (!IsClientInGame(x) || !IsPlayerAlive(x))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop if the player isn't stuck.
|
|
||||||
new stuckindex = AntiStickIsStuck(x);
|
|
||||||
if (stuckindex == -1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AntiStickClientCollisionGroup(x, false) == ANTISTICK_COLLISIONS_ON)
|
|
||||||
{
|
|
||||||
AntiStickClientCollisionGroup(x, true, ANTISTICK_COLLISIONS_OFF);
|
|
||||||
CreateTimer(0.5, AntiStickSolidify, x, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AntiStickClientCollisionGroup(stuckindex, false) == ANTISTICK_COLLISIONS_ON)
|
|
||||||
{
|
|
||||||
AntiStickClientCollisionGroup(stuckindex, true, ANTISTICK_COLLISIONS_OFF);
|
|
||||||
CreateTimer(0.5, AntiStickSolidify, stuckindex, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Repeated timer function.
|
|
||||||
* Re-solidifies a player being unstuck.
|
|
||||||
*
|
|
||||||
* @param timer The timer handle.
|
|
||||||
* @param client The client index.
|
|
||||||
*/
|
|
||||||
public Action:AntiStickSolidify(Handle:timer, any:client)
|
|
||||||
{
|
|
||||||
// Validate player is in-game, alive, and is being unstuck.
|
|
||||||
if (!IsClientInGame(client) || !IsPlayerAlive(client) || AntiStickClientCollisionGroup(client, false) == ANTISTICK_COLLISIONS_ON)
|
|
||||||
{
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop if the player is still stuck.
|
// Compare z values.
|
||||||
if (AntiStickIsStuck(client) > -1)
|
new Float:max1z = AntiStickGetBoxMaxBoundary(2, client1modelbox);
|
||||||
|
new Float:max2z = AntiStickGetBoxMaxBoundary(2, client2modelbox);
|
||||||
|
new Float:min1z = AntiStickGetBoxMaxBoundary(2, client1modelbox, true);
|
||||||
|
new Float:min2z = AntiStickGetBoxMaxBoundary(2, client2modelbox, true);
|
||||||
|
|
||||||
|
if (max1z < min2z || min1z > max2z)
|
||||||
{
|
{
|
||||||
return Plugin_Continue;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AntiStickClientCollisionGroup(client, true, ANTISTICK_COLLISIONS_ON);
|
// They are intersecting.
|
||||||
|
return true;
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,14 +537,107 @@ public Action:AntiStickSolidify(Handle:timer, any:client)
|
|||||||
* @param collisiongroup Collision group flag.
|
* @param collisiongroup Collision group flag.
|
||||||
* @return The collision group on the client, -1 if applying collision group.
|
* @return The collision group on the client, -1 if applying collision group.
|
||||||
*/
|
*/
|
||||||
AntiStickClientCollisionGroup(client, bool:apply = true, collisiongroup = 0)
|
AntiStickClientCollisionGroup(client, bool:apply = false, collisiongroup = 0)
|
||||||
{
|
{
|
||||||
if (apply)
|
if (apply)
|
||||||
{
|
{
|
||||||
SetEntData(client, g_iToolsCollisionGroup, collisiongroup, 1, true);
|
SetEntProp(client, Prop_Data, "m_CollisionGroup", collisiongroup);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetEntData(client, g_iToolsCollisionGroup, 1);
|
return GetEntProp(client, Prop_Data, "m_CollisionGroup");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command callback (zr_antistick_list_models)
|
||||||
|
* Lists all player's models and model hull data.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
* @param argc Argument count.
|
||||||
|
*/
|
||||||
|
public Action:AntiStickListModelsCommand(client, argc)
|
||||||
|
{
|
||||||
|
// Tell client we are listing model data.
|
||||||
|
TranslationPrintToConsole(client, "AntiStick command list models list");
|
||||||
|
|
||||||
|
decl String:clientname[MAX_NAME_LENGTH];
|
||||||
|
decl String:modelname[PLATFORM_MAX_PATH];
|
||||||
|
new Float:hull_width;
|
||||||
|
|
||||||
|
// x = Client index.
|
||||||
|
for (new x = 1; x <= MaxClients; x++)
|
||||||
|
{
|
||||||
|
// If client isn't in-game, then stop.
|
||||||
|
if (!IsClientInGame(x))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all needed data.
|
||||||
|
GetClientName(x, clientname, sizeof(clientname));
|
||||||
|
GetClientModel(x, modelname, sizeof(modelname));
|
||||||
|
hull_width = AntiStickGetModelHullWidth(x);
|
||||||
|
|
||||||
|
TranslationPrintToConsole(client, "AntiStick command list models name", clientname, modelname, hull_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command callback (zr_antistick_set_width)
|
||||||
|
* Set the hull width on any model.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
* @param argc Argument count.
|
||||||
|
*/
|
||||||
|
public Action:AntiStickSetWidthCommand(client, argc)
|
||||||
|
{
|
||||||
|
// If not enough arguments given, then stop.
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
TranslationReplyToCommand(client, "AntiStick command set width syntax");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get target model.
|
||||||
|
decl String:model[PLATFORM_MAX_PATH];
|
||||||
|
GetCmdArg(1, model, sizeof(model));
|
||||||
|
|
||||||
|
// If model doesn't exist, then stop.
|
||||||
|
if (!FileExists(model))
|
||||||
|
{
|
||||||
|
new target = FindTarget(client, model);
|
||||||
|
if (target <= 0)
|
||||||
|
{
|
||||||
|
TranslationReplyToCommand(client, "AntiStick command set width invalid model", model);
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get the target's model.
|
||||||
|
GetClientModel(target, model, sizeof(model));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the given hull width..
|
||||||
|
decl String:strHullwidth[PLATFORM_MAX_PATH];
|
||||||
|
GetCmdArg(2, strHullwidth, sizeof(strHullwidth));
|
||||||
|
|
||||||
|
new Float:hull_width = StringToFloat(strHullwidth);
|
||||||
|
if (hull_width <= 0.0)
|
||||||
|
{
|
||||||
|
TranslationReplyToCommand(client, "AntiStick command set width invalid width", hull_width);
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set hull width.
|
||||||
|
AntiStickSetModelHullWidth(0, model, hull_width);
|
||||||
|
|
||||||
|
// Save data.
|
||||||
|
AntiStickSaveData();
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
@ -39,6 +39,7 @@ CommandsInit()
|
|||||||
InfectOnCommandsCreate();
|
InfectOnCommandsCreate();
|
||||||
MenuOnCommandsCreate();
|
MenuOnCommandsCreate();
|
||||||
ZAdminOnCommandsCreate();
|
ZAdminOnCommandsCreate();
|
||||||
|
AntiStickOnCommandsCreate();
|
||||||
ZCookiesOnCommandsCreate();
|
ZCookiesOnCommandsCreate();
|
||||||
ZSpawnOnCommandsCreate();
|
ZSpawnOnCommandsCreate();
|
||||||
ZTeleOnCommandsCreate();
|
ZTeleOnCommandsCreate();
|
||||||
@ -48,201 +49,4 @@ CommandsInit()
|
|||||||
// Forward event to modules. (hook commands)
|
// Forward event to modules. (hook commands)
|
||||||
ClassOnCommandsHook();
|
ClassOnCommandsHook();
|
||||||
DamageOnCommandsHook();
|
DamageOnCommandsHook();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*CreateCommands()
|
|
||||||
{
|
|
||||||
RegAdminCmd("zr_infect", Command_Infect, ADMFLAG_GENERIC, "Infects the specified player");
|
|
||||||
RegAdminCmd("zr_spawn", Command_Respawn, ADMFLAG_GENERIC, "Respawns the specified player following auto-respawning rules");
|
|
||||||
|
|
||||||
|
|
||||||
//RegAdminCmd("zr_set_class_knockback", Command_SetClassKnockback, ADMFLAG_GENERIC, "Sets the knockback to the specified class. Usage: zr_set_class_knockback <class name> <value>");
|
|
||||||
//RegAdminCmd("zr_get_class_knockback", Command_GetClassKnockback, ADMFLAG_GENERIC, "Gets the knockback to the specified class. Usage: zr_get_class_knockback <class name>");
|
|
||||||
|
|
||||||
RegAdminCmd("zr_admin", Command_AdminMenu, ADMFLAG_GENERIC, "Displays the admin menu for Zombie: Reloaded.");
|
|
||||||
//RegAdminCmd("zr_knockback_m", Command_KnockbackMMenu, ADMFLAG_GENERIC, "Displays the knockback multiplier menu.");
|
|
||||||
|
|
||||||
RegAdminCmd("zr_anticamp_create_volume", Command_AnticampCreateVolume, ADMFLAG_GENERIC, "Creates a rectangular hurt volume between two points. Usage: ht_create_volume <damage> <interval> <x1> <y1> <z1> <x2> <y2> <z2>");
|
|
||||||
RegAdminCmd("zr_anticamp_remove_volume", Command_AnticampRemoveVolume, ADMFLAG_GENERIC, "Removes a volume. Use zr_anticamp_list to list volumes. Usage: zr_anticamp_remove_volume <volume index>");
|
|
||||||
RegAdminCmd("zr_anticamp_list", Command_AnticampList, ADMFLAG_GENERIC, "List current volumes.");
|
|
||||||
|
|
||||||
RegConsoleCmd("zr_log_flags", Command_LogFlags, "List available logging flags.");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*public Action:Command_Infect(client, argc)
|
|
||||||
{
|
|
||||||
new bool:enabled = GetConVarBool(g_hCvarsList[CVAR_ENABLE]);
|
|
||||||
if (argc < 1 || !enabled)
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
decl String:arg1[32];
|
|
||||||
GetCmdArg(1, arg1, sizeof(arg1));
|
|
||||||
|
|
||||||
decl String:target_name_list[MAX_TARGET_LENGTH];
|
|
||||||
new targets[MAXPLAYERS];
|
|
||||||
new bool:tn_is_ml;
|
|
||||||
|
|
||||||
new tcount = ProcessTargetString(arg1, client, targets, MAXPLAYERS, COMMAND_FILTER_ALIVE, target_name_list, sizeof(target_name_list), tn_is_ml);
|
|
||||||
if (tcount <= 0)
|
|
||||||
{
|
|
||||||
ReplyToTargetError(client, tcount);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
decl String:target_name[64];
|
|
||||||
decl String:client_name[64];
|
|
||||||
|
|
||||||
if (client > 0)
|
|
||||||
{
|
|
||||||
GetClientName(client, client_name, sizeof(client_name));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
client_name = "Console\0";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (new x = 0; x < tcount; x++)
|
|
||||||
{
|
|
||||||
InfectHumanToZombie(targets[x]);
|
|
||||||
if (LogCheckFlag(LOG_GAME_EVENTS, LOG_MODULE_COMMANDS))
|
|
||||||
{
|
|
||||||
GetClientName(targets[x], target_name, sizeof(target_name));
|
|
||||||
LogMessageFormatted(client, "admin commands", "infect", "\"%s\" infected \"%s\".", true, client_name, target_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action:Command_Respawn(client, argc)
|
|
||||||
{
|
|
||||||
new bool:enabled = GetConVarBool(g_hCvarsList[CVAR_ENABLE]);
|
|
||||||
if (argc < 1 || !enabled)
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
decl String:arg1[32];
|
|
||||||
GetCmdArg(1, arg1, sizeof(arg1));
|
|
||||||
|
|
||||||
decl String:target_name_list[MAX_TARGET_LENGTH];
|
|
||||||
new targets[MAXPLAYERS];
|
|
||||||
new bool:tn_is_ml;
|
|
||||||
|
|
||||||
new tcount = ProcessTargetString(arg1, client, targets, MAXPLAYERS, COMMAND_FILTER_DEAD, target_name_list, sizeof(target_name_list), tn_is_ml);
|
|
||||||
if (tcount <= 0)
|
|
||||||
{
|
|
||||||
ReplyToTargetError(client, tcount);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
decl String:client_name[64];
|
|
||||||
decl String:target_name[64];
|
|
||||||
|
|
||||||
if (client > 0)
|
|
||||||
{
|
|
||||||
GetClientName(client, client_name, sizeof(client_name));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
client_name = "Console\0";
|
|
||||||
}
|
|
||||||
|
|
||||||
new team;
|
|
||||||
for (new x = 0; x < tcount; x++)
|
|
||||||
{
|
|
||||||
team = GetClientTeam(targets[x]);
|
|
||||||
if (team == CS_TEAM_T || team == CS_TEAM_CT)
|
|
||||||
{
|
|
||||||
if (LogCheckFlag(LOG_GAME_EVENTS, LOG_MODULE_COMMANDS))
|
|
||||||
{
|
|
||||||
GetClientName(targets[x], target_name, sizeof(target_name));
|
|
||||||
LogMessageFormatted(targets[x], "admin commands", "spawn", "\"%s\" spawned player \"%s\".", true, client_name, target_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
RespawnSpawnClient(targets[x]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*public Action:Command_AdminMenu(client, argc)
|
|
||||||
{
|
|
||||||
if (ZRIsClientValid(client))
|
|
||||||
{
|
|
||||||
ZAdminMenu(client);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// BAD!
|
|
||||||
// ReplyToCommand(client, "This menu cannot be used from the console.");
|
|
||||||
}
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action:Command_KnockbackMMenu(client, argc)
|
|
||||||
{
|
|
||||||
if (ZRIsClientValid(client))
|
|
||||||
{
|
|
||||||
// Disabled, under construction.
|
|
||||||
// ZRKnockbackMMenu(client);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Tsk tsk no translation? :P
|
|
||||||
//ReplyToCommand(client, "This menu cannot be used from the console.");
|
|
||||||
}
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action:Command_TeleMenu(client, argc)
|
|
||||||
{
|
|
||||||
if (ZRIsClientValid(client))
|
|
||||||
{
|
|
||||||
ZRZTeleMenu(client);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// BAD!
|
|
||||||
ReplyToCommand(client, "This menu cannot be used from the console.");
|
|
||||||
}
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action:Command_LogFlags(client, argc)
|
|
||||||
{
|
|
||||||
decl String:message[2048];
|
|
||||||
message[0] = 0;
|
|
||||||
|
|
||||||
StrCat(message, sizeof(message), "LOG_CORE_EVENTS (1) - Log core events like executing files, error messages, etc.\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_GAME_EVENTS (2) - Log game events like admin commands, suicide prevention and anticamp kills.\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_PLAYER_COMMANDS (4) - Log commands made by the player.\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_DEBUG (8) - Enable debug messages (if they exist).\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_DEBUG_DETAIL (16) - Detailed debug messages. May cause spam.\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_DEBUG_MAX_DETAIL (32) - Low level detailed debug messages. Causes spam! Only enable right before and after testing.\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_LOG_TO_ADMINS (64) - Display log messages to admin chat.\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_LOG_TO_CLIENT (128) - Display log messages to the client that executed the event/command.\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_IGNORE_CONSOLE (256) - Don't log messages from client 0 (console).\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULES_ENABLED (512) - Enable detailed log control for developers. Module logs overrides previous flags.\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_ZOMBIE (1024) - zombie.inc");
|
|
||||||
|
|
||||||
ReplyToCommand(client, message);
|
|
||||||
message[0] = 0;
|
|
||||||
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_AMBIENTSOUNDS (2048) - ambientsounds.inc\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_OVERLAYS (4096) - overlays.inc\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_SAYTRIGGERS (8192) - sayhooks.inc\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_TELEPORT (16384) - teleport.inc\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_CLASSES (32768) - classes.inc\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_WEAPONRESTICT (65536) - weaponrestrict.inc\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_COMMANDS (131072) - commands.inc\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_ANTICAMP (262144) - anticamp.inc\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_DAMAGE (524288) - damage.inc\n");
|
|
||||||
StrCat(message, sizeof(message), "LOG_MODULE_OFFSETS (524288) - offsets.inc");
|
|
||||||
|
|
||||||
ReplyToCommand(client, message);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}*/
|
|
@ -126,7 +126,7 @@ enum CvarsList
|
|||||||
Handle:CVAR_AMBIENTSOUNDS_LENGTH,
|
Handle:CVAR_AMBIENTSOUNDS_LENGTH,
|
||||||
Handle:CVAR_AMBIENTSOUNDS_VOLUME,
|
Handle:CVAR_AMBIENTSOUNDS_VOLUME,
|
||||||
Handle:CVAR_ANTISTICK,
|
Handle:CVAR_ANTISTICK,
|
||||||
Handle:CVAR_ANTISTICK_INTERVAL,
|
Handle:CVAR_ANTISTICK_FILE_PATH,
|
||||||
Handle:CVAR_SPAWNPROTECT,
|
Handle:CVAR_SPAWNPROTECT,
|
||||||
Handle:CVAR_SPAWNPROTECT_TIME,
|
Handle:CVAR_SPAWNPROTECT_TIME,
|
||||||
Handle:CVAR_SPAWNPROTECT_SPEED,
|
Handle:CVAR_SPAWNPROTECT_SPEED,
|
||||||
@ -387,8 +387,8 @@ CvarsCreate()
|
|||||||
// ===========================
|
// ===========================
|
||||||
// Anti-Stick (module)
|
// Anti-Stick (module)
|
||||||
// ===========================
|
// ===========================
|
||||||
g_hCvarsList[CVAR_ANTISTICK] = CreateConVar("zr_antistick", "1", "Automatically unstick players when stuck within each others' collision hull.");
|
g_hCvarsList[CVAR_ANTISTICK] = CreateConVar("zr_antistick", "1", "Automatically unstick players when stuck within each others' collision hull.");
|
||||||
g_hCvarsList[CVAR_ANTISTICK_INTERVAL] = CreateConVar("zr_antistick_interval", "0.5", "Time between each check for stuck players. [Dependency: zr_antistick]");
|
g_hCvarsList[CVAR_ANTISTICK_FILE_PATH] = CreateConVar("zr_antistick_file_path", "data/antistick.dat", "File to store antistick model hull data. [Dependency: zr_antistick]");
|
||||||
|
|
||||||
// ===========================
|
// ===========================
|
||||||
// Spawn Protect (module)
|
// Spawn Protect (module)
|
||||||
|
@ -87,7 +87,6 @@ public Action:EventRoundStart(Handle:event, const String:name[], bool:dontBroadc
|
|||||||
RoundEndOnRoundStart();
|
RoundEndOnRoundStart();
|
||||||
InfectOnRoundStart();
|
InfectOnRoundStart();
|
||||||
SEffectsOnRoundStart();
|
SEffectsOnRoundStart();
|
||||||
AntiStickOnRoundStart();
|
|
||||||
ZSpawnOnRoundStart();
|
ZSpawnOnRoundStart();
|
||||||
VolOnRoundStart();
|
VolOnRoundStart();
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea
|
|||||||
|
|
||||||
// Get attackers eye angles.
|
// Get attackers eye angles.
|
||||||
new Float:attackerang[3];
|
new Float:attackerang[3];
|
||||||
KnockbackGetClientEyeAngles(attacker, attackerang);
|
GetClientEyeAngles(attacker, attackerang);
|
||||||
|
|
||||||
// Calculate knockback end-vector.
|
// Calculate knockback end-vector.
|
||||||
TR_TraceRayFilter(attackerloc, attackerang, MASK_ALL, RayType_Infinite, KnockbackTRFilter);
|
TR_TraceRayFilter(attackerloc, attackerang, MASK_ALL, RayType_Infinite, KnockbackTRFilter);
|
||||||
@ -198,15 +198,4 @@ KnockbackFindExplodingGrenade(Float:heLoc[3])
|
|||||||
|
|
||||||
// Didn't find the grenade.
|
// Didn't find the grenade.
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get client's eye angles.
|
|
||||||
*
|
|
||||||
* @param client The client index.
|
|
||||||
* @param vecAngles The angle vector of the client's eyes.
|
|
||||||
*/
|
|
||||||
KnockbackGetClientEyeAngles(client, Float:vecAngles[3])
|
|
||||||
{
|
|
||||||
SDKCall(g_hToolsEyeAngles, client, vecAngles);
|
|
||||||
}
|
|
@ -70,7 +70,7 @@ enum LogModules
|
|||||||
bool:LogModule_Invalid = 0, /** Used as return value when an error occoured.*/
|
bool:LogModule_Invalid = 0, /** Used as return value when an error occoured.*/
|
||||||
|
|
||||||
bool:LogModule_Account,
|
bool:LogModule_Account,
|
||||||
bool:LogModule_Antistick,
|
bool:LogModule_AntiStick,
|
||||||
bool:LogModule_Config,
|
bool:LogModule_Config,
|
||||||
bool:LogModule_Cvars,
|
bool:LogModule_Cvars,
|
||||||
bool:LogModule_Damage,
|
bool:LogModule_Damage,
|
||||||
|
@ -59,7 +59,7 @@ LogGetModuleNameString(String:buffer[], maxlen, LogModules:module, bool:shortNam
|
|||||||
{
|
{
|
||||||
return shortName ? strcopy(buffer, maxlen, "account") : strcopy(buffer, maxlen, "Account");
|
return shortName ? strcopy(buffer, maxlen, "account") : strcopy(buffer, maxlen, "Account");
|
||||||
}
|
}
|
||||||
case LogModule_Antistick:
|
case LogModule_AntiStick:
|
||||||
{
|
{
|
||||||
return shortName ? strcopy(buffer, maxlen, "antistick") : strcopy(buffer, maxlen, "Anti-Stick");
|
return shortName ? strcopy(buffer, maxlen, "antistick") : strcopy(buffer, maxlen, "Anti-Stick");
|
||||||
}
|
}
|
||||||
@ -148,7 +148,7 @@ LogModules:LogGetModule(const String:moduleName[])
|
|||||||
}
|
}
|
||||||
else if (StrEqual(moduleName, "antistick", false))
|
else if (StrEqual(moduleName, "antistick", false))
|
||||||
{
|
{
|
||||||
return LogModule_Antistick;
|
return LogModule_AntiStick;
|
||||||
}
|
}
|
||||||
else if (StrEqual(moduleName, "config", false))
|
else if (StrEqual(moduleName, "config", false))
|
||||||
{
|
{
|
||||||
|
@ -42,7 +42,6 @@ new g_iToolsDefaultFOV;
|
|||||||
* Initialize global SDKTools handles.
|
* Initialize global SDKTools handles.
|
||||||
*/
|
*/
|
||||||
new Handle:g_hToolsGameConfig = INVALID_HANDLE;
|
new Handle:g_hToolsGameConfig = INVALID_HANDLE;
|
||||||
new Handle:g_hToolsEyeAngles = INVALID_HANDLE;
|
|
||||||
new Handle:g_hToolsTerminateRound = INVALID_HANDLE;
|
new Handle:g_hToolsTerminateRound = INVALID_HANDLE;
|
||||||
new Handle:g_hToolsCSWeaponDrop = INVALID_HANDLE;
|
new Handle:g_hToolsCSWeaponDrop = INVALID_HANDLE;
|
||||||
/**
|
/**
|
||||||
@ -108,7 +107,6 @@ ToolsFindOffsets()
|
|||||||
WeaponsOnOffsetsFound();
|
WeaponsOnOffsetsFound();
|
||||||
AccountOnOffsetsFound();
|
AccountOnOffsetsFound();
|
||||||
VEffectsOnOffsetsFound();
|
VEffectsOnOffsetsFound();
|
||||||
AntiStickOnOffsetsFound();
|
|
||||||
ZMarketOnOffsetsFound();
|
ZMarketOnOffsetsFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,18 +124,6 @@ ToolsSetupGameData()
|
|||||||
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "GameData", "Can't load game config file (plugin.zombiereloaded.txt) from the gamedata directory.");
|
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "GameData", "Can't load game config file (plugin.zombiereloaded.txt) from the gamedata directory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prep the SDKCall for "EyeAngles."
|
|
||||||
StartPrepSDKCall(SDKCall_Player);
|
|
||||||
PrepSDKCall_SetFromConf(g_hToolsGameConfig, SDKConf_Virtual, "EyeAngles");
|
|
||||||
PrepSDKCall_SetReturnInfo(SDKType_QAngle, SDKPass_ByValue);
|
|
||||||
g_hToolsEyeAngles = EndPrepSDKCall();
|
|
||||||
|
|
||||||
// If offset "EyeAngles" can't be found, then stop the plugin.
|
|
||||||
if(g_hToolsEyeAngles == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "GameData", "Offset \"EyeAngles\" was not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prep the SDKCall for "TerminateRound."
|
// Prep the SDKCall for "TerminateRound."
|
||||||
StartPrepSDKCall(SDKCall_GameRules);
|
StartPrepSDKCall(SDKCall_GameRules);
|
||||||
PrepSDKCall_SetFromConf(g_hToolsGameConfig, SDKConf_Signature, "TerminateRound");
|
PrepSDKCall_SetFromConf(g_hToolsGameConfig, SDKConf_Signature, "TerminateRound");
|
||||||
|
Loading…
Reference in New Issue
Block a user