summaryrefslogtreecommitdiff
path: root/sourcemod/scripting/include/gokz
diff options
context:
space:
mode:
authornavewindre <nw@moneybot.cc>2023-12-04 18:06:10 +0100
committernavewindre <nw@moneybot.cc>2023-12-04 18:06:10 +0100
commitaef0d1c1268ab7d4bc18996c9c6b4da16a40aadc (patch)
tree43e766b51704f4ab8b383583bdc1871eeeb9c698 /sourcemod/scripting/include/gokz
parent38f1140c11724da05a23a10385061200b907cf6e (diff)
bbbbbbbbwaaaaaaaaaaa
Diffstat (limited to 'sourcemod/scripting/include/gokz')
-rw-r--r--sourcemod/scripting/include/gokz/anticheat.inc168
-rw-r--r--sourcemod/scripting/include/gokz/chat.inc45
-rw-r--r--sourcemod/scripting/include/gokz/core.inc1920
-rw-r--r--sourcemod/scripting/include/gokz/global.inc317
-rw-r--r--sourcemod/scripting/include/gokz/hud.inc468
-rw-r--r--sourcemod/scripting/include/gokz/jumpbeam.inc148
-rw-r--r--sourcemod/scripting/include/gokz/jumpstats.inc442
-rw-r--r--sourcemod/scripting/include/gokz/kzplayer.inc584
-rw-r--r--sourcemod/scripting/include/gokz/localdb.inc353
-rw-r--r--sourcemod/scripting/include/gokz/localranks.inc176
-rw-r--r--sourcemod/scripting/include/gokz/momsurffix.inc23
-rw-r--r--sourcemod/scripting/include/gokz/paint.inc114
-rw-r--r--sourcemod/scripting/include/gokz/pistol.inc93
-rw-r--r--sourcemod/scripting/include/gokz/profile.inc291
-rw-r--r--sourcemod/scripting/include/gokz/quiet.inc205
-rw-r--r--sourcemod/scripting/include/gokz/racing.inc189
-rw-r--r--sourcemod/scripting/include/gokz/replays.inc275
-rw-r--r--sourcemod/scripting/include/gokz/slayonend.inc43
-rw-r--r--sourcemod/scripting/include/gokz/tips.inc59
-rw-r--r--sourcemod/scripting/include/gokz/tpanglefix.inc40
-rw-r--r--sourcemod/scripting/include/gokz/version.inc12
21 files changed, 5965 insertions, 0 deletions
diff --git a/sourcemod/scripting/include/gokz/anticheat.inc b/sourcemod/scripting/include/gokz/anticheat.inc
new file mode 100644
index 0000000..7fa5409
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/anticheat.inc
@@ -0,0 +1,168 @@
+/*
+ gokz-anticheat Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_anticheat_included_
+#endinput
+#endif
+#define _gokz_anticheat_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum ACReason:
+{
+ ACReason_BhopMacro = 0,
+ ACReason_BhopHack,
+ ACREASON_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define AC_MAX_BUTTON_SAMPLES 40
+#define AC_MAX_BHOP_GROUND_TICKS 8
+#define AC_MAX_BHOP_SAMPLES 30
+#define AC_BINDEXCEPTION_SAMPLES 5
+#define AC_LOG_PATH "logs/gokz-anticheat.log"
+
+stock char gC_ACReasons[ACREASON_COUNT][] =
+{
+ "BHop Macro",
+ "BHop Hack"
+};
+
+
+
+// =====[ FORWARDS ]=====
+
+/**
+ * Called when gokz-anticheat suspects a player of cheating.
+ *
+ * @param client Client index.
+ * @param reason Reason for suspicion.
+ * @param notes Additional reasoning, description etc.
+ * @param stats Data supporting the suspicion e.g. scroll pattern.
+ */
+forward void GOKZ_AC_OnPlayerSuspected(int client, ACReason reason, const char[] notes, const char[] stats);
+
+
+
+// =====[ NATIVES ]=====
+
+/**
+ * Gets the number of recent bhop samples available for a player.
+ *
+ * @param client Client index.
+ * @return Number of bhop samples available.
+ */
+native int GOKZ_AC_GetSampleSize(int client);
+
+/**
+ * Gets whether a player hit a perfect bhop for a number of
+ * recent bhops. Buffer must be large enough to fit the sample
+ * size.
+ *
+ * @param client Client index.
+ * @param buffer Buffer for perfect bhop booleans, with the first element being the most recent bhop.
+ * @param sampleSize Maximum recent bhop samples.
+ * @return Number of bhop samples.
+ */
+native int GOKZ_AC_GetHitPerf(int client, bool[] buffer, int sampleSize);
+
+/**
+ * Gets a player's number of perfect bhops out of a sample
+ * size of bhops.
+ *
+ * @param client Client index.
+ * @param sampleSize Maximum recent bhop samples to include in calculation.
+ * @return Player's number of perfect bhops.
+ */
+native int GOKZ_AC_GetPerfCount(int client, int sampleSize);
+
+/**
+ * Gets a player's ratio of perfect bhops to normal bhops.
+ *
+ * @param client Client index.
+ * @param sampleSize Maximum recent bhop samples to include in calculation.
+ * @return Player's ratio of perfect bhops to normal bhops.
+ */
+native float GOKZ_AC_GetPerfRatio(int client, int sampleSize);
+
+/**
+ * Gets a player's jump input counts for a number of recent
+ * bhops. Buffer must be large enough to fit the sample size.
+ *
+ * @param client Client index.
+ * @param buffer Buffer for jump input counts, with the first element being the most recent bhop.
+ * @param sampleSize Maximum recent bhop samples.
+ * @return Number of bhop samples.
+ */
+native int GOKZ_AC_GetJumpInputs(int client, int[] buffer, int sampleSize);
+
+/**
+ * Gets a player's average number of jump inputs for a number
+ * of recent bhops.
+ *
+ * @param client Client index.
+ * @param sampleSize Maximum recent bhop samples to include in calculation.
+ * @return Player's average number of jump inputs.
+ */
+native float GOKZ_AC_GetAverageJumpInputs(int client, int sampleSize);
+
+/**
+ * Gets a player's jump input counts prior to a number of recent
+ * bhops. Buffer must be large enough to fit the sample size.
+ * Includes the jump input that resulted in the jump.
+ *
+ * @param client Client index.
+ * @param buffer Buffer for jump input counts, with the first element being the most recent bhop.
+ * @param sampleSize Maximum recent bhop samples.
+ * @return Number of bhop samples.
+ */
+native int GOKZ_AC_GetPreJumpInputs(int client, int[] buffer, int sampleSize);
+
+/**
+ * Gets a player's jump input counts after a number of recent
+ * bhops. Buffer must be large enough to fit the sample size.
+ * Excludes the jump input that resulted in the jump.
+ *
+ * @param client Client index.
+ * @param buffer Buffer for jump input counts, with the first element being the most recent bhop.
+ * @param sampleSize Maximum recent bhop samples.
+ * @return Number of bhop samples.
+ */
+native int GOKZ_AC_GetPostJumpInputs(int client, int[] buffer, int sampleSize);
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_anticheat =
+{
+ name = "gokz-anticheat",
+ file = "gokz-anticheat.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_anticheat_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_AC_GetSampleSize");
+ MarkNativeAsOptional("GOKZ_AC_GetHitPerf");
+ MarkNativeAsOptional("GOKZ_AC_GetPerfCount");
+ MarkNativeAsOptional("GOKZ_AC_GetPerfRatio");
+ MarkNativeAsOptional("GOKZ_AC_GetJumpInputs");
+ MarkNativeAsOptional("GOKZ_AC_GetAverageJumpInputs");
+ MarkNativeAsOptional("GOKZ_AC_GetPreJumpInputs");
+ MarkNativeAsOptional("GOKZ_AC_GetPostJumpInputs");
+}
+#endif \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/chat.inc b/sourcemod/scripting/include/gokz/chat.inc
new file mode 100644
index 0000000..0264a57
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/chat.inc
@@ -0,0 +1,45 @@
+/*
+ gokz-chat Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_chat_included_
+#endinput
+#endif
+#define _gokz_chat_included_
+
+
+
+// =====[ NATIVES ]=====
+
+/**
+ * Gets whether a mode is loaded.
+ *
+ * @param client Client.
+ * @param tag Tag to prepend to the player name in chat.
+ * @param color Color to use for the tag.
+ */
+native void GOKZ_CH_SetChatTag(int client, const char[] tag, const char[] color);
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_chat =
+{
+ name = "gokz-chat",
+ file = "gokz-chat.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_chat_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_CH_SetChatTag");
+}
+#endif \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/core.inc b/sourcemod/scripting/include/gokz/core.inc
new file mode 100644
index 0000000..fb450d1
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/core.inc
@@ -0,0 +1,1920 @@
+/*
+ gokz-core Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_core_included_
+#endinput
+#endif
+#define _gokz_core_included_
+
+#include <cstrike>
+#include <regex>
+#include <topmenus>
+
+#include <gokz>
+
+
+
+// =====[ ENUMS ]=====
+
+enum
+{
+ TimeType_Nub = 0,
+ TimeType_Pro,
+ TIMETYPE_COUNT
+};
+
+enum
+{
+ MapPrefix_Other = 0,
+ MapPrefix_KZPro,
+ MAPPREFIX_COUNT
+};
+
+enum StartPositionType:
+{
+ StartPositionType_Spawn,
+ StartPositionType_Custom,
+ StartPositionType_MapButton,
+ StartPositionType_MapStart,
+ STARTPOSITIONTYPE_COUNT
+};
+
+enum CourseTimerType:
+{
+ CourseTimerType_None,
+ CourseTimerType_Default,
+ CourseTimerType_Button,
+ CourseTimerType_ZoneLegacy,
+ CourseTimerType_ZoneNew,
+ CourseTimerType_COUNT
+};
+
+enum OptionProp:
+{
+ OptionProp_Cookie = 0,
+ OptionProp_Type,
+ OptionProp_DefaultValue,
+ OptionProp_MinValue,
+ OptionProp_MaxValue,
+ OPTIONPROP_COUNT
+};
+
+enum OptionType:
+{
+ OptionType_Int = 0,
+ OptionType_Float
+};
+
+enum Option:
+{
+ OPTION_INVALID = -1,
+ Option_Mode,
+ Option_Style,
+ Option_CheckpointMessages,
+ Option_CheckpointSounds,
+ Option_TeleportSounds,
+ Option_ErrorSounds,
+ Option_VirtualButtonIndicators,
+ Option_TimerButtonZoneType,
+ Option_ButtonThroughPlayers,
+ Option_Safeguard,
+ OPTION_COUNT
+};
+
+enum
+{
+ Mode_Vanilla = 0,
+ Mode_SimpleKZ,
+ Mode_KZTimer,
+ MODE_COUNT
+};
+
+enum
+{
+ Style_Normal = 0,
+ STYLE_COUNT
+};
+
+enum
+{
+ CheckpointMessages_Disabled = 0,
+ CheckpointMessages_Enabled,
+ CHECKPOINTMESSAGES_COUNT
+};
+
+enum
+{
+ CheckpointSounds_Disabled = 0,
+ CheckpointSounds_Enabled,
+ CHECKPOINTSOUNDS_COUNT
+};
+
+enum
+{
+ TeleportSounds_Disabled = 0,
+ TeleportSounds_Enabled,
+ TELEPORTSOUNDS_COUNT
+};
+
+enum
+{
+ ErrorSounds_Disabled = 0,
+ ErrorSounds_Enabled,
+ ERRORSOUNDS_COUNT
+};
+
+enum
+{
+ VirtualButtonIndicators_Disabled = 0,
+ VirtualButtonIndicators_Enabled,
+ VIRTUALBUTTONINDICATORS_COUNT
+};
+
+enum
+{
+ TimerButtonZoneType_BothButtons = 0,
+ TimerButtonZoneType_EndZone,
+ TimerButtonZoneType_BothZones,
+ TIMERBUTTONZONETYPE_COUNT
+};
+
+enum
+{
+ ButtonThroughPlayers_Disabled = 0,
+ ButtonThroughPlayers_Enabled,
+ BUTTONTHROUGHPLAYERS_COUNT
+};
+
+enum
+{
+ Safeguard_Disabled = 0,
+ Safeguard_EnabledNUB,
+ Safeguard_EnabledPRO,
+ SAFEGUARD_COUNT
+};
+
+enum
+{
+ ModeCVar_Accelerate = 0,
+ ModeCVar_AccelerateUseWeaponSpeed,
+ ModeCVar_AirAccelerate,
+ ModeCVar_AirMaxWishSpeed,
+ ModeCVar_EnableBunnyhopping,
+ ModeCVar_Friction,
+ ModeCVar_Gravity,
+ ModeCVar_JumpImpulse,
+ ModeCVar_LadderScaleSpeed,
+ ModeCVar_LedgeMantleHelper,
+ ModeCVar_MaxSpeed,
+ ModeCVar_MaxVelocity,
+ ModeCVar_StaminaJumpCost,
+ ModeCVar_StaminaLandCost,
+ ModeCVar_StaminaMax,
+ ModeCVar_StaminaRecoveryRate,
+ ModeCVar_StandableNormal,
+ ModeCVar_TimeBetweenDucks,
+ ModeCVar_WalkableNormal,
+ ModeCVar_WaterAccelerate,
+ MoveCVar_WaterMoveSpeedMultiplier,
+ MoveCVar_WaterSwimMode,
+ MoveCVar_WeaponEncumbrancePerItem,
+ ModeCVar_WeaponEncumbranceScale,
+ MODECVAR_COUNT
+};
+
+// NOTE: gokz-core/map/entlump.sp
+enum EntlumpTokenType
+{
+ EntlumpTokenType_OpenBrace, // {
+ EntlumpTokenType_CloseBrace, // }
+ EntlumpTokenType_Identifier, // everything that's inside quotations
+ EntlumpTokenType_Unknown,
+ EntlumpTokenType_EndOfStream
+};
+
+// NOTE: gokz-core/map/triggers.sp
+// NOTE: corresponds to climb_teleport_type in kz_mapping_api.fgd
+enum TeleportType
+{
+ TeleportType_Invalid = -1,
+ TeleportType_Normal,
+ TeleportType_MultiBhop,
+ TeleportType_SingleBhop,
+ TeleportType_SequentialBhop,
+ TELEPORTTYPE_COUNT
+};
+
+enum TriggerType
+{
+ TriggerType_Invalid = 0,
+ TriggerType_Teleport,
+ TriggerType_Antibhop
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define GOKZ_CHECKPOINT_VERSION 2
+#define GOKZ_MAX_CHECKPOINTS 2048
+#define GOKZ_MAX_COURSES 100
+
+#define GOKZ_BHOP_NO_CHECKPOINT_TIME 0.15
+#define GOKZ_MULT_NO_CHECKPOINT_TIME 0.11
+#define GOKZ_LADDER_NO_CHECKPOINT_TIME 1.5
+#define GOKZ_PAUSE_COOLDOWN 1.0
+#define GOKZ_TIMER_START_NO_TELEPORT_TICKS 4
+#define GOKZ_TIMER_START_GROUND_TICKS 4
+#define GOKZ_TIMER_START_NOCLIP_TICKS 4
+#define GOKZ_JUMPSTATS_NOCLIP_RESET_TICKS 4
+#define GOKZ_TIMER_SOUND_COOLDOWN 0.15
+#define GOKZ_VIRTUAL_BUTTON_USE_DETECTION_TIME 2.0
+#define GOKZ_TURNBIND_COOLDOWN 0.3
+
+#define GOKZ_MAPPING_API_VERSION_NONE 0 // the map doesn't have a mapping api version
+#define GOKZ_MAPPING_API_VERSION 1
+
+#define GOKZ_ANTI_BHOP_TRIGGER_DEFAULT_DELAY 0.2
+#define GOKZ_TELEPORT_TRIGGER_DEFAULT_TYPE TeleportType_Normal
+#define GOKZ_TELEPORT_TRIGGER_DEFAULT_DELAY 0.0
+#define GOKZ_TELEPORT_TRIGGER_DEFAULT_USE_DEST_ANGLES true
+#define GOKZ_TELEPORT_TRIGGER_DEFAULT_RESET_SPEED true
+#define GOKZ_TELEPORT_TRIGGER_DEFAULT_RELATIVE_DESTINATION false
+#define GOKZ_TELEPORT_TRIGGER_DEFAULT_REORIENT_PLAYER false
+#define GOKZ_TELEPORT_TRIGGER_BHOP_MIN_DELAY 0.08
+
+#define GOKZ_SOUND_CHECKPOINT "buttons/blip1.wav"
+#define GOKZ_SOUND_TELEPORT "buttons/blip1.wav"
+#define GOKZ_SOUND_TIMER_STOP "buttons/button18.wav"
+
+#define GOKZ_START_NAME "climb_start"
+#define GOKZ_BONUS_START_NAME_REGEX "^climb_bonus(\\d+)_start$"
+#define GOKZ_BONUS_END_NAME_REGEX "^climb_bonus(\\d+)_end$"
+
+#define GOKZ_START_BUTTON_NAME "climb_startbutton"
+#define GOKZ_END_BUTTON_NAME "climb_endbutton"
+#define GOKZ_BONUS_START_BUTTON_NAME_REGEX "^climb_bonus(\\d+)_startbutton$"
+#define GOKZ_BONUS_END_BUTTON_NAME_REGEX "^climb_bonus(\\d+)_endbutton$"
+#define GOKZ_ANTI_BHOP_TRIGGER_NAME "climb_anti_bhop"
+#define GOKZ_ANTI_CP_TRIGGER_NAME "climb_anti_checkpoint"
+#define GOKZ_ANTI_PAUSE_TRIGGER_NAME "climb_anti_pause"
+#define GOKZ_ANTI_JUMPSTAT_TRIGGER_NAME "climb_anti_jumpstat"
+#define GOKZ_BHOP_RESET_TRIGGER_NAME "climb_bhop_reset"
+#define GOKZ_TELEPORT_TRIGGER_NAME "climb_teleport"
+
+#define GOKZ_START_ZONE_NAME "climb_startzone"
+#define GOKZ_END_ZONE_NAME "climb_endzone"
+#define GOKZ_BONUS_START_ZONE_NAME_REGEX "^climb_bonus(\\d+)_startzone$"
+#define GOKZ_BONUS_END_ZONE_NAME_REGEX "^climb_bonus(\\d+)_endzone$"
+
+#define GOKZ_CFG_SERVER "sourcemod/gokz/gokz.cfg"
+#define GOKZ_CFG_OPTIONS "cfg/sourcemod/gokz/options.cfg"
+#define GOKZ_CFG_OPTIONS_SORTING "cfg/sourcemod/gokz/options_menu_sorting.cfg"
+#define GOKZ_CFG_OPTIONS_ROOT "Options"
+#define GOKZ_CFG_OPTIONS_DESCRIPTION "description"
+#define GOKZ_CFG_OPTIONS_DEFAULT "default"
+
+#define GOKZ_OPTION_MAX_NAME_LENGTH 30
+#define GOKZ_OPTION_MAX_DESC_LENGTH 255
+#define GENERAL_OPTION_CATEGORY "General"
+
+// TODO: where do i put the defines?
+#define GOKZ_BSP_HEADER_IDENTIFIER (('P' << 24) | ('S' << 16) | ('B' << 8) | 'V')
+#define GOKZ_ENTLUMP_MAX_KEY 32
+#define GOKZ_ENTLUMP_MAX_VALUE 1024
+
+#define GOKZ_MAX_MAPTRIGGERS_ERROR_LENGTH 256
+
+#define CHAR_ESCAPE view_as<char>(27)
+
+#define GOKZ_SAFEGUARD_RESTART_MIN_DELAY 0.6
+#define GOKZ_SAFEGUARD_RESTART_MAX_DELAY 5.0
+
+// Prevents the player from retouching a trigger too often.
+#define GOKZ_MAX_RETOUCH_TRIGGER_COUNT 4
+
+stock char gC_TimeTypeNames[TIMETYPE_COUNT][] =
+{
+ "NUB",
+ "PRO"
+};
+
+stock char gC_ModeNames[MODE_COUNT][] =
+{
+ "Vanilla",
+ "SimpleKZ",
+ "KZTimer"
+};
+
+stock char gC_ModeNamesShort[MODE_COUNT][] =
+{
+ "VNL",
+ "SKZ",
+ "KZT"
+};
+
+stock char gC_ModeKeys[MODE_COUNT][] =
+{
+ "vanilla",
+ "simplekz",
+ "kztimer"
+};
+
+stock float gF_ModeVirtualButtonRanges[MODE_COUNT] =
+{
+ 0.0,
+ 32.0,
+ 70.0
+};
+
+stock char gC_ModeStartSounds[MODE_COUNT][] =
+{
+ "common/wpn_select.wav",
+ "buttons/button9.wav",
+ "buttons/button3.wav"
+};
+
+stock char gC_ModeEndSounds[MODE_COUNT][] =
+{
+ "common/wpn_select.wav",
+ "buttons/bell1.wav",
+ "buttons/button3.wav"
+};
+
+stock char gC_ModeFalseEndSounds[MODE_COUNT][] =
+{
+ "common/wpn_select.wav",
+ "buttons/button11.wav",
+ "buttons/button2.wav"
+};
+
+stock char gC_StyleNames[STYLE_COUNT][] =
+{
+ "Normal"
+};
+
+stock char gC_StyleNamesShort[STYLE_COUNT][] =
+{
+ "NRM"
+};
+
+stock char gC_CoreOptionNames[OPTION_COUNT][] =
+{
+ "GOKZ - Mode",
+ "GOKZ - Style",
+ "GOKZ - Checkpoint Messages",
+ "GOKZ - Checkpoint Sounds",
+ "GOKZ - Teleport Sounds",
+ "GOKZ - Error Sounds",
+ "GOKZ - VB Indicators",
+ "GOKZ - Timer Button Zone Type",
+ "GOKZ - Button Through Players",
+ "GOKZ - Safeguard"
+};
+
+stock char gC_CoreOptionDescriptions[OPTION_COUNT][] =
+{
+ "Movement Mode - 0 = Vanilla, 1 = SimpleKZ, 2 = KZTimer",
+ "Movement Style - 0 = Normal",
+ "Checkpoint Messages - 0 = Disabled, 1 = Enabled",
+ "Checkpoint Sounds - 0 = Disabled, 1 = Enabled",
+ "Teleport Sounds - 0 = Disabled, 1 = Enabled",
+ "Error Sounds - 0 = Disabled, 1 = Enabled",
+ "Virtual Button Indicators - 0 = Disabled, 1 = Enabled",
+ "Timer Button Zone Type - 0 = Both buttons, 1 = Only end zone, 2 = Both zones",
+ "Button Through Players - 0 = Disabled, 1 = Enabled",
+ "Safeguard - 0 = Disabled, 1 = Enabled (NUB), 2 = Enabled (PRO)"
+};
+
+stock char gC_CoreOptionPhrases[OPTION_COUNT][] =
+{
+ "Options Menu - Mode",
+ "Options Menu - Style",
+ "Options Menu - Checkpoint Messages",
+ "Options Menu - Checkpoint Sounds",
+ "Options Menu - Teleport Sounds",
+ "Options Menu - Error Sounds",
+ "Options Menu - Virtual Button Indicators",
+ "Options Menu - Timer Button Zone Type",
+ "Options Menu - Button Through Players",
+ "Options Menu - Safeguard"
+};
+
+stock char gC_TimerButtonZoneTypePhrases[TIMERBUTTONZONETYPE_COUNT][] =
+{
+ "Timer Button Zone Type - Both Buttons",
+ "Timer Button Zone Type - Only End Zone",
+ "Timer Button Zone Type - Both Zones"
+};
+
+stock char gC_SafeGuardPhrases[SAFEGUARD_COUNT][] =
+{
+ "Options Menu - Disabled",
+ "Safeguard - Enabled NUB",
+ "Safeguard - Enabled PRO"
+}
+
+stock int gI_CoreOptionCounts[OPTION_COUNT] =
+{
+ MODE_COUNT,
+ STYLE_COUNT,
+ CHECKPOINTMESSAGES_COUNT,
+ CHECKPOINTSOUNDS_COUNT,
+ TELEPORTSOUNDS_COUNT,
+ ERRORSOUNDS_COUNT,
+ VIRTUALBUTTONINDICATORS_COUNT,
+ TIMERBUTTONZONETYPE_COUNT,
+ BUTTONTHROUGHPLAYERS_COUNT,
+ SAFEGUARD_COUNT
+};
+
+stock int gI_CoreOptionDefaults[OPTION_COUNT] =
+{
+ Mode_KZTimer,
+ Style_Normal,
+ CheckpointMessages_Disabled,
+ CheckpointSounds_Enabled,
+ TeleportSounds_Disabled,
+ ErrorSounds_Enabled,
+ VirtualButtonIndicators_Disabled,
+ TimerButtonZoneType_BothButtons,
+ ButtonThroughPlayers_Enabled,
+ Safeguard_Disabled
+};
+
+stock char gC_ModeCVars[MODECVAR_COUNT][] =
+{
+ "sv_accelerate",
+ "sv_accelerate_use_weapon_speed",
+ "sv_airaccelerate",
+ "sv_air_max_wishspeed",
+ "sv_enablebunnyhopping",
+ "sv_friction",
+ "sv_gravity",
+ "sv_jump_impulse",
+ "sv_ladder_scale_speed",
+ "sv_ledge_mantle_helper",
+ "sv_maxspeed",
+ "sv_maxvelocity",
+ "sv_staminajumpcost",
+ "sv_staminalandcost",
+ "sv_staminamax",
+ "sv_staminarecoveryrate",
+ "sv_standable_normal",
+ "sv_timebetweenducks",
+ "sv_walkable_normal",
+ "sv_wateraccelerate",
+ "sv_water_movespeed_multiplier",
+ "sv_water_swim_mode",
+ "sv_weapon_encumbrance_per_item",
+ "sv_weapon_encumbrance_scale"
+};
+
+
+// =====[ STRUCTS ]=====
+
+enum struct Checkpoint
+{
+ float origin[3];
+ float angles[3];
+ float ladderNormal[3];
+ bool onLadder;
+ int groundEnt;
+
+ void Create(int client)
+ {
+ Movement_GetOrigin(client, this.origin);
+ Movement_GetEyeAngles(client, this.angles);
+ GetEntPropVector(client, Prop_Send, "m_vecLadderNormal", this.ladderNormal);
+ this.onLadder = Movement_GetMovetype(client) == MOVETYPE_LADDER;
+ this.groundEnt = GetEntPropEnt(client, Prop_Data, "m_hGroundEntity");
+ }
+}
+
+enum struct UndoTeleportData
+{
+ float tempOrigin[3];
+ float tempAngles[3];
+ float origin[3];
+ float angles[3];
+ // Undo TP properties
+ bool lastTeleportOnGround;
+ bool lastTeleportInBhopTrigger;
+ bool lastTeleportInAntiCpTrigger;
+
+ void Init(int client, bool lastTeleportInBhopTrigger, bool lastTeleportOnGround, bool lastTeleportInAntiCpTrigger)
+ {
+ Movement_GetOrigin(client, this.tempOrigin);
+ Movement_GetEyeAngles(client, this.tempAngles);
+ this.lastTeleportInBhopTrigger = lastTeleportInBhopTrigger;
+ this.lastTeleportOnGround = lastTeleportOnGround;
+ this.lastTeleportInAntiCpTrigger = lastTeleportInAntiCpTrigger;
+ }
+
+ void Update()
+ {
+ this.origin = this.tempOrigin;
+ this.angles = this.tempAngles;
+ }
+}
+
+
+// NOTE: gokz-core/map/entlump.sp
+enum struct EntlumpToken
+{
+ EntlumpTokenType type;
+ char string[GOKZ_ENTLUMP_MAX_VALUE];
+}
+
+// NOTE: gokz-core/map/triggers.sp
+enum struct AntiBhopTrigger
+{
+ int entRef;
+ int hammerID;
+ float time;
+}
+
+enum struct TeleportTrigger
+{
+ int hammerID;
+ TeleportType type;
+ float delay;
+ char tpDestination[256];
+ bool useDestAngles;
+ bool resetSpeed;
+ bool relativeDestination;
+ bool reorientPlayer;
+}
+
+enum struct TouchedTrigger
+{
+ TriggerType triggerType;
+ int entRef; // entref of one of the TeleportTriggers
+ int startTouchTick; // tick where the player touched the trigger
+ int groundTouchTick; // tick where the player touched the ground
+}
+
+// Legacy triggers that activate timer buttons.
+enum struct TimerButtonTrigger
+{
+ int hammerID;
+ int course;
+ bool isStartTimer;
+}
+
+// =====[ FORWARDS ]=====
+
+/**
+ * Called when a player's options values are loaded from clientprefs.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnOptionsLoaded(int client);
+
+/**
+ * Called when a player's option's value is changed.
+ * Only called if client is in game.
+ *
+ * @param client Client index.
+ * @param option Option name.
+ * @param newValue New value of the option.
+ */
+forward void GOKZ_OnOptionChanged(int client, const char[] option, any newValue);
+
+/**
+ * Called when a player starts their timer.
+ *
+ * @param client Client index.
+ * @param course Course number.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnTimerStart(int client, int course);
+
+/**
+ * Called when a player has started their timer.
+ *
+ * @param client Client index.
+ * @param course Course number.
+ */
+forward void GOKZ_OnTimerStart_Post(int client, int course);
+
+/**
+ * Called when a player ends their timer.
+ *
+ * @param client Client index.
+ * @param course Course number.
+ * @param time Player's end time.
+ * @param teleportsUsed Number of teleports used by player.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnTimerEnd(int client, int course, float time, int teleportsUsed);
+
+/**
+ * Called when a player has ended their timer.
+ *
+ * @param client Client index.
+ * @param course Course number.
+ * @param time Player's end time.
+ * @param teleportsUsed Number of teleports used by player.
+ */
+forward void GOKZ_OnTimerEnd_Post(int client, int course, float time, int teleportsUsed);
+
+/**
+ * Called when the end timer message is printed to chat.
+ *
+ * @param client Client index.
+ * @param course Course number.
+ * @param time Player's end time.
+ * @param teleportsUsed Number of teleports used by player.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnTimerEndMessage(int client, int course, float time, int teleportsUsed);
+
+/**
+ * Called when a player's timer has been forcefully stopped.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnTimerStopped(int client);
+
+/**
+ * Called when a player pauses.
+ *
+ * @param client Client index.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnPause(int client);
+
+/**
+ * Called when a player has paused.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnPause_Post(int client);
+
+/**
+ * Called when a player resumes.
+ *
+ * @param client Client index.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnResume(int client);
+
+/**
+ * Called when a player has resumed.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnResume_Post(int client);
+
+/**
+ * Called when a player makes a checkpoint.
+ *
+ * @param client Client index.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnMakeCheckpoint(int client);
+
+/**
+ * Called when a player has made a checkpoint.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnMakeCheckpoint_Post(int client);
+
+/**
+ * Called when a player teleports to their checkpoint.
+ *
+ * @param client Client index.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnTeleportToCheckpoint(int client);
+
+/**
+ * Called when a player has teleported to their checkpoint.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnTeleportToCheckpoint_Post(int client);
+
+/**
+ * Called when a player goes to a previous checkpoint.
+ *
+ * @param client Client index.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnPrevCheckpoint(int client);
+
+/**
+ * Called when a player has gone to a previous checkpoint.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnPrevCheckpoint_Post(int client);
+
+/**
+ * Called when a player goes to a next checkpoint.
+ *
+ * @param client Client index.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnNextCheckpoint(int client);
+
+/**
+ * Called when a player has gone to a next checkpoint.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnNextCheckpoint_Post(int client);
+
+/**
+ * Called when a player teleports to start.
+ *
+ * @param client Client index.
+ * @param course Course index.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnTeleportToStart(int client, int course);
+
+/**
+ * Called when a player has teleported to start.
+ *
+ * @param client Client index.
+ * @param course Course index.
+ */
+forward void GOKZ_OnTeleportToStart_Post(int client, int course);
+
+/**
+ * Called when a player teleports to end.
+ *
+ * @param client Client index.
+ * @param course Course index.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnTeleportToEnd(int client, int course);
+
+/**
+ * Called when a player has teleported to end.
+ *
+ * @param client Client index.
+ * @param course Course index.
+ */
+forward void GOKZ_OnTeleportToEnd_Post(int client, int course);
+
+/**
+ * Called when a player undoes a teleport.
+ *
+ * @param client Client index.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnUndoTeleport(int client);
+
+/**
+ * Called when a player has undone a teleport.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnUndoTeleport_Post(int client);
+
+/**
+ * Called when a player has performed a counted teleport (teleport count went up)
+ * i.e. a catch-all for teleport to checkpoint, teleport to start, undo teleport etc.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnCountedTeleport_Post(int client);
+
+/**
+ * Called when a player's start position is set.
+ *
+ * @param client Client index.
+ * @param type Start position type.
+ * @param origin Start position origin.
+ * @param angles Start position eye angles.
+ */
+forward void GOKZ_OnStartPositionSet_Post(int client, StartPositionType type, const float origin[3], const float angles[3]);
+
+/**
+ * Called when player's begins a jump that is deemed valid.
+ * A jump is deemed invalid if a player is teleported.
+ *
+ * @param client Client index.
+ * @param jumped Whether player jumped.
+ * @param ladderJump Whether it was a ladder jump.
+ * @param jumpbug Whether player performed a jumpbug.
+ */
+forward void GOKZ_OnJumpValidated(int client, bool jumped, bool ladderJump, bool jumpbug);
+
+/**
+ * Called when player's current jump is invalidated.
+ * A jump is deemed invalid if a player is teleported.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnJumpInvalidated(int client);
+
+/**
+ * Called when a player has been switched to a team.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnJoinTeam(int client, int team);
+
+/**
+ * Called the first time a player spawns in on a team.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnFirstSpawn(int client);
+
+/**
+ * Called when a mode has been loaded.
+ *
+ * @param mode Mode loaded.
+ */
+forward void GOKZ_OnModeLoaded(int mode);
+
+/**
+ * Called when a mode has been unloaded.
+ *
+ * @param mode Mode unloaded.
+ */
+forward void GOKZ_OnModeUnloaded(int mode);
+
+/**
+ * Called when a plugin other than gokz-core calls a native
+ * that may affect a player's timer or teleport count in
+ * their favour e.g. GOKZ_StartTimer, GOKZ_EndTimer,
+ * GOKZ_SetTime and GOKZ_SetTeleportCount.
+ *
+ * @param plugin Handle of the calling plugin.
+ * @param client Client index.
+ * @return Plugin_Handled or Plugin_Stop to block, Plugin_Continue to proceed.
+ */
+forward Action GOKZ_OnTimerNativeCalledExternally(Handle plugin, int client);
+
+/**
+ * Called when the options menu has been created and 3rd
+ * party plugins can grab the handle or add categories.
+ *
+ * @param topMenu Options top menu handle.
+ */
+forward void GOKZ_OnOptionsMenuCreated(TopMenu topMenu);
+
+/**
+ * Called when the options menu is ready to have items added.
+ *
+ * @param topMenu Options top menu handle.
+ */
+forward void GOKZ_OnOptionsMenuReady(TopMenu topMenu);
+
+/**
+ * Called when a course is registered. A course is registered if both the
+ * start and end of it (e.g. timer buttons) have been detected.
+ *
+ * @param course Course number.
+ */
+forward void GOKZ_OnCourseRegistered(int course);
+
+/**
+ * Called when a player's run becomes invalidated.
+ * An invalidated run doesn't necessarily stop the timer.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_OnRunInvalidated(int client);
+
+/**
+ * Called when a sound is emitted to the client via GOKZ Core.
+ *
+ * @param client Client index.
+ * @param sample Sound file name relative to the "sound" folder.
+ * @param volume Sound volume.
+ * @param description Optional description.
+ * @return Plugin_Continue to allow the sound to be played, Plugin_Stop to block it,
+ * Plugin_Changed when any parameter has been modified.
+ */
+forward Action GOKZ_OnEmitSoundToClient(int client, const char[] sample, float &volume, const char[] description);
+
+
+// =====[ NATIVES ]=====
+
+/**
+ * Gets whether a mode is loaded.
+ *
+ * @param mode Mode.
+ * @return Whether mode is loaded.
+ */
+native bool GOKZ_GetModeLoaded(int mode);
+
+/**
+ * Gets the version number of a loaded mode.
+ *
+ * @param mode Mode.
+ * @return Version number of the mode, or -1 if not loaded.
+ */
+native int GOKZ_GetModeVersion(int mode);
+
+/**
+ * Sets whether a mode is loaded. To be used by mode plugins.
+ *
+ * @param mode Mode.
+ * @param loaded Whether mode is loaded.
+ * @param version Version number of the mode.
+ */
+native void GOKZ_SetModeLoaded(int mode, bool loaded, int version = -1);
+
+/**
+ * Gets the total number of loaded modes.
+ *
+ * @return Number of loaded modes.
+ */
+native int GOKZ_GetLoadedModeCount();
+
+/**
+ * Sets the player's current mode.
+ * If the player's timer is running, it will be stopped.
+ *
+ * @param client Client index.
+ * @param mode Mode.
+ * @return Whether the operation was successful.
+ */
+native bool GOKZ_SetMode(int client, int mode);
+
+/**
+ * Gets the Handle to the options top menu.
+ *
+ * @return Handle to the options top menu,
+ * or null if not created yet.
+ */
+native TopMenu GOKZ_GetOptionsTopMenu();
+
+/**
+ * Gets whether a course is registered. A course is registered if both the
+ * start and end of it (e.g. timer buttons) have been detected.
+ *
+ * @param course Course number.
+ * @return Whether course has been registered.
+ */
+native bool GOKZ_GetCourseRegistered(int course);
+
+/**
+ * Prints a message to a client's chat, formatting colours and optionally
+ * adding the chat prefix. If using the chat prefix, specify a colour at
+ * the beginning of the message e.g. "{default}Hello!".
+ *
+ * @param client Client index.
+ * @param addPrefix Whether to add the chat prefix.
+ * @param format Formatting rules.
+ * @param any Variable number of format parameters.
+ */
+native void GOKZ_PrintToChat(int client, bool addPrefix, const char[] format, any...);
+
+/**
+ * Prints a message to a client's chat, formatting colours and optionally
+ * adding the chat prefix. If using the chat prefix, specify a colour at
+ * the beginning of the message e.g. "{default}Hello!". Also prints the
+ * message to the server log.
+ *
+ * @param client Client index.
+ * @param addPrefix Whether to add the chat prefix.
+ * @param format Formatting rules.
+ * @param any Variable number of format parameters.
+ */
+native void GOKZ_PrintToChatAndLog(int client, bool addPrefix, const char[] format, any...);
+
+/**
+ * Starts a player's timer for a course on the current map.
+ * This can be blocked by OnTimerNativeCalledExternally().
+ *
+ * @param client Client index.
+ * @param course Course number.
+ * @param allowMidair Whether player is allowed to start timer midair.
+ * @return Whether player's timer was started.
+ */
+native bool GOKZ_StartTimer(int client, int course, bool allowOffGround = false);
+
+/**
+ * Ends a player's timer for a course on the current map.
+ * This can be blocked by OnTimerNativeCalledExternally().
+ *
+ * @param client Client index.
+ * @param course Course number.
+ * @return Whether player's timer was ended.
+ */
+native bool GOKZ_EndTimer(int client, int course);
+
+/**
+ * Forces a player's timer to stop. Intended for run invalidation.
+ *
+ * @param client Client index.
+ * @param playSound Whether to play the timer stop sound.
+ * @return Whether player's timer was stopped.
+ */
+native bool GOKZ_StopTimer(int client, bool playSound = true);
+
+/**
+ * Forces all players' timers to stop. Intended for run invalidation.
+ *
+ * @param playSound Whether to play the timer stop sound.
+ */
+native void GOKZ_StopTimerAll(bool playSound = true);
+
+/**
+ * Gets whether or not a player's timer is running i.e. isn't 'stopped'.
+ *
+ * @param client Client index.
+ * @return Whether player's timer is running.
+ */
+native bool GOKZ_GetTimerRunning(int client);
+
+/**
+ * Gets whether or not a player's timer is valid i.e the run is a valid run.
+ *
+ * @param client Client index.
+ * @return Whether player's timer is running.
+ */
+native bool GOKZ_GetValidTimer(int client);
+
+/**
+ * Gets the course a player is currently running.
+ *
+ * @param client Client index.
+ * @return Course number.
+ */
+native int GOKZ_GetCourse(int client);
+
+/**
+ * Set the player's current course.
+ * This can be blocked by OnTimerNativeCalledExternally().
+ *
+ * @param client Client index.
+ * @param course Course number.
+ * @return Whether native was allowed to proceed.
+ */
+native bool GOKZ_SetCourse(int client, int course);
+
+/**
+ * Gets whether a player is paused.
+ *
+ * @param client Client index.
+ * @return Whether player is paused.
+ */
+native bool GOKZ_GetPaused(int client);
+
+/**
+ * Gets a player's current run time.
+ *
+ * @param client Client index.
+ * @return Player's current run time.
+ */
+native float GOKZ_GetTime(int client);
+
+/**
+ * Gets a player's current run time.
+ * This can be blocked by OnTimerNativeCalledExternally().
+ *
+ * @param client Client index.
+ * @param time Run time to set to.
+ * @return Whether native was allowed to proceed.
+ */
+native bool GOKZ_SetTime(int client, float time);
+
+/**
+ * Mark a player's run as invalid without stopping the timer.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_InvalidateRun(int client);
+
+/**
+ * Gets a player's current checkpoint count.
+ *
+ * @param client Client index.
+ * @return Player's current checkpoint count.
+ */
+native int GOKZ_GetCheckpointCount(int client);
+
+/**
+ * Sets a player's current checkpoint count.
+ * This can be blocked by OnTimerNativeCalledExternally().
+ *
+ * @param client Client index.
+ * @param cpCount Checkpoint count to set to.
+ * @return Whether native was allowed to proceed.
+ */
+native int GOKZ_SetCheckpointCount(int client, int cpCount);
+
+/**
+ * Gets checkpoint data of a player.
+ *
+ * @param client Client index.
+ * @return Client's checkpoint data.
+ */
+native ArrayList GOKZ_GetCheckpointData(int client);
+
+/**
+ * Sets checkpoint data of a player. The checkpoint data is assumed to be ordered.
+ * This can be blocked by OnTimerNativeCalledExternally().
+ *
+ * @param client Client index.
+ * @param checkpoints Checkpoint data.
+ * @param version Checkpoint version.
+ * @return Whether native was allowed to proceed and operation was successful.
+ */
+native bool GOKZ_SetCheckpointData(int client, ArrayList checkpoints, int version);
+
+/**
+ * Get undo teleport data of a player.
+ *
+ * @param client Client index.
+ * @return ArrayList of length 1 containing player's undo teleport data.
+ */
+native ArrayList GOKZ_GetUndoTeleportData(int client);
+
+/**
+ * Set undo teleport data of a player.
+ * This can be blocked by OnTimerNativeCalledExternally().
+ *
+ * @param client Client index.
+ * @param undoTeleportDataArray ArrayList of length 1 containing player's undo teleport data.
+ * @param version Checkpoint version.
+ * @return Whether native was allowed to proceed and operation was successful.
+ */
+native bool GOKZ_SetUndoTeleportData(int client, ArrayList undoTeleportDataArray, int version);
+
+/**
+ * Gets a player's current teleport count.
+ *
+ * @param client Client index.
+ * @return Player's current teleport count.
+ */
+native int GOKZ_GetTeleportCount(int client);
+
+/**
+ * Sets a player's current teleport count.
+ * This can be blocked by OnTimerNativeCalledExternally().
+ *
+ * @param client Client index.
+ * @param tpCount Teleport count to set to.
+ * @return Whether native was allowed to proceed.
+ */
+native bool GOKZ_SetTeleportCount(int client, int tpCount);
+
+/**
+ * Teleports a player to start, or respawns them.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_TeleportToStart(int client);
+
+/**
+ * Teleports a player to the start zone/button of the specified course.
+ *
+ * @param client Client index.
+ * @param course Course index.
+ */
+native void GOKZ_TeleportToSearchStart(int client, int course);
+
+/**
+ * Gets the virtual button position the player currently has.
+ *
+ * @param client Client index.
+ * @param position Returns the client's virtual button position.
+ * @param isStart True to get the start button position, false for the end button.
+ * @return The course the button belongs to.
+ */
+native int GOKZ_GetVirtualButtonPosition(int client, float position[3], bool isStart);
+
+/**
+ * Sets the virtual button position the player currently has.
+ *
+ * @param client Client index.
+ * @param position The client's virtual button position.
+ * @param course The course the virtual button belongs to.
+ * @param isStart True to get the start button position, false for the end button.
+ */
+native void GOKZ_SetVirtualButtonPosition(int client, const float position[3], int course, bool isStart);
+
+/**
+ * Resets the player's virtual button.
+ *
+ * @param client Client index.
+ * @param isStart True to get the start button position, false for the end button.
+ */
+native void GOKZ_ResetVirtualButtonPosition(int client, bool isStart);
+
+/**
+ * Locks the virtual button position of a player.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_LockVirtualButtons(int client);
+
+/**
+ * Gets the start position the player currently has.
+ *
+ * @param client Client index.
+ * @param position Returns the client's start position.
+ * @param angles Returns the client's start angles.
+ * @return Player's current start position type.
+ */
+native StartPositionType GOKZ_GetStartPosition(int client, float position[3], float angles[3]);
+
+/**
+ * Sets the start position the player currently has.
+ *
+ * @param client Client index.
+ * @param type The start position type.
+ * @param position The client's start position.
+ * @param angles The client's start angles.
+ */
+native void GOKZ_SetStartPosition(int client, StartPositionType type, const float position[3], const float angles[3]);
+
+/**
+ * Gets the type of start position the player currently has.
+ * The "Spawn" type means teleport to start will respawn the player.
+ *
+ * @param client Client index.
+ * @return Player's current start position type.
+ */
+native StartPositionType GOKZ_GetStartPositionType(int client);
+
+/**
+ * Set the start position of the player to the start of a course.
+ *
+ * @param client Client index.
+ * @param course Course index.
+ *
+ * @return False if the course start was not found.
+ */
+native bool GOKZ_SetStartPositionToMapStart(int client, int course);
+
+/**
+ * Teleports a player to end.
+ *
+ * @param client Client index.
+ * @param course Course index.
+ */
+native void GOKZ_TeleportToEnd(int client, int course);
+
+/**
+ * Set a new checkpoint at a player's current position.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_MakeCheckpoint(int client);
+
+/**
+ * Gets whether a player can make a new checkpoint.
+ * @param client Client index.
+ * @return Whether player can set a checkpoint.
+ */
+native bool GOKZ_GetCanMakeCheckpoint(int client);
+
+/**
+ * Teleports a player to their last checkpoint.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_TeleportToCheckpoint(int client);
+
+/**
+ * Gets whether a player can teleport to their checkpoint
+ * e.g. will return false if player has no checkpoints.
+ *
+ * @param client Client index.
+ * @return Whether player can teleport to checkpoint.
+ */
+native bool GOKZ_GetCanTeleportToCheckpoint(int client);
+
+/**
+ * Teleport a player back to a previous checkpoint.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_PrevCheckpoint(int client);
+
+/**
+ * Gets whether a player can go to their previous checkpoint
+ * e.g. will return false if player has no checkpoints.
+ *
+ * @param client Client index.
+ * @return Whether player can go to previous checkpoint.
+ */
+native bool GOKZ_GetCanPrevCheckpoint(int client);
+
+/**
+ * Teleport a player to a more recent checkpoint.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_NextCheckpoint(int client);
+
+/**
+ * Gets whether a player can go to their next checkpoint
+ * e.g. will return false if player has no checkpoints.
+ *
+ * @param client Client index.
+ * @return Whether player can go to next checkpoint.
+ */
+native bool GOKZ_GetCanNextCheckpoint(int client);
+
+/**
+ * Teleport a player to where they last teleported from.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_UndoTeleport(int client);
+
+/**
+ * Gets whether a player can undo their teleport
+ * e.g. will return false if teleport was from midair.
+ *
+ * @param client Client index.
+ * @return Whether player can undo teleport.
+ */
+native bool GOKZ_GetCanUndoTeleport(int client);
+
+/**
+ * Pause a player's timer and freeze them.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_Pause(int client);
+
+/**
+ * Gets whether a player can pause. Pausing is not allowed
+ * under some circumstance when the timer is running.
+ *
+ * @param client Client index.
+ */
+native bool GOKZ_GetCanPause(int client);
+
+/**
+ * Resumes a player's timer and unfreezes them.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_Resume(int client);
+
+/**
+ * Gets whether a player can resume. Resuming is not allowed
+ * under some circumstance when the timer is running.
+ *
+ * @param client Client index.
+ */
+native bool GOKZ_GetCanResume(int client);
+
+/**
+ * Toggles the paused state of a player.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_TogglePause(int client);
+
+/**
+ * Gets whether a player can teleport to start.
+ *
+ * @param client Client index.
+ * @return Whether player can teleport to start.
+ */
+native bool GOKZ_GetCanTeleportToStartOrEnd(int client);
+
+/**
+ * Plays the error sound to a player if they have the option enabled.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_PlayErrorSound(int client);
+
+/**
+ * Set the origin of a player without invalidating any jumpstats.
+ *
+ * Only use this in plugins that create a new mode!
+ *
+ * @param client Client index.
+ * @param origin The new origin.
+ */
+native void GOKZ_SetValidJumpOrigin(int client, const float origin[3]);
+
+/**
+ * Registers an option with gokz-core, which uses clientprefs to
+ * keep track of the option's value and to save it to a database.
+ * This also effectively provides natives and forwards for other
+ * plugins to access any options that have been registered.
+ *
+ * @param name Option name.
+ * @param description Option description.
+ * @param type Type to treat the option value as.
+ * @param defaultValue Default value of option.
+ * @param minValue Minimum value of option.
+ * @param maxValue Maximum value of option.
+ * @return Whether registration was successful.
+ */
+native bool GOKZ_RegisterOption(const char[] name, const char[] description, OptionType type, any defaultValue, any minValue, any maxValue);
+
+/**
+ * Gets a property of a registered option. If used outside of
+ * gokz-core to get the cookie, a clone of its Handle is returned.
+ *
+ * @param option Option name.
+ * @param prop Option property to get.
+ * @return Value of property, or -1 (int) if option isn't registered.
+ */
+native any GOKZ_GetOptionProp(const char[] option, OptionProp prop);
+
+/**
+ * Sets a property of a registered option. For safety and simplicity,
+ * the cookie property is read-only and will fail to be set.
+ *
+ * @param option Option name.
+ * @param prop Option property to set.
+ * @param value Value to set the property to.
+ * @return Whether option property was successfully set.
+ */
+native bool GOKZ_SetOptionProp(const char[] option, OptionProp prop, any value);
+
+/**
+ * Gets the current value of a player's option.
+ *
+ * @param client Client index.
+ * @param option Option name.
+ * @return Current value of option, or -1 (int) if option isn't registered.
+ */
+native any GOKZ_GetOption(int client, const char[] option);
+
+/**
+ * Sets a player's option's value. Fails if option doesn't exist,
+ * or if desired value is outside the registered value range.
+ *
+ * @param client Client index.
+ * @param option Option name.
+ * @param value New option value.
+ * @return Whether option was successfully set.
+ */
+native bool GOKZ_SetOption(int client, const char[] option, any value);
+
+/**
+ * Gets whether player's last takeoff was a perfect bunnyhop as adjusted by GOKZ.
+ *
+ * @param client Client index.
+ * @return Whether player's last takeoff was a GOKZ perfect b-hop.
+ */
+native bool GOKZ_GetHitPerf(int client);
+
+/**
+ * Sets whether player's last takeoff was a perfect bunnyhop as adjusted by GOKZ.
+ * Intended to be called by GOKZ mode plugins only.
+ *
+ * @param client Client index.
+ * @param hitPerf Whether player's last takeoff was a GOKZ perfect b-hop.
+ */
+native void GOKZ_SetHitPerf(int client, bool hitPerf);
+
+/**
+ * Gets a player's horizontal speed at the time of their last takeoff as recorded by GOKZ.
+ *
+ * @param client Client index.
+ * @return Player's last takeoff speed as recorded by GOKZ.
+ */
+native float GOKZ_GetTakeoffSpeed(int client);
+
+/**
+ * Sets a player's recorded horizontal speed at the time of their last takeoff.
+ * Intended to be called by GOKZ mode plugins only.
+ *
+ * @param client Client index.
+ * @param takeoffSpeed Player's last takeoff speed as recorded by GOKZ.
+ */
+native void GOKZ_SetTakeoffSpeed(int client, float takeoffSpeed);
+
+/**
+ * Gets whether a player's current or last jump/airtime is valid.
+ * A jump is deemed invalid if the player is teleported.
+ *
+ * @param client Client index.
+ * @return Validity of player's current or last jump.
+ */
+native bool GOKZ_GetValidJump(int client);
+
+/**
+ * Has a player switch to a team via GOKZ Core.
+ *
+ * @param client Client index.
+ * @param team Which team to switch to.
+ * @param restorePos Whether to restore saved position if leaving spectators.
+ * @param forceBroadcast Force JoinTeam forward calling even if client's team did not change.
+ */
+native void GOKZ_JoinTeam(int client, int team, bool restorePos = true, bool forceBroadcast = false);
+
+/**
+ * Emit a sound to a player via GOKZ Core.
+ * Sounds emitted by this native will call GOKZ_OnEmitSoundToClient forward.
+ *
+ * @param client Client index.
+ * @param sample Sound file name relative to the "sound" folder.
+ * @param volume Sound volume.
+ * @param description Optional description.
+ */
+native void GOKZ_EmitSoundToClient(int client, const char[] sample, float volume = SNDVOL_NORMAL, const char[] description = "");
+
+
+// =====[ STOCKS ]=====
+
+/**
+ * Makes a player join a team if they aren't on one and respawns them.
+ *
+ * @param client Client index.
+ * @param team Which team to switch to if not on one.
+ * @param restorePos Whether to restore saved position if leaving spectators.
+ */
+stock void GOKZ_RespawnPlayer(int client, int team = CS_TEAM_T, bool restorePos = true)
+{
+ if (IsSpectating(client))
+ {
+ GOKZ_JoinTeam(client, team, restorePos);
+ }
+ else
+ {
+ CS_RespawnPlayer(client);
+ }
+}
+
+/**
+ * Prints a message to all client's chat, formatting colours and optionally
+ * adding the chat prefix. If using the chat prefix, specify a colour at
+ * the beginning of the message e.g. "{default}Hello!".
+ *
+ * @param addPrefix Whether to add the chat prefix.
+ * @param format Formatting rules.
+ * @param any Variable number of format parameters.
+ */
+stock void GOKZ_PrintToChatAll(bool addPrefix, const char[] format, any...)
+{
+ char buffer[1024];
+ for (int client = 1; client <= MaxClients; client++)
+ {
+ if (IsClientInGame(client))
+ {
+ SetGlobalTransTarget(client);
+ VFormat(buffer, sizeof(buffer), format, 3);
+ GOKZ_PrintToChat(client, addPrefix, buffer);
+ }
+ }
+}
+
+/**
+ * Prints a chat message to those spectating the client, formatting colours
+ * and optionally adding the chat prefix. If using the chat prefix, specify
+ * a colour at the beginning of the message e.g. "{default}Hello!".
+ *
+ * @param client Client index.
+ * @param addPrefix Whether to add the chat prefix.
+ * @param format Formatting rules.
+ * @param any Variable number of format parameters.
+ */
+stock void GOKZ_PrintToChatSpectators(int client, bool addPrefix, const char[] format, any...)
+{
+ char buffer[1024];
+ for (int target = 1; target <= MaxClients; target++)
+ {
+ if (IsClientInGame(target) && GetObserverTarget(target) == client)
+ {
+ SetGlobalTransTarget(target);
+ VFormat(buffer, sizeof(buffer), format, 4);
+ GOKZ_PrintToChat(target, addPrefix, buffer);
+ }
+ }
+}
+
+/**
+ * Gets the player's current time type.
+ *
+ * @param client Client index.
+ * @return Player's current time type.
+ */
+stock int GOKZ_GetTimeType(int client)
+{
+ return GOKZ_GetTimeTypeEx(GOKZ_GetTeleportCount(client));
+}
+
+/**
+ * Gets the time type given a teleport count.
+ *
+ * @param teleports Teleport count.
+ * @return Time type.
+ */
+stock int GOKZ_GetTimeTypeEx(int teleportCount)
+{
+ if (teleportCount == 0)
+ {
+ return TimeType_Pro;
+ }
+ return TimeType_Nub;
+}
+
+/**
+ * Clears and populates a menu with an item for each mode
+ * in order of the mode enumeration. Highlights the client's
+ * selected mode with an asterisk.
+ *
+ * @param client Client index to check selected mode.
+ * @param menu Menu to populate items with.
+ * @param disableUnloadedModes Draw items for unloaded modes as disabled.
+ */
+stock void GOKZ_MenuAddModeItems(int client, Menu menu, bool disableUnloadedModes)
+{
+ int selectedMode = GOKZ_GetCoreOption(client, Option_Mode);
+ char display[32];
+
+ menu.RemoveAllItems();
+
+ for (int mode = 0; mode < MODE_COUNT; mode++)
+ {
+ FormatEx(display, sizeof(display), "%s", gC_ModeNames[mode]);
+ // Add asterisk to selected mode
+ if (mode == selectedMode)
+ {
+ Format(display, sizeof(display), "%s*", display);
+ }
+
+ if (GOKZ_GetModeLoaded(mode))
+ {
+ menu.AddItem("", display, ITEMDRAW_DEFAULT);
+ }
+ else
+ {
+ menu.AddItem("", display, ITEMDRAW_DISABLED);
+ }
+ }
+}
+
+/**
+ * Increment an (integer-type) option's value.
+ * Loops back to min. value if max. value is exceeded.
+ *
+ * @param client Client index.
+ * @param option Option name.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_CycleOption(int client, const char[] option)
+{
+ int maxValue = GOKZ_GetOptionProp(option, OptionProp_MaxValue);
+ if (maxValue == -1)
+ {
+ return false;
+ }
+
+ int newValue = GOKZ_GetOption(client, option) + 1;
+ if (newValue > GOKZ_GetOptionProp(option, OptionProp_MaxValue))
+ {
+ newValue = GOKZ_GetOptionProp(option, OptionProp_MinValue);
+ }
+ return GOKZ_SetOption(client, option, newValue);
+}
+
+/**
+ * Returns whether an option is a gokz-core option.
+ *
+ * @param option Option name.
+ * @param optionEnum Variable to store enumerated gokz-core option (if it is one).
+ * @return Whether option is a gokz-core option.
+ */
+stock bool GOKZ_IsCoreOption(const char[] option, Option &optionEnum = OPTION_INVALID)
+{
+ for (Option i; i < OPTION_COUNT; i++)
+ {
+ if (StrEqual(option, gC_CoreOptionNames[i]))
+ {
+ optionEnum = i;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Gets a property of a gokz-core option.
+ *
+ * @param coreOption gokz-core option.
+ * @param prop Option property to get.
+ * @return Value of property, or -1 if option isn't registered.
+ */
+stock any GOKZ_GetCoreOptionProp(Option option, OptionProp prop)
+{
+ return GOKZ_GetOptionProp(gC_CoreOptionNames[option], prop);
+}
+
+/**
+ * Gets the current value of a player's gokz-core option.
+ *
+ * @param client Client index.
+ * @param option gokz-core option.
+ * @return Current value of option.
+ */
+stock any GOKZ_GetCoreOption(int client, Option option)
+{
+ return GOKZ_GetOption(client, gC_CoreOptionNames[option]);
+}
+
+/**
+ * Sets the player's gokz-core option's value.
+ *
+ * @param client Client index.
+ * @param option gokz-core option.
+ * @param value New option value.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_SetCoreOption(int client, Option option, any value)
+{
+ return GOKZ_SetOption(client, gC_CoreOptionNames[option], value);
+}
+
+/**
+ * Increment an integer-type gokz-core option's value.
+ * Loops back to '0' if max value is exceeded.
+ *
+ * @param client Client index.
+ * @param option gokz-core option.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_CycleCoreOption(int client, Option option)
+{
+ return GOKZ_CycleOption(client, gC_CoreOptionNames[option]);
+}
+
+/**
+ * Gets the current default mode.
+ *
+ * @return Default mode.
+ */
+stock int GOKZ_GetDefaultMode()
+{
+ return GOKZ_GetCoreOptionProp(Option_Mode, OptionProp_DefaultValue);
+}
+
+/**
+ * Returns whether a course number is a valid (within valid range).
+ *
+ * @param course Course number.
+ * @param bonus Whether to only consider bonus course numbers as valid.
+ * @return Whether course number is valid.
+ */
+stock bool GOKZ_IsValidCourse(int course, bool bonus = false)
+{
+ return (!bonus && course == 0) || (0 < course && course < GOKZ_MAX_COURSES);
+}
+
+/**
+ * Returns an integer from an entity's name as matched using a regular expression.
+ *
+ * @param entity Entity index.
+ * @param re Regular expression to match the integer with.
+ * @param substringID ID of the substring that will contain the integer.
+ * @returns Integer found in the entity's name, or -1 if not found.
+ */
+stock int GOKZ_MatchIntFromEntityName(int entity, Regex re, int substringID)
+{
+ int num = -1;
+ char buffer[32];
+ GetEntityName(entity, buffer, sizeof(buffer));
+
+ if (re.Match(buffer) > 0)
+ {
+ re.GetSubString(1, buffer, sizeof(buffer));
+ num = StringToInt(buffer);
+ }
+
+ return num;
+}
+
+/**
+ * Emits a sound to other players that are spectating the client.
+ * Sounds emitted by this function will call GOKZ_OnEmitSoundToClient forward.
+ *
+ * @param sample Sound file name relative to the "sound" folder.
+ * @param volume Sound volume.
+ * @param description Optional description.
+ */
+stock void GOKZ_EmitSoundToAll(const char[] sample, float volume = SNDVOL_NORMAL, const char[] description = "")
+{
+ for (int client = 1; client <= MaxClients; client++)
+ {
+ if (IsClientInGame(client))
+ {
+ GOKZ_EmitSoundToClient(client, sample, volume, description);
+ }
+ }
+}
+
+/**
+ * Emits a sound to other players that are spectating the client.
+ * Sounds emitted by this function will call GOKZ_OnEmitSoundToClient forward.
+ *
+ * @param client Client being spectated.
+ * @param sample Sound file name relative to the "sound" folder.
+ * @param volume Sound volume.
+ * @param description Optional description.
+ */
+stock void GOKZ_EmitSoundToClientSpectators(int client, const char[] sample, float volume = SNDVOL_NORMAL, const char[] description = "")
+{
+ for (int i = 1; i <= MaxClients; i++)
+ {
+ if (IsValidClient(i) && GetObserverTarget(i) == client)
+ {
+ GOKZ_EmitSoundToClient(i, sample, volume);
+ }
+ }
+}
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_core =
+{
+ name = "gokz-core",
+ file = "gokz-core.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_core_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_GetModeLoaded");
+ MarkNativeAsOptional("GOKZ_GetModeVersion");
+ MarkNativeAsOptional("GOKZ_SetModeLoaded");
+ MarkNativeAsOptional("GOKZ_GetLoadedModeCount");
+ MarkNativeAsOptional("GOKZ_SetMode");
+ MarkNativeAsOptional("GOKZ_GetOptionsTopMenu");
+ MarkNativeAsOptional("GOKZ_GetCourseRegistered");
+ MarkNativeAsOptional("GOKZ_PrintToChat");
+ MarkNativeAsOptional("GOKZ_PrintToChatAndLog");
+ MarkNativeAsOptional("GOKZ_StartTimer");
+ MarkNativeAsOptional("GOKZ_EndTimer");
+ MarkNativeAsOptional("GOKZ_StopTimer");
+ MarkNativeAsOptional("GOKZ_StopTimerAll");
+ MarkNativeAsOptional("GOKZ_TeleportToStart");
+ MarkNativeAsOptional("GOKZ_TeleportToSearchStart");
+ MarkNativeAsOptional("GOKZ_GetVirtualButtonPosition");
+ MarkNativeAsOptional("GOKZ_SetVirtualButtonPosition");
+ MarkNativeAsOptional("GOKZ_ResetVirtualButtonPosition");
+ MarkNativeAsOptional("GOKZ_LockVirtualButtons");
+ MarkNativeAsOptional("GOKZ_GetStartPosition");
+ MarkNativeAsOptional("GOKZ_SetStartPosition");
+ MarkNativeAsOptional("GOKZ_GetStartPositionType");
+ MarkNativeAsOptional("GOKZ_SetStartPositionToMapStart");
+ MarkNativeAsOptional("GOKZ_TeleportToEnd");
+ MarkNativeAsOptional("GOKZ_MakeCheckpoint");
+ MarkNativeAsOptional("GOKZ_GetCanMakeCheckpoint");
+ MarkNativeAsOptional("GOKZ_TeleportToCheckpoint");
+ MarkNativeAsOptional("GOKZ_GetCanTeleportToCheckpoint");
+ MarkNativeAsOptional("GOKZ_PrevCheckpoint");
+ MarkNativeAsOptional("GOKZ_GetCanPrevCheckpoint");
+ MarkNativeAsOptional("GOKZ_NextCheckpoint");
+ MarkNativeAsOptional("GOKZ_GetCanNextCheckpoint");
+ MarkNativeAsOptional("GOKZ_UndoTeleport");
+ MarkNativeAsOptional("GOKZ_GetCanUndoTeleport");
+ MarkNativeAsOptional("GOKZ_Pause");
+ MarkNativeAsOptional("GOKZ_GetCanPause");
+ MarkNativeAsOptional("GOKZ_Resume");
+ MarkNativeAsOptional("GOKZ_GetCanResume");
+ MarkNativeAsOptional("GOKZ_TogglePause");
+ MarkNativeAsOptional("GOKZ_GetCanTeleportToStartOrEnd");
+ MarkNativeAsOptional("GOKZ_PlayErrorSound");
+ MarkNativeAsOptional("GOKZ_SetValidJumpOrigin");
+ MarkNativeAsOptional("GOKZ_GetTimerRunning");
+ MarkNativeAsOptional("GOKZ_GetCourse");
+ MarkNativeAsOptional("GOKZ_SetCourse");
+ MarkNativeAsOptional("GOKZ_GetPaused");
+ MarkNativeAsOptional("GOKZ_GetTime");
+ MarkNativeAsOptional("GOKZ_SetTime");
+ MarkNativeAsOptional("GOKZ_InvalidateRun");
+ MarkNativeAsOptional("GOKZ_GetCheckpointCount");
+ MarkNativeAsOptional("GOKZ_SetCheckpointCount");
+ MarkNativeAsOptional("GOKZ_GetCheckpointData");
+ MarkNativeAsOptional("GOKZ_SetCheckpointData");
+ MarkNativeAsOptional("GOKZ_GetUndoTeleportData");
+ MarkNativeAsOptional("GOKZ_SetUndoTeleportData");
+ MarkNativeAsOptional("GOKZ_GetTeleportCount");
+ MarkNativeAsOptional("GOKZ_SetTeleportCount");
+ MarkNativeAsOptional("GOKZ_RegisterOption");
+ MarkNativeAsOptional("GOKZ_GetOptionProp");
+ MarkNativeAsOptional("GOKZ_SetOptionProp");
+ MarkNativeAsOptional("GOKZ_GetOption");
+ MarkNativeAsOptional("GOKZ_SetOption");
+ MarkNativeAsOptional("GOKZ_GetHitPerf");
+ MarkNativeAsOptional("GOKZ_SetHitPerf");
+ MarkNativeAsOptional("GOKZ_GetTakeoffSpeed");
+ MarkNativeAsOptional("GOKZ_SetTakeoffSpeed");
+ MarkNativeAsOptional("GOKZ_GetValidJump");
+ MarkNativeAsOptional("GOKZ_JoinTeam");
+ MarkNativeAsOptional("GOKZ_EmitSoundToClient");
+}
+#endif \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/global.inc b/sourcemod/scripting/include/gokz/global.inc
new file mode 100644
index 0000000..0f23a0c
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/global.inc
@@ -0,0 +1,317 @@
+/*
+ gokz-global Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_global_included_
+#endinput
+#endif
+#define _gokz_global_included_
+
+#include <GlobalAPI>
+
+
+
+// =====[ ENUMS ]=====
+
+enum
+{
+ EnforcedCVar_Cheats = 0,
+ EnforcedCVar_ClampUnsafeVelocities,
+ EnforcedCVar_DropKnifeEnable,
+ EnforcedCVar_AutoBunnyhopping,
+ EnforcedCVar_MinUpdateRate,
+ EnforcedCVar_MaxUpdateRate,
+ EnforcedCVar_MinCmdRate,
+ EnforcedCVar_MaxCmdRate,
+ EnforcedCVar_ClientCmdrateDifference,
+ EnforcedCVar_Turbophysics,
+ ENFORCEDCVAR_COUNT
+};
+
+enum
+{
+ BannedPluginCommand_Funcommands = 0,
+ BannedPluginCommand_Playercommands,
+ BANNEDPLUGINCOMMAND_COUNT
+};
+
+enum
+{
+ BannedPlugin_Funcommands = 0,
+ BannedPlugin_Playercommands,
+ BANNEDPLUGIN_COUNT
+};
+
+enum GlobalMode
+{
+ GlobalMode_Invalid = -1,
+ GlobalMode_KZTimer = 200,
+ GlobalMode_KZSimple,
+ GlobalMode_Vanilla
+}
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define GL_SOUND_NEW_RECORD "gokz/holyshit.mp3"
+#define GL_FPS_MAX_CHECK_INTERVAL 1.0
+#define GL_FPS_MAX_KICK_TIMEOUT 10.0
+#define GL_FPS_MAX_MIN_VALUE 120
+#define GL_MYAW_MAX_VALUE 0.3
+
+stock char gC_EnforcedCVars[ENFORCEDCVAR_COUNT][] =
+{
+ "sv_cheats",
+ "sv_clamp_unsafe_velocities",
+ "mp_drop_knife_enable",
+ "sv_autobunnyhopping",
+ "sv_minupdaterate",
+ "sv_maxupdaterate",
+ "sv_mincmdrate",
+ "sv_maxcmdrate",
+ "sv_client_cmdrate_difference",
+ "sv_turbophysics"
+};
+
+stock char gC_BannedPluginCommands[BANNEDPLUGINCOMMAND_COUNT][] =
+{
+ "sm_beacon",
+ "sm_slap"
+};
+
+stock char gC_BannedPlugins[BANNEDPLUGIN_COUNT][] =
+{
+ "Fun Commands",
+ "Player Commands"
+};
+
+stock float gF_EnforcedCVarValues[ENFORCEDCVAR_COUNT] =
+{
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 128.0,
+ 128.0,
+ 128.0,
+ 128.0,
+ 0.0,
+ 0.0
+};
+
+
+
+// =====[ FORWARDS ]=====
+
+/**
+ * Called when a player sets a new global top time.
+ *
+ * @param client Client index.
+ * @param course Course number e.g. 0=main, 1='bonus1' etc.
+ * @param mode Player's movement mode.
+ * @param timeType Time type i.e. NUB or PRO.
+ * @param rank Ranking within the same time type.
+ * @param rankOverall Overall (NUB and PRO) ranking (0 if not ranked high enough).
+ * @param runTime Player's end time.
+ */
+forward void GOKZ_GL_OnNewTopTime(int client, int course, int mode, int timeType, int rank, int rankOverall, float runTime);
+
+
+
+// =====[ NATIVES ]=====
+
+/**
+ * Prints to chat the global records for a map, course and mode.
+ *
+ * @param client Client index.
+ * @param map Map name or "" for current map.
+ * @param course Course number e.g. 0=main, 1='bonus1' etc.
+ * @param mode GOKZ mode.
+ */
+native void GOKZ_GL_PrintRecords(int client, const char[] map = "", int course, int mode, const char[] steamid = DEFAULT_STRING);
+
+/**
+ * Opens up the global map top menu for a map, course and mode.
+ *
+ * @param client Client index.
+ * @param map Map name or "" for current map.
+ * @param course Course number e.g. 0=main, 1='bonus1' etc.
+ * @param mode GOKZ mode.
+ * @param timeType Type of time i.e. NUB or PRO.
+ */
+native void GOKZ_GL_DisplayMapTopMenu(int client, const char[] map = "", int course, int mode, int timeType);
+
+/**
+ * Get the total global points of a player.
+ *
+ * @param client Client index.
+ * @param mode GOKZ mode.
+ * @param timeType Type of time i.e. NUB or PRO.
+ */
+native void GOKZ_GL_GetPoints(int client, int mode, int timeType);
+
+/**
+ * Get the global points on the main coruse of the current map.
+ *
+ * @param client Client index.
+ * @param mode GOKZ mode.
+ * @param timeType Type of time i.e. NUB or PRO.
+ */
+native void GOKZ_GL_GetMapPoints(int client, int mode, int timeType);
+
+/**
+ * Get the total global ranking points of a player.
+ *
+ * @param client Client index.
+ * @param mode GOKZ mode.
+ * @return The points.
+ */
+native int GOKZ_GL_GetRankPoints(int client, int mode);
+
+/**
+ * Get the amount of maps a player finished.
+ *
+ * @param client Client index.
+ * @param mode GOKZ mode.
+ * @param timeType Type of time i.e. NUB or PRO.
+ */
+native void GOKZ_GL_GetFinishes(int client, int mode, int timeType);
+
+/**
+ * Fetch the points a player got from the Global API.
+ *
+ * @param client Client index. -1 to update all indices.
+ * @param mode GOKZ mode. -1 to update all modes.
+ */
+native void GOKZ_GL_UpdatePoints(int client = -1, int mode = -1);
+
+/**
+ * Gets whether the Global API key is valid or not for global status.
+ *
+ * @return True if the API key is valid, false otherwise or if there is no connection to the Global API.
+ */
+native bool GOKZ_GL_GetAPIKeyValid();
+
+/**
+ * Gets whether the running plugins are valid or not for global status.
+ *
+ * @return True if the plugins are valid, false otherwise.
+ */
+native bool GOKZ_GL_GetPluginsValid();
+
+/**
+ * Gets whether the setting enforcer is valid or not for global status.
+ *
+ * @return True if the setting enforcer is valid, false otherwise.
+ */
+native bool GOKZ_GL_GetSettingsEnforcerValid();
+
+/**
+ * Gets whether the current map is valid or not for global status.
+ *
+ * @return True if the map is valid, false otherwise or if there is no connection to the Global API.
+ */
+native bool GOKZ_GL_GetMapValid();
+
+/**
+ * Gets whether the current player is valid or not for global status.
+ *
+ * @param client Client index.
+ * @return True if the player is valid, false otherwise or if there is no connection to the Global API.
+ */
+native bool GOKZ_GL_GetPlayerValid(int client);
+
+
+
+// =====[ STOCKS ]=====
+
+/**
+ * Gets the global mode enumeration equivalent for the GOKZ mode.
+ *
+ * @param mode GOKZ mode.
+ * @return Global mode enumeration equivalent.
+ */
+stock GlobalMode GOKZ_GL_GetGlobalMode(int mode)
+{
+ switch (mode)
+ {
+ case Mode_Vanilla:return GlobalMode_Vanilla;
+ case Mode_SimpleKZ:return GlobalMode_KZSimple;
+ case Mode_KZTimer:return GlobalMode_KZTimer;
+ }
+ return GlobalMode_Invalid;
+}
+
+/**
+ * Gets the global mode enumeration equivalent for the GOKZ mode.
+ *
+ * @param mode GOKZ mode.
+ * @return Global mode enumeration equivalent.
+ */
+stock int GOKZ_GL_FromGlobalMode(GlobalMode mode)
+{
+ switch (mode)
+ {
+ case GlobalMode_Vanilla:return Mode_Vanilla;
+ case GlobalMode_KZSimple:return Mode_SimpleKZ;
+ case GlobalMode_KZTimer:return Mode_KZTimer;
+ }
+ return -1;
+}
+
+/**
+ * Gets the string representation of a mode.
+ *
+ * @param mode GOKZ mode.
+ * @param mode_str String version of the mode.
+ * @param size Max length of mode_str.
+ * @return True if the conversion was successful.
+ */
+stock bool GOKZ_GL_GetModeString(int mode, char[] mode_str, int size)
+{
+ switch (mode)
+ {
+ case Mode_Vanilla:strcopy(mode_str, size, "kz_vanilla");
+ case Mode_SimpleKZ:strcopy(mode_str, size, "kz_simple");
+ case Mode_KZTimer:strcopy(mode_str, size, "kz_timer");
+ default:return false;
+ }
+ return true;
+}
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_global =
+{
+ name = "gokz-global",
+ file = "gokz-global.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_global_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_GL_PrintRecords");
+ MarkNativeAsOptional("GOKZ_GL_DisplayMapTopMenu");
+ MarkNativeAsOptional("GOKZ_GL_UpdatePoints");
+ MarkNativeAsOptional("GOKZ_GL_GetAPIKeyValid");
+ MarkNativeAsOptional("GOKZ_GL_GetPluginsValid");
+ MarkNativeAsOptional("GOKZ_GL_GetSettingsEnforcerValid");
+ MarkNativeAsOptional("GOKZ_GL_GetMapValid");
+ MarkNativeAsOptional("GOKZ_GL_GetPlayerValid");
+ MarkNativeAsOptional("GOKZ_GL_GetPoints");
+ MarkNativeAsOptional("GOKZ_GL_GetMapPoints");
+ MarkNativeAsOptional("GOKZ_GL_GetRankPoints");
+ MarkNativeAsOptional("GOKZ_GL_GetFinishes");
+ MarkNativeAsOptional("GOKZ_GL_UpdatePoints");
+}
+#endif \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/hud.inc b/sourcemod/scripting/include/gokz/hud.inc
new file mode 100644
index 0000000..5d658ff
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/hud.inc
@@ -0,0 +1,468 @@
+/*
+ gokz-hud Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_hud_included_
+#endinput
+#endif
+#define _gokz_hud_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum HUDOption:
+{
+ HUDOPTION_INVALID = -1,
+ HUDOption_TPMenu,
+ HUDOption_InfoPanel,
+ HUDOption_ShowKeys,
+ HUDOption_TimerText,
+ HUDOption_TimerStyle,
+ HUDOption_TimerType,
+ HUDOption_SpeedText,
+ HUDOption_ShowWeapon,
+ HUDOption_ShowControls,
+ HUDOption_DeadstrafeColor,
+ HUDOption_ShowSpectators,
+ HUDOption_SpecListPosition,
+ HUDOption_UpdateRate,
+ HUDOption_DynamicMenu,
+ HUDOPTION_COUNT
+};
+
+enum
+{
+ TPMenu_Disabled = 0,
+ TPMenu_Simple,
+ TPMenu_Advanced,
+ TPMENU_COUNT
+};
+
+enum
+{
+ InfoPanel_Disabled = 0,
+ InfoPanel_Enabled,
+ INFOPANEL_COUNT
+};
+
+enum
+{
+ ShowKeys_Spectating = 0,
+ ShowKeys_Always,
+ ShowKeys_Disabled,
+ SHOWKEYS_COUNT
+};
+
+enum
+{
+ TimerText_Disabled = 0,
+ TimerText_InfoPanel,
+ TimerText_TPMenu,
+ TimerText_Bottom,
+ TimerText_Top,
+ TIMERTEXT_COUNT
+};
+
+enum
+{
+ TimerStyle_Standard = 0,
+ TimerStyle_Precise,
+ TIMERSTYLE_COUNT
+};
+
+enum
+{
+ TimerType_Disabled = 0,
+ TimerType_Enabled,
+ TIMERTYPE_COUNT
+};
+
+enum
+{
+ SpeedText_Disabled = 0,
+ SpeedText_InfoPanel,
+ SpeedText_Bottom,
+ SPEEDTEXT_COUNT
+};
+
+enum
+{
+ ShowWeapon_Disabled = 0,
+ ShowWeapon_Enabled,
+ SHOWWEAPON_COUNT
+};
+
+enum
+{
+ ReplayControls_Disabled = 0,
+ ReplayControls_Enabled,
+ REPLAYCONTROLS_COUNT
+};
+
+enum
+{
+ DeadstrafeColor_Disabled = 0,
+ DeadstrafeColor_Enabled,
+ DEADSTRAFECOLOR_COUNT
+};
+
+enum
+{
+ ShowSpecs_Disabled = 0,
+ ShowSpecs_Number,
+ ShowSpecs_Full,
+ SHOWSPECS_COUNT
+};
+
+enum
+{
+ SpecListPosition_TPMenu = 0,
+ SpecListPosition_InfoPanel,
+ SPECLISTPOSITION_COUNT
+}
+
+enum
+{
+ UpdateRate_Slow = 0,
+ UpdateRate_Fast,
+ UPDATERATE_COUNT,
+};
+
+enum
+{
+ DynamicMenu_Legacy = 0,
+ DynamicMenu_Disabled,
+ DynamicMenu_Enabled,
+ DYNAMICMENU_COUNT
+};
+
+// =====[ STRUCTS ]======
+
+enum struct HUDInfo
+{
+ bool TimerRunning;
+ int TimeType;
+ float Time;
+ bool Paused;
+ bool OnGround;
+ bool OnLadder;
+ bool Noclipping;
+ bool Ducking;
+ bool HitBhop;
+ bool IsTakeoff;
+ float Speed;
+ int ID;
+ bool Jumped;
+ bool HitPerf;
+ bool HitJB;
+ float TakeoffSpeed;
+ int Buttons;
+ int CurrentTeleport;
+}
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define HUD_OPTION_CATEGORY "HUD"
+#define HUD_MAX_BHOP_GROUND_TICKS 5
+#define HUD_MAX_HINT_SIZE 227
+
+stock char gC_HUDOptionNames[HUDOPTION_COUNT][] =
+{
+ "GOKZ HUD - Teleport Menu",
+ "GOKZ HUD - Centre Panel",
+ "GOKZ HUD - Show Keys",
+ "GOKZ HUD - Timer Text",
+ "GOKZ HUD - Timer Style",
+ "GOKZ HUD - Show Time Type",
+ "GOKZ HUD - Speed Text",
+ "GOKZ HUD - Show Weapon",
+ "GOKZ HUD - Show Controls",
+ "GOKZ HUD - Dead Strafe",
+ "GOKZ HUD - Show Spectators",
+ "GOKZ HUD - Spec List Pos",
+ "GOKZ HUD - Update Rate",
+ "GOKZ HUD - Dynamic Menu"
+};
+
+stock char gC_HUDOptionDescriptions[HUDOPTION_COUNT][] =
+{
+ "Teleport Menu - 0 = Disabled, 1 = Simple, 2 = Advanced",
+ "Centre Information Panel - 0 = Disabled, 1 = Enabled",
+ "Key Press Display - 0 = Spectating, 1 = Always, 2 = Disabled",
+ "Timer Display - 0 = Disabled, 1 = Centre Panel, 2 = Teleport Menu, 3 = Bottom, 4 = Top",
+ "Timer Style - 0 = Standard, 1 = Precise",
+ "Timer Type - 0 = Disabled, 1 = Enabled",
+ "Speed Display - 0 = Disabled, 1 = Centre Panel, 2 = Bottom",
+ "Weapon Viewmodel - 0 = Disabled, 1 = Enabled",
+ "Replay Controls Display - 0 = Disbled, 1 = Enabled",
+ "Dead Strafe Indicator - 0 = Disabled, 1 = Enabled",
+ "Show Spectators - 0 = Disabled, 1 = Number Only, 2 = Number and Names",
+ "Spectator List Position - 0 = Teleport Menu, 2 = Center Panel",
+ "HUD Update Rate - 0 = Slow, 1 = Fast",
+ "Dynamic Menu - 0 = Legacy, 1 = Disabled, 2 = Enabled"
+};
+
+stock char gC_HUDOptionPhrases[HUDOPTION_COUNT][] =
+{
+ "Options Menu - Teleport Menu",
+ "Options Menu - Info Panel",
+ "Options Menu - Show Keys",
+ "Options Menu - Timer Text",
+ "Options Menu - Timer Style",
+ "Options Menu - Timer Type",
+ "Options Menu - Speed Text",
+ "Options Menu - Show Weapon",
+ "Options Menu - Show Controls",
+ "Options Menu - Dead Strafe Indicator",
+ "Options Menu - Show Spectators",
+ "Options Menu - Spectator List Position",
+ "Options Menu - Update Rate",
+ "Options Menu - Dynamic Menu"
+};
+
+stock int gI_HUDOptionCounts[HUDOPTION_COUNT] =
+{
+ TPMENU_COUNT,
+ INFOPANEL_COUNT,
+ SHOWKEYS_COUNT,
+ TIMERTEXT_COUNT,
+ TIMERSTYLE_COUNT,
+ TIMERTYPE_COUNT,
+ SPEEDTEXT_COUNT,
+ SHOWWEAPON_COUNT,
+ REPLAYCONTROLS_COUNT,
+ DEADSTRAFECOLOR_COUNT,
+ SHOWSPECS_COUNT,
+ SPECLISTPOSITION_COUNT,
+ UPDATERATE_COUNT,
+ DYNAMICMENU_COUNT
+};
+
+stock int gI_HUDOptionDefaults[HUDOPTION_COUNT] =
+{
+ TPMenu_Advanced,
+ InfoPanel_Enabled,
+ ShowKeys_Spectating,
+ TimerText_InfoPanel,
+ TimerStyle_Standard,
+ TimerType_Enabled,
+ SpeedText_InfoPanel,
+ ShowWeapon_Enabled,
+ ReplayControls_Enabled,
+ DeadstrafeColor_Disabled,
+ ShowSpecs_Disabled,
+ SpecListPosition_TPMenu,
+ UpdateRate_Slow,
+ DynamicMenu_Legacy
+};
+
+stock char gC_TPMenuPhrases[TPMENU_COUNT][] =
+{
+ "Options Menu - Disabled",
+ "Options Menu - Simple",
+ "Options Menu - Advanced"
+};
+
+stock char gC_ShowKeysPhrases[SHOWKEYS_COUNT][] =
+{
+ "Options Menu - Spectating",
+ "Options Menu - Always",
+ "Options Menu - Disabled"
+};
+
+stock char gC_TimerTextPhrases[TIMERTEXT_COUNT][] =
+{
+ "Options Menu - Disabled",
+ "Options Menu - Info Panel",
+ "Options Menu - Teleport Menu",
+ "Options Menu - Bottom",
+ "Options Menu - Top"
+};
+
+stock char gC_TimerTypePhrases[TIMERTYPE_COUNT][] =
+{
+ "Options Menu - Disabled",
+ "Options Menu - Enabled"
+};
+
+stock char gC_SpeedTextPhrases[SPEEDTEXT_COUNT][] =
+{
+ "Options Menu - Disabled",
+ "Options Menu - Info Panel",
+ "Options Menu - Bottom"
+};
+
+stock char gC_ShowControlsPhrases[REPLAYCONTROLS_COUNT][] =
+{
+ "Options Menu - Disabled",
+ "Options Menu - Enabled"
+};
+
+stock char gC_DeadstrafeColorPhrases[DEADSTRAFECOLOR_COUNT][] =
+{
+ "Options Menu - Disabled",
+ "Options Menu - Enabled"
+};
+
+stock char gC_ShowSpecsPhrases[SHOWSPECS_COUNT][] =
+{
+ "Options Menu - Disabled",
+ "Options Menu - Number",
+ "Options Menu - Number and Names"
+};
+
+stock char gC_SpecListPositionPhrases[SPECLISTPOSITION_COUNT][] =
+{
+ "Options Menu - Teleport Menu",
+ "Options Menu - Info Panel"
+};
+
+stock char gC_HUDUpdateRatePhrases[UPDATERATE_COUNT][]=
+{
+ "Options Menu - Slow",
+ "Options Menu - Fast"
+};
+
+stock char gC_DynamicMenuPhrases[DYNAMICMENU_COUNT][]=
+{
+ "Options Menu - Legacy",
+ "Options Menu - Disabled",
+ "Options Menu - Enabled"
+};
+
+// =====[ NATIVES ]=====
+
+/**
+ * Returns whether the GOKZ HUD menu is showing for a client.
+ *
+ * @param client Client index.
+ * @return Whether the GOKZ HUD menu is showing.
+ */
+native bool GOKZ_HUD_GetMenuShowing(int client);
+
+/**
+ * Sets whether the GOKZ HUD menu would be showing for a client.
+ *
+ * @param client Client index.
+ * @param value Whether the GOKZ HUD menu would be showing for a client.
+ */
+native void GOKZ_HUD_SetMenuShowing(int client, bool value);
+
+/**
+ * Gets the spectator text for the menu. Used by GOKZ-replays.
+ *
+ * @param client Client index.
+ * @param value Whether the GOKZ HUD menu would be showing for a client.
+ */
+native void GOKZ_HUD_GetMenuSpectatorText(int client, any[] info, char[] buffer, int size);
+
+/**
+ * Forces the client's TP menu to update.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_HUD_ForceUpdateTPMenu(int client);
+
+// =====[ STOCKS ]=====
+
+/**
+ * Returns whether an option is a gokz-hud option.
+ *
+ * @param option Option name.
+ * @param optionEnum Variable to store enumerated gokz-hud option (if it is one).
+ * @return Whether option is a gokz-hud option.
+ */
+stock bool GOKZ_HUD_IsHUDOption(const char[] option, HUDOption &optionEnum = HUDOPTION_INVALID)
+{
+ for (HUDOption i; i < HUDOPTION_COUNT; i++)
+ {
+ if (StrEqual(option, gC_HUDOptionNames[i]))
+ {
+ optionEnum = i;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Gets the current value of a player's gokz-hud option.
+ *
+ * @param client Client index.
+ * @param option gokz-hud option.
+ * @return Current value of option.
+ */
+stock any GOKZ_HUD_GetOption(int client, HUDOption option)
+{
+ return GOKZ_GetOption(client, gC_HUDOptionNames[option]);
+}
+
+/**
+ * Sets a player's gokz-hud option's value.
+ *
+ * @param client Client index.
+ * @param option gokz-hud option.
+ * @param value New option value.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_HUD_SetOption(int client, HUDOption option, any value)
+{
+ return GOKZ_SetOption(client, gC_HUDOptionNames[option], value);
+}
+
+/**
+ * Increment an integer-type gokz-hud option's value.
+ * Loops back to '0' if max value is exceeded.
+ *
+ * @param client Client index.
+ * @param option gokz-hud option.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_HUD_CycleOption(int client, HUDOption option)
+{
+ return GOKZ_CycleOption(client, gC_HUDOptionNames[option]);
+}
+
+/**
+ * Represents a time float as a string e.g. 01:23.45
+ * and according to the client's HUD options.
+ *
+ * @param client Client index.
+ * @param time Time in seconds.
+ * @return String representation of time.
+ */
+stock char[] GOKZ_HUD_FormatTime(int client, float time)
+{
+ bool precise = GOKZ_HUD_GetOption(client, HUDOption_TimerStyle) == TimerStyle_Precise;
+ return GOKZ_FormatTime(time, precise);
+}
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_hud =
+{
+ name = "gokz-hud",
+ file = "gokz-hud.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_hud_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_HUD_GetMenuShowing");
+ MarkNativeAsOptional("GOKZ_HUD_SetMenuShowing");
+ MarkNativeAsOptional("GOKZ_HUD_GetMenuSpectatorText");
+ MarkNativeAsOptional("GOKZ_HUD_ForceUpdateTPMenu");
+}
+#endif
diff --git a/sourcemod/scripting/include/gokz/jumpbeam.inc b/sourcemod/scripting/include/gokz/jumpbeam.inc
new file mode 100644
index 0000000..1b92479
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/jumpbeam.inc
@@ -0,0 +1,148 @@
+/*
+ gokz-jumpbeam Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_jumpbeam_included_
+#endinput
+#endif
+#define _gokz_jumpbeam_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum JBOption:
+{
+ JBOPTION_INVALID = -1,
+ JBOption_Type,
+ JBOPTION_COUNT
+};
+
+enum
+{
+ JBType_Disabled = 0,
+ JBType_Feet,
+ JBType_Head,
+ JBType_FeetAndHead,
+ JBType_Ground,
+ JBTYPE_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define JB_BEAM_LIFETIME 4.0
+
+stock char gC_JBOptionNames[JBOPTION_COUNT][] =
+{
+ "GOKZ JB - Jump Beam Type"
+};
+
+stock char gC_JBOptionDescriptions[JBOPTION_COUNT][] =
+{
+ "Jump Beam Type - 0 = Disabled, 1 = Feet, 2 = Head, 3 = Feet & Head, 4 = Ground"
+};
+
+stock int gI_JBOptionDefaultValues[JBOPTION_COUNT] =
+{
+ JBType_Disabled
+};
+
+stock int gI_JBOptionCounts[JBOPTION_COUNT] =
+{
+ JBTYPE_COUNT
+};
+
+stock char gC_JBOptionPhrases[JBOPTION_COUNT][] =
+{
+ "Options Menu - Jump Beam"
+};
+
+stock char gC_JBTypePhrases[JBTYPE_COUNT][] =
+{
+ "Options Menu - Disabled",
+ "Options Menu - Feet",
+ "Options Menu - Head",
+ "Options Menu - Feet and Head",
+ "Options Menu - Ground"
+};
+
+
+
+// =====[ STOCKS ]=====
+
+/**
+ * Returns whether an option is a gokz-jumpbeam option.
+ *
+ * @param option Option name.
+ * @param optionEnum Variable to store enumerated gokz-jumpbeam option (if it is one).
+ * @return Whether option is a gokz-jumpbeam option.
+ */
+stock bool GOKZ_JB_IsJBOption(const char[] option, JBOption &optionEnum = JBOPTION_INVALID)
+{
+ for (JBOption i; i < JBOPTION_COUNT; i++)
+ {
+ if (StrEqual(option, gC_JBOptionNames[i]))
+ {
+ optionEnum = i;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Gets the current value of a player's gokz-jumpbeam option.
+ *
+ * @param client Client index.
+ * @param option gokz-jumpbeam option.
+ * @return Current value of option.
+ */
+stock any GOKZ_JB_GetOption(int client, JBOption option)
+{
+ return GOKZ_GetOption(client, gC_JBOptionNames[option]);
+}
+
+/**
+ * Sets a player's gokz-jumpbeam option's value.
+ *
+ * @param client Client index.
+ * @param option gokz-jumpbeam option.
+ * @param value New option value.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_JB_SetOption(int client, JBOption option, any value)
+{
+ return GOKZ_SetOption(client, gC_JBOptionNames[option], value);
+}
+
+/**
+ * Increment an integer-type gokz-jumpbeam option's value.
+ * Loops back to '0' if max value is exceeded.
+ *
+ * @param client Client index.
+ * @param option gokz-jumpbeam option.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_JB_CycleOption(int client, JBOption option)
+{
+ return GOKZ_CycleOption(client, gC_JBOptionNames[option]);
+}
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_jumpbeam =
+{
+ name = "gokz-jumpbeam",
+ file = "gokz-jumpbeam.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+}; \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/jumpstats.inc b/sourcemod/scripting/include/gokz/jumpstats.inc
new file mode 100644
index 0000000..452ae28
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/jumpstats.inc
@@ -0,0 +1,442 @@
+/*
+ gokz-jumpstats Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_jumpstats_included_
+#endinput
+#endif
+#define _gokz_jumpstats_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum
+{
+ JumpType_FullInvalid = -1,
+ JumpType_LongJump,
+ JumpType_Bhop,
+ JumpType_MultiBhop,
+ JumpType_WeirdJump,
+ JumpType_LadderJump,
+ JumpType_Ladderhop,
+ JumpType_Jumpbug,
+ JumpType_LowpreBhop,
+ JumpType_LowpreWeirdJump,
+ JumpType_Fall,
+ JumpType_Other,
+ JumpType_Invalid,
+ JUMPTYPE_COUNT
+};
+
+enum
+{
+ StrafeDirection_None,
+ StrafeDirection_Left,
+ StrafeDirection_Right
+};
+
+enum
+{
+ DistanceTier_None = 0,
+ DistanceTier_Meh,
+ DistanceTier_Impressive,
+ DistanceTier_Perfect,
+ DistanceTier_Godlike,
+ DistanceTier_Ownage,
+ DistanceTier_Wrecker,
+ DISTANCETIER_COUNT
+};
+
+enum JSOption:
+{
+ JSOPTION_INVALID = -1,
+ JSOption_JumpstatsMaster,
+ JSOption_MinChatTier,
+ JSOption_MinConsoleTier,
+ JSOption_MinSoundTier,
+ JSOption_FailstatsConsole,
+ JSOption_FailstatsChat,
+ JSOption_JumpstatsAlways,
+ JSOption_ExtendedChatReport,
+ JSOption_MinChatBroadcastTier,
+ JSOption_MinSoundBroadcastTier,
+ JSOPTION_COUNT
+};
+
+enum
+{
+ JSToggleOption_Disabled = 0,
+ JSToggleOption_Enabled,
+ JSTOGGLEOPTION_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define JS_CFG_TIERS "cfg/sourcemod/gokz/gokz-jumpstats-tiers.cfg"
+#define JS_CFG_SOUNDS "cfg/sourcemod/gokz/gokz-jumpstats-sounds.cfg"
+#define JS_CFG_BROADCAST "cfg/sourcemod/gokz/gokz-jumpstats-broadcast.cfg"
+#define JS_OPTION_CATEGORY "Jumpstats"
+#define JS_MAX_LADDERJUMP_OFFSET 2.0
+#define JS_MAX_BHOP_GROUND_TICKS 5
+#define JS_MAX_DUCKBUG_RESET_TICKS 6
+#define JS_MAX_WEIRDJUMP_FALL_OFFSET 64.0
+#define JS_TOUCH_GRACE_TICKS 3
+#define JS_MAX_TRACKED_STRAFES 48
+#define JS_MIN_BLOCK_DISTANCE 186
+#define JS_MIN_LAJ_BLOCK_DISTANCE 50
+#define JS_MAX_LAJ_FAILSTAT_DISTANCE 250
+#define JS_TOP_RECORD_COUNT 20
+#define JS_MAX_JUMP_DISTANCE 500
+#define JS_FAILSTATS_MAX_TRACKED_TICKS 128
+#define JS_MIN_TELEPORT_DELAY 5
+#define JS_SPEED_MODIFICATION_TOLERANCE 0.1
+#define JS_OFFSET_EPSILON 0.03125
+
+stock char gC_JumpTypes[JUMPTYPE_COUNT][] =
+{
+ "Long Jump",
+ "Bunnyhop",
+ "Multi Bunnyhop",
+ "Weird Jump",
+ "Ladder Jump",
+ "Ladderhop",
+ "Jumpbug",
+ "Lowpre Bunnyhop",
+ "Lowpre Weird Jump",
+ "Fall",
+ "Unknown Jump",
+ "Invalid Jump"
+};
+
+stock char gC_JumpTypesShort[JUMPTYPE_COUNT][] =
+{
+ "LJ",
+ "BH",
+ "MBH",
+ "WJ",
+ "LAJ",
+ "LAH",
+ "JB",
+ "LBH",
+ "LWJ",
+ "FL",
+ "UNK",
+ "INV"
+};
+
+stock char gC_JumpTypeKeys[JUMPTYPE_COUNT][] =
+{
+ "longjump",
+ "bhop",
+ "multibhop",
+ "weirdjump",
+ "ladderjump",
+ "ladderhop",
+ "jumpbug",
+ "lowprebhop",
+ "lowpreweirdjump",
+ "fall",
+ "unknown",
+ "invalid"
+};
+
+stock char gC_DistanceTiers[DISTANCETIER_COUNT][] =
+{
+ "None",
+ "Meh",
+ "Impressive",
+ "Perfect",
+ "Godlike",
+ "Ownage",
+ "Wrecker"
+};
+
+stock char gC_DistanceTierKeys[DISTANCETIER_COUNT][] =
+{
+ "none",
+ "meh",
+ "impressive",
+ "perfect",
+ "godlike",
+ "ownage",
+ "wrecker"
+};
+
+stock char gC_DistanceTierChatColours[DISTANCETIER_COUNT][] =
+{
+ "{grey}",
+ "{grey}",
+ "{blue}",
+ "{green}",
+ "{darkred}",
+ "{gold}",
+ "{orchid}"
+};
+
+stock char gC_JSOptionNames[JSOPTION_COUNT][] =
+{
+ "GOKZ JS - Master Switch",
+ "GOKZ JS - Chat Report",
+ "GOKZ JS - Console Report",
+ "GOKZ JS - Sounds",
+ "GOKZ JS - Failstats Console",
+ "GOKZ JS - Failstats Chat",
+ "GOKZ JS - Jumpstats Always",
+ "GOKZ JS - Ext Chat Report",
+ "GOKZ JS - Min Chat Broadcast",
+ "GOKZ JS - Min Sound Broadcast"
+};
+
+stock char gC_JSOptionDescriptions[JSOPTION_COUNT][] =
+{
+ "Master Switch for All Jumpstats Functionality - 0 = Disabled, 1 = Enabled",
+ "Minimum Tier for Jumpstats Chat Report - 0 = Disabled, 1 = Meh+, 2 = Impressive+, 3 = Perfect+, 4 = Godlike+, 5 = Ownage+, 6 = Wrecker",
+ "Minimum Tier for Jumpstats Console report - 0 = Disabled, 1 = Meh+, 2 = Impressive+, 3 = Perfect+, 4 = Godlike+, 5 = Ownage+, 6 = Wrecker",
+ "Minimum Tier for Jumpstats Sounds - 0 = Disabled, 2 = Impressive+, 3 = Perfect+, 4 = Godlike+, 5 = Ownage+, 6 = Wrecker",
+ "Print Failstats To Console - 0 = Disabled, 1 = Enabled",
+ "Print Failstats To Chat - 0 = Disabled, 1 = Enabled",
+ "Always show jumpstats, even for invalid jumps - 0 = Disabled, 1 = Enabled",
+ "Extended Chat Report - 0 = Disabled, 1 = Enabled",
+ "Minimum Jump Tier for Jumpstat Chat Broadcast - 0 = Disabled, 1 = Meh+, 2 = Impressive+, 3 = Perfect+, 4 = Godlike+, 5 = Ownage+, 6 = Wrecker",
+ "Minimum Jump Tier for Jumpstat Sound Broadcast - 0 = Disabled, 1 = Meh+, 2 = Impressive+, 3 = Perfect+, 4 = Godlike+, 5 = Ownage+, 6 = Wrecker"
+};
+
+stock char gI_JSOptionPhrases[JSOPTION_COUNT][] =
+{
+ "Options Menu - Jumpstats Master Switch",
+ "Options Menu - Jumpstats Chat Report",
+ "Options Menu - Jumpstats Console Report",
+ "Options Menu - Jumpstats Sounds",
+ "Options Menu - Failstats Console Report",
+ "Options Menu - Failstats Chat Report",
+ "Options Menu - Jumpstats Always",
+ "Options Menu - Extended Jump Chat Report",
+ "Options Menu - Minimal Jump Chat Broadcast Tier",
+ "Options Menu - Minimal Jump Sound Broadcast Tier"
+};
+
+stock int gI_JSOptionDefaults[JSOPTION_COUNT] =
+{
+ JSToggleOption_Enabled,
+ DistanceTier_Meh,
+ DistanceTier_Meh,
+ DistanceTier_Impressive,
+ JSToggleOption_Enabled,
+ JSToggleOption_Disabled,
+ JSToggleOption_Disabled,
+ JSToggleOption_Disabled,
+ DistanceTier_Ownage,
+ DistanceTier_None
+};
+
+stock int gI_JSOptionCounts[JSOPTION_COUNT] =
+{
+ JSTOGGLEOPTION_COUNT,
+ DISTANCETIER_COUNT,
+ DISTANCETIER_COUNT,
+ DISTANCETIER_COUNT,
+ JSTOGGLEOPTION_COUNT,
+ JSTOGGLEOPTION_COUNT,
+ JSTOGGLEOPTION_COUNT,
+ JSTOGGLEOPTION_COUNT,
+ DISTANCETIER_COUNT,
+ DISTANCETIER_COUNT
+};
+
+
+
+// =====[ STRUCTS ]=====
+
+enum struct Jump
+{
+ int jumper;
+ int block;
+ int crouchRelease;
+ int crouchTicks;
+ int deadair;
+ int duration;
+ int originalType;
+ int overlap;
+ int releaseW;
+ int strafes;
+ int type;
+ float deviation;
+ float distance;
+ float edge;
+ float height;
+ float maxSpeed;
+ float offset;
+ float preSpeed;
+ float sync;
+ float width;
+
+ // For the 'always' stats
+ float miss;
+
+ // We can't make a separate enum struct for that cause it won't let us
+ // index an array of enum structs.
+ int strafes_gainTicks[JS_MAX_TRACKED_STRAFES];
+ int strafes_deadair[JS_MAX_TRACKED_STRAFES];
+ int strafes_overlap[JS_MAX_TRACKED_STRAFES];
+ int strafes_ticks[JS_MAX_TRACKED_STRAFES];
+ float strafes_gain[JS_MAX_TRACKED_STRAFES];
+ float strafes_loss[JS_MAX_TRACKED_STRAFES];
+ float strafes_sync[JS_MAX_TRACKED_STRAFES];
+ float strafes_width[JS_MAX_TRACKED_STRAFES];
+}
+
+
+
+// =====[ FORWARDS ]=====
+
+/**
+ * Called when a player begins their jump.
+ *
+ * @param client Client index.
+ * @param jumpType Type of jump.
+ */
+forward void GOKZ_JS_OnTakeoff(int client, int jumpType);
+
+/**
+ * Called when a player lands their jump.
+ *
+ * @param jump The jumpstats.
+ */
+forward void GOKZ_JS_OnLanding(Jump jump);
+
+/**
+ * Called when player's current jump has been declared an invalid jumpstat.
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_JS_OnJumpInvalidated(int client);
+
+/**
+ * Called when a player fails a blockjump.
+ *
+ * @param jump The jumpstats.
+ */
+forward void GOKZ_JS_OnFailstat(Jump jump);
+
+/**
+ * Called when a player lands a jump and has always-on jumpstats enabled.
+ *
+ * @param jump The jumpstats.
+ */
+forward void GOKZ_JS_OnJumpstatAlways(Jump jump);
+
+/**
+ * Called when a player fails a jump and has always-on failstats enabled.
+ *
+ * @param jump The failstats.
+ */
+forward void GOKZ_JS_OnFailstatAlways(Jump jump);
+
+
+
+// =====[ NATIVES ]=====
+
+/**
+ * Gets the default jumpstats option value as set by a config file.
+ *
+ * @param option GOKZ Jumpstats option.
+ * @return Default option value.
+ */
+native int GOKZ_JS_GetDefaultOption(JSOption option);
+
+/**
+ * Declare a player's current jump an invalid jumpstat.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_JS_InvalidateJump(int client);
+
+
+
+// =====[ STOCKS ]=====
+
+/**
+ * Returns whether an option is a gokz-jumpstats option.
+ *
+ * @param option Option name.
+ * @param optionEnum Variable to store enumerated gokz-jumpstats option (if it is one).
+ * @return Whether option is a gokz-jumpstats option.
+ */
+stock bool GOKZ_JS_IsJSOption(const char[] option, JSOption &optionEnum = JSOPTION_INVALID)
+{
+ for (JSOption i; i < JSOPTION_COUNT; i++)
+ {
+ if (StrEqual(option, gC_JSOptionNames[i]))
+ {
+ optionEnum = i;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Gets the current value of a player's gokz-jumpstats option.
+ *
+ * @param client Client index.
+ * @param option gokz-jumpstats option.
+ * @return Current value of option.
+ */
+stock any GOKZ_JS_GetOption(int client, JSOption option)
+{
+ return GOKZ_GetOption(client, gC_JSOptionNames[option]);
+}
+
+/**
+ * Sets a player's gokz-jumpstats option's value.
+ *
+ * @param client Client index.
+ * @param option gokz-jumpstats option.
+ * @param value New option value.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_JS_SetOption(int client, JSOption option, any value)
+{
+ return GOKZ_SetOption(client, gC_JSOptionNames[option], value);
+}
+
+/**
+ * Increment an integer-type gokz-jumpstats option's value.
+ * Loops back to '0' if max value is exceeded.
+ *
+ * @param client Client index.
+ * @param option gokz-jumpstats option.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_JS_CycleOption(int client, JSOption option)
+{
+ return GOKZ_CycleOption(client, gC_JSOptionNames[option]);
+}
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_jumpstats =
+{
+ name = "gokz-jumpstats",
+ file = "gokz-jumpstats.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_jumpstats_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_JS_GetDefaultOption");
+ MarkNativeAsOptional("GOKZ_JS_InvalidateJump");
+}
+#endif
diff --git a/sourcemod/scripting/include/gokz/kzplayer.inc b/sourcemod/scripting/include/gokz/kzplayer.inc
new file mode 100644
index 0000000..8176d39
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/kzplayer.inc
@@ -0,0 +1,584 @@
+/*
+ GOKZ KZPlayer Methodmap Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_kzplayer_included_
+#endinput
+#endif
+#define _gokz_kzplayer_included_
+
+#include <movementapi>
+
+#include <gokz>
+
+
+
+methodmap KZPlayer < MovementAPIPlayer {
+
+ public KZPlayer(int client) {
+ return view_as<KZPlayer>(MovementAPIPlayer(client));
+ }
+
+
+
+ // =====[ GENERAL ]=====
+
+ property bool Valid {
+ public get() {
+ return IsValidClient(this.ID);
+ }
+ }
+
+ property bool InGame {
+ public get() {
+ return IsClientInGame(this.ID);
+ }
+ }
+
+ property bool Authorized {
+ public get() {
+ return IsClientAuthorized(this.ID);
+ }
+ }
+
+ property bool Fake {
+ public get() {
+ return IsFakeClient(this.ID);
+ }
+ }
+
+ property bool Alive {
+ public get() {
+ return IsPlayerAlive(this.ID);
+ }
+ }
+
+ property ObsMode ObserverMode {
+ public get() {
+ return GetObserverMode(this.ID);
+ }
+ }
+
+ property int ObserverTarget {
+ public get() {
+ return GetObserverTarget(this.ID);
+ }
+ }
+
+
+
+ // =====[ CORE ]=====
+ #if defined _gokz_core_included_
+
+ public void StartTimer(int course) {
+ GOKZ_StartTimer(this.ID, course);
+ }
+
+ public void EndTimer(int course) {
+ GOKZ_EndTimer(this.ID, course);
+ }
+
+ public bool StopTimer() {
+ return GOKZ_StopTimer(this.ID);
+ }
+
+ public void TeleportToStart() {
+ GOKZ_TeleportToStart(this.ID);
+ }
+
+ public void TeleportToSearchStart(int course) {
+ GOKZ_TeleportToSearchStart(this.ID, course);
+ }
+
+ public void TeleportToEnd(int course) {
+ GOKZ_TeleportToEnd(this.ID, course);
+ }
+
+ property StartPositionType StartPositionType {
+ public get() {
+ return GOKZ_GetStartPositionType(this.ID);
+ }
+ }
+
+ public void MakeCheckpoint() {
+ GOKZ_MakeCheckpoint(this.ID);
+ }
+
+ property bool CanMakeCheckpoint {
+ public get() {
+ return GOKZ_GetCanMakeCheckpoint(this.ID);
+ }
+ }
+
+ public void TeleportToCheckpoint() {
+ GOKZ_TeleportToCheckpoint(this.ID);
+ }
+
+ property bool CanTeleportToCheckpoint {
+ public get() {
+ return GOKZ_GetCanTeleportToCheckpoint(this.ID);
+ }
+ }
+
+ public void PrevCheckpoint() {
+ GOKZ_PrevCheckpoint(this.ID);
+ }
+
+ property bool CanPrevCheckpoint {
+ public get() {
+ return GOKZ_GetCanPrevCheckpoint(this.ID);
+ }
+ }
+
+ public void NextCheckpoint() {
+ GOKZ_NextCheckpoint(this.ID);
+ }
+
+ property bool CanNextCheckpoint {
+ public get() {
+ return GOKZ_GetCanNextCheckpoint(this.ID);
+ }
+ }
+
+ public void UndoTeleport() {
+ GOKZ_UndoTeleport(this.ID);
+ }
+
+ property bool CanUndoTeleport {
+ public get() {
+ return GOKZ_GetCanUndoTeleport(this.ID);
+ }
+ }
+
+ public void Pause() {
+ GOKZ_Pause(this.ID);
+ }
+
+ property bool CanPause {
+ public get() {
+ return GOKZ_GetCanPause(this.ID);
+ }
+ }
+
+ public void Resume() {
+ GOKZ_Resume(this.ID);
+ }
+
+ property bool CanResume {
+ public get() {
+ return GOKZ_GetCanResume(this.ID);
+ }
+ }
+
+ public void TogglePause() {
+ GOKZ_TogglePause(this.ID);
+ }
+
+ public void PlayErrorSound() {
+ GOKZ_PlayErrorSound(this.ID);
+ }
+
+ property bool TimerRunning {
+ public get() {
+ return GOKZ_GetTimerRunning(this.ID);
+ }
+ }
+
+ property int Course {
+ public get() {
+ return GOKZ_GetCourse(this.ID);
+ }
+ }
+
+ property bool Paused {
+ public get() {
+ return GOKZ_GetPaused(this.ID);
+ }
+ public set(bool pause) {
+ if (pause) {
+ this.Pause();
+ }
+ else {
+ this.Resume();
+ }
+ }
+ }
+
+ property bool CanTeleportToStart {
+ public get() {
+ return GOKZ_GetCanTeleportToStartOrEnd(this.ID);
+ }
+ }
+
+ property float Time {
+ public get() {
+ return GOKZ_GetTime(this.ID);
+ }
+ public set(float value) {
+ GOKZ_SetTime(this.ID, value);
+ }
+ }
+
+ property int CheckpointCount {
+ public get() {
+ return GOKZ_GetCheckpointCount(this.ID);
+ }
+ public set(int cpCount) {
+ GOKZ_SetCheckpointCount(this.ID, cpCount);
+ }
+ }
+
+ property ArrayList CheckpointData {
+ public get() {
+ return GOKZ_GetCheckpointData(this.ID);
+ }
+ public set(ArrayList checkpoints) {
+ GOKZ_SetCheckpointData(this.ID, checkpoints, GOKZ_CHECKPOINT_VERSION);
+ }
+ }
+
+ property int TeleportCount {
+ public get() {
+ return GOKZ_GetTeleportCount(this.ID);
+ }
+ public set(int value) {
+ GOKZ_SetTeleportCount(this.ID, value);
+ }
+ }
+
+ property int TimeType {
+ public get() {
+ return GOKZ_GetTimeType(this.ID);
+ }
+ }
+
+ property bool GOKZHitPerf {
+ public get() {
+ return GOKZ_GetHitPerf(this.ID);
+ }
+ public set(bool value) {
+ GOKZ_SetHitPerf(this.ID, value);
+ }
+ }
+
+ property float GOKZTakeoffSpeed {
+ public get() {
+ return GOKZ_GetTakeoffSpeed(this.ID);
+ }
+ public set(float value) {
+ GOKZ_SetTakeoffSpeed(this.ID, value);
+ }
+ }
+
+ property bool ValidJump {
+ public get() {
+ return GOKZ_GetValidJump(this.ID);
+ }
+ }
+
+ public any GetOption(const char[] option) {
+ return GOKZ_GetOption(this.ID, option);
+ }
+
+ public bool SetOption(const char[] option, any value) {
+ return GOKZ_SetOption(this.ID, option, value);
+ }
+
+ public bool CycleOption(const char[] option) {
+ return GOKZ_CycleOption(this.ID, option);
+ }
+
+ public any GetCoreOption(Option option) {
+ return GOKZ_GetCoreOption(this.ID, option);
+ }
+
+ public bool SetCoreOption(Option option, int value) {
+ return GOKZ_SetCoreOption(this.ID, option, value);
+ }
+
+ public bool CycleCoreOption(Option option) {
+ return GOKZ_CycleCoreOption(this.ID, option);
+ }
+
+ property int Mode {
+ public get() {
+ return this.GetCoreOption(Option_Mode);
+ }
+ public set(int value) {
+ this.SetCoreOption(Option_Mode, value);
+ }
+ }
+
+ property int Style {
+ public get() {
+ return this.GetCoreOption(Option_Style);
+ }
+ public set(int value) {
+ this.SetCoreOption(Option_Style, value);
+ }
+ }
+
+ property int CheckpointMessages {
+ public get() {
+ return this.GetCoreOption(Option_CheckpointMessages);
+ }
+ public set(int value) {
+ this.SetCoreOption(Option_CheckpointMessages, value);
+ }
+ }
+
+ property int CheckpointSounds {
+ public get() {
+ return this.GetCoreOption(Option_CheckpointSounds);
+ }
+ public set(int value) {
+ this.SetCoreOption(Option_CheckpointSounds, value);
+ }
+ }
+
+ property int TeleportSounds {
+ public get() {
+ return this.GetCoreOption(Option_TeleportSounds);
+ }
+ public set(int value) {
+ this.SetCoreOption(Option_TeleportSounds, value);
+ }
+ }
+
+ property int ErrorSounds {
+ public get() {
+ return this.GetCoreOption(Option_ErrorSounds);
+ }
+ public set(int value) {
+ this.SetCoreOption(Option_ErrorSounds, value);
+ }
+ }
+
+ #endif
+ // =====[ END CORE ]=====
+
+
+
+ // =====[ HUD ]=====
+ #if defined _gokz_hud_included_
+
+ public any GetHUDOption(HUDOption option) {
+ return GOKZ_HUD_GetOption(this.ID, option);
+ }
+
+ public bool SetHUDOption(HUDOption option, any value) {
+ return GOKZ_HUD_SetOption(this.ID, option, value);
+ }
+
+ public bool CycleHUDOption(HUDOption option) {
+ return GOKZ_HUD_CycleOption(this.ID, option);
+ }
+
+ property int TPMenu {
+ public get() {
+ return this.GetHUDOption(HUDOption_TPMenu);
+ }
+ public set(int value) {
+ this.SetHUDOption(HUDOption_TPMenu, value);
+ }
+ }
+
+ property int InfoPanel {
+ public get() {
+ return this.GetHUDOption(HUDOption_InfoPanel);
+ }
+ public set(int value) {
+ this.SetHUDOption(HUDOption_InfoPanel, value);
+ }
+ }
+
+ property int ShowKeys {
+ public get() {
+ return this.GetHUDOption(HUDOption_ShowKeys);
+ }
+ public set(int value) {
+ this.SetHUDOption(HUDOption_ShowKeys, value);
+ }
+ }
+
+ property int TimerText {
+ public get() {
+ return this.GetHUDOption(HUDOption_TimerText);
+ }
+ public set(int value) {
+ this.SetHUDOption(HUDOption_TimerText, value);
+ }
+ }
+
+ property int TimerStyle {
+ public get() {
+ return this.GetHUDOption(HUDOption_TimerStyle);
+ }
+ public set(int value) {
+ this.SetHUDOption(HUDOption_TimerStyle, value);
+ }
+ }
+
+ property int SpeedText {
+ public get() {
+ return this.GetHUDOption(HUDOption_SpeedText);
+ }
+ public set(int value) {
+ this.SetHUDOption(HUDOption_SpeedText, value);
+ }
+ }
+
+ property int ShowWeapon {
+ public get() {
+ return this.GetHUDOption(HUDOption_ShowWeapon);
+ }
+ public set(int value) {
+ this.SetHUDOption(HUDOption_ShowWeapon, value);
+ }
+ }
+
+ property int ReplayControls {
+ public get() {
+ return this.GetHUDOption(HUDOption_ShowControls);
+ }
+ public set(int value) {
+ this.SetHUDOption(HUDOption_ShowControls, value);
+ }
+ }
+
+ property int ShowSpectators {
+ public get() {
+ return this.GetHUDOption(HUDOption_ShowSpectators);
+ }
+ public set(int value) {
+ this.SetHUDOption(HUDOption_ShowSpectators, value);
+ }
+ }
+
+ property int SpecListPosition {
+ public get() {
+ return this.GetHUDOption(HUDOption_SpecListPosition);
+ }
+ public set(int value){
+ this.SetHUDOption(HUDOption_SpecListPosition, value);
+ }
+ }
+
+ property bool MenuShowing {
+ public get() {
+ return GOKZ_HUD_GetMenuShowing(this.ID);
+ }
+ public set(bool value) {
+ GOKZ_HUD_SetMenuShowing(this.ID, value);
+ }
+ }
+ property int DynamicMenu {
+ public get() {
+ return this.GetHUDOption(HUDOption_DynamicMenu);
+ }
+ public set(int value) {
+ this.SetHUDOption(HUDOption_DynamicMenu, value);
+ }
+ }
+ #endif
+ // =====[ END HUD ]=====
+
+
+
+ // =====[ PISTOL ]=====
+ #if defined _gokz_pistol_included_
+
+ property int Pistol {
+ public get() {
+ return this.GetOption(PISTOL_OPTION_NAME);
+ }
+ public set(int value) {
+ this.SetOption(PISTOL_OPTION_NAME, value);
+ }
+ }
+
+ #endif
+ // =====[ END PISTOL ]=====
+
+
+
+ // =====[ JUMP BEAM ]=====
+ #if defined _gokz_jumpbeam_included_
+
+ public any GetJBOption(JBOption option) {
+ return GOKZ_JB_GetOption(this.ID, option);
+ }
+
+ public bool SetJBOption(JBOption option, any value) {
+ return GOKZ_JB_SetOption(this.ID, option, value);
+ }
+
+ public bool CycleJBOption(JBOption option) {
+ return GOKZ_JB_CycleOption(this.ID, option);
+ }
+
+ property int JBType {
+ public get() {
+ return this.GetJBOption(JBOption_Type);
+ }
+ public set(int value) {
+ this.SetJBOption(JBOption_Type, value);
+ }
+ }
+
+ #endif
+ // =====[ END JUMP BEAM ]=====
+
+
+
+ // =====[ TIPS ]=====
+ #if defined _gokz_tips_included_
+
+ property int Tips {
+ public get() {
+ return this.GetOption(TIPS_OPTION_NAME);
+ }
+ public set(int value) {
+ this.SetOption(TIPS_OPTION_NAME, value);
+ }
+ }
+
+ #endif
+ // =====[ END TIPS ]=====
+
+
+
+ // =====[ QUIET ]=====
+ #if defined _gokz_quiet_included_
+
+ property int ShowPlayers {
+ public get() {
+ return this.GetOption(gC_QTOptionNames[QTOption_ShowPlayers]);
+ }
+ public set(int value) {
+ this.SetOption(gC_QTOptionNames[QTOption_ShowPlayers], value);
+ }
+ }
+
+ #endif
+ // =====[ END QUIET ]=====
+
+
+
+ // =====[ SLAY ON END ]=====
+ #if defined _gokz_slayonend_included_
+
+ property int SlayOnEnd {
+ public get() {
+ return this.GetOption(SLAYONEND_OPTION_NAME);
+ }
+ public set(int value) {
+ this.SetOption(SLAYONEND_OPTION_NAME, value);
+ }
+ }
+
+ #endif
+ // =====[ END SLAY ON END ]=====
+} \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/localdb.inc b/sourcemod/scripting/include/gokz/localdb.inc
new file mode 100644
index 0000000..472a120
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/localdb.inc
@@ -0,0 +1,353 @@
+/*
+ gokz-localdb Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_localdb_included_
+#endinput
+#endif
+#define _gokz_localdb_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum DatabaseType
+{
+ DatabaseType_None = -1,
+ DatabaseType_MySQL,
+ DatabaseType_SQLite
+};
+
+enum
+{
+ JumpstatDB_Lookup_JumpID = 0,
+ JumpstatDB_Lookup_Distance,
+ JumpstatDB_Lookup_Block
+};
+
+enum
+{
+ JumpstatDB_FindPlayer_SteamID32 = 0,
+ JumpstatDB_FindPlayer_Alias
+};
+
+enum
+{
+ JumpstatDB_Top20_JumpID = 0,
+ JumpstatDB_Top20_SteamID,
+ JumpstatDB_Top20_Alias,
+ JumpstatDB_Top20_Block,
+ JumpstatDB_Top20_Distance,
+ JumpstatDB_Top20_Strafes,
+ JumpstatDB_Top20_Sync,
+ JumpstatDB_Top20_Pre,
+ JumpstatDB_Top20_Max,
+ JumpstatDB_Top20_Air
+};
+
+enum
+{
+ JumpstatDB_PBMenu_JumpID = 0,
+ JumpstatDB_PBMenu_JumpType,
+ JumpstatDB_PBMenu_Distance,
+ JumpstatDB_PBMenu_Strafes,
+ JumpstatDB_PBMenu_Sync,
+ JumpstatDB_PBMenu_Pre,
+ JumpstatDB_PBMenu_Max,
+ JumpstatDB_PBMenu_Air
+};
+
+enum
+{
+ JumpstatDB_BlockPBMenu_JumpID = 0,
+ JumpstatDB_BlockPBMenu_JumpType,
+ JumpstatDB_BlockPBMenu_Block,
+ JumpstatDB_BlockPBMenu_Distance,
+ JumpstatDB_BlockPBMenu_Strafes,
+ JumpstatDB_BlockPBMenu_Sync,
+ JumpstatDB_BlockPBMenu_Pre,
+ JumpstatDB_BlockPBMenu_Max,
+ JumpstatDB_BlockPBMenu_Air
+};
+
+enum
+{
+ JumpstatDB_Cache_Distance = 0,
+ JumpstatDB_Cache_Block,
+ JumpstatDB_Cache_BlockDistance,
+ JUMPSTATDB_CACHE_COUNT
+};
+
+enum
+{
+ TimerSetupDB_GetVBPos_SteamID = 0,
+ TimerSetupDB_GetVBPos_MapID,
+ TimerSetupDB_GetVBPos_Course,
+ TimerSetupDB_GetVBPos_IsStart,
+ TimerSetupDB_GetVBPos_PositionX,
+ TimerSetupDB_GetVBPos_PositionY,
+ TimerSetupDB_GetVBPos_PositionZ
+};
+
+enum
+{
+ TimerSetupDB_GetStartPos_SteamID = 0,
+ TimerSetupDB_GetStartPos_MapID,
+ TimerSetupDB_GetStartPos_PositionX,
+ TimerSetupDB_GetStartPos_PositionY,
+ TimerSetupDB_GetStartPos_PositionZ,
+ TimerSetupDB_GetStartPos_Angle0,
+ TimerSetupDB_GetStartPos_Angle1
+};
+
+enum DBOption:
+{
+ DBOption_AutoLoadTimerSetup = 0,
+ DBOPTION_COUNT
+};
+
+enum
+{
+ DBOption_Disabled = 0,
+ DBOption_Enabled,
+ DBOPTIONBOOL_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define GOKZ_DB_JS_DISTANCE_PRECISION 10000
+#define GOKZ_DB_JS_SYNC_PRECISION 100
+#define GOKZ_DB_JS_PRE_PRECISION 100
+#define GOKZ_DB_JS_MAX_PRECISION 100
+#define GOKZ_DB_JS_AIRTIME_PRECISION 10000
+#define GOKZ_DB_JS_MAX_JUMPS_PER_PLAYER 100
+
+stock char gC_DBOptionNames[DBOPTION_COUNT][] =
+{
+ "GOKZ DB - Auto Load Setup"
+};
+
+stock char gC_DBOptionDescriptions[DBOPTION_COUNT][] =
+{
+ "Automatically load timer setup on map start - 0 = Disabled, 1 = Enabled"
+}
+
+stock int gI_DBOptionDefaultValues[DBOPTION_COUNT] =
+{
+ DBOption_Disabled
+};
+
+stock int gI_DBOptionCounts[DBOPTION_COUNT] =
+{
+ DBOPTIONBOOL_COUNT
+};
+
+stock char gC_DBOptionPhrases[DBOPTION_COUNT][] =
+{
+ "Options Menu - Auto Load Timer Setup"
+};
+
+
+
+// =====[ TYPES ]=====
+
+typeset GetVBPositionCallback
+{
+ function Action(int client, const float position[3], int course, bool isStart);
+};
+
+typeset GetStartPositionCallback
+{
+ function Action(int client, const float position[3], const float angles[3]);
+};
+
+
+
+// =====[ FORWARDS ]=====
+
+/**
+ * Called when gokz-localdb has connected to the database.
+ * Use GOKZ_DB_GetDatabase to get a clone of the database handle.
+ *
+ * @param DBType Database type.
+ */
+forward void GOKZ_DB_OnDatabaseConnect(DatabaseType DBType);
+
+/**
+ * Called when a player is ready for database interaction.
+ * At this point, the player is present and updated in the "Players" table.
+ *
+ * @param client Client index.
+ * @param steamID SteamID32 of the player (from GetSteamAccountID()).
+ * @param cheater Whether player is marked as a cheater in the database.
+ */
+forward void GOKZ_DB_OnClientSetup(int client, int steamID, bool cheater);
+
+/**
+ * Called when the current map is ready for database interaction.
+ * At this point, the map is present and updated in the "Maps" table.
+ *
+ * @param mapID MapID from the "Maps" table.
+ */
+forward void GOKZ_DB_OnMapSetup(int mapID);
+
+/**
+ * Called when a time has been inserted into the database.
+ *
+ * @param client Client index.
+ * @param steamID SteamID32 of the player (from GetSteamAccountID()).
+ * @param mapID MapID from the "Maps" table.
+ * @param course Course number e.g. 0=main, 1='bonus1' etc.
+ * @param mode Player's movement mode.
+ * @param style Player's movement style.
+ * @param runTimeMS Player's end time in milliseconds.
+ * @param teleportsUsed Number of teleports used by player.
+ */
+forward void GOKZ_DB_OnTimeInserted(
+ int client,
+ int steamID,
+ int mapID,
+ int course,
+ int mode,
+ int style,
+ int runTimeMS,
+ int teleportsUsed);
+
+/**
+ * Called when jumpstat PB has been achieved.
+ *
+ * @param client Client index.
+ * @param jumptype Type of the jump.
+ * @param mode Mode the jump was performed in.
+ * @param distance Distance jumped.
+ * @param block The size of the block jumped across.
+ * @param strafes The amount of strafes used.
+ * @param sync Keyboard/mouse synchronisation of the jump.
+ * @param pre Speed at takeoff.
+ * @param max Maximum speed during the jump.
+ * @param airtime Amount of time spend airborne.
+ */
+forward void GOKZ_DB_OnJumpstatPB(
+ int client,
+ int jumptype,
+ int mode,
+ float distance,
+ int block,
+ int strafes,
+ float sync,
+ float pre,
+ float max,
+ int airtime);
+
+
+// =====[ NATIVES ]=====
+
+/**
+ * Gets a clone of the GOKZ local database handle.
+ *
+ * @param database Database handle, or null if connection hasn't been made.
+ */
+native Database GOKZ_DB_GetDatabase();
+
+/**
+ * Gets the GOKZ local database type.
+ *
+ * @return Database type.
+ */
+native DatabaseType GOKZ_DB_GetDatabaseType();
+
+/**
+ * Gets whether client has been set up for GOKZ Local DB.
+ *
+ * @param client Client index.
+ * @return Whether GOKZ Local DB has set up the client.
+ */
+native bool GOKZ_DB_IsClientSetUp(int client);
+
+/**
+ * Gets whether GOKZ Local DB is set up for the current map.
+ *
+ * @return Whether GOKZ Local DB has set up the current map.
+ */
+native bool GOKZ_DB_IsMapSetUp();
+
+/**
+ * Gets the current map's MapID as in the "Maps" table.
+ *
+ * @return MapID from the "Maps" table.
+ */
+native int GOKZ_DB_GetCurrentMapID();
+
+/**
+ * Gets whether player is marked as a cheater in the database.
+ *
+ * @param client Client index.
+ * @return Whether player is marked as a cheater in the database.
+ */
+native bool GOKZ_DB_IsCheater(int client);
+
+/**
+ * Sets wheter player is marked as a cheater in the database.
+ *
+ * @param client Client index.
+ * @param cheater Whether to mark the player as a cheater.
+ */
+native void GOKZ_DB_SetCheater(int client, bool cheater);
+
+
+
+// =====[ STOCKS ]=====
+
+/**
+ * Converts a time float (seconds) to an integer (milliseconds).
+ *
+ * @param time Time in seconds.
+ * @return Time in milliseconds.
+ */
+stock int GOKZ_DB_TimeFloatToInt(float time)
+{
+ return RoundFloat(time * 1000.0);
+}
+
+/**
+ * Converts a time integer (milliseconds) to a float (seconds).
+ *
+ * @param time Time in milliseconds.
+ * @return Time in seconds.
+ */
+stock float GOKZ_DB_TimeIntToFloat(int time)
+{
+ return time / 1000.0;
+}
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_localdb =
+{
+ name = "gokz-localdb",
+ file = "gokz-localdb.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_localdb_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_DB_GetDatabase");
+ MarkNativeAsOptional("GOKZ_DB_GetDatabaseType");
+ MarkNativeAsOptional("GOKZ_DB_IsClientSetUp");
+ MarkNativeAsOptional("GOKZ_DB_IsMapSetUp");
+ MarkNativeAsOptional("GOKZ_DB_GetCurrentMapID");
+ MarkNativeAsOptional("GOKZ_DB_IsCheater");
+ MarkNativeAsOptional("GOKZ_DB_SetCheater");
+}
+#endif
diff --git a/sourcemod/scripting/include/gokz/localranks.inc b/sourcemod/scripting/include/gokz/localranks.inc
new file mode 100644
index 0000000..914c6cb
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/localranks.inc
@@ -0,0 +1,176 @@
+/*
+ gokz-localranks Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_localranks_included_
+#endinput
+#endif
+#define _gokz_localranks_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum
+{
+ RecordType_Nub = 0,
+ RecordType_Pro,
+ RecordType_NubAndPro,
+ RECORDTYPE_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define LR_CFG_MAP_POOL "cfg/sourcemod/gokz/gokz-localranks-mappool.cfg"
+#define LR_CFG_SOUNDS "cfg/sourcemod/gokz/gokz-localranks-sounds.cfg"
+#define LR_COMMAND_COOLDOWN 2.5
+#define LR_MAP_TOP_CUTOFF 20
+#define LR_PLAYER_TOP_CUTOFF 20
+
+
+
+// =====[ FORWARDS ]=====
+
+/**
+ * Called when a player's time has been processed by GOKZ Local Ranks.
+ *
+ * @param client Client index.
+ * @param steamID SteamID32 of the player (from GetSteamAccountID()).
+ * @param mapID MapID from the "Maps" database table.
+ * @param course Course number e.g. 0=main, 1='bonus1' etc.
+ * @param mode Player's movement mode.
+ * @param style Player's movement style.
+ * @param runTime Player's end time.
+ * @param teleportsUsed Number of teleportsUsed used by player.
+ * @param firstTime Whether this is player's first time on this course.
+ * @param pbDiff Difference between new time and PB in seconds (-'ve means beat PB).
+ * @param rank New rank of the player's PB time.
+ * @param maxRank New total number of players with times.
+ * @param firstTimePro Whether this is player's first PRO time on this course.
+ * @param pbDiffPro Difference between new time and PRO PB in seconds (-'ve means beat PB).
+ * @param rankPro New rank of the player's PB PRO time.
+ * @param maxRankPro New total number of players with PRO times.
+ */
+forward void GOKZ_LR_OnTimeProcessed(
+ int client,
+ int steamID,
+ int mapID,
+ int course,
+ int mode,
+ int style,
+ float runTime,
+ int teleportsUsed,
+ bool firstTime,
+ float pbDiff,
+ int rank,
+ int maxRank,
+ bool firstTimePro,
+ float pbDiffPro,
+ int rankPro,
+ int maxRankPro);
+
+/**
+ * Called when a player sets a new local record.
+ *
+ * @param client Client index.
+ * @param steamID SteamID32 of the player (from GetSteamAccountID()).
+ * @param mapID MapID from the "Maps" table.
+ * @param course Course number e.g. 0=main, 1='bonus1' etc.
+ * @param mode Player's movement mode.
+ * @param style Player's movement style.
+ * @param recordType Type of record.
+ */
+forward void GOKZ_LR_OnNewRecord(
+ int client,
+ int steamID,
+ int mapID,
+ int course,
+ int mode,
+ int style,
+ int recordType,
+ float pbDiff,
+ int teleportsUsed);
+
+/**
+ * Called when a player misses the server record time.
+ * Is called regardless of player's current run type.
+ *
+ * @param client Client index.
+ * @param recordTime Record time missed.
+ * @param course Course number e.g. 0=main, 1='bonus1' etc.
+ * @param mode Player's movement mode.
+ * @param style Player's movement style.
+ * @param recordType Type of record.
+ */
+forward void GOKZ_LR_OnRecordMissed(int client, float recordTime, int course, int mode, int style, int recordType);
+
+/**
+ * Called when a player misses their personal best time.
+ * Is called regardless of player's current run type.
+ *
+ * @param client Client index.
+ * @param pbTime Personal best time missed.
+ * @param course Course number e.g. 0=main, 1='bonus1' etc.
+ * @param mode Player's movement mode.
+ * @param style Player's movement style.
+ * @param recordType Type of record.
+ */
+forward void GOKZ_LR_OnPBMissed(int client, float pbTime, int course, int mode, int style, int recordType);
+
+
+
+// =====[ NATIVES ]=====
+
+/**
+ * Gets whether player has missed the server record time.
+ *
+ * @param client Client index.
+ * @param timeType Which record time i.e. NUB or PRO.
+ * @return Whether player has missed the server record time.
+ */
+native bool GOKZ_LR_GetRecordMissed(int client, int timeType);
+
+/**
+ * Gets whether player has missed their personal best time.
+ *
+ * @param client Client index.
+ * @param timeType Which PB time i.e. NUB or PRO.
+ * @return Whether player has missed their PB time.
+ */
+native bool GOKZ_LR_GetPBMissed(int client, int timeType);
+
+/**
+ * Reopens the map top menu with the already selected parameters.
+ * Don't use if the client hasn't opened the map top menu before.
+ *
+ * @param client Client index.
+ */
+native void GOKZ_LR_ReopenMapTopMenu(int client);
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_localranks =
+{
+ name = "gokz-localranks",
+ file = "gokz-localranks.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_localranks_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_LR_GetRecordMissed");
+ MarkNativeAsOptional("GOKZ_LR_GetPBMissed");
+ MarkNativeAsOptional("GOKZ_LR_ReopenMapTopMenu");
+}
+#endif \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/momsurffix.inc b/sourcemod/scripting/include/gokz/momsurffix.inc
new file mode 100644
index 0000000..65f603e
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/momsurffix.inc
@@ -0,0 +1,23 @@
+/*
+ gokz-momsurffix Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_momsurffix_included_
+#endinput
+#endif
+#define _gokz_momsurffix_included_
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_momsurffix =
+{
+ name = "gokz-momsurffix",
+ file = "gokz-momsurffix.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+}; \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/paint.inc b/sourcemod/scripting/include/gokz/paint.inc
new file mode 100644
index 0000000..19f4fb5
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/paint.inc
@@ -0,0 +1,114 @@
+/*
+ gokz-paint Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_paint_included_
+#endinput
+#endif
+#define _gokz_paint_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum PaintOption:
+{
+ PAINTOPTION_INVALID = -1,
+ PaintOption_Color,
+ PaintOption_Size,
+ PAINTOPTION_COUNT
+};
+
+enum
+{
+ PaintColor_Red = 0,
+ PaintColor_White,
+ PaintColor_Black,
+ PaintColor_Blue,
+ PaintColor_Brown,
+ PaintColor_Green,
+ PaintColor_Yellow,
+ PaintColor_Purple,
+ PAINTCOLOR_COUNT
+};
+
+enum
+{
+ PaintSize_Small = 0,
+ PaintSize_Medium,
+ PaintSize_Big,
+ PAINTSIZE_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define PAINT_OPTION_CATEGORY "Paint"
+#define MIN_PAINT_SPACING 1.0
+
+stock char gC_PaintOptionNames[PAINTOPTION_COUNT][] =
+{
+ "GOKZ Paint - Color",
+ "GOKZ Paint - Size"
+};
+
+stock char gC_PaintOptionDescriptions[PAINTOPTION_COUNT][] =
+{
+ "Paint Color",
+ "Paint Size - 0 = Small, 1 = Medium, 2 = Big"
+};
+
+stock char gC_PaintOptionPhrases[PAINTOPTION_COUNT][] =
+{
+ "Options Menu - Paint Color",
+ "Options Menu - Paint Size"
+};
+
+stock int gI_PaintOptionCounts[PAINTOPTION_COUNT] =
+{
+ PAINTCOLOR_COUNT,
+ PAINTSIZE_COUNT
+};
+
+stock int gI_PaintOptionDefaults[PAINTOPTION_COUNT] =
+{
+ PaintColor_Red,
+ PaintSize_Medium
+};
+
+stock char gC_PaintColorPhrases[PAINTCOLOR_COUNT][] =
+{
+ "Options Menu - Red",
+ "Options Menu - White",
+ "Options Menu - Black",
+ "Options Menu - Blue",
+ "Options Menu - Brown",
+ "Options Menu - Green",
+ "Options Menu - Yellow",
+ "Options Menu - Purple"
+};
+
+stock char gC_PaintSizePhrases[PAINTSIZE_COUNT][] =
+{
+ "Options Menu - Small",
+ "Options Menu - Medium",
+ "Options Menu - Big"
+};
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_paint =
+{
+ name = "gokz-paint",
+ file = "gokz-paint.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
diff --git a/sourcemod/scripting/include/gokz/pistol.inc b/sourcemod/scripting/include/gokz/pistol.inc
new file mode 100644
index 0000000..1edd5f9
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/pistol.inc
@@ -0,0 +1,93 @@
+/*
+ gokz-pistol Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_pistol_included_
+#endinput
+#endif
+#define _gokz_pistol_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum
+{
+ Pistol_Disabled = 0,
+ Pistol_USPS,
+ Pistol_Glock18,
+ Pistol_DualBerettas,
+ Pistol_P250,
+ Pistol_FiveSeveN,
+ Pistol_Tec9,
+ Pistol_CZ75Auto,
+ Pistol_DesertEagle,
+ Pistol_R8Revolver,
+ PISTOL_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define PISTOL_OPTION_NAME "GOKZ - Pistol"
+#define PISTOL_OPTION_DESCRIPTION "Pistol - 0 = Disabled, 1 = USP-S / P2000, 2 = Glock-18, 3 = Dual Berettas, 4 = P250, 5 = Five-SeveN, 6 = Tec-9, 7 = CZ75-Auto, 8 = Desert Eagle, 9 = R8 Revolver"
+
+stock char gC_PistolNames[PISTOL_COUNT][] =
+{
+ "", // Disabled
+ "USP-S / P2000",
+ "Glock-18",
+ "Dual Berettas",
+ "P250",
+ "Five-SeveN",
+ "Tec-9",
+ "CZ75-Auto",
+ "Desert Eagle",
+ "R8 Revolver"
+};
+
+stock char gC_PistolClassNames[PISTOL_COUNT][] =
+{
+ "", // Disabled
+ "weapon_hkp2000",
+ "weapon_glock",
+ "weapon_elite",
+ "weapon_p250",
+ "weapon_fiveseven",
+ "weapon_tec9",
+ "weapon_cz75a",
+ "weapon_deagle",
+ "weapon_revolver"
+};
+
+stock int gI_PistolTeams[PISTOL_COUNT] =
+{
+ CS_TEAM_NONE, // Disabled
+ CS_TEAM_CT,
+ CS_TEAM_T,
+ CS_TEAM_NONE,
+ CS_TEAM_NONE,
+ CS_TEAM_CT,
+ CS_TEAM_T,
+ CS_TEAM_NONE,
+ CS_TEAM_NONE,
+ CS_TEAM_NONE
+};
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_pistol =
+{
+ name = "gokz-pistol",
+ file = "gokz-pistol.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+}; \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/profile.inc b/sourcemod/scripting/include/gokz/profile.inc
new file mode 100644
index 0000000..70d314a
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/profile.inc
@@ -0,0 +1,291 @@
+/*
+ gokz-profile Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_profile_included_
+#endinput
+#endif
+#define _gokz_profile_included_
+
+
+// =====[ RANKS ]=====
+
+#define RANK_COUNT 23
+
+stock int gI_rankThreshold[MODE_COUNT][RANK_COUNT] = {
+ {
+ 0,
+ 1,
+ 500,
+ 1000,
+
+ 2000,
+ 5000,
+ 10000,
+
+ 20000,
+ 30000,
+ 40000,
+
+ 60000,
+ 70000,
+ 80000,
+
+ 100000,
+ 120000,
+ 140000,
+
+ 160000,
+ 180000,
+ 200000,
+
+ 250000,
+ 300000,
+ 400000,
+ 600000
+ },
+ {
+ 0,
+ 1,
+ 500,
+ 1000,
+
+ 2000,
+ 5000,
+ 10000,
+
+ 20000,
+ 30000,
+ 40000,
+
+ 60000,
+ 70000,
+ 80000,
+
+ 100000,
+ 120000,
+ 150000,
+
+ 200000,
+ 230000,
+ 250000,
+
+ 300000,
+ 400000,
+ 500000,
+ 800000
+ },
+ {
+ 0,
+ 1,
+ 500,
+ 1000,
+
+ 2000,
+ 5000,
+ 10000,
+
+ 20000,
+ 30000,
+ 40000,
+
+ 60000,
+ 70000,
+ 80000,
+
+ 100000,
+ 120000,
+ 150000,
+
+ 200000,
+ 230000,
+ 250000,
+
+ 400000,
+ 600000,
+ 800000,
+ 1000000
+ },
+};
+
+stock char gC_rankName[RANK_COUNT][] = {
+ "New",
+ "Beginner-",
+ "Beginner",
+ "Beginner+",
+ "Amateur-",
+ "Amateur",
+ "Amateur+",
+ "Casual-",
+ "Casual",
+ "Casual+",
+ "Regular-",
+ "Regular",
+ "Regular+",
+ "Skilled-",
+ "Skilled",
+ "Skilled+",
+ "Expert-",
+ "Expert",
+ "Expert+",
+ "Semipro",
+ "Pro",
+ "Master",
+ "Legend"
+};
+
+stock char gC_rankColor[RANK_COUNT][] = {
+ "{grey}",
+ "{default}",
+ "{default}",
+ "{default}",
+ "{blue}",
+ "{blue}",
+ "{blue}",
+ "{lightgreen}",
+ "{lightgreen}",
+ "{lightgreen}",
+ "{green}",
+ "{green}",
+ "{green}",
+ "{purple}",
+ "{purple}",
+ "{purple}",
+ "{orchid}",
+ "{orchid}",
+ "{orchid}",
+ "{lightred}",
+ "{lightred}",
+ "{red}",
+ "{gold}"
+};
+
+
+// =====[ ENUMS ]=====
+
+enum ProfileOption:
+{
+ PROFILEOPTION_INVALID = -1,
+ ProfileOption_ShowRankChat,
+ ProfileOption_ShowRankClanTag,
+ ProfileOption_TagType,
+ PROFILEOPTION_COUNT
+};
+
+enum
+{
+ ProfileOptionBool_Disabled = 0,
+ ProfileOptionBool_Enabled,
+ PROFILEOPTIONBOOL_COUNT
+};
+
+enum
+{
+ ProfileTagType_Rank = 0,
+ ProfileTagType_Admin,
+ ProfileTagType_VIP,
+ PROFILETAGTYPE_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+stock char gC_ProfileOptionNames[PROFILEOPTION_COUNT][] =
+{
+ "GOKZ Profile - Show Rank Chat",
+ "GOKZ Profile - Show Rank Clan",
+ "GOKZ Profile - Tag Type"
+};
+
+stock char gC_ProfileOptionDescriptions[PROFILEOPTION_COUNT][] =
+{
+ "Show Rank Tag in Chat - 0 = Disabled, 1 = Enabled",
+ "Show Rank in Clan - 0 = Disabled, 1 = Enabled",
+ "Type of Tag to Show - 0 = Rank, 1 = Admin, 2 = VIP"
+};
+
+stock char gC_ProfileOptionPhrases[PROFILEOPTION_COUNT][] =
+{
+ "Options Menu - Show Rank Chat",
+ "Options Menu - Show Rank Clan",
+ "Options Menu - Tag Type",
+};
+
+stock char gC_ProfileBoolPhrases[PROFILEOPTIONBOOL_COUNT][] =
+{
+ "Options Menu - Disabled",
+ "Options Menu - Enabled"
+};
+
+stock char gC_ProfileTagTypePhrases[PROFILETAGTYPE_COUNT][] =
+{
+ "Options Menu - Tag Rank",
+ "Options Menu - Tag Admin",
+ "Options Menu - Tag VIP"
+};
+
+stock int gI_ProfileOptionCounts[PROFILEOPTION_COUNT] =
+{
+ PROFILEOPTIONBOOL_COUNT,
+ PROFILEOPTIONBOOL_COUNT,
+ PROFILETAGTYPE_COUNT
+};
+
+stock int gI_ProfileOptionDefaults[PROFILEOPTION_COUNT] =
+{
+ ProfileOptionBool_Enabled,
+ ProfileOptionBool_Enabled,
+ ProfileTagType_Rank
+};
+
+#define PROFILE_OPTION_CATEGORY "Profile"
+#define TAG_COLOR_ADMIN "{red}"
+#define TAG_COLOR_VIP "{purple}"
+
+
+// =====[ FORWARDS ]=====
+
+
+/**
+ * Called when the rank of a player is updated.
+ *
+ * @param client Client index.
+ * @param mode Game mode.
+ * @param rank The new rank.
+ */
+forward void GOKZ_PF_OnRankUpdated(int client, int mode, int rank);
+
+// =====[ NATIVES ]=====
+
+/**
+ * Gets whether a mode is loaded.
+ *
+ * @param client Client.
+ * @param tag Mode.
+ * @returns Integer representing the player rank.
+ */
+native int GOKZ_PF_GetRank(int client, int mode);
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_profile =
+{
+ name = "gokz-profile",
+ file = "gokz-profile.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_profile_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_PF_GetRank");
+}
+#endif \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/quiet.inc b/sourcemod/scripting/include/gokz/quiet.inc
new file mode 100644
index 0000000..a328b7e
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/quiet.inc
@@ -0,0 +1,205 @@
+/*
+ gokz-quiet Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_quiet_included_
+#endinput
+#endif
+#define _gokz_quiet_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum QTOption:
+{
+ QTOPTION_INVALID = -1,
+ QTOption_ShowPlayers,
+ QTOption_Soundscapes,
+ QTOption_FallDamageSound,
+ QTOption_AmbientSounds,
+ QTOption_CheckpointVolume,
+ QTOption_TeleportVolume,
+ QTOption_TimerVolume,
+ QTOption_ErrorVolume,
+ QTOption_ServerRecordVolume,
+ QTOption_WorldRecordVolume,
+ QTOption_JumpstatsVolume,
+ QTOPTION_COUNT
+};
+
+enum
+{
+ ShowPlayers_Disabled = 0,
+ ShowPlayers_Enabled,
+ SHOWPLAYERS_COUNT
+};
+
+enum
+{
+ Soundscapes_Disabled = 0,
+ Soundscapes_Enabled,
+ SOUNDSCAPES_COUNT
+};
+
+// =====[ CONSTANTS ]=====
+
+#define QUIET_OPTION_CATEGORY "Quiet"
+#define DEFAULT_VOLUME 10
+#define VOLUME_COUNT 21 // Maximum of 200%
+
+#define EFFECT_IMPACT 8
+#define EFFECT_KNIFESLASH 2
+#define BLANK_SOUNDSCAPEINDEX 482 // Search for "coopcementplant.missionselect_blank" id with sv_soundscape_printdebuginfo.
+
+stock char gC_QTOptionNames[QTOPTION_COUNT][] =
+{
+ "GOKZ QT - Show Players",
+ "GOKZ QT - Soundscapes",
+ "GOKZ QT - Fall Damage Sound",
+ "GOKZ QT - Ambient Sounds",
+ "GOKZ QT - Checkpoint Volume",
+ "GOKZ QT - Teleport Volume",
+ "GOKZ QT - Timer Volume",
+ "GOKZ QT - Error Volume",
+ "GOKZ QT - Server Record Volume",
+ "GOKZ QT - World Record Volume",
+ "GOKZ QT - Jumpstats Volume"
+};
+
+stock char gC_QTOptionDescriptions[QTOPTION_COUNT][] =
+{
+ "Visibility of Other Players - 0 = Disabled, 1 = Enabled",
+ "Play Soundscapes - 0 = Disabled, 1 = Enabled",
+ "Play Fall Damage Sound - 0 to 20 = 0% to 200%",
+ "Play Ambient Sounds - 0 to 20 = 0% to 200%",
+ "Checkpoint Volume - 0 to 20 = 0% to 200%",
+ "Teleport Volume - 0 to 20 = 0% to 200%",
+ "Timer Volume - 0 to 20 = 0% to 200%",
+ "Error Volume - 0 to 20 = 0% to 200%",
+ "Server Record Volume - 0 to 20 = 0% to 200%",
+ "World Record Volume - 0 to 20 = 0% to 200%",
+ "Jumpstats Volume - 0 to 20 = 0% to 200%"
+};
+
+stock int gI_QTOptionDefaultValues[QTOPTION_COUNT] =
+{
+ ShowPlayers_Enabled,
+ Soundscapes_Enabled,
+ DEFAULT_VOLUME, // Fall damage volume
+ DEFAULT_VOLUME, // Ambient volume
+ DEFAULT_VOLUME, // Checkpoint volume
+ DEFAULT_VOLUME, // Teleport volume
+ DEFAULT_VOLUME, // Timer volume
+ DEFAULT_VOLUME, // Error volume
+ DEFAULT_VOLUME, // Server Record Volume
+ DEFAULT_VOLUME, // World Record Volume
+ DEFAULT_VOLUME // Jumpstats Volume
+};
+
+stock int gI_QTOptionCounts[QTOPTION_COUNT] =
+{
+ SHOWPLAYERS_COUNT,
+ SOUNDSCAPES_COUNT,
+ VOLUME_COUNT, // Fall damage volume
+ VOLUME_COUNT, // Ambient volume
+ VOLUME_COUNT, // Checkpoint volume
+ VOLUME_COUNT, // Teleport volume
+ VOLUME_COUNT, // Timer volume
+ VOLUME_COUNT, // Error volume
+ VOLUME_COUNT, // Server Record volume
+ VOLUME_COUNT, // World Record volume
+ VOLUME_COUNT // Jumpstats volume
+};
+
+stock char gC_QTOptionPhrases[QTOPTION_COUNT][] =
+{
+ "Options Menu - Show Players",
+ "Options Menu - Soundscapes",
+ "Options Menu - Fall Damage Sounds",
+ "Options Menu - Ambient Sounds",
+ "Options Menu - Checkpoint Volume",
+ "Options Menu - Teleport Volume",
+ "Options Menu - Timer Volume",
+ "Options Menu - Error Volume",
+ "Options Menu - Server Record Volume",
+ "Options Menu - World Record Volume",
+ "Options Menu - Jumpstats Volume"
+};
+
+// =====[ STOCKS ]=====
+
+/**
+ * Returns whether an option is a gokz-quiet option.
+ *
+ * @param option Option name.
+ * @param optionEnum Variable to store enumerated gokz-quiet option (if it is one).
+ * @return Whether option is a gokz-quiet option.
+ */
+stock bool GOKZ_QT_IsQTOption(const char[] option, QTOption &optionEnum = QTOPTION_INVALID)
+{
+ for (QTOption i; i < QTOPTION_COUNT; i++)
+ {
+ if (StrEqual(option, gC_QTOptionNames[i]))
+ {
+ optionEnum = i;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Gets the current value of a player's gokz-quiet option.
+ *
+ * @param client Client index.
+ * @param option gokz-quiet option.
+ * @return Current value of option.
+ */
+stock any GOKZ_QT_GetOption(int client, QTOption option)
+{
+ return GOKZ_GetOption(client, gC_QTOptionNames[option]);
+}
+
+/**
+ * Sets a player's gokz-quiet option's value.
+ *
+ * @param client Client index.
+ * @param option gokz-quiet option.
+ * @param value New option value.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_QT_SetOption(int client, QTOption option, any value)
+{
+ return GOKZ_SetOption(client, gC_QTOptionNames[option], value);
+}
+
+/**
+ * Increment an integer-type gokz-quiet option's value.
+ * Loops back to '0' if max value is exceeded.
+ *
+ * @param client Client index.
+ * @param option gokz-quiet option.
+ * @return Whether option was successfully set.
+ */
+stock bool GOKZ_QT_CycleOption(int client, QTOption option)
+{
+ return GOKZ_CycleOption(client, gC_QTOptionNames[option]);
+}
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_quiet =
+{
+ name = "gokz-quiet",
+ file = "gokz-quiet.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+}; \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/racing.inc b/sourcemod/scripting/include/gokz/racing.inc
new file mode 100644
index 0000000..d6819ea
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/racing.inc
@@ -0,0 +1,189 @@
+/*
+ gokz-racing Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_racing_included_
+#endinput
+#endif
+#define _gokz_racing_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum RaceInfo:
+{
+ RaceInfo_ID,
+ RaceInfo_Status,
+ RaceInfo_HostUserID,
+ RaceInfo_FinishedRacerCount,
+ RaceInfo_Type,
+ RaceInfo_Course,
+ RaceInfo_Mode,
+ RaceInfo_CheckpointRule,
+ RaceInfo_CooldownRule,
+ RACEINFO_COUNT
+};
+
+enum
+{
+ RaceType_Normal,
+ RaceType_Duel,
+ RACETYPE_COUNT
+};
+
+enum
+{
+ RaceStatus_Pending,
+ RaceStatus_Countdown,
+ RaceStatus_Started,
+ RaceStatus_Aborting,
+ RACESTATUS_COUNT
+};
+
+enum
+{
+ RacerStatus_Available,
+ RacerStatus_Pending,
+ RacerStatus_Accepted,
+ RacerStatus_Racing,
+ RacerStatus_Finished,
+ RacerStatus_Surrendered,
+ RACERSTATUS_COUNT
+};
+
+enum
+{
+ CheckpointRule_None,
+ CheckpointRule_Limit,
+ CheckpointRule_Cooldown,
+ CheckpointRule_Unlimited,
+ CHECKPOINTRULE_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define RC_COUNTDOWN_TIME 10.0
+#define RC_REQUEST_TIMEOUT_TIME 15.0
+
+
+
+// =====[ FORWARDS ]=====
+
+/**
+ * Called when a player has finished their race.
+ *
+ * @param client Client index.
+ * @param raceID ID of the race.
+ * @param place Final placement in the race.
+ */
+forward void GOKZ_RC_OnFinish(int client, int raceID, int place);
+
+/**
+ * Called when a player has surrendered their race.
+ *
+ * @param client Client index.
+ * @param raceID ID of the race.
+ */
+forward void GOKZ_RC_OnSurrender(int client, int raceID);
+
+/**
+ * Called when a player receives a race request.
+ *
+ * @param client Client index.
+ * @param raceID ID of the race.
+ */
+forward void GOKZ_RC_OnRequestReceived(int client, int raceID)
+
+/**
+ * Called when a player accepts a race request.
+ *
+ * @param client Client index.
+ * @param raceID ID of the race.
+ */
+forward void GOKZ_RC_OnRequestAccepted(int client, int raceID)
+
+/**
+ * Called when a player declines a race request.
+ *
+ * @param client Client index.
+ * @param raceID ID of the race.
+ * @param timeout Whether the client was too late to respond.
+ */
+forward void GOKZ_RC_OnRequestDeclined(int client, int raceID, bool timeout)
+
+/**
+ * Called when a race has been registered.
+ * The initial status of a race is RaceStatus_Pending.
+ *
+ * @param raceID ID of the race.
+ */
+forward void GOKZ_RC_OnRaceRegistered(int raceID);
+
+/**
+ * Called when a race's info property has changed.
+ *
+ * @param raceID ID of the race.
+ * @param prop Info property that was changed.
+ * @param oldValue Previous value.
+ * @param newValue New value.
+ */
+forward void GOKZ_RC_OnRaceInfoChanged(int raceID, RaceInfo prop, int oldValue, int newValue);
+
+
+
+// =====[ NATIVES ]=====
+
+/**
+ * Gets the value of a race info property.
+ *
+ * @param raceID Race index.
+ * @param prop Info property to get.
+ * @return Value of the info property.
+ */
+native int GOKZ_RC_GetRaceInfo(int raceID, RaceInfo prop);
+
+/**
+ * Gets a player's racer status.
+ * Refer to the RacerStatus enumeration.
+ *
+ * @param client Client index.
+ * @return Racer status of the client.
+ */
+native int GOKZ_RC_GetStatus(int client);
+
+/**
+ * Gets the ID of the race a player is in.
+ *
+ * @param client Client index.
+ * @return ID of the race the player is in, or -1 if not in a race.
+ */
+native int GOKZ_RC_GetRaceID(int client);
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_racing =
+{
+ name = "gokz-racing",
+ file = "gokz-racing.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_racing_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_RC_GetRaceInfo");
+ MarkNativeAsOptional("GOKZ_RC_GetStatus");
+ MarkNativeAsOptional("GOKZ_RC_GetRaceID");
+}
+#endif \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/replays.inc b/sourcemod/scripting/include/gokz/replays.inc
new file mode 100644
index 0000000..6aabdbd
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/replays.inc
@@ -0,0 +1,275 @@
+/*
+ gokz-replays Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_replays_included_
+#endinput
+#endif
+#define _gokz_replays_included_
+
+// Bit of a hack, but need it for other plugins that depend on replays to compile
+#if defined REQUIRE_PLUGIN
+#undef REQUIRE_PLUGIN
+#include <gokz/anticheat>
+#define REQUIRE_PLUGIN
+#else
+#include <gokz/anticheat>
+#endif
+
+
+
+// =====[ ENUMS ]=====
+enum
+{
+ ReplayType_Run = 0,
+ ReplayType_Cheater,
+ ReplayType_Jump,
+ REPLAYTYPE_COUNT
+};
+
+enum ReplaySaveState
+{
+ ReplaySave_Local = 0,
+ ReplaySave_Temp,
+ ReplaySave_Disabled
+};
+
+// NOTE: Replays use delta compression for storage.
+// This enum is the indices of the ReplayTickData enum struct.
+// NOTE: This has to match the ReplayTickData enum struct!!!
+enum
+{
+ RPDELTA_DELTAFLAGS = 0,
+ RPDELTA_DELTAFLAGS2,
+ RPDELTA_VEL_X,
+ RPDELTA_VEL_Y,
+ RPDELTA_VEL_Z,
+ RPDELTA_MOUSE_X,
+ RPDELTA_MOUSE_Y,
+ RPDELTA_ORIGIN_X,
+ RPDELTA_ORIGIN_Y,
+ RPDELTA_ORIGIN_Z,
+ RPDELTA_ANGLES_X,
+ RPDELTA_ANGLES_Y,
+ RPDELTA_ANGLES_Z,
+ RPDELTA_VELOCITY_X,
+ RPDELTA_VELOCITY_Y,
+ RPDELTA_VELOCITY_Z,
+ RPDELTA_FLAGS,
+ RPDELTA_PACKETSPERSECOND,
+ RPDELTA_LAGGEDMOVEMENTVALUE,
+ RPDELTA_BUTTONSFORCED,
+
+ RP_V2_TICK_DATA_BLOCKSIZE
+};
+
+
+
+// =====[ STRUCTS ] =====
+
+enum struct GeneralReplayHeader
+{
+ int magicNumber;
+ int formatVersion;
+ int replayType;
+ char gokzVersion[32];
+ char mapName[64];
+ int mapFileSize;
+ int serverIP;
+ int timestamp;
+ char playerAlias[MAX_NAME_LENGTH];
+ int playerSteamID;
+ int mode;
+ int style;
+ float playerSensitivity;
+ float playerMYaw;
+ float tickrate;
+ int tickCount;
+ int equippedWeapon;
+ int equippedKnife;
+}
+
+enum struct JumpReplayHeader
+{
+ int jumpType;
+ float distance;
+ int blockDistance;
+ int strafeCount;
+ float sync;
+ float pre;
+ float max;
+ int airtime;
+}
+
+enum struct CheaterReplayHeader
+{
+ ACReason ACReason;
+}
+
+enum struct RunReplayHeader
+{
+ float time;
+ int course;
+ int teleportsUsed;
+}
+
+// NOTE: Make sure to change the RPDELTA_* enum, TickDataToArray() and TickDataFromArray() when adding/removing stuff from this!!!
+enum struct ReplayTickData
+{
+ int deltaFlags;
+ int deltaFlags2;
+ float vel[3];
+ int mouse[2];
+ float origin[3];
+ float angles[3];
+ float velocity[3];
+ int flags;
+ float packetsPerSecond;
+ float laggedMovementValue;
+ int buttonsForced;
+}
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define RP_DIRECTORY "data/gokz-replays" // In Path_SM
+#define RP_DIRECTORY_RUNS "data/gokz-replays/_runs" // In Path_SM
+#define RP_DIRECTORY_RUNS_TEMP "data/gokz-replays/_tempRuns" // In Path_SM
+#define RP_DIRECTORY_CHEATERS "data/gokz-replays/_cheaters" // In Path_SM
+#define RP_DIRECTORY_JUMPS "data/gokz-replays/_jumps" // In Path_SM
+#define RP_DIRECTORY_BLOCKJUMPS "blocks"
+#define RP_FILE_EXTENSION "replay"
+#define RP_MAGIC_NUMBER 0x676F6B7A
+#define RP_FORMAT_VERSION 0x02
+#define RP_NAV_FILE "maps/gokz-replays.nav"
+#define RP_V1_TICK_DATA_BLOCKSIZE 7
+#define RP_CACHE_BLOCKSIZE 4
+#define RP_MAX_BOTS 4
+#define RP_PLAYBACK_BREATHER_TIME 2.0
+#define RP_MIN_CHEATER_REPLAY_LENGTH 30 // 30 seconds
+#define RP_MAX_CHEATER_REPLAY_LENGTH 120 // 2 minutes
+#define RP_MAX_BHOP_GROUND_TICKS 5
+#define RP_SKIP_TIME 10 // 10 seconds
+#define RP_MAX_DURATION 6451200 // 14 hours on 128 tick
+#define RP_JUMP_STEP_SOUND_THRESHOLD 140.0
+#define RP_PLAYER_ACCELSPEED 450.0
+
+#define RP_MOVETYPE_MASK (0xF)
+#define RP_IN_ATTACK (1 << 4)
+#define RP_IN_ATTACK2 (1 << 5)
+#define RP_IN_JUMP (1 << 6)
+#define RP_IN_DUCK (1 << 7)
+#define RP_IN_FORWARD (1 << 8)
+#define RP_IN_BACK (1 << 9)
+#define RP_IN_LEFT (1 << 10)
+#define RP_IN_RIGHT (1 << 11)
+#define RP_IN_MOVELEFT (1 << 12)
+#define RP_IN_MOVERIGHT (1 << 13)
+#define RP_IN_RELOAD (1 << 14)
+#define RP_IN_SPEED (1 << 15)
+#define RP_IN_USE (1 << 16)
+#define RP_IN_BULLRUSH (1 << 17)
+#define RP_FL_ONGROUND (1 << 18)
+#define RP_FL_DUCKING (1 << 19)
+#define RP_FL_SWIM (1 << 20)
+#define RP_UNDER_WATER (1 << 21)
+#define RP_TELEPORT_TICK (1 << 22)
+#define RP_TAKEOFF_TICK (1 << 23)
+#define RP_HIT_PERF (1 << 24)
+#define RP_SECONDARY_EQUIPPED (1 << 25)
+
+
+
+// =====[ FORWARDS ]=====
+
+/**
+ * Called when a replay of a player is written to disk.
+ * This includes replays of cheaters which are saved if
+ * the player is marked as a cheater by gokz-localdb.
+ *
+ * @param client The client ID of the player who completed the run.
+ * @param replayType The type of the replay (Run/Jump/Cheater).
+ * @param map The name of the map the run was completed on.
+ * @param course The specific course on the map the run was completed on.
+ * @param timeType The type of time (Pro/Nub).
+ * @param time The time the run was completed in.
+ * @param filePath Replay file path.
+ * @param tempReplay Whether the replay file should only be temporaily stored.
+ * @return Plugin_Handled to take over the temporary replay deletion, Plugin_Continue to allow temporary replay deletion by the replay plugin.
+ */
+forward Action GOKZ_RP_OnReplaySaved(int client, int replayType, const char[] map, int course, int timeType, float time, const char[] filePath, bool tempReplay);
+
+/**
+ * Called when a currently being recorded replay is discarded from
+ * memory and recording has been stopped (without writing it to disk).
+ *
+ * @param client Client index.
+ */
+forward void GOKZ_RP_OnReplayDiscarded(int client);
+
+/**
+ * Called when a player has ended their timer, and gokz-replays has
+ * processed the time and has possibly written a replay to disk.
+ *
+ * @param client Client index.
+ * @param filePath Replay file path, or "" if no replay saved.
+ * @param course Course number.
+ * @param time Player's end time.
+ * @param teleportsUsed Number of teleports used by player.
+ */
+forward void GOKZ_RP_OnTimerEnd_Post(int client, const char[] filePath, int course, float time, int teleportsUsed);
+
+
+
+// =====[ NATIVES ]====
+
+/**
+ * Called by the HUD to get the state of the current replay.
+ *
+ * @param client Client index.
+ * @param info Struct to pass the values into.
+ * @return If successful
+ */
+native int GOKZ_RP_GetPlaybackInfo(int client, any[] info);
+
+/**
+ * Called by the LocalDB to initiate a replay of a jump
+ *
+ * @param client Client index.
+ * @param path Path to the replay file.
+ * @return The client ID of the bot performing the replay.
+ */
+native int GOKZ_RP_LoadJumpReplay(int client, char[] path);
+
+/**
+ * Called by the HUD to show the replay control menu.
+ *
+ * @param client Client index.
+ */
+native bool GOKZ_RP_UpdateReplayControlMenu(int client);
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_replays =
+{
+ name = "gokz-replays",
+ file = "gokz-replays.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+};
+
+#if !defined REQUIRE_PLUGIN
+public void __pl_gokz_replays_SetNTVOptional()
+{
+ MarkNativeAsOptional("GOKZ_RP_GetPlaybackInfo");
+ MarkNativeAsOptional("GOKZ_RP_LoadJumpReplay");
+ MarkNativeAsOptional("GOKZ_RP_UpdateReplayControlMenu");
+}
+#endif
diff --git a/sourcemod/scripting/include/gokz/slayonend.inc b/sourcemod/scripting/include/gokz/slayonend.inc
new file mode 100644
index 0000000..2ed01e5
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/slayonend.inc
@@ -0,0 +1,43 @@
+/*
+ gokz-slayonend Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_slayonend_included_
+#endinput
+#endif
+#define _gokz_slayonend_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum
+{
+ SlayOnEnd_Disabled = 0,
+ SlayOnEnd_Enabled,
+ SLAYONEND_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define SLAYONEND_OPTION_NAME "GOKZ - Slay On End"
+#define SLAYONEND_OPTION_DESCRIPTION "Automatic Slaying Upon Ending Timer - 0 = Disabled, 1 = Enabled"
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_slayonend =
+{
+ name = "gokz-slayonend",
+ file = "gokz-slayonend.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+}; \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/tips.inc b/sourcemod/scripting/include/gokz/tips.inc
new file mode 100644
index 0000000..b5e2d3e
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/tips.inc
@@ -0,0 +1,59 @@
+/*
+ gokz-tips Plugin Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+*/
+
+#if defined _gokz_tips_included_
+#endinput
+#endif
+#define _gokz_tips_included_
+
+
+
+// =====[ ENUMS ]=====
+
+enum
+{
+ Tips_Disabled = 0,
+ Tips_Enabled,
+ TIPS_COUNT
+};
+
+
+
+// =====[ CONSTANTS ]=====
+
+#define TIPS_PLUGINS_COUNT 9
+#define TIPS_CORE "gokz-tips-core.phrases.txt"
+#define TIPS_TIPS "gokz-tips-tips.phrases.txt"
+#define TIPS_OPTION_NAME "GOKZ - Tips"
+#define TIPS_OPTION_DESCRIPTION "Random Tips Periodically in Chat - 0 = Disabled, 1 = Enabled"
+
+stock char gC_PluginsWithTips[TIPS_PLUGINS_COUNT][] =
+{
+ "goto",
+ "hud",
+ "jumpstats",
+ "localranks",
+ "measure",
+ "pistol",
+ "quiet",
+ "replays",
+ "spec"
+}
+
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_tips =
+{
+ name = "gokz-tips",
+ file = "gokz-tips.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+}; \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/tpanglefix.inc b/sourcemod/scripting/include/gokz/tpanglefix.inc
new file mode 100644
index 0000000..fc8faa2
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/tpanglefix.inc
@@ -0,0 +1,40 @@
+/*
+ gokz-tpanglefix Plugin Include
+
+ Website: https://github.com/KZGlobalTeam/gokz
+*/
+
+#if defined _gokz_tpanglefix_included_
+#endinput
+#endif
+#define _gokz_tpanglefix_included_
+
+
+// =====[ ENUMS ]=====
+
+enum
+{
+ TPAngleFix_Disabled = 0,
+ TPAngleFix_Enabled,
+ TPANGLEFIX_COUNT
+};
+
+
+// =====[ CONSTANTS ]=====
+
+#define TPANGLEFIX_OPTION_NAME "GOKZ - TPAngleFix"
+#define TPANGLEFIX_OPTION_DESCRIPTION "TPAngleFix - 0 = Disabled, 1 = Enabled"
+
+
+// =====[ DEPENDENCY ]=====
+
+public SharedPlugin __pl_gokz_tpanglefix =
+{
+ name = "gokz-tpanglefix",
+ file = "gokz-tpanglefix.smx",
+ #if defined REQUIRE_PLUGIN
+ required = 1,
+ #else
+ required = 0,
+ #endif
+}; \ No newline at end of file
diff --git a/sourcemod/scripting/include/gokz/version.inc b/sourcemod/scripting/include/gokz/version.inc
new file mode 100644
index 0000000..34cdb19
--- /dev/null
+++ b/sourcemod/scripting/include/gokz/version.inc
@@ -0,0 +1,12 @@
+/*
+ GOKZ Version Include
+
+ Website: https://bitbucket.org/kztimerglobalteam/gokz
+
+ You should not need to edit this file.
+ This file is overwritten in the build pipeline for versioning.
+*/
+
+
+
+#define GOKZ_VERSION "" \ No newline at end of file