summaryrefslogtreecommitdiff
path: root/source/sourcemod/scripting
diff options
context:
space:
mode:
Diffstat (limited to 'source/sourcemod/scripting')
-rw-r--r--source/sourcemod/scripting/gokz-anticheat.sp4
-rw-r--r--source/sourcemod/scripting/gokz-core.sp6
-rw-r--r--source/sourcemod/scripting/gokz-core/demofix.sp47
-rw-r--r--source/sourcemod/scripting/gokz-core/misc.sp9
-rw-r--r--source/sourcemod/scripting/gokz-errorboxfixer.sp89
-rw-r--r--source/sourcemod/scripting/gokz-global.sp740
-rw-r--r--source/sourcemod/scripting/gokz-goto.sp231
-rw-r--r--source/sourcemod/scripting/gokz-hud.sp3
-rw-r--r--source/sourcemod/scripting/gokz-mode-kztimer.sp709
-rw-r--r--source/sourcemod/scripting/gokz-mode-simplekz.sp846
-rw-r--r--source/sourcemod/scripting/gokz-paint.sp410
-rw-r--r--source/sourcemod/scripting/gokz-pistol.sp303
-rw-r--r--source/sourcemod/scripting/gokz-playermodels.sp198
-rw-r--r--source/sourcemod/scripting/gokz-profile.sp396
-rw-r--r--source/sourcemod/scripting/gokz-quiet.sp151
-rw-r--r--source/sourcemod/scripting/gokz-racing.sp174
-rw-r--r--source/sourcemod/scripting/gokz-replays.sp397
-rw-r--r--source/sourcemod/scripting/gokz-slayonend.sp190
-rw-r--r--source/sourcemod/scripting/gokz-spec.sp323
-rw-r--r--source/sourcemod/scripting/gokz-tips.sp357
-rw-r--r--source/sourcemod/scripting/include/dhooks.inc731
-rw-r--r--source/sourcemod/scripting/include/gokz.inc44
-rw-r--r--source/sourcemod/scripting/include/movementapi.inc2
-rw-r--r--source/sourcemod/scripting/movementapi.sp239
-rw-r--r--source/sourcemod/scripting/movementapi/forwards.sp268
-rw-r--r--source/sourcemod/scripting/movementapi/hooks.sp580
-rw-r--r--source/sourcemod/scripting/movementapi/natives.sp183
-rw-r--r--source/sourcemod/scripting/movementapi/stocks.sp200
28 files changed, 1854 insertions, 5976 deletions
diff --git a/source/sourcemod/scripting/gokz-anticheat.sp b/source/sourcemod/scripting/gokz-anticheat.sp
index 9925eca..e35f025 100644
--- a/source/sourcemod/scripting/gokz-anticheat.sp
+++ b/source/sourcemod/scripting/gokz-anticheat.sp
@@ -167,7 +167,7 @@ public MRESReturn DHooks_OnTeleport(int client, Handle params)
public void GOKZ_OnFirstSpawn(int client)
{
- GOKZ_PrintToChat(client, false, "%t", "Anti-Cheat Warning");
+ // GOKZ_PrintToChat(client, false, "%t", "Anti-Cheat Warning");
}
public void GOKZ_AC_OnPlayerSuspected(int client, ACReason reason, const char[] notes, const char[] stats)
@@ -315,4 +315,4 @@ static void AutoBanClient(int client, int minutes, const char[] reason, const ch
{
BanClient(client, minutes, BANFLAG_AUTO, reason, kickMessage, "gokz-anticheat", 0);
}
-} \ No newline at end of file
+}
diff --git a/source/sourcemod/scripting/gokz-core.sp b/source/sourcemod/scripting/gokz-core.sp
index 897403f..429bab5 100644
--- a/source/sourcemod/scripting/gokz-core.sp
+++ b/source/sourcemod/scripting/gokz-core.sp
@@ -216,7 +216,7 @@ public void OnPlayerSpawn(Event event, const char[] name, bool dontBroadcast) //
OnPlayerSpawn_Pause(client);
OnPlayerSpawn_ValidJump(client);
OnPlayerSpawn_FirstSpawn(client);
- OnPlayerSpawn_GodMode(client);
+ // OnPlayerSpawn_GodMode(client);
OnPlayerSpawn_PlayerCollision(client);
}
}
@@ -439,7 +439,7 @@ public void OnRoundStart(Event event, const char[] name, bool dontBroadcast) //
public Action CS_OnTerminateRound(float &delay, CSRoundEndReason &reason)
{
- return Plugin_Handled;
+ return Plugin_Continue;
}
public void GOKZ_OnModeUnloaded(int mode)
@@ -540,4 +540,4 @@ static bool IsRealObjective(char[] objective)
{
return StrEqual(objective, "PRISON ESCAPE") || StrEqual(objective, "DEATHMATCH")
|| StrEqual(objective, "BOMB TARGET") || StrEqual(objective, "HOSTAGE RESCUE");
-} \ No newline at end of file
+}
diff --git a/source/sourcemod/scripting/gokz-core/demofix.sp b/source/sourcemod/scripting/gokz-core/demofix.sp
index 84a9307..3839fad 100644
--- a/source/sourcemod/scripting/gokz-core/demofix.sp
+++ b/source/sourcemod/scripting/gokz-core/demofix.sp
@@ -8,7 +8,7 @@ void OnPluginStart_Demofix()
CV_EnableDemofix = AutoExecConfig_CreateConVar("gokz_demofix", "1", "Whether GOKZ applies demo record fix to server. (0 = Disabled, 1 = Update warmup period once, 2 = Regularly reset warmup period)", _, true, 0.0, true, 2.0);
CV_EnableDemofix.AddChangeHook(OnDemofixConVarChanged);
// If the map is tweaking the warmup value, we need to rerun the fix again.
- FindConVar("mp_warmuptime").AddChangeHook(OnDemofixConVarChanged);
+ // FindConVar("mp_warmuptime").AddChangeHook(OnDemofixConVarChanged);
// We assume that the map is already loaded on late load.
if (gB_LateLoad)
{
@@ -28,7 +28,7 @@ void OnMapEnd_Demofix()
void OnRoundStart_Demofix()
{
- DoDemoFix();
+ // DoDemoFix();
}
public Action Command_Demorestart(int client, const char[] command, int argc)
@@ -53,7 +53,7 @@ static void FixRecord(int client)
public void OnDemofixConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
{
- DoDemoFix();
+ // DoDemoFix();
}
public Action Timer_EnableDemoRecord(Handle timer)
@@ -64,47 +64,10 @@ public Action Timer_EnableDemoRecord(Handle timer)
static void DoDemoFix()
{
- if (H_DemofixTimer != null)
- {
- delete H_DemofixTimer;
- }
- // Setting the cvar value to 1 can avoid clogging the demo file and slightly increase performance.
- switch (CV_EnableDemofix.IntValue)
- {
- case 0:
- {
- if (!mapRunning)
- {
- return;
- }
- GameRules_SetProp("m_bWarmupPeriod", 0);
- }
- case 1:
- {
- // Set warmup time to 2^31-1, effectively forever
- if (FindConVar("mp_warmuptime").IntValue != 2147483647)
- {
- FindConVar("mp_warmuptime").SetInt(2147483647);
- }
- EnableDemoRecord();
- }
- case 2:
- {
- H_DemofixTimer = CreateTimer(1.0, Timer_EnableDemoRecord, _, TIMER_REPEAT);
- }
- }
}
static void EnableDemoRecord()
{
- // Enable warmup to allow demo recording
- // m_fWarmupPeriodEnd is set in the past to hide the timer UI
- if (!mapRunning)
- {
- return;
- }
- GameRules_SetProp("m_bWarmupPeriod", 1);
- GameRules_SetPropFloat("m_fWarmupPeriodStart", GetGameTime() - 1.0);
- GameRules_SetPropFloat("m_fWarmupPeriodEnd", GetGameTime() - 1.0);
-} \ No newline at end of file
+
+}
diff --git a/source/sourcemod/scripting/gokz-core/misc.sp b/source/sourcemod/scripting/gokz-core/misc.sp
index a117880..ae44a1d 100644
--- a/source/sourcemod/scripting/gokz-core/misc.sp
+++ b/source/sourcemod/scripting/gokz-core/misc.sp
@@ -208,7 +208,7 @@ void OnPlayerRunCmd_Turnbinds(int client, int buttons, int tickcount, float angl
void OnPlayerSpawn_PlayerCollision(int client)
{
// Let players go through other players
- SetEntProp(client, Prop_Send, "m_CollisionGroup", GOKZ_COLLISION_GROUP_STANDARD);
+ // SetEntProp(client, Prop_Send, "m_CollisionGroup", GOKZ_COLLISION_GROUP_STANDARD);
}
void OnSetModel_PlayerCollision(int client)
@@ -230,7 +230,7 @@ void OnSetModel_PlayerCollision(int client)
void OnRoundStart_ForceAllTalk()
{
- gCV_sv_full_alltalk.BoolValue = true;
+ // gCV_sv_full_alltalk.BoolValue = true;
}
@@ -350,7 +350,10 @@ void JoinTeam(int client, int newTeam, bool restorePos, bool forceBroadcast = fa
// Need to teleport the player to a valid one.
float spawnOrigin[3];
float spawnAngles[3];
- GetValidSpawn(spawnOrigin, spawnAngles);
+ if (newTeam == CS_TEAM_CT)
+ GetValidSpawnCT(spawnOrigin, spawnAngles);
+ else
+ GetValidSpawnT(spawnOrigin, spawnAngles);
TeleportPlayer(client, spawnOrigin, spawnAngles);
}
hasSavedPosition[client] = false;
diff --git a/source/sourcemod/scripting/gokz-errorboxfixer.sp b/source/sourcemod/scripting/gokz-errorboxfixer.sp
deleted file mode 100644
index fd3f76a..0000000
--- a/source/sourcemod/scripting/gokz-errorboxfixer.sp
+++ /dev/null
@@ -1,89 +0,0 @@
-#include <sourcemod>
-#include <sdktools>
-
-#include <gokz>
-
-#undef REQUIRE_PLUGIN
-#include <updater>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-public Plugin myinfo =
-{
- name = "GOKZ KZErrorBoxFixer",
- author = "1NutWunDeR",
- description = "Adds missing models for KZ maps",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-errorboxfixer.txt"
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-public void OnMapStart()
-{
- AddFileToDownloadsTable("models/kzmod/buttons/stand_button.vtf");
- AddFileToDownloadsTable("models/kzmod/buttons/stand_button.vmt");
- AddFileToDownloadsTable("models/kzmod/buttons/stand_button_normal.vtf");
- AddFileToDownloadsTable("models/kzmod/buttons/standing_button.mdl");
- AddFileToDownloadsTable("models/kzmod/buttons/standing_button.dx90.vtx");
- AddFileToDownloadsTable("models/kzmod/buttons/standing_button.phy");
- AddFileToDownloadsTable("models/kzmod/buttons/standing_button.vvd");
- AddFileToDownloadsTable("models/kzmod/buttons/stone_button.mdl");
- AddFileToDownloadsTable("models/kzmod/buttons/stone_button.dx90.vtx");
- AddFileToDownloadsTable("models/kzmod/buttons/stone_button.phy");
- AddFileToDownloadsTable("models/kzmod/buttons/stone_button.vvd");
- AddFileToDownloadsTable("models/props_wasteland/pipecluster002a.mdl");
- AddFileToDownloadsTable("models/props_wasteland/pipecluster002a.dx90.vtx");
- AddFileToDownloadsTable("models/props_wasteland/pipecluster002a.phy");
- AddFileToDownloadsTable("models/props_wasteland/pipecluster002a.vvd");
- AddFileToDownloadsTable("materials/kzmod/starttimersign.vmt");
- AddFileToDownloadsTable("materials/kzmod/starttimersign.vtf");
- AddFileToDownloadsTable("materials/kzmod/stoptimersign.vmt");
- AddFileToDownloadsTable("materials/kzmod/stoptimersign.vtf");
- AddFileToDownloadsTable("models/props/switch001.mdl");
- AddFileToDownloadsTable("models/props/switch001.vvd");
- AddFileToDownloadsTable("models/props/switch001.phy");
- AddFileToDownloadsTable("models/props/switch001.vtx");
- AddFileToDownloadsTable("models/props/switch001.dx90.vtx");
- AddFileToDownloadsTable("materials/models/props/switch.vmt");
- AddFileToDownloadsTable("materials/models/props/switch.vtf");
- AddFileToDownloadsTable("materials/models/props/switch001.vmt");
- AddFileToDownloadsTable("materials/models/props/switch001.vtf");
- AddFileToDownloadsTable("materials/models/props/switch001_normal.vmt");
- AddFileToDownloadsTable("materials/models/props/switch001_normal.vtf");
- AddFileToDownloadsTable("materials/models/props/switch001_lightwarp.vmt");
- AddFileToDownloadsTable("materials/models/props/switch001_lightwarp.vtf");
- AddFileToDownloadsTable("materials/models/props/switch001_exponent.vmt");
- AddFileToDownloadsTable("materials/models/props/switch001_exponent.vtf");
- AddFileToDownloadsTable("materials/models/props/startkztimer.vmt");
- AddFileToDownloadsTable("materials/models/props/startkztimer.vtf");
- AddFileToDownloadsTable("materials/models/props/stopkztimer.vmt");
- AddFileToDownloadsTable("materials/models/props/stopkztimer.vtf");
-
- PrecacheModel("models/kzmod/buttons/stand_button.vmt", true);
- PrecacheModel("models/props_wasteland/pipecluster002a.mdl", true);
- PrecacheModel("models/kzmod/buttons/standing_button.mdl", true);
- PrecacheModel("models/kzmod/buttons/stone_button.mdl", true);
- PrecacheModel("materials/kzmod/starttimersign.vmt", true);
- PrecacheModel("materials/kzmod/stoptimersign.vmt", true);
- PrecacheModel("models/props/switch001.mdl", true);
- PrecacheModel("materials/models/props/startkztimer.vmt", true);
- PrecacheModel("materials/models/props/stopkztimer.vmt", true);
-}
diff --git a/source/sourcemod/scripting/gokz-global.sp b/source/sourcemod/scripting/gokz-global.sp
deleted file mode 100644
index 79f8b6a..0000000
--- a/source/sourcemod/scripting/gokz-global.sp
+++ /dev/null
@@ -1,740 +0,0 @@
-#include <sourcemod>
-
-#include <sdktools>
-
-#include <GlobalAPI>
-#include <gokz/anticheat>
-#include <gokz/core>
-#include <gokz/global>
-#include <gokz/replays>
-#include <gokz/momsurffix>
-
-#include <autoexecconfig>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <gokz/localdb>
-#include <gokz/localranks>
-#include <updater>
-
-#include <gokz/kzplayer>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Global",
- author = "DanZay",
- description = "Provides centralised records and bans via GlobalAPI",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-global.txt"
-
-bool gB_GOKZLocalDB;
-
-bool gB_APIKeyCheck;
-bool gB_ModeCheck[MODE_COUNT];
-bool gB_BannedCommandsCheck;
-char gC_CurrentMap[64];
-int gI_CurrentMapFileSize;
-bool gB_InValidRun[MAXPLAYERS + 1];
-bool gB_GloballyVerified[MAXPLAYERS + 1];
-bool gB_EnforcerOnFreshMap;
-bool gB_JustLateLoaded;
-int gI_FPSMax[MAXPLAYERS + 1];
-bool gB_waitingForFPSKick[MAXPLAYERS + 1];
-bool gB_MapValidated;
-int gI_MapID;
-int gI_MapFileSize;
-int gI_MapTier;
-
-ConVar gCV_gokz_settings_enforcer;
-ConVar gCV_gokz_warn_for_non_global_map;
-ConVar gCV_EnforcedCVar[ENFORCEDCVAR_COUNT];
-
-#include "gokz-global/api.sp"
-#include "gokz-global/ban_player.sp"
-#include "gokz-global/commands.sp"
-#include "gokz-global/maptop_menu.sp"
-#include "gokz-global/print_records.sp"
-#include "gokz-global/send_run.sp"
-#include "gokz-global/points.sp"
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- CreateNatives();
- RegPluginLibrary("gokz-global");
- gB_JustLateLoaded = late;
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- if (FloatAbs(1.0 / GetTickInterval() - 128.0) > EPSILON)
- {
- SetFailState("gokz-global currently only supports 128 tickrate servers.");
- }
- if (FindCommandLineParam("-insecure") || FindCommandLineParam("-tools"))
- {
- SetFailState("gokz-global currently only supports VAC-secured servers.");
- }
- LoadTranslations("gokz-common.phrases");
- LoadTranslations("gokz-global.phrases");
-
- gB_APIKeyCheck = false;
- gB_MapValidated = false;
- gI_MapID = -1;
- gI_MapFileSize = -1;
- gI_MapTier = -1;
-
- for (int mode = 0; mode < MODE_COUNT; mode++)
- {
- gB_ModeCheck[mode] = false;
- }
-
- CreateConVars();
- CreateGlobalForwards();
- RegisterCommands();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
- gB_GOKZLocalDB = LibraryExists("gokz-localdb");
-
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsClientInGame(client))
- {
- OnClientPutInServer(client);
- }
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
- gB_GOKZLocalDB = gB_GOKZLocalDB || StrEqual(name, "gokz-localdb");
-}
-
-public void OnLibraryRemoved(const char[] name)
-{
- gB_GOKZLocalDB = gB_GOKZLocalDB && !StrEqual(name, "gokz-localdb");
-}
-
-Action IntegrityChecks(Handle timer)
-{
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsValidClient(client) && !IsFakeClient(client))
- {
- QueryClientConVar(client, "fps_max", FPSCheck, client);
- QueryClientConVar(client, "m_yaw", MYAWCheck, client);
- }
- }
-
- for (int i = 0; i < BANNEDPLUGINCOMMAND_COUNT; i++)
- {
- if (CommandExists(gC_BannedPluginCommands[i]))
- {
- Handle bannedIterator = GetPluginIterator();
- char pluginName[128];
- bool foundPlugin = false;
- while (MorePlugins(bannedIterator))
- {
- Handle bannedPlugin = ReadPlugin(bannedIterator);
- GetPluginInfo(bannedPlugin, PlInfo_Name, pluginName, sizeof(pluginName));
- if (StrEqual(pluginName, gC_BannedPlugins[i]))
- {
- char pluginPath[128];
- GetPluginFilename(bannedPlugin, pluginPath, sizeof(pluginPath));
- ServerCommand("sm plugins unload %s", pluginPath);
- char disabledPath[256], enabledPath[256], pluginFile[4][128];
- int subfolders = ExplodeString(pluginPath, "/", pluginFile, sizeof(pluginFile), sizeof(pluginFile[]));
- BuildPath(Path_SM, disabledPath, sizeof(disabledPath), "plugins/disabled/%s", pluginFile[subfolders - 1]);
- BuildPath(Path_SM, enabledPath, sizeof(enabledPath), "plugins/%s", pluginPath);
- RenameFile(disabledPath, enabledPath);
- LogError("[KZ] %s cannot be loaded at the same time as gokz-global. %s has been disabled.", pluginName, pluginName);
- delete bannedPlugin;
- foundPlugin = true;
- break;
- }
- delete bannedPlugin;
- }
- if (!foundPlugin && gB_BannedCommandsCheck)
- {
- gB_BannedCommandsCheck = false;
- LogError("You can't have a plugin which implements the %s command. Please disable it and reload the map.", gC_BannedPluginCommands[i]);
- }
- delete bannedIterator;
- }
- }
-
- return Plugin_Handled;
-}
-
-public void FPSCheck(QueryCookie cookie, int client, ConVarQueryResult result, const char[] cvarName, const char[] cvarValue, any value)
-{
- if (IsValidClient(client) && !IsFakeClient(client))
- {
- gI_FPSMax[client] = StringToInt(cvarValue);
- if (gI_FPSMax[client] > 0 && gI_FPSMax[client] < GL_FPS_MAX_MIN_VALUE)
- {
- if (!gB_waitingForFPSKick[client])
- {
- gB_waitingForFPSKick[client] = true;
- CreateTimer(GL_FPS_MAX_KICK_TIMEOUT, FPSKickPlayer, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE);
- GOKZ_PrintToChat(client, true, "%t", "Warn Player fps_max");
- if (GOKZ_GetTimerRunning(client))
- {
- GOKZ_StopTimer(client, true);
- }
- else
- {
- GOKZ_EmitSoundToClient(client, GOKZ_SOUND_TIMER_STOP, _, "Timer Stop");
- }
- }
- }
- else
- {
- gB_waitingForFPSKick[client] = false;
- }
- }
-}
-
-public void MYAWCheck(QueryCookie cookie, int client, ConVarQueryResult result, const char[] cvarName, const char[] cvarValue, any value)
-{
- if (IsValidClient(client) && !IsFakeClient(client) && StringToFloat(cvarValue) > GL_MYAW_MAX_VALUE)
- {
- KickClient(client, "%T", "Kick Player m_yaw", client);
- }
-}
-
-Action FPSKickPlayer(Handle timer, int userid)
-{
- int client = GetClientOfUserId(userid);
- if (IsValidClient(client) && !IsFakeClient(client) && gB_waitingForFPSKick[client])
- {
- KickClient(client, "%T", "Kick Player fps_max", client);
- }
-
- return Plugin_Handled;
-}
-
-
-
-// =====[ CLIENT EVENTS ]=====
-
-public void OnClientPutInServer(int client)
-{
- gB_GloballyVerified[client] = false;
- gB_waitingForFPSKick[client] = false;
- OnClientPutInServer_PrintRecords(client);
-}
-
-// OnClientAuthorized is apparently too early
-public void OnClientPostAdminCheck(int client)
-{
- ResetPoints(client);
-
- if (GlobalAPI_IsInit() && !IsFakeClient(client))
- {
- CheckClientGlobalBan(client);
- UpdatePoints(client);
- }
-}
-
-public void GlobalAPI_OnInitialized()
-{
- SetupAPI();
-}
-
-
-public Action GOKZ_OnTimerStart(int client, int course)
-{
- KZPlayer player = KZPlayer(client);
- int mode = player.Mode;
-
- // We check the timer running to prevent spam when standing inside VB.
- if (gCV_gokz_warn_for_non_global_map.BoolValue
- && GlobalAPI_HasAPIKey()
- && !GlobalsEnabled(mode)
- && !GOKZ_GetTimerRunning(client))
- {
- GOKZ_PrintToChat(client, true, "%t", "Warn Player Not Global Run");
- }
-
- return Plugin_Continue;
-}
-
-public void GOKZ_OnTimerStart_Post(int client, int course)
-{
- KZPlayer player = KZPlayer(client);
- int mode = player.Mode;
- gB_InValidRun[client] = GlobalsEnabled(mode);
-}
-
-public void GOKZ_OnTimerEnd_Post(int client, int course, float time, int teleportsUsed)
-{
- if (gB_GloballyVerified[client] && gB_InValidRun[client])
- {
- SendTime(client, course, time, teleportsUsed);
- }
-}
-
-public Action GOKZ_RP_OnReplaySaved(int client, int replayType, const char[] map, int course, int timeType, float time, const char[] filePath, bool tempReplay)
-{
- if (gB_GloballyVerified[client] && gB_InValidRun[client])
- {
- OnReplaySaved_SendReplay(client, replayType, map, course, timeType, time, filePath, tempReplay);
- return Plugin_Handled;
- }
- return Plugin_Continue;
-}
-
-public void GOKZ_OnRunInvalidated(int client)
-{
- gB_InValidRun[client] = false;
-}
-
-public void GOKZ_GL_OnNewTopTime(int client, int course, int mode, int timeType, int rank, int rankOverall, float runTime)
-{
- AnnounceNewTopTime(client, course, mode, timeType, rank, rankOverall);
-}
-
-public void GOKZ_AC_OnPlayerSuspected(int client, ACReason reason, const char[] notes, const char[] stats)
-{
- if (!gB_GloballyVerified[client])
- {
- return;
- }
-
- GlobalBanPlayer(client, reason, notes, stats);
- gB_GloballyVerified[client] = false;
-}
-
-
-
-// =====[ OTHER EVENTS ]=====
-
-public void OnMapStart()
-{
- LoadSounds();
-
- GetCurrentMapDisplayName(gC_CurrentMap, sizeof(gC_CurrentMap));
- gI_CurrentMapFileSize = GetCurrentMapFileSize();
-
- gB_BannedCommandsCheck = true;
-
- // Prevent just reloading the plugin after messing with the map
- if (gB_JustLateLoaded)
- {
- gB_JustLateLoaded = false;
- }
- else
- {
- gB_EnforcerOnFreshMap = true;
- }
-
- // In case of late loading
- if (GlobalAPI_IsInit())
- {
- GlobalAPI_OnInitialized();
- }
-
- // Setup a timer to monitor server/client integrity
- CreateTimer(1.0, IntegrityChecks, INVALID_HANDLE, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT);
-}
-
-public void OnMapEnd()
-{
- // So it doesn't get carried over to the next map
- gI_MapID = -1;
- for (int client = 1; client < MaxClients; client++)
- {
- ResetMapPoints(client);
- }
-}
-
-public void GOKZ_OnOptionChanged(int client, const char[] option, any newValue)
-{
- if (StrEqual(option, gC_CoreOptionNames[Option_Mode])
- && GlobalAPI_IsInit())
- {
- UpdatePoints(client);
- }
-}
-
-public void GOKZ_OnModeUnloaded(int mode)
-{
- gB_ModeCheck[mode] = false;
-}
-
-public Action GOKZ_OnTimerNativeCalledExternally(Handle plugin, int client)
-{
- char pluginName[64];
- GetPluginInfo(plugin, PlInfo_Name, pluginName, sizeof(pluginName));
- if (GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client))
- {
- LogMessage("Invalidated %N's run as gokz-core native was called by \"%s\"", client, pluginName);
- }
- GOKZ_InvalidateRun(client);
- return Plugin_Continue;
-}
-
-
-
-// =====[ PUBLIC ]=====
-
-bool GlobalsEnabled(int mode)
-{
- return gB_APIKeyCheck && gB_BannedCommandsCheck && gCV_gokz_settings_enforcer.BoolValue && gB_EnforcerOnFreshMap && MapCheck() && gB_ModeCheck[mode];
-}
-
-bool MapCheck()
-{
- return gB_MapValidated
- && gI_MapID > 0
- && gI_MapFileSize == gI_CurrentMapFileSize;
-}
-
-void PrintGlobalCheckToChat(int client)
-{
- GOKZ_PrintToChat(client, true, "%t", "Global Check Header");
- GOKZ_PrintToChat(client, false, "%t", "Global Check",
- gB_APIKeyCheck ? "{green}✓" : "{darkred}X",
- gB_BannedCommandsCheck ? "{green}✓" : "{darkred}X",
- gCV_gokz_settings_enforcer.BoolValue && gB_EnforcerOnFreshMap ? "{green}✓" : "{darkred}X",
- MapCheck() ? "{green}✓" : "{darkred}X",
- gB_GloballyVerified[client] ? "{green}✓" : "{darkred}X");
-
- char modeCheck[256];
- FormatEx(modeCheck, sizeof(modeCheck), "{purple}%s %s", gC_ModeNames[0], gB_ModeCheck[0] ? "{green}✓" : "{darkred}X");
- for (int i = 1; i < MODE_COUNT; i++)
- {
- FormatEx(modeCheck, sizeof(modeCheck), "%s {grey}| {purple}%s %s", modeCheck, gC_ModeNames[i], gB_ModeCheck[i] ? "{green}✓" : "{darkred}X");
- }
- GOKZ_PrintToChat(client, false, "%s", modeCheck);
-}
-
-void AnnounceNewTopTime(int client, int course, int mode, int timeType, int rank, int rankOverall)
-{
- bool newRecord = false;
-
- if (timeType == TimeType_Nub && rankOverall != 0)
- {
- if (rankOverall == 1)
- {
- if (course == 0)
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Record (NUB)", client, gC_ModeNamesShort[mode]);
- }
- else
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Bonus Record (NUB)", client, course, gC_ModeNamesShort[mode]);
- }
- newRecord = true;
- }
- else
- {
- if (course == 0)
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Top Time (NUB)", client, rankOverall, gC_ModeNamesShort[mode]);
- }
- else
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Top Bonus Time (NUB)", client, rankOverall, course, gC_ModeNamesShort[mode]);
- }
- }
- }
- else if (timeType == TimeType_Pro)
- {
- if (rankOverall != 0)
- {
- if (rankOverall == 1)
- {
- if (course == 0)
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Record (NUB)", client, gC_ModeNamesShort[mode]);
- }
- else
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Bonus Record (NUB)", client, course, gC_ModeNamesShort[mode]);
- }
- newRecord = true;
- }
- else
- {
- if (course == 0)
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Top Time (NUB)", client, rankOverall, gC_ModeNamesShort[mode]);
- }
- else
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Top Bonus Time (NUB)", client, rankOverall, course, gC_ModeNamesShort[mode]);
- }
- }
- }
-
- if (rank == 1)
- {
- if (course == 0)
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Record (PRO)", client, gC_ModeNamesShort[mode]);
- }
- else
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Bonus Record (PRO)", client, course, gC_ModeNamesShort[mode]);
- }
- newRecord = true;
- }
- else
- {
- if (course == 0)
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Top Time (PRO)", client, rank, gC_ModeNamesShort[mode]);
- }
- else
- {
- GOKZ_PrintToChatAll(true, "%t", "New Global Top Bonus Time (PRO)", client, rank, course, gC_ModeNamesShort[mode]);
- }
- }
- }
-
- if (newRecord)
- {
- PlayBeatRecordSound();
- }
-}
-
-void PlayBeatRecordSound()
-{
- GOKZ_EmitSoundToAll(GL_SOUND_NEW_RECORD, _, "World Record");
-}
-
-
-
-// =====[ PRIVATE ]=====
-
-static void CreateConVars()
-{
- AutoExecConfig_SetFile("gokz-global", "sourcemod/gokz");
- AutoExecConfig_SetCreateFile(true);
-
- gCV_gokz_settings_enforcer = AutoExecConfig_CreateConVar("gokz_settings_enforcer", "1", "Whether GOKZ enforces convars required for global records.", _, true, 0.0, true, 1.0);
- gCV_gokz_warn_for_non_global_map = AutoExecConfig_CreateConVar("gokz_warn_for_non_global_map", "1", "Whether or not GOKZ should warn players if the global check does not pass.", _, true, 0.0, true, 1.0);
- gCV_gokz_settings_enforcer.AddChangeHook(OnConVarChanged);
-
- AutoExecConfig_ExecuteFile();
- AutoExecConfig_CleanFile();
-
- for (int i = 0; i < ENFORCEDCVAR_COUNT; i++)
- {
- gCV_EnforcedCVar[i] = FindConVar(gC_EnforcedCVars[i]);
- gCV_EnforcedCVar[i].FloatValue = gF_EnforcedCVarValues[i];
- gCV_EnforcedCVar[i].AddChangeHook(OnEnforcedConVarChanged);
- }
-}
-
-public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
-{
- if (convar == gCV_gokz_settings_enforcer)
- {
- if (gCV_gokz_settings_enforcer.BoolValue)
- {
- for (int i = 0; i < ENFORCEDCVAR_COUNT; i++)
- {
- gCV_EnforcedCVar[i].FloatValue = gF_EnforcedCVarValues[i];
- }
- }
- else
- {
- for (int client = 1; client <= MaxClients; client++)
- {
- gB_InValidRun[client] = false;
- }
-
- // You have to change map before you can re-activate that
- gB_EnforcerOnFreshMap = false;
- }
- }
-}
-
-public void OnEnforcedConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
-{
- if (gCV_gokz_settings_enforcer.BoolValue)
- {
- for (int i = 0; i < ENFORCEDCVAR_COUNT; i++)
- {
- if (convar == gCV_EnforcedCVar[i])
- {
- gCV_EnforcedCVar[i].FloatValue = gF_EnforcedCVarValues[i];
- return;
- }
- }
- }
-}
-
-static void SetupAPI()
-{
- GlobalAPI_GetAuthStatus(GetAuthStatusCallback);
- GlobalAPI_GetModes(GetModeInfoCallback);
- GlobalAPI_GetMapByName(GetMapCallback, _, gC_CurrentMap);
-
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsValidClient(client) && !IsFakeClient(client))
- {
- CheckClientGlobalBan(client);
- }
- }
-}
-
-public int GetAuthStatusCallback(JSON_Object auth_json, GlobalAPIRequestData request)
-{
- if (request.Failure)
- {
- LogError("Failed to check API key with Global API.");
- return 0;
- }
-
- APIAuth auth = view_as<APIAuth>(auth_json);
- if (!auth.IsValid)
- {
- LogError("Global API key was found to be missing or invalid.");
- }
- gB_APIKeyCheck = auth.IsValid;
- return 0;
-}
-
-public int GetModeInfoCallback(JSON_Object modes, GlobalAPIRequestData request)
-{
- if (request.Failure)
- {
- LogError("Failed to check mode versions with Global API.");
- return 0;
- }
-
- if (!modes.IsArray)
- {
- LogError("GlobalAPI returned a malformed response while looking up the modes.");
- return 0;
- }
-
- for (int i = 0; i < modes.Length; i++)
- {
- APIMode mode = view_as<APIMode>(modes.GetObjectIndexed(i));
- int mode_id = GOKZ_GL_FromGlobalMode(view_as<GlobalMode>(mode.Id));
- if (mode_id == -1)
- {
- LogError("GlobalAPI returned a malformed mode.");
- }
- else if (mode.LatestVersion <= GOKZ_GetModeVersion(mode_id))
- {
- gB_ModeCheck[mode_id] = true;
- }
- else
- {
- char desc[128];
-
- gB_ModeCheck[mode_id] = false;
- mode.GetLatestVersionDesc(desc, sizeof(desc));
- LogError("Global API requires %s mode version %d (%s). You have version %d (%s).",
- gC_ModeNames[mode_id], mode.LatestVersion, desc, GOKZ_GetModeVersion(mode_id), GOKZ_VERSION);
- }
- }
- return 0;
-}
-
-public int GetMapCallback(JSON_Object map_json, GlobalAPIRequestData request)
-{
- if (request.Failure || map_json == INVALID_HANDLE)
- {
- LogError("Failed to get map info.");
- return 0;
- }
-
- APIMap map = view_as<APIMap>(map_json);
-
- gB_MapValidated = map.IsValidated;
- gI_MapID = map.Id;
- gI_MapFileSize = map.Filesize;
- gI_MapTier = map.Difficulty;
-
- // We don't do that earlier cause we need the map ID
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsValidClient(client) && IsClientAuthorized(client) && !IsFakeClient(client))
- {
- UpdatePoints(client);
- }
- }
- return 0;
-}
-
-void CheckClientGlobalBan(int client)
-{
- char steamid[32];
- GetClientAuthId(client, AuthId_Steam2, steamid, sizeof(steamid));
- GlobalAPI_GetPlayerBySteamId(CheckClientGlobalBan_Callback, client, steamid);
-}
-
-public void CheckClientGlobalBan_Callback(JSON_Object player_json, GlobalAPIRequestData request, int client)
-{
- if (!IsValidClient(client))
- {
- return;
- }
-
- if (request.Failure)
- {
- LogError("Failed to get ban info.");
- return;
- }
-
- char client_steamid[32], response_steamid[32];
- GetClientAuthId(client, AuthId_Steam2, client_steamid, sizeof(client_steamid));
-
- if (!player_json.IsArray || player_json.Length != 1)
- {
- LogError("Got malformed reply when querying steamid %s", client_steamid);
- return;
- }
-
- APIPlayer player = view_as<APIPlayer>(player_json.GetObjectIndexed(0));
- player.GetSteamId(response_steamid, sizeof(response_steamid));
- if (!StrEqual(client_steamid, response_steamid))
- {
- return;
- }
-
- gB_GloballyVerified[client] = !player.IsBanned;
-
- if (player.IsBanned && gB_GOKZLocalDB)
- {
- GOKZ_DB_SetCheater(client, true);
- }
-}
-
-static void LoadSounds()
-{
- char downloadPath[PLATFORM_MAX_PATH];
- FormatEx(downloadPath, sizeof(downloadPath), "sound/%s", GL_SOUND_NEW_RECORD);
- AddFileToDownloadsTable(downloadPath);
- PrecacheSound(GL_SOUND_NEW_RECORD, true);
-} \ No newline at end of file
diff --git a/source/sourcemod/scripting/gokz-goto.sp b/source/sourcemod/scripting/gokz-goto.sp
deleted file mode 100644
index 7dd67cb..0000000
--- a/source/sourcemod/scripting/gokz-goto.sp
+++ /dev/null
@@ -1,231 +0,0 @@
-#include <sourcemod>
-
-#include <cstrike>
-#include <sdktools>
-
-#include <gokz/core>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <updater>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Goto",
- author = "DanZay",
- description = "Allows players to teleport to another player",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-goto.txt"
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- RegPluginLibrary("gokz-goto");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- LoadTranslations("common.phrases");
- LoadTranslations("gokz-common.phrases");
- LoadTranslations("gokz-goto.phrases");
-
- RegisterCommands();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-
-
-// =====[ GOTO ]=====
-
-// Returns whether teleport to target was successful
-bool GotoPlayer(int client, int target, bool printMessage = true)
-{
- if (GOKZ_GetCoreOption(client, Option_Safeguard) > Safeguard_Disabled && GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client))
- {
- if (printMessage)
- {
- GOKZ_PrintToChat(client, true, "%t", "Safeguard - Blocked");
- GOKZ_PlayErrorSound(client);
- }
- return false;
- }
- if (target == client)
- {
- if (printMessage)
- {
- GOKZ_PrintToChat(client, true, "%t", "Goto Failure (Not Yourself)");
- GOKZ_PlayErrorSound(client);
- }
- return false;
- }
- if (!IsPlayerAlive(target))
- {
- if (printMessage)
- {
- GOKZ_PrintToChat(client, true, "%t", "Goto Failure (Dead)");
- GOKZ_PlayErrorSound(client);
- }
- return false;
- }
-
- float targetOrigin[3];
- float targetAngles[3];
-
- Movement_GetOrigin(target, targetOrigin);
- Movement_GetEyeAngles(target, targetAngles);
-
- if (!IsPlayerAlive(client))
- {
- GOKZ_RespawnPlayer(client);
- }
-
- TeleportPlayer(client, targetOrigin, targetAngles);
-
- GOKZ_PrintToChat(client, true, "%t", "Goto Success", target);
-
- if (GOKZ_GetTimerRunning(client))
- {
- GOKZ_PrintToChat(client, true, "%t", "Timer Stopped (Goto)");
- GOKZ_StopTimer(client);
- }
-
- return true;
-}
-
-
-
-// =====[ GOTO MENU ]=====
-
-int DisplayGotoMenu(int client)
-{
- Menu menu = new Menu(MenuHandler_Goto);
- menu.SetTitle("%T", "Goto Menu - Title", client);
- int menuItems = GotoMenuAddItems(client, menu);
- if (menuItems == 0)
- {
- delete menu;
- }
- else
- {
- menu.Display(client, MENU_TIME_FOREVER);
- }
- return menuItems;
-}
-
-public int MenuHandler_Goto(Menu menu, MenuAction action, int param1, int param2)
-{
- if (action == MenuAction_Select)
- {
- char info[16];
- menu.GetItem(param2, info, sizeof(info));
- int target = GetClientOfUserId(StringToInt(info));
-
- if (!IsValidClient(target))
- {
- GOKZ_PrintToChat(param1, true, "%t", "Player No Longer Valid");
- GOKZ_PlayErrorSound(param1);
- DisplayGotoMenu(param1);
- }
- else if (!GotoPlayer(param1, target))
- {
- DisplayGotoMenu(param1);
- }
- }
- else if (action == MenuAction_End)
- {
- delete menu;
- }
- return 0;
-}
-
-// Returns number of items added to the menu
-int GotoMenuAddItems(int client, Menu menu)
-{
- char display[MAX_NAME_LENGTH + 4];
- int targetCount = 0;
-
- for (int i = 1; i <= MaxClients; i++)
- {
- if (!IsClientInGame(i) || !IsPlayerAlive(i) || i == client)
- {
- continue;
- }
-
- if (IsFakeClient(i))
- {
- FormatEx(display, sizeof(display), "BOT %N", i);
- }
- else
- {
- FormatEx(display, sizeof(display), "%N", i);
- }
-
- menu.AddItem(IntToStringEx(GetClientUserId(i)), display, ITEMDRAW_DEFAULT);
- targetCount++;
- }
-
- return targetCount;
-}
-
-
-
-// =====[ COMMANDS ]=====
-
-void RegisterCommands()
-{
- RegConsoleCmd("sm_goto", CommandGoto, "[KZ] Teleport to another player. Usage: !goto <player>");
-}
-
-public Action CommandGoto(int client, int args)
-{
- // If no arguments, display the goto menu
- if (args < 1)
- {
- if (DisplayGotoMenu(client) == 0)
- {
- // No targets, so show error
- GOKZ_PrintToChat(client, true, "%t", "No Players Found");
- GOKZ_PlayErrorSound(client);
- }
- }
- // Otherwise try to teleport to the specified player
- else
- {
- char specifiedPlayer[MAX_NAME_LENGTH];
- GetCmdArg(1, specifiedPlayer, sizeof(specifiedPlayer));
-
- int target = FindTarget(client, specifiedPlayer, false, false);
- if (target != -1)
- {
- GotoPlayer(client, target);
- }
- }
- return Plugin_Handled;
-} \ No newline at end of file
diff --git a/source/sourcemod/scripting/gokz-hud.sp b/source/sourcemod/scripting/gokz-hud.sp
index e9db12a..3a5b7e9 100644
--- a/source/sourcemod/scripting/gokz-hud.sp
+++ b/source/sourcemod/scripting/gokz-hud.sp
@@ -196,7 +196,6 @@ public void OnPlayerSpawn(Event event, const char[] name, bool dontBroadcast) //
public Action OnPlayerDeath(Event event, const char[] name, bool dontBroadcast) // player_death pre hook
{
- event.BroadcastDisabled = true; // Block death notices
return Plugin_Continue;
}
@@ -331,4 +330,4 @@ static void SetHUDInfo(KZPlayer player, HUDInfo info, int cmdnum)
info.IsTakeoff = Movement_GetTakeoffCmdNum(player.ID) == cmdnum;
info.Buttons = player.Buttons;
info.CurrentTeleport = player.TeleportCount;
-} \ No newline at end of file
+}
diff --git a/source/sourcemod/scripting/gokz-mode-kztimer.sp b/source/sourcemod/scripting/gokz-mode-kztimer.sp
deleted file mode 100644
index 272652b..0000000
--- a/source/sourcemod/scripting/gokz-mode-kztimer.sp
+++ /dev/null
@@ -1,709 +0,0 @@
-#include <sourcemod>
-
-#include <sdkhooks>
-#include <sdktools>
-#include <dhooks>
-
-#include <movementapi>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <gokz/core>
-#include <updater>
-
-#include <gokz/kzplayer>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Mode - KZTimer",
- author = "DanZay",
- description = "KZTimer mode for GOKZ",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-mode-kztimer.txt"
-
-#define MODE_VERSION 217
-#define DUCK_SPEED_NORMAL 8.0
-#define PRE_VELMOD_MAX 1.104 // Calculated 276/250
-#define PERF_SPEED_CAP 380.0
-
-float gF_ModeCVarValues[MODECVAR_COUNT] =
-{
- 6.5, // sv_accelerate
- 0.0, // sv_accelerate_use_weapon_speed
- 100.0, // sv_airaccelerate
- 30.0, // sv_air_max_wishspeed
- 1.0, // sv_enablebunnyhopping
- 5.0, // sv_friction
- 800.0, // sv_gravity
- 301.993377, // sv_jump_impulse
- 1.0, // sv_ladder_scale_speed
- 0.0, // sv_ledge_mantle_helper
- 320.0, // sv_maxspeed
- 2000.0, // sv_maxvelocity
- 0.0, // sv_staminajumpcost
- 0.0, // sv_staminalandcost
- 0.0, // sv_staminamax
- 0.0, // sv_staminarecoveryrate
- 0.7, // sv_standable_normal
- 0.0, // sv_timebetweenducks
- 0.7, // sv_walkable_normal
- 10.0, // sv_wateraccelerate
- 0.8, // sv_water_movespeed_multiplier
- 0.0, // sv_water_swim_mode
- 0.0, // sv_weapon_encumbrance_per_item
- 0.0 // sv_weapon_encumbrance_scale
-};
-
-bool gB_GOKZCore;
-ConVar gCV_ModeCVar[MODECVAR_COUNT];
-float gF_PreVelMod[MAXPLAYERS + 1];
-float gF_PreVelModLastChange[MAXPLAYERS + 1];
-float gF_RealPreVelMod[MAXPLAYERS + 1];
-int gI_PreTickCounter[MAXPLAYERS + 1];
-Handle gH_GetPlayerMaxSpeed;
-DynamicDetour gH_CanUnduck;
-int gI_TickCount[MAXPLAYERS + 1];
-DynamicDetour gH_AirAccelerate;
-int gI_OldButtons[MAXPLAYERS + 1];
-int gI_OldFlags[MAXPLAYERS + 1];
-bool gB_OldOnGround[MAXPLAYERS + 1];
-float gF_OldVelocity[MAXPLAYERS + 1][3];
-bool gB_Jumpbugged[MAXPLAYERS + 1];
-int gI_OffsetCGameMovement_player;
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public void OnPluginStart()
-{
- if (FloatAbs(1.0 / GetTickInterval() - 128.0) > EPSILON)
- {
- SetFailState("gokz-mode-kztimer only supports 128 tickrate servers.");
- }
- HookEvents();
- CreateConVars();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
- if (LibraryExists("gokz-core"))
- {
- gB_GOKZCore = true;
- GOKZ_SetModeLoaded(Mode_KZTimer, true, MODE_VERSION);
- }
-
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsClientInGame(client))
- {
- OnClientPutInServer(client);
- }
- }
-}
-
-public void OnPluginEnd()
-{
- if (gB_GOKZCore)
- {
- GOKZ_SetModeLoaded(Mode_KZTimer, false);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
- else if (StrEqual(name, "gokz-core"))
- {
- gB_GOKZCore = true;
- GOKZ_SetModeLoaded(Mode_KZTimer, true, MODE_VERSION);
- }
-}
-
-public void OnLibraryRemoved(const char[] name)
-{
- gB_GOKZCore = gB_GOKZCore && !StrEqual(name, "gokz-core");
-}
-
-
-
-// =====[ CLIENT EVENTS ]=====
-
-public void OnClientPutInServer(int client)
-{
- if (IsValidClient(client))
- {
- HookClientEvents(client);
- }
- if (IsUsingMode(client))
- {
- ReplicateConVars(client);
- }
-}
-
-public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
-{
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return Plugin_Continue;
- }
-
- KZPlayer player = KZPlayer(client);
- RemoveCrouchJumpBind(player, buttons);
- gF_RealPreVelMod[player.ID] = CalcPrestrafeVelMod(player);
- ReduceDuckSlowdown(player);
- FixWaterBoost(player, buttons);
- FixDisplacementStuck(player);
-
- gB_Jumpbugged[player.ID] = false;
- gI_OldButtons[player.ID] = buttons;
- gI_OldFlags[player.ID] = GetEntityFlags(client);
- gB_OldOnGround[player.ID] = Movement_GetOnGround(client);
- gI_TickCount[player.ID] = tickcount;
- Movement_GetVelocity(client, gF_OldVelocity[client]);
- return Plugin_Continue;
-}
-
-public MRESReturn DHooks_OnGetPlayerMaxSpeed(int client, Handle hReturn)
-{
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return MRES_Ignored;
- }
-
- DHookSetReturn(hReturn, SPEED_NORMAL * gF_RealPreVelMod[client]);
- return MRES_Supercede;
-}
-
-public MRESReturn DHooks_OnAirAccelerate_Pre(Address pThis, DHookParam hParams)
-{
- int client = GOKZGetClientFromGameMovementAddress(pThis, gI_OffsetCGameMovement_player);
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return MRES_Ignored;
- }
-
- // NOTE: Prestrafing changes GetPlayerMaxSpeed, which changes
- // air acceleration, so remove gF_PreVelMod[client] from wishspeed/maxspeed.
- // This also applies to when the player is ducked: their wishspeed is
- // 85 and with prestrafing can be ~93.
- float wishspeed = DHookGetParam(hParams, 2);
- if (gF_PreVelMod[client] > 1.0)
- {
- DHookSetParam(hParams, 2, wishspeed / gF_PreVelMod[client]);
- return MRES_ChangedHandled;
- }
-
- return MRES_Ignored;
-}
-
-public MRESReturn DHooks_OnCanUnduck_Pre(Address pThis, DHookReturn hReturn)
-{
- int client = GOKZGetClientFromGameMovementAddress(pThis, gI_OffsetCGameMovement_player);
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return MRES_Ignored;
- }
- // Just landed fully ducked, you can't unduck.
- if (Movement_GetLandingTick(client) == (gI_TickCount[client] - 1) && GetEntPropFloat(client, Prop_Send, "m_flDuckAmount") >= 1.0 && GetEntProp(client, Prop_Send, "m_bDucked"))
- {
- hReturn.Value = false;
- return MRES_Supercede;
- }
- return MRES_Ignored;
-}
-
-public void SDKHook_OnClientPreThink_Post(int client)
-{
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return;
- }
-
- // Don't tweak convars if GOKZ isn't running
- if (gB_GOKZCore)
- {
- TweakConVars();
- }
-}
-
-public Action Movement_OnCategorizePositionPost(int client, float origin[3], float velocity[3])
-{
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return Plugin_Continue;
- }
- return SlopeFix(client, origin, velocity);
-}
-
-public Action Movement_OnJumpPre(int client, float origin[3], float velocity[3])
-{
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return Plugin_Continue;
- }
-
- KZPlayer player = KZPlayer(client);
- return TweakJump(player, velocity);
-}
-
-public Action Movement_OnJumpPost(int client)
-{
- if (!IsUsingMode(client))
- {
- return Plugin_Continue;
- }
-
- KZPlayer player = KZPlayer(client);
- if (gB_GOKZCore)
- {
- player.GOKZHitPerf = player.HitPerf;
- player.GOKZTakeoffSpeed = player.TakeoffSpeed;
- }
- return Plugin_Continue;
-}
-
-public void Movement_OnStopTouchGround(int client)
-{
- if (!IsUsingMode(client))
- {
- return;
- }
-
- KZPlayer player = KZPlayer(client);
- if (gB_GOKZCore)
- {
- player.GOKZHitPerf = player.HitPerf;
- player.GOKZTakeoffSpeed = player.TakeoffSpeed;
- }
-}
-
-public void Movement_OnChangeMovetype(int client, MoveType oldMovetype, MoveType newMovetype)
-{
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return;
- }
-
- KZPlayer player = KZPlayer(client);
- if (gB_GOKZCore && newMovetype == MOVETYPE_WALK)
- {
- player.GOKZHitPerf = false;
- player.GOKZTakeoffSpeed = player.TakeoffSpeed;
- }
-}
-
-public void GOKZ_OnOptionChanged(int client, const char[] option, any newValue)
-{
- if (StrEqual(option, gC_CoreOptionNames[Option_Mode]) && newValue == Mode_KZTimer)
- {
- ReplicateConVars(client);
- }
-}
-
-public void GOKZ_OnCountedTeleport_Post(int client)
-{
- KZPlayer player = KZPlayer(client);
- ResetPrestrafeVelMod(player);
-}
-
-
-
-// =====[ GENERAL ]=====
-
-bool IsUsingMode(int client)
-{
- // If GOKZ core isn't loaded, then apply mode at all times
- return !gB_GOKZCore || GOKZ_GetCoreOption(client, Option_Mode) == Mode_KZTimer;
-}
-
-void HookEvents()
-{
- GameData gameData = LoadGameConfigFile("movementapi.games");
- if (gameData == INVALID_HANDLE)
- {
- SetFailState("Failed to find movementapi.games config");
- }
-
- int offset = gameData.GetOffset("GetPlayerMaxSpeed");
- if (offset == -1)
- {
- SetFailState("Failed to get GetPlayerMaxSpeed offset");
- }
- gH_GetPlayerMaxSpeed = DHookCreate(offset, HookType_Entity, ReturnType_Float, ThisPointer_CBaseEntity, DHooks_OnGetPlayerMaxSpeed);
-
- gH_AirAccelerate = DynamicDetour.FromConf(gameData, "CGameMovement::AirAccelerate");
- if (gH_AirAccelerate == INVALID_HANDLE)
- {
- SetFailState("Failed to find CGameMovement::AirAccelerate function signature");
- }
-
- if (!gH_AirAccelerate.Enable(Hook_Pre, DHooks_OnAirAccelerate_Pre))
- {
- SetFailState("Failed to enable detour on CGameMovement::AirAccelerate");
- }
-
- char buffer[16];
- if (!gameData.GetKeyValue("CGameMovement::player", buffer, sizeof(buffer)))
- {
- SetFailState("Failed to get CGameMovement::player offset.");
- }
- gI_OffsetCGameMovement_player = StringToInt(buffer);
-
- gameData = LoadGameConfigFile("gokz-core.games");
- gH_CanUnduck = DynamicDetour.FromConf(gameData, "CCSGameMovement::CanUnduck");
- if (gH_CanUnduck == INVALID_HANDLE)
- {
- SetFailState("Failed to find CCSGameMovement::CanUnduck function signature");
- }
-
- if (!gH_CanUnduck.Enable(Hook_Pre, DHooks_OnCanUnduck_Pre))
- {
- SetFailState("Failed to enable detour on CCSGameMovement::CanUnduck");
- }
- delete gameData;
-}
-
-// =====[ CONVARS ]=====
-
-void CreateConVars()
-{
- for (int cvar = 0; cvar < MODECVAR_COUNT; cvar++)
- {
- gCV_ModeCVar[cvar] = FindConVar(gC_ModeCVars[cvar]);
- }
-}
-
-void TweakConVars()
-{
- for (int i = 0; i < MODECVAR_COUNT; i++)
- {
- gCV_ModeCVar[i].FloatValue = gF_ModeCVarValues[i];
- }
-}
-
-void ReplicateConVars(int client)
-{
- // Replicate convars only when player changes mode in GOKZ
- // so that lagg isn't caused by other players using other
- // modes, and also as an optimisation.
-
- if (IsFakeClient(client))
- {
- return;
- }
-
- for (int i = 0; i < MODECVAR_COUNT; i++)
- {
- gCV_ModeCVar[i].ReplicateToClient(client, FloatToStringEx(gF_ModeCVarValues[i]));
- }
-}
-
-
-
-// =====[ VELOCITY MODIFIER ]=====
-
-void HookClientEvents(int client)
-{
- DHookEntity(gH_GetPlayerMaxSpeed, true, client);
- SDKHook(client, SDKHook_PreThinkPost, SDKHook_OnClientPreThink_Post);
-}
-
-// Adapted from KZTimerGlobal
-float CalcPrestrafeVelMod(KZPlayer player)
-{
- if (!player.OnGround)
- {
- return gF_PreVelMod[player.ID];
- }
-
- if (!player.Turning)
- {
- if (GetEngineTime() - gF_PreVelModLastChange[player.ID] > 0.2)
- {
- gF_PreVelMod[player.ID] = 1.0;
- gF_PreVelModLastChange[player.ID] = GetEngineTime();
- }
- else if (gF_PreVelMod[player.ID] > PRE_VELMOD_MAX + 0.007)
- {
- return PRE_VELMOD_MAX - 0.001; // Returning without setting the variable is intentional
- }
- }
- else if ((player.Buttons & IN_MOVELEFT || player.Buttons & IN_MOVERIGHT) && player.Speed > 248.9)
- {
- float increment = 0.0009;
- if (gF_PreVelMod[player.ID] > 1.04)
- {
- increment = 0.001;
- }
-
- bool forwards = GetClientMovingDirection(player.ID, false) > 0.0;
-
- if ((player.Buttons & IN_MOVERIGHT && player.TurningRight || player.TurningLeft && !forwards)
- || (player.Buttons & IN_MOVELEFT && player.TurningLeft || player.TurningRight && !forwards))
- {
- gI_PreTickCounter[player.ID]++;
-
- if (gI_PreTickCounter[player.ID] < 75)
- {
- gF_PreVelMod[player.ID] += increment;
- if (gF_PreVelMod[player.ID] > PRE_VELMOD_MAX)
- {
- if (gF_PreVelMod[player.ID] > PRE_VELMOD_MAX + 0.007)
- {
- gF_PreVelMod[player.ID] = PRE_VELMOD_MAX - 0.001;
- }
- else
- {
- gF_PreVelMod[player.ID] -= 0.007;
- }
- }
- gF_PreVelMod[player.ID] += increment;
- }
- else
- {
- gF_PreVelMod[player.ID] -= 0.0045;
- gI_PreTickCounter[player.ID] -= 2;
-
- if (gF_PreVelMod[player.ID] < 1.0)
- {
- gF_PreVelMod[player.ID] = 1.0;
- gI_PreTickCounter[player.ID] = 0;
- }
- }
- }
- else
- {
- gF_PreVelMod[player.ID] -= 0.04;
-
- if (gF_PreVelMod[player.ID] < 1.0)
- {
- gF_PreVelMod[player.ID] = 1.0;
- }
- }
-
- gF_PreVelModLastChange[player.ID] = GetEngineTime();
- }
- else
- {
- gI_PreTickCounter[player.ID] = 0;
- return 1.0; // Returning without setting the variable is intentional
- }
-
- return gF_PreVelMod[player.ID];
-}
-
-// Adapted from KZTimerGlobal
-float GetClientMovingDirection(int client, bool ladder)
-{
- float fVelocity[3];
- GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fVelocity);
-
- float fEyeAngles[3];
- GetClientEyeAngles(client, fEyeAngles);
-
- if (fEyeAngles[0] > 70.0)fEyeAngles[0] = 70.0;
- if (fEyeAngles[0] < -70.0)fEyeAngles[0] = -70.0;
-
- float fViewDirection[3];
-
- if (ladder)
- {
- GetEntPropVector(client, Prop_Send, "m_vecLadderNormal", fViewDirection);
- }
- else
- {
- GetAngleVectors(fEyeAngles, fViewDirection, NULL_VECTOR, NULL_VECTOR);
- }
-
- NormalizeVector(fVelocity, fVelocity);
- NormalizeVector(fViewDirection, fViewDirection);
-
- float direction = GetVectorDotProduct(fVelocity, fViewDirection);
- if (ladder)
- {
- direction = direction * -1;
- }
- return direction;
-}
-
-void ResetPrestrafeVelMod(KZPlayer player)
-{
- gF_PreVelMod[player.ID] = 1.0;
- gI_PreTickCounter[player.ID] = 0;
-}
-
-
-
-// =====[ SLOPEFIX ]=====
-
-// ORIGINAL AUTHORS : Mev & Blacky
-// URL : https://forums.alliedmods.net/showthread.php?p=2322788
-// NOTE : Modified by DanZay for this plugin
-
-Action SlopeFix(int client, float origin[3], float velocity[3])
-{
- KZPlayer player = KZPlayer(client);
- // Check if player landed on the ground
- if (Movement_GetOnGround(client) && !gB_OldOnGround[client])
- {
- float vMins[] = {-16.0, -16.0, 0.0};
- // Always use ducked hull as the real hull size isn't updated yet.
- // Might cause slight issues in extremely rare scenarios.
- float vMaxs[] = {16.0, 16.0, 54.0};
-
- float vEndPos[3];
- vEndPos[0] = origin[0];
- vEndPos[1] = origin[1];
- vEndPos[2] = origin[2] - gF_ModeCVarValues[ModeCVar_MaxVelocity];
-
- // Set up and do tracehull to find out if the player landed on a slope
- TR_TraceHullFilter(origin, vEndPos, vMins, vMaxs, MASK_PLAYERSOLID_BRUSHONLY, TraceRayDontHitSelf, client);
-
- if (TR_DidHit())
- {
- // Gets the normal vector of the surface under the player
- float vPlane[3], vLast[3];
- player.GetLandingVelocity(vLast);
- TR_GetPlaneNormal(null, vPlane);
-
- // Make sure it's not flat ground and not a surf ramp (1.0 = flat ground, < 0.7 = surf ramp)
- if (0.7 <= vPlane[2] < 1.0)
- {
- /*
- Copy the ClipVelocity function from sdk2013
- (https://mxr.alliedmods.net/hl2sdk-sdk2013/source/game/shared/gamemovement.cpp#3145)
- With some minor changes to make it actually work
- */
-
- float fBackOff = GetVectorDotProduct(vLast, vPlane);
-
- float change, vVel[3];
- for (int i; i < 2; i++)
- {
- change = vPlane[i] * fBackOff;
- vVel[i] = vLast[i] - change;
- }
-
- float fAdjust = GetVectorDotProduct(vVel, vPlane);
- if (fAdjust < 0.0)
- {
- for (int i; i < 2; i++)
- {
- vVel[i] -= (vPlane[i] * fAdjust);
- }
- }
-
- vVel[2] = 0.0;
- vLast[2] = 0.0;
-
- // Make sure the player is going down a ramp by checking if they actually will gain speed from the boost
- if (GetVectorLength(vVel) > GetVectorLength(vLast))
- {
- CopyVector(vVel, velocity);
- player.SetLandingVelocity(velocity);
- return Plugin_Changed;
- }
- }
- }
- }
- return Plugin_Continue;
-}
-
-public bool TraceRayDontHitSelf(int entity, int mask, any data)
-{
- return entity != data && !(0 < entity <= MaxClients);
-}
-
-
-
-// =====[ JUMPING ]=====
-
-Action TweakJump(KZPlayer player, float velocity[3])
-{
- if (player.HitPerf)
- {
- if (GetVectorHorizontalLength(velocity) > PERF_SPEED_CAP)
- {
- SetVectorHorizontalLength(velocity, PERF_SPEED_CAP);
- return Plugin_Changed;
- }
- }
- return Plugin_Continue;
-}
-// =====[ OTHER ]=====
-
-void FixWaterBoost(KZPlayer player, int buttons)
-{
- if (GetEntProp(player.ID, Prop_Send, "m_nWaterLevel") >= 2) // WL_Waist = 2
- {
- // If duck is being pressed and we're not already ducking or on ground
- if (GetEntityFlags(player.ID) & (FL_DUCKING | FL_ONGROUND) == 0
- && buttons & IN_DUCK && ~gI_OldButtons[player.ID] & IN_DUCK)
- {
- float newOrigin[3];
- Movement_GetOrigin(player.ID, newOrigin);
- newOrigin[2] += 9.0;
-
- TR_TraceHullFilter(newOrigin, newOrigin, view_as<float>({-16.0, -16.0, 0.0}), view_as<float>({16.0, 16.0, 54.0}), MASK_PLAYERSOLID, TraceEntityFilterPlayers);
- if (!TR_DidHit())
- {
- TeleportEntity(player.ID, newOrigin, NULL_VECTOR, NULL_VECTOR);
- }
- }
- }
-}
-
-void FixDisplacementStuck(KZPlayer player)
-{
- int flags = GetEntityFlags(player.ID);
- bool unducked = ~flags & FL_DUCKING && gI_OldFlags[player.ID] & FL_DUCKING;
-
- float standingMins[] = {-16.0, -16.0, 0.0};
- float standingMaxs[] = {16.0, 16.0, 72.0};
-
- if (unducked)
- {
- // check if we're stuck after unducking and if we're stuck then force duck
- float origin[3];
- Movement_GetOrigin(player.ID, origin);
- TR_TraceHullFilter(origin, origin, standingMins, standingMaxs, MASK_PLAYERSOLID, TraceEntityFilterPlayers);
-
- if (TR_DidHit())
- {
- player.SetVelocity(gF_OldVelocity[player.ID]);
- SetEntProp(player.ID, Prop_Send, "m_bDucking", true);
- }
- }
-}
-
-void RemoveCrouchJumpBind(KZPlayer player, int &buttons)
-{
- if (player.OnGround && buttons & IN_JUMP && !(gI_OldButtons[player.ID] & IN_JUMP) && !(gI_OldButtons[player.ID] & IN_DUCK))
- {
- buttons &= ~IN_DUCK;
- }
-}
-
-void ReduceDuckSlowdown(KZPlayer player)
-{
- if (GetEntProp(player.ID, Prop_Data, "m_afButtonReleased") & IN_DUCK)
- {
- Movement_SetDuckSpeed(player.ID, DUCK_SPEED_NORMAL);
- }
-}
diff --git a/source/sourcemod/scripting/gokz-mode-simplekz.sp b/source/sourcemod/scripting/gokz-mode-simplekz.sp
deleted file mode 100644
index 99d76ac..0000000
--- a/source/sourcemod/scripting/gokz-mode-simplekz.sp
+++ /dev/null
@@ -1,846 +0,0 @@
-#include <sourcemod>
-
-#include <sdkhooks>
-#include <sdktools>
-#include <dhooks>
-
-#include <movementapi>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <gokz/core>
-#include <updater>
-
-#include <gokz/kzplayer>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Mode - SimpleKZ",
- author = "DanZay",
- description = "SimpleKZ mode for GOKZ",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-mode-simplekz.txt"
-
-#define MODE_VERSION 21
-#define PS_MAX_REWARD_TURN_RATE 0.703125 // Degrees per tick (90 degrees per second)
-#define PS_MAX_TURN_RATE_DECREMENT 0.015625 // Degrees per tick (2 degrees per second)
-#define PS_SPEED_MAX 26.54321 // Units
-#define PS_SPEED_INCREMENT 0.35 // Units per tick
-#define PS_SPEED_DECREMENT_MIDAIR 0.2824 // Units per tick (lose PS_SPEED_MAX in 0 offset jump i.e. 94 ticks)
-#define PS_GRACE_TICKS 3 // No. of ticks allowed to fail prestrafe checks when prestrafing - helps players with low fps
-#define DUCK_SPEED_NORMAL 8.0
-#define DUCK_SPEED_MINIMUM 6.0234375 // Equal to if you just ducked/unducked for the first time in a while
-
-float gF_ModeCVarValues[MODECVAR_COUNT] =
-{
- 6.5, // sv_accelerate
- 0.0, // sv_accelerate_use_weapon_speed
- 100.0, // sv_airaccelerate
- 30.0, // sv_air_max_wishspeed
- 1.0, // sv_enablebunnyhopping
- 5.2, // sv_friction
- 800.0, // sv_gravity
- 301.993377, // sv_jump_impulse
- 1.0, // sv_ladder_scale_speed
- 0.0, // sv_ledge_mantle_helper
- 320.0, // sv_maxspeed
- 3500.0, // sv_maxvelocity
- 0.0, // sv_staminajumpcost
- 0.0, // sv_staminalandcost
- 0.0, // sv_staminamax
- 0.0, // sv_staminarecoveryrate
- 0.7, // sv_standable_normal
- 0.0, // sv_timebetweenducks
- 0.7, // sv_walkable_normal
- 10.0, // sv_wateraccelerate
- 0.8, // sv_water_movespeed_multiplier
- 0.0, // sv_water_swim_mode
- 0.0, // sv_weapon_encumbrance_per_item
- 0.0 // sv_weapon_encumbrance_scale
-};
-
-bool gB_GOKZCore;
-ConVar gCV_ModeCVar[MODECVAR_COUNT];
-bool gB_HitTweakedPerf[MAXPLAYERS + 1];
-int gI_Cmdnum[MAXPLAYERS + 1];
-float gF_PSBonusSpeed[MAXPLAYERS + 1];
-float gF_PSVelMod[MAXPLAYERS + 1];
-float gF_PSVelModLanding[MAXPLAYERS + 1];
-bool gB_PSTurningLeft[MAXPLAYERS + 1];
-float gF_PSTurnRate[MAXPLAYERS + 1];
-int gI_PSTicksSinceIncrement[MAXPLAYERS + 1];
-Handle gH_GetPlayerMaxSpeed;
-DynamicDetour gH_CanUnduck;
-int gI_TickCount[MAXPLAYERS + 1];
-DynamicDetour gH_AirAccelerate;
-int gI_OldButtons[MAXPLAYERS + 1];
-int gI_OldFlags[MAXPLAYERS + 1];
-bool gB_OldOnGround[MAXPLAYERS + 1];
-float gF_OldOrigin[MAXPLAYERS + 1][3];
-float gF_OldAngles[MAXPLAYERS + 1][3];
-float gF_OldVelocity[MAXPLAYERS + 1][3];
-int gI_LastJumpButtonCmdnum[MAXPLAYERS + 1];
-int gI_OffsetCGameMovement_player;
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public void OnPluginStart()
-{
- if (FloatAbs(1.0 / GetTickInterval() - 128.0) > EPSILON)
- {
- SetFailState("gokz-mode-simplekz only supports 128 tickrate servers.");
- }
- HookEvents();
- CreateConVars();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
- if (LibraryExists("gokz-core"))
- {
- gB_GOKZCore = true;
- GOKZ_SetModeLoaded(Mode_SimpleKZ, true, MODE_VERSION);
- }
-
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsClientInGame(client))
- {
- OnClientPutInServer(client);
- }
- }
-}
-
-public void OnPluginEnd()
-{
- if (gB_GOKZCore)
- {
- GOKZ_SetModeLoaded(Mode_SimpleKZ, false);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
- else if (StrEqual(name, "gokz-core"))
- {
- gB_GOKZCore = true;
- GOKZ_SetModeLoaded(Mode_SimpleKZ, true, MODE_VERSION);
- }
-}
-
-public void OnLibraryRemoved(const char[] name)
-{
- gB_GOKZCore = gB_GOKZCore && !StrEqual(name, "gokz-core");
-}
-
-
-
-// =====[ CLIENT EVENTS ]=====
-
-public void OnClientPutInServer(int client)
-{
- ResetClient(client);
- if (IsValidClient(client))
- {
- HookClientEvents(client);
- }
- if (IsUsingMode(client))
- {
- ReplicateConVars(client);
- }
-}
-
-public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
-{
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return Plugin_Continue;
- }
-
- KZPlayer player = KZPlayer(client);
- RemoveCrouchJumpBind(player, buttons);
- ReduceDuckSlowdown(player);
- CalcPrestrafeVelMod(player, angles);
- FixWaterBoost(player, buttons);
- FixDisplacementStuck(player);
-
- gB_HitTweakedPerf[player.ID] = false;
- gI_Cmdnum[player.ID] = cmdnum;
- gI_OldButtons[player.ID] = buttons;
- gI_OldFlags[player.ID] = GetEntityFlags(player.ID);
- gB_OldOnGround[player.ID] = player.OnGround;
- gI_TickCount[player.ID] = tickcount;
- player.GetOrigin(gF_OldOrigin[player.ID]);
- player.GetEyeAngles(gF_OldAngles[player.ID]);
- player.GetVelocity(gF_OldVelocity[player.ID]);
-
- return Plugin_Continue;
-}
-
-public MRESReturn DHooks_OnGetPlayerMaxSpeed(int client, Handle hReturn)
-{
- if (!IsUsingMode(client))
- {
- return MRES_Ignored;
- }
- DHookSetReturn(hReturn, SPEED_NORMAL * gF_PSVelMod[client]);
- return MRES_Supercede;
-}
-
-public MRESReturn DHooks_OnAirAccelerate_Pre(Address pThis, DHookParam hParams)
-{
- int client = GOKZGetClientFromGameMovementAddress(pThis, gI_OffsetCGameMovement_player);
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return MRES_Ignored;
- }
-
- // NOTE: Prestrafing changes GetPlayerMaxSpeed, which changes
- // air acceleration, so remove gF_PreVelMod[client] from wishspeed/maxspeed.
- // This also applies to when the player is ducked: their wishspeed is
- // 85 and with prestrafing can be ~93.
- float wishspeed = DHookGetParam(hParams, 2);
- if (gF_PSVelMod[client] > 1.0)
- {
- DHookSetParam(hParams, 2, wishspeed / gF_PSVelMod[client]);
- return MRES_ChangedHandled;
- }
-
- return MRES_Ignored;
-}
-
-public MRESReturn DHooks_OnCanUnduck_Pre(Address pThis, DHookReturn hReturn)
-{
- int client = GOKZGetClientFromGameMovementAddress(pThis, gI_OffsetCGameMovement_player);
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return MRES_Ignored;
- }
- // Just landed fully ducked, you can't unduck.
- if (Movement_GetLandingTick(client) == (gI_TickCount[client] - 1) && GetEntPropFloat(client, Prop_Send, "m_flDuckAmount") >= 1.0 && GetEntProp(client, Prop_Send, "m_bDucked"))
- {
- hReturn.Value = false;
- return MRES_Supercede;
- }
- return MRES_Ignored;
-}
-
-public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2])
-{
- if (!IsValidClient(client) || !IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return;
- }
-
- if (buttons & IN_JUMP)
- {
- gI_LastJumpButtonCmdnum[client] = cmdnum;
- }
-}
-
-public void SDKHook_OnClientPreThink_Post(int client)
-{
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return;
- }
-
- // Don't tweak convars if GOKZ isn't running
- if (gB_GOKZCore)
- {
- TweakConVars();
- }
-}
-
-public void Movement_OnStartTouchGround(int client)
-{
- if (!IsUsingMode(client))
- {
- return;
- }
-
- KZPlayer player = KZPlayer(client);
- gF_PSVelModLanding[player.ID] = gF_PSVelMod[player.ID];
-}
-
-public Action Movement_OnJumpPre(int client, float origin[3], float velocity[3])
-{
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return Plugin_Continue;
- }
-
- KZPlayer player = KZPlayer(client);
- return TweakJump(player, origin, velocity);
-}
-
-public Action Movement_OnCategorizePositionPost(int client, float origin[3], float velocity[3])
-{
- if (!IsPlayerAlive(client) || !IsUsingMode(client))
- {
- return Plugin_Continue;
- }
- return SlopeFix(client, origin, velocity);
-}
-
-public void Movement_OnChangeMovetype(int client, MoveType oldMovetype, MoveType newMovetype)
-{
- if (!IsUsingMode(client))
- {
- return;
- }
-
- KZPlayer player = KZPlayer(client);
- if (gB_GOKZCore && newMovetype == MOVETYPE_WALK)
- {
- player.GOKZHitPerf = false;
- player.GOKZTakeoffSpeed = player.TakeoffSpeed;
- }
-}
-
-public void GOKZ_OnOptionChanged(int client, const char[] option, any newValue)
-{
- if (StrEqual(option, gC_CoreOptionNames[Option_Mode]) && newValue == Mode_SimpleKZ)
- {
- ReplicateConVars(client);
- }
-}
-
-public void GOKZ_OnCountedTeleport_Post(int client)
-{
- ResetClient(client);
-}
-
-
-
-// =====[ GENERAL ]=====
-
-bool IsUsingMode(int client)
-{
- // If GOKZ core isn't loaded, then apply mode at all times
- return !gB_GOKZCore || GOKZ_GetCoreOption(client, Option_Mode) == Mode_SimpleKZ;
-}
-
-void ResetClient(int client)
-{
- KZPlayer player = KZPlayer(client);
- ResetVelMod(player);
-}
-
-void HookEvents()
-{
- GameData gameData = LoadGameConfigFile("movementapi.games");
- if (gameData == INVALID_HANDLE)
- {
- SetFailState("Failed to find movementapi.games config");
- }
-
- int offset = gameData.GetOffset("GetPlayerMaxSpeed");
- if (offset == -1)
- {
- SetFailState("Failed to get GetPlayerMaxSpeed offset");
- }
- gH_GetPlayerMaxSpeed = DHookCreate(offset, HookType_Entity, ReturnType_Float, ThisPointer_CBaseEntity, DHooks_OnGetPlayerMaxSpeed);
-
- gH_AirAccelerate = DynamicDetour.FromConf(gameData, "CGameMovement::AirAccelerate");
- if (gH_AirAccelerate == INVALID_HANDLE)
- {
- SetFailState("Failed to find CGameMovement::AirAccelerate function signature");
- }
-
- if (!gH_AirAccelerate.Enable(Hook_Pre, DHooks_OnAirAccelerate_Pre))
- {
- SetFailState("Failed to enable detour on CGameMovement::AirAccelerate");
- }
-
- char buffer[16];
- if (!gameData.GetKeyValue("CGameMovement::player", buffer, sizeof(buffer)))
- {
- SetFailState("Failed to get CGameMovement::player offset.");
- }
- gI_OffsetCGameMovement_player = StringToInt(buffer);
-
- gameData = LoadGameConfigFile("gokz-core.games");
- gH_CanUnduck = DynamicDetour.FromConf(gameData, "CCSGameMovement::CanUnduck");
- if (gH_CanUnduck == INVALID_HANDLE)
- {
- SetFailState("Failed to find CCSGameMovement::CanUnduck function signature");
- }
-
- if (!gH_CanUnduck.Enable(Hook_Pre, DHooks_OnCanUnduck_Pre))
- {
- SetFailState("Failed to enable detour on CCSGameMovement::CanUnduck");
- }
- delete gameData;
-}
-
-// =====[ CONVARS ]=====
-
-void CreateConVars()
-{
- for (int i = 0; i < MODECVAR_COUNT; i++)
- {
- gCV_ModeCVar[i] = FindConVar(gC_ModeCVars[i]);
- }
-}
-
-void TweakConVars()
-{
- for (int i = 0; i < MODECVAR_COUNT; i++)
- {
- gCV_ModeCVar[i].FloatValue = gF_ModeCVarValues[i];
- }
-}
-
-void ReplicateConVars(int client)
-{
- /*
- Replicate convars only when player changes mode in GOKZ
- so that lagg isn't caused by other players using other
- modes, and also as an optimisation.
- */
-
- if (IsFakeClient(client))
- {
- return;
- }
-
- for (int i = 0; i < MODECVAR_COUNT; i++)
- {
- gCV_ModeCVar[i].ReplicateToClient(client, FloatToStringEx(gF_ModeCVarValues[i]));
- }
-}
-
-
-
-// =====[ VELOCITY MODIFIER ]=====
-
-void HookClientEvents(int client)
-{
- DHookEntity(gH_GetPlayerMaxSpeed, true, client);
- SDKHook(client, SDKHook_PreThinkPost, SDKHook_OnClientPreThink_Post);
-}
-
-void ResetVelMod(KZPlayer player)
-{
- gF_PSBonusSpeed[player.ID] = 0.0;
- gF_PSVelMod[player.ID] = 1.0;
- gF_PSTurnRate[player.ID] = 0.0;
-}
-
-void CalcPrestrafeVelMod(KZPlayer player, const float angles[3])
-{
- gI_PSTicksSinceIncrement[player.ID]++;
-
- // Short circuit if speed is 0 (also avoids divide by 0 errors)
- if (player.Speed < EPSILON)
- {
- ResetVelMod(player);
- return;
- }
-
- // Current speed without bonus
- float baseSpeed = FloatMin(SPEED_NORMAL, player.Speed / gF_PSVelMod[player.ID]);
-
- float newBonusSpeed = gF_PSBonusSpeed[player.ID];
-
- // If player is in mid air, decrement their velocity modifier
- if (!player.OnGround)
- {
- newBonusSpeed -= PS_SPEED_DECREMENT_MIDAIR;
- }
- // If player is turning at the required speed, and has the correct button inputs, reward it
- else if (player.Turning && ValidPrestrafeButtons(player))
- {
- // If player changes their prestrafe direction, reset it
- if (player.TurningLeft && !gB_PSTurningLeft[player.ID]
- || player.TurningRight && gB_PSTurningLeft[player.ID])
- {
- ResetVelMod(player);
- newBonusSpeed = 0.0;
- }
-
- // Keep track of the direction of the turn
- gB_PSTurningLeft[player.ID] = player.TurningLeft;
-
- // Step one of calculating new turn rate
- float newTurningRate = FloatAbs(CalcDeltaAngle(gF_OldAngles[player.ID][1], angles[1]));
-
- // If no turning for just a few ticks, then forgive and calculate reward based on that no. of ticks
- if (gI_PSTicksSinceIncrement[player.ID] <= PS_GRACE_TICKS)
- {
- // This turn occurred over multiple ticks, so scale appropriately
- // Also cap turn rate at maximum reward turn rate
- newTurningRate = FloatMin(PS_MAX_REWARD_TURN_RATE,
- newTurningRate / gI_PSTicksSinceIncrement[player.ID]);
-
- // Limit how fast turn rate can decrease (also scaled appropriately)
- gF_PSTurnRate[player.ID] = FloatMax(newTurningRate,
- gF_PSTurnRate[player.ID] - PS_MAX_TURN_RATE_DECREMENT * gI_PSTicksSinceIncrement[player.ID]);
-
- newBonusSpeed += CalcPreRewardSpeed(gF_PSTurnRate[player.ID], baseSpeed) * gI_PSTicksSinceIncrement[player.ID];
- }
- else
- {
- // Cap turn rate at maximum reward turn rate
- newTurningRate = FloatMin(PS_MAX_REWARD_TURN_RATE, newTurningRate);
-
- // Limit how fast turn rate can decrease
- gF_PSTurnRate[player.ID] = FloatMax(newTurningRate,
- gF_PSTurnRate[player.ID] - PS_MAX_TURN_RATE_DECREMENT);
-
- // This is normal turning behaviour
- newBonusSpeed += CalcPreRewardSpeed(gF_PSTurnRate[player.ID], baseSpeed);
- }
-
- gI_PSTicksSinceIncrement[player.ID] = 0;
- }
- else if (gI_PSTicksSinceIncrement[player.ID] > PS_GRACE_TICKS)
- {
- // They definitely aren't turning, but limit how fast turn rate can decrease
- gF_PSTurnRate[player.ID] = FloatMax(0.0,
- gF_PSTurnRate[player.ID] - PS_MAX_TURN_RATE_DECREMENT);
- }
-
- if (newBonusSpeed < 0.0)
- {
- // Keep velocity modifier positive
- newBonusSpeed = 0.0;
- }
- else
- {
- // Scale the bonus speed based on current base speed and turn rate
- float baseSpeedScaleFactor = baseSpeed / SPEED_NORMAL; // Max 1.0
- float turnRateScaleFactor = FloatMin(1.0, gF_PSTurnRate[player.ID] / PS_MAX_REWARD_TURN_RATE);
- float scaledMaxBonusSpeed = PS_SPEED_MAX * baseSpeedScaleFactor * turnRateScaleFactor;
- newBonusSpeed = FloatMin(newBonusSpeed, scaledMaxBonusSpeed);
- }
-
- gF_PSBonusSpeed[player.ID] = newBonusSpeed;
- gF_PSVelMod[player.ID] = 1.0 + (newBonusSpeed / baseSpeed);
-}
-
-bool ValidPrestrafeButtons(KZPlayer player)
-{
- bool forwardOrBack = player.Buttons & (IN_FORWARD | IN_BACK) && !(player.Buttons & IN_FORWARD && player.Buttons & IN_BACK);
- bool leftOrRight = player.Buttons & (IN_MOVELEFT | IN_MOVERIGHT) && !(player.Buttons & IN_MOVELEFT && player.Buttons & IN_MOVERIGHT);
- return forwardOrBack || leftOrRight;
-}
-
-float CalcPreRewardSpeed(float yawDiff, float baseSpeed)
-{
- // Formula
- float reward;
- if (yawDiff >= PS_MAX_REWARD_TURN_RATE)
- {
- reward = PS_SPEED_INCREMENT;
- }
- else
- {
- reward = PS_SPEED_INCREMENT * (yawDiff / PS_MAX_REWARD_TURN_RATE);
- }
-
- return reward * baseSpeed / SPEED_NORMAL;
-}
-
-
-
-
-// =====[ JUMPING ]=====
-
-Action TweakJump(KZPlayer player, float origin[3], float velocity[3])
-{
- // TakeoffCmdnum and TakeoffSpeed is not defined here because the player technically hasn't taken off yet.
- int cmdsSinceLanding = gI_Cmdnum[player.ID] - player.LandingCmdNum;
- gB_HitTweakedPerf[player.ID] = cmdsSinceLanding <= 1
- || cmdsSinceLanding <= 3 && gI_Cmdnum[player.ID] - gI_LastJumpButtonCmdnum[player.ID] <= 3;
-
- if (gB_HitTweakedPerf[player.ID])
- {
- if (cmdsSinceLanding <= 1)
- {
- NerfRealPerf(player, origin);
- }
-
- ApplyTweakedTakeoffSpeed(player, velocity);
-
- if (cmdsSinceLanding > 1 || player.TakeoffSpeed > SPEED_NORMAL)
- {
- // Restore prestrafe lost due to briefly being on the ground
- gF_PSVelMod[player.ID] = gF_PSVelModLanding[player.ID];
- }
- return Plugin_Changed;
- }
- return Plugin_Continue;
-}
-
-public Action Movement_OnJumpPost(int client)
-{
- if (!IsUsingMode(client))
- {
- return Plugin_Continue;
- }
- KZPlayer player = KZPlayer(client);
- player.GOKZHitPerf = gB_HitTweakedPerf[player.ID];
- player.GOKZTakeoffSpeed = player.TakeoffSpeed;
- return Plugin_Continue;
-}
-
-public void Movement_OnStopTouchGround(int client)
-{
- if (!IsUsingMode(client))
- {
- return;
- }
- KZPlayer player = KZPlayer(client);
- player.GOKZHitPerf = gB_HitTweakedPerf[player.ID];
- player.GOKZTakeoffSpeed = player.TakeoffSpeed;
-}
-
-void NerfRealPerf(KZPlayer player, float origin[3])
-{
- // Not worth worrying about if player is already falling
- // player.VerticalVelocity is not updated yet! Use processing velocity.
- float velocity[3];
- Movement_GetProcessingVelocity(player.ID, velocity);
- if (velocity[2] < EPSILON)
- {
- return;
- }
-
- // Work out where the ground was when they bunnyhopped
- float startPosition[3], endPosition[3], mins[3], maxs[3], groundOrigin[3];
-
- startPosition = origin;
-
- endPosition = startPosition;
- endPosition[2] = endPosition[2] - 2.0; // Should be less than 2.0 units away
-
- GetEntPropVector(player.ID, Prop_Send, "m_vecMins", mins);
- GetEntPropVector(player.ID, Prop_Send, "m_vecMaxs", maxs);
-
- Handle trace = TR_TraceHullFilterEx(
- startPosition,
- endPosition,
- mins,
- maxs,
- MASK_PLAYERSOLID,
- TraceEntityFilterPlayers,
- player.ID);
-
- // This is expected to always hit, previously this can fail upon jumpbugs.
- if (TR_DidHit(trace))
- {
- TR_GetEndPosition(groundOrigin, trace);
- origin[2] = groundOrigin[2];
- }
-
- delete trace;
-}
-
-void ApplyTweakedTakeoffSpeed(KZPlayer player, float velocity[3])
-{
- // Note that resulting velocity has same direction as landing velocity, not current velocity
- // because current velocity direction can change drastically in just one tick (eg. walls)
- // and it doesnt make sense for the new velocity to push you in that direction.
-
- float newVelocity[3], baseVelocity[3];
- player.GetLandingVelocity(newVelocity);
- player.GetBaseVelocity(baseVelocity);
- SetVectorHorizontalLength(newVelocity, CalcTweakedTakeoffSpeed(player));
- AddVectors(newVelocity, baseVelocity, newVelocity); // For backwards compatibility
- velocity[0] = newVelocity[0];
- velocity[1] = newVelocity[1];
-}
-
-// Takeoff speed assuming player has met the conditions to need tweaking
-float CalcTweakedTakeoffSpeed(KZPlayer player)
-{
- // Formula
- if (player.LandingSpeed > SPEED_NORMAL)
- {
- return FloatMin(player.LandingSpeed, (0.2 * player.LandingSpeed + 200) * gF_PSVelModLanding[player.ID]);
- }
- return player.LandingSpeed;
-}
-
-
-
-// =====[ SLOPEFIX ]=====
-
-// ORIGINAL AUTHORS : Mev & Blacky
-// URL : https://forums.alliedmods.net/showthread.php?p=2322788
-// NOTE : Modified by DanZay for this plugin
-
-Action SlopeFix(int client, float origin[3], float velocity[3])
-{
- KZPlayer player = KZPlayer(client);
- // Check if player landed on the ground
- if (Movement_GetOnGround(client) && !gB_OldOnGround[client])
- {
- float vMins[] = {-16.0, -16.0, 0.0};
- // Always use ducked hull as the real hull size isn't updated yet.
- // Might cause slight issues in extremely rare scenarios.
- float vMaxs[] = {16.0, 16.0, 54.0};
-
- float vEndPos[3];
- vEndPos[0] = origin[0];
- vEndPos[1] = origin[1];
- vEndPos[2] = origin[2] - gF_ModeCVarValues[ModeCVar_MaxVelocity];
-
- // Set up and do tracehull to find out if the player landed on a slope
- TR_TraceHullFilter(origin, vEndPos, vMins, vMaxs, MASK_PLAYERSOLID_BRUSHONLY, TraceRayDontHitSelf, client);
-
- if (TR_DidHit())
- {
- // Gets the normal vector of the surface under the player
- float vPlane[3], vLast[3];
- player.GetLandingVelocity(vLast);
- TR_GetPlaneNormal(null, vPlane);
-
- // Make sure it's not flat ground and not a surf ramp (1.0 = flat ground, < 0.7 = surf ramp)
- if (0.7 <= vPlane[2] < 1.0)
- {
- /*
- Copy the ClipVelocity function from sdk2013
- (https://mxr.alliedmods.net/hl2sdk-sdk2013/source/game/shared/gamemovement.cpp#3145)
- With some minor changes to make it actually work
- */
-
- float fBackOff = GetVectorDotProduct(vLast, vPlane);
-
- float change, vVel[3];
- for (int i; i < 2; i++)
- {
- change = vPlane[i] * fBackOff;
- vVel[i] = vLast[i] - change;
- }
-
- float fAdjust = GetVectorDotProduct(vVel, vPlane);
- if (fAdjust < 0.0)
- {
- for (int i; i < 2; i++)
- {
- vVel[i] -= (vPlane[i] * fAdjust);
- }
- }
-
- vVel[2] = 0.0;
- vLast[2] = 0.0;
-
- // Make sure the player is going down a ramp by checking if they actually will gain speed from the boost
- if (GetVectorLength(vVel) > GetVectorLength(vLast))
- {
- CopyVector(vVel, velocity);
- player.SetLandingVelocity(velocity);
- return Plugin_Changed;
- }
- }
- }
- }
- return Plugin_Continue;
-}
-
-public bool TraceRayDontHitSelf(int entity, int mask, any data)
-{
- return entity != data && !(0 < entity <= MaxClients);
-}
-
-
-
-// =====[ OTHER ]=====
-
-void FixWaterBoost(KZPlayer player, int buttons)
-{
- if (GetEntProp(player.ID, Prop_Send, "m_nWaterLevel") >= 2) // WL_Waist = 2
- {
- // If duck is being pressed and we're not already ducking or on ground
- if (GetEntityFlags(player.ID) & (FL_DUCKING | FL_ONGROUND) == 0
- && buttons & IN_DUCK && ~gI_OldButtons[player.ID] & IN_DUCK)
- {
- float newOrigin[3];
- Movement_GetOrigin(player.ID, newOrigin);
- newOrigin[2] += 9.0;
-
- TR_TraceHullFilter(newOrigin, newOrigin, view_as<float>( { -16.0, -16.0, 0.0 } ), view_as<float>( { 16.0, 16.0, 54.0 } ), MASK_PLAYERSOLID, TraceEntityFilterPlayers);
- if (!TR_DidHit())
- {
- TeleportEntity(player.ID, newOrigin, NULL_VECTOR, NULL_VECTOR);
- }
- }
- }
-}
-
-void FixDisplacementStuck(KZPlayer player)
-{
- int flags = GetEntityFlags(player.ID);
- bool unducked = ~flags & FL_DUCKING && gI_OldFlags[player.ID] & FL_DUCKING;
-
- float standingMins[] = {-16.0, -16.0, 0.0};
- float standingMaxs[] = {16.0, 16.0, 72.0};
-
- if (unducked)
- {
- // check if we're stuck after unducking and if we're stuck then force duck
- float origin[3];
- Movement_GetOrigin(player.ID, origin);
- TR_TraceHullFilter(origin, origin, standingMins, standingMaxs, MASK_PLAYERSOLID, TraceEntityFilterPlayers);
-
- if (TR_DidHit())
- {
- player.SetVelocity(gF_OldVelocity[player.ID]);
- SetEntProp(player.ID, Prop_Send, "m_bDucking", true);
- }
- }
-}
-
-void RemoveCrouchJumpBind(KZPlayer player, int &buttons)
-{
- if (player.OnGround && buttons & IN_JUMP && !(gI_OldButtons[player.ID] & IN_JUMP) && !(gI_OldButtons[player.ID] & IN_DUCK))
- {
- buttons &= ~IN_DUCK;
- }
-}
-
-void ReduceDuckSlowdown(KZPlayer player)
-{
- /*
- Duck speed is reduced by the game upon ducking or unducking.
- The goal here is to accept that duck speed is reduced, but
- stop it from being reduced further when spamming duck.
-
- This is done by enforcing a minimum duck speed equivalent to
- the value as if the player only ducked once. When not in not
- in the middle of ducking, duck speed is reset to its normal
- value in effort to reduce the number of times the minimum
- duck speed is enforced. This should reduce noticeable lagg.
- */
-
- if (!GetEntProp(player.ID, Prop_Send, "m_bDucking")
- && player.DuckSpeed < DUCK_SPEED_NORMAL - EPSILON)
- {
- player.DuckSpeed = DUCK_SPEED_NORMAL;
- }
- else if (player.DuckSpeed < DUCK_SPEED_MINIMUM - EPSILON)
- {
- player.DuckSpeed = DUCK_SPEED_MINIMUM;
- }
-}
diff --git a/source/sourcemod/scripting/gokz-paint.sp b/source/sourcemod/scripting/gokz-paint.sp
deleted file mode 100644
index 3de93a7..0000000
--- a/source/sourcemod/scripting/gokz-paint.sp
+++ /dev/null
@@ -1,410 +0,0 @@
-#include <sourcemod>
-
-#include <gokz/core>
-#include <gokz/paint>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <updater>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-// Credit to SlidyBat for a large part of the painting code (https://forums.alliedmods.net/showthread.php?p=2541664)
-// Credit to Cabbage McGravel of the MomentumMod team for making the textures
-
-public Plugin myinfo =
-{
- name = "GOKZ Paint",
- author = "zealain",
- description = "Provides client sided paint for visibility",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-paint.txt"
-
-char gC_PaintColors[][32] =
-{
- "paint_red",
- "paint_white",
- "paint_black",
- "paint_blue",
- "paint_brown",
- "paint_green",
- "paint_yellow",
- "paint_purple"
-};
-
-char gC_PaintSizePostfix[][8] =
-{
- "_small",
- "_med",
- "_large"
-};
-
-int gI_Decals[sizeof(gC_PaintColors)][sizeof(gC_PaintSizePostfix)];
-float gF_LastPaintPos[MAXPLAYERS + 1][3];
-bool gB_IsPainting[MAXPLAYERS + 1];
-
-TopMenu gTM_Options;
-TopMenuObject gTMO_CatPaint;
-TopMenuObject gTMO_ItemsPaint[PAINTOPTION_COUNT];
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- RegPluginLibrary("gokz-paint");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- LoadTranslations("gokz-paint.phrases");
-
- RegisterCommands();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-
- TopMenu topMenu;
- if (LibraryExists("gokz-core") && ((topMenu = GOKZ_GetOptionsTopMenu()) != null))
- {
- GOKZ_OnOptionsMenuReady(topMenu);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-
-
-// =====[ EVENTS ]=====
-
-public void GOKZ_OnOptionsMenuCreated(TopMenu topMenu)
-{
- OnOptionsMenuCreated_OptionsMenu(topMenu);
-}
-
-public void GOKZ_OnOptionsMenuReady(TopMenu topMenu)
-{
- OnOptionsMenuReady_Options();
- OnOptionsMenuReady_OptionsMenu(topMenu);
-}
-
-public void OnMapStart()
-{
- char buffer[PLATFORM_MAX_PATH];
-
- AddFileToDownloadsTable("materials/gokz/paint/paint_decal.vtf");
- for (int color = 0; color < sizeof(gC_PaintColors); color++)
- {
- for (int size = 0; size < sizeof(gC_PaintSizePostfix); size++)
- {
- Format(buffer, sizeof(buffer), "gokz/paint/%s%s.vmt", gC_PaintColors[color], gC_PaintSizePostfix[size]);
- gI_Decals[color][size] = PrecachePaint(buffer);
- }
- }
-
- CreateTimer(0.1, Timer_Paint, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
-}
-
-
-
-// =====[ PAINT ]=====
-
-void Paint(int client)
-{
- if (!IsValidClient(client) ||
- IsFakeClient(client))
- {
- return;
- }
-
- float position[3];
- bool hit = GetPlayerEyeViewPoint(client, position);
-
- if (!hit || GetVectorDistance(position, gF_LastPaintPos[client], true) < MIN_PAINT_SPACING)
- {
- return;
- }
-
- int paint = GOKZ_GetOption(client, gC_PaintOptionNames[PaintOption_Color]);
- int size = GOKZ_GetOption(client, gC_PaintOptionNames[PaintOption_Size]);
-
- TE_SetupWorldDecal(position, gI_Decals[paint][size]);
- TE_SendToClient(client);
-
- gF_LastPaintPos[client] = position;
-}
-
-public Action Timer_Paint(Handle timer)
-{
- for (int client = 1; client <= MAXPLAYERS; client++)
- {
- if (gB_IsPainting[client])
- {
- Paint(client);
- }
- }
- return Plugin_Continue;
-}
-
-void TE_SetupWorldDecal(const float origin[3], int index)
-{
- TE_Start("World Decal");
- TE_WriteVector("m_vecOrigin", origin);
- TE_WriteNum("m_nIndex", index);
-}
-
-int PrecachePaint(char[] filename)
-{
- char path[PLATFORM_MAX_PATH];
- Format(path, sizeof(path), "materials/%s", filename);
- AddFileToDownloadsTable(path);
-
- return PrecacheDecal(filename, true);
-}
-
-bool GetPlayerEyeViewPoint(int client, float position[3])
-{
- float angles[3];
- GetClientEyeAngles(client, angles);
-
- float origin[3];
- GetClientEyePosition(client, origin);
-
- Handle trace = TR_TraceRayFilterEx(origin, angles, MASK_PLAYERSOLID, RayType_Infinite, TraceEntityFilterPlayers);
- if (TR_DidHit(trace))
- {
- TR_GetEndPosition(position, trace);
- delete trace;
- return true;
- }
- delete trace;
- return false;
-}
-
-
-
-// =====[ OPTIONS ]=====
-
-void OnOptionsMenuReady_Options()
-{
- RegisterOptions();
-}
-
-void RegisterOptions()
-{
- for (PaintOption option; option < PAINTOPTION_COUNT; option++)
- {
- GOKZ_RegisterOption(gC_PaintOptionNames[option], gC_PaintOptionDescriptions[option],
- OptionType_Int, gI_PaintOptionDefaults[option], 0, gI_PaintOptionCounts[option] - 1);
- }
-}
-
-
-
-// =====[ OPTIONS MENU ]=====
-
-void OnOptionsMenuCreated_OptionsMenu(TopMenu topMenu)
-{
- if (gTM_Options == topMenu && gTMO_CatPaint != INVALID_TOPMENUOBJECT)
- {
- return;
- }
-
- gTMO_CatPaint = topMenu.AddCategory(PAINT_OPTION_CATEGORY, TopMenuHandler_Categories);
-}
-
-void OnOptionsMenuReady_OptionsMenu(TopMenu topMenu)
-{
- // Make sure category exists
- if (gTMO_CatPaint == INVALID_TOPMENUOBJECT)
- {
- GOKZ_OnOptionsMenuCreated(topMenu);
- }
-
- if (gTM_Options == topMenu)
- {
- return;
- }
-
- gTM_Options = topMenu;
-
- // Add gokz-paint option items
- for (int option = 0; option < view_as<int>(PAINTOPTION_COUNT); option++)
- {
- gTMO_ItemsPaint[option] = gTM_Options.AddItem(gC_PaintOptionNames[option], TopMenuHandler_Paint, gTMO_CatPaint);
- }
-}
-
-void DisplayPaintOptionsMenu(int client)
-{
- gTM_Options.DisplayCategory(gTMO_CatPaint, client);
-}
-
-public void TopMenuHandler_Categories(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength)
-{
- if (action == TopMenuAction_DisplayOption || action == TopMenuAction_DisplayTitle)
- {
- if (topobj_id == gTMO_CatPaint)
- {
- Format(buffer, maxlength, "%T", "Options Menu - Paint", param);
- }
- }
-}
-
-public void TopMenuHandler_Paint(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength)
-{
- PaintOption option = PAINTOPTION_INVALID;
- for (int i = 0; i < view_as<int>(PAINTOPTION_COUNT); i++)
- {
- if (topobj_id == gTMO_ItemsPaint[i])
- {
- option = view_as<PaintOption>(i);
- break;
- }
- }
-
- if (option == PAINTOPTION_INVALID)
- {
- return;
- }
-
- if (action == TopMenuAction_DisplayOption)
- {
- switch (option)
- {
- case PaintOption_Color:
- {
- FormatEx(buffer, maxlength, "%T - %T",
- gC_PaintOptionPhrases[option], param,
- gC_PaintColorPhrases[GOKZ_GetOption(param, gC_PaintOptionNames[option])], param);
- }
- case PaintOption_Size:
- {
- FormatEx(buffer, maxlength, "%T - %T",
- gC_PaintOptionPhrases[option], param,
- gC_PaintSizePhrases[GOKZ_GetOption(param, gC_PaintOptionNames[option])], param);
- }
- }
- }
- else if (action == TopMenuAction_SelectOption)
- {
- if (option == PaintOption_Color)
- {
- DisplayColorMenu(param);
- }
- else
- {
- GOKZ_CycleOption(param, gC_PaintOptionNames[option]);
- gTM_Options.Display(param, TopMenuPosition_LastCategory);
- }
- }
-}
-
-void DisplayColorMenu(int client)
-{
- char buffer[32];
-
- Menu menu = new Menu(MenuHandler_PaintColor);
- menu.ExitButton = true;
- menu.ExitBackButton = true;
- menu.SetTitle("%T", "Paint Color Menu - Title", client);
-
- for (int i = 0; i < PAINTCOLOR_COUNT; i++)
- {
- FormatEx(buffer, sizeof(buffer), "%T", gC_PaintColorPhrases[i], client);
- menu.AddItem(gC_PaintColors[i], buffer);
- }
-
- menu.Display(client, MENU_TIME_FOREVER);
-}
-
-int MenuHandler_PaintColor(Menu menu, MenuAction action, int param1, int param2)
-{
- switch (action)
- {
- case MenuAction_Select:
- {
- char item[32];
- menu.GetItem(param2, item, sizeof(item));
-
- for (int i = 0; i < PAINTCOLOR_COUNT; i++)
- {
- if (StrEqual(gC_PaintColors[i], item))
- {
- GOKZ_SetOption(param1, gC_PaintOptionNames[PaintOption_Color], i);
- DisplayPaintOptionsMenu(param1);
- return 0;
- }
- }
- }
-
- case MenuAction_Cancel:
- {
- if (param2 == MenuCancel_ExitBack)
- {
- DisplayPaintOptionsMenu(param1);
- }
- }
-
- case MenuAction_End:
- {
- delete menu;
- }
- }
-
- return 0;
-}
-
-
-
-// =====[ COMMANDS ]=====
-
-void RegisterCommands()
-{
- RegConsoleCmd("+paint", CommandPaintStart, "[KZ] Start painting.");
- RegConsoleCmd("-paint", CommandPaintEnd, "[KZ] Stop painting.");
- RegConsoleCmd("sm_paint", CommandPaint, "[KZ] Place a paint.");
- RegConsoleCmd("sm_paintoptions", CommandPaintOptions, "[KZ] Open the paint options.");
-}
-
-public Action CommandPaintStart(int client, int args)
-{
- gB_IsPainting[client] = true;
- return Plugin_Handled;
-}
-
-public Action CommandPaintEnd(int client, int args)
-{
- gB_IsPainting[client] = false;
- return Plugin_Handled;
-}
-
-public Action CommandPaint(int client, int args)
-{
- Paint(client);
- return Plugin_Handled;
-}
-
-public Action CommandPaintOptions(int client, int args)
-{
- DisplayPaintOptionsMenu(client);
- return Plugin_Handled;
-}
diff --git a/source/sourcemod/scripting/gokz-pistol.sp b/source/sourcemod/scripting/gokz-pistol.sp
deleted file mode 100644
index 53f79d9..0000000
--- a/source/sourcemod/scripting/gokz-pistol.sp
+++ /dev/null
@@ -1,303 +0,0 @@
-#include <sourcemod>
-
-#include <cstrike>
-#include <sdktools>
-
-#include <gokz/core>
-#include <gokz/pistol>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <updater>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Pistol",
- author = "DanZay",
- description = "Allows players to pick a pistol to KZ with",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-pistols.txt"
-
-TopMenu gTM_Options;
-TopMenuObject gTMO_CatGeneral;
-TopMenuObject gTMO_ItemPistol;
-bool gB_CameFromOptionsMenu[MAXPLAYERS + 1];
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- RegPluginLibrary("gokz-pistol");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- LoadTranslations("gokz-common.phrases");
- LoadTranslations("gokz-pistol.phrases");
-
- HookEvents();
- RegisterCommands();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-
- TopMenu topMenu;
- if (LibraryExists("gokz-core") && ((topMenu = GOKZ_GetOptionsTopMenu()) != null))
- {
- GOKZ_OnOptionsMenuReady(topMenu);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-
-
-// =====[ CLIENT EVENTS ]=====
-
-public void OnPlayerSpawn(Event event, const char[] name, bool dontBroadcast) // player_spawn post hook
-{
- int client = GetClientOfUserId(event.GetInt("userid"));
- if (IsValidClient(client))
- {
- UpdatePistol(client);
- }
-}
-
-public void GOKZ_OnOptionChanged(int client, const char[] option, any newValue)
-{
- if (StrEqual(option, PISTOL_OPTION_NAME))
- {
- UpdatePistol(client);
- }
-}
-
-
-
-// =====[ OTHER EVENTS ]=====
-
-public void GOKZ_OnOptionsMenuReady(TopMenu topMenu)
-{
- OnOptionsMenuReady_Options();
- OnOptionsMenuReady_OptionsMenu(topMenu);
-}
-
-
-
-// =====[ GENERAL ]=====
-
-void HookEvents()
-{
- HookEvent("player_spawn", OnPlayerSpawn, EventHookMode_Post);
-}
-
-
-
-// =====[ PISTOL ]=====
-
-void UpdatePistol(int client)
-{
- GivePistol(client, GOKZ_GetOption(client, PISTOL_OPTION_NAME));
-}
-
-void GivePistol(int client, int pistol)
-{
- if (!IsClientInGame(client) || !IsPlayerAlive(client)
- || GetClientTeam(client) == CS_TEAM_NONE)
- {
- return;
- }
-
- int playerTeam = GetClientTeam(client);
- bool switchedTeams = false;
-
- // Switch teams to the side that buys that gun so that gun skins load
- if (gI_PistolTeams[pistol] == CS_TEAM_CT && playerTeam != CS_TEAM_CT)
- {
- CS_SwitchTeam(client, CS_TEAM_CT);
- switchedTeams = true;
- }
- else if (gI_PistolTeams[pistol] == CS_TEAM_T && playerTeam != CS_TEAM_T)
- {
- CS_SwitchTeam(client, CS_TEAM_T);
- switchedTeams = true;
- }
-
- // Give the player this pistol (or remove it)
- int currentPistol = GetPlayerWeaponSlot(client, CS_SLOT_SECONDARY);
- if (currentPistol != -1)
- {
- RemovePlayerItem(client, currentPistol);
- }
-
- if (pistol == Pistol_Disabled)
- {
- // Force switch to knife to avoid weird behaviour
- // Doesn't use EquipPlayerWeapon because server hangs when player spawns
- FakeClientCommand(client, "use weapon_knife");
- }
- else
- {
- GivePlayerItem(client, gC_PistolClassNames[pistol]);
- }
-
- // Go back to original team
- if (switchedTeams)
- {
- CS_SwitchTeam(client, playerTeam);
- }
-}
-
-
-
-// =====[ PISTOL MENU ]=====
-
-void DisplayPistolMenu(int client, int atItem = 0, bool fromOptionsMenu = false)
-{
- Menu menu = new Menu(MenuHandler_Pistol);
- menu.SetTitle("%T", "Pistol Menu - Title", client);
- PistolMenuAddItems(client, menu);
- menu.DisplayAt(client, atItem, MENU_TIME_FOREVER);
-
- gB_CameFromOptionsMenu[client] = fromOptionsMenu;
-}
-
-public int MenuHandler_Pistol(Menu menu, MenuAction action, int param1, int param2)
-{
- if (action == MenuAction_Select)
- {
- GOKZ_SetOption(param1, PISTOL_OPTION_NAME, param2);
- DisplayPistolMenu(param1, param2 / 6 * 6, gB_CameFromOptionsMenu[param1]); // Re-display menu at same spot
- }
- else if (action == MenuAction_Cancel && gB_CameFromOptionsMenu[param1])
- {
- gTM_Options.Display(param1, TopMenuPosition_LastCategory);
- }
- else if (action == MenuAction_End)
- {
- delete menu;
- }
- return 0;
-}
-
-void PistolMenuAddItems(int client, Menu menu)
-{
- int selectedPistol = GOKZ_GetOption(client, PISTOL_OPTION_NAME);
- char display[32];
-
- for (int pistol = 0; pistol < PISTOL_COUNT; pistol++)
- {
- if (pistol == Pistol_Disabled)
- {
- FormatEx(display, sizeof(display), "%T", "Options Menu - Disabled", client);
- }
- else
- {
- FormatEx(display, sizeof(display), "%s", gC_PistolNames[pistol]);
- }
-
- // Add asterisk to selected pistol
- if (pistol == selectedPistol)
- {
- Format(display, sizeof(display), "%s*", display);
- }
-
- menu.AddItem("", display, ITEMDRAW_DEFAULT);
- }
-}
-
-
-
-// =====[ OPTIONS ]=====
-
-void OnOptionsMenuReady_Options()
-{
- RegisterOption();
-}
-
-void RegisterOption()
-{
- GOKZ_RegisterOption(PISTOL_OPTION_NAME, PISTOL_OPTION_DESCRIPTION,
- OptionType_Int, Pistol_USPS, 0, PISTOL_COUNT - 1);
-}
-
-
-
-// =====[ OPTIONS MENU ]=====
-
-void OnOptionsMenuReady_OptionsMenu(TopMenu topMenu)
-{
- if (gTM_Options == topMenu)
- {
- return;
- }
-
- gTM_Options = topMenu;
- gTMO_CatGeneral = gTM_Options.FindCategory(GENERAL_OPTION_CATEGORY);
- gTMO_ItemPistol = gTM_Options.AddItem(PISTOL_OPTION_NAME, TopMenuHandler_Pistol, gTMO_CatGeneral);
-}
-
-public void TopMenuHandler_Pistol(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength)
-{
- if (topobj_id != gTMO_ItemPistol)
- {
- return;
- }
-
- if (action == TopMenuAction_DisplayOption)
- {
- int pistol = GOKZ_GetOption(param, PISTOL_OPTION_NAME);
- if (pistol == Pistol_Disabled)
- {
- FormatEx(buffer, maxlength, "%T - %T",
- "Options Menu - Pistol", param,
- "Options Menu - Disabled", param);
- }
- else
- {
- FormatEx(buffer, maxlength, "%T - %s",
- "Options Menu - Pistol", param,
- gC_PistolNames[pistol]);
- }
- }
- else if (action == TopMenuAction_SelectOption)
- {
- DisplayPistolMenu(param, _, true);
- }
-}
-
-
-
-// =====[ COMMANDS ]=====
-
-void RegisterCommands()
-{
- RegConsoleCmd("sm_pistol", CommandPistolMenu, "[KZ] Open the pistol selection menu.");
-}
-
-public Action CommandPistolMenu(int client, int args)
-{
- DisplayPistolMenu(client);
- return Plugin_Handled;
-} \ No newline at end of file
diff --git a/source/sourcemod/scripting/gokz-playermodels.sp b/source/sourcemod/scripting/gokz-playermodels.sp
deleted file mode 100644
index 237b7df..0000000
--- a/source/sourcemod/scripting/gokz-playermodels.sp
+++ /dev/null
@@ -1,198 +0,0 @@
-#include <sourcemod>
-
-#include <cstrike>
-#include <sdktools>
-
-#include <gokz/core>
-
-#include <autoexecconfig>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <updater>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Player Models",
- author = "DanZay",
- description = "Sets player's model upon spawning",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-playermodels.txt"
-#define PLAYER_MODEL_T "models/player/tm_leet_varianta.mdl"
-#define PLAYER_MODEL_CT "models/player/ctm_idf_variantc.mdl"
-#define PLAYER_MODEL_T_BOT "models/player/custom_player/legacy/tm_leet_varianta.mdl"
-#define PLAYER_MODEL_CT_BOT "models/player/custom_player/legacy/ctm_idf_variantc.mdl"
-ConVar gCV_gokz_player_models_alpha;
-ConVar gCV_sv_disable_immunity_alpha;
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- RegPluginLibrary("gokz-playermodels");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- CreateConVars();
- HookEvents();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-
-
-// =====[ CLIENT EVENTS ]=====
-
-public void OnPlayerSpawn(Event event, const char[] name, bool dontBroadcast) // player_spawn post hook
-{
- int client = GetClientOfUserId(event.GetInt("userid"));
- if (IsValidClient(client))
- {
- // Can't use a timer here because it's not precise enough. We want exactly 2 ticks of delay!
- // 2 ticks is the minimum amount of time after which gloves will work.
- // The reason we need precision is because SetEntityModel momentarily resets the
- // player hull to standing (or something along those lines), so when a player
- // spawns/gets reset to a crouch tunnel where there's a trigger less than 18 units from the top
- // of the ducked player hull, then they touch that trigger! SetEntityModel interferes with the
- // fix for that (JoinTeam in gokz-core/misc calls TeleportPlayer in gokz.inc, which fixes that bug).
- RequestFrame(RequestFrame_UpdatePlayerModel, GetClientUserId(client));
- }
-}
-
-
-
-// =====[ OTHER EVENTS ]=====
-
-public void OnMapStart()
-{
- PrecachePlayerModels();
-}
-
-
-
-// =====[ GENERAL ]=====
-
-void HookEvents()
-{
- HookEvent("player_spawn", OnPlayerSpawn, EventHookMode_Post);
-}
-
-
-
-// =====[ CONVARS ]=====
-
-void CreateConVars()
-{
- AutoExecConfig_SetFile("gokz-playermodels", "sourcemod/gokz");
- AutoExecConfig_SetCreateFile(true);
-
- gCV_gokz_player_models_alpha = AutoExecConfig_CreateConVar("gokz_player_models_alpha", "65", "Amount of alpha (transparency) to set player models to.", _, true, 0.0, true, 255.0);
- gCV_gokz_player_models_alpha.AddChangeHook(OnConVarChanged);
-
- AutoExecConfig_ExecuteFile();
- AutoExecConfig_CleanFile();
-
- gCV_sv_disable_immunity_alpha = FindConVar("sv_disable_immunity_alpha");
-}
-
-public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
-{
- if (convar == gCV_gokz_player_models_alpha)
- {
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsClientInGame(client) && IsPlayerAlive(client))
- {
- UpdatePlayerModelAlpha(client);
- }
- }
- }
-}
-
-
-
-// =====[ PLAYER MODELS ]=====
-
-public void RequestFrame_UpdatePlayerModel(int userid)
-{
- RequestFrame(RequestFrame_UpdatePlayerModel2, userid);
-}
-
-public void RequestFrame_UpdatePlayerModel2(int userid)
-{
- int client = GetClientOfUserId(userid);
- if (!IsValidClient(client) || !IsPlayerAlive(client))
- {
- return;
- }
- // Bots are unaffected by the bobbing animation caused by the new models.
- switch (GetClientTeam(client))
- {
- case CS_TEAM_T:
- {
- if (IsFakeClient(client))
- {
- SetEntityModel(client, PLAYER_MODEL_T_BOT);
- }
- else
- {
- SetEntityModel(client, PLAYER_MODEL_T);
- }
- }
- case CS_TEAM_CT:
- {
- if (IsFakeClient(client))
- {
- SetEntityModel(client, PLAYER_MODEL_CT_BOT);
- }
- else
- {
- SetEntityModel(client, PLAYER_MODEL_CT);
- }
- }
- }
-
- UpdatePlayerModelAlpha(client);
-}
-
-void UpdatePlayerModelAlpha(int client)
-{
- SetEntityRenderMode(client, RENDER_TRANSCOLOR);
- SetEntityRenderColor(client, _, _, _, gCV_gokz_player_models_alpha.IntValue);
-}
-
-void PrecachePlayerModels()
-{
- gCV_sv_disable_immunity_alpha.IntValue = 1; // Ensures player transparency works
-
- PrecacheModel(PLAYER_MODEL_T, true);
- PrecacheModel(PLAYER_MODEL_CT, true);
- PrecacheModel(PLAYER_MODEL_T_BOT, true);
- PrecacheModel(PLAYER_MODEL_CT_BOT, true);
-} \ No newline at end of file
diff --git a/source/sourcemod/scripting/gokz-profile.sp b/source/sourcemod/scripting/gokz-profile.sp
deleted file mode 100644
index 9d92e61..0000000
--- a/source/sourcemod/scripting/gokz-profile.sp
+++ /dev/null
@@ -1,396 +0,0 @@
-#include <sourcemod>
-
-#include <cstrike>
-
-#include <gokz/core>
-#include <gokz/profile>
-#include <gokz/global>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <updater>
-#include <gokz/chat>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Profile",
- author = "zealain",
- description = "Player profiles and ranks based on local and global data.",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-profile.txt"
-
-int gI_Rank[MAXPLAYERS + 1][MODE_COUNT];
-bool gB_Localranks;
-bool gB_Chat;
-
-#include "gokz-profile/options.sp"
-#include "gokz-profile/profile.sp"
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- CreateNatives();
- RegPluginLibrary("gokz-profile");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- LoadTranslations("common.phrases");
- LoadTranslations("gokz-profile.phrases");
- CreateGlobalForwards();
- RegisterCommands();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
- gB_Localranks = LibraryExists("gokz-localranks");
- gB_Chat = LibraryExists("gokz-chat");
-
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsValidClient(client) && !IsFakeClient(client))
- {
- UpdateRank(client, GOKZ_GetCoreOption(client, Option_Mode));
- }
- }
-
- TopMenu topMenu;
- if (LibraryExists("gokz-core") && ((topMenu = GOKZ_GetOptionsTopMenu()) != null))
- {
- GOKZ_OnOptionsMenuReady(topMenu);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
- gB_Localranks = gB_Localranks || StrEqual(name, "gokz-localranks");
- gB_Chat = gB_Chat || StrEqual(name, "gokz-chat");
-}
-
-public void OnLibraryRemoved(const char[] name)
-{
- gB_Localranks = gB_Localranks && !StrEqual(name, "gokz-localranks");
- gB_Chat = gB_Chat && !StrEqual(name, "gokz-chat");
-}
-
-
-
-// =====[ EVENTS ]=====
-
-public Action OnClientCommandKeyValues(int client, KeyValues kv)
-{
- // Block clan tag changes - Credit: GoD-Tony (https://forums.alliedmods.net/showpost.php?p=2337679&postcount=6)
- char cmd[16];
- if (kv.GetSectionName(cmd, sizeof(cmd)) && StrEqual(cmd, "ClanTagChanged", false))
- {
- return Plugin_Handled;
- }
- return Plugin_Continue;
-}
-
-public void OnRebuildAdminCache(AdminCachePart part)
-{
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsValidClient(client) && !IsFakeClient(client))
- {
- int mode = GOKZ_GetCoreOption(client, Option_Mode);
- UpdateRank(client, mode);
- }
- }
-}
-
-public void GOKZ_OnOptionsMenuCreated(TopMenu topMenu)
-{
- OnOptionsMenuCreated_OptionsMenu(topMenu);
-}
-
-public void GOKZ_OnOptionsMenuReady(TopMenu topMenu)
-{
- OnOptionsMenuReady_Options();
- OnOptionsMenuReady_OptionsMenu(topMenu);
-}
-
-public void GOKZ_OnOptionsLoaded(int client)
-{
- if (IsValidClient(client) && !IsFakeClient(client))
- {
- int mode = GOKZ_GetCoreOption(client, Option_Mode);
- UpdateTags(client, gI_Rank[client][mode], mode);
- }
-}
-
-public void OnClientConnected(int client)
-{
- for (int mode = 0; mode < MODE_COUNT; mode++)
- {
- gI_Rank[client][mode] = 0;
- }
- Profile_OnClientConnected(client);
-}
-
-public void OnClientDisconnect(int client)
-{
- Profile_OnClientDisconnect(client);
-}
-
-public void GOKZ_OnOptionChanged(int client, const char[] option, any newValue)
-{
- Option coreOption;
- if (GOKZ_IsCoreOption(option, coreOption) && coreOption == Option_Mode)
- {
- UpdateRank(client, newValue);
- }
- else if (StrEqual(option, gC_ProfileOptionNames[ProfileOption_ShowRankChat], true)
- || StrEqual(option, gC_ProfileOptionNames[ProfileOption_ShowRankClanTag], true)
- || StrEqual(option, gC_ProfileOptionNames[ProfileOption_TagType], true))
- {
- UpdateRank(client, GOKZ_GetCoreOption(client, Option_Mode));
- }
-}
-
-public void GOKZ_GL_OnPointsUpdated(int client, int mode)
-{
- UpdateRank(client, mode);
- Profile_OnPointsUpdated(client, mode);
-}
-
-public void UpdateRank(int client, int mode)
-{
- if (!IsValidClient(client) || IsFakeClient(client))
- {
- return;
- }
-
- int tagType = GetAvailableTagTypeOrDefault(client);
-
- if (tagType != ProfileTagType_Rank)
- {
- char clanTag[64], chatTag[32], color[64];
-
- if (tagType == ProfileTagType_Admin)
- {
- FormatEx(clanTag, sizeof(clanTag), "[%s %T]", gC_ModeNamesShort[mode], "Tag - Admin", client);
- FormatEx(chatTag, sizeof(chatTag), "%T", "Tag - Admin", client);
- color = TAG_COLOR_ADMIN;
- }
- if (tagType == ProfileTagType_VIP)
- {
- FormatEx(clanTag, sizeof(clanTag), "[%s %T]", gC_ModeNamesShort[mode], "Tag - VIP", client);
- FormatEx(chatTag, sizeof(chatTag), "%T", "Tag - VIP", client);
- color = TAG_COLOR_VIP;
- }
-
- if (GOKZ_GetOption(client, gC_ProfileOptionNames[ProfileOption_ShowRankClanTag]) != ProfileOptionBool_Enabled)
- {
- FormatEx(clanTag, sizeof(clanTag), "[%s]", gC_ModeNamesShort[mode]);
- }
- CS_SetClientClanTag(client, clanTag);
-
- if (gB_Chat)
- {
- if (GOKZ_GetOption(client, gC_ProfileOptionNames[ProfileOption_ShowRankChat]) == ProfileOptionBool_Enabled)
- {
- GOKZ_CH_SetChatTag(client, chatTag, color);
- }
- else
- {
- GOKZ_CH_SetChatTag(client, "", "{default}");
- }
- }
- return;
- }
-
- int points = GOKZ_GL_GetRankPoints(client, mode);
- int rank;
- for (rank = 1; rank < RANK_COUNT; rank++)
- {
- if (points < gI_rankThreshold[mode][rank])
- {
- break;
- }
- }
- rank--;
-
- if (GOKZ_GetCoreOption(client, Option_Mode) == mode)
- {
- if (points == -1)
- {
- UpdateTags(client, -1, mode);
- }
- else
- {
- UpdateTags(client, rank, mode);
- }
- }
-
- if (gI_Rank[client][mode] != rank)
- {
- gI_Rank[client][mode] = rank;
- Call_OnRankUpdated(client, mode, rank);
- }
-}
-
-void UpdateTags(int client, int rank, int mode)
-{
- char str[64];
- if (rank != -1 &&
- GOKZ_GetOption(client, gC_ProfileOptionNames[ProfileOption_ShowRankClanTag]) == ProfileOptionBool_Enabled)
- {
- FormatEx(str, sizeof(str), "[%s %s]", gC_ModeNamesShort[mode], gC_rankName[rank]);
- CS_SetClientClanTag(client, str);
- }
- else
- {
- FormatEx(str, sizeof(str), "[%s]", gC_ModeNamesShort[mode]);
- CS_SetClientClanTag(client, str);
- }
-
- if (gB_Chat)
- {
- if (rank != -1 &&
- GOKZ_GetOption(client, gC_ProfileOptionNames[ProfileOption_ShowRankChat]) == ProfileOptionBool_Enabled)
- {
- GOKZ_CH_SetChatTag(client, gC_rankName[rank], gC_rankColor[rank]);
- }
- else
- {
- GOKZ_CH_SetChatTag(client, "", "{default}");
- }
- }
-}
-
-bool CanUseTagType(int client, int tagType)
-{
- switch (tagType)
- {
- case ProfileTagType_Rank: return true;
- case ProfileTagType_VIP: return CheckCommandAccess(client, "gokz_flag_vip", ADMFLAG_CUSTOM1);
- case ProfileTagType_Admin: return CheckCommandAccess(client, "gokz_flag_admin", ADMFLAG_GENERIC);
- default: return false;
- }
-}
-
-int GetAvailableTagTypeOrDefault(int client)
-{
- int tagType = GOKZ_GetOption(client, gC_ProfileOptionNames[ProfileOption_TagType]);
- if (!CanUseTagType(client, tagType))
- {
- return ProfileTagType_Rank;
- }
-
- return tagType;
-}
-
-// =====[ COMMANDS ]=====
-
-void RegisterCommands()
-{
- RegConsoleCmd("sm_profile", CommandProfile, "[KZ] Show the profile of a player. Usage: !profile <player>");
- RegConsoleCmd("sm_p", CommandProfile, "[KZ] Show the profile of a player. Usage: !p <player>");
- RegConsoleCmd("sm_profileoptions", CommandProfileOptions, "[KZ] Show the profile options.");
- RegConsoleCmd("sm_pfo", CommandProfileOptions, "[KZ] Show the profile options.");
- RegConsoleCmd("sm_ranks", CommandRanks, "[KZ] Show all the available ranks.");
-}
-
-public Action CommandProfile(int client, int args)
-{
- if (args == 0)
- {
- ShowProfile(client, client);
- }
- else
- {
- char playerName[64];
- GetCmdArgString(playerName, sizeof(playerName));
- int player = FindTarget(client, playerName, true, false);
- if (player != -1)
- {
- ShowProfile(client, player);
- }
- }
- return Plugin_Handled;
-}
-
-public Action CommandProfileOptions(int client, int args)
-{
- DisplayProfileOptionsMenu(client);
- return Plugin_Handled;
-}
-
-public Action CommandRanks(int client, int args)
-{
- char rankBuffer[256];
- char buffer[256];
- int mode = GOKZ_GetCoreOption(client, Option_Mode);
-
- Format(buffer, sizeof(buffer), "%s: ", gC_ModeNamesShort[mode]);
-
- for (int i = 0; i < RANK_COUNT; i++) {
- Format(rankBuffer, sizeof(rankBuffer), "%s%s (%d) ", gC_rankColor[i], gC_rankName[i], gI_rankThreshold[mode][i]);
- StrCat(buffer, sizeof(buffer), rankBuffer);
-
- if (i > 0 && i % 3 == 0) {
- GOKZ_PrintToChat(client, true, buffer);
- Format(buffer, sizeof(buffer), "%s: ", gC_ModeNamesShort[mode]);
- }
- }
-
- GOKZ_PrintToChat(client, true, buffer);
-
- return Plugin_Handled;
-}
-
-
-// =====[ FORWARDS ]=====
-
-static GlobalForward H_OnRankUpdated;
-
-
-void CreateGlobalForwards()
-{
- H_OnRankUpdated = new GlobalForward("GOKZ_PF_OnRankUpdated", ET_Ignore, Param_Cell, Param_Cell, Param_Cell);
-}
-
-void Call_OnRankUpdated(int client, int mode, int rank)
-{
- Call_StartForward(H_OnRankUpdated);
- Call_PushCell(client);
- Call_PushCell(mode);
- Call_PushCell(rank);
- Call_Finish();
-}
-
-
-
-// =====[ NATIVES ]=====
-
-void CreateNatives()
-{
- CreateNative("GOKZ_PF_GetRank", Native_GetRank);
-}
-
-public int Native_GetRank(Handle plugin, int numParams)
-{
- return gI_Rank[GetNativeCell(1)][GetNativeCell(2)];
-}
diff --git a/source/sourcemod/scripting/gokz-quiet.sp b/source/sourcemod/scripting/gokz-quiet.sp
deleted file mode 100644
index 06cc246..0000000
--- a/source/sourcemod/scripting/gokz-quiet.sp
+++ /dev/null
@@ -1,151 +0,0 @@
-#include <sourcemod>
-
-#include <cstrike>
-#include <sdkhooks>
-#include <dhooks>
-
-#include <gokz/core>
-#include <gokz/quiet>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <updater>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Quiet",
- author = "DanZay",
- description = "Provides options for a quieter KZ experience",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-quiet.txt"
-
-
-#include "gokz-quiet/ambient.sp"
-#include "gokz-quiet/soundscape.sp"
-#include "gokz-quiet/hideplayers.sp"
-#include "gokz-quiet/falldamage.sp"
-#include "gokz-quiet/gokz-sounds.sp"
-#include "gokz-quiet/options.sp"
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- RegPluginLibrary("gokz-quiet");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- OnPluginStart_HidePlayers();
- OnPluginStart_FallDamage();
- OnPluginStart_Ambient();
-
- LoadTranslations("gokz-common.phrases");
- LoadTranslations("gokz-quiet.phrases");
-
- RegisterCommands();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-
- TopMenu topMenu;
- if (LibraryExists("gokz-core") && ((topMenu = GOKZ_GetOptionsTopMenu()) != null))
- {
- GOKZ_OnOptionsMenuReady(topMenu);
- }
-
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsClientInGame(client))
- {
- GOKZ_OnJoinTeam(client, GetClientTeam(client));
- }
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-
-
-// =====[ CLIENT EVENTS ]=====
-
-public void GOKZ_OnJoinTeam(int client, int team)
-{
- OnJoinTeam_HidePlayers(client, team);
-}
-
-public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2])
-{
- if (!IsValidClient(client))
- {
- return;
- }
-
- OnPlayerRunCmdPost_Soundscape(client);
-}
-
-
-// =====[ OTHER EVENTS ]=====
-
-public void GOKZ_OnOptionsMenuReady(TopMenu topMenu)
-{
- OnOptionsMenuReady_Options();
- OnOptionsMenuReady_OptionsMenu(topMenu);
-}
-
-public void GOKZ_OnOptionChanged(int client, const char[] option, any newValue)
-{
- any qtOption;
- if (GOKZ_QT_IsQTOption(option, qtOption))
- {
- OnOptionChanged_Options(client, qtOption, newValue);
- }
-}
-
-public void GOKZ_OnOptionsMenuCreated(TopMenu topMenu)
-{
- OnOptionsMenuCreated_OptionsMenu(topMenu);
-}
-
-// =====[ STOP SOUNDS ]=====
-
-void StopSounds(int client)
-{
- ClientCommand(client, "snd_playsounds Music.StopAllExceptMusic");
- GOKZ_PrintToChat(client, true, "%t", "Stopped Sounds");
-}
-
-
-// =====[ COMMANDS ]=====
-
-void RegisterCommands()
-{
- RegConsoleCmd("sm_hide", CommandToggleShowPlayers, "[KZ] Toggle the visibility of other players.");
- RegConsoleCmd("sm_stopsound", CommandStopSound, "[KZ] Stop all sounds e.g. map soundscapes (music).");
-}
-
-public Action CommandStopSound(int client, int args)
-{
- StopSounds(client);
- return Plugin_Handled;
-} \ No newline at end of file
diff --git a/source/sourcemod/scripting/gokz-racing.sp b/source/sourcemod/scripting/gokz-racing.sp
deleted file mode 100644
index 416d28a..0000000
--- a/source/sourcemod/scripting/gokz-racing.sp
+++ /dev/null
@@ -1,174 +0,0 @@
-#include <sourcemod>
-
-#include <gokz/core>
-#include <gokz/racing>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <updater>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Racing",
- author = "DanZay",
- description = "Lets players race against each other",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-racing.txt"
-
-#include "gokz-racing/announce.sp"
-#include "gokz-racing/api.sp"
-#include "gokz-racing/commands.sp"
-#include "gokz-racing/duel_menu.sp"
-#include "gokz-racing/race.sp"
-#include "gokz-racing/race_menu.sp"
-#include "gokz-racing/racer.sp"
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- CreateNatives();
- RegPluginLibrary("gokz-racing");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- LoadTranslations("gokz-common.phrases");
- LoadTranslations("gokz-racing.phrases");
-
- CreateGlobalForwards();
- RegisterCommands();
-
- OnPluginStart_Race();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-
-
-// =====[ CLIENT EVENTS ]=====
-
-public void OnClientPutInServer(int client)
-{
- OnClientPutInServer_Racer(client);
-}
-
-public void OnClientDisconnect(int client)
-{
- OnClientDisconnect_Racer(client);
-}
-
-public Action GOKZ_OnTimerStart(int client, int course)
-{
- Action action = OnTimerStart_Racer(client, course);
- if (action != Plugin_Continue)
- {
- return action;
- }
-
- return Plugin_Continue;
-}
-
-public void GOKZ_OnTimerStart_Post(int client, int course)
-{
- OnTimerStart_Post_Racer(client);
-}
-
-public void GOKZ_OnTimerEnd_Post(int client, int course, float time, int teleportsUsed)
-{
- FinishRacer(client, course);
-}
-
-public Action GOKZ_OnMakeCheckpoint(int client)
-{
- Action action = OnMakeCheckpoint_Racer(client);
- if (action != Plugin_Continue)
- {
- return action;
- }
-
- return Plugin_Continue;
-}
-
-public void GOKZ_OnMakeCheckpoint_Post(int client)
-{
- OnMakeCheckpoint_Post_Racer(client);
-}
-
-public Action GOKZ_OnUndoTeleport(int client)
-{
- Action action = OnUndoTeleport_Racer(client);
- if (action != Plugin_Continue)
- {
- return action;
- }
-
- return Plugin_Continue;
-}
-
-public void GOKZ_RC_OnFinish(int client, int raceID, int place)
-{
- OnFinish_Announce(client, raceID, place);
- OnFinish_Race(raceID);
-}
-
-public void GOKZ_RC_OnSurrender(int client, int raceID)
-{
- OnSurrender_Announce(client, raceID);
-}
-
-public void GOKZ_RC_OnRequestReceived(int client, int raceID)
-{
- OnRequestReceived_Announce(client, raceID);
-}
-
-public void GOKZ_RC_OnRequestAccepted(int client, int raceID)
-{
- OnRequestAccepted_Announce(client, raceID);
- OnRequestAccepted_Race(raceID);
-}
-
-public void GOKZ_RC_OnRequestDeclined(int client, int raceID, bool timeout)
-{
- OnRequestDeclined_Announce(client, raceID, timeout);
- OnRequestDeclined_Race(raceID);
-}
-
-
-
-// =====[ OTHER EVENTS ]=====
-
-public void GOKZ_RC_OnRaceStarted(int raceID)
-{
- OnRaceStarted_Announce(raceID);
-}
-
-public void GOKZ_RC_OnRaceAborted(int raceID)
-{
- OnRaceAborted_Announce(raceID);
-} \ No newline at end of file
diff --git a/source/sourcemod/scripting/gokz-replays.sp b/source/sourcemod/scripting/gokz-replays.sp
deleted file mode 100644
index bc826c4..0000000
--- a/source/sourcemod/scripting/gokz-replays.sp
+++ /dev/null
@@ -1,397 +0,0 @@
-#include <sourcemod>
-
-#include <cstrike>
-#include <sdkhooks>
-#include <sdktools>
-#include <dhooks>
-
-#include <movementapi>
-
-#include <gokz/core>
-#include <gokz/localranks>
-#include <gokz/replays>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <gokz/hud>
-#include <gokz/jumpstats>
-#include <gokz/localdb>
-#include <updater>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-//#define DEBUG
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Replays",
- author = "DanZay",
- description = "Records runs to disk and allows playback using bots",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-replays.txt"
-
-bool gB_GOKZHUD;
-bool gB_GOKZLocalDB;
-char gC_CurrentMap[64];
-int gI_CurrentMapFileSize;
-bool gB_HideNameChange;
-bool gB_NubRecordMissed[MAXPLAYERS + 1];
-ArrayList g_ReplayInfoCache;
-Address gA_BotDuckAddr;
-int gI_BotDuckPatchRestore[40]; // Size of patched section in gamedata
-int gI_BotDuckPatchLength;
-
-DynamicDetour gH_DHooks_TeamFull;
-
-#include "gokz-replays/commands.sp"
-#include "gokz-replays/nav.sp"
-#include "gokz-replays/playback.sp"
-#include "gokz-replays/recording.sp"
-#include "gokz-replays/replay_cache.sp"
-#include "gokz-replays/replay_menu.sp"
-#include "gokz-replays/api.sp"
-#include "gokz-replays/controls.sp"
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- CreateNatives();
- RegPluginLibrary("gokz-replays");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- LoadTranslations("gokz-common.phrases");
- LoadTranslations("gokz-replays.phrases");
-
- CreateGlobalForwards();
- HookEvents();
- RegisterCommands();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
- gB_GOKZLocalDB = LibraryExists("gokz-localdb");
- gB_GOKZHUD = LibraryExists("gokz-hud");
-
- for (int client = 1; client <= MaxClients; client++)
- {
- if (IsClientInGame(client))
- {
- OnClientPutInServer(client);
- }
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
- gB_GOKZLocalDB = gB_GOKZLocalDB || StrEqual(name, "gokz-localdb");
- gB_GOKZHUD = gB_GOKZHUD || StrEqual(name, "gokz-hud");
-}
-
-public void OnLibraryRemoved(const char[] name)
-{
- gB_GOKZLocalDB = gB_GOKZLocalDB && !StrEqual(name, "gokz-localdb");
- gB_GOKZHUD = gB_GOKZHUD && !StrEqual(name, "gokz-hud");
-}
-
-public void OnPluginEnd()
-{
- // Restore bot auto duck behavior.
- if (gA_BotDuckAddr == Address_Null)
- {
- return;
- }
- for (int i = 0; i < gI_BotDuckPatchLength; i++)
- {
- StoreToAddress(gA_BotDuckAddr + view_as<Address>(i), gI_BotDuckPatchRestore[i], NumberType_Int8);
- }
-}
-
-// =====[ OTHER EVENTS ]=====
-
-public void OnMapStart()
-{
- UpdateCurrentMap(); // Do first
- OnMapStart_Nav();
- OnMapStart_Recording();
- OnMapStart_ReplayCache();
-}
-
-public void OnConfigsExecuted()
-{
- FindConVar("mp_autoteambalance").BoolValue = false;
- FindConVar("mp_limitteams").IntValue = 0;
- // Stop the bots!
- FindConVar("bot_stop").BoolValue = true;
- FindConVar("bot_chatter").SetString("off");
- FindConVar("bot_zombie").BoolValue = true;
- FindConVar("bot_join_after_player").BoolValue = false;
- FindConVar("bot_quota_mode").SetString("normal");
- FindConVar("bot_quota").Flags &= ~FCVAR_NOTIFY;
- FindConVar("bot_quota").Flags &= ~FCVAR_REPLICATED;
-}
-
-public void OnEntityCreated(int entity, const char[] classname)
-{
- // Block trigger and door interaction for bots
- // Credit to shavit's simple bhop timer - https://github.com/shavitush/bhoptimer
-
- // trigger_once | trigger_multiple.. etc
- // func_door | func_door_rotating
- if (StrContains(classname, "trigger_") != -1 || StrContains(classname, "_door") != -1)
- {
- SDKHook(entity, SDKHook_StartTouch, HookTriggers);
- SDKHook(entity, SDKHook_EndTouch, HookTriggers);
- SDKHook(entity, SDKHook_Touch, HookTriggers);
- }
-}
-
-public Action HookTriggers(int entity, int other)
-{
- if (other >= 1 && other <= MaxClients && IsFakeClient(other))
- {
- return Plugin_Handled;
- }
-
- return Plugin_Continue;
-}
-
-public Action Hook_SayText2(UserMsg msg_id, any msg, const int[] players, int playersNum, bool reliable, bool init)
-{
- // Name change supression
- // Credit to shavit's simple bhop timer - https://github.com/shavitush/bhoptimer
- if (!gB_HideNameChange)
- {
- return Plugin_Continue;
- }
-
- char msgName[24];
- Protobuf pbmsg = msg;
- pbmsg.ReadString("msg_name", msgName, sizeof(msgName));
- if (StrEqual(msgName, "#Cstrike_Name_Change"))
- {
- gB_HideNameChange = false;
- return Plugin_Handled;
- }
-
- return Plugin_Continue;
-}
-
-public MRESReturn DHooks_OnTeamFull_Pre(Address pThis, DHookReturn hReturn, DHookParam hParams)
-{
- DHookSetReturn(hReturn, false);
- return MRES_Supercede;
-}
-
-// =====[ CLIENT EVENTS ]=====
-
-public void OnClientPutInServer(int client)
-{
- OnClientPutInServer_Playback(client);
- OnClientPutInServer_Recording(client);
-}
-
-public void OnClientAuthorized(int client, const char[] auth)
-{
- OnClientAuthorized_Recording(client);
-}
-
-public void OnClientDisconnect(int client)
-{
- OnClientDisconnect_Playback(client);
- OnClientDisconnect_Recording(client);
-}
-
-public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
-{
- if (!IsFakeClient(client))
- {
- return Plugin_Continue;
- }
- OnPlayerRunCmd_Playback(client, buttons, vel, angles);
- return Plugin_Changed;
-}
-
-public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2])
-{
- OnPlayerRunCmdPost_Playback(client);
- OnPlayerRunCmdPost_Recording(client, buttons, tickcount, vel, mouse);
- OnPlayerRunCmdPost_ReplayControls(client, cmdnum);
-}
-
-public Action GOKZ_OnTimerStart(int client, int course)
-{
- Action action = GOKZ_OnTimerStart_Recording(client);
- if (action != Plugin_Continue)
- {
- return action;
- }
-
- return Plugin_Continue;
-}
-
-public void GOKZ_OnTimerStart_Post(int client, int course)
-{
- gB_NubRecordMissed[client] = false;
- GOKZ_OnTimerStart_Post_Recording(client);
-}
-
-public void GOKZ_OnTimerEnd_Post(int client, int course, float time, int teleportsUsed)
-{
- GOKZ_OnTimerEnd_Recording(client, course, time, teleportsUsed);
-}
-
-public void GOKZ_OnPause_Post(int client)
-{
- GOKZ_OnPause_Recording(client);
-}
-
-public void GOKZ_OnResume_Post(int client)
-{
- GOKZ_OnResume_Recording(client);
-}
-
-public void GOKZ_OnTimerStopped(int client)
-{
- GOKZ_OnTimerStopped_Recording(client);
-}
-
-public void GOKZ_OnCountedTeleport_Post(int client)
-{
- GOKZ_OnCountedTeleport_Recording(client);
-}
-
-public void GOKZ_LR_OnRecordMissed(int client, float recordTime, int course, int mode, int style, int recordType)
-{
- if (recordType == RecordType_Nub)
- {
- gB_NubRecordMissed[client] = true;
- }
- GOKZ_LR_OnRecordMissed_Recording(client, recordType);
-}
-
-public void GOKZ_AC_OnPlayerSuspected(int client, ACReason reason)
-{
- GOKZ_AC_OnPlayerSuspected_Recording(client, reason);
-}
-
-public void GOKZ_DB_OnJumpstatPB(int client, int jumptype, int mode, float distance, int block, int strafes, float sync, float pre, float max, int airtime)
-{
- GOKZ_DB_OnJumpstatPB_Recording(client, jumptype, distance, block, strafes, sync, pre, max, airtime);
-}
-
-public void GOKZ_OnOptionsLoaded(int client)
-{
- if (IsFakeClient(client))
- {
- GOKZ_OnOptionsLoaded_Playback(client);
- }
-}
-
-// =====[ PRIVATE ]=====
-
-static void HookEvents()
-{
- HookUserMessage(GetUserMessageId("SayText2"), Hook_SayText2, true);
- GameData gameData = LoadGameConfigFile("gokz-replays.games");
-
- gH_DHooks_TeamFull = DynamicDetour.FromConf(gameData, "CCSGameRules::TeamFull");
- if (gH_DHooks_TeamFull == INVALID_HANDLE)
- {
- SetFailState("Failed to find CCSGameRules::TeamFull function signature");
- }
-
- if (!gH_DHooks_TeamFull.Enable(Hook_Pre, DHooks_OnTeamFull_Pre))
- {
- SetFailState("Failed to enable detour on CCSGameRules::TeamFull");
- }
-
- // Remove bot auto duck behavior.
- gA_BotDuckAddr = gameData.GetAddress("BotDuck");
- gI_BotDuckPatchLength = gameData.GetOffset("BotDuckPatchLength");
- for (int i = 0; i < gI_BotDuckPatchLength; i++)
- {
- gI_BotDuckPatchRestore[i] = LoadFromAddress(gA_BotDuckAddr + view_as<Address>(i), NumberType_Int8);
- StoreToAddress(gA_BotDuckAddr + view_as<Address>(i), 0x90, NumberType_Int8);
- }
- delete gameData;
-}
-
-static void UpdateCurrentMap()
-{
- GetCurrentMapDisplayName(gC_CurrentMap, sizeof(gC_CurrentMap));
- gI_CurrentMapFileSize = GetCurrentMapFileSize();
-}
-
-
-// =====[ PUBLIC ]=====
-
-// NOTE: These serialisation functions were made because the internal data layout of enum structs can change.
-void TickDataToArray(ReplayTickData tickData, any result[RP_V2_TICK_DATA_BLOCKSIZE])
-{
- // NOTE: HAS to match ReplayTickData exactly!
- result[0] = tickData.deltaFlags;
- result[1] = tickData.deltaFlags2;
- result[2] = tickData.vel[0];
- result[3] = tickData.vel[1];
- result[4] = tickData.vel[2];
- result[5] = tickData.mouse[0];
- result[6] = tickData.mouse[1];
- result[7] = tickData.origin[0];
- result[8] = tickData.origin[1];
- result[9] = tickData.origin[2];
- result[10] = tickData.angles[0];
- result[11] = tickData.angles[1];
- result[12] = tickData.angles[2];
- result[13] = tickData.velocity[0];
- result[14] = tickData.velocity[1];
- result[15] = tickData.velocity[2];
- result[16] = tickData.flags;
- result[17] = tickData.packetsPerSecond;
- result[18] = tickData.laggedMovementValue;
- result[19] = tickData.buttonsForced;
-}
-
-void TickDataFromArray(any array[RP_V2_TICK_DATA_BLOCKSIZE], ReplayTickData result)
-{
- // NOTE: HAS to match ReplayTickData exactly!
- result.deltaFlags = array[0];
- result.deltaFlags2 = array[1];
- result.vel[0] = array[2];
- result.vel[1] = array[3];
- result.vel[2] = array[4];
- result.mouse[0] = array[5];
- result.mouse[1] = array[6];
- result.origin[0] = array[7];
- result.origin[1] = array[8];
- result.origin[2] = array[9];
- result.angles[0] = array[10];
- result.angles[1] = array[11];
- result.angles[2] = array[12];
- result.velocity[0] = array[13];
- result.velocity[1] = array[14];
- result.velocity[2] = array[15];
- result.flags = array[16];
- result.packetsPerSecond = array[17];
- result.laggedMovementValue = array[18];
- result.buttonsForced = array[19];
-}
diff --git a/source/sourcemod/scripting/gokz-slayonend.sp b/source/sourcemod/scripting/gokz-slayonend.sp
deleted file mode 100644
index c83c4e6..0000000
--- a/source/sourcemod/scripting/gokz-slayonend.sp
+++ /dev/null
@@ -1,190 +0,0 @@
-#include <sourcemod>
-
-#include <gokz/core>
-#include <gokz/slayonend>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <updater>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Slay On End",
- author = "DanZay",
- description = "Adds option to slay the player upon ending their timer",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-slayonend.txt"
-
-TopMenu gTM_Options;
-TopMenuObject gTMO_CatGeneral;
-TopMenuObject gTMO_ItemSlayOnEnd;
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- RegPluginLibrary("gokz-slayonend");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- LoadTranslations("gokz-common.phrases");
- LoadTranslations("gokz-slayonend.phrases");
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-
- TopMenu topMenu;
- if (LibraryExists("gokz-core") && ((topMenu = GOKZ_GetOptionsTopMenu()) != null))
- {
- GOKZ_OnOptionsMenuReady(topMenu);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-
-
-// =====[ CLIENT EVENTS ]=====
-
-public void GOKZ_OnTimerEnd_Post(int client, int course, float time, int teleportsUsed)
-{
- OnTimerEnd_SlayOnEnd(client);
-}
-
-public void GOKZ_OnOptionChanged(int client, const char[] option, any newValue)
-{
- OnOptionChanged_Options(client, option, newValue);
-}
-
-
-
-// =====[ OTHER EVENTS ]=====
-
-public void GOKZ_OnOptionsMenuReady(TopMenu topMenu)
-{
- OnOptionsMenuReady_Options();
- OnOptionsMenuReady_OptionsMenu(topMenu);
-}
-
-
-
-// =====[ SLAY ON END ]=====
-
-void OnTimerEnd_SlayOnEnd(int client)
-{
- if (GOKZ_GetOption(client, SLAYONEND_OPTION_NAME) == SlayOnEnd_Enabled)
- {
- CreateTimer(3.0, Timer_SlayPlayer, GetClientUserId(client));
- }
-}
-
-public Action Timer_SlayPlayer(Handle timer, int userid)
-{
- int client = GetClientOfUserId(userid);
- if (IsValidClient(client))
- {
- ForcePlayerSuicide(client);
- }
- return Plugin_Continue;
-}
-
-
-
-// =====[ OPTIONS ]=====
-
-void OnOptionsMenuReady_Options()
-{
- RegisterOption();
-}
-
-void RegisterOption()
-{
- GOKZ_RegisterOption(SLAYONEND_OPTION_NAME, SLAYONEND_OPTION_DESCRIPTION,
- OptionType_Int, SlayOnEnd_Disabled, 0, SLAYONEND_COUNT - 1);
-}
-
-void OnOptionChanged_Options(int client, const char[] option, any newValue)
-{
- if (StrEqual(option, SLAYONEND_OPTION_NAME))
- {
- switch (newValue)
- {
- case SlayOnEnd_Disabled:
- {
- GOKZ_PrintToChat(client, true, "%t", "Option - Slay On End - Disable");
- }
- case SlayOnEnd_Enabled:
- {
- GOKZ_PrintToChat(client, true, "%t", "Option - Slay On End - Enable");
- }
- }
- }
-}
-
-
-
-// =====[ OPTIONS MENU ]=====
-
-void OnOptionsMenuReady_OptionsMenu(TopMenu topMenu)
-{
- if (gTM_Options == topMenu)
- {
- return;
- }
-
- gTM_Options = topMenu;
- gTMO_CatGeneral = gTM_Options.FindCategory(GENERAL_OPTION_CATEGORY);
- gTMO_ItemSlayOnEnd = gTM_Options.AddItem(SLAYONEND_OPTION_NAME, TopMenuHandler_SlayOnEnd, gTMO_CatGeneral);
-}
-
-public void TopMenuHandler_SlayOnEnd(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength)
-{
- if (topobj_id != gTMO_ItemSlayOnEnd)
- {
- return;
- }
-
- if (action == TopMenuAction_DisplayOption)
- {
- if (GOKZ_GetOption(param, SLAYONEND_OPTION_NAME) == SlayOnEnd_Disabled)
- {
- FormatEx(buffer, maxlength, "%T - %T",
- "Options Menu - Slay On End", param,
- "Options Menu - Disabled", param);
- }
- else
- {
- FormatEx(buffer, maxlength, "%T - %T",
- "Options Menu - Slay On End", param,
- "Options Menu - Enabled", param);
- }
- }
- else if (action == TopMenuAction_SelectOption)
- {
- GOKZ_CycleOption(param, SLAYONEND_OPTION_NAME);
- gTM_Options.Display(param, TopMenuPosition_LastCategory);
- }
-} \ No newline at end of file
diff --git a/source/sourcemod/scripting/gokz-spec.sp b/source/sourcemod/scripting/gokz-spec.sp
deleted file mode 100644
index 29f842f..0000000
--- a/source/sourcemod/scripting/gokz-spec.sp
+++ /dev/null
@@ -1,323 +0,0 @@
-#include <sourcemod>
-
-#include <cstrike>
-
-#include <gokz/core>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <updater>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Spectate Menu",
- author = "DanZay",
- description = "Provides easy ways to spectate players",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-spec.txt"
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- RegPluginLibrary("gokz-spec");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- LoadTranslations("common.phrases");
- LoadTranslations("gokz-common.phrases");
- LoadTranslations("gokz-spec.phrases");
-
- RegisterCommands();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-}
-
-
-
-// =====[ SPEC MENU ]=====
-
-int DisplaySpecMenu(int client, bool useFilter = false, char[] filter = "")
-{
- Menu menu = new Menu(MenuHandler_Spec);
- menu.SetTitle("%T", "Spec Menu - Title", client);
- int menuItems = SpecMenuAddItems(client, menu, useFilter, filter);
- if (menuItems == 0 || menuItems == 1)
- {
- delete menu;
- }
- else
- {
- menu.Display(client, MENU_TIME_FOREVER);
- }
- return menuItems;
-}
-
-bool Spectate(int client)
-{
- if (!CanSpectate(client))
- {
- return false;
- }
-
- GOKZ_JoinTeam(client, CS_TEAM_SPECTATOR);
-
- // Put player in free look mode and apply according movetype
- SetEntProp(client, Prop_Send, "m_iObserverMode", 6);
- SetEntityMoveType(client, MOVETYPE_OBSERVER);
- return true;
-}
-
-// Returns whether change to spectating the target was successful
-bool SpectatePlayer(int client, int target, bool printMessage = true)
-{
- if (!CanSpectate(client))
- {
- return false;
- }
-
- if (target == client)
- {
- Spectate(client);
- return true;
- }
- else if (!IsPlayerAlive(target))
- {
- if (printMessage)
- {
- GOKZ_PrintToChat(client, true, "%t", "Spectate Failure (Dead)");
- GOKZ_PlayErrorSound(client);
- }
- return false;
- }
-
- GOKZ_JoinTeam(client, CS_TEAM_SPECTATOR);
- SetEntProp(client, Prop_Send, "m_iObserverMode", 4);
- SetEntPropEnt(client, Prop_Send, "m_hObserverTarget", target);
-
- return true;
-}
-
-bool CanSpectate(int client)
-{
- return !IsPlayerAlive(client) || GOKZ_GetPaused(client) || GOKZ_GetCanPause(client);
-}
-
-public int MenuHandler_Spec(Menu menu, MenuAction action, int param1, int param2)
-{
- if (action == MenuAction_Select)
- {
- char info[16];
- menu.GetItem(param2, info, sizeof(info));
- int target = GetClientOfUserId(StringToInt(info));
-
- if (!IsValidClient(target))
- {
- GOKZ_PrintToChat(param1, true, "%t", "Player No Longer Valid");
- GOKZ_PlayErrorSound(param1);
- DisplaySpecMenu(param1);
- }
- else if (!SpectatePlayer(param1, target))
- {
- DisplaySpecMenu(param1);
- }
- }
- else if (action == MenuAction_End)
- {
- delete menu;
- }
- return 0;
-}
-
-// Returns number of items added to the menu
-int SpecMenuAddItems(int client, Menu menu, bool useFilter, char[] filter)
-{
- char display[MAX_NAME_LENGTH + 4];
- int targetCount = 0;
- int latestResult;
-
- for (int i = 1; i <= MaxClients; i++)
- {
- if (!IsClientInGame(i) || !IsPlayerAlive(i) || i == client)
- {
- continue;
- }
- if (useFilter)
- {
- FormatEx(display, sizeof(display), "%N", i);
- if (StrContains(display, filter, false) != -1)
- {
- if (IsFakeClient(i))
- {
- FormatEx(display, sizeof(display), "BOT %N", i);
- }
- }
- else // If it doesn't fit the filter, move on
- {
- continue;
- }
- }
- else
- {
- if (IsFakeClient(i))
- {
- FormatEx(display, sizeof(display), "BOT %N", i);
- }
- else
- {
- FormatEx(display, sizeof(display), "%N", i);
- }
- }
- latestResult = i;
- menu.AddItem(IntToStringEx(GetClientUserId(i)), display, ITEMDRAW_DEFAULT);
- targetCount++;
- }
- // The only spectate-able player is the latest result, this happens when the player issuing the command also fits in the filter
- if (targetCount == 1)
- {
- SpectatePlayer(client, latestResult);
- }
-
- return targetCount;
-}
-
-
-
-// =====[ COMMANDS ]=====
-
-void RegisterCommands()
-{
- RegConsoleCmd("sm_spec", CommandSpec, "[KZ] Spectate another player. Usage: !spec <player>");
- RegConsoleCmd("sm_specs", CommandSpecs, "[KZ] List currently spectating players in chat.");
- RegConsoleCmd("sm_speclist", CommandSpecs, "[KZ] List currently spectating players in chat.");
-}
-
-public Action CommandSpec(int client, int args)
-{
- // If no arguments, display the spec menu
- if (args < 1)
- {
- if (DisplaySpecMenu(client) == 0)
- {
- // No targets, so just join spec
- Spectate(client);
- }
- }
- // Otherwise try to spectate the player
- else
- {
- char specifiedPlayer[MAX_NAME_LENGTH];
- GetCmdArg(1, specifiedPlayer, sizeof(specifiedPlayer));
-
- char targetName[MAX_TARGET_LENGTH];
- int targetList[1], targetCount;
- bool tnIsML;
- int flags = COMMAND_FILTER_NO_MULTI | COMMAND_FILTER_NO_IMMUNITY | COMMAND_FILTER_ALIVE;
-
- if ((targetCount = ProcessTargetString(
- specifiedPlayer,
- client,
- targetList,
- 1,
- flags,
- targetName,
- sizeof(targetName),
- tnIsML)) == 1)
- {
- SpectatePlayer(client, targetList[0]);
- }
- else if (targetCount == COMMAND_TARGET_AMBIGUOUS)
- {
- DisplaySpecMenu(client, true, specifiedPlayer);
- }
- else
- {
- ReplyToTargetError(client, targetCount);
- }
-
- }
- return Plugin_Handled;
-}
-
-public Action CommandSpecs(int client, int args)
-{
- int specs = 0;
- char specNames[1024];
-
- int target = IsPlayerAlive(client) ? client : GetObserverTarget(client);
- int targetSpecs = 0;
- char targetSpecNames[1024];
-
- for (int i = 1; i <= MaxClients; i++)
- {
- if (IsClientInGame(i) && !IsFakeClient(i) && IsSpectating(i))
- {
- specs++;
- if (specs == 1)
- {
- FormatEx(specNames, sizeof(specNames), "{lime}%N", i);
- }
- else
- {
- Format(specNames, sizeof(specNames), "%s{grey}, {lime}%N", specNames, i);
- }
-
- if (target != -1 && GetObserverTarget(i) == target)
- {
- targetSpecs++;
- if (targetSpecs == 1)
- {
- FormatEx(targetSpecNames, sizeof(targetSpecNames), "{lime}%N", i);
- }
- else
- {
- Format(targetSpecNames, sizeof(targetSpecNames), "%s{grey}, {lime}%N", targetSpecNames, i);
- }
- }
- }
- }
-
- if (specs == 0)
- {
- GOKZ_PrintToChat(client, true, "%t", "Spectator List (None)");
- }
- else
- {
- GOKZ_PrintToChat(client, true, "%t", "Spectator List", specs, specNames);
- if (targetSpecs == 0)
- {
- GOKZ_PrintToChat(client, false, "%t", "Target Spectator List (None)", target);
- }
- else
- {
- GOKZ_PrintToChat(client, false, "%t", "Target Spectator List", target, targetSpecs, targetSpecNames);
- }
- }
- return Plugin_Handled;
-} \ No newline at end of file
diff --git a/source/sourcemod/scripting/gokz-tips.sp b/source/sourcemod/scripting/gokz-tips.sp
deleted file mode 100644
index 8a84b9e..0000000
--- a/source/sourcemod/scripting/gokz-tips.sp
+++ /dev/null
@@ -1,357 +0,0 @@
-#include <sourcemod>
-
-#include <gokz/core>
-#include <gokz/tips>
-
-#include <autoexecconfig>
-
-#undef REQUIRE_EXTENSIONS
-#undef REQUIRE_PLUGIN
-#include <updater>
-
-#include <gokz/kzplayer>
-
-#pragma newdecls required
-#pragma semicolon 1
-
-
-
-public Plugin myinfo =
-{
- name = "GOKZ Tips",
- author = "DanZay",
- description = "Prints tips to chat periodically based on loaded plugins",
- version = GOKZ_VERSION,
- url = GOKZ_SOURCE_URL
-};
-
-#define UPDATER_URL GOKZ_UPDATER_BASE_URL..."gokz-tips.txt"
-
-bool gC_PluginsWithTipsLoaded[TIPS_PLUGINS_COUNT];
-ArrayList g_TipPhrases;
-int gI_CurrentTip;
-Handle gH_TipTimer;
-TopMenu gTM_Options;
-TopMenuObject gTMO_CatGeneral;
-TopMenuObject gTMO_ItemTips;
-ConVar gCV_gokz_tips_interval;
-
-
-
-// =====[ PLUGIN EVENTS ]=====
-
-public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
-{
- RegPluginLibrary("gokz-tips");
- return APLRes_Success;
-}
-
-public void OnPluginStart()
-{
- LoadTranslations("gokz-common.phrases");
- LoadTranslations("gokz-tips.phrases");
- LoadTranslations("gokz-tips-tips.phrases");
- LoadTranslations("gokz-tips-core.phrases");
-
- // Load translations of tips for other GOKZ plugins
- char translation[PLATFORM_MAX_PATH];
- for (int i = 0; i < TIPS_PLUGINS_COUNT; i++)
- {
- FormatEx(translation, sizeof(translation), "gokz-tips-%s.phrases", gC_PluginsWithTips[i]);
- LoadTranslations(translation);
- }
-
- CreateConVars();
- RegisterCommands();
- CreateTipsTimer();
-}
-
-public void OnAllPluginsLoaded()
-{
- if (LibraryExists("updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-
- char gokzPlugin[PLATFORM_MAX_PATH];
- for (int i = 0; i < TIPS_PLUGINS_COUNT; i++)
- {
- FormatEx(gokzPlugin, sizeof(gokzPlugin), "gokz-%s", gC_PluginsWithTips[i]);
- gC_PluginsWithTipsLoaded[i] = LibraryExists(gokzPlugin);
- }
-
- TopMenu topMenu;
- if (LibraryExists("gokz-core") && ((topMenu = GOKZ_GetOptionsTopMenu()) != null))
- {
- GOKZ_OnOptionsMenuReady(topMenu);
- }
-}
-
-public void OnLibraryAdded(const char[] name)
-{
- if (StrEqual(name, "updater"))
- {
- Updater_AddPlugin(UPDATER_URL);
- }
-
- char gokzPlugin[PLATFORM_MAX_PATH];
- for (int i = 0; i < TIPS_PLUGINS_COUNT; i++)
- {
- FormatEx(gokzPlugin, sizeof(gokzPlugin), "gokz-%s", gC_PluginsWithTips[i]);
- gC_PluginsWithTipsLoaded[i] = gC_PluginsWithTipsLoaded[i] || StrEqual(name, gokzPlugin);
- }
-}
-
-public void OnLibraryRemoved(const char[] name)
-{
- char gokzPlugin[PLATFORM_MAX_PATH];
- for (int i = 0; i < TIPS_PLUGINS_COUNT; i++)
- {
- FormatEx(gokzPlugin, sizeof(gokzPlugin), "gokz-%s", gC_PluginsWithTips[i]);
- gC_PluginsWithTipsLoaded[i] = gC_PluginsWithTipsLoaded[i] && !StrEqual(name, gokzPlugin);
- }
-}
-
-
-
-// =====[ CLIENT EVENTS ]=====
-
-public void GOKZ_OnOptionChanged(int client, const char[] option, any newValue)
-{
- OnOptionChanged_Options(client, option, newValue);
-}
-
-
-
-// =====[ OTHER EVENTS ]=====
-
-public void OnMapStart()
-{
- LoadTipPhrases();
-}
-
-public void GOKZ_OnOptionsMenuReady(TopMenu topMenu)
-{
- OnOptionsMenuReady_Options();
- OnOptionsMenuReady_OptionsMenu(topMenu);
-}
-
-
-
-// =====[ CONVARS ]=====
-
-void CreateConVars()
-{
- AutoExecConfig_SetFile("gokz-tips", "sourcemod/gokz");
- AutoExecConfig_SetCreateFile(true);
-
- gCV_gokz_tips_interval = AutoExecConfig_CreateConVar("gokz_tips_interval", "75", "How often GOKZ tips are printed to chat in seconds.", _, true, 1.0, false);
- gCV_gokz_tips_interval.AddChangeHook(OnConVarChanged);
-
- AutoExecConfig_ExecuteFile();
- AutoExecConfig_CleanFile();
-}
-
-public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
-{
- if (convar == gCV_gokz_tips_interval)
- {
- CreateTipsTimer();
- }
-}
-
-
-
-// =====[ TIPS ]=====
-
-void LoadTipPhrases()
-{
- if (g_TipPhrases == null)
- {
- g_TipPhrases = new ArrayList(64, 0);
- }
- else
- {
- g_TipPhrases.Clear();
- }
-
- char tipsPath[PLATFORM_MAX_PATH];
-
- BuildPath(Path_SM, tipsPath, sizeof(tipsPath), "translations/%s", TIPS_TIPS);
- LoadTipPhrasesFromFile(tipsPath);
-
- BuildPath(Path_SM, tipsPath, sizeof(tipsPath), "translations/%s", TIPS_CORE);
- LoadTipPhrasesFromFile(tipsPath);
-
- // Load tips for other loaded GOKZ plugins
- for (int i = 0; i < TIPS_PLUGINS_COUNT; i++)
- {
- if (gC_PluginsWithTipsLoaded[i])
- {
- BuildPath(Path_SM, tipsPath, sizeof(tipsPath), "translations/gokz-tips-%s.phrases.txt", gC_PluginsWithTips[i]);
- LoadTipPhrasesFromFile(tipsPath);
- }
- }
-
- ShuffleTipPhrases();
-}
-
-void LoadTipPhrasesFromFile(const char[] filePath)
-{
- KeyValues kv = new KeyValues("Phrases");
- if (!kv.ImportFromFile(filePath))
- {
- SetFailState("Failed to load file: \"%s\".", filePath);
- }
-
- char phraseName[64];
- kv.GotoFirstSubKey(true);
- do
- {
- kv.GetSectionName(phraseName, sizeof(phraseName));
- g_TipPhrases.PushString(phraseName);
- } while (kv.GotoNextKey(true));
-
- delete kv;
-}
-
-void ShuffleTipPhrases()
-{
- for (int i = g_TipPhrases.Length - 1; i >= 1; i--)
- {
- int j = GetRandomInt(0, i);
- char tempStringI[64];
- g_TipPhrases.GetString(i, tempStringI, sizeof(tempStringI));
- char tempStringJ[64];
- g_TipPhrases.GetString(j, tempStringJ, sizeof(tempStringJ));
- g_TipPhrases.SetString(i, tempStringJ);
- g_TipPhrases.SetString(j, tempStringI);
- }
-}
-
-void CreateTipsTimer()
-{
- if (gH_TipTimer != null)
- {
- delete gH_TipTimer;
- }
- gH_TipTimer = CreateTimer(gCV_gokz_tips_interval.FloatValue, Timer_PrintTip, _, TIMER_REPEAT);
-}
-
-public Action Timer_PrintTip(Handle timer)
-{
- char tip[256];
- g_TipPhrases.GetString(gI_CurrentTip, tip, sizeof(tip));
-
- for (int client = 1; client <= MaxClients; client++)
- {
- KZPlayer player = KZPlayer(client);
- if (player.InGame && player.Tips != Tips_Disabled)
- {
- GOKZ_PrintToChat(client, true, "%t", tip);
- }
- }
-
- gI_CurrentTip = NextIndex(gI_CurrentTip, g_TipPhrases.Length);
- return Plugin_Continue;
-}
-
-
-
-// =====[ OPTIONS ]=====
-
-void OnOptionsMenuReady_Options()
-{
- RegisterOption();
-}
-
-void RegisterOption()
-{
- GOKZ_RegisterOption(TIPS_OPTION_NAME, TIPS_OPTION_DESCRIPTION,
- OptionType_Int, Tips_Enabled, 0, TIPS_COUNT - 1);
-}
-
-void OnOptionChanged_Options(int client, const char[] option, any newValue)
-{
- if (StrEqual(option, TIPS_OPTION_NAME))
- {
- switch (newValue)
- {
- case Tips_Disabled:
- {
- GOKZ_PrintToChat(client, true, "%t", "Option - Tips - Disable");
- }
- case Tips_Enabled:
- {
- GOKZ_PrintToChat(client, true, "%t", "Option - Tips - Enable");
- }
- }
- }
-}
-
-
-
-// =====[ OPTIONS MENU ]=====
-
-void OnOptionsMenuReady_OptionsMenu(TopMenu topMenu)
-{
- if (gTM_Options == topMenu)
- {
- return;
- }
-
- gTM_Options = topMenu;
- gTMO_CatGeneral = gTM_Options.FindCategory(GENERAL_OPTION_CATEGORY);
- gTMO_ItemTips = gTM_Options.AddItem(TIPS_OPTION_NAME, TopMenuHandler_Tips, gTMO_CatGeneral);
-}
-
-public void TopMenuHandler_Tips(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength)
-{
- if (topobj_id != gTMO_ItemTips)
- {
- return;
- }
-
- if (action == TopMenuAction_DisplayOption)
- {
- if (GOKZ_GetOption(param, TIPS_OPTION_NAME) == Tips_Disabled)
- {
- FormatEx(buffer, maxlength, "%T - %T",
- "Options Menu - Tips", param,
- "Options Menu - Disabled", param);
- }
- else
- {
- FormatEx(buffer, maxlength, "%T - %T",
- "Options Menu - Tips", param,
- "Options Menu - Enabled", param);
- }
- }
- else if (action == TopMenuAction_SelectOption)
- {
- GOKZ_CycleOption(param, TIPS_OPTION_NAME);
- gTM_Options.Display(param, TopMenuPosition_LastCategory);
- }
-}
-
-
-
-// =====[ COMMANDS ]=====
-
-void RegisterCommands()
-{
- RegConsoleCmd("sm_tips", CommandToggleTips, "[KZ] Toggle seeing help and tips.");
-}
-
-public Action CommandToggleTips(int client, int args)
-{
- if (GOKZ_GetOption(client, TIPS_OPTION_NAME) == Tips_Disabled)
- {
- GOKZ_SetOption(client, TIPS_OPTION_NAME, Tips_Enabled);
- }
- else
- {
- GOKZ_SetOption(client, TIPS_OPTION_NAME, Tips_Disabled);
- }
- return Plugin_Handled;
-} \ No newline at end of file
diff --git a/source/sourcemod/scripting/include/dhooks.inc b/source/sourcemod/scripting/include/dhooks.inc
index 76ff8c4..5354b89 100644
--- a/source/sourcemod/scripting/include/dhooks.inc
+++ b/source/sourcemod/scripting/include/dhooks.inc
@@ -1,35 +1,3 @@
-/**
- * vim: set ts=4 sw=4 tw=99 noet :
- * =============================================================================
- * SourceMod (C)2021 AlliedModders LLC. All rights reserved.
- * =============================================================================
- *
- * This file is part of the SourceMod/SourcePawn SDK.
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, version 3.0, as published by the
- * Free Software Foundation.
- *
- * 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/>.
- *
- * As a special exception, AlliedModders LLC gives you permission to link the
- * code of this program (as well as its derivative works) to "Half-Life 2," the
- * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
- * by the Valve Corporation. You must obey the GNU General Public License in
- * all respects for all other code used. Additionally, AlliedModders LLC grants
- * this exception to all derivative works. AlliedModders LLC defines further
- * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
- * or <http://www.sourcemod.net/license.php>.
- *
- * Version: $Id$
- */
-
#if defined _dhooks_included
#endinput
#endif
@@ -70,8 +38,8 @@ enum ReturnType
ReturnType_Int,
ReturnType_Bool,
ReturnType_Float,
- ReturnType_String, // Note this is a string_t
- ReturnType_StringPtr, // Note this is a string_t *
+ ReturnType_String, //Note this is a string_t
+ ReturnType_StringPtr, //Note this is a string_t *
ReturnType_CharPtr,
ReturnType_Vector,
ReturnType_VectorPtr,
@@ -85,8 +53,8 @@ enum HookParamType
HookParamType_Int,
HookParamType_Bool,
HookParamType_Float,
- HookParamType_String, // Note this is a string_t
- HookParamType_StringPtr, // Note this is a string_t *
+ HookParamType_String, //Note this is a string_t
+ HookParamType_StringPtr, //Note this is a string_t *
HookParamType_CharPtr,
HookParamType_VectorPtr,
HookParamType_CBaseEntity,
@@ -119,34 +87,34 @@ enum CallingConvention
enum HookMode
{
- Hook_Pre, /**< Callback will be executed BEFORE the original function. */
- Hook_Post /**< Callback will be executed AFTER the original function. */
+ Hook_Pre, // Callback will be executed BEFORE the original function.
+ Hook_Post // Callback will be executed AFTER the original function.
};
enum MRESReturn
{
- MRES_ChangedHandled = -2, /**< Use changed values and return MRES_Handled */
- MRES_ChangedOverride, /**< Use changed values and return MRES_Override */
- MRES_Ignored, /**< plugin didn't take any action */
- MRES_Handled, /**< plugin did something, but real function should still be called */
- MRES_Override, /**< call real function, but use my return value */
- MRES_Supercede /**< skip real function; use my return value */
+ MRES_ChangedHandled = -2, // Use changed values and return MRES_Handled
+ MRES_ChangedOverride, // Use changed values and return MRES_Override
+ MRES_Ignored, // plugin didn't take any action
+ MRES_Handled, // plugin did something, but real function should still be called
+ MRES_Override, // call real function, but use my return value
+ MRES_Supercede // skip real function; use my return value
};
enum DHookPassFlag
{
- DHookPass_ByVal = (1<<0), /**< Passing by value */
- DHookPass_ByRef = (1<<1), /**< Passing by reference */
- DHookPass_ODTOR = (1<<2), /**< Object has a destructor */
- DHookPass_OCTOR = (1<<3), /**< Object has a constructor */
- DHookPass_OASSIGNOP = (1<<4), /**< Object has an assignment operator */
+ DHookPass_ByVal = (1<<0), /**< Passing by value */
+ DHookPass_ByRef = (1<<1), /**< Passing by reference */
+ DHookPass_ODTOR = (1<<2), /**< Object has a destructor */
+ DHookPass_OCTOR = (1<<3), /**< Object has a constructor */
+ DHookPass_OASSIGNOP = (1<<4), /**< Object has an assignment operator */
};
enum DHookRegister
{
// Don't change the register and use the default for the calling convention.
DHookRegister_Default,
-
+
// 8-bit general purpose registers
DHookRegister_AL,
DHookRegister_CL,
@@ -156,7 +124,7 @@ enum DHookRegister
DHookRegister_CH,
DHookRegister_DH,
DHookRegister_BH,
-
+
// 32-bit general purpose registers
DHookRegister_EAX,
DHookRegister_ECX,
@@ -166,7 +134,7 @@ enum DHookRegister
DHookRegister_EBP,
DHookRegister_ESI,
DHookRegister_EDI,
-
+
// 128-bit XMM registers
DHookRegister_XMM0,
DHookRegister_XMM1,
@@ -176,17 +144,17 @@ enum DHookRegister
DHookRegister_XMM5,
DHookRegister_XMM6,
DHookRegister_XMM7,
-
+
// 80-bit FPU registers
DHookRegister_ST0
};
typeset ListenCB
{
- // Deleted
+ //Deleted
function void (int entity);
-
- // Created
+
+ //Created
function void (int entity, const char[] classname);
};
@@ -194,47 +162,46 @@ typeset DHookRemovalCB
{
function void (int hookid);
};
-
typeset DHookCallback
{
- // Function Example: void Ham::Test() with this pointer ignore
+ //Function Example: void Ham::Test() with this pointer ignore
function MRESReturn ();
-
- // Function Example: void Ham::Test() with this pointer passed
+
+ //Function Example: void Ham::Test() with this pointer passed
function MRESReturn (int pThis);
-
- // Function Example: void Ham::Test(int cake) with this pointer ignore
+
+ //Function Example: void Ham::Test(int cake) with this pointer ignore
function MRESReturn (DHookParam hParams);
-
- // Function Example: void Ham::Test(int cake) with this pointer passed
+
+ //Function Example: void Ham::Test(int cake) with this pointer passed
function MRESReturn (int pThis, DHookParam hParams);
-
- // Function Example: int Ham::Test() with this pointer ignore
+
+ //Function Example: int Ham::Test() with this pointer ignore
function MRESReturn (DHookReturn hReturn);
-
- // Function Example: int Ham::Test() with this pointer passed
+
+ //Function Example: int Ham::Test() with this pointer passed
function MRESReturn (int pThis, DHookReturn hReturn);
-
- // Function Example: int Ham::Test(int cake) with this pointer ignore
+
+ //Function Example: int Ham::Test(int cake) with this pointer ignore
function MRESReturn (DHookReturn hReturn, DHookParam hParams);
-
- // Function Example: int Ham::Test(int cake) with this pointer passed
+
+ //Function Example: int Ham::Test(int cake) with this pointer passed
function MRESReturn (int pThis, DHookReturn hReturn, DHookParam hParams);
-
- // Address NOW
-
- // Function Example: void Ham::Test() with this pointer passed
+
+ //Address NOW
+
+ //Function Example: void Ham::Test() with this pointer passed
function MRESReturn (Address pThis);
-
- // Function Example: void Ham::Test(int cake) with this pointer passed
+
+ //Function Example: void Ham::Test(int cake) with this pointer passed
function MRESReturn (Address pThis, DHookParam hParams);
-
- // Function Example: int Ham::Test() with this pointer passed
+
+ //Function Example: int Ham::Test() with this pointer passed
function MRESReturn (Address pThis, DHookReturn hReturn);
-
- // Function Example: int Ham::Test(int cake) with this pointer passed
+
+ //Function Example: int Ham::Test(int cake) with this pointer passed
function MRESReturn (Address pThis, DHookReturn hReturn, DHookParam hParams);
-
+
};
// Represents the parameters of the hooked function.
@@ -266,15 +233,13 @@ methodmap DHookParam < Handle
// @param num Parameter number to get, starting at 1.
// @param buffer String buffer to store result.
// @param size Buffer size.
- //
+ //
// @error Invalid handle, invalid param number or invalid param type.
public native void GetString(int num, char[] buffer, int size);
// Set the value of a parameter.
// Use only for: int, entity, edict, bool or float parameter types.
//
- // An entity parameter type can be set to NULL using INVALID_ENT_REFERENCE (-1).
- //
// The changes are only applied when MRES_ChangedHandled or MRES_ChangedOverride
// is returned in the callback.
//
@@ -371,18 +336,9 @@ methodmap DHookParam < Handle
//
// @param num Parameter number to check, starting at 1.
//
- // @return true if null, false otherwise.
+ // @return True if null, false otherwise.
// @error Non-pointer parameter.
public native bool IsNull(int num);
-
- // Get param address (Use only for ptr param types)
- //
- // @param num Param number to get. (Example if the function has 2 params and you need the value
- // of the first param num would be 1.)
- //
- // @return Address of the parameter.
- // @error Invalid handle. Invalid param number. Invalid param type.
- public native Address GetAddress(int num);
};
@@ -392,8 +348,6 @@ methodmap DHookReturn < Handle
// Retrieves or sets the return value.
// Use only for: int, entity, edict, bool or float return types.
//
- // An entity return type can be set to NULL using INVALID_ENT_REFERENCE (-1).
- //
// The return value is only readable in a post hook.
// The value is only applied when MRES_Override or MRES_Supercede is returned
// in the callback.
@@ -455,7 +409,7 @@ methodmap DHookSetup < Handle
// @param source Whether to look in Offsets, Signatures, or Addresses.
// @param name Name of the property to find.
//
- // @return true on success, false if nothing was found.
+ // @return True on success, false if nothing was found.
// @error Invalid setup or gamedata handle.
public native bool SetFromConf(Handle gameconf, SDKFuncConfSource source, const char[] name);
@@ -465,7 +419,7 @@ methodmap DHookSetup < Handle
// @param size Used for Objects (not Object ptr) to define the size of the object.
// @param flag Used to change the pass type (ignored by detours).
// @param custom_register The register this argument is passed in instead of the stack (ignored by vhooks).
- //
+ //
// @error Invalid setup handle or too many params added (request upping the max in thread).
public native void AddParam(HookParamType type, int size=-1, DHookPassFlag flag=DHookPass_ByVal, DHookRegister custom_register=DHookRegister_Default);
};
@@ -473,7 +427,7 @@ methodmap DHookSetup < Handle
// A DynamicHook allows to hook a virtual function on any C++ object.
// Currently CBaseEntity and CGameRules have a convenience API for easy entity hooking,
// but it's possible to provide a raw this-pointer to hook any object in memory too.
-//
+//
// Internally this intercepts function calls by replacing the function pointer
// in the virtual table of the object with our own function.
methodmap DynamicHook < DHookSetup
@@ -484,7 +438,7 @@ methodmap DynamicHook < DHookSetup
// @param hooktype Type of hook.
// @param returntype Type of return value.
// @param thistype Type of this pointer or ignore (ignore can be used if not needed).
- //
+ //
// @error Failed to create hook setup handle or invalid callback function.
public native DynamicHook(int offset, HookType hooktype, ReturnType returntype, ThisPointerType thistype);
@@ -506,14 +460,14 @@ methodmap DynamicHook < DHookSetup
// If you need to read the return value of the function, choose a post hook.
//
// @param mode The desired hook mode - pre or post.
- // A pre hook calls your callback BEFORE the original function is called.
+ // A pre hook calls your callback BEFORE the original function is called.
// You can access the parameters, set the return value, and skip the original function.
// A post hook calls your callback AFTER the original function executed.
// You can access the parameters and get/set the return value.
// @param entity Entity index to hook on.
// @param callback Callback function.
// @param removalcb Optional callback for when the hook is removed.
- //
+ //
// @return A hookid on success, INVALID_HOOK_ID otherwise.
// @error Invalid setup handle, invalid address, invalid hook type or invalid callback.
public native int HookEntity(HookMode mode, int entity, DHookCallback callback, DHookRemovalCB removalcb=INVALID_FUNCTION);
@@ -524,13 +478,13 @@ methodmap DynamicHook < DHookSetup
// If you need to read the return value of the function, choose a post hook.
//
// @param mode The desired hook mode - pre or post.
- // A pre hook calls your callback BEFORE the original function is called.
+ // A pre hook calls your callback BEFORE the original function is called.
// You can access the parameters, set the return value, and skip the original function.
// A post hook calls your callback AFTER the original function executed.
// You can access the parameters and get/set the return value.
// @param callback Callback function.
// @param removalcb Optional callback for when the hook is removed.
- //
+ //
// @return A hookid on success, INVALID_HOOK_ID otherwise.
// @error Invalid setup handle, invalid address, invalid hook type or invalid callback.
public native int HookGamerules(HookMode mode, DHookCallback callback, DHookRemovalCB removalcb=INVALID_FUNCTION);
@@ -539,22 +493,23 @@ methodmap DynamicHook < DHookSetup
// If you need to read the return value of the function, choose a post hook.
//
// @param mode The desired hook mode - pre or post.
- // A pre hook calls your callback BEFORE the original function is called.
+ // A pre hook calls your callback BEFORE the original function is called.
// You can access the parameters, set the return value, and skip the original function.
// A post hook calls your callback AFTER the original function executed.
// You can access the parameters and get/set the return value.
// @param addr This pointer address.
// @param callback Callback function.
- //
+ //
// @return A hookid on success, INVALID_HOOK_ID otherwise.
// @error Invalid setup handle, invalid address, invalid hook type or invalid callback.
public native int HookRaw(HookMode mode, Address addr, DHookCallback callback);
- // Remove hook by hook id.
- //
+ // Remove hook by hook id:
+ // This will NOT fire the removal callback!
+ //
// @param hookid Hook id to remove.
- //
- // @return true on success, false otherwise
+ //
+ // @return True on success, false otherwise
public static native bool RemoveHook(int hookid);
};
@@ -566,7 +521,7 @@ methodmap DynamicHook < DHookSetup
// Internally this works by replacing the first instructions of the function
// with a jump to our own code. This means that the signature used to find
// the function address in the first place might not match anymore after a detour.
-// If you need to detour the same function in different plugins make sure to
+// If you need to detour the same function in different plugins make sure to
// wildcard \x2a the first 6 bytes of the signature to accommodate for the patched
// jump introduced by the detour.
methodmap DynamicDetour < DHookSetup
@@ -599,13 +554,13 @@ methodmap DynamicDetour < DHookSetup
// If you need to read the return value of the function, choose a post hook.
//
// @param mode The desired hook mode - pre or post.
- // A pre hook calls your callback BEFORE the original function is called.
+ // A pre hook calls your callback BEFORE the original function is called.
// You can access the parameters, set the return value, and skip the original function.
// A post hook calls your callback AFTER the original function executed.
// You can access the parameters and get/set the return value.
// @param callback Callback function.
//
- // @return true if detour was enabled, false otherwise.
+ // @return True if detour was enabled, false otherwise.
// @error Hook handle is not setup for a detour.
public native bool Enable(HookMode mode, DHookCallback callback);
@@ -614,405 +569,367 @@ methodmap DynamicDetour < DHookSetup
// @param mode The hook mode to disable - pre or post.
// @param callback Callback function.
//
- // @return true if detour was disabled, false otherwise.
+ // @return True if detour was disabled, false otherwise.
// @error Hook handle is not setup for a detour or function is not detoured.
public native bool Disable(HookMode mode, DHookCallback callback);
};
-/**
- * Adds an entity listener hook
+/* Adds an entity listener hook
*
- * @param type Type of listener to add
- * @param callback Callback to use
- */
+ * @param type Type of listener to add
+ * @param callback Callback to use
+ *
+ * @noreturn
+*/
native void DHookAddEntityListener(ListenType type, ListenCB callback);
-/**
- * Removes an entity listener hook
+/* Removes an entity listener hook
*
- * @param type Type of listener to remove
- * @param callback Callback this listener was using
+ * @param type Type of listener to remove
+ * @param callback Callback this listener was using
*
- * @return true if one was removed, false otherwise
- */
+ * @return True if one was removed false otherwise.
+*/
native bool DHookRemoveEntityListener(ListenType type, ListenCB callback);
-/**
- * Creates a hook
- *
- * @param offset vtable offset of function to hook
- * @param hooktype Type of hook
- * @param returntype Type of return value
- * @param thistype Type of this pointer or ignore (ignore can be used if not needed)
- * @param callback Optional callback function, if not set here must be set when hooking.
+/* Creates a hook
*
- * @return Returns setup handle for the hook.
- * @error Failed to create hook setup handle or invalid callback function.
- */
+ * @param offset vtable offset of function to hook
+ * @param hooktype Type of hook
+ * @param returntype Type of return value
+ * @param thistype Type of this pointer or ignore (ignore can be used if not needed)
+ * @param callback Optional callback function, if not set here must be set when hooking.
+ *
+ * @return Returns setup handle for the hook.
+ * @error Failed to create hook setup handle or invalid callback function.
+*/
native DynamicHook DHookCreate(int offset, HookType hooktype, ReturnType returntype, ThisPointerType thistype, DHookCallback callback=INVALID_FUNCTION);
/**
* Creates a detour
*
- * @param funcaddr The address of the function to detour.
- * Can be Address_Null if you want to load the address from gamedata using DHookSetFromConf.
- * @param callConv Calling convention of the function.
- * @param returnType Type of the return value.
- * @param thisType Type of this pointer or ignore (ignore can be used if not needed)
+ * @param funcaddr The address of the function to detour.
+ * Can be Address_Null if you want to load the address from gamedata using DHookSetFromConf.
+ * @param callConv Calling convention of the function.
+ * @param returnType Type of the return value.
+ * @param thisType Type of this pointer or ignore (ignore can be used if not needed)
*
- * @return Setup handle for the detour.
- * @error Failed to create detour setup handle.
- */
+ * @return Setup handle for the detour.
+ * @error Failed to create detour setup handle.
+ */
native DynamicDetour DHookCreateDetour(Address funcaddr, CallingConvention callConv, ReturnType returntype, ThisPointerType thisType);
/**
* Setup a detour or hook for a function as described in a "Functions" section in gamedata.
*
- * @param gameconf GameConfig handle
- * @param name Name of the function in the gamedata to load.
+ * @param gameconf GameConfig handle
+ * @param name Name of the function in the gamedata to load.
*
- * @return Setup handle for the detour or INVALID_HANDLE if offset/signature/address wasn't found.
- * @error Failed to create detour setup handle, invalid gamedata handle, invalid callback function or
- * failed to find function in gamedata.
+ * @return Setup handle for the detour or INVALID_HANDLE if offset/signature/address wasn't found.
+ * @error Failed to create detour setup handle, invalid gamedata handle, invalid callback function or failed to find function in gamedata.
*/
native DHookSetup DHookCreateFromConf(Handle gameconf, const char[] name);
/**
* Load details for a vhook or detour from a gamedata file.
*
- * @param setup Hook setup handle to set the offset or address on.
- * @param gameconf GameConfig handle
- * @param source Whether to look in Offsets or Signatures.
- * @param name Name of the property to find.
+ * @param setup Hook setup handle to set the offset or address on.
+ * @param gameconf GameConfig handle
+ * @param source Whether to look in Offsets or Signatures.
+ * @param name Name of the property to find.
*
- * @return true on success, false if nothing was found.
- * @error Invalid setup or gamedata handle.
+ * @return True on success, false if nothing was found.
+ * @error Invalid setup or gamedata handle.
*/
native bool DHookSetFromConf(Handle setup, Handle gameconf, SDKFuncConfSource source, const char[] name);
/**
* Enable the detour of the function described in the hook setup handle.
*
- * @param setup Hook setup handle
- * @param post true to make the hook a post hook. (If you need to change the return value or need the return
- * value use a post hook! If you need to change params and return use a pre and post hook!)
- * @param callback Callback function
+ * @param setup Hook setup handle
+ * @param post True to make the hook a post hook. (If you need to change the retunr value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
+ * @param callback Callback function
*
- * @return true if detour was enabled, false otherwise.
- * @error Hook handle is not setup for a detour.
+ * @return True if detour was enabled, false otherwise.
+ * @error Hook handle is not setup for a detour.
*/
native bool DHookEnableDetour(Handle setup, bool post, DHookCallback callback);
/**
* Disable the detour of the function described in the hook setup handle.
*
- * @param setup Hook setup handle
- * @param post true to disable a post hook.
- * @param callback Callback function
+ * @param setup Hook setup handle
+ * @param post True to disable a post hook.
+ * @param callback Callback function
*
- * @return true if detour was disabled, false otherwise.
- * @error Hook handle is not setup for a detour or function is not detoured.
+ * @return True if detour was disabled, false otherwise.
+ * @error Hook handle is not setup for a detour or function is not detoured.
*/
native bool DHookDisableDetour(Handle setup, bool post, DHookCallback callback);
-/**
- * Adds param to a hook setup
- *
- * @param setup Setup handle to add the param to.
- * @param type Param type
- * @param size Used for Objects (not Object ptr) to define the size of the object.
- * @param flag Used to change the pass type.
- * @param custom_register The register this argument is passed in instead of the stack.
+/* Adds param to a hook setup
*
- * @error Invalid setup handle or too many params added (request upping the max in thread)
- */
+ * @param setup Setup handle to add the param to.
+ * @param type Param type
+ * @param size Used for Objects (not Object ptr) to define the size of the object.
+ * @param flag Used to change the pass type.
+ * @param custom_register The register this argument is passed in instead of the stack.
+ *
+ * @error Invalid setup handle or too many params added (request upping the max in thread)
+ * @noreturn
+*/
native void DHookAddParam(Handle setup, HookParamType type, int size=-1, DHookPassFlag flag=DHookPass_ByVal, DHookRegister custom_register=DHookRegister_Default);
-/**
- * Hook entity
- *
- * @param setup Setup handle to use to add the hook.
- * @param post true to make the hook a post hook. (If you need to change the return value or need the return
- * value use a post hook! If you need to change params and return use a pre and post hook!)
- * @param entity Entity index to hook on.
- * @param removalcb Callback for when the hook is removed (Entity hooks are auto-removed on entity destroyed and
- * will call this callback)
- * @param callback Optional callback function, if not set here must be set when creating the hook.
- *
- * @return INVALID_HOOK_ID on fail a hookid on success
- * @error Invalid setup handle, invalid address, invalid hook type or invalid callback.
- */
+/* Hook entity
+ *
+ * @param setup Setup handle to use to add the hook.
+ * @param post True to make the hook a post hook. (If you need to change the return value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
+ * @param entity Entity index to hook on.
+ * @param removalcb Callback for when the hook is removed (Entity hooks are auto-removed on entity destroyed and will call this callback)
+ * @param callback Optional callback function, if not set here must be set when creating the hook.
+ *
+ * @error Invalid setup handle, invalid address, invalid hook type or invalid callback.
+ * @return INVALID_HOOK_ID on fail a hookid on success
+*/
native int DHookEntity(Handle setup, bool post, int entity, DHookRemovalCB removalcb=INVALID_FUNCTION, DHookCallback callback=INVALID_FUNCTION);
-/**
- * Hook gamerules
- *
- * @param setup Setup handle to use to add the hook.
- * @param post true to make the hook a post hook. (If you need to change the return value or need the return
- * value use a post hook! If you need to change params and return use a pre and post hook!)
- * @param removalcb Callback for when the hook is removed (Game rules hooks are auto-removed on map end and will
- * call this callback)
- * @param callback Optional callback function, if not set here must be set when creating the hook.
- *
- * @return INVALID_HOOK_ID on fail a hookid on success
- * @error Invalid setup handle, invalid address, invalid hook type or invalid callback.
- */
+/* Hook gamerules
+ *
+ * @param setup Setup handle to use to add the hook.
+ * @param post True to make the hook a post hook. (If you need to change the return value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
+ * @param removalcb Callback for when the hook is removed (Game rules hooks are auto-removed on map end and will call this callback)
+ * @param callback Optional callback function, if not set here must be set when creating the hook.
+ *
+ * @error Invalid setup handle, invalid address, invalid hook type or invalid callback.
+ * @return INVALID_HOOK_ID on fail a hookid on success
+*/
native int DHookGamerules(Handle setup, bool post, DHookRemovalCB removalcb=INVALID_FUNCTION, DHookCallback callback=INVALID_FUNCTION);
-/**
- * Hook a raw pointer
- *
- * @param setup Setup handle to use to add the hook.
- * @param post true to make the hook a post hook. (If you need to change the return value or need the return
- * alue use a post hook! If you need to change params and return use a pre and post hook!)
- * @param addr This pointer address.
- * @param removalcb Callback for when the hook is removed (Entity hooks are auto-removed on entity destroyed and
- * will call this callback)
- * @param callback Optional callback function, if not set here must be set when creating the hook.
- *
- * @return INVALID_HOOK_ID on fail a hookid on success
- * @error Invalid setup handle, invalid address, invalid hook type or invalid callback.
- */
+/* Hook a raw pointer
+ *
+ * @param setup Setup handle to use to add the hook.
+ * @param post True to make the hook a post hook. (If you need to change the return value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
+ * @param addr This pointer address.
+ * @param removalcb Callback for when the hook is removed (Entity hooks are auto-removed on entity destroyed and will call this callback)
+ * @param callback Optional callback function, if not set here must be set when creating the hook.
+ *
+ * @error Invalid setup handle, invalid address, invalid hook type or invalid callback.
+ * @return INVALID_HOOK_ID on fail a hookid on success
+*/
native int DHookRaw(Handle setup, bool post, Address addr, DHookRemovalCB removalcb=INVALID_FUNCTION, DHookCallback callback=INVALID_FUNCTION);
-/**
- * Remove hook by hook id
- *
- * @param hookid Hook id to remove
- *
- * @return true on success, false otherwise
- */
+/* Remove hook by hook id
+ *
+ * @param hookid Hook id to remove
+ *
+ * @return true on success false otherwise
+ * @note This will not fire the removal callback!
+*/
native bool DHookRemoveHookID(int hookid);
-/**
- * Get param value (Use only for: int, entity, edict, bool or float param types)
- *
- * @param hParams Handle to params structure
- * @param num Param number to get. (Example if the function has 2 params and you need the value of the first
- * param num would be 1. 0 Will return the number of params stored)
- *
- * @return value if num greater than 0. If 0 returns paramcount.
- * @error Invalid handle. Invalid param number. Invalid param type.
- */
+/* Get param value (Use only for: int, entity, bool or float param types)
+ *
+ * @param hParams Handle to params structure
+ * @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1. 0 Will return the number of params stored)
+ *
+ * @error Invalid handle. Invalid param number. Invalid param type.
+ * @return value if num greater than 0. If 0 returns paramcount.
+*/
native any DHookGetParam(Handle hParams, int num);
-/**
- * Get vector param value
- *
- * @param hParams Handle to params structure
- * @param num Param number to get. (Example if the function has 2 params and you need the value of the first
- * param num would be 1.)
- * @param vec Vector buffer to store result.
- *
- * @error Invalid handle. Invalid param number. Invalid param type.
- */
+/* Get vector param value
+ *
+ * @param hParams Handle to params structure
+ * @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1.)
+ * @param vec Vector buffer to store result.
+ *
+ * @error Invalid handle. Invalid param number. Invalid param type.
+ * @noreturn
+*/
native void DHookGetParamVector(Handle hParams, int num, float vec[3]);
-/**
- * Get string param value
- *
- * @param hParams Handle to params structure
- * @param num Param number to get. (Example if the function has 2 params and you need the value of the first
- * param num would be 1.)
- * @param buffer String buffer to store result
- * @param size Buffer size
- *
- * @error Invalid handle. Invalid param number. Invalid param type.
- */
+/* Get string param value
+ *
+ * @param hParams Handle to params structure
+ * @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1.)
+ * @param buffer String buffer to store result
+ * @param size Buffer size
+ *
+ * @error Invalid handle. Invalid param number. Invalid param type.
+ * @noreturn
+*/
native void DHookGetParamString(Handle hParams, int num, char[] buffer, int size);
-/**
- * Set param value (Use only for: int, entity, edict, bool or float param types)
- *
- * An entity param type can be set to NULL using INVALID_ENT_REFERENCE (-1).
- *
- * @param hParams Handle to params structure
- * @param num Param number to set (Example if the function has 2 params and you need to set the value of the
- * first param num would be 1.)
- * @param value Value to set it as (only pass int, bool, float or entity index)
- *
- * @error Invalid handle. Invalid param number. Invalid param type.
- */
+/* Set param value (Use only for: int, entity, bool or float param types)
+ *
+ * @param hParams Handle to params structure
+ * @param num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
+ * @param value Value to set it as (only pass int, bool, float or entity index)
+ *
+ * @error Invalid handle. Invalid param number. Invalid param type.
+ * @noreturn
+*/
native void DHookSetParam(Handle hParams, int num, any value);
-/**
- * Set vector param value
- *
- * @param hParams Handle to params structure
- * @param num Param number to set (Example if the function has 2 params and you need to set the value of the
- * first param num would be 1.)
- * @param vec Value to set vector as.
- *
- * @error Invalid handle. Invalid param number. Invalid param type.
- */
+/* Set vector param value
+ *
+ * @param hParams Handle to params structure
+ * @param num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
+ * @param vec Value to set vector as.
+ *
+ * @error Invalid handle. Invalid param number. Invalid param type.
+ * @noreturn
+*/
native void DHookSetParamVector(Handle hParams, int num, float vec[3]);
-/**
- * Set string param value
- *
- * @param hParams Handle to params structure
- * @param num Param number to set (Example if the function has 2 params and you need to set the value of the
- * first param num would be 1.)
- * @param value Value to set string as.
- *
- * @error Invalid handle. Invalid param number. Invalid param type.
- */
+/* Set string param value
+ *
+ * @param hParams Handle to params structure
+ * @param num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
+ * @param value Value to set string as.
+ *
+ * @error Invalid handle. Invalid param number. Invalid param type.
+ * @noreturn
+*/
native void DHookSetParamString(Handle hParams, int num, char[] value);
-/**
- * Get return value (Use only for: int, entity, bool or float return types)
- *
- * @param hReturn Handle to return structure
- *
- * @error Invalid Handle, invalid type.
- * @return Returns default value if prehook returns actual value if post hook.
- */
+/* Get return value (Use only for: int, entity, bool or float return types)
+ *
+ * @param hReturn Handle to return structure
+ *
+ * @error Invalid Handle, invalid type.
+ * @return Returns default value if prehook returns actual value if post hook.
+*/
native any DHookGetReturn(Handle hReturn);
-/**
- * Get return vector value
- *
- * @param hReturn Handle to return structure
- * @param vec Vector buffer to store result in. (In pre hooks will be default value (0.0,0.0,0.0))
- *
- * @error Invalid Handle, invalid type.
- */
+/* Get return vector value
+ *
+ * @param hReturn Handle to return structure
+ * @param vec Vector buffer to store result in. (In pre hooks will be default value (0.0,0.0,0.0))
+ *
+ * @error Invalid Handle, invalid type.
+ * @noreturn
+*/
native void DHookGetReturnVector(Handle hReturn, float vec[3]);
-/**
- * Get return string value
- *
- * @param hReturn Handle to return structure
- * @param buffer String buffer to store result in. (In pre hooks will be default value "")
- * @param size String buffer size
- *
- * @error Invalid Handle, invalid type.
- */
+/* Get return string value
+ *
+ * @param hReturn Handle to return structure
+ * @param buffer String buffer to store result in. (In pre hooks will be default value "")
+ * @param size String buffer size
+ *
+ * @error Invalid Handle, invalid type.
+ * @noreturn
+*/
native void DHookGetReturnString(Handle hReturn, char[] buffer, int size);
-/**
- * Set return value (Use only for: int, entity, bool or float return types)
- *
- * An entity return type can be set to NULL using INVALID_ENT_REFERENCE (-1).
- *
- * @param hReturn Handle to return structure
- * @param value Value to set return as
- *
- * @error Invalid Handle, invalid type.
- */
+/* Set return value (Use only for: int, entity, bool or float return types)
+ *
+ * @param hReturn Handle to return structure
+ * @param value Value to set return as
+ *
+ * @error Invalid Handle, invalid type.
+ * @noreturn
+*/
native void DHookSetReturn(Handle hReturn, any value);
-/**
- * Set return vector value
- *
- * @param hReturn Handle to return structure
- * @param vec Value to set return vector as
- *
- * @error Invalid Handle, invalid type.
- */
+/* Set return vector value
+ *
+ * @param hReturn Handle to return structure
+ * @param vec Value to set return vector as
+ *
+ * @error Invalid Handle, invalid type.
+ * @noreturn
+*/
native void DHookSetReturnVector(Handle hReturn, float vec[3]);
-/**
- * Set return string value
- *
- * @param hReturn Handle to return structure
- * @param value Value to set return string as
- *
- * @error Invalid Handle, invalid type.
- */
+/* Set return string value
+ *
+ * @param hReturn Handle to return structure
+ * @param value Value to set return string as
+ *
+ * @error Invalid Handle, invalid type.
+ * @noreturn
+*/
native void DHookSetReturnString(Handle hReturn, char[] value);
//WE SHOULD WRAP THESE AROUND STOCKS FOR NON PTR AS WE SUPPORT BOTH WITH THESE NATIVE'S
-/**
- * Gets an objects variable value
+/* Gets an objects variable value
*
- * @param hParams Handle to params structure
- * @param num Param number to get.
- * @param offset Offset within the object to the var to get.
- * @param type Type of var it is
+ * @param hParams Handle to params structure
+ * @param num Param number to get.
+ * @param offset Offset within the object to the var to get.
+ * @param type Type of var it is
*
- * @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
- * @return Value of the objects var. If EHANDLE type or entity returns entity index.
- */
+ * @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
+ * @return Value of the objects var. If EHANDLE type or entity returns entity index.
+*/
native any DHookGetParamObjectPtrVar(Handle hParams, int num, int offset, ObjectValueType type);
-/**
- * Sets an objects variable value
+/* Sets an objects variable value
*
- * @param hParams Handle to params structure
- * @param num Param number to set.
- * @param offset Offset within the object to the var to set.
- * @param type Type of var it is
- * @param value The value to set the var to.
+ * @param hParams Handle to params structure
+ * @param num Param number to set.
+ * @param offset Offset within the object to the var to set.
+ * @param type Type of var it is
+ * @param value The value to set the var to.
*
- * @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
- */
+ * @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
+ * @noreturn
+*/
native void DHookSetParamObjectPtrVar(Handle hParams, int num, int offset, ObjectValueType type, any value);
-/**
- * Gets an objects vector variable value
+/* Gets an objects vector variable value
*
- * @param hParams Handle to params structure
- * @param num Param number to get.
- * @param offset Offset within the object to the var to get.
- * @param type Type of var it is
- * @param buffer Buffer to store the result vector
+ * @param hParams Handle to params structure
+ * @param num Param number to get.
+ * @param offset Offset within the object to the var to get.
+ * @param type Type of var it is
+ * @param buffer Buffer to store the result vector
*
- * @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
- */
+ * @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
+ * @noreturn
+*/
native void DHookGetParamObjectPtrVarVector(Handle hParams, int num, int offset, ObjectValueType type, float buffer[3]);
-/**
- * Sets an objects vector variable value
+/* Sets an objects vector variable value
*
- * @param hParams Handle to params structure
- * @param num Param number to set.
- * @param offset Offset within the object to the var to set.
- * @param type Type of var it is
- * @param value The value to set the vector var to.
+ * @param hParams Handle to params structure
+ * @param num Param number to set.
+ * @param offset Offset within the object to the var to set.
+ * @param type Type of var it is
+ * @param value The value to set the vector var to.
*
- * @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
- */
+ * @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
+ * @noreturn
+*/
native void DHookSetParamObjectPtrVarVector(Handle hParams, int num, int offset, ObjectValueType type, float value[3]);
-/**
- * Gets an objects string variable value
+/* Gets an objects string variable value
*
- * @param hParams Handle to params structure
- * @param num Param number to get.
- * @param offset Offset within the object to the var to get.
- * @param type Type of var it is
- * @param buffer Buffer to store the result vector
- * @param size Size of the buffer
+ * @param hParams Handle to params structure
+ * @param num Param number to get.
+ * @param offset Offset within the object to the var to get.
+ * @param type Type of var it is
+ * @param buffer Buffer to store the result vector
+ * @param size Size of the buffer
*
- * @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
- */
+ * @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
+ * @noreturn
+*/
native void DHookGetParamObjectPtrString(Handle hParams, int num, int offset, ObjectValueType type, char[] buffer, int size);
-/**
- * Checks if a pointer param is null
+/* Checks if a pointer param is null
*
- * @param hParams Handle to params structure
- * @param num Param number to check.
+ * @param hParams Handle to params structure
+ * @param num Param number to check.
*
- * @return true if null, false otherwise.
- * @error Non pointer param
- */
+ * @error Non pointer param
+ * @return True if null false otherwise.
+*/
native bool DHookIsNullParam(Handle hParams, int num);
-/**
- * Get param address (Use only for ptr param types)
- *
- * @param hParams Handle to params structure
- * @param num Param number to get. (Example if the function has 2 params and you need the value of the first
- * param num would be 1.)
- *
- * @return Address of the parameter.
- * @error Invalid handle. Invalid param number. Invalid param type.
- */
-native Address DHookGetParamAddress(Handle hParams, int num);
-
public Extension __ext_dhooks =
{
name = "dhooks",
@@ -1063,7 +980,6 @@ public __ext_dhooks_SetNTVOptional()
MarkNativeAsOptional("DHookSetParamObjectPtrVarVector");
MarkNativeAsOptional("DHookIsNullParam");
MarkNativeAsOptional("DHookGetParamObjectPtrString");
- MarkNativeAsOptional("DHookGetParamAddress");
MarkNativeAsOptional("DHookParam.IsNull");
MarkNativeAsOptional("DHookParam.Get");
@@ -1077,7 +993,6 @@ public __ext_dhooks_SetNTVOptional()
MarkNativeAsOptional("DHookParam.GetObjectVarString");
MarkNativeAsOptional("DHookParam.SetObjectVar");
MarkNativeAsOptional("DHookParam.SetObjectVarVector");
- MarkNativeAsOptional("DHookParam.GetAddress");
MarkNativeAsOptional("DHookReturn.Value.get");
MarkNativeAsOptional("DHookReturn.Value.set");
MarkNativeAsOptional("DHookReturn.GetVector");
@@ -1097,4 +1012,4 @@ public __ext_dhooks_SetNTVOptional()
MarkNativeAsOptional("DynamicDetour.Enable");
MarkNativeAsOptional("DynamicDetour.Disable");
}
-#endif
+#endif \ No newline at end of file
diff --git a/source/sourcemod/scripting/include/gokz.inc b/source/sourcemod/scripting/include/gokz.inc
index edbd896..6e41ed1 100644
--- a/source/sourcemod/scripting/include/gokz.inc
+++ b/source/sourcemod/scripting/include/gokz.inc
@@ -769,7 +769,49 @@ stock bool GetValidSpawn(float origin[3], float angles[3])
{
// Return true if the spawn found is truly valid (not in the ground or out of bounds)
bool foundValidSpawn;
- bool searchCT;
+ bool searchCT = false;
+ float spawnOrigin[3];
+ float spawnAngles[3];
+ int spawnEntity = -1;
+ while (!foundValidSpawn)
+ {
+ if (searchCT)
+ {
+ spawnEntity = FindEntityByClassname(spawnEntity, "info_player_counterterrorist");
+ }
+ else
+ {
+ spawnEntity = FindEntityByClassname(spawnEntity, "info_player_terrorist");
+ }
+
+ if (spawnEntity != -1)
+ {
+ GetEntPropVector(spawnEntity, Prop_Data, "m_vecOrigin", spawnOrigin);
+ GetEntPropVector(spawnEntity, Prop_Data, "m_angRotation", spawnAngles);
+ if (IsSpawnValid(spawnOrigin))
+ {
+ origin = spawnOrigin;
+ angles = spawnAngles;
+ foundValidSpawn = true;
+ }
+ }
+ else if (!searchCT)
+ {
+ searchCT = true;
+ }
+ else
+ {
+ break;
+ }
+ }
+ return foundValidSpawn;
+}
+
+stock bool GetValidSpawnCT(float origin[3], float angles[3])
+{
+ // Return true if the spawn found is truly valid (not in the ground or out of bounds)
+ bool foundValidSpawn;
+ bool searchCT = true;
float spawnOrigin[3];
float spawnAngles[3];
int spawnEntity = -1;
diff --git a/source/sourcemod/scripting/include/movementapi.inc b/source/sourcemod/scripting/include/movementapi.inc
index 290c3f2..45ee263 100644
--- a/source/sourcemod/scripting/include/movementapi.inc
+++ b/source/sourcemod/scripting/include/movementapi.inc
@@ -660,4 +660,4 @@ public void __pl_movementapi_SetNTVOptional()
MarkNativeAsOptional("Movement_SetLandingOrigin");
MarkNativeAsOptional("Movement_SetLandingVelocity");
}
-#endif \ No newline at end of file
+#endif
diff --git a/source/sourcemod/scripting/movementapi.sp b/source/sourcemod/scripting/movementapi.sp
new file mode 100644
index 0000000..79862bf
--- /dev/null
+++ b/source/sourcemod/scripting/movementapi.sp
@@ -0,0 +1,239 @@
+#include <sourcemod>
+
+#include <sdkhooks>
+#include <dhooks>
+
+#include <movement>
+
+#pragma newdecls required
+#pragma semicolon 1
+
+
+
+public Plugin myinfo =
+{
+ name = "MovementAPI",
+ author = "DanZay",
+ description = "Provides API focused on player movement",
+ version = "2.4.2",
+ url = "https://github.com/danzayau/MovementAPI"
+};
+
+GameData gH_GameData;
+Handle gH_GetMaxSpeed;
+int gI_Cmdnum[MAXPLAYERS + 1];
+int gI_TickCount[MAXPLAYERS + 1];
+
+bool gB_Jumped[MAXPLAYERS + 1];
+bool gB_HitPerf[MAXPLAYERS + 1];
+float gF_NobugLandingOrigin[MAXPLAYERS + 1][3];
+float gF_LandingOrigin[MAXPLAYERS + 1][3];
+float gF_LandingVelocity[MAXPLAYERS + 1][3];
+int gI_LandingTick[MAXPLAYERS + 1];
+int gI_LandingCmdNum[MAXPLAYERS + 1];
+float gF_TakeoffOrigin[MAXPLAYERS + 1][3];
+float gF_TakeoffVelocity[MAXPLAYERS + 1][3];
+int gI_TakeoffTick[MAXPLAYERS + 1];
+int gI_TakeoffCmdNum[MAXPLAYERS + 1];
+bool gB_Turning[MAXPLAYERS + 1];
+bool gB_TurningLeft[MAXPLAYERS + 1];
+
+float gF_OldOrigin[MAXPLAYERS + 1][3];
+float gF_OldVelocity[MAXPLAYERS + 1][3];
+float gF_OldEyeAngles[MAXPLAYERS + 1][3];
+bool gB_OldOnGround[MAXPLAYERS + 1];
+bool gB_OldDucking[MAXPLAYERS + 1];
+MoveType gMT_OldMovetype[MAXPLAYERS + 1];
+
+#include "movementapi/stocks.sp"
+#include "movementapi/hooks.sp"
+#include "movementapi/natives.sp"
+#include "movementapi/forwards.sp"
+
+public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
+{
+ CreateNatives();
+ RegPluginLibrary("movementapi");
+ return APLRes_Success;
+}
+
+public void OnPluginStart()
+{
+ HookEvents();
+ CreateGlobalForwards();
+ HookEvent("player_spawn", OnPlayerSpawn, EventHookMode_Post);
+ HookEvent("player_jump", OnPlayerJump, EventHookMode_Post);
+ for (int client = 1; client <= MaxClients; client++)
+ {
+ if (IsClientInGame(client))
+ {
+ OnClientPutInServer(client);
+ if (IsPlayerAlive(client))
+ {
+ ResetClientData(client);
+ }
+ }
+ }
+}
+
+void HookEvents()
+{
+ PrepSDKCalls();
+ HookGameMovementFunctions();
+}
+
+public void OnClientPutInServer(int client)
+{
+ SDKHook(client, SDKHook_PostThinkPost, OnPlayerPostThinkPost);
+}
+
+public void OnPlayerPostThinkPost(int client)
+{
+ if (!IsPlayerAlive(client))
+ {
+ return;
+ }
+
+ CheckGround(client);
+ float eyeAngles[3];
+ Movement_GetEyeAngles(client, eyeAngles);
+ UpdateTurning(client, gF_OldEyeAngles[client], eyeAngles);
+ gF_OldEyeAngles[client] = eyeAngles;
+
+ Movement_GetOrigin(client, gF_OldOrigin[client]);
+ Movement_GetVelocity(client, gF_OldVelocity[client]);
+ gB_OldOnGround[client] = Movement_GetOnGround(client);
+ gB_OldDucking[client] = gB_Ducking[client];
+ gMT_OldMovetype[client] = Movement_GetMovetype(client);
+ gB_OldWalkMoved[client] = gB_WalkMoved[client];
+}
+
+public void OnPlayerSpawn(Event event, const char[] name, bool dontBroadcast)
+{
+ int client = GetClientOfUserId(GetEventInt(event, "userid"));
+ ResetClientData(client);
+}
+
+public void OnPlayerJump(Event event, const char[] name, bool dontBroadcast)
+{
+ int client = GetClientOfUserId(GetEventInt(event, "userid"));
+ bool jumpbug = !gB_OldOnGround[client];
+ Call_OnPlayerJump(client, jumpbug);
+}
+
+public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
+{
+ CheckNoclip(client);
+ CheckGround(client);
+ gI_Cmdnum[client] = cmdnum;
+ gI_TickCount[client] = tickcount;
+ return Plugin_Continue;
+}
+
+float GetMaxSpeed(int client)
+{
+ return SDKCall(gH_GetMaxSpeed, client);
+}
+
+static void PrepSDKCalls()
+{
+ gH_GameData = LoadGameConfigFile("movementapi.games");
+ StartPrepSDKCall(SDKCall_Player);
+ PrepSDKCall_SetFromConf(gH_GameData, SDKConf_Virtual, "GetPlayerMaxSpeed");
+ PrepSDKCall_SetReturnInfo(SDKType_Float, SDKPass_ByValue);
+ gH_GetMaxSpeed = EndPrepSDKCall();
+}
+
+static void ResetClientData(int client)
+{
+ gB_Jumped[client] = false;
+ gB_HitPerf[client] = false;
+ gF_TakeoffOrigin[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gF_TakeoffVelocity[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gI_TakeoffTick[client] = 0;
+ gF_LandingOrigin[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gF_LandingVelocity[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gI_LandingTick[client] = 0;
+ gB_Turning[client] = false;
+ gB_TurningLeft[client] = false;
+
+ gF_OldOrigin[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gF_OldVelocity[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gF_OldEyeAngles[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gB_OldOnGround[client] = false;
+ gB_OldDucking[client] = false;
+ gMT_OldMovetype[client] = MOVETYPE_WALK;
+
+ gB_ProcessingLadderMove[client] = false;
+ gF_PreLadderMoveVelocity[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gB_TakeoffFromLadder[client] = false;
+ gF_PostLadderMoveOrigin[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gF_PostLadderMoveVelocity[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gB_ProcessingDuck[client] = false;
+ gF_PreLadderMoveVelocity[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gB_Ducking[client] = false;
+ gB_PrevOnGround[client] = false;
+ gB_Duckbugged[client] = false;
+ gF_PostDuckOrigin[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+
+ gB_Jumpbugged[client] = false;
+
+ gB_WalkMoved[client] = false;
+ gF_PostWalkMoveVelocity[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gF_PostAAOrigin[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+ gF_PostAAVelocity[client] = view_as<float>( { 0.0, 0.0, 0.0 } );
+
+ gB_OldWalkMoved[client] = false;
+
+}
+
+static void UpdateTurning(int client, const float oldEyeAngles[3], const float eyeAngles[3])
+{
+ gB_Turning[client] = eyeAngles[1] != oldEyeAngles[1];
+ gB_TurningLeft[client] = eyeAngles[1] < oldEyeAngles[1] - 180
+ || eyeAngles[1] > oldEyeAngles[1] && eyeAngles[1] < oldEyeAngles[1] + 180;
+}
+
+static void CheckNoclip(int client)
+{
+ // Leaving and entering noclip counts for leaving and touching ground is arbitrary.
+ // Though this is required for some GOKZ functions to work properly.
+ MoveType movetype = Movement_GetMovetype(client);
+ if (gMT_OldMovetype[client] != movetype)
+ {
+ // Entering noclip
+ if (movetype == MOVETYPE_NOCLIP)
+ {
+ gF_LandingOrigin[client] = gF_Origin[client];
+ gF_LandingVelocity[client] = gF_Velocity[client];
+ gI_LandingTick[client] = gI_TickCount[client];
+ gI_LandingCmdNum[client] = gI_Cmdnum[client];
+ }
+ else // Leaving noclip
+ {
+ gF_TakeoffOrigin[client] = gF_Origin[client];
+ gF_TakeoffVelocity[client] = gF_Velocity[client];
+ gI_TakeoffTick[client] = gI_TickCount[client];
+ gI_TakeoffCmdNum[client] = gI_Cmdnum[client];
+ gB_HitPerf[client] = false;
+ gB_Jumped[client] = false;
+ }
+ Call_OnChangeMovetype(client, gMT_OldMovetype[client], movetype);
+ }
+}
+
+static void CheckGround(int client)
+{
+ // Check if the player somehow leaves the ground outside of movement processing (eg. triggers)
+ // The player can't touch the ground outside of movement processing, no need to check for that.
+ if (gB_OldOnGround[client] && !Movement_GetOnGround(client))
+ {
+ Movement_GetOrigin(client, gF_TakeoffOrigin[client]);
+ Movement_GetVelocity(client, gF_TakeoffVelocity[client]);
+ gI_TakeoffTick[client] = gI_TickCount[client];
+ gI_TakeoffCmdNum[client] = gI_Cmdnum[client];
+ gB_HitPerf[client] = false;
+ gB_Jumped[client] = false;
+ Call_OnStopTouchGround(client, false, false, false);
+ }
+}
diff --git a/source/sourcemod/scripting/movementapi/forwards.sp b/source/sourcemod/scripting/movementapi/forwards.sp
new file mode 100644
index 0000000..9cf0b72
--- /dev/null
+++ b/source/sourcemod/scripting/movementapi/forwards.sp
@@ -0,0 +1,268 @@
+static Handle H_OnStartDucking;
+static Handle H_OnStopDucking;
+static Handle H_OnStartTouchGround;
+static Handle H_OnStopTouchGround;
+static Handle H_OnChangeMovetype;
+static Handle H_OnPlayerJump;
+
+static Handle H_OnPlayerMovePre;
+static Handle H_OnPlayerMovePost;
+static Handle H_OnDuckPre;
+static Handle H_OnDuckPost;
+static Handle H_OnLadderMovePre;
+static Handle H_OnLadderMovePost;
+static Handle H_OnFullLadderMovePre;
+static Handle H_OnFullLadderMovePost;
+static Handle H_OnJumpPre;
+static Handle H_OnJumpPost;
+static Handle H_OnAirAcceleratePre;
+static Handle H_OnAirAcceleratePost;
+static Handle H_OnWalkMovePre;
+static Handle H_OnWalkMovePost;
+static Handle H_OnCategorizePositionPre;
+static Handle H_OnCategorizePositionPost;
+
+void CreateGlobalForwards()
+{
+ H_OnStartDucking = CreateGlobalForward("Movement_OnStartDucking", ET_Ignore, Param_Cell);
+ H_OnStopDucking = CreateGlobalForward("Movement_OnStopDucking", ET_Ignore, Param_Cell);
+ H_OnStartTouchGround = CreateGlobalForward("Movement_OnStartTouchGround", ET_Ignore, Param_Cell);
+ H_OnStopTouchGround = CreateGlobalForward("Movement_OnStopTouchGround", ET_Ignore, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
+ H_OnChangeMovetype = CreateGlobalForward("Movement_OnChangeMovetype", ET_Ignore, Param_Cell, Param_Cell, Param_Cell);
+ H_OnPlayerJump = CreateGlobalForward("Movement_OnPlayerJump", ET_Ignore, Param_Cell, Param_Cell);
+
+ H_OnPlayerMovePre = CreateGlobalForward("Movement_OnPlayerMovePre", ET_Event, Param_Cell, Param_Array, Param_Array);
+ H_OnPlayerMovePost = CreateGlobalForward("Movement_OnPlayerMovePost", ET_Event, Param_Cell, Param_Array, Param_Array);
+
+ H_OnDuckPre = CreateGlobalForward("Movement_OnDuckPre", ET_Event, Param_Cell, Param_Array, Param_Array);
+ H_OnDuckPost = CreateGlobalForward("Movement_OnDuckPost", ET_Event, Param_Cell, Param_Array, Param_Array);
+
+ H_OnLadderMovePre = CreateGlobalForward("Movement_OnLadderMovePre", ET_Event, Param_Cell, Param_Array, Param_Array);
+ H_OnLadderMovePost = CreateGlobalForward("Movement_OnLadderMovePost", ET_Event, Param_Cell, Param_Array, Param_Array);
+
+ H_OnFullLadderMovePre = CreateGlobalForward("Movement_OnFullLadderMovePre", ET_Event, Param_Cell, Param_Array, Param_Array);
+ H_OnFullLadderMovePost = CreateGlobalForward("Movement_OnFullLadderMovePost", ET_Event, Param_Cell, Param_Array, Param_Array);
+
+ H_OnJumpPre = CreateGlobalForward("Movement_OnJumpPre", ET_Event, Param_Cell, Param_Array, Param_Array);
+ H_OnJumpPost = CreateGlobalForward("Movement_OnJumpPost", ET_Event, Param_Cell, Param_Array, Param_Array);
+
+ H_OnAirAcceleratePre = CreateGlobalForward("Movement_OnAirAcceleratePre", ET_Event, Param_Cell, Param_Array, Param_Array);
+ H_OnAirAcceleratePost = CreateGlobalForward("Movement_OnAirAcceleratePost", ET_Event, Param_Cell, Param_Array, Param_Array);
+
+ H_OnWalkMovePre = CreateGlobalForward("Movement_OnWalkMovePre", ET_Event, Param_Cell, Param_Array, Param_Array);
+ H_OnWalkMovePost = CreateGlobalForward("Movement_OnWalkMovePost", ET_Event, Param_Cell, Param_Array, Param_Array);
+
+ H_OnCategorizePositionPre = CreateGlobalForward("Movement_OnCategorizePositionPre", ET_Event, Param_Cell, Param_Array, Param_Array);
+ H_OnCategorizePositionPost = CreateGlobalForward("Movement_OnCategorizePositionPost", ET_Event, Param_Cell, Param_Array, Param_Array);
+}
+
+void Call_OnStartDucking(int client)
+{
+ Call_StartForward(H_OnStartDucking);
+ Call_PushCell(client);
+ Call_Finish();
+}
+
+void Call_OnStopDucking(int client)
+{
+ Call_StartForward(H_OnStopDucking);
+ Call_PushCell(client);
+ Call_Finish();
+}
+
+void Call_OnStartTouchGround(int client)
+{
+ Call_StartForward(H_OnStartTouchGround);
+ Call_PushCell(client);
+ Call_Finish();
+}
+
+void Call_OnStopTouchGround(int client, bool jumped, bool ladderJump, bool jumpbug)
+{
+ Call_StartForward(H_OnStopTouchGround);
+ Call_PushCell(client);
+ Call_PushCell(jumped);
+ Call_PushCell(ladderJump);
+ Call_PushCell(jumpbug);
+ Call_Finish();
+ // Immediately update OldOnGround state, so we can catch takeoffs that happen outside movement processing.
+ gB_OldOnGround[client] = false;
+}
+
+
+void Call_OnChangeMovetype(int client, MoveType oldMovetype, MoveType newMovetype)
+{
+ Call_StartForward(H_OnChangeMovetype);
+ Call_PushCell(client);
+ Call_PushCell(oldMovetype);
+ Call_PushCell(newMovetype);
+ Call_Finish();
+}
+
+void Call_OnPlayerJump(int client, bool jumpbug)
+{
+ Call_StartForward(H_OnPlayerJump);
+ Call_PushCell(client);
+ Call_PushCell(jumpbug);
+ Call_Finish();
+}
+
+Action Call_OnPlayerMovePre(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnPlayerMovePre);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnPlayerMovePost(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnPlayerMovePost);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnDuckPre(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnDuckPre);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnDuckPost(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnDuckPost);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnLadderMovePre(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnLadderMovePre);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnLadderMovePost(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnLadderMovePost);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnFullLadderMovePre(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnFullLadderMovePre);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnFullLadderMovePost(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnFullLadderMovePost);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnJumpPre(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnJumpPre);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnJumpPost(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnJumpPost);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnAirAcceleratePre(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnAirAcceleratePre);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnAirAcceleratePost(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnAirAcceleratePost);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnWalkMovePre(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnWalkMovePre);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnWalkMovePost(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnWalkMovePost);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnCategorizePositionPre(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnCategorizePositionPre);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+}
+
+Action Call_OnCategorizePositionPost(int client, float origin[3], float velocity[3], Action &result)
+{
+ Call_StartForward(H_OnCategorizePositionPost);
+ Call_PushCell(client);
+ Call_PushArrayEx(origin, 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(velocity, 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ return result;
+} \ No newline at end of file
diff --git a/source/sourcemod/scripting/movementapi/hooks.sp b/source/sourcemod/scripting/movementapi/hooks.sp
new file mode 100644
index 0000000..7b97b62
--- /dev/null
+++ b/source/sourcemod/scripting/movementapi/hooks.sp
@@ -0,0 +1,580 @@
+static DynamicDetour H_OnPlayerMove;
+static DynamicDetour H_OnDuck;
+static DynamicDetour H_OnLadderMove;
+static DynamicDetour H_OnFullLadderMove;
+static DynamicDetour H_OnJump;
+static DynamicDetour H_OnAirAccelerate;
+static DynamicDetour H_OnWalkMove;
+static DynamicDetour H_OnCategorizePosition;
+
+float gF_Origin[MAXPLAYERS + 1][3];
+float gF_Velocity[MAXPLAYERS + 1][3];
+
+bool gB_ProcessingLadderMove[MAXPLAYERS + 1];
+float gF_PreLadderMoveVelocity[MAXPLAYERS + 1][3];
+bool gB_TakeoffFromLadder[MAXPLAYERS + 1];
+float gF_PostLadderMoveOrigin[MAXPLAYERS + 1][3];
+float gF_PostLadderMoveVelocity[MAXPLAYERS + 1][3];
+
+bool gB_ProcessingDuck[MAXPLAYERS + 1];
+bool gB_Ducking[MAXPLAYERS + 1];
+bool gB_PrevOnGround[MAXPLAYERS + 1];
+bool gB_Duckbugged[MAXPLAYERS + 1];
+float gF_PostDuckOrigin[MAXPLAYERS + 1][3];
+
+bool gB_Jumpbugged[MAXPLAYERS + 1];
+
+bool gB_WalkMoved[MAXPLAYERS + 1];
+float gF_PostWalkMoveVelocity[MAXPLAYERS + 1][3];
+float gF_PostAAOrigin[MAXPLAYERS + 1][3];
+float gF_PostAAVelocity[MAXPLAYERS + 1][3];
+
+bool gB_OldWalkMoved[MAXPLAYERS + 1];
+
+void HookGameMovementFunctions()
+{
+ HookGameMovementFunction(H_OnDuck, "CCSGameMovement::Duck", DHooks_OnDuck_Pre, DHooks_OnDuck_Post);
+ HookGameMovementFunction(H_OnLadderMove, "CGameMovement::LadderMove", DHooks_OnLadderMove_Pre, DHooks_OnLadderMove_Post);
+ HookGameMovementFunction(H_OnFullLadderMove, "CGameMovement::FullLadderMove", DHooks_OnFullLadderMove_Pre, DHooks_OnFullLadderMove_Post);
+ HookGameMovementFunction(H_OnAirAccelerate, "CGameMovement::AirAccelerate", DHooks_OnAirAccelerate_Pre, DHooks_OnAirAccelerate_Post);
+ HookGameMovementFunction(H_OnWalkMove, "CGameMovement::WalkMove", DHooks_OnWalkMove_Pre, DHooks_OnWalkMove_Post);
+ HookGameMovementFunction(H_OnJump, "CCSGameMovement::OnJump", DHooks_OnJump_Pre, DHooks_OnJump_Post);
+ HookGameMovementFunction(H_OnPlayerMove, "CCSGameMovement::PlayerMove", DHooks_OnPlayerMove_Pre, DHooks_OnPlayerMove_Post);
+ HookGameMovementFunction(H_OnCategorizePosition, "CGameMovement::CategorizePosition", DHooks_OnCategorizePosition_Pre, DHooks_OnCategorizePosition_Post);
+}
+
+Action UpdateMoveData(Address pThis, int client, Function func)
+{
+ GameMove_GetOrigin(pThis, gF_Origin[client]);
+ GameMove_GetVelocity(pThis, gF_Velocity[client]);
+ Action result;
+ Call_StartFunction(INVALID_HANDLE, func);
+ Call_PushCell(client);
+ Call_PushArrayEx(gF_Origin[client], 3, SM_PARAM_COPYBACK);
+ Call_PushArrayEx(gF_Velocity[client], 3, SM_PARAM_COPYBACK);
+ Call_Finish(result);
+ if (result != Plugin_Continue)
+ {
+ GameMove_SetOrigin(pThis, gF_Origin[client]);
+ GameMove_SetVelocity(pThis, gF_Velocity[client]);
+ }
+ return result;
+}
+
+public MRESReturn DHooks_OnDuck_Pre(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client) || Movement_GetMovetype(client) == MOVETYPE_NOCLIP)
+ {
+ return MRES_Ignored;
+ }
+ Action result = UpdateMoveData(pThis, client, Call_OnDuckPre);
+
+ gB_Ducking[client] = Movement_GetDucking(client);
+ gB_ProcessingDuck[client] = true;
+
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnDuck_Post(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client) || Movement_GetMovetype(client) == MOVETYPE_NOCLIP)
+ {
+ return MRES_Ignored;
+ }
+
+ if (gB_Ducking[client] && !gB_OldDucking[client])
+ {
+ Call_OnStartDucking(client);
+ }
+ else if (!gB_Ducking[client] && gB_OldDucking[client])
+ {
+ Call_OnStopDucking(client);
+ }
+ gB_ProcessingDuck[client] = false;
+ GameMove_GetOrigin(pThis, gF_PostDuckOrigin[client]);
+
+ Action result = UpdateMoveData(pThis, client, Call_OnDuckPost);
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnLadderMove_Pre(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client) || Movement_GetMovetype(client) == MOVETYPE_NOCLIP)
+ {
+ return MRES_Ignored;
+ }
+ Action result = UpdateMoveData(pThis, client, Call_OnLadderMovePre);
+
+ gB_ProcessingLadderMove[client] = true;
+ GameMove_GetVelocity(pThis, gF_PreLadderMoveVelocity[client]);
+
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnLadderMove_Post(Address pThis, DHookReturn hReturn)
+{
+ // While the movetype changed here, the vertical velocity is not yet updated.
+ // gF_PostLadderMoveVelocity can be incorrect here.
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client) || Movement_GetMovetype(client) == MOVETYPE_NOCLIP)
+ {
+ return MRES_Ignored;
+ }
+
+ GameMove_GetOrigin(pThis, gF_PostLadderMoveOrigin[client]);
+ GameMove_GetVelocity(pThis, gF_PostLadderMoveVelocity[client]);
+ gB_ProcessingLadderMove[client] = false;
+ bool returnValue = DHookGetReturn(hReturn);
+ // If this returns false, and the movetype was originally MOVETYPE_LADDER, that means the player will change movetype and takeoff (LAJ)
+ // If this returns true, the movetype can still change in FullLadderMove by jumping (LAH)
+ // The current movetype here is still ladder, but it will change right after this function call.
+ if (!returnValue && Movement_GetMovetype(client) == MOVETYPE_LADDER)
+ {
+ gF_TakeoffVelocity[client] = gF_PostLadderMoveVelocity[client];
+ gF_TakeoffOrigin[client] = gF_PostLadderMoveOrigin[client];
+ gI_TakeoffTick[client] = gI_TickCount[client];
+ gI_TakeoffCmdNum[client] = gI_Cmdnum[client];
+ gB_Jumped[client] = false;
+ gB_HitPerf[client] = false;
+ Call_OnChangeMovetype(client, MOVETYPE_LADDER, MOVETYPE_WALK);
+ }
+ else if (returnValue && gMT_OldMovetype[client] != MOVETYPE_LADDER)
+ {
+ if (Movement_GetMovetype(client) == MOVETYPE_LADDER)
+ {
+ gF_LandingOrigin[client] = gF_PostLadderMoveOrigin[client];
+ // We don't really care about nobug origin when player lands on ladder.
+ gF_NobugLandingOrigin[client] = gF_LandingOrigin[client];
+ gF_LandingVelocity[client] = gF_PreLadderMoveVelocity[client];
+ gI_LandingCmdNum[client] = gI_Cmdnum[client];
+ gI_LandingTick[client] = gI_TickCount[client];
+ Call_OnChangeMovetype(client, MOVETYPE_WALK, MOVETYPE_LADDER);
+ }
+ }
+ else if (returnValue && gMT_OldMovetype[client] == MOVETYPE_LADDER)
+ {
+ // Player is on the ladder and in the air, pressing jump pushes them away from the ladder.
+ float curtime = GetGameTime();
+ int buttons = GetClientButtons(client);
+ float ignoreLadderJumpTime = GetEntPropFloat(client, Prop_Data, "m_ignoreLadderJumpTime");
+ if (buttons & IN_JUMP && ignoreLadderJumpTime <= curtime)
+ {
+ gF_TakeoffVelocity[client] = gF_PostLadderMoveVelocity[client];
+ gF_TakeoffOrigin[client] = gF_PostLadderMoveOrigin[client];
+ gI_TakeoffTick[client] = gI_TickCount[client];
+ gI_TakeoffCmdNum[client] = gI_Cmdnum[client];
+ gB_Jumped[client] = false;
+ gB_HitPerf[client] = false;
+ gB_TakeoffFromLadder[client] = true;
+ Call_OnChangeMovetype(client, MOVETYPE_LADDER, MOVETYPE_WALK);
+ }
+ }
+ Action result = UpdateMoveData(pThis, client, Call_OnLadderMovePost);
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnFullLadderMove_Pre(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+ Action result = UpdateMoveData(pThis, client, Call_OnFullLadderMovePre);
+
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnJump_Pre(Address pThis, DHookParam hParams)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+
+ gB_Jumped[client] = true;
+ if (gB_Duckbugged[client])
+ {
+ gB_Jumpbugged[client] = true;
+ }
+
+ // HitPerf must be modified here so plugins can know if player hits a perf or not.
+ // Not a perf if last movetype was ladder, because jumping works differently on ladders.
+ if (gMT_OldMovetype[client] != MOVETYPE_LADDER)
+ {
+ // If you walked on the last tick then clearly it's not going to be a perf.
+ // Can't perf if you don't jump.
+ gB_HitPerf[client] = !gB_OldWalkMoved[client];
+ }
+ else
+ {
+ gB_HitPerf[client] = false;
+ }
+
+ Action result = UpdateMoveData(pThis, client, Call_OnJumpPre);
+
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnJump_Post(Address pThis, DHookParam hParams)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+ // We need to update LadderMove velocity again in case of jumping.
+ GameMove_GetVelocity(pThis, gF_PostLadderMoveVelocity[client]);
+
+ // Current origin because the player hasn't moved yet.
+ gF_TakeoffOrigin[client] = gF_Origin[client];
+ gF_TakeoffVelocity[client] = gF_Velocity[client];
+ gI_TakeoffCmdNum[client] = gI_Cmdnum[client];
+ gI_TakeoffTick[client] = gI_TickCount[client];
+
+ // OnJump will only be called if the client previously touched some sort of ground, so Call_OnStopTouchGround should always be called.
+ Call_OnStopTouchGround(client, true, gB_TakeoffFromLadder[client], gB_Jumpbugged[client]);
+
+ Action result = UpdateMoveData(pThis, client, Call_OnJumpPost);
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnFullLadderMove_Post(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client) || Movement_GetMovetype(client) == MOVETYPE_NOCLIP)
+ {
+ return MRES_Ignored;
+ }
+
+ Action result = UpdateMoveData(pThis, client, Call_OnFullLadderMovePost);
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+// We hook AirAccelerate because TryPlayerMove in AirMove can change velocity
+// AirAccelerate velocity is required for nobug landing origin.
+public MRESReturn DHooks_OnAirAccelerate_Pre(Address pThis, DHookParam hParams)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+ Action result = UpdateMoveData(pThis, client, Call_OnAirAcceleratePre);
+
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnAirAccelerate_Post(Address pThis, DHookParam hParams)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+
+ GameMove_GetOrigin(pThis, gF_PostAAOrigin[client]);
+ GameMove_GetVelocity(pThis, gF_PostAAVelocity[client]);
+
+ Action result = UpdateMoveData(pThis, client, Call_OnAirAcceleratePost);
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+// WalkMove is called too early to detect if the player is still on ground or not.
+public MRESReturn DHooks_OnWalkMove_Pre(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+ Action result = UpdateMoveData(pThis, client, Call_OnWalkMovePre);
+
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnWalkMove_Post(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+
+ GameMove_GetVelocity(pThis, gF_PostWalkMoveVelocity[client]);
+ gB_WalkMoved[client] = true;
+
+ Action result = UpdateMoveData(pThis, client, Call_OnWalkMovePost);
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnPlayerMove_Pre(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+
+ gB_Duckbugged[client] = false;
+ gB_WalkMoved[client] = false;
+ gB_Jumpbugged[client] = false;
+ gB_Jumped[client] = false;
+ gB_TakeoffFromLadder[client] = false;
+
+ Action result = UpdateMoveData(pThis, client, Call_OnPlayerMovePre);
+
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnPlayerMove_Post(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+ Action result = UpdateMoveData(pThis, client, Call_OnPlayerMovePost);
+
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnCategorizePosition_Pre(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+ Action result = UpdateMoveData(pThis, client, Call_OnCategorizePositionPre);
+
+ gB_PrevOnGround[client] = Movement_GetOnGround(client);
+
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+public MRESReturn DHooks_OnCategorizePosition_Post(Address pThis)
+{
+ int client = GetClientFromGameMovementAddress(pThis);
+ if (!IsPlayerAlive(client) || IsFakeClient(client))
+ {
+ return MRES_Ignored;
+ }
+ bool ground = Movement_GetOnGround(client);
+ // Ground state changed!
+ if (gB_PrevOnGround[client] != ground)
+ {
+ if (ground) // Landing
+ {
+ NobugLandingOrigin(client, gF_NobugLandingOrigin[client]);
+
+ gF_LandingOrigin[client] = gF_Origin[client];
+ gI_LandingCmdNum[client] = gI_Cmdnum[client];
+ gI_LandingTick[client] = gI_TickCount[client];
+ Call_OnStartTouchGround(client);
+ }
+ else // Takeoff
+ {
+ gF_TakeoffOrigin[client] = gF_OldOrigin[client];
+ // Note: Jumping isn't detected here.
+ if (gB_WalkMoved[client])
+ {
+ gF_TakeoffVelocity[client] = gF_PostWalkMoveVelocity[client];
+ }
+ else
+ {
+ gF_TakeoffVelocity[client] = gF_PostLadderMoveVelocity[client];
+ }
+ gI_TakeoffTick[client] = gI_TickCount[client];
+ gI_TakeoffCmdNum[client] = gI_Cmdnum[client];
+ gB_Jumped[client] = false;
+ gB_HitPerf[client] = false;
+ bool hadLadderMoveType = Movement_GetMovetype(client) == MOVETYPE_LADDER || gMT_OldMovetype[client] == MOVETYPE_LADDER;
+ Call_OnStopTouchGround(client, false, hadLadderMoveType && !gB_WalkMoved[client], false);
+ }
+ }
+
+ Action result = UpdateMoveData(pThis, client, Call_OnCategorizePositionPost);
+ if (result != Plugin_Continue)
+ {
+ return MRES_Handled;
+ }
+ else
+ {
+ return MRES_Ignored;
+ }
+}
+
+static void NobugLandingOrigin(int client, float landingOrigin[3])
+{
+ // NOTE: Get ground position and distance to ground.
+ float groundEndPoint[3];
+ groundEndPoint = gF_Origin[client];
+ groundEndPoint[2] -= 2.0;
+ float mins[3] = {-16.0, -16.0, 0.0};
+ float maxs[3] = {16.0, 16.0, 0.0};
+ TR_TraceHullFilter(gF_Origin[client], groundEndPoint, mins, maxs, MASK_PLAYERSOLID, TraceEntityFilterPlayers, client);
+
+ float groundPos[3];
+ TR_GetEndPosition(groundPos);
+
+ // NOTE: This is almost guaranteed to hit because CategorizePosition does
+ // the exact same trace to determine if the player is on the ground or not.
+ if (!TR_DidHit())
+ {
+ // Use groundEndPoint if trace fails, because this MIGHT
+ // give less distance in this extremely rare case.
+ groundPos = groundEndPoint;
+ }
+
+ gB_Duckbugged[client] = gB_ProcessingDuck[client];
+ float distanceToGround = gF_Origin[client][2] - groundPos[2];
+ float velocity[3], origin[3];
+ // If there's any distance to the ground, then we'll trace it with this one.
+
+ // It seems like sometimes the player can end up ever so slighly above this "ground" value,
+ // likely due to floating point precision error. Treat it as a bugged jump as well.
+ if (distanceToGround > 0.001 || gB_ProcessingDuck[client])
+ {
+ // Use the current origin and velocity if we're not touching the ground
+ gF_LandingVelocity[client] = gF_Velocity[client];
+ velocity = gF_Velocity[client];
+ origin = gF_Origin[client];
+ }
+ else
+ {
+ // NOTE: Use gF_OldVelocity and gF_OldOrigin if jump is potentially bugged.
+ gF_LandingVelocity[client] = gF_PostAAVelocity[client];
+ velocity = gF_PostAAVelocity[client];
+ origin = gF_PostAAOrigin[client];
+ }
+
+ float firstTraceEndpoint[3], scaledVelocity[3];
+ scaledVelocity = velocity;
+ ScaleVector(scaledVelocity, GetTickInterval());
+ AddVectors(origin, scaledVelocity, firstTraceEndpoint);
+
+ TR_TraceHullFilter(origin, firstTraceEndpoint, mins, maxs, MASK_PLAYERSOLID, TraceEntityFilterPlayers, client);
+ if (!TR_DidHit())
+ {
+ // It is possible to not hit the trace, if your vertical velocity is low enough.
+ // In an extreme case, you would need 10 more traces for this to hit.
+ // It is also possible to miss the trace on a flat jump, by hitting the very edge of a block.
+
+ // Use groundPos, because this will give no distance advantage to the player, but
+ // it will let the player not have his jump invalidated.
+ landingOrigin = groundPos;
+ }
+ else
+ {
+ TR_GetEndPosition(landingOrigin);
+ }
+}
diff --git a/source/sourcemod/scripting/movementapi/natives.sp b/source/sourcemod/scripting/movementapi/natives.sp
new file mode 100644
index 0000000..f8cd7a5
--- /dev/null
+++ b/source/sourcemod/scripting/movementapi/natives.sp
@@ -0,0 +1,183 @@
+void CreateNatives()
+{
+ CreateNative("Movement_GetJumped", Native_GetJumped);
+ CreateNative("Movement_GetHitPerf", Native_GetHitPerf);
+ CreateNative("Movement_GetTakeoffOrigin", Native_GetTakeoffOrigin);
+ CreateNative("Movement_GetTakeoffVelocity", Native_GetTakeoffVelocity);
+ CreateNative("Movement_GetTakeoffSpeed", Native_GetTakeoffSpeed);
+ CreateNative("Movement_GetTakeoffTick", Native_GetTakeoffTick);
+ CreateNative("Movement_GetTakeoffCmdNum", Native_GetTakeoffCmdNum);
+ CreateNative("Movement_GetNobugLandingOrigin", Native_GetNobugLandingOrigin);
+ CreateNative("Movement_GetLandingOrigin", Native_GetLandingOrigin);
+ CreateNative("Movement_GetLandingVelocity", Native_GetLandingVelocity);
+ CreateNative("Movement_GetLandingSpeed", Native_GetLandingSpeed);
+ CreateNative("Movement_GetLandingTick", Native_GetLandingTick);
+ CreateNative("Movement_GetLandingCmdNum", Native_GetLandingCmdNum);
+ CreateNative("Movement_GetTurning", Native_GetTurning);
+ CreateNative("Movement_GetTurningLeft", Native_GetTurningLeft);
+ CreateNative("Movement_GetTurningRight", Native_GetTurningRight);
+ CreateNative("Movement_GetMaxSpeed", Native_GetMaxSpeed);
+ CreateNative("Movement_GetDuckbugged", Native_GetDuckbugged);
+ CreateNative("Movement_GetJumpbugged", Native_GetJumpbugged);
+ CreateNative("Movement_GetProcessingOrigin", Native_GetProcessingOrigin);
+ CreateNative("Movement_GetProcessingVelocity", Native_GetProcessingVelocity);
+ CreateNative("Movement_SetTakeoffOrigin", Native_SetTakeoffOrigin);
+ CreateNative("Movement_SetTakeoffVelocity", Native_SetTakeoffVelocity);
+ CreateNative("Movement_SetLandingOrigin", Native_SetLandingOrigin);
+ CreateNative("Movement_SetLandingVelocity", Native_SetLandingVelocity);
+}
+
+public int Native_GetJumped(Handle plugin, int numParams)
+{
+ return gB_Jumped[GetNativeCell(1)];
+}
+
+public int Native_GetHitPerf(Handle plugin, int numParams)
+{
+ return gB_HitPerf[GetNativeCell(1)];
+}
+
+public int Native_GetTakeoffOrigin(Handle plugin, int numParams)
+{
+ return SetNativeArray(2, gF_TakeoffOrigin[GetNativeCell(1)], 3);
+}
+
+public int Native_GetTakeoffVelocity(Handle plugin, int numParams)
+{
+ return SetNativeArray(2, gF_TakeoffVelocity[GetNativeCell(1)], 3);
+}
+
+public int Native_GetTakeoffSpeed(Handle plugin, int numParams)
+{
+ return view_as<int>(GetVectorHorizontalLength(gF_TakeoffVelocity[GetNativeCell(1)]));
+}
+
+public int Native_GetTakeoffTick(Handle plugin, int numParams)
+{
+ return gI_TakeoffTick[GetNativeCell(1)];
+}
+
+public int Native_GetTakeoffCmdNum(Handle plugin, int numParams)
+{
+ return gI_TakeoffCmdNum[GetNativeCell(1)];
+}
+
+public int Native_GetNobugLandingOrigin(Handle plugin, int numParams)
+{
+ return SetNativeArray(2, gF_NobugLandingOrigin[GetNativeCell(1)], 3);
+}
+
+public int Native_GetLandingOrigin(Handle plugin, int numParams)
+{
+ return SetNativeArray(2, gF_LandingOrigin[GetNativeCell(1)], 3);
+}
+
+public int Native_GetLandingVelocity(Handle plugin, int numParams)
+{
+ return SetNativeArray(2, gF_LandingVelocity[GetNativeCell(1)], 3);
+}
+
+public int Native_GetLandingSpeed(Handle plugin, int numParams)
+{
+ return view_as<int>(GetVectorHorizontalLength(gF_LandingVelocity[GetNativeCell(1)]));
+}
+
+public int Native_GetLandingTick(Handle plugin, int numParams)
+{
+ return gI_LandingTick[GetNativeCell(1)];
+}
+
+public int Native_GetLandingCmdNum(Handle plugin, int numParams)
+{
+ return gI_LandingCmdNum[GetNativeCell(1)];
+}
+
+public int Native_GetTurning(Handle plugin, int numParams)
+{
+ return view_as<int>(gB_Turning[GetNativeCell(1)]);
+}
+
+public int Native_GetTurningLeft(Handle plugin, int numParams)
+{
+ return view_as<int>(gB_TurningLeft[GetNativeCell(1)]);
+}
+
+public int Native_GetTurningRight(Handle plugin, int numParams)
+{
+ int client = GetNativeCell(1);
+ return view_as<int>(gB_Turning[client] && !gB_TurningLeft[client]);
+}
+
+public int Native_GetMaxSpeed(Handle plugin, int numParams)
+{
+ int client = GetNativeCell(1);
+ return view_as<int>(GetMaxSpeed(client));
+}
+
+public int Native_GetDuckbugged(Handle plugin, int numParams)
+{
+ return view_as<int>(gB_Duckbugged[GetNativeCell(1)]);
+}
+
+public int Native_GetJumpbugged(Handle plugin, int numParams)
+{
+ return view_as<int>(gB_Jumpbugged[GetNativeCell(1)]);
+}
+
+public int Native_GetProcessingOrigin(Handle plugin, int numParams)
+{
+ return SetNativeArray(2, gF_Origin[GetNativeCell(1)], 3);
+}
+
+public int Native_GetProcessingVelocity(Handle plugin, int numParams)
+{
+ return SetNativeArray(2, gF_Velocity[GetNativeCell(1)], 3);
+}
+
+public int Native_SetTakeoffOrigin(Handle plugin, int numParams)
+{
+ float array[3];
+ GetNativeArray(2, array, sizeof(array));
+ for (int i = 0; i < 3; i++)
+ {
+ gF_TakeoffOrigin[GetNativeCell(1)][i] = array[i];
+ }
+
+ return 0;
+}
+
+public int Native_SetTakeoffVelocity(Handle plugin, int numParams)
+{
+ float array[3];
+ GetNativeArray(2, array, sizeof(array));
+ for (int i = 0; i < 3; i++)
+ {
+ gF_TakeoffVelocity[GetNativeCell(1)][i] = array[i];
+ }
+
+ return 0;
+}
+
+public int Native_SetLandingOrigin(Handle plugin, int numParams)
+{
+ float array[3];
+ GetNativeArray(2, array, sizeof(array));
+ for (int i = 0; i < 3; i++)
+ {
+ gF_LandingOrigin[GetNativeCell(1)][i] = array[i];
+ }
+
+ return 0;
+}
+
+public int Native_SetLandingVelocity(Handle plugin, int numParams)
+{
+ float array[3];
+ GetNativeArray(2, array, sizeof(array));
+ for (int i = 0; i < 3; i++)
+ {
+ gF_LandingVelocity[GetNativeCell(1)][i] = array[i];
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/source/sourcemod/scripting/movementapi/stocks.sp b/source/sourcemod/scripting/movementapi/stocks.sp
new file mode 100644
index 0000000..e080efc
--- /dev/null
+++ b/source/sourcemod/scripting/movementapi/stocks.sp
@@ -0,0 +1,200 @@
+stock void GameMove_SetVelocity(Address addr, float velocity[3])
+{
+ if (velocity[0] != velocity[0] || velocity[1] != velocity[1] || velocity[2] != velocity[2])
+ {
+ return;
+ }
+ static int mvOffset;
+ static int velocityOffset;
+ if (!mvOffset)
+ {
+ char buffer[8];
+ if (!gH_GameData.GetKeyValue("CGameMovement::mv", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CGameMovement::mv offset.");
+ return;
+ }
+ mvOffset = StringToInt(buffer);
+ if (!gH_GameData.GetKeyValue("CMoveData::m_vecVelocity", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CMoveData::m_vecVelocity offset.");
+ return;
+ }
+ velocityOffset = StringToInt(buffer);
+ }
+
+ Address mvAddress = view_as<Address>(LoadFromAddress(view_as<Address>(view_as<int>(addr) + mvOffset), NumberType_Int32));
+ // TODO: idk if raw cast works here or not
+ StoreToAddress(view_as<Address>(view_as<int>(mvAddress) + velocityOffset), view_as<int>(velocity[0]), NumberType_Int32);
+ StoreToAddress(view_as<Address>(view_as<int>(mvAddress) + velocityOffset + 4), view_as<int>(velocity[1]), NumberType_Int32);
+ StoreToAddress(view_as<Address>(view_as<int>(mvAddress) + velocityOffset + 8), view_as<int>(velocity[2]), NumberType_Int32);
+}
+
+stock void GameMove_SetOrigin(Address addr, float origin[3])
+{
+ if (origin[0] != origin[0] || origin[1] != origin[1] || origin[2] != origin[2])
+ {
+ return;
+ }
+ static int mvOffset;
+ static int originOffset;
+ if (!mvOffset)
+ {
+ char buffer[8];
+ if (!gH_GameData.GetKeyValue("CGameMovement::mv", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CGameMovement::mv offset.");
+ return;
+ }
+ mvOffset = StringToInt(buffer);
+ if (!gH_GameData.GetKeyValue("CMoveData::m_vecAbsOrigin", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CMoveData::m_vecAbsOrigin offset.");
+ return;
+ }
+ originOffset = StringToInt(buffer);
+ }
+
+ Address mvAddress = view_as<Address>(LoadFromAddress(view_as<Address>(view_as<int>(addr) + mvOffset), NumberType_Int32));
+ // TODO: idk if raw cast works here or not
+ StoreToAddress(view_as<Address>(view_as<int>(mvAddress) + originOffset), view_as<int>(origin[0]), NumberType_Int32);
+ StoreToAddress(view_as<Address>(view_as<int>(mvAddress) + originOffset + 4), view_as<int>(origin[1]), NumberType_Int32);
+ StoreToAddress(view_as<Address>(view_as<int>(mvAddress) + originOffset + 8), view_as<int>(origin[2]), NumberType_Int32);
+}
+
+stock void GameMove_GetVelocity(Address addr, float result[3])
+{
+ static int mvOffset;
+ static int velocityOffset;
+ if (!mvOffset)
+ {
+ char buffer[8];
+ if (!gH_GameData.GetKeyValue("CGameMovement::mv", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CGameMovement::mv offset.");
+ return;
+ }
+ mvOffset = StringToInt(buffer);
+ if (!gH_GameData.GetKeyValue("CMoveData::m_vecVelocity", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CMoveData::m_vecVelocity offset.");
+ return;
+ }
+ velocityOffset = StringToInt(buffer);
+ }
+
+ Address mvAddress = view_as<Address>(LoadFromAddress(view_as<Address>(view_as<int>(addr) + mvOffset), NumberType_Int32));
+ result[0] = view_as<float>(LoadFromAddress(view_as<Address>(view_as<int>(mvAddress) + velocityOffset), NumberType_Int32));
+ result[1] = view_as<float>(LoadFromAddress(view_as<Address>(view_as<int>(mvAddress) + velocityOffset + 4), NumberType_Int32));
+ result[2] = view_as<float>(LoadFromAddress(view_as<Address>(view_as<int>(mvAddress) + velocityOffset + 8), NumberType_Int32));
+}
+
+stock void GameMove_GetOrigin(Address addr, float result[3])
+{
+ static int mvOffset;
+ static int originOffset;
+ if (!mvOffset)
+ {
+ char buffer[8];
+ if (!gH_GameData.GetKeyValue("CGameMovement::mv", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CGameMovement::mv offset.");
+ return;
+ }
+ mvOffset = StringToInt(buffer);
+ if (!gH_GameData.GetKeyValue("CMoveData::m_vecAbsOrigin", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CMoveData::m_vecAbsOrigin offset.");
+ return;
+ }
+ originOffset = StringToInt(buffer);
+ }
+
+ Address mvAddress = view_as<Address>(LoadFromAddress(view_as<Address>(view_as<int>(addr) + mvOffset), NumberType_Int32));
+ result[0] = view_as<float>(LoadFromAddress(view_as<Address>(view_as<int>(mvAddress) + originOffset), NumberType_Int32));
+ result[1] = view_as<float>(LoadFromAddress(view_as<Address>(view_as<int>(mvAddress) + originOffset + 4), NumberType_Int32));
+ result[2] = view_as<float>(LoadFromAddress(view_as<Address>(view_as<int>(mvAddress) + originOffset + 8), NumberType_Int32));
+}
+
+stock void GameMove_GetEyeAngles(Address addr, float result[3])
+{
+ static int mvOffset;
+ static int viewAngleOffset;
+ if (!mvOffset)
+ {
+ char buffer[8];
+ if (!gH_GameData.GetKeyValue("CGameMovement::mv", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CGameMovement::mv offset.");
+ return;
+ }
+ mvOffset = StringToInt(buffer);
+ if (!gH_GameData.GetKeyValue("CMoveData::m_viewAngleOffset", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CMoveData::m_viewAngleOffset offset.");
+ return;
+ }
+ viewAngleOffset = StringToInt(buffer);
+ }
+
+ Address mvAddress = view_as<Address>(LoadFromAddress(view_as<Address>(view_as<int>(addr) + mvOffset), NumberType_Int32));
+ result[0] = view_as<float>(LoadFromAddress(view_as<Address>(view_as<int>(mvAddress) + viewAngleOffset), NumberType_Int32));
+ result[1] = view_as<float>(LoadFromAddress(view_as<Address>(view_as<int>(mvAddress) + viewAngleOffset + 4), NumberType_Int32));
+ result[2] = view_as<float>(LoadFromAddress(view_as<Address>(view_as<int>(mvAddress) + viewAngleOffset + 8), NumberType_Int32));
+}
+
+stock int GetEntityFromAddress(Address pEntity) {
+ static int offs_RefEHandle;
+ if (offs_RefEHandle) {
+ return EntRefToEntIndex(LoadFromAddress(pEntity + view_as<Address>(offs_RefEHandle), NumberType_Int32) | (1 << 31));
+ }
+
+ // if we don't have it already, attempt to lookup offset based on SDK information
+ // CWorld is derived from CBaseEntity so it should have both offsets
+ int offs_angRotation = FindDataMapInfo(0, "m_angRotation"),
+ offs_vecViewOffset = FindDataMapInfo(0, "m_vecViewOffset");
+ if (offs_angRotation == -1) {
+ ThrowError("Could not find offset for ((CBaseEntity) CWorld)::m_angRotation");
+ } else if (offs_vecViewOffset == -1) {
+ ThrowError("Could not find offset for ((CBaseEntity) CWorld)::m_vecViewOffset");
+ } else if ((offs_angRotation + 0x0C) != (offs_vecViewOffset - 0x04)) {
+ char game[32];
+ GetGameFolderName(game, sizeof(game));
+ ThrowError("Could not confirm offset of CBaseEntity::m_RefEHandle "
+ ... "(incorrect assumption for game '%s'?)", game);
+ }
+
+ // offset seems right, cache it for the next call
+ offs_RefEHandle = offs_angRotation + 0x0C;
+ return GetEntityFromAddress(pEntity);
+}
+
+stock int GetClientFromGameMovementAddress(Address addr)
+{
+ char buffer[8];
+ if (!gH_GameData.GetKeyValue("CGameMovement::player", buffer, sizeof(buffer)))
+ {
+ ThrowError("Failed to get CGameMovement::player offset.");
+ return -1;
+ }
+ int offset = StringToInt(buffer);
+ Address playerAddr = view_as<Address>(LoadFromAddress(view_as<Address>(view_as<int>(addr) + offset), NumberType_Int32));
+ return GetEntityFromAddress(playerAddr);
+}
+
+stock void HookGameMovementFunction(DynamicDetour handle, char[] fName, DHookCallback preCallback, DHookCallback postCallback)
+{
+ handle = DynamicDetour.FromConf(gH_GameData, fName);
+ if (!handle)
+ {
+ SetFailState("Failed to find %s config", fName);
+ }
+ if (!handle.Enable(Hook_Pre, preCallback))
+ {
+ SetFailState("Failed to enable detour on %s", fName);
+ }
+ if (!handle.Enable(Hook_Post, postCallback))
+ {
+ SetFailState("Failed to enable detour on %s", fName);
+ }
+}