diff options
Diffstat (limited to 'sourcemod/scripting/gokz-core')
22 files changed, 0 insertions, 7758 deletions
diff --git a/sourcemod/scripting/gokz-core/commands.sp b/sourcemod/scripting/gokz-core/commands.sp deleted file mode 100644 index 6aba82c..0000000 --- a/sourcemod/scripting/gokz-core/commands.sp +++ /dev/null @@ -1,385 +0,0 @@ -void RegisterCommands() -{ - RegConsoleCmd("sm_options", CommandOptions, "[KZ] Open the options menu."); - RegConsoleCmd("sm_o", CommandOptions, "[KZ] Open the options menu."); - RegConsoleCmd("sm_checkpoint", CommandMakeCheckpoint, "[KZ] Set a checkpoint."); - RegConsoleCmd("sm_gocheck", CommandTeleportToCheckpoint, "[KZ] Teleport to your current checkpoint."); - RegConsoleCmd("sm_prev", CommandPrevCheckpoint, "[KZ] Go back a checkpoint."); - RegConsoleCmd("sm_next", CommandNextCheckpoint, "[KZ] Go forward a checkpoint."); - RegConsoleCmd("sm_undo", CommandUndoTeleport, "[KZ] Undo teleport."); - RegConsoleCmd("sm_start", CommandTeleportToStart, "[KZ] Teleport to the start."); - RegConsoleCmd("sm_searchstart", CommandSearchStart, "[KZ] Teleport to the start zone/button of a specified course."); - RegConsoleCmd("sm_end", CommandTeleportToEnd, "[KZ] Teleport to the end."); - RegConsoleCmd("sm_restart", CommandTeleportToStart, "[KZ] Teleport to your start position."); - RegConsoleCmd("sm_r", CommandTeleportToStart, "[KZ] Teleport to your start position."); - RegConsoleCmd("sm_setstartpos", CommandSetStartPos, "[KZ] Set your custom start position to your current position."); - RegConsoleCmd("sm_ssp", CommandSetStartPos, "[KZ] Set your custom start position to your current position."); - RegConsoleCmd("sm_clearstartpos", CommandClearStartPos, "[KZ] Clear your custom start position."); - RegConsoleCmd("sm_csp", CommandClearStartPos, "[KZ] Clear your custom start position."); - RegConsoleCmd("sm_main", CommandMain, "[KZ] Teleport to the start of the main course."); - RegConsoleCmd("sm_m", CommandMain, "[KZ] Teleport to the start of the main course."); - RegConsoleCmd("sm_bonus", CommandBonus, "[KZ] Teleport to the start of a bonus. Usage: `!bonus <#bonus>"); - RegConsoleCmd("sm_b", CommandBonus, "[KZ] Teleport to the start of a bonus. Usage: `!b <#bonus>"); - RegConsoleCmd("sm_pause", CommandTogglePause, "[KZ] Toggle pausing your timer and stopping you in your position."); - RegConsoleCmd("sm_resume", CommandTogglePause, "[KZ] Toggle pausing your timer and stopping you in your position."); - RegConsoleCmd("sm_stop", CommandStopTimer, "[KZ] Stop your timer."); - RegConsoleCmd("sm_virtualbuttonindicators", CommandToggleVirtualButtonIndicators, "[KZ] Toggle virtual button indicators."); - RegConsoleCmd("sm_vbi", CommandToggleVirtualButtonIndicators, "[KZ] Toggle virtual button indicators."); - RegConsoleCmd("sm_virtualbuttons", CommandToggleVirtualButtonsLock, "[KZ] Toggle locking virtual buttons, preventing them from being moved."); - RegConsoleCmd("sm_vb", CommandToggleVirtualButtonsLock, "[KZ] Toggle locking virtual buttons, preventing them from being moved."); - RegConsoleCmd("sm_mode", CommandMode, "[KZ] Open the movement mode selection menu."); - RegConsoleCmd("sm_vanilla", CommandVanilla, "[KZ] Switch to the Vanilla mode."); - RegConsoleCmd("sm_vnl", CommandVanilla, "[KZ] Switch to the Vanilla mode."); - RegConsoleCmd("sm_v", CommandVanilla, "[KZ] Switch to the Vanilla mode."); - RegConsoleCmd("sm_simplekz", CommandSimpleKZ, "[KZ] Switch to the SimpleKZ mode."); - RegConsoleCmd("sm_skz", CommandSimpleKZ, "[KZ] Switch to the SimpleKZ mode."); - RegConsoleCmd("sm_s", CommandSimpleKZ, "[KZ] Switch to the SimpleKZ mode."); - RegConsoleCmd("sm_kztimer", CommandKZTimer, "[KZ] Switch to the KZTimer mode."); - RegConsoleCmd("sm_kzt", CommandKZTimer, "[KZ] Switch to the KZTimer mode."); - RegConsoleCmd("sm_k", CommandKZTimer, "[KZ] Switch to the KZTimer mode."); - RegConsoleCmd("sm_nc", CommandToggleNoclip, "[KZ] Toggle noclip."); - RegConsoleCmd("+noclip", CommandEnableNoclip, "[KZ] Noclip on."); - RegConsoleCmd("-noclip", CommandDisableNoclip, "[KZ] Noclip off."); - RegConsoleCmd("sm_ncnt", CommandToggleNoclipNotrigger, "[KZ] Toggle noclip-notrigger."); - RegConsoleCmd("+noclipnt", CommandEnableNoclipNotrigger, "[KZ] Noclip-notrigger on."); - RegConsoleCmd("-noclipnt", CommandDisableNoclipNotrigger, "[KZ] Noclip-notrigger off."); - RegConsoleCmd("sm_sg", CommandNubSafeGuard, "[KZ] Toggle NUB safeguard."); - RegConsoleCmd("sm_safe", CommandNubSafeGuard, "[KZ] Toggle NUB safeguard."); - RegConsoleCmd("sm_safeguard", CommandNubSafeGuard, "[KZ] Toggle NUB safeguard."); - RegConsoleCmd("sm_pro", CommandProSafeGuard, "[KZ] Toggle PRO safeguard."); - RegConsoleCmd("kill", CommandKill); - RegConsoleCmd("killvector", CommandKill); - RegConsoleCmd("explode", CommandKill); - RegConsoleCmd("explodevector", CommandKill); -} - -void AddCommandsListeners() -{ - AddCommandListener(CommandJoinTeam, "jointeam"); -} - -bool SwitchToModeIfAvailable(int client, int mode) -{ - if (!GOKZ_GetModeLoaded(mode)) - { - GOKZ_PrintToChat(client, true, "%t", "Mode Not Available", gC_ModeNames[mode]); - return false; - } - else - { - // Safeguard Check - if (GOKZ_GetCoreOption(client, Option_Safeguard) > Safeguard_Disabled && GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Safeguard - Blocked"); - GOKZ_PlayErrorSound(client); - return false; - } - GOKZ_SetCoreOption(client, Option_Mode, mode); - return true; - } -} - -public Action CommandKill(int client, int args) -{ - if (IsPlayerAlive(client) && GOKZ_GetCoreOption(client, Option_Safeguard) > Safeguard_Disabled && GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Safeguard - Blocked"); - GOKZ_PlayErrorSound(client); - return Plugin_Handled; - } - return Plugin_Continue; -} - -public Action CommandOptions(int client, int args) -{ - DisplayOptionsMenu(client); - return Plugin_Handled; -} - -public Action CommandJoinTeam(int client, const char[] command, int argc) -{ - char teamString[4]; - GetCmdArgString(teamString, sizeof(teamString)); - int team = StringToInt(teamString); - - if (team == CS_TEAM_SPECTATOR) - { - if (!GOKZ_GetPaused(client) && !GOKZ_GetCanPause(client)) - { - SendFakeTeamEvent(client); - return Plugin_Handled; - } - } - else if (IsPlayerAlive(client) && GOKZ_GetCoreOption(client, Option_Safeguard) > Safeguard_Disabled && GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Safeguard - Blocked"); - GOKZ_PlayErrorSound(client); - SendFakeTeamEvent(client); - return Plugin_Handled; - } - GOKZ_JoinTeam(client, team); - return Plugin_Handled; -} - -public Action CommandMakeCheckpoint(int client, int args) -{ - GOKZ_MakeCheckpoint(client); - return Plugin_Handled; -} - -public Action CommandTeleportToCheckpoint(int client, int args) -{ - GOKZ_TeleportToCheckpoint(client); - return Plugin_Handled; -} - -public Action CommandPrevCheckpoint(int client, int args) -{ - GOKZ_PrevCheckpoint(client); - return Plugin_Handled; -} - -public Action CommandNextCheckpoint(int client, int args) -{ - GOKZ_NextCheckpoint(client); - return Plugin_Handled; -} - -public Action CommandUndoTeleport(int client, int args) -{ - GOKZ_UndoTeleport(client); - return Plugin_Handled; -} - -public Action CommandTeleportToStart(int client, int args) -{ - GOKZ_TeleportToStart(client); - return Plugin_Handled; -} - -public Action CommandSearchStart(int client, int args) -{ - if (args == 0) - { - GOKZ_TeleportToSearchStart(client, GetCurrentCourse(client)); - return Plugin_Handled; - } - else - { - char argCourse[4]; - GetCmdArg(1, argCourse, sizeof(argCourse)); - int course = StringToInt(argCourse); - if (GOKZ_IsValidCourse(course, false)) - { - GOKZ_TeleportToSearchStart(client, course); - } - else if (StrEqual(argCourse, "main", false) || course == 0) - { - GOKZ_TeleportToSearchStart(client, 0); - } - else - { - GOKZ_PrintToChat(client, true, "%t", "Invalid Course Number", argCourse); - } - } - return Plugin_Handled; -} - -public Action CommandTeleportToEnd(int client, int args) -{ - if (args == 0) - { - GOKZ_TeleportToEnd(client, GetCurrentCourse(client)); - } - else - { - char argCourse[4]; - GetCmdArg(1, argCourse, sizeof(argCourse)); - int course = StringToInt(argCourse); - if (GOKZ_IsValidCourse(course, false)) - { - GOKZ_TeleportToEnd(client, course); - } - else if (StrEqual(argCourse, "main", false) || course == 0) - { - GOKZ_TeleportToEnd(client, 0); - } - else - { - GOKZ_PrintToChat(client, true, "%t", "Invalid Course Number", argCourse); - } - } - return Plugin_Handled; -} - -public Action CommandSetStartPos(int client, int args) -{ - SetStartPositionToCurrent(client, StartPositionType_Custom); - - GOKZ_PrintToChat(client, true, "%t", "Set Custom Start Position"); - if (GOKZ_GetCoreOption(client, Option_CheckpointSounds) == CheckpointSounds_Enabled) - { - GOKZ_EmitSoundToClient(client, GOKZ_SOUND_CHECKPOINT, _, "Set Start Position"); - } - - return Plugin_Handled; -} - -public Action CommandClearStartPos(int client, int args) -{ - if (ClearCustomStartPosition(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Cleared Custom Start Position"); - } - - return Plugin_Handled; -} - -public Action CommandMain(int client, int args) -{ - TeleportToCourseStart(client, 0); - return Plugin_Handled; -} - -public Action CommandBonus(int client, int args) -{ - if (args == 0) - { // Go to Bonus 1 - TeleportToCourseStart(client, 1); - } - else - { // Go to specified Bonus # - char argBonus[4]; - GetCmdArg(1, argBonus, sizeof(argBonus)); - int bonus = StringToInt(argBonus); - if (GOKZ_IsValidCourse(bonus, true)) - { - TeleportToCourseStart(client, bonus); - } - else - { - GOKZ_PrintToChat(client, true, "%t", "Invalid Bonus Number", argBonus); - } - } - return Plugin_Handled; -} - -public Action CommandTogglePause(int client, int args) -{ - if (!IsPlayerAlive(client)) - { - GOKZ_RespawnPlayer(client); - } - else - { - TogglePause(client); - } - return Plugin_Handled; -} - -public Action CommandStopTimer(int client, int args) -{ - if (TimerStop(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Timer Stopped"); - } - return Plugin_Handled; -} - -public Action CommandToggleVirtualButtonIndicators(int client, int args) -{ - if (GOKZ_GetCoreOption(client, Option_VirtualButtonIndicators) == VirtualButtonIndicators_Disabled) - { - GOKZ_SetCoreOption(client, Option_VirtualButtonIndicators, VirtualButtonIndicators_Enabled); - } - else - { - GOKZ_SetCoreOption(client, Option_VirtualButtonIndicators, VirtualButtonIndicators_Disabled); - } - return Plugin_Handled; -} - -public Action CommandToggleVirtualButtonsLock(int client, int args) -{ - if (ToggleVirtualButtonsLock(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Locked Virtual Buttons"); - } - else - { - GOKZ_PrintToChat(client, true, "%t", "Unlocked Virtual Buttons"); - } - return Plugin_Handled; -} - -public Action CommandMode(int client, int args) -{ - DisplayModeMenu(client); - return Plugin_Handled; -} - -public Action CommandVanilla(int client, int args) -{ - SwitchToModeIfAvailable(client, Mode_Vanilla); - return Plugin_Handled; -} - -public Action CommandSimpleKZ(int client, int args) -{ - SwitchToModeIfAvailable(client, Mode_SimpleKZ); - return Plugin_Handled; -} - -public Action CommandKZTimer(int client, int args) -{ - SwitchToModeIfAvailable(client, Mode_KZTimer); - return Plugin_Handled; -} - -public Action CommandToggleNoclip(int client, int args) -{ - ToggleNoclip(client); - return Plugin_Handled; -} - -public Action CommandEnableNoclip(int client, int args) -{ - EnableNoclip(client); - return Plugin_Handled; -} - -public Action CommandDisableNoclip(int client, int args) -{ - DisableNoclip(client); - return Plugin_Handled; -} - -public Action CommandToggleNoclipNotrigger(int client, int args) -{ - ToggleNoclipNotrigger(client); - return Plugin_Handled; -} - -public Action CommandEnableNoclipNotrigger(int client, int args) -{ - EnableNoclipNotrigger(client); - return Plugin_Handled; -} - -public Action CommandDisableNoclipNotrigger(int client, int args) -{ - DisableNoclipNotrigger(client); - return Plugin_Handled; -} - -public Action CommandNubSafeGuard(int client, int args) -{ - ToggleNubSafeGuard(client); - return Plugin_Handled; -} - -public Action CommandProSafeGuard(int client, int args) -{ - ToggleProSafeGuard(client); - return Plugin_Handled; -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/demofix.sp b/sourcemod/scripting/gokz-core/demofix.sp deleted file mode 100644 index 84a9307..0000000 --- a/sourcemod/scripting/gokz-core/demofix.sp +++ /dev/null @@ -1,110 +0,0 @@ -static ConVar CV_EnableDemofix; -static Handle H_DemofixTimer; -static bool mapRunning; - -void OnPluginStart_Demofix() -{ - AddCommandListener(Command_Demorestart, "demorestart"); - CV_EnableDemofix = AutoExecConfig_CreateConVar("gokz_demofix", "1", "Whether GOKZ applies demo record fix to server. (0 = Disabled, 1 = Update warmup period once, 2 = Regularly reset warmup period)", _, true, 0.0, true, 2.0); - CV_EnableDemofix.AddChangeHook(OnDemofixConVarChanged); - // If the map is tweaking the warmup value, we need to rerun the fix again. - FindConVar("mp_warmuptime").AddChangeHook(OnDemofixConVarChanged); - // We assume that the map is already loaded on late load. - if (gB_LateLoad) - { - mapRunning = true; - } -} - -void OnMapStart_Demofix() -{ - mapRunning = true; -} - -void OnMapEnd_Demofix() -{ - mapRunning = false; -} - -void OnRoundStart_Demofix() -{ - DoDemoFix(); -} - -public Action Command_Demorestart(int client, const char[] command, int argc) -{ - FixRecord(client); - return Plugin_Continue; -} - -static void FixRecord(int client) -{ - // For some reasons, demo playback speed is absolute trash without a round_start event. - // So whenever the client starts recording a demo, we create the event and send it to them. - Event e = CreateEvent("round_start", true); - int timelimit = FindConVar("mp_timelimit").IntValue; - e.SetInt("timelimit", timelimit); - e.SetInt("fraglimit", 0); - e.SetString("objective", "demofix"); - - e.FireToClient(client); - delete e; -} - -public void OnDemofixConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue) -{ - DoDemoFix(); -} - -public Action Timer_EnableDemoRecord(Handle timer) -{ - EnableDemoRecord(); - return Plugin_Continue; -} - -static void DoDemoFix() -{ - if (H_DemofixTimer != null) - { - delete H_DemofixTimer; - } - // Setting the cvar value to 1 can avoid clogging the demo file and slightly increase performance. - switch (CV_EnableDemofix.IntValue) - { - case 0: - { - if (!mapRunning) - { - return; - } - - GameRules_SetProp("m_bWarmupPeriod", 0); - } - case 1: - { - // Set warmup time to 2^31-1, effectively forever - if (FindConVar("mp_warmuptime").IntValue != 2147483647) - { - FindConVar("mp_warmuptime").SetInt(2147483647); - } - EnableDemoRecord(); - } - case 2: - { - H_DemofixTimer = CreateTimer(1.0, Timer_EnableDemoRecord, _, TIMER_REPEAT); - } - } -} - -static void EnableDemoRecord() -{ - // Enable warmup to allow demo recording - // m_fWarmupPeriodEnd is set in the past to hide the timer UI - if (!mapRunning) - { - return; - } - GameRules_SetProp("m_bWarmupPeriod", 1); - GameRules_SetPropFloat("m_fWarmupPeriodStart", GetGameTime() - 1.0); - GameRules_SetPropFloat("m_fWarmupPeriodEnd", GetGameTime() - 1.0); -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/forwards.sp b/sourcemod/scripting/gokz-core/forwards.sp deleted file mode 100644 index efb064f..0000000 --- a/sourcemod/scripting/gokz-core/forwards.sp +++ /dev/null @@ -1,401 +0,0 @@ -static GlobalForward H_OnOptionsLoaded; -static GlobalForward H_OnOptionChanged; -static GlobalForward H_OnTimerStart; -static GlobalForward H_OnTimerStart_Post; -static GlobalForward H_OnTimerEnd; -static GlobalForward H_OnTimerEnd_Post; -static GlobalForward H_OnTimerEndMessage; -static GlobalForward H_OnTimerStopped; -static GlobalForward H_OnPause; -static GlobalForward H_OnPause_Post; -static GlobalForward H_OnResume; -static GlobalForward H_OnResume_Post; -static GlobalForward H_OnMakeCheckpoint; -static GlobalForward H_OnMakeCheckpoint_Post; -static GlobalForward H_OnTeleportToCheckpoint; -static GlobalForward H_OnTeleportToCheckpoint_Post; -static GlobalForward H_OnTeleport; -static GlobalForward H_OnPrevCheckpoint; -static GlobalForward H_OnPrevCheckpoint_Post; -static GlobalForward H_OnNextCheckpoint; -static GlobalForward H_OnNextCheckpoint_Post; -static GlobalForward H_OnTeleportToStart; -static GlobalForward H_OnTeleportToStart_Post; -static GlobalForward H_OnTeleportToEnd; -static GlobalForward H_OnTeleportToEnd_Post; -static GlobalForward H_OnUndoTeleport; -static GlobalForward H_OnUndoTeleport_Post; -static GlobalForward H_OnCountedTeleport_Post; -static GlobalForward H_OnStartPositionSet_Post; -static GlobalForward H_OnJumpValidated; -static GlobalForward H_OnJumpInvalidated; -static GlobalForward H_OnJoinTeam; -static GlobalForward H_OnFirstSpawn; -static GlobalForward H_OnModeLoaded; -static GlobalForward H_OnModeUnloaded; -static GlobalForward H_OnTimerNativeCalledExternally; -static GlobalForward H_OnOptionsMenuCreated; -static GlobalForward H_OnOptionsMenuReady; -static GlobalForward H_OnCourseRegistered; -static GlobalForward H_OnRunInvalidated; -static GlobalForward H_OnEmitSoundToClient; - -void CreateGlobalForwards() -{ - H_OnOptionsLoaded = new GlobalForward("GOKZ_OnOptionsLoaded", ET_Ignore, Param_Cell); - H_OnOptionChanged = new GlobalForward("GOKZ_OnOptionChanged", ET_Ignore, Param_Cell, Param_String, Param_Cell); - H_OnTimerStart = new GlobalForward("GOKZ_OnTimerStart", ET_Hook, Param_Cell, Param_Cell); - H_OnTimerStart_Post = new GlobalForward("GOKZ_OnTimerStart_Post", ET_Ignore, Param_Cell, Param_Cell); - H_OnTimerEnd = new GlobalForward("GOKZ_OnTimerEnd", ET_Hook, Param_Cell, Param_Cell, Param_Float, Param_Cell); - H_OnTimerEnd_Post = new GlobalForward("GOKZ_OnTimerEnd_Post", ET_Ignore, Param_Cell, Param_Cell, Param_Float, Param_Cell); - H_OnTimerEndMessage = new GlobalForward("GOKZ_OnTimerEndMessage", ET_Hook, Param_Cell, Param_Cell, Param_Float, Param_Cell); - H_OnTimerStopped = new GlobalForward("GOKZ_OnTimerStopped", ET_Ignore, Param_Cell); - H_OnPause = new GlobalForward("GOKZ_OnPause", ET_Hook, Param_Cell); - H_OnPause_Post = new GlobalForward("GOKZ_OnPause_Post", ET_Ignore, Param_Cell); - H_OnResume = new GlobalForward("GOKZ_OnResume", ET_Hook, Param_Cell); - H_OnResume_Post = new GlobalForward("GOKZ_OnResume_Post", ET_Ignore, Param_Cell); - H_OnMakeCheckpoint = new GlobalForward("GOKZ_OnMakeCheckpoint", ET_Hook, Param_Cell); - H_OnMakeCheckpoint_Post = new GlobalForward("GOKZ_OnMakeCheckpoint_Post", ET_Ignore, Param_Cell); - H_OnTeleportToCheckpoint = new GlobalForward("GOKZ_OnTeleportToCheckpoint", ET_Hook, Param_Cell); - H_OnTeleportToCheckpoint_Post = new GlobalForward("GOKZ_OnTeleportToCheckpoint_Post", ET_Ignore, Param_Cell); - H_OnTeleport = new GlobalForward("GOKZ_OnTeleport", ET_Hook, Param_Cell); - H_OnPrevCheckpoint = new GlobalForward("GOKZ_OnPrevCheckpoint", ET_Hook, Param_Cell); - H_OnPrevCheckpoint_Post = new GlobalForward("GOKZ_OnPrevCheckpoint_Post", ET_Ignore, Param_Cell); - H_OnNextCheckpoint = new GlobalForward("GOKZ_OnNextCheckpoint", ET_Hook, Param_Cell); - H_OnNextCheckpoint_Post = new GlobalForward("GOKZ_OnNextCheckpoint_Post", ET_Ignore, Param_Cell); - H_OnTeleportToStart = new GlobalForward("GOKZ_OnTeleportToStart", ET_Hook, Param_Cell, Param_Cell); - H_OnTeleportToStart_Post = new GlobalForward("GOKZ_OnTeleportToStart_Post", ET_Ignore, Param_Cell, Param_Cell); - H_OnTeleportToEnd = new GlobalForward("GOKZ_OnTeleportToEnd", ET_Hook, Param_Cell, Param_Cell); - H_OnTeleportToEnd_Post = new GlobalForward("GOKZ_OnTeleportToEnd_Post", ET_Ignore, Param_Cell, Param_Cell); - H_OnUndoTeleport = new GlobalForward("GOKZ_OnUndoTeleport", ET_Hook, Param_Cell); - H_OnUndoTeleport_Post = new GlobalForward("GOKZ_OnUndoTeleport_Post", ET_Ignore, Param_Cell); - H_OnStartPositionSet_Post = new GlobalForward("GOKZ_OnStartPositionSet_Post", ET_Ignore, Param_Cell, Param_Cell, Param_Array, Param_Array); - H_OnCountedTeleport_Post = new GlobalForward("GOKZ_OnCountedTeleport_Post", ET_Ignore, Param_Cell); - H_OnJumpValidated = new GlobalForward("GOKZ_OnJumpValidated", ET_Ignore, Param_Cell, Param_Cell, Param_Cell, Param_Cell); - H_OnJumpInvalidated = new GlobalForward("GOKZ_OnJumpInvalidated", ET_Ignore, Param_Cell); - H_OnJoinTeam = new GlobalForward("GOKZ_OnJoinTeam", ET_Ignore, Param_Cell, Param_Cell); - H_OnFirstSpawn = new GlobalForward("GOKZ_OnFirstSpawn", ET_Ignore, Param_Cell); - H_OnModeLoaded = new GlobalForward("GOKZ_OnModeLoaded", ET_Ignore, Param_Cell); - H_OnModeUnloaded = new GlobalForward("GOKZ_OnModeUnloaded", ET_Ignore, Param_Cell); - H_OnTimerNativeCalledExternally = new GlobalForward("GOKZ_OnTimerNativeCalledExternally", ET_Event, Param_Cell, Param_Cell); - H_OnOptionsMenuCreated = new GlobalForward("GOKZ_OnOptionsMenuCreated", ET_Ignore, Param_Cell); - H_OnOptionsMenuReady = new GlobalForward("GOKZ_OnOptionsMenuReady", ET_Ignore, Param_Cell); - H_OnCourseRegistered = new GlobalForward("GOKZ_OnCourseRegistered", ET_Ignore, Param_Cell); - H_OnRunInvalidated = new GlobalForward("GOKZ_OnRunInvalidated", ET_Ignore, Param_Cell); - H_OnEmitSoundToClient = new GlobalForward("GOKZ_OnEmitSoundToClient", ET_Hook, Param_Cell, Param_String, Param_FloatByRef, Param_String); -} - -void Call_GOKZ_OnOptionsLoaded(int client) -{ - Call_StartForward(H_OnOptionsLoaded); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnOptionChanged(int client, const char[] option, int optionValue) -{ - Call_StartForward(H_OnOptionChanged); - Call_PushCell(client); - Call_PushString(option); - Call_PushCell(optionValue); - Call_Finish(); -} - -void Call_GOKZ_OnTimerStart(int client, int course, Action &result) -{ - Call_StartForward(H_OnTimerStart); - Call_PushCell(client); - Call_PushCell(course); - Call_Finish(result); -} - -void Call_GOKZ_OnTimerStart_Post(int client, int course) -{ - Call_StartForward(H_OnTimerStart_Post); - Call_PushCell(client); - Call_PushCell(course); - Call_Finish(); -} - -void Call_GOKZ_OnTimerEnd(int client, int course, float time, int teleportsUsed, Action &result) -{ - Call_StartForward(H_OnTimerEnd); - Call_PushCell(client); - Call_PushCell(course); - Call_PushFloat(time); - Call_PushCell(teleportsUsed); - Call_Finish(result); -} - -void Call_GOKZ_OnTimerEnd_Post(int client, int course, float time, int teleportsUsed) -{ - Call_StartForward(H_OnTimerEnd_Post); - Call_PushCell(client); - Call_PushCell(course); - Call_PushFloat(time); - Call_PushCell(teleportsUsed); - Call_Finish(); -} - -void Call_GOKZ_OnTimerEndMessage(int client, int course, float time, int teleportsUsed, Action &result) -{ - Call_StartForward(H_OnTimerEndMessage); - Call_PushCell(client); - Call_PushCell(course); - Call_PushFloat(time); - Call_PushCell(teleportsUsed); - Call_Finish(result); -} - -void Call_GOKZ_OnTimerStopped(int client) -{ - Call_StartForward(H_OnTimerStopped); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnPause(int client, Action &result) -{ - Call_StartForward(H_OnPause); - Call_PushCell(client); - Call_Finish(result); -} - -void Call_GOKZ_OnPause_Post(int client) -{ - Call_StartForward(H_OnPause_Post); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnResume(int client, Action &result) -{ - Call_StartForward(H_OnResume); - Call_PushCell(client); - Call_Finish(result); -} - -void Call_GOKZ_OnResume_Post(int client) -{ - Call_StartForward(H_OnResume_Post); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnMakeCheckpoint(int client, Action &result) -{ - Call_StartForward(H_OnMakeCheckpoint); - Call_PushCell(client); - Call_Finish(result); -} - -void Call_GOKZ_OnMakeCheckpoint_Post(int client) -{ - Call_StartForward(H_OnMakeCheckpoint_Post); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnTeleportToCheckpoint(int client, Action &result) -{ - Call_StartForward(H_OnTeleportToCheckpoint); - Call_PushCell(client); - Call_Finish(result); -} - -void Call_GOKZ_OnTeleportToCheckpoint_Post(int client) -{ - Call_StartForward(H_OnTeleportToCheckpoint_Post); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnTeleport(int client) -{ - Call_StartForward(H_OnTeleport); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnPrevCheckpoint(int client, Action &result) -{ - Call_StartForward(H_OnPrevCheckpoint); - Call_PushCell(client); - Call_Finish(result); -} - -void Call_GOKZ_OnPrevCheckpoint_Post(int client) -{ - Call_StartForward(H_OnPrevCheckpoint_Post); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnNextCheckpoint(int client, Action &result) -{ - Call_StartForward(H_OnNextCheckpoint); - Call_PushCell(client); - Call_Finish(result); -} - -void Call_GOKZ_OnNextCheckpoint_Post(int client) -{ - Call_StartForward(H_OnNextCheckpoint_Post); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnTeleportToStart(int client, int course, Action &result) -{ - Call_StartForward(H_OnTeleportToStart); - Call_PushCell(client); - Call_PushCell(course); - Call_Finish(result); -} - -void Call_GOKZ_OnTeleportToStart_Post(int client, int course) -{ - Call_StartForward(H_OnTeleportToStart_Post); - Call_PushCell(client); - Call_PushCell(course); - Call_Finish(); -} - -void Call_GOKZ_OnTeleportToEnd(int client, int course, Action &result) -{ - Call_StartForward(H_OnTeleportToEnd); - Call_PushCell(client); - Call_PushCell(course); - Call_Finish(result); -} - -void Call_GOKZ_OnTeleportToEnd_Post(int client, int course) -{ - Call_StartForward(H_OnTeleportToEnd_Post); - Call_PushCell(client); - Call_PushCell(course); - Call_Finish(); -} - -void Call_GOKZ_OnUndoTeleport(int client, Action &result) -{ - Call_StartForward(H_OnUndoTeleport); - Call_PushCell(client); - Call_Finish(result); -} - -void Call_GOKZ_OnUndoTeleport_Post(int client) -{ - Call_StartForward(H_OnUndoTeleport_Post); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnCountedTeleport_Post(int client) -{ - Call_StartForward(H_OnCountedTeleport_Post); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnStartPositionSet_Post(int client, StartPositionType type, const float origin[3], const float angles[3]) -{ - Call_StartForward(H_OnStartPositionSet_Post); - Call_PushCell(client); - Call_PushCell(type); - Call_PushArray(origin, 3); - Call_PushArray(angles, 3); - Call_Finish(); -} - -void Call_GOKZ_OnJumpValidated(int client, bool jumped, bool ladderJump, bool jumpbug) -{ - Call_StartForward(H_OnJumpValidated); - Call_PushCell(client); - Call_PushCell(jumped); - Call_PushCell(ladderJump); - Call_PushCell(jumpbug); - Call_Finish(); -} - -void Call_GOKZ_OnJumpInvalidated(int client) -{ - Call_StartForward(H_OnJumpInvalidated); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnJoinTeam(int client, int team) -{ - Call_StartForward(H_OnJoinTeam); - Call_PushCell(client); - Call_PushCell(team); - Call_Finish(); -} - -void Call_GOKZ_OnFirstSpawn(int client) -{ - Call_StartForward(H_OnFirstSpawn); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnModeLoaded(int mode) -{ - Call_StartForward(H_OnModeLoaded); - Call_PushCell(mode); - Call_Finish(); -} - -void Call_GOKZ_OnModeUnloaded(int mode) -{ - Call_StartForward(H_OnModeUnloaded); - Call_PushCell(mode); - Call_Finish(); -} - -void Call_GOKZ_OnTimerNativeCalledExternally(Handle plugin, int client, Action &result) -{ - Call_StartForward(H_OnTimerNativeCalledExternally); - Call_PushCell(plugin); - Call_PushCell(client); - Call_Finish(result); -} - -void Call_GOKZ_OnOptionsMenuCreated(TopMenu topMenu) -{ - Call_StartForward(H_OnOptionsMenuCreated); - Call_PushCell(topMenu); - Call_Finish(); -} - -void Call_GOKZ_OnOptionsMenuReady(TopMenu topMenu) -{ - Call_StartForward(H_OnOptionsMenuReady); - Call_PushCell(topMenu); - Call_Finish(); -} - -void Call_GOKZ_OnCourseRegistered(int course) -{ - Call_StartForward(H_OnCourseRegistered); - Call_PushCell(course); - Call_Finish(); -} - -void Call_GOKZ_OnRunInvalidated(int client) -{ - Call_StartForward(H_OnRunInvalidated); - Call_PushCell(client); - Call_Finish(); -} - -void Call_GOKZ_OnEmitSoundToClient(int client, const char[] sample, float &volume, const char[] description, Action &result) -{ - Call_StartForward(H_OnEmitSoundToClient); - Call_PushCell(client); - Call_PushString(sample); - Call_PushFloatRef(volume); - Call_PushString(description); - Call_Finish(result); -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/buttons.sp b/sourcemod/scripting/gokz-core/map/buttons.sp deleted file mode 100644 index 8923fbd..0000000 --- a/sourcemod/scripting/gokz-core/map/buttons.sp +++ /dev/null @@ -1,138 +0,0 @@ -/* - Hooks between specifically named func_buttons and GOKZ. -*/ - - - -static Regex RE_BonusStartButton; -static Regex RE_BonusEndButton; - - - -// =====[ EVENTS ]===== - -void OnPluginStart_MapButtons() -{ - RE_BonusStartButton = CompileRegex(GOKZ_BONUS_START_BUTTON_NAME_REGEX); - RE_BonusEndButton = CompileRegex(GOKZ_BONUS_END_BUTTON_NAME_REGEX); -} - -void OnEntitySpawned_MapButtons(int entity) -{ - char buffer[32]; - - GetEntityClassname(entity, buffer, sizeof(buffer)); - if (!StrEqual("func_button", buffer, false)) - { - return; - } - - if (GetEntityName(entity, buffer, sizeof(buffer)) == 0) - { - return; - } - - int course = 0; - if (StrEqual(GOKZ_START_BUTTON_NAME, buffer, false)) - { - HookSingleEntityOutput(entity, "OnPressed", OnStartButtonPress); - RegisterCourseStart(course); - } - else if (StrEqual(GOKZ_END_BUTTON_NAME, buffer, false)) - { - HookSingleEntityOutput(entity, "OnPressed", OnEndButtonPress); - RegisterCourseEnd(course); - } - else if ((course = GetStartButtonBonusNumber(entity)) != -1) - { - HookSingleEntityOutput(entity, "OnPressed", OnBonusStartButtonPress); - RegisterCourseStart(course); - } - else if ((course = GetEndButtonBonusNumber(entity)) != -1) - { - HookSingleEntityOutput(entity, "OnPressed", OnBonusEndButtonPress); - RegisterCourseEnd(course); - } -} - -public void OnStartButtonPress(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - ProcessStartButtonPress(activator, 0); -} - -public void OnEndButtonPress(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - ProcessEndButtonPress(activator, 0); -} - -public void OnBonusStartButtonPress(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - int course = GetStartButtonBonusNumber(caller); - if (!GOKZ_IsValidCourse(course, true)) - { - return; - } - - ProcessStartButtonPress(activator, course); -} - -public void OnBonusEndButtonPress(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - int course = GetEndButtonBonusNumber(caller); - if (!GOKZ_IsValidCourse(course, true)) - { - return; - } - - ProcessEndButtonPress(activator, course); -} - - - -// =====[ PRIVATE ]===== - -static void ProcessStartButtonPress(int client, int course) -{ - if (GOKZ_StartTimer(client, course)) - { - // Only calling on success is intended behaviour (and prevents virtual button exploits) - OnStartButtonPress_Teleports(client, course); - OnStartButtonPress_VirtualButtons(client, course); - } -} - -static void ProcessEndButtonPress(int client, int course) -{ - GOKZ_EndTimer(client, course); - OnEndButtonPress_VirtualButtons(client, course); -} - -static int GetStartButtonBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartButton, 1); -} - -static int GetEndButtonBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndButton, 1); -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/end.sp b/sourcemod/scripting/gokz-core/map/end.sp deleted file mode 100644 index d119084..0000000 --- a/sourcemod/scripting/gokz-core/map/end.sp +++ /dev/null @@ -1,155 +0,0 @@ -/* - Hooks between specifically named end destinations and GOKZ -*/ - - - -static Regex RE_BonusEndButton; -static Regex RE_BonusEndZone; -static CourseTimerType endType[GOKZ_MAX_COURSES]; -static float endOrigin[GOKZ_MAX_COURSES][3]; -static float endAngles[GOKZ_MAX_COURSES][3]; - - - -// =====[ EVENTS ]===== - -void OnPluginStart_MapEnd() -{ - RE_BonusEndButton = CompileRegex(GOKZ_BONUS_END_BUTTON_NAME_REGEX); - RE_BonusEndZone = CompileRegex(GOKZ_BONUS_END_ZONE_NAME_REGEX); -} - -void OnEntitySpawnedPost_MapEnd(int entity) -{ - char buffer[32]; - - GetEntityClassname(entity, buffer, sizeof(buffer)); - - if (StrEqual("trigger_multiple", buffer, false)) - { - bool isEndZone; - if (GetEntityName(entity, buffer, sizeof(buffer)) != 0) - { - if (StrEqual(GOKZ_END_ZONE_NAME, buffer, false)) - { - isEndZone = true; - StoreEnd(0, entity, CourseTimerType_ZoneNew); - } - else if (GetEndZoneBonusNumber(entity) != -1) - { - int course = GetEndZoneBonusNumber(entity); - if (GOKZ_IsValidCourse(course, true)) - { - isEndZone = true; - StoreEnd(course, entity, CourseTimerType_ZoneNew); - } - } - } - if (!isEndZone) - { - TimerButtonTrigger trigger; - if (IsTimerButtonTrigger(entity, trigger) && !trigger.isStartTimer) - { - StoreEnd(trigger.course, entity, CourseTimerType_ZoneLegacy); - } - } - } - else if (StrEqual("func_button", buffer, false)) - { - bool isEndButton; - if (GetEntityName(entity, buffer, sizeof(buffer)) != 0) - { - if (StrEqual(GOKZ_END_BUTTON_NAME, buffer, false)) - { - isEndButton = true; - StoreEnd(0, entity, CourseTimerType_Button); - } - else - { - int course = GetEndButtonBonusNumber(entity); - if (GOKZ_IsValidCourse(course, true)) - { - isEndButton = true; - StoreEnd(course, entity, CourseTimerType_Button); - } - } - } - if (!isEndButton) - { - TimerButtonTrigger trigger; - if (IsTimerButtonTrigger(entity, trigger) && !trigger.isStartTimer) - { - StoreEnd(trigger.course, entity, CourseTimerType_Button); - } - } - } -} - -void OnMapStart_MapEnd() -{ - for (int course = 0; course < GOKZ_MAX_COURSES; course++) - { - endType[course] = CourseTimerType_None; - } -} - -bool GetMapEndPosition(int course, float origin[3], float angles[3]) -{ - if (endType[course] == CourseTimerType_None) - { - return false; - } - - origin = endOrigin[course]; - angles = endAngles[course]; - - return true; -} - - - -// =====[ PRIVATE ]===== - -static void StoreEnd(int course, int entity, CourseTimerType type) -{ - // If StoreEnd is called, then there is at least an end position (even though it might not be a valid one) - if (endType[course] < CourseTimerType_Default) - { - endType[course] = CourseTimerType_Default; - } - - // Real zone is always better than "fake" zones which are better than buttons - // as the buttons found in a map with fake zones aren't meant to be visible. - if (endType[course] >= type) - { - return; - } - - float origin[3], distFromCenter[3]; - GetEntityPositions(entity, origin, endOrigin[course], endAngles[course], distFromCenter); - - // If it is a button or the center of the center of the zone is invalid - if (type == CourseTimerType_Button || !IsSpawnValid(endOrigin[course])) - { - // Attempt with various positions around the entity, pick the first valid one. - if (!FindValidPositionAroundTimerEntity(entity, endOrigin[course], endAngles[course], type == CourseTimerType_Button)) - { - endOrigin[course][2] -= 64.0; // Move the origin down so the eye position is directly on top of the button/zone. - return; - } - } - - // Only update the CourseTimerType if a valid position is found. - endType[course] = type; -} - -static int GetEndButtonBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndButton, 1); -} - -static int GetEndZoneBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndZone, 1); -} diff --git a/sourcemod/scripting/gokz-core/map/mapfile.sp b/sourcemod/scripting/gokz-core/map/mapfile.sp deleted file mode 100644 index db60e7e..0000000 --- a/sourcemod/scripting/gokz-core/map/mapfile.sp +++ /dev/null @@ -1,502 +0,0 @@ -/* - Mapping API - - Reads data from the current map file. -*/ - -static Regex RE_BonusStartButton; -static Regex RE_BonusEndButton; - -// NOTE: 4 megabyte array for entity lump reading. -static char gEntityLump[4194304]; - -// =====[ PUBLIC ]===== - -void EntlumpParse(StringMap antiBhopTriggers, StringMap teleportTriggers, StringMap timerButtonTriggers, int &mappingApiVersion) -{ - char mapPath[512]; - GetCurrentMap(mapPath, sizeof(mapPath)); - Format(mapPath, sizeof(mapPath), "maps/%s.bsp", mapPath); - - // https://developer.valvesoftware.com/wiki/Source_BSP_File_Format - - File file = OpenFile(mapPath, "rb"); - if (file != INVALID_HANDLE) - { - int identifier; - file.ReadInt32(identifier); - - if (identifier == GOKZ_BSP_HEADER_IDENTIFIER) - { - // skip version number - file.Seek(4, SEEK_CUR); - - // the entity lump info is the first lump in the array, so we don't need to seek any further. - int offset; - int length; - file.ReadInt32(offset); - file.ReadInt32(length); - - // jump to the start of the entity lump - file.Seek(offset, SEEK_SET); - - int charactersRead = file.ReadString(gEntityLump, sizeof(gEntityLump), length); - delete file; - if (charactersRead >= sizeof(gEntityLump) - 1) - { - PushMappingApiError("ERROR: Entity lump: The map's entity lump is too big! Reduce the amount of entities in your map."); - return; - } - gEntityLump[length] = '\0'; - - int index = 0; - - StringMap entity = new StringMap(); - bool gotWorldSpawn = false; - while (EntlumpParseEntity(entity, gEntityLump, index)) - { - char classname[128]; - char targetName[GOKZ_ENTLUMP_MAX_VALUE]; - entity.GetString("classname", classname, sizeof(classname)); - - if (!gotWorldSpawn && StrEqual("worldspawn", classname, false)) - { - gotWorldSpawn = true; - char versionString[32]; - if (entity.GetString("climb_mapping_api_version", versionString, sizeof(versionString))) - { - if (StringToIntEx(versionString, mappingApiVersion) == 0) - { - PushMappingApiError("ERROR: Entity lump: Couldn't parse Mapping API version from map properties: \"%s\".", versionString); - mappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE; - } - } - else - { - // map doesn't have a mapping api version. - mappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE; - } - } - else if (StrEqual("trigger_multiple", classname, false)) - { - TriggerType triggerType; - if (!gotWorldSpawn || mappingApiVersion != GOKZ_MAPPING_API_VERSION_NONE) - { - if (entity.GetString("targetname", targetName, sizeof(targetName))) - { - // get trigger properties if applicable - triggerType = GetTriggerType(targetName); - if (triggerType == TriggerType_Antibhop) - { - AntiBhopTrigger trigger; - if (GetAntiBhopTriggerEntityProperties(trigger, entity)) - { - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - antiBhopTriggers.SetArray(key, trigger, sizeof(trigger)); - } - } - else if (triggerType == TriggerType_Teleport) - { - TeleportTrigger trigger; - if (GetTeleportTriggerEntityProperties(trigger, entity)) - { - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - teleportTriggers.SetArray(key, trigger, sizeof(trigger)); - } - } - } - } - - // Tracking legacy timer triggers that press the timer buttons upon triggered. - if (triggerType == TriggerType_Invalid) - { - char touchOutput[128]; - ArrayList value; - - if (entity.GetString("OnStartTouch", touchOutput, sizeof(touchOutput))) - { - TimerButtonTriggerCheck(touchOutput, sizeof(touchOutput), entity, timerButtonTriggers); - } - else if (entity.GetValue("OnStartTouch", value)) // If there are multiple outputs, we have to check for all of them. - { - for (int i = 0; i < value.Length; i++) - { - value.GetString(i, touchOutput, sizeof(touchOutput)); - TimerButtonTriggerCheck(touchOutput, sizeof(touchOutput), entity, timerButtonTriggers); - } - } - } - } - else if (StrEqual("func_button", classname, false)) - { - char pressOutput[128]; - ArrayList value; - - if (entity.GetString("OnPressed", pressOutput, sizeof(pressOutput))) - { - TimerButtonTriggerCheck(pressOutput, sizeof(pressOutput), entity, timerButtonTriggers); - } - else if (entity.GetValue("OnPressed", value)) // If there are multiple outputs, we have to check for all of them. - { - for (int i = 0; i < value.Length; i++) - { - value.GetString(i, pressOutput, sizeof(pressOutput)); - TimerButtonTriggerCheck(pressOutput, sizeof(pressOutput), entity, timerButtonTriggers); - } - } - } - // clear for next loop - entity.Clear(); - } - delete entity; - } - delete file; - } - else - { - // TODO: do something more elegant - SetFailState("Catastrophic extreme hyperfailure! Mapping API Couldn't open the map file for reading! %s. The map file might be gone or another program is using it.", mapPath); - } -} - - -// =====[ EVENTS ]===== - -void OnPluginStart_MapFile() -{ - char buffer[64]; - char press[8]; - FormatEx(press, sizeof(press), "%s%s", CHAR_ESCAPE, "Press"); - - buffer = GOKZ_BONUS_START_BUTTON_NAME_REGEX; - ReplaceStringEx(buffer, sizeof(buffer), "$", ""); - StrCat(buffer, sizeof(buffer), press); - RE_BonusStartButton = CompileRegex(buffer); - - buffer = GOKZ_BONUS_END_BUTTON_NAME_REGEX; - ReplaceStringEx(buffer, sizeof(buffer), "$", ""); - StrCat(buffer, sizeof(buffer), press); - RE_BonusEndButton = CompileRegex(buffer); -} - - -// =====[ PRIVATE ]===== - -static void EntlumpSkipAllWhiteSpace(char[] entityLump, int &index) -{ - while (IsCharSpace(entityLump[index]) && entityLump[index] != '\0') - { - index++; - } -} - -static int EntlumpGetString(char[] result, int maxLength, int copyCount, char[] entityLump, int entlumpIndex) -{ - int finalLength; - for (int i = 0; i < maxLength - 1 && i < copyCount; i++) - { - if (entityLump[entlumpIndex + i] == '\0') - { - break; - } - result[i] = entityLump[entlumpIndex + i]; - finalLength++; - } - - result[finalLength] = '\0'; - return finalLength; -} - -static EntlumpToken EntlumpGetToken(char[] entityLump, int &entlumpIndex) -{ - EntlumpToken result; - - EntlumpSkipAllWhiteSpace(entityLump, entlumpIndex); - - switch (entityLump[entlumpIndex]) - { - case '{': - { - result.type = EntlumpTokenType_OpenBrace; - EntlumpGetString(result.string, sizeof(result.string), 1, entityLump, entlumpIndex); - entlumpIndex++; - } - case '}': - { - result.type = EntlumpTokenType_CloseBrace; - EntlumpGetString(result.string, sizeof(result.string), 1, entityLump, entlumpIndex); - entlumpIndex++; - } - case '\0': - { - result.type = EntlumpTokenType_EndOfStream; - EntlumpGetString(result.string, sizeof(result.string), 1, entityLump, entlumpIndex); - entlumpIndex++; - } - case '\"': - { - result.type = EntlumpTokenType_Identifier; - int identifierLen; - entlumpIndex++; - for (int i = 0; i < sizeof(result.string) - 1; i++) - { - // NOTE: Unterminated strings can probably never happen, since the map has to be - // loaded by the game first and the engine will fail the load before we get to it. - if (entityLump[entlumpIndex + i] == '\0') - { - result.type = EntlumpTokenType_Unknown; - break; - } - if (entityLump[entlumpIndex + i] == '\"') - { - break; - } - result.string[i] = entityLump[entlumpIndex + i]; - identifierLen++; - } - - entlumpIndex += identifierLen + 1; // +1 to skip over last quotation mark - result.string[identifierLen] = '\0'; - } - default: - { - result.type = EntlumpTokenType_Unknown; - result.string[0] = entityLump[entlumpIndex]; - result.string[1] = '\0'; - } - } - - return result; -} - -static bool EntlumpParseEntity(StringMap result, char[] entityLump, int &entlumpIndex) -{ - EntlumpToken token; - token = EntlumpGetToken(entityLump, entlumpIndex); - if (token.type == EntlumpTokenType_EndOfStream) - { - return false; - } - - // NOTE: The following errors will very very likely never happen, since the entity lump has to be - // loaded by the game first and the engine will fail the load before we get to it. - // But if there's an obscure bug in this code, then we'll know!!! - for (;;) - { - token = EntlumpGetToken(entityLump, entlumpIndex); - switch (token.type) - { - case EntlumpTokenType_OpenBrace: - { - continue; - } - case EntlumpTokenType_Identifier: - { - EntlumpToken valueToken; - valueToken = EntlumpGetToken(entityLump, entlumpIndex); - if (valueToken.type == EntlumpTokenType_Identifier) - { - char tempString[GOKZ_ENTLUMP_MAX_VALUE]; - ArrayList values; - if (result.GetString(token.string, tempString, sizeof(tempString))) - { - result.Remove(token.string); - values = new ArrayList(ByteCountToCells(GOKZ_ENTLUMP_MAX_VALUE)); - values.PushString(tempString); - values.PushString(valueToken.string); - result.SetValue(token.string, values); - } - else if (result.GetValue(token.string, values)) - { - values.PushString(valueToken.string); - } - else - { - result.SetString(token.string, valueToken.string); - } - } - else - { - PushMappingApiError("ERROR: Entity lump: Unexpected token \"%s\".", valueToken.string); - return false; - } - } - case EntlumpTokenType_CloseBrace: - { - break; - } - case EntlumpTokenType_EndOfStream: - { - PushMappingApiError("ERROR: Entity lump: Unexpected end of entity lump! Entity lump parsing failed."); - return false; - } - default: - { - PushMappingApiError("ERROR: Entity lump: Invalid token \"%s\". Entity lump parsing failed.", token.string); - return false; - } - } - } - - return true; -} - -static bool GetHammerIDFromEntityStringMap(int &result, StringMap entity) -{ - char hammerID[32]; - if (!entity.GetString("hammerid", hammerID, sizeof(hammerID)) - || StringToIntEx(hammerID, result) == 0) - { - // if we don't have the hammer id, then we can't match the entity to an existing one! - char origin[64]; - entity.GetString("origin", origin, sizeof(origin)); - PushMappingApiError("ERROR: Failed to parse \"hammerid\" keyvalue on trigger! \"%i\" origin: %s.", result, origin); - return false; - } - return true; -} - -static bool GetAntiBhopTriggerEntityProperties(AntiBhopTrigger result, StringMap entity) -{ - if (!GetHammerIDFromEntityStringMap(result.hammerID, entity)) - { - return false; - } - - char time[32]; - if (!entity.GetString("climb_anti_bhop_time", time, sizeof(time)) - || StringToFloatEx(time, result.time) == 0) - { - result.time = GOKZ_ANTI_BHOP_TRIGGER_DEFAULT_DELAY; - } - - return true; -} - -static bool GetTeleportTriggerEntityProperties(TeleportTrigger result, StringMap entity) -{ - if (!GetHammerIDFromEntityStringMap(result.hammerID, entity)) - { - return false; - } - - char buffer[64]; - if (!entity.GetString("climb_teleport_type", buffer, sizeof(buffer)) - || StringToIntEx(buffer, view_as<int>(result.type)) == 0) - { - result.type = GOKZ_TELEPORT_TRIGGER_DEFAULT_TYPE; - } - - if (!entity.GetString("climb_teleport_destination", result.tpDestination, sizeof(result.tpDestination))) - { - // We don't want triggers without destinations dangling about, so we need to tell everyone about it!!! - PushMappingApiError("ERROR: Could not find \"climb_teleport_destination\" keyvalue on a climb_teleport trigger! hammer id \"%i\".", - result.hammerID); - return false; - } - - if (!entity.GetString("climb_teleport_delay", buffer, sizeof(buffer)) - || StringToFloatEx(buffer, result.delay) == 0) - { - result.delay = GOKZ_TELEPORT_TRIGGER_DEFAULT_DELAY; - } - - if (!entity.GetString("climb_teleport_use_dest_angles", buffer, sizeof(buffer)) - || StringToIntEx(buffer, result.useDestAngles) == 0) - { - result.useDestAngles = GOKZ_TELEPORT_TRIGGER_DEFAULT_USE_DEST_ANGLES; - } - - if (!entity.GetString("climb_teleport_reset_speed", buffer, sizeof(buffer)) - || StringToIntEx(buffer, result.resetSpeed) == 0) - { - result.resetSpeed = GOKZ_TELEPORT_TRIGGER_DEFAULT_RESET_SPEED; - } - - if (!entity.GetString("climb_teleport_reorient_player", buffer, sizeof(buffer)) - || StringToIntEx(buffer, result.reorientPlayer) == 0) - { - result.reorientPlayer = GOKZ_TELEPORT_TRIGGER_DEFAULT_REORIENT_PLAYER; - } - - if (!entity.GetString("climb_teleport_relative", buffer, sizeof(buffer)) - || StringToIntEx(buffer, result.relativeDestination) == 0) - { - result.relativeDestination = GOKZ_TELEPORT_TRIGGER_DEFAULT_RELATIVE_DESTINATION; - } - - // NOTE: Clamping - if (IsBhopTrigger(result.type)) - { - result.delay = FloatMax(result.delay, GOKZ_TELEPORT_TRIGGER_BHOP_MIN_DELAY); - } - else - { - result.delay = FloatMax(result.delay, 0.0); - } - - return true; -} - -static void TimerButtonTriggerCheck(char[] touchOutput, int size, StringMap entity, StringMap timerButtonTriggers) -{ - int course = 0; - char startOutput[128]; - char endOutput[128]; - FormatEx(startOutput, sizeof(startOutput), "%s%s%s", GOKZ_START_BUTTON_NAME, CHAR_ESCAPE, "Press"); - FormatEx(endOutput, sizeof(endOutput), "%s%s%s", GOKZ_END_BUTTON_NAME, CHAR_ESCAPE, "Press"); - if (StrContains(touchOutput, startOutput, false) != -1) - { - TimerButtonTrigger trigger; - if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity)) - { - trigger.course = 0; - trigger.isStartTimer = true; - } - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - timerButtonTriggers.SetArray(key, trigger, sizeof(trigger)); - } - else if (StrContains(touchOutput, endOutput, false) != -1) - { - TimerButtonTrigger trigger; - if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity)) - { - trigger.course = 0; - trigger.isStartTimer = false; - } - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - timerButtonTriggers.SetArray(key, trigger, sizeof(trigger)); - } - else if (RE_BonusStartButton.Match(touchOutput) > 0) - { - RE_BonusStartButton.GetSubString(1, touchOutput, sizeof(size)); - course = StringToInt(touchOutput); - TimerButtonTrigger trigger; - if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity)) - { - trigger.course = course; - trigger.isStartTimer = true; - } - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - timerButtonTriggers.SetArray(key, trigger, sizeof(trigger)); - } - else if (RE_BonusEndButton.Match(touchOutput) > 0) - { - RE_BonusEndButton.GetSubString(1, touchOutput, sizeof(size)); - course = StringToInt(touchOutput); - TimerButtonTrigger trigger; - if (GetHammerIDFromEntityStringMap(trigger.hammerID, entity)) - { - trigger.course = course; - trigger.isStartTimer = false; - } - char key[32]; - IntToString(trigger.hammerID, key, sizeof(key)); - timerButtonTriggers.SetArray(key, trigger, sizeof(trigger)); - } -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/prefix.sp b/sourcemod/scripting/gokz-core/map/prefix.sp deleted file mode 100644 index 3ecbf89..0000000 --- a/sourcemod/scripting/gokz-core/map/prefix.sp +++ /dev/null @@ -1,48 +0,0 @@ -/* - Mapping API - Prefix - - Detects the map's prefix. -*/ - - - -static int currentMapPrefix; - - - -// =====[ PUBLIC ]===== - -int GetCurrentMapPrefix() -{ - return currentMapPrefix; -} - - - -// =====[ LISTENERS ]===== - -void OnMapStart_Prefix() -{ - char map[PLATFORM_MAX_PATH], mapPrefix[PLATFORM_MAX_PATH]; - GetCurrentMapDisplayName(map, sizeof(map)); - - // Get all characters before the first '_' character - for (int i = 0; i < sizeof(mapPrefix); i++) - { - if (map[i] == '\0' || map[i] == '_') - { - break; - } - - mapPrefix[i] = map[i]; - } - - if (StrEqual(mapPrefix[0], "kzpro", false)) - { - currentMapPrefix = MapPrefix_KZPro; - } - else - { - currentMapPrefix = MapPrefix_Other; - } -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/starts.sp b/sourcemod/scripting/gokz-core/map/starts.sp deleted file mode 100644 index 94d5b33..0000000 --- a/sourcemod/scripting/gokz-core/map/starts.sp +++ /dev/null @@ -1,219 +0,0 @@ -/* - Hooks between start destinations and GOKZ. -*/ - - - -static Regex RE_BonusStart; -static bool startExists[GOKZ_MAX_COURSES]; -static float startOrigin[GOKZ_MAX_COURSES][3]; -static float startAngles[GOKZ_MAX_COURSES][3]; - -// Used for SearchStart -static Regex RE_BonusStartButton; -static Regex RE_BonusStartZone; -static CourseTimerType startType[GOKZ_MAX_COURSES]; -static float searchStartOrigin[GOKZ_MAX_COURSES][3]; -static float searchStartAngles[GOKZ_MAX_COURSES][3]; - -// =====[ EVENTS ]===== - -void OnPluginStart_MapStarts() -{ - RE_BonusStart = CompileRegex(GOKZ_BONUS_START_NAME_REGEX); - RE_BonusStartButton = CompileRegex(GOKZ_BONUS_START_BUTTON_NAME_REGEX); - RE_BonusStartZone = CompileRegex(GOKZ_BONUS_START_ZONE_NAME_REGEX); -} - -void OnEntitySpawned_MapStarts(int entity) -{ - char buffer[32]; - - GetEntityClassname(entity, buffer, sizeof(buffer)); - if (!StrEqual("info_teleport_destination", buffer, false)) - { - return; - } - - if (GetEntityName(entity, buffer, sizeof(buffer)) == 0) - { - return; - } - - if (StrEqual(GOKZ_START_NAME, buffer, false)) - { - StoreStart(0, entity); - } - else - { - int course = GetStartBonusNumber(entity); - if (GOKZ_IsValidCourse(course, true)) - { - StoreStart(course, entity); - } - } -} - -void OnEntitySpawnedPost_MapStarts(int entity) -{ - char buffer[32]; - GetEntityClassname(entity, buffer, sizeof(buffer)); - - if (StrEqual("trigger_multiple", buffer, false)) - { - bool isStartZone; - if (GetEntityName(entity, buffer, sizeof(buffer)) != 0) - { - if (StrEqual(GOKZ_START_ZONE_NAME, buffer, false)) - { - isStartZone = true; - StoreSearchStart(0, entity, CourseTimerType_ZoneNew); - } - else if (GetStartZoneBonusNumber(entity) != -1) - { - int course = GetStartZoneBonusNumber(entity); - if (GOKZ_IsValidCourse(course, true)) - { - isStartZone = true; - StoreSearchStart(course, entity, CourseTimerType_ZoneNew); - } - } - } - if (!isStartZone) - { - TimerButtonTrigger trigger; - if (IsTimerButtonTrigger(entity, trigger) && trigger.isStartTimer) - { - StoreSearchStart(trigger.course, entity, CourseTimerType_ZoneLegacy); - } - } - - } - else if (StrEqual("func_button", buffer, false)) - { - bool isStartButton; - if (GetEntityName(entity, buffer, sizeof(buffer)) != 0) - { - if (StrEqual(GOKZ_START_BUTTON_NAME, buffer, false)) - { - isStartButton = true; - StoreSearchStart(0, entity, CourseTimerType_Button); - } - else - { - int course = GetStartButtonBonusNumber(entity); - if (GOKZ_IsValidCourse(course, true)) - { - isStartButton = true; - StoreSearchStart(course, entity, CourseTimerType_Button); - } - } - } - if (!isStartButton) - { - TimerButtonTrigger trigger; - if (IsTimerButtonTrigger(entity, trigger) && trigger.isStartTimer) - { - StoreSearchStart(trigger.course, entity, CourseTimerType_Button); - } - } - } -} - -void OnMapStart_MapStarts() -{ - for (int course = 0; course < GOKZ_MAX_COURSES; course++) - { - startExists[course] = false; - startType[course] = CourseTimerType_None; - } -} - -bool GetMapStartPosition(int course, float origin[3], float angles[3]) -{ - if (!startExists[course]) - { - return false; - } - - origin = startOrigin[course]; - angles = startAngles[course]; - - return true; -} - -bool GetSearchStartPosition(int course, float origin[3], float angles[3]) -{ - if (startType[course] == CourseTimerType_None) - { - return false; - } - - origin = searchStartOrigin[course]; - angles = searchStartAngles[course]; - - return true; -} - -// =====[ PRIVATE ]===== - -static void StoreStart(int course, int entity) -{ - float origin[3], angles[3]; - GetEntPropVector(entity, Prop_Send, "m_vecOrigin", origin); - GetEntPropVector(entity, Prop_Data, "m_angRotation", angles); - angles[2] = 0.0; // Roll should always be 0.0 - - startExists[course] = true; - startOrigin[course] = origin; - startAngles[course] = angles; -} - -static void StoreSearchStart(int course, int entity, CourseTimerType type) -{ - // If StoreSearchStart is called, then there is at least an end position (even though it might not be a valid one) - if (startType[course] < CourseTimerType_Default) - { - startType[course] = CourseTimerType_Default; - } - - // Real zone is always better than "fake" zones which are better than buttons - // as the buttons found in a map with fake zones aren't meant to be visible. - if (startType[course] >= type) - { - return; - } - - float origin[3], distFromCenter[3]; - GetEntityPositions(entity, origin, searchStartOrigin[course], searchStartAngles[course], distFromCenter); - - // If it is a button or the center of the center of the zone is invalid - if (type == CourseTimerType_Button || !IsSpawnValid(searchStartOrigin[course])) - { - // Attempt with various positions around the entity, pick the first valid one. - if (!FindValidPositionAroundTimerEntity(entity, searchStartOrigin[course], searchStartAngles[course], type == CourseTimerType_Button)) - { - searchStartOrigin[course][2] -= 64.0; // Move the origin down so the eye position is directly on top of the button/zone. - return; - } - } - - // Only update the CourseTimerType if a valid position is found. - startType[course] = type; -} - - -static int GetStartBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusStart, 1); -} - -static int GetStartButtonBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartButton, 1); -} - -static int GetStartZoneBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartZone, 1); -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/triggers.sp b/sourcemod/scripting/gokz-core/map/triggers.sp deleted file mode 100644 index 2444493..0000000 --- a/sourcemod/scripting/gokz-core/map/triggers.sp +++ /dev/null @@ -1,855 +0,0 @@ -/* - Mapping API - Triggers - - Implements trigger related features. -*/ - - - -static float lastTrigMultiTouchTime[MAXPLAYERS + 1]; -static float lastTrigTeleTouchTime[MAXPLAYERS + 1]; -static float lastTouchGroundOrLadderTime[MAXPLAYERS + 1]; -static int lastTouchSingleBhopEntRef[MAXPLAYERS + 1]; -static ArrayList lastTouchSequentialBhopEntRefs[MAXPLAYERS + 1]; -static int triggerTouchCount[MAXPLAYERS + 1]; -static int antiCpTriggerTouchCount[MAXPLAYERS + 1]; -static int antiPauseTriggerTouchCount[MAXPLAYERS + 1]; -static int antiJumpstatTriggerTouchCount[MAXPLAYERS + 1]; -static int mapMappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE; -static int bhopTouchCount[MAXPLAYERS + 1]; -static bool jumpedThisTick[MAXPLAYERS + 1]; -static float jumpOrigin[MAXPLAYERS + 1][3]; -static float jumpVelocity[MAXPLAYERS + 1][3]; -static ArrayList triggerTouchList[MAXPLAYERS + 1]; // arraylist of TouchedTrigger that the player is currently touching. this array won't ever get long (unless the mapper does something weird). -static StringMap triggerTouchCounts[MAXPLAYERS + 1]; // stringmap of int touch counts with key being a string of the entity reference. -static StringMap antiBhopTriggers; // stringmap of AntiBhopTrigger with key being a string of the m_iHammerID entprop. -static StringMap teleportTriggers; // stringmap of TeleportTrigger with key being a string of the m_iHammerID entprop. -static StringMap timerButtonTriggers; // stringmap of legacy timer zone triggers with key being a string of the m_iHammerID entprop. -static ArrayList parseErrorStrings; - - - -// =====[ PUBLIC ]===== - -bool BhopTriggersJustTouched(int client) -{ - // NOTE: This is slightly incorrect since we touch triggers in the air, but - // it doesn't matter since we can't checkpoint in the air. - if (bhopTouchCount[client] > 0) - { - return true; - } - // GetEngineTime return changes between calls. We only call it once at the beginning. - float engineTime = GetEngineTime(); - // If the player touches a teleport trigger, increase the delay required - if (engineTime - lastTouchGroundOrLadderTime[client] < GOKZ_MULT_NO_CHECKPOINT_TIME // Just touched ground or ladder - && engineTime - lastTrigMultiTouchTime[client] < GOKZ_MULT_NO_CHECKPOINT_TIME // Just touched trigger_multiple - || engineTime - lastTrigTeleTouchTime[client] < GOKZ_BHOP_NO_CHECKPOINT_TIME) // Just touched trigger_teleport - { - return true; - } - - return Movement_GetMovetype(client) == MOVETYPE_LADDER - && triggerTouchCount[client] > 0 - && engineTime - lastTrigTeleTouchTime[client] < GOKZ_LADDER_NO_CHECKPOINT_TIME; -} - -bool AntiCpTriggerIsTouched(int client) -{ - return antiCpTriggerTouchCount[client] > 0; -} - -bool AntiPauseTriggerIsTouched(int client) -{ - return antiPauseTriggerTouchCount[client] > 0; -} - -void PushMappingApiError(char[] format, any ...) -{ - char error[GOKZ_MAX_MAPTRIGGERS_ERROR_LENGTH]; - VFormat(error, sizeof(error), format, 2); - parseErrorStrings.PushString(error); -} - -TriggerType GetTriggerType(char[] targetName) -{ - TriggerType result = TriggerType_Invalid; - - if (StrEqual(targetName, GOKZ_ANTI_BHOP_TRIGGER_NAME)) - { - result = TriggerType_Antibhop; - } - else if (StrEqual(targetName, GOKZ_TELEPORT_TRIGGER_NAME)) - { - result = TriggerType_Teleport; - } - - return result; -} - -bool IsBhopTrigger(TeleportType type) -{ - return type == TeleportType_MultiBhop - || type == TeleportType_SingleBhop - || type == TeleportType_SequentialBhop; -} - -bool IsTimerButtonTrigger(int entity, TimerButtonTrigger trigger) -{ - char hammerID[32]; - bool gotHammerID = GetEntityHammerIDString(entity, hammerID, sizeof(hammerID)); - if (gotHammerID && timerButtonTriggers.GetArray(hammerID, trigger, sizeof(trigger))) - { - return true; - } - return false; -} - -// =====[ EVENTS ]===== - -void OnPluginStart_MapTriggers() -{ - parseErrorStrings = new ArrayList(ByteCountToCells(GOKZ_MAX_MAPTRIGGERS_ERROR_LENGTH)); - antiBhopTriggers = new StringMap(); - teleportTriggers = new StringMap(); - timerButtonTriggers = new StringMap(); -} - -void OnMapStart_MapTriggers() -{ - parseErrorStrings.Clear(); - antiBhopTriggers.Clear(); - teleportTriggers.Clear(); - timerButtonTriggers.Clear(); - mapMappingApiVersion = GOKZ_MAPPING_API_VERSION_NONE; - EntlumpParse(antiBhopTriggers, teleportTriggers, timerButtonTriggers, mapMappingApiVersion); - - if (mapMappingApiVersion > GOKZ_MAPPING_API_VERSION) - { - SetFailState("Map's mapping api version is too big! Maximum supported version is %i, but map has %i. If you're not on the latest GOKZ version, then update!", - GOKZ_MAPPING_API_VERSION, mapMappingApiVersion); - } -} - -void OnClientPutInServer_MapTriggers(int client) -{ - triggerTouchCount[client] = 0; - antiCpTriggerTouchCount[client] = 0; - antiPauseTriggerTouchCount[client] = 0; - antiJumpstatTriggerTouchCount[client] = 0; - - if (triggerTouchList[client] == null) - { - triggerTouchList[client] = new ArrayList(sizeof(TouchedTrigger)); - } - else - { - triggerTouchList[client].Clear(); - } - - if (triggerTouchCounts[client] == null) - { - triggerTouchCounts[client] = new StringMap(); - } - else - { - triggerTouchCounts[client].Clear(); - } - - bhopTouchCount[client] = 0; - - if (lastTouchSequentialBhopEntRefs[client] == null) - { - lastTouchSequentialBhopEntRefs[client] = new ArrayList(); - } - else - { - lastTouchSequentialBhopEntRefs[client].Clear(); - } -} - -void OnPlayerRunCmd_MapTriggers(int client, int &buttons) -{ - int flags = GetEntityFlags(client); - MoveType moveType = GetEntityMoveType(client); - - // if the player isn't touching any bhop triggers on ground/a ladder, then - // reset the singlebhop and sequential bhop state. - if ((flags & FL_ONGROUND || moveType == MOVETYPE_LADDER) - && bhopTouchCount[client] == 0) - { - ResetBhopState(client); - } - - if (antiJumpstatTriggerTouchCount[client] > 0) - { - if (GetFeatureStatus(FeatureType_Native, "GOKZ_JS_InvalidateJump") == FeatureStatus_Available) - { - GOKZ_JS_InvalidateJump(client); - } - } - - // Check if we're touching any triggers and act accordingly. - // NOTE: Read through the touch list in reverse order, so some - // trigger behaviours will be better. Trust me! - int triggerTouchListLength = triggerTouchList[client].Length; - for (int i = triggerTouchListLength - 1; i >= 0; i--) - { - TouchedTrigger touched; - triggerTouchList[client].GetArray(i, touched); - - if (touched.triggerType == TriggerType_Antibhop) - { - TouchAntibhopTrigger(client, touched, buttons, flags); - } - else if (touched.triggerType == TriggerType_Teleport) - { - // Sometimes due to lag or whatever, the player can be - // teleported twice by the same trigger. This fixes that. - if (TouchTeleportTrigger(client, touched, flags)) - { - RemoveTriggerFromTouchList(client, EntRefToEntIndex(touched.entRef)); - i--; - triggerTouchListLength--; - } - } - } - jumpedThisTick[client] = false; -} - -void OnPlayerSpawn_MapTriggers(int client) -{ - // Print trigger errors every time a player spawns so that - // mappers and testers can very easily spot mistakes in names - // and get them fixed asap. - if (parseErrorStrings.Length > 0) - { - char errStart[] = "ERROR: Errors detected when trying to load triggers!"; - CPrintToChat(client, "{red}%s", errStart); - PrintToConsole(client, "\n%s", errStart); - - int length = parseErrorStrings.Length; - for (int err = 0; err < length; err++) - { - char error[GOKZ_MAX_MAPTRIGGERS_ERROR_LENGTH]; - parseErrorStrings.GetString(err, error, sizeof(error)); - CPrintToChat(client, "{red}%s", error); - PrintToConsole(client, error); - } - CPrintToChat(client, "{red}If the errors get clipped off in the chat, then look in your developer console!\n"); - } -} - -public void OnPlayerJump_Triggers(int client) -{ - jumpedThisTick[client] = true; - GetClientAbsOrigin(client, jumpOrigin[client]); - Movement_GetVelocity(client, jumpVelocity[client]); -} - -void OnEntitySpawned_MapTriggers(int entity) -{ - char classname[32]; - GetEntityClassname(entity, classname, sizeof(classname)); - char name[64]; - GetEntityName(entity, name, sizeof(name)); - - bool triggerMultiple = StrEqual("trigger_multiple", classname); - if (triggerMultiple) - { - char hammerID[32]; - bool gotHammerID = GetEntityHammerIDString(entity, hammerID, sizeof(hammerID)); - - if (StrEqual(GOKZ_TELEPORT_TRIGGER_NAME, name)) - { - TeleportTrigger teleportTrigger; - if (gotHammerID && teleportTriggers.GetArray(hammerID, teleportTrigger, sizeof(teleportTrigger))) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnTeleportTrigTouchStart_MapTriggers); - HookSingleEntityOutput(entity, "OnEndTouch", OnTeleportTrigTouchEnd_MapTriggers); - } - else - { - PushMappingApiError("ERROR: Couldn't match teleport trigger's Hammer ID %s with any Hammer ID from the map.", hammerID); - } - } - else if (StrEqual(GOKZ_ANTI_BHOP_TRIGGER_NAME, name)) - { - AntiBhopTrigger antiBhopTrigger; - if (gotHammerID && antiBhopTriggers.GetArray(hammerID, antiBhopTrigger, sizeof(antiBhopTrigger))) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnAntiBhopTrigTouchStart_MapTriggers); - HookSingleEntityOutput(entity, "OnEndTouch", OnAntiBhopTrigTouchEnd_MapTriggers); - } - else - { - PushMappingApiError("ERROR: Couldn't match antibhop trigger's Hammer ID %s with any Hammer ID from the map.", hammerID); - } - } - else if (StrEqual(GOKZ_BHOP_RESET_TRIGGER_NAME, name)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnBhopResetTouchStart_MapTriggers); - } - else if (StrEqual(GOKZ_ANTI_CP_TRIGGER_NAME, name, false)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnAntiCpTrigTouchStart_MapTriggers); - HookSingleEntityOutput(entity, "OnEndTouch", OnAntiCpTrigTouchEnd_MapTriggers); - } - else if (StrEqual(GOKZ_ANTI_PAUSE_TRIGGER_NAME, name, false)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnAntiPauseTrigTouchStart_MapTriggers); - HookSingleEntityOutput(entity, "OnEndTouch", OnAntiPauseTrigTouchEnd_MapTriggers); - } - else if (StrEqual(GOKZ_ANTI_JUMPSTAT_TRIGGER_NAME, name, false)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnAntiJumpstatTrigTouchStart_MapTriggers); - HookSingleEntityOutput(entity, "OnEndTouch", OnAntiJumpstatTrigTouchEnd_MapTriggers); - } - else - { - // NOTE: SDKHook touch hooks bypass trigger filters. We want that only with - // non mapping api triggers because it prevents checkpointing on bhop blocks. - SDKHook(entity, SDKHook_StartTouchPost, OnTrigMultTouchStart_MapTriggers); - SDKHook(entity, SDKHook_EndTouchPost, OnTrigMultTouchEnd_MapTriggers); - } - } - else if (StrEqual("trigger_teleport", classname)) - { - SDKHook(entity, SDKHook_StartTouchPost, OnTrigTeleTouchStart_MapTriggers); - SDKHook(entity, SDKHook_EndTouchPost, OnTrigTeleTouchEnd_MapTriggers); - } -} - -public void OnAntiBhopTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - int touchCount = IncrementTriggerTouchCount(other, entity); - if (touchCount <= 0) - { - // The trigger has fired a matching endtouch output before - // the starttouch output, so ignore it. - return; - } - - if (jumpedThisTick[other]) - { - TeleportEntity(other, jumpOrigin[other], NULL_VECTOR, jumpVelocity[other]); - } - - AddTriggerToTouchList(other, entity, TriggerType_Antibhop); -} - -public void OnAntiBhopTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - DecrementTriggerTouchCount(other, entity); - RemoveTriggerFromTouchList(other, entity); -} - -public void OnTeleportTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - int touchCount = IncrementTriggerTouchCount(other, entity); - if (touchCount <= 0) - { - // The trigger has fired a matching endtouch output before - // the starttouch output, so ignore it. - return; - } - - char key[32]; - GetEntityHammerIDString(entity, key, sizeof(key)); - TeleportTrigger trigger; - if (teleportTriggers.GetArray(key, trigger, sizeof(trigger)) - && IsBhopTrigger(trigger.type)) - { - bhopTouchCount[other]++; - } - - AddTriggerToTouchList(other, entity, TriggerType_Teleport); -} - -public void OnTeleportTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - DecrementTriggerTouchCount(other, entity); - - char key[32]; - GetEntityHammerIDString(entity, key, sizeof(key)); - TeleportTrigger trigger; - if (teleportTriggers.GetArray(key, trigger, sizeof(trigger)) - && IsBhopTrigger(trigger.type)) - { - bhopTouchCount[other]--; - } - - RemoveTriggerFromTouchList(other, entity); -} - -public void OnBhopResetTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - ResetBhopState(other); -} - -public void OnAntiCpTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiCpTriggerTouchCount[other]++; -} - -public void OnAntiCpTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiCpTriggerTouchCount[other]--; -} - -public void OnAntiPauseTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiPauseTriggerTouchCount[other]++; -} - -public void OnAntiPauseTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiPauseTriggerTouchCount[other]--; -} - -public void OnAntiJumpstatTrigTouchStart_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiJumpstatTriggerTouchCount[other]++; -} - -public void OnAntiJumpstatTrigTouchEnd_MapTriggers(const char[] output, int entity, int other, float delay) -{ - if (!IsValidClient(other)) - { - return; - } - - antiJumpstatTriggerTouchCount[other]--; -} - -public void OnTrigMultTouchStart_MapTriggers(int entity, int other) -{ - if (!IsValidClient(other)) - { - return; - } - - lastTrigMultiTouchTime[other] = GetEngineTime(); - triggerTouchCount[other]++; -} - -public void OnTrigMultTouchEnd_MapTriggers(int entity, int other) -{ - if (!IsValidClient(other)) - { - return; - } - - triggerTouchCount[other]--; -} - -public void OnTrigTeleTouchStart_MapTriggers(int entity, int other) -{ - if (!IsValidClient(other)) - { - return; - } - - lastTrigTeleTouchTime[other] = GetEngineTime(); - triggerTouchCount[other]++; -} - -public void OnTrigTeleTouchEnd_MapTriggers(int entity, int other) -{ - if (!IsValidClient(other)) - { - return; - } - - triggerTouchCount[other]--; -} - -void OnStartTouchGround_MapTriggers(int client) -{ - lastTouchGroundOrLadderTime[client] = GetEngineTime(); - - for (int i = 0; i < triggerTouchList[client].Length; i++) - { - TouchedTrigger touched; - triggerTouchList[client].GetArray(i, touched); - // set the touched tick to the tick that the player touches the ground. - touched.groundTouchTick = gI_TickCount[client]; - triggerTouchList[client].SetArray(i, touched); - } -} - -void OnStopTouchGround_MapTriggers(int client) -{ - for (int i = 0; i < triggerTouchList[client].Length; i++) - { - TouchedTrigger touched; - triggerTouchList[client].GetArray(i, touched); - - if (touched.triggerType == TriggerType_Teleport) - { - char key[32]; - GetEntityHammerIDString(touched.entRef, key, sizeof(key)); - TeleportTrigger trigger; - // set last touched triggers for single and sequential bhop. - if (teleportTriggers.GetArray(key, trigger, sizeof(trigger)) - && IsBhopTrigger(trigger.type)) - { - if (trigger.type == TeleportType_SequentialBhop) - { - lastTouchSequentialBhopEntRefs[client].Push(touched.entRef); - } - // NOTE: For singlebhops, we don't care which type of bhop we last touched, because - // otherwise jumping back and forth between a multibhop and a singlebhop wouldn't work. - if (i == 0 && IsBhopTrigger(trigger.type)) - { - // We only want to set this once in this loop. - lastTouchSingleBhopEntRef[client] = touched.entRef; - } - } - } - } -} - -void OnChangeMovetype_MapTriggers(int client, MoveType newMovetype) -{ - if (newMovetype == MOVETYPE_LADDER) - { - lastTouchGroundOrLadderTime[client] = GetEngineTime(); - } -} - - - -// =====[ PRIVATE ]===== - -static void AddTriggerToTouchList(int client, int trigger, TriggerType triggerType) -{ - int triggerEntRef = EntIndexToEntRef(trigger); - - TouchedTrigger touched; - touched.triggerType = triggerType; - touched.entRef = triggerEntRef; - touched.startTouchTick = gI_TickCount[client]; - touched.groundTouchTick = -1; - if (GetEntityFlags(client) & FL_ONGROUND) - { - touched.groundTouchTick = gI_TickCount[client]; - } - - triggerTouchList[client].PushArray(touched); -} - -static void RemoveTriggerFromTouchList(int client, int trigger) -{ - int triggerEntRef = EntIndexToEntRef(trigger); - for (int i = 0; i < triggerTouchList[client].Length; i++) - { - TouchedTrigger touched; - triggerTouchList[client].GetArray(i, touched); - if (touched.entRef == triggerEntRef) - { - triggerTouchList[client].Erase(i); - break; - } - } -} - -static int IncrementTriggerTouchCount(int client, int trigger) -{ - int entref = EntIndexToEntRef(trigger); - char szEntref[64]; - FormatEx(szEntref, sizeof(szEntref), "%i", entref); - - int value = 0; - triggerTouchCounts[client].GetValue(szEntref, value); - - value += 1; - triggerTouchCounts[client].SetValue(szEntref, value); - - return value; -} - -static void DecrementTriggerTouchCount(int client, int trigger) -{ - int entref = EntIndexToEntRef(trigger); - char szEntref[64]; - FormatEx(szEntref, sizeof(szEntref), "%i", entref); - - int value = 0; - triggerTouchCounts[client].GetValue(szEntref, value); - - value -= 1; - triggerTouchCounts[client].SetValue(szEntref, value); -} - -static void TouchAntibhopTrigger(int client, TouchedTrigger touched, int &newButtons, int flags) -{ - if (!(flags & FL_ONGROUND)) - { - // Disable jump when the player is in the air. - // This is a very simple way to fix jumpbugging antibhop triggers. - newButtons &= ~IN_JUMP; - return; - } - - if (touched.groundTouchTick == -1) - { - // The player hasn't touched the ground inside this trigger yet. - return; - } - - char key[32]; - GetEntityHammerIDString(touched.entRef, key, sizeof(key)); - AntiBhopTrigger trigger; - if (antiBhopTriggers.GetArray(key, trigger, sizeof(trigger))) - { - float touchTime = CalculateGroundTouchTime(client, touched); - if (trigger.time == 0.0 || touchTime <= trigger.time) - { - // disable jump - newButtons &= ~IN_JUMP; - } - } -} - -static bool TouchTeleportTrigger(int client, TouchedTrigger touched, int flags) -{ - bool shouldTeleport = false; - - char key[32]; - GetEntityHammerIDString(touched.entRef, key, sizeof(key)); - TeleportTrigger trigger; - if (!teleportTriggers.GetArray(key, trigger, sizeof(trigger))) - { - // Couldn't get the teleport trigger from the trigger array for some reason. - return shouldTeleport; - } - - bool isBhopTrigger = IsBhopTrigger(trigger.type); - // NOTE: Player hasn't touched the ground inside this trigger yet. - if (touched.groundTouchTick == -1 && isBhopTrigger) - { - return shouldTeleport; - } - - float destOrigin[3]; - float destAngles[3]; - bool gotDestOrigin; - bool gotDestAngles; - int destinationEnt = GetTeleportDestinationAndOrientation(trigger.tpDestination, destOrigin, destAngles, gotDestOrigin, gotDestAngles); - - float triggerOrigin[3]; - bool gotTriggerOrigin = GetEntityAbsOrigin(touched.entRef, triggerOrigin); - - // NOTE: We only use the trigger's origin if we're using a relative destination, so if - // we're not using a relative destination and don't have it, then it's fine. - if (!IsValidEntity(destinationEnt) || !gotDestOrigin - || (!gotTriggerOrigin && trigger.relativeDestination)) - { - PrintToConsole(client, "[KZ] Invalid teleport destination \"%s\" on trigger with hammerID %i.", trigger.tpDestination, trigger.hammerID); - return shouldTeleport; - } - - // NOTE: Find out if we should actually teleport. - if (isBhopTrigger && (flags & FL_ONGROUND)) - { - float touchTime = CalculateGroundTouchTime(client, touched); - if (touchTime > trigger.delay) - { - shouldTeleport = true; - } - else if (trigger.type == TeleportType_SingleBhop) - { - shouldTeleport = lastTouchSingleBhopEntRef[client] == touched.entRef; - } - else if (trigger.type == TeleportType_SequentialBhop) - { - int length = lastTouchSequentialBhopEntRefs[client].Length; - for (int j = 0; j < length; j++) - { - int entRef = lastTouchSequentialBhopEntRefs[client].Get(j); - if (entRef == touched.entRef) - { - shouldTeleport = true; - break; - } - } - } - } - else if (trigger.type == TeleportType_Normal) - { - float touchTime = CalculateStartTouchTime(client, touched); - shouldTeleport = touchTime > trigger.delay || (trigger.delay == 0.0); - } - - if (!shouldTeleport) - { - return shouldTeleport; - } - - bool shouldReorientPlayer = trigger.reorientPlayer - && gotDestAngles && (destAngles[1] != 0.0); - - float zAxis[3]; - zAxis = view_as<float>({0.0, 0.0, 1.0}); - - // NOTE: Work out finalOrigin. - float finalOrigin[3]; - if (trigger.relativeDestination) - { - float playerOrigin[3]; - Movement_GetOrigin(client, playerOrigin); - - float playerOffsetFromTrigger[3]; - SubtractVectors(playerOrigin, triggerOrigin, playerOffsetFromTrigger); - - if (shouldReorientPlayer) - { - // NOTE: rotate player offset by the destination trigger's yaw. - RotateVectorAxis(playerOffsetFromTrigger, zAxis, DegToRad(destAngles[1]), playerOffsetFromTrigger); - } - - AddVectors(destOrigin, playerOffsetFromTrigger, finalOrigin); - } - else - { - finalOrigin = destOrigin; - } - - // NOTE: Work out finalPlayerAngles. - float finalPlayerAngles[3]; - Movement_GetEyeAngles(client, finalPlayerAngles); - if (shouldReorientPlayer) - { - finalPlayerAngles[1] -= destAngles[1]; - - float velocity[3]; - Movement_GetVelocity(client, velocity); - - // NOTE: rotate velocity by the destination trigger's yaw. - RotateVectorAxis(velocity, zAxis, DegToRad(destAngles[1]), velocity); - Movement_SetVelocity(client, velocity); - } - else if (!trigger.reorientPlayer && trigger.useDestAngles) - { - finalPlayerAngles = destAngles; - } - - if (shouldTeleport) - { - TeleportPlayer(client, finalOrigin, finalPlayerAngles, gotDestAngles && trigger.useDestAngles, trigger.resetSpeed); - } - - return shouldTeleport; -} - -static float CalculateGroundTouchTime(int client, TouchedTrigger touched) -{ - float result = float(gI_TickCount[client] - touched.groundTouchTick) * GetTickInterval(); - return result; -} - -static float CalculateStartTouchTime(int client, TouchedTrigger touched) -{ - float result = float(gI_TickCount[client] - touched.startTouchTick) * GetTickInterval(); - return result; -} - -static void ResetBhopState(int client) -{ - lastTouchSingleBhopEntRef[client] = INVALID_ENT_REFERENCE; - lastTouchSequentialBhopEntRefs[client].Clear(); -} - -static bool GetEntityHammerIDString(int entity, char[] buffer, int maxLength) -{ - if (!IsValidEntity(entity)) - { - return false; - } - - if (!HasEntProp(entity, Prop_Data, "m_iHammerID")) - { - return false; - } - - int hammerID = GetEntProp(entity, Prop_Data, "m_iHammerID"); - IntToString(hammerID, buffer, maxLength); - - return true; -} - -// NOTE: returns an entity reference (possibly invalid). -static int GetTeleportDestinationAndOrientation(char[] targetName, float origin[3], float angles[3] = NULL_VECTOR, bool &gotOrigin = false, bool &gotAngles = false) -{ - // NOTE: We're not caching the teleport destination because it could change. - int destination = GOKZFindEntityByName(targetName, .ignorePlayers = true); - if (!IsValidEntity(destination)) - { - return destination; - } - - gotOrigin = GetEntityAbsOrigin(destination, origin); - - if (HasEntProp(destination, Prop_Data, "m_angAbsRotation")) - { - GetEntPropVector(destination, Prop_Data, "m_angAbsRotation", angles); - gotAngles = true; - } - else - { - gotAngles = false; - } - - return destination; -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/map/zones.sp b/sourcemod/scripting/gokz-core/map/zones.sp deleted file mode 100644 index 684e42d..0000000 --- a/sourcemod/scripting/gokz-core/map/zones.sp +++ /dev/null @@ -1,183 +0,0 @@ -/* - Hooks between specifically named trigger_multiples and GOKZ. -*/ - - - -static Regex RE_BonusStartZone; -static Regex RE_BonusEndZone; -static bool touchedGroundSinceTouchingStartZone[MAXPLAYERS + 1]; - - - -// =====[ EVENTS ]===== - -void OnPluginStart_MapZones() -{ - RE_BonusStartZone = CompileRegex(GOKZ_BONUS_START_ZONE_NAME_REGEX); - RE_BonusEndZone = CompileRegex(GOKZ_BONUS_END_ZONE_NAME_REGEX); -} - -void OnStartTouchGround_MapZones(int client) -{ - touchedGroundSinceTouchingStartZone[client] = true; -} - -void OnEntitySpawned_MapZones(int entity) -{ - char buffer[32]; - - GetEntityClassname(entity, buffer, sizeof(buffer)); - if (!StrEqual("trigger_multiple", buffer, false)) - { - return; - } - - if (GetEntityName(entity, buffer, sizeof(buffer)) == 0) - { - return; - } - - int course = 0; - if (StrEqual(GOKZ_START_ZONE_NAME, buffer, false)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnStartZoneStartTouch); - HookSingleEntityOutput(entity, "OnEndTouch", OnStartZoneEndTouch); - RegisterCourseStart(course); - } - else if (StrEqual(GOKZ_END_ZONE_NAME, buffer, false)) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnEndZoneStartTouch); - RegisterCourseEnd(course); - } - else if ((course = GetStartZoneBonusNumber(entity)) != -1) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnBonusStartZoneStartTouch); - HookSingleEntityOutput(entity, "OnEndTouch", OnBonusStartZoneEndTouch); - RegisterCourseStart(course); - } - else if ((course = GetEndZoneBonusNumber(entity)) != -1) - { - HookSingleEntityOutput(entity, "OnStartTouch", OnBonusEndZoneStartTouch); - RegisterCourseEnd(course); - } -} - -public void OnStartZoneStartTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - ProcessStartZoneStartTouch(activator, 0); -} - -public void OnStartZoneEndTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - ProcessStartZoneEndTouch(activator, 0); -} - -public void OnEndZoneStartTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - ProcessEndZoneStartTouch(activator, 0); -} - -public void OnBonusStartZoneStartTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - int course = GetStartZoneBonusNumber(caller); - if (!GOKZ_IsValidCourse(course, true)) - { - return; - } - - ProcessStartZoneStartTouch(activator, course); -} - -public void OnBonusStartZoneEndTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - int course = GetStartZoneBonusNumber(caller); - if (!GOKZ_IsValidCourse(course, true)) - { - return; - } - - ProcessStartZoneEndTouch(activator, course); -} - -public void OnBonusEndZoneStartTouch(const char[] name, int caller, int activator, float delay) -{ - if (!IsValidEntity(caller) || !IsValidClient(activator)) - { - return; - } - - int course = GetEndZoneBonusNumber(caller); - if (!GOKZ_IsValidCourse(course, true)) - { - return; - } - - ProcessEndZoneStartTouch(activator, course); -} - - - -// =====[ PRIVATE ]===== - -static void ProcessStartZoneStartTouch(int client, int course) -{ - touchedGroundSinceTouchingStartZone[client] = Movement_GetOnGround(client); - - GOKZ_StopTimer(client, false); - SetCurrentCourse(client, course); - - OnStartZoneStartTouch_Teleports(client, course); -} - -static void ProcessStartZoneEndTouch(int client, int course) -{ - if (!touchedGroundSinceTouchingStartZone[client]) - { - return; - } - - GOKZ_StartTimer(client, course, true); - GOKZ_ResetVirtualButtonPosition(client, true); -} - -static void ProcessEndZoneStartTouch(int client, int course) -{ - GOKZ_EndTimer(client, course); - GOKZ_ResetVirtualButtonPosition(client, false); -} - -static int GetStartZoneBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusStartZone, 1); -} - -static int GetEndZoneBonusNumber(int entity) -{ - return GOKZ_MatchIntFromEntityName(entity, RE_BonusEndZone, 1); -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/menus/mode_menu.sp b/sourcemod/scripting/gokz-core/menus/mode_menu.sp deleted file mode 100644 index 934d29c..0000000 --- a/sourcemod/scripting/gokz-core/menus/mode_menu.sp +++ /dev/null @@ -1,40 +0,0 @@ -/* - Lets players choose their mode. -*/ - - - -// =====[ PUBLIC ]===== - -void DisplayModeMenu(int client) -{ - Menu menu = new Menu(MenuHandler_Mode); - menu.SetTitle("%T", "Mode Menu - Title", client); - GOKZ_MenuAddModeItems(client, menu, true); - menu.Display(client, MENU_TIME_FOREVER); -} - - - -// =====[ EVENTS ]===== - -public int MenuHandler_Mode(Menu menu, MenuAction action, int param1, int param2) -{ - if (action == MenuAction_Select) - { - GOKZ_SetCoreOption(param1, Option_Mode, param2); - if (GetCameFromOptionsMenu(param1)) - { - DisplayOptionsMenu(param1, TopMenuPosition_LastCategory); - } - } - else if (action == MenuAction_Cancel && GetCameFromOptionsMenu(param1)) - { - DisplayOptionsMenu(param1, TopMenuPosition_LastCategory); - } - else if (action == MenuAction_End) - { - delete menu; - } - return 0; -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/menus/options_menu.sp b/sourcemod/scripting/gokz-core/menus/options_menu.sp deleted file mode 100644 index 240ee81..0000000 --- a/sourcemod/scripting/gokz-core/menus/options_menu.sp +++ /dev/null @@ -1,174 +0,0 @@ -/* - TopMenu that allows users to browse categories of options. - - Adds core options to the general category where players - can cycle the value of each core option. -*/ - - - -static TopMenu optionsMenu; -static TopMenuObject catGeneral; -static TopMenuObject itemsGeneral[OPTION_COUNT]; -static bool cameFromOptionsMenu[MAXPLAYERS + 1]; - - - -// =====[ PUBLIC ]===== - -void DisplayOptionsMenu(int client, TopMenuPosition position = TopMenuPosition_Start) -{ - optionsMenu.Display(client, position); - cameFromOptionsMenu[client] = false; -} - -TopMenu GetOptionsTopMenu() -{ - return optionsMenu; -} - -bool GetCameFromOptionsMenu(int client) -{ - return cameFromOptionsMenu[client]; -} - - - -// =====[ LISTENERS ]===== - -void OnAllPluginsLoaded_OptionsMenu() -{ - optionsMenu = new TopMenu(TopMenuHandler_Options); - Call_GOKZ_OnOptionsMenuCreated(optionsMenu); - Call_GOKZ_OnOptionsMenuReady(optionsMenu); -} - -void OnConfigsExecuted_OptionsMenu() -{ - SortOptionsMenu(); -} - -void OnOptionsMenuCreated_OptionsMenu() -{ - catGeneral = optionsMenu.AddCategory(GENERAL_OPTION_CATEGORY, TopMenuHandler_Options); -} - -void OnOptionsMenuReady_OptionsMenu() -{ - for (int option = 0; option < view_as<int>(OPTION_COUNT); option++) - { - if (option == view_as<int>(Option_Style)) - { - continue; // TODO Currently hard-coded to skip style - } - itemsGeneral[option] = optionsMenu.AddItem(gC_CoreOptionNames[option], TopMenuHandler_General, catGeneral); - } -} - - - -// =====[ HANDLER ]===== - -public void TopMenuHandler_Options(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength) -{ - if (action == TopMenuAction_DisplayOption || action == TopMenuAction_DisplayTitle) - { - if (topobj_id == INVALID_TOPMENUOBJECT) - { - Format(buffer, maxlength, "%T", "Options Menu - Title", param); - } - else if (topobj_id == catGeneral) - { - Format(buffer, maxlength, "%T", "Options Menu - General", param); - } - } -} - -public void TopMenuHandler_General(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength) -{ - Option option = OPTION_INVALID; - for (int i = 0; i < view_as<int>(OPTION_COUNT); i++) - { - if (topobj_id == itemsGeneral[i]) - { - option = view_as<Option>(i); - break; - } - } - - if (option == OPTION_INVALID) - { - return; - } - - if (action == TopMenuAction_DisplayOption) - { - switch (option) - { - case Option_Mode: - { - FormatEx(buffer, maxlength, "%T - %s", - gC_CoreOptionPhrases[option], param, - gC_ModeNames[GOKZ_GetCoreOption(param, option)]); - } - case Option_TimerButtonZoneType: - { - FormatEx(buffer, maxlength, "%T - %T", - gC_CoreOptionPhrases[option], param, - gC_TimerButtonZoneTypePhrases[GOKZ_GetCoreOption(param, option)], param); - } - case Option_Safeguard: - { - FormatEx(buffer, maxlength, "%T - %T", - gC_CoreOptionPhrases[option], param, - gC_SafeGuardPhrases[GOKZ_GetCoreOption(param, option)], param); - } - default:FormatToggleableOptionDisplay(param, option, buffer, maxlength); - } - } - else if (action == TopMenuAction_SelectOption) - { - switch (option) - { - case Option_Mode: - { - cameFromOptionsMenu[param] = true; - DisplayModeMenu(param); - } - default: - { - GOKZ_CycleCoreOption(param, option); - optionsMenu.Display(param, TopMenuPosition_LastCategory); - } - } - } -} - - - -// =====[ PRIVATE ]===== - -static void SortOptionsMenu() -{ - char error[256]; - if (!optionsMenu.LoadConfig(GOKZ_CFG_OPTIONS_SORTING, error, sizeof(error))) - { - LogError("Failed to load file: \"%s\". Error: %s", GOKZ_CFG_OPTIONS_SORTING, error); - } -} - -static void FormatToggleableOptionDisplay(int client, Option option, char[] buffer, int maxlength) -{ - if (GOKZ_GetCoreOption(client, option) == 0) - { - FormatEx(buffer, maxlength, "%T - %T", - gC_CoreOptionPhrases[option], client, - "Options Menu - Disabled", client); - } - else - { - FormatEx(buffer, maxlength, "%T - %T", - gC_CoreOptionPhrases[option], client, - "Options Menu - Enabled", client); - } -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/misc.sp b/sourcemod/scripting/gokz-core/misc.sp deleted file mode 100644 index a117880..0000000 --- a/sourcemod/scripting/gokz-core/misc.sp +++ /dev/null @@ -1,803 +0,0 @@ -/* - Small features that aren't worth splitting into their own file. -*/ - - - -// =====[ GOKZ.CFG ]===== - -void OnMapStart_KZConfig() -{ - char gokzCfgFullPath[PLATFORM_MAX_PATH]; - FormatEx(gokzCfgFullPath, sizeof(gokzCfgFullPath), "cfg/%s", GOKZ_CFG_SERVER); - - if (FileExists(gokzCfgFullPath)) - { - ServerCommand("exec %s", GOKZ_CFG_SERVER); - } - else - { - SetFailState("Failed to load file: \"%s\". Check that it exists.", gokzCfgFullPath); - } -} - - - -// =====[ GODMODE ]===== - -void OnPlayerSpawn_GodMode(int client) -{ - // Stop players from taking damage - SetEntProp(client, Prop_Data, "m_takedamage", 0); - SetEntityFlags(client, GetEntityFlags(client) | FL_GODMODE); -} - - - -// =====[ NOCLIP ]===== - -int noclipReleaseTime[MAXPLAYERS + 1]; - -void ToggleNoclip(int client) -{ - if (Movement_GetMovetype(client) != MOVETYPE_NOCLIP) - { - EnableNoclip(client); - } - else - { - DisableNoclip(client); - } -} - -void EnableNoclip(int client) -{ - if (IsValidClient(client) && IsPlayerAlive(client)) - { - if (GOKZ_GetCoreOption(client, Option_Safeguard) > Safeguard_Disabled && GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Safeguard - Blocked"); - GOKZ_PlayErrorSound(client); - return; - } - Movement_SetMovetype(client, MOVETYPE_NOCLIP); - GOKZ_StopTimer(client); - } -} - -void DisableNoclip(int client) -{ - if (IsValidClient(client) && IsPlayerAlive(client) && Movement_GetMovetype(client) == MOVETYPE_NOCLIP) - { - noclipReleaseTime[client] = GetGameTickCount(); - Movement_SetMovetype(client, MOVETYPE_WALK); - SetEntProp(client, Prop_Send, "m_CollisionGroup", GOKZ_COLLISION_GROUP_STANDARD); - - // Prevents an exploit that would let you noclip out of start zones - RemoveNoclipGroundFlag(client); - } -} - -void ToggleNoclipNotrigger(int client) -{ - if (Movement_GetMovetype(client) != MOVETYPE_NOCLIP) - { - EnableNoclipNotrigger(client); - } - else - { - DisableNoclipNotrigger(client); - } -} - -void EnableNoclipNotrigger(int client) -{ - if (IsValidClient(client) && IsPlayerAlive(client)) - { - if (GOKZ_GetCoreOption(client, Option_Safeguard) > Safeguard_Disabled && GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Safeguard - Blocked"); - GOKZ_PlayErrorSound(client); - return; - } - Movement_SetMovetype(client, MOVETYPE_NOCLIP); - SetEntProp(client, Prop_Send, "m_CollisionGroup", GOKZ_COLLISION_GROUP_NOTRIGGER); - GOKZ_StopTimer(client); - } -} - -void DisableNoclipNotrigger(int client) -{ - if (IsValidClient(client) && IsPlayerAlive(client) && Movement_GetMovetype(client) == MOVETYPE_NOCLIP) - { - noclipReleaseTime[client] = GetGameTickCount(); - Movement_SetMovetype(client, MOVETYPE_WALK); - SetEntProp(client, Prop_Send, "m_CollisionGroup", GOKZ_COLLISION_GROUP_STANDARD); - - // Prevents an exploit that would let you noclip out of start zones - RemoveNoclipGroundFlag(client); - } -} - -void RemoveNoclipGroundFlag(int client) -{ - float startPosition[3], endPosition[3]; - GetClientAbsOrigin(client, startPosition); - endPosition = startPosition; - endPosition[2] = startPosition[2] - 2.0; - Handle trace = TR_TraceHullFilterEx( - startPosition, - endPosition, - view_as<float>( { -16.0, -16.0, 0.0 } ), - view_as<float>( { 16.0, 16.0, 72.0 } ), - MASK_PLAYERSOLID, - TraceEntityFilterPlayers, - client); - - if (!TR_DidHit(trace)) - { - SetEntityFlags(client, GetEntityFlags(client) & ~FL_ONGROUND); - } - delete trace; -} - -bool JustNoclipped(int client) -{ - return GetGameTickCount() - noclipReleaseTime[client] <= GOKZ_TIMER_START_NOCLIP_TICKS; -} - -void OnClientPutInServer_Noclip(int client) -{ - noclipReleaseTime[client] = 0; -} - -// =====[ TURNBINDS ]===== - -static int turnbindsLastLeftStart[MAXPLAYERS + 1]; -static int turnbindsLastRightStart[MAXPLAYERS + 1]; -static float turnbindsLastValidYaw[MAXPLAYERS + 1]; -static int turnbindsOldButtons[MAXPLAYERS + 1]; - -void OnClientPutInServer_Turnbinds(int client) -{ - turnbindsLastLeftStart[client] = 0; - turnbindsLastRightStart[client] = 0; -} -// Ensures that there is a minimum time between starting to turnbind in one direction -// and then starting to turnbind in the other direction -void OnPlayerRunCmd_Turnbinds(int client, int buttons, int tickcount, float angles[3]) -{ - if (IsFakeClient(client)) - { - return; - } - if (buttons & IN_LEFT && tickcount < turnbindsLastRightStart[client] + RoundToNearest(GOKZ_TURNBIND_COOLDOWN / GetTickInterval())) - { - angles[1] = turnbindsLastValidYaw[client]; - TeleportEntity(client, NULL_VECTOR, angles, NULL_VECTOR); - buttons = 0; - } - else if (buttons & IN_RIGHT && tickcount < turnbindsLastLeftStart[client] + RoundToNearest(GOKZ_TURNBIND_COOLDOWN / GetTickInterval())) - { - angles[1] = turnbindsLastValidYaw[client]; - TeleportEntity(client, NULL_VECTOR, angles, NULL_VECTOR); - buttons = 0; - } - else - { - turnbindsLastValidYaw[client] = angles[1]; - - if (!(turnbindsOldButtons[client] & IN_LEFT) && (buttons & IN_LEFT)) - { - turnbindsLastLeftStart[client] = tickcount; - } - - if (!(turnbindsOldButtons[client] & IN_RIGHT) && (buttons & IN_RIGHT)) - { - turnbindsLastRightStart[client] = tickcount; - } - - turnbindsOldButtons[client] = buttons; - } -} - - - -// =====[ PLAYER COLLISION ]===== - -void OnPlayerSpawn_PlayerCollision(int client) -{ - // Let players go through other players - SetEntProp(client, Prop_Send, "m_CollisionGroup", GOKZ_COLLISION_GROUP_STANDARD); -} - -void OnSetModel_PlayerCollision(int client) -{ - // Fix custom models temporarily changing player collisions - SetEntPropVector(client, Prop_Data, "m_vecMins", PLAYER_MINS); - if (GetEntityFlags(client) & FL_DUCKING == 0) - { - SetEntPropVector(client, Prop_Data, "m_vecMaxs", PLAYER_MAXS); - } - else - { - SetEntPropVector(client, Prop_Data, "m_vecMaxs", PLAYER_MAXS_DUCKED); - } -} - - -// =====[ FORCE SV_FULL_ALLTALK 1 ]===== - -void OnRoundStart_ForceAllTalk() -{ - gCV_sv_full_alltalk.BoolValue = true; -} - - - -// =====[ ERROR SOUNDS ]===== - -#define SOUND_ERROR "buttons/button10.wav" - -void PlayErrorSound(int client) -{ - if (GOKZ_GetCoreOption(client, Option_ErrorSounds) == ErrorSounds_Enabled) - { - GOKZ_EmitSoundToClient(client, SOUND_ERROR, _, "Error"); - } -} - - - -// =====[ STOP SOUNDS ]===== - -Action OnNormalSound_StopSounds(int entity) -{ - char className[20]; - GetEntityClassname(entity, className, sizeof(className)); - if (StrEqual(className, "func_button", false)) - { - return Plugin_Handled; // No sounds directly from func_button - } - return Plugin_Continue; -} - - - -// =====[ JOIN TEAM HANDLING ]===== - -static bool hasSavedPosition[MAXPLAYERS + 1]; -static float savedOrigin[MAXPLAYERS + 1][3]; -static float savedAngles[MAXPLAYERS + 1][3]; -static bool savedOnLadder[MAXPLAYERS + 1]; - -void OnClientPutInServer_JoinTeam(int client) -{ - // Automatically put the player on a team if he doesn't choose one. - // The mp_force_pick_time convar is the built in way to do this, but that obviously - // does not call GOKZ_JoinTeam which includes a fix for spawning in the void when - // there is no valid spawns available. - CreateTimer(12.0, Timer_ForceJoinTeam, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); - - hasSavedPosition[client] = false; -} - -public Action Timer_ForceJoinTeam(Handle timer, int userid) -{ - int client = GetClientOfUserId(userid); - if (IsValidClient(client)) - { - int team = GetClientTeam(client); - if (team == CS_TEAM_NONE) - { - GOKZ_JoinTeam(client, CS_TEAM_SPECTATOR, false); - } - } - return Plugin_Stop; -} - -void OnTimerStart_JoinTeam(int client) -{ - hasSavedPosition[client] = false; -} - -void JoinTeam(int client, int newTeam, bool restorePos, bool forceBroadcast = false) -{ - KZPlayer player = KZPlayer(client); - int currentTeam = GetClientTeam(client); - - // Don't use CS_TEAM_NONE - if (newTeam == CS_TEAM_NONE) - { - newTeam = CS_TEAM_SPECTATOR; - } - - if (newTeam == CS_TEAM_SPECTATOR && currentTeam != CS_TEAM_SPECTATOR) - { - if (currentTeam != CS_TEAM_NONE) - { - player.GetOrigin(savedOrigin[client]); - player.GetEyeAngles(savedAngles[client]); - savedOnLadder[client] = player.Movetype == MOVETYPE_LADDER; - hasSavedPosition[client] = true; - } - - if (!player.Paused && !player.CanPause) - { - player.StopTimer(); - } - ChangeClientTeam(client, CS_TEAM_SPECTATOR); - Call_GOKZ_OnJoinTeam(client, newTeam); - } - else if (newTeam == CS_TEAM_CT && currentTeam != CS_TEAM_CT - || newTeam == CS_TEAM_T && currentTeam != CS_TEAM_T) - { - ForcePlayerSuicide(client); - CS_SwitchTeam(client, newTeam); - CS_RespawnPlayer(client); - if (restorePos && hasSavedPosition[client]) - { - TeleportPlayer(client, savedOrigin[client], savedAngles[client]); - if (savedOnLadder[client]) - { - player.Movetype = MOVETYPE_LADDER; - } - } - else - { - player.StopTimer(); - // Just joining a team alone can put you into weird invalid spawns. - // Need to teleport the player to a valid one. - float spawnOrigin[3]; - float spawnAngles[3]; - GetValidSpawn(spawnOrigin, spawnAngles); - TeleportPlayer(client, spawnOrigin, spawnAngles); - } - hasSavedPosition[client] = false; - Call_GOKZ_OnJoinTeam(client, newTeam); - } - else if (forceBroadcast) - { - Call_GOKZ_OnJoinTeam(client, newTeam); - } -} - -void SendFakeTeamEvent(int client) -{ - // Send a fake event to close the team menu - Event event = CreateEvent("player_team"); - event.SetInt("userid", GetClientUserId(client)); - event.FireToClient(client); - event.Cancel(); -} - -// =====[ VALID JUMP TRACKING ]===== - -/* - Valid jump tracking is intended to detect when the player - has performed a normal jump that hasn't been affected by - (unexpected) teleports or other cases that may result in - the player becoming airborne, such as spawning. - - There are ways to trick the plugin, but it is rather - unlikely to happen during normal gameplay. -*/ - -static bool validJump[MAXPLAYERS + 1]; -static float validJumpTeleportOrigin[MAXPLAYERS + 1][3]; -static int lastInvalidatedTick[MAXPLAYERS + 1]; -bool GetValidJump(int client) -{ - return validJump[client]; -} - -static void InvalidateJump(int client) -{ - lastInvalidatedTick[client] = GetGameTickCount(); - if (validJump[client]) - { - validJump[client] = false; - Call_GOKZ_OnJumpInvalidated(client); - } -} - -void OnStopTouchGround_ValidJump(int client, bool jumped, bool ladderJump, bool jumpbug) -{ - if (Movement_GetMovetype(client) == MOVETYPE_WALK && lastInvalidatedTick[client] != GetGameTickCount()) - { - validJump[client] = true; - Call_GOKZ_OnJumpValidated(client, jumped, ladderJump, jumpbug); - } - else - { - InvalidateJump(client); - } -} - -void OnPlayerRunCmdPost_ValidJump(int client) -{ - if (gB_VelocityTeleported[client] || gB_OriginTeleported[client]) - { - InvalidateJump(client); - } -} - -void OnChangeMovetype_ValidJump(int client, MoveType oldMovetype, MoveType newMovetype) -{ - if (oldMovetype == MOVETYPE_LADDER && newMovetype == MOVETYPE_WALK && lastInvalidatedTick[client] != GetGameTickCount()) // Ladderjump - { - validJump[client] = true; - Call_GOKZ_OnJumpValidated(client, false, true, false); - } - else - { - InvalidateJump(client); - } -} - -void OnClientDisconnect_ValidJump(int client) -{ - InvalidateJump(client); -} - -void OnPlayerSpawn_ValidJump(int client) -{ - // That should definitely be out of bounds - CopyVector({ 40000.0, 40000.0, 40000.0 }, validJumpTeleportOrigin[client]); - InvalidateJump(client); -} - -void OnPlayerDeath_ValidJump(int client) -{ - InvalidateJump(client); -} - -void OnValidOriginChange_ValidJump(int client, const float origin[3]) -{ - CopyVector(origin, validJumpTeleportOrigin[client]); -} - -void OnTeleport_ValidJump(int client) -{ - float origin[3]; - Movement_GetOrigin(client, origin); - if (gB_OriginTeleported[client] && GetVectorDistance(validJumpTeleportOrigin[client], origin, true) <= EPSILON) - { - gB_OriginTeleported[client] = false; - CopyVector({ 40000.0, 40000.0, 40000.0 }, validJumpTeleportOrigin[client]); - return; - } - - if (gB_OriginTeleported[client]) - { - InvalidateJump(client); - Call_GOKZ_OnTeleport(client); - } - - if (gB_VelocityTeleported[client]) - { - InvalidateJump(client); - } -} - - - -// =====[ FIRST SPAWN ]===== - -static bool hasSpawned[MAXPLAYERS + 1]; - -void OnClientPutInServer_FirstSpawn(int client) -{ - hasSpawned[client] = false; -} - -void OnPlayerSpawn_FirstSpawn(int client) -{ - int team = GetClientTeam(client); - if (!hasSpawned[client] && (team == CS_TEAM_CT || team == CS_TEAM_T)) - { - hasSpawned[client] = true; - Call_GOKZ_OnFirstSpawn(client); - } -} - - - -// =====[ TIME LIMIT ]===== - -void OnConfigsExecuted_TimeLimit() -{ - CreateTimer(1.0, Timer_TimeLimit, _, TIMER_REPEAT); -} - -public Action Timer_TimeLimit(Handle timer) -{ - int timelimit; - if (!GetMapTimeLimit(timelimit) || timelimit == 0) - { - return Plugin_Continue; - } - - int timeleft; - // Check for less than -1 in case we miss 0 - ignore -1 because that means infinite time limit - if (GetMapTimeLeft(timeleft) && (timeleft == 0 || timeleft < -1)) - { - CreateTimer(5.0, Timer_EndRound); // End the round after a delay or it won't end the map - return Plugin_Stop; - } - - return Plugin_Continue; -} - -public Action Timer_EndRound(Handle timer) -{ - CS_TerminateRound(1.0, CSRoundEnd_Draw, true); - return Plugin_Continue; -} - - - -// =====[ COURSE REGISTER ]===== - -static bool startRegistered[GOKZ_MAX_COURSES]; -static bool endRegistered[GOKZ_MAX_COURSES]; -static bool courseRegistered[GOKZ_MAX_COURSES]; - -bool GetCourseRegistered(int course) -{ - return courseRegistered[course]; -} - -void RegisterCourseStart(int course) -{ - startRegistered[course] = true; - TryRegisterCourse(course); -} - -void RegisterCourseEnd(int course) -{ - endRegistered[course] = true; - TryRegisterCourse(course); -} - -void OnMapStart_CourseRegister() -{ - for (int course = 0; course < GOKZ_MAX_COURSES; course++) - { - courseRegistered[course] = false; - } -} - -static void TryRegisterCourse(int course) -{ - if (!courseRegistered[course] && startRegistered[course] && endRegistered[course]) - { - courseRegistered[course] = true; - Call_GOKZ_OnCourseRegistered(course); - } -} - - - -// =====[ SPAWN FIXES ]===== - -void OnMapStart_FixMissingSpawns() -{ - int tSpawn = FindEntityByClassname(-1, "info_player_terrorist"); - int ctSpawn = FindEntityByClassname(-1, "info_player_counterterrorist"); - - if (tSpawn == -1 && ctSpawn == -1) - { - LogMessage("Couldn't fix spawns because none exist."); - return; - } - - if (tSpawn == -1 || ctSpawn == -1) - { - float origin[3], angles[3]; - GetValidSpawn(origin, angles); - - int newSpawn = CreateEntityByName((tSpawn == -1) ? "info_player_terrorist" : "info_player_counterterrorist"); - if (DispatchSpawn(newSpawn)) - { - TeleportEntity(newSpawn, origin, angles, NULL_VECTOR); - } - } -} - -// =====[ BUTTONS ]===== - -void OnClientPreThinkPost_UseButtons(int client) -{ - if (GOKZ_GetCoreOption(client, Option_ButtonThroughPlayers) == ButtonThroughPlayers_Enabled && GetEntProp(client, Prop_Data, "m_afButtonPressed") & IN_USE) - { - int entity = FindUseEntity(client); - if (entity != -1) - { - AcceptEntityInput(entity, "Use", client, client, 1); - } - } -} - -static int FindUseEntity(int client) -{ - float fwd[3]; - float angles[3]; - GetClientEyeAngles(client, angles); - GetAngleVectors(angles, fwd, NULL_VECTOR, NULL_VECTOR); - - Handle trace; - - float eyeOrigin[3]; - GetClientEyePosition(client, eyeOrigin); - int useableContents = (MASK_NPCSOLID_BRUSHONLY | MASK_OPAQUE_AND_NPCS) & ~CONTENTS_OPAQUE; - - float endpos[3]; - - // Check if +use trace collide with a player first, so we don't activate any button twice - trace = TR_TraceRayFilterEx(eyeOrigin, angles, useableContents, RayType_Infinite, TRFOtherPlayersOnly, client); - if (TR_DidHit(trace)) - { - int ent = TR_GetEntityIndex(trace); - if (ent < 1 || ent > MaxClients) - { - return -1; - } - // Search for a button behind it. - trace = TR_TraceRayFilterEx(eyeOrigin, angles, useableContents, RayType_Infinite, TraceEntityFilterPlayers); - if (TR_DidHit(trace)) - { - char buffer[20]; - ent = TR_GetEntityIndex(trace); - // Make sure that it is a button, and this button activates when pressed. - // If it is not a button, check its parent to see if it is a button. - bool isButton; - while (ent != -1) - { - GetEntityClassname(ent, buffer, sizeof(buffer)); - if (StrEqual("func_button", buffer, false) && GetEntProp(ent, Prop_Data, "m_spawnflags") & SF_BUTTON_USE_ACTIVATES) - { - isButton = true; - break; - } - else - { - ent = GetEntPropEnt(ent, Prop_Data, "m_hMoveParent"); - } - } - if (isButton) - { - TR_GetEndPosition(endpos, trace); - float delta[3]; - for (int i = 0; i < 2; i++) - { - delta[i] = endpos[i] - eyeOrigin[i]; - } - // Z distance is treated differently. - float m_vecMins[3]; - float m_vecMaxs[3]; - float m_vecOrigin[3]; - GetEntPropVector(ent, Prop_Send, "m_vecOrigin", m_vecOrigin); - GetEntPropVector(ent, Prop_Send, "m_vecMins", m_vecMins); - GetEntPropVector(ent, Prop_Send, "m_vecMaxs", m_vecMaxs); - - delta[2] = IntervalDistance(endpos[2], m_vecOrigin[2] + m_vecMins[2], m_vecOrigin[2] + m_vecMaxs[2]); - if (GetVectorLength(delta) < 80.0) - { - return ent; - } - } - } - } - - int nearestEntity; - float nearestPoint[3]; - float nearestDist = FLOAT_MAX; - ArrayList entities = new ArrayList(); - TR_EnumerateEntitiesSphere(eyeOrigin, 80.0, 1<<5, AddEntities, entities); - for (int i = 0; i < entities.Length; i++) - { - char buffer[64]; - int ent = entities.Get(i); - GetEntityClassname(ent, buffer, sizeof(buffer)); - // Check if the entity is a button and it is pressable. - if (StrEqual("func_button", buffer, false) && GetEntProp(ent, Prop_Data, "m_spawnflags") & SF_BUTTON_USE_ACTIVATES) - { - float point[3]; - CalcNearestPoint(ent, eyeOrigin, point); - - float dir[3]; - for (int j = 0; j < 3; j++) - { - dir[j] = point[j] - eyeOrigin[2]; - } - // Check the maximum angle the player can be away from the button. - float minimumDot = GetEntPropFloat(ent, Prop_Send, "m_flUseLookAtAngle"); - NormalizeVector(dir, dir); - float dot = GetVectorDotProduct(dir, fwd); - if (dot < minimumDot) - { - continue; - } - - float dist = CalcDistanceToLine(point, eyeOrigin, fwd); - if (dist < nearestDist) - { - trace = TR_TraceRayFilterEx(eyeOrigin, point, useableContents, RayType_EndPoint, TraceEntityFilterPlayers); - if (TR_GetFraction(trace) == 1.0 || TR_GetEntityIndex(trace) == ent) - { - CopyVector(point, nearestPoint); - nearestDist = dist; - nearestEntity = ent; - } - } - } - } - // We found the closest button, but we still need to check if there is a player in front of it or not. - // In the case that there isn't a player inbetween, we don't return the entity index, because that button will be pressed by the game function anyway. - // If there is, we will press two buttons at once, the "right" button found by this function and the "wrong" button that we only happen to press because - // there is a player in the way. - - trace = TR_TraceRayFilterEx(eyeOrigin, nearestPoint, useableContents, RayType_EndPoint, TRFOtherPlayersOnly); - if (TR_DidHit(trace)) - { - return nearestEntity; - } - return -1; -} - -public bool AddEntities(int entity, ArrayList entities) -{ - entities.Push(entity); - return true; -} - -static float IntervalDistance(float x, float x0, float x1) -{ - if (x0 > x1) - { - float tmp = x0; - x0 = x1; - x1 = tmp; - } - if (x < x0) - { - return x0 - x; - } - else if (x > x1) - { - return x - x1; - } - return 0.0; -} -// TraceRay filter for other players exclusively. -public bool TRFOtherPlayersOnly(int entity, int contentmask, int client) -{ - return (0 < entity <= MaxClients) && (entity != client); -} - -// =====[ SAFE MODE ]===== - -void ToggleNubSafeGuard(int client) -{ - if (GOKZ_GetCoreOption(client, Option_Safeguard) == Safeguard_EnabledNUB) - { - GOKZ_SetCoreOption(client, Option_Safeguard, Safeguard_Disabled); - } - else - { - GOKZ_SetCoreOption(client, Option_Safeguard, Safeguard_EnabledNUB); - } -} - -void ToggleProSafeGuard(int client) -{ - if (GOKZ_GetCoreOption(client, Option_Safeguard) == Safeguard_EnabledPRO) - { - GOKZ_SetCoreOption(client, Option_Safeguard, Safeguard_Disabled); - } - else - { - GOKZ_SetCoreOption(client, Option_Safeguard, Safeguard_EnabledPRO); - } -} diff --git a/sourcemod/scripting/gokz-core/modes.sp b/sourcemod/scripting/gokz-core/modes.sp deleted file mode 100644 index ce6f8ae..0000000 --- a/sourcemod/scripting/gokz-core/modes.sp +++ /dev/null @@ -1,106 +0,0 @@ -static bool modeLoaded[MODE_COUNT]; -static int modeVersion[MODE_COUNT]; -static bool GOKZHitPerf[MAXPLAYERS + 1]; -static float GOKZTakeoffSpeed[MAXPLAYERS + 1]; - - - -// =====[ PUBLIC ]===== - -bool GetModeLoaded(int mode) -{ - return modeLoaded[mode]; -} - -int GetModeVersion(int mode) -{ - return modeLoaded[mode] ? modeVersion[mode] : -1; -} - -void SetModeLoaded(int mode, bool loaded, int version = -1) -{ - if (!modeLoaded[mode] && loaded) - { - modeLoaded[mode] = true; - modeVersion[mode] = version; - Call_GOKZ_OnModeLoaded(mode); - } - else if (modeLoaded[mode] && !loaded) - { - modeLoaded[mode] = false; - Call_GOKZ_OnModeUnloaded(mode); - } -} - -int GetLoadedModeCount() -{ - int count = 0; - for (int mode = 0; mode < MODE_COUNT; mode++) - { - if (modeLoaded[mode]) - { - count++; - } - } - return count; -} - -int GetALoadedMode() -{ - for (int mode = 0; mode < MODE_COUNT; mode++) - { - if (GOKZ_GetModeLoaded(mode)) - { - return mode; - } - } - return -1; // Uh-oh -} - -bool GetGOKZHitPerf(int client) -{ - return GOKZHitPerf[client]; -} - -void SetGOKZHitPerf(int client, bool hitPerf) -{ - GOKZHitPerf[client] = hitPerf; -} - -float GetGOKZTakeoffSpeed(int client) -{ - return GOKZTakeoffSpeed[client]; -} - -void SetGOKZTakeoffSpeed(int client, float takeoffSpeed) -{ - GOKZTakeoffSpeed[client] = takeoffSpeed; -} - - - -// =====[ EVENTS ]===== - -void OnAllPluginsLoaded_Modes() -{ - if (GetLoadedModeCount() <= 0) - { - SetFailState("At least one GOKZ mode plugin is required."); - } -} - -void OnPlayerSpawn_Modes(int client) -{ - GOKZHitPerf[client] = false; - GOKZTakeoffSpeed[client] = 0.0; -} - -void OnOptionChanged_Mode(int client, Option option) -{ - if (option == Option_Mode) - { - // Remove speed when switching modes - Movement_SetVelocityModifier(client, 1.0); - Movement_SetVelocity(client, view_as<float>( { 0.0, 0.0, 0.0 } )); - } -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/natives.sp b/sourcemod/scripting/gokz-core/natives.sp deleted file mode 100644 index 319810c..0000000 --- a/sourcemod/scripting/gokz-core/natives.sp +++ /dev/null @@ -1,647 +0,0 @@ -void CreateNatives() -{ - CreateNative("GOKZ_GetModeLoaded", Native_GetModeLoaded); - CreateNative("GOKZ_GetModeVersion", Native_GetModeVersion); - CreateNative("GOKZ_SetModeLoaded", Native_SetModeLoaded); - CreateNative("GOKZ_GetLoadedModeCount", Native_GetLoadedModeCount); - CreateNative("GOKZ_SetMode", Native_SetMode); - CreateNative("GOKZ_PrintToChat", Native_PrintToChat); - CreateNative("GOKZ_PrintToChatAndLog", Native_PrintToChatAndLog); - CreateNative("GOKZ_GetOptionsTopMenu", Native_GetOptionsTopMenu); - CreateNative("GOKZ_GetCourseRegistered", Native_GetCourseRegistered); - - CreateNative("GOKZ_StartTimer", Native_StartTimer); - CreateNative("GOKZ_EndTimer", Native_EndTimer); - CreateNative("GOKZ_StopTimer", Native_StopTimer); - CreateNative("GOKZ_StopTimerAll", Native_StopTimerAll); - CreateNative("GOKZ_TeleportToStart", Native_TeleportToStart); - CreateNative("GOKZ_TeleportToSearchStart", Native_TeleportToSearchStart); - CreateNative("GOKZ_GetVirtualButtonPosition", Native_GetVirtualButtonPosition); - CreateNative("GOKZ_SetVirtualButtonPosition", Native_SetVirtualButtonPosition); - CreateNative("GOKZ_ResetVirtualButtonPosition", Native_ResetVirtualButtonPosition); - CreateNative("GOKZ_LockVirtualButtons", Native_LockVirtualButtons); - CreateNative("GOKZ_GetStartPosition", Native_GetStartPosition); - CreateNative("GOKZ_SetStartPosition", Native_SetStartPosition); - CreateNative("GOKZ_TeleportToEnd", Native_TeleportToEnd); - CreateNative("GOKZ_GetStartPositionType", Native_GetStartPositionType); - CreateNative("GOKZ_SetStartPositionToMapStart", Native_SetStartPositionToMapStart); - CreateNative("GOKZ_MakeCheckpoint", Native_MakeCheckpoint); - CreateNative("GOKZ_GetCanMakeCheckpoint", Native_GetCanMakeCheckpoint); - CreateNative("GOKZ_TeleportToCheckpoint", Native_TeleportToCheckpoint); - CreateNative("GOKZ_GetCanTeleportToCheckpoint", Native_GetCanTeleportToCheckpoint); - CreateNative("GOKZ_PrevCheckpoint", Native_PrevCheckpoint); - CreateNative("GOKZ_GetCanPrevCheckpoint", Native_GetCanPrevCheckpoint); - CreateNative("GOKZ_NextCheckpoint", Native_NextCheckpoint); - CreateNative("GOKZ_GetCanNextCheckpoint", Native_GetCanNextCheckpoint); - CreateNative("GOKZ_UndoTeleport", Native_UndoTeleport); - CreateNative("GOKZ_GetCanUndoTeleport", Native_GetCanUndoTeleport); - CreateNative("GOKZ_Pause", Native_Pause); - CreateNative("GOKZ_GetCanPause", Native_GetCanPause); - CreateNative("GOKZ_Resume", Native_Resume); - CreateNative("GOKZ_GetCanResume", Native_GetCanResume); - CreateNative("GOKZ_TogglePause", Native_TogglePause); - CreateNative("GOKZ_GetCanTeleportToStart", Native_GetCanTeleportToStart); - CreateNative("GOKZ_GetCanTeleportToEnd", Native_GetCanTeleportToEnd); - CreateNative("GOKZ_PlayErrorSound", Native_PlayErrorSound); - CreateNative("GOKZ_SetValidJumpOrigin", Native_SetValidJumpOrigin); - - CreateNative("GOKZ_GetTimerRunning", Native_GetTimerRunning); - CreateNative("GOKZ_GetValidTimer", Native_GetValidTimer); - CreateNative("GOKZ_GetCourse", Native_GetCourse); - CreateNative("GOKZ_SetCourse", Native_SetCourse); - CreateNative("GOKZ_GetPaused", Native_GetPaused); - CreateNative("GOKZ_GetTime", Native_GetTime); - CreateNative("GOKZ_SetTime", Native_SetTime); - CreateNative("GOKZ_InvalidateRun", Native_InvalidateRun); - CreateNative("GOKZ_GetCheckpointCount", Native_GetCheckpointCount); - CreateNative("GOKZ_SetCheckpointCount", Native_SetCheckpointCount); - CreateNative("GOKZ_GetCheckpointData", Native_GetCheckpointData); - CreateNative("GOKZ_SetCheckpointData", Native_SetCheckpointData); - CreateNative("GOKZ_GetUndoTeleportData", Native_GetUndoTeleportData); - CreateNative("GOKZ_SetUndoTeleportData", Native_SetUndoTeleportData); - CreateNative("GOKZ_GetTeleportCount", Native_GetTeleportCount); - CreateNative("GOKZ_SetTeleportCount", Native_SetTeleportCount); - CreateNative("GOKZ_RegisterOption", Native_RegisterOption); - CreateNative("GOKZ_GetOptionProp", Native_GetOptionProp); - CreateNative("GOKZ_SetOptionProp", Native_SetOptionProp); - CreateNative("GOKZ_GetOption", Native_GetOption); - CreateNative("GOKZ_SetOption", Native_SetOption); - CreateNative("GOKZ_GetHitPerf", Native_GetHitPerf); - CreateNative("GOKZ_SetHitPerf", Native_SetHitPerf); - CreateNative("GOKZ_GetTakeoffSpeed", Native_GetTakeoffSpeed); - CreateNative("GOKZ_SetTakeoffSpeed", Native_SetTakeoffSpeed); - CreateNative("GOKZ_GetValidJump", Native_GetValidJump); - CreateNative("GOKZ_JoinTeam", Native_JoinTeam); - - CreateNative("GOKZ_EmitSoundToClient", Native_EmitSoundToClient); -} - -public int Native_GetModeLoaded(Handle plugin, int numParams) -{ - return view_as<int>(GetModeLoaded(GetNativeCell(1))); -} - -public int Native_GetModeVersion(Handle plugin, int numParams) -{ - return view_as<int>(GetModeVersion(GetNativeCell(1))); -} - -public int Native_SetModeLoaded(Handle plugin, int numParams) -{ - SetModeLoaded(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3)); - return 0; -} - -public int Native_GetLoadedModeCount(Handle plugin, int numParams) -{ - return GetLoadedModeCount(); -} - -public int Native_SetMode(Handle plugin, int numParams) -{ - return view_as<bool>(SwitchToModeIfAvailable(GetNativeCell(1),GetNativeCell(2))); -} - -public int Native_PrintToChatAndLog(Handle plugin, int numParams) -{ - NativeHelper_PrintToChatOrLog(true); - return 0; -} - -public int Native_PrintToChat(Handle plugin, int numParams) -{ - NativeHelper_PrintToChatOrLog(false); - return 0; -} - -static int NativeHelper_PrintToChatOrLog(bool alwaysLog) -{ - int client = GetNativeCell(1); - bool addPrefix = GetNativeCell(2); - - char buffer[1024]; - SetGlobalTransTarget(client); - FormatNativeString(0, 3, 4, sizeof(buffer), _, buffer); - - // The console (client 0) gets a special treatment - if (client == 0 || (!IsValidClient(client) && !IsClientSourceTV(client)) || alwaysLog) - { - // Strip colors - // We can't regex-replace, so I'm quite sure that's the most efficient way. - // It's also not perfectly safe, we will just assume you never have curly - // braces without a color in beween. - char colorlessBuffer[1024]; - FormatEx(colorlessBuffer, sizeof(colorlessBuffer), "%L: ", client); - int iIn = 0, iOut = strlen(colorlessBuffer); - do - { - if (buffer[iIn] == '{') - { - for (; buffer[iIn] != '}' && iIn < sizeof(buffer) - 2; iIn++){} - if (iIn >= sizeof(buffer) - 2) - { - break; - } - iIn++; - continue; - } - - colorlessBuffer[iOut] = buffer[iIn]; - iIn++; - iOut++; - } while (buffer[iIn] != '\0' && iIn < sizeof(buffer) - 1 && iOut < sizeof(colorlessBuffer) - 1); - colorlessBuffer[iOut] = '\0'; - LogMessage(colorlessBuffer); - } - - if (client != 0) - { - if (addPrefix) - { - char prefix[64]; - gCV_gokz_chat_prefix.GetString(prefix, sizeof(prefix)); - Format(buffer, sizeof(buffer), "%s%s", prefix, buffer); - } - - CPrintToChat(client, "%s", buffer); - } - return 0; -} - -public int Native_GetOptionsTopMenu(Handle plugin, int numParams) -{ - return view_as<int>(GetOptionsTopMenu()); -} - -public int Native_GetCourseRegistered(Handle plugin, int numParams) -{ - return view_as<int>(GetCourseRegistered(GetNativeCell(1))); -} - -public int Native_StartTimer(Handle plugin, int numParams) -{ - if (BlockedExternallyCalledTimerNative(plugin, GetNativeCell(1))) - { - return view_as<int>(false); - } - - return view_as<int>(TimerStart(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3))); -} - -public int Native_EndTimer(Handle plugin, int numParams) -{ - if (BlockedExternallyCalledTimerNative(plugin, GetNativeCell(1))) - { - return view_as<int>(false); - } - - return view_as<int>(TimerEnd(GetNativeCell(1), GetNativeCell(2))); -} - -public int Native_StopTimer(Handle plugin, int numParams) -{ - return view_as<int>(TimerStop(GetNativeCell(1), GetNativeCell(2))); -} - -public int Native_StopTimerAll(Handle plugin, int numParams) -{ - TimerStopAll(GetNativeCell(1)); - return 0; -} - -public int Native_TeleportToStart(Handle plugin, int numParams) -{ - TeleportToStart(GetNativeCell(1)); - return 0; -} - -public int Native_TeleportToSearchStart(Handle plugin, int numParams) -{ - TeleportToSearchStart(GetNativeCell(1), GetNativeCell(2)); - return 0; -} - -public int Native_GetVirtualButtonPosition(Handle plugin, int numParams) -{ - int course; - float position[3]; - - course = GetVirtualButtonPosition(GetNativeCell(1), position, GetNativeCell(3)); - SetNativeArray(2, position, sizeof(position)); - - return course; -} - -public int Native_SetVirtualButtonPosition(Handle plugin, int numParams) -{ - float position[3]; - - GetNativeArray(2, position, sizeof(position)); - SetVirtualButtonPosition(GetNativeCell(1), position, GetNativeCell(3), view_as<bool>(GetNativeCell(4))); - return 0; -} - -public int Native_ResetVirtualButtonPosition(Handle plugin, int numParams) -{ - ResetVirtualButtonPosition(GetNativeCell(1), GetNativeCell(2)); - return 0; -} - -public int Native_LockVirtualButtons(Handle plugin, int numParams) -{ - LockVirtualButtons(GetNativeCell(1)); - return 0; -} - -public int Native_GetStartPosition(Handle plugin, int numParams) -{ - StartPositionType type; - float position[3], angles[3]; - - type = GetStartPosition(GetNativeCell(1), position, angles); - SetNativeArray(2, position, sizeof(position)); - SetNativeArray(3, angles, sizeof(angles)); - - return view_as<int>(type); -} - -public int Native_SetStartPosition(Handle plugin, int numParams) -{ - float position[3], angles[3]; - - GetNativeArray(3, position, sizeof(position)); - GetNativeArray(4, angles, sizeof(angles)); - SetStartPosition(GetNativeCell(1), GetNativeCell(2), position, angles); - return 0; -} - -public int Native_TeleportToEnd(Handle plugin, int numParams) -{ - TeleportToEnd(GetNativeCell(1), GetNativeCell(2)); - return 0; -} - -public int Native_GetStartPositionType(Handle plugin, int numParams) -{ - return view_as<int>(GetStartPositionType(GetNativeCell(1))); -} - -public int Native_SetStartPositionToMapStart(Handle plugin, int numParams) -{ - return SetStartPositionToMapStart(GetNativeCell(1), GetNativeCell(2)); -} - -public int Native_MakeCheckpoint(Handle plugin, int numParams) -{ - MakeCheckpoint(GetNativeCell(1)); - return 0; -} - -public int Native_GetCanMakeCheckpoint(Handle plugin, int numParams) -{ - return CanMakeCheckpoint(GetNativeCell(1)); -} - -public int Native_TeleportToCheckpoint(Handle plugin, int numParams) -{ - TeleportToCheckpoint(GetNativeCell(1)); - return 0; -} - -public int Native_GetCanTeleportToCheckpoint(Handle plugin, int numParams) -{ - return CanTeleportToCheckpoint(GetNativeCell(1)); -} - -public int Native_PrevCheckpoint(Handle plugin, int numParams) -{ - PrevCheckpoint(GetNativeCell(1)); - return 0; -} - -public int Native_GetCanPrevCheckpoint(Handle plugin, int numParams) -{ - return CanPrevCheckpoint(GetNativeCell(1)); -} - -public int Native_NextCheckpoint(Handle plugin, int numParams) -{ - NextCheckpoint(GetNativeCell(1)); - return 0; -} - -public int Native_GetCanNextCheckpoint(Handle plugin, int numParams) -{ - return CanNextCheckpoint(GetNativeCell(1)); -} - -public int Native_UndoTeleport(Handle plugin, int numParams) -{ - UndoTeleport(GetNativeCell(1)); - return 0; -} - -public int Native_GetCanUndoTeleport(Handle plugin, int numParams) -{ - return CanUndoTeleport(GetNativeCell(1)); -} - -public int Native_Pause(Handle plugin, int numParams) -{ - Pause(GetNativeCell(1)); - return 0; -} - -public int Native_GetCanPause(Handle plugin, int numParams) -{ - return CanPause(GetNativeCell(1)); -} - -public int Native_Resume(Handle plugin, int numParams) -{ - Resume(GetNativeCell(1)); - return 0; -} - -public int Native_GetCanResume(Handle plugin, int numParams) -{ - return CanResume(GetNativeCell(1)); -} - -public int Native_TogglePause(Handle plugin, int numParams) -{ - TogglePause(GetNativeCell(1)); - return 0; -} - -public int Native_GetCanTeleportToStart(Handle plugin, int numParams) -{ - return CanTeleportToStart(GetNativeCell(1)); -} - -public int Native_GetCanTeleportToEnd(Handle plugin, int numParams) -{ - return CanTeleportToEnd(GetNativeCell(1)); -} - -public int Native_PlayErrorSound(Handle plugin, int numParams) -{ - PlayErrorSound(GetNativeCell(1)); - return 0; -} - -public int Native_SetValidJumpOrigin(Handle plugin, int numParams) -{ - int client = GetNativeCell(1); - float origin[3]; - GetNativeArray(2, origin, sizeof(origin)); - - // The order is important here! - OnValidOriginChange_ValidJump(client, origin); - - // Using Movement_SetOrigin instead causes considerable lag for spectators - SetEntPropVector(client, Prop_Data, "m_vecAbsOrigin", origin); - return 0; -} - -public int Native_GetTimerRunning(Handle plugin, int numParams) -{ - return view_as<int>(GetTimerRunning(GetNativeCell(1))); -} - -public int Native_GetValidTimer(Handle plugin, int numParams) -{ - return view_as<int>(GetValidTimer(GetNativeCell(1))); -} - -public int Native_GetCourse(Handle plugin, int numParams) -{ - return GetCurrentCourse(GetNativeCell(1)); -} - -public int Native_SetCourse(Handle plugin, int numParams) -{ - if (BlockedExternallyCalledTimerNative(plugin, GetNativeCell(1))) - { - return view_as<int>(false); - } - SetCurrentCourse(GetNativeCell(1), GetNativeCell(2)); - return view_as<int>(false); -} - -public int Native_GetPaused(Handle plugin, int numParams) -{ - return view_as<int>(GetPaused(GetNativeCell(1))); -} - -public int Native_GetTime(Handle plugin, int numParams) -{ - return view_as<int>(GetCurrentTime(GetNativeCell(1))); -} - -public int Native_SetTime(Handle plugin, int numParams) -{ - if (BlockedExternallyCalledTimerNative(plugin, GetNativeCell(1))) - { - return view_as<int>(false); - } - - SetCurrentTime(GetNativeCell(1), view_as<float>(GetNativeCell(2))); - return view_as<int>(true); -} - -public int Native_InvalidateRun(Handle plugin, int numParams) -{ - InvalidateRun(GetNativeCell(1)); - return view_as<int>(true); -} - -public int Native_GetCheckpointCount(Handle plugin, int numParams) -{ - return GetCheckpointCount(GetNativeCell(1)); -} - -public int Native_SetCheckpointCount(Handle plugin, int numParams) -{ - if (BlockedExternallyCalledTimerNative(plugin, GetNativeCell(1))) - { - return view_as<int>(false); - } - SetCheckpointCount(GetNativeCell(1), GetNativeCell(2)); - return view_as<int>(true); -} - -public int Native_GetCheckpointData(Handle plugin, int numParams) -{ - ArrayList temp = GetCheckpointData(GetNativeCell(1)); - Handle cps = CloneHandle(temp, plugin); - delete temp; - return view_as<int>(cps); -} - -public int Native_SetCheckpointData(Handle plugin, int numParams) -{ - if (BlockedExternallyCalledTimerNative(plugin, GetNativeCell(1))) - { - return view_as<int>(false); - } - return SetCheckpointData(GetNativeCell(1), view_as<ArrayList>(GetNativeCell(2)), GetNativeCell(3)); -} - -public int Native_GetUndoTeleportData(Handle plugin, int numParams) -{ - ArrayList temp = GetUndoTeleportData(GetNativeCell(1)); - Handle utd = CloneHandle(temp, plugin); - delete temp; - return view_as<int>(utd); -} - -public int Native_SetUndoTeleportData(Handle plugin, int numParams) -{ - if (BlockedExternallyCalledTimerNative(plugin, GetNativeCell(1))) - { - return view_as<int>(false); - } - return SetUndoTeleportData(GetNativeCell(1), view_as<ArrayList>(GetNativeCell(2)), GetNativeCell(3)); -} - -public int Native_GetTeleportCount(Handle plugin, int numParams) -{ - return GetTeleportCount(GetNativeCell(1)); -} - -public int Native_SetTeleportCount(Handle plugin, int numParams) -{ - if (BlockedExternallyCalledTimerNative(plugin, GetNativeCell(1))) - { - return view_as<int>(false); - } - - SetTeleportCount(GetNativeCell(1), GetNativeCell(2)); - return view_as<int>(true); -} - -public int Native_RegisterOption(Handle plugin, int numParams) -{ - char name[GOKZ_OPTION_MAX_NAME_LENGTH]; - GetNativeString(1, name, sizeof(name)); - char description[255]; - GetNativeString(2, description, sizeof(description)); - return view_as<int>(RegisterOption(name, description, GetNativeCell(3), GetNativeCell(4), GetNativeCell(5), GetNativeCell(6))); -} - -public int Native_GetOptionProp(Handle plugin, int numParams) -{ - char option[GOKZ_OPTION_MAX_NAME_LENGTH]; - GetNativeString(1, option, sizeof(option)); - OptionProp prop = GetNativeCell(2); - any value = GetOptionProp(option, prop); - - // Return clone of Handle if called by another plugin - if (prop == OptionProp_Cookie && plugin != gH_ThisPlugin) - { - value = CloneHandle(value, plugin); - } - - return value; -} - -public int Native_SetOptionProp(Handle plugin, int numParams) -{ - char option[GOKZ_OPTION_MAX_NAME_LENGTH]; - GetNativeString(1, option, sizeof(option)); - OptionProp prop = GetNativeCell(2); - return SetOptionProp(option, prop, GetNativeCell(3)); -} - -public int Native_GetOption(Handle plugin, int numParams) -{ - char option[GOKZ_OPTION_MAX_NAME_LENGTH]; - GetNativeString(2, option, sizeof(option)); - return view_as<int>(GetOption(GetNativeCell(1), option)); -} - -public int Native_SetOption(Handle plugin, int numParams) -{ - char option[GOKZ_OPTION_MAX_NAME_LENGTH]; - GetNativeString(2, option, sizeof(option)); - return view_as<int>(SetOption(GetNativeCell(1), option, GetNativeCell(3))); -} - -public int Native_GetHitPerf(Handle plugin, int numParams) -{ - return view_as<int>(GetGOKZHitPerf(GetNativeCell(1))); -} - -public int Native_SetHitPerf(Handle plugin, int numParams) -{ - SetGOKZHitPerf(GetNativeCell(1), view_as<bool>(GetNativeCell(2))); - return 0; -} - -public int Native_GetTakeoffSpeed(Handle plugin, int numParams) -{ - return view_as<int>(GetGOKZTakeoffSpeed(GetNativeCell(1))); -} - -public int Native_SetTakeoffSpeed(Handle plugin, int numParams) -{ - SetGOKZTakeoffSpeed(GetNativeCell(1), view_as<float>(GetNativeCell(2))); - return 0; -} - -public int Native_GetValidJump(Handle plugin, int numParams) -{ - return view_as<int>(GetValidJump(GetNativeCell(1))); -} - -public int Native_JoinTeam(Handle plugin, int numParams) -{ - JoinTeam(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3), GetNativeCell(4)); - return 0; -} - -public int Native_EmitSoundToClient(Handle plugin, int numParams) -{ - int client = GetNativeCell(1); - - char sample[PLATFORM_MAX_PATH]; - GetNativeString(2, sample, sizeof(sample)); - - float volume = GetNativeCell(3); - float newVolume = volume; - - char description[64]; - GetNativeString(4, description, sizeof(description)); - - Action result; - - Call_GOKZ_OnEmitSoundToClient(client, sample, newVolume, description, result); - if (result == Plugin_Stop) - { - return 0; - } - if (result == Plugin_Changed) - { - EmitSoundToClient(client, sample, _, _, _, _, newVolume); - return 0; - } - EmitSoundToClient(client, sample, _, _, _, _, volume); - return 0; -} - -// =====[ PRIVATE ]===== - -static bool BlockedExternallyCalledTimerNative(Handle plugin, int client) -{ - if (plugin != gH_ThisPlugin) - { - Action result; - Call_GOKZ_OnTimerNativeCalledExternally(plugin, client, result); - if (result != Plugin_Continue) - { - return true; - } - } - return false; -} diff --git a/sourcemod/scripting/gokz-core/options.sp b/sourcemod/scripting/gokz-core/options.sp deleted file mode 100644 index 6daef13..0000000 --- a/sourcemod/scripting/gokz-core/options.sp +++ /dev/null @@ -1,438 +0,0 @@ -static StringMap optionData; -static StringMap optionDescriptions; - - - -// =====[ PUBLIC ]===== - -bool RegisterOption(const char[] name, const char[] description, OptionType type, any defaultValue, any minValue, any maxValue) -{ - if (!IsValueInRange(type, defaultValue, minValue, maxValue)) - { - LogError("Failed to register option \"%s\" due to invalid default value and value range.", name); - return false; - } - - if (strlen(name) > GOKZ_OPTION_MAX_NAME_LENGTH - 1) - { - LogError("Failed to register option \"%s\" because its name is too long.", name); - return false; - } - - if (strlen(name) > GOKZ_OPTION_MAX_NAME_LENGTH - 1) - { - LogError("Failed to register option \"%s\" because its description is too long.", name); - return false; - } - - ArrayList data; - Cookie cookie; - if (IsRegisteredOption(name)) - { - optionData.GetValue(name, data); - cookie = GetOptionProp(name, OptionProp_Cookie); - } - else - { - data = new ArrayList(1, view_as<int>(OPTIONPROP_COUNT)); - cookie = new Cookie(name, description, CookieAccess_Private); - } - - data.Set(view_as<int>(OptionProp_Cookie), cookie); - data.Set(view_as<int>(OptionProp_Type), type); - data.Set(view_as<int>(OptionProp_DefaultValue), defaultValue); - data.Set(view_as<int>(OptionProp_MinValue), minValue); - data.Set(view_as<int>(OptionProp_MaxValue), maxValue); - - optionData.SetValue(name, data, true); - optionDescriptions.SetString(name, description, true); - - // Support late-loading/registering - for (int client = 1; client <= MaxClients; client++) - { - if (AreClientCookiesCached(client)) - { - LoadOption(client, name); - } - } - - return true; -} - -any GetOptionProp(const char[] option, OptionProp prop) -{ - ArrayList data; - if (!optionData.GetValue(option, data)) - { - LogError("Failed to get option property of unregistered option \"%s\".", option); - return -1; - } - - return data.Get(view_as<int>(prop)); -} - -bool SetOptionProp(const char[] option, OptionProp prop, any newValue) -{ - ArrayList data; - if (!optionData.GetValue(option, data)) - { - LogError("Failed to set property of unregistered option \"%s\".", option); - return false; - } - - if (prop == OptionProp_Cookie) - { - LogError("Failed to set cookie of option \"%s\" as it is read-only."); - return false; - } - - OptionType type = GetOptionProp(option, OptionProp_Type); - any defaultValue = GetOptionProp(option, OptionProp_DefaultValue); - any minValue = GetOptionProp(option, OptionProp_MinValue); - any maxValue = GetOptionProp(option, OptionProp_MaxValue); - - switch (prop) - { - case OptionProp_DefaultValue: - { - if (!IsValueInRange(type, newValue, minValue, maxValue)) - { - LogError("Failed to set default value of option \"%s\" due to invalid default value and value range.", option); - return false; - } - } - case OptionProp_MinValue: - { - if (!IsValueInRange(type, defaultValue, newValue, maxValue)) - { - LogError("Failed to set minimum value of option \"%s\" due to invalid default value and value range.", option); - return false; - } - } - case OptionProp_MaxValue: - { - if (!IsValueInRange(type, defaultValue, minValue, newValue)) - { - LogError("Failed to set maximum value of option \"%s\" due to invalid default value and value range.", option); - return false; - } - } - } - - data.Set(view_as<int>(prop), newValue); - return optionData.SetValue(option, data, true); -} - -any GetOption(int client, const char[] option) -{ - if (!IsRegisteredOption(option)) - { - LogError("Failed to get value of unregistered option \"%s\".", option); - return -1; - } - - Cookie cookie = GetOptionProp(option, OptionProp_Cookie); - OptionType type = GetOptionProp(option, OptionProp_Type); - char value[100]; - cookie.Get(client, value, sizeof(value)); - - if (type == OptionType_Float) - { - return StringToFloat(value); - } - else //if (type == OptionType_Int) - { - return StringToInt(value); - } -} - -bool SetOption(int client, const char[] option, any newValue) -{ - if (!IsRegisteredOption(option)) - { - LogError("Failed to set value of unregistered option \"%s\".", option); - return false; - } - - if (GetOption(client, option) == newValue) - { - return true; - } - - OptionType type = GetOptionProp(option, OptionProp_Type); - any minValue = GetOptionProp(option, OptionProp_MinValue); - any maxValue = GetOptionProp(option, OptionProp_MaxValue); - - if (!IsValueInRange(type, newValue, minValue, maxValue)) - { - LogError("Failed to set value of option \"%s\" because desired value was outside registered value range.", option); - return false; - } - - char newValueString[100]; - if (type == OptionType_Float) - { - FloatToString(newValue, newValueString, sizeof(newValueString)); - } - else //if (type == OptionType_Int) - { - IntToString(newValue, newValueString, sizeof(newValueString)); - } - - Cookie cookie = GetOptionProp(option, OptionProp_Cookie); - cookie.Set(client, newValueString); - - if (IsClientInGame(client)) - { - Call_GOKZ_OnOptionChanged(client, option, newValue); - } - - return true; -} - -bool IsRegisteredOption(const char[] option) -{ - int dummy; - return optionData.GetValue(option, dummy); -} - - - -// =====[ EVENTS ]===== - -void OnPluginStart_Options() -{ - optionData = new StringMap(); - optionDescriptions = new StringMap(); - RegisterOptions(); -} - -void OnClientCookiesCached_Options(int client) -{ - StringMapSnapshot optionDataSnapshot = optionData.Snapshot(); - char option[GOKZ_OPTION_MAX_NAME_LENGTH]; - - for (int i = 0; i < optionDataSnapshot.Length; i++) - { - optionDataSnapshot.GetKey(i, option, sizeof(option)); - LoadOption(client, option); - } - - delete optionDataSnapshot; - - Call_GOKZ_OnOptionsLoaded(client); -} - -void OnClientPutInServer_Options(int client) -{ - if (!GetModeLoaded(GOKZ_GetCoreOption(client, Option_Mode))) - { - GOKZ_SetCoreOption(client, Option_Mode, GetALoadedMode()); - } -} - -void OnOptionChanged_Options(int client, Option option, int newValue) -{ - if (option == Option_Mode && !GetModeLoaded(newValue)) - { - GOKZ_PrintToChat(client, true, "%t", "Mode Not Available", newValue); - GOKZ_SetCoreOption(client, Option_Mode, GetALoadedMode()); - } - else - { - PrintOptionChangeMessage(client, option, newValue); - } -} - -void OnModeUnloaded_Options(int mode) -{ - for (int client = 1; client <= MaxClients; client++) - { - if (IsClientInGame(client) && GOKZ_GetCoreOption(client, Option_Mode) == mode) - { - GOKZ_SetCoreOption(client, Option_Mode, GetALoadedMode()); - } - } -} - -void OnMapStart_Options() -{ - LoadDefaultOptions(); -} - - - -// =====[ PRIVATE ]===== - -static void RegisterOptions() -{ - for (Option option; option < OPTION_COUNT; option++) - { - RegisterOption(gC_CoreOptionNames[option], gC_CoreOptionDescriptions[option], - OptionType_Int, gI_CoreOptionDefaults[option], 0, gI_CoreOptionCounts[option] - 1); - } -} - -static bool IsValueInRange(OptionType type, any value, any minValue, any maxValue) -{ - if (type == OptionType_Float) - { - return FloatCompare(minValue, value) <= 0 && FloatCompare(value, maxValue) <= 0; - } - else //if (type == OptionType_Int) - { - return minValue <= value && value <= maxValue; - } -} - -static void LoadOption(int client, const char[] option) -{ - char valueString[100]; - Cookie cookie = GetOptionProp(option, OptionProp_Cookie); - cookie.Get(client, valueString, sizeof(valueString)); - - // If there's no stored value for the option, set it to default - if (valueString[0] == '\0') - { - SetOption(client, option, GetOptionProp(option, OptionProp_DefaultValue)); - return; - } - - OptionType type = GetOptionProp(option, OptionProp_Type); - any minValue = GetOptionProp(option, OptionProp_MinValue); - any maxValue = GetOptionProp(option, OptionProp_MaxValue); - any value; - - // If stored option isn't a valid float or integer, or is out of range, set it to default - if (type == OptionType_Float && StringToFloatEx(valueString, value) == 0) - { - SetOption(client, option, GetOptionProp(option, OptionProp_DefaultValue)); - } - else if (type == OptionType_Int && StringToIntEx(valueString, value) == 0) - { - SetOption(client, option, GetOptionProp(option, OptionProp_DefaultValue)); - } - else if (!IsValueInRange(type, value, minValue, maxValue)) - { - SetOption(client, option, GetOptionProp(option, OptionProp_DefaultValue)); - } -} - -// Load default optionData from a config file, creating one and adding optionData if necessary -static void LoadDefaultOptions() -{ - KeyValues oldKV = new KeyValues(GOKZ_CFG_OPTIONS_ROOT); - - if (FileExists(GOKZ_CFG_OPTIONS) && !oldKV.ImportFromFile(GOKZ_CFG_OPTIONS)) - { - LogError("Failed to load file: \"%s\".", GOKZ_CFG_OPTIONS); - delete oldKV; - return; - } - - KeyValues newKV = new KeyValues(GOKZ_CFG_OPTIONS_ROOT); // This one will be sorted by option name - StringMapSnapshot optionDataSnapshot = optionData.Snapshot(); - ArrayList optionDataSnapshotArray = new ArrayList(ByteCountToCells(GOKZ_OPTION_MAX_NAME_LENGTH), 0); - char option[GOKZ_OPTION_MAX_NAME_LENGTH]; - char optionDescription[GOKZ_OPTION_MAX_DESC_LENGTH]; - - // Sort the optionData by name - for (int i = 0; i < optionDataSnapshot.Length; i++) - { - optionDataSnapshot.GetKey(i, option, sizeof(option)); - optionDataSnapshotArray.PushString(option); - } - SortADTArray(optionDataSnapshotArray, Sort_Ascending, Sort_String); - - // Get the values from the KeyValues, otherwise set them - for (int i = 0; i < optionDataSnapshotArray.Length; i++) - { - oldKV.Rewind(); - newKV.Rewind(); - optionDataSnapshotArray.GetString(i, option, sizeof(option)); - optionDescriptions.GetString(option, optionDescription, sizeof(optionDescription)); - - newKV.JumpToKey(option, true); - newKV.SetString(GOKZ_CFG_OPTIONS_DESCRIPTION, optionDescription); - - OptionType type = GetOptionProp(option, OptionProp_Type); - if (type == OptionType_Float) - { - if (oldKV.JumpToKey(option, false) && oldKV.JumpToKey(GOKZ_CFG_OPTIONS_DEFAULT, false)) - { - oldKV.GoBack(); - newKV.SetFloat(GOKZ_CFG_OPTIONS_DEFAULT, oldKV.GetFloat(GOKZ_CFG_OPTIONS_DEFAULT)); - SetOptionProp(option, OptionProp_DefaultValue, oldKV.GetFloat(GOKZ_CFG_OPTIONS_DEFAULT)); - } - else - { - newKV.SetFloat(GOKZ_CFG_OPTIONS_DEFAULT, GetOptionProp(option, OptionProp_DefaultValue)); - } - } - else if (type == OptionType_Int) - { - if (oldKV.JumpToKey(option, false) && oldKV.JumpToKey(GOKZ_CFG_OPTIONS_DEFAULT, false)) - { - oldKV.GoBack(); - newKV.SetNum(GOKZ_CFG_OPTIONS_DEFAULT, oldKV.GetNum(GOKZ_CFG_OPTIONS_DEFAULT)); - SetOptionProp(option, OptionProp_DefaultValue, oldKV.GetNum(GOKZ_CFG_OPTIONS_DEFAULT)); - } - else - { - newKV.SetNum(GOKZ_CFG_OPTIONS_DEFAULT, GetOptionProp(option, OptionProp_DefaultValue)); - } - } - } - - newKV.Rewind(); - newKV.ExportToFile(GOKZ_CFG_OPTIONS); - - delete oldKV; - delete newKV; - delete optionDataSnapshot; - delete optionDataSnapshotArray; -} - -static void PrintOptionChangeMessage(int client, Option option, int newValue) -{ - // NOTE: Not all optionData have a message for when they are changed. - switch (option) - { - case Option_Mode: - { - GOKZ_PrintToChat(client, true, "%t", "Switched Mode", gC_ModeNames[newValue]); - } - case Option_VirtualButtonIndicators: - { - switch (newValue) - { - case VirtualButtonIndicators_Disabled: - { - GOKZ_PrintToChat(client, true, "%t", "Option - Virtual Button Indicators - Disable"); - } - case VirtualButtonIndicators_Enabled: - { - GOKZ_PrintToChat(client, true, "%t", "Option - Virtual Button Indicators - Enable"); - } - } - } - case Option_Safeguard: - { - switch (newValue) - { - case Safeguard_Disabled: - { - GOKZ_PrintToChat(client, true, "%t", "Option - Safeguard - Disable"); - } - case Safeguard_EnabledNUB: - { - GOKZ_PrintToChat(client, true, "%t", "Option - Safeguard - Enable (NUB)"); - } - case Safeguard_EnabledPRO: - { - GOKZ_PrintToChat(client, true, "%t", "Option - Safeguard - Enable (PRO)"); - } - } - } - } -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/teamnumfix.sp b/sourcemod/scripting/gokz-core/teamnumfix.sp deleted file mode 100644 index 0c5d81d..0000000 --- a/sourcemod/scripting/gokz-core/teamnumfix.sp +++ /dev/null @@ -1,68 +0,0 @@ -static Handle H_RemovePlayer; -static int teamEntID[4]; -static int oldTeam[MAXPLAYERS + 1]; -static int realTeam[MAXPLAYERS + 1]; - -void OnPluginStart_TeamNumber() -{ - GameData gamedataConf = LoadGameConfigFile("gokz-core.games"); - if (gamedataConf == null) - { - SetFailState("Failed to load gokz-core gamedata"); - } - - StartPrepSDKCall(SDKCall_Entity); - PrepSDKCall_SetVirtual(gamedataConf.GetOffset("CCSTeam::RemovePlayer")); - PrepSDKCall_AddParameter(SDKType_CBasePlayer, SDKPass_Pointer); - H_RemovePlayer = EndPrepSDKCall(); - if (H_RemovePlayer == INVALID_HANDLE) - { - SetFailState("Unable to prepare SDKCall for CCSTeam::RemovePlayer!"); - } -} - -void OnMapStart_TeamNumber() -{ - // Fetch the entity ID of team entities and store them. - int team = FindEntityByClassname(MaxClients + 1, "cs_team_manager"); - while (team != -1) - { - int teamNum = GetEntProp(team, Prop_Send, "m_iTeamNum"); - teamEntID[teamNum] = team; - team = FindEntityByClassname(team, "cs_team_manager"); - } -} - -void OnGameFrame_TeamNumber() -{ - for (int client = 1; client <= MaxClients; client++) - { - if (!IsClientInGame(client) || !IsPlayerAlive(client)) - { - continue; - } - int team = GetEntProp(client, Prop_Data, "m_iTeamNum"); - // If the entprop changed, remove the player from the old team, but make sure it's a valid team first - if (team != oldTeam[client] && oldTeam[client] < 4 && oldTeam[client] > 0) - { - SDKCall(H_RemovePlayer, teamEntID[oldTeam[client]], client); - } - oldTeam[client] = team; - } -} - -void OnPlayerJoinTeam_TeamNumber(Event event, int client) -{ - // If the old team value is invalid, fix it. - if (event.GetInt("oldteam") > 4 || event.GetInt("oldteam") < 0) - { - event.SetInt("oldteam", 0); - } - realTeam[client] = event.GetInt("team"); -} - -void OnPlayerDeath_TeamNumber(int client) -{ - // Switch the client's team to a valid team to prevent crashes. - CS_SwitchTeam(client, realTeam[client]); -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/teleports.sp b/sourcemod/scripting/gokz-core/teleports.sp deleted file mode 100644 index 764fc6e..0000000 --- a/sourcemod/scripting/gokz-core/teleports.sp +++ /dev/null @@ -1,917 +0,0 @@ -/* - Checkpoints and teleporting, including ability to go back - to previous checkpoint, go to next checkpoint, and undo. -*/ - - -static ArrayList checkpoints[MAXPLAYERS + 1]; -static int checkpointCount[MAXPLAYERS + 1]; -static int checkpointIndex[MAXPLAYERS + 1]; -static int checkpointIndexStart[MAXPLAYERS + 1]; -static int checkpointIndexEnd[MAXPLAYERS + 1]; -static int teleportCount[MAXPLAYERS + 1]; -static StartPositionType startType[MAXPLAYERS + 1]; -static StartPositionType nonCustomStartType[MAXPLAYERS + 1]; -static float nonCustomStartOrigin[MAXPLAYERS + 1][3]; -static float nonCustomStartAngles[MAXPLAYERS + 1][3]; -static float customStartOrigin[MAXPLAYERS + 1][3]; -static float customStartAngles[MAXPLAYERS + 1][3]; -static float endOrigin[MAXPLAYERS + 1][3]; -static float endAngles[MAXPLAYERS + 1][3]; -static UndoTeleportData undoTeleportData[MAXPLAYERS + 1]; -static float lastRestartAttemptTime[MAXPLAYERS + 1]; - -// =====[ PUBLIC ]===== - -int GetCheckpointCount(int client) -{ - return checkpointCount[client]; -} - -void SetCheckpointCount(int client, int cpCount) -{ - checkpointCount[client] = cpCount; -} - -int GetTeleportCount(int client) -{ - return teleportCount[client]; -} - -void SetTeleportCount(int client, int tpCount) -{ - teleportCount[client] = tpCount; -} - -// CHECKPOINT - -void OnMapStart_Checkpoints() -{ - for (int client = 0; client < MAXPLAYERS + 1; client++) - { - if (checkpoints[client] != INVALID_HANDLE) - { - delete checkpoints[client]; - } - checkpoints[client] = new ArrayList(sizeof(Checkpoint)); - } -} - -void MakeCheckpoint(int client) -{ - if (!CanMakeCheckpoint(client, true)) - { - return; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnMakeCheckpoint(client, result); - if (result != Plugin_Continue) - { - return; - } - - // Make Checkpoint - checkpointCount[client]++; - Checkpoint cp; - cp.Create(client); - - if (checkpoints[client] == INVALID_HANDLE) - { - checkpoints[client] = new ArrayList(sizeof(Checkpoint)); - } - - checkpointIndex[client] = NextIndex(checkpointIndex[client], GOKZ_MAX_CHECKPOINTS); - checkpointIndexEnd[client] = checkpointIndex[client]; - // The list has yet to be filled up, do PushArray instead of SetArray - if (checkpoints[client].Length < GOKZ_MAX_CHECKPOINTS && checkpointIndex[client] == checkpoints[client].Length) - { - checkpoints[client].PushArray(cp); - // Initialize start and end index for the first checkpoint - if (checkpoints[client].Length == 1) - { - checkpointIndexStart[client] = 0; - checkpointIndexEnd[client] = 0; - } - } - else - { - checkpoints[client].SetArray(checkpointIndex[client], cp); - // The new checkpoint has overridden the oldest checkpoint, move the start index by one. - if (checkpointIndexEnd[client] == checkpointIndexStart[client]) - { - checkpointIndexStart[client] = NextIndex(checkpointIndexStart[client], GOKZ_MAX_CHECKPOINTS); - } - } - - - if (GOKZ_GetCoreOption(client, Option_CheckpointSounds) == CheckpointSounds_Enabled) - { - GOKZ_EmitSoundToClient(client, GOKZ_SOUND_CHECKPOINT, _, "Checkpoint"); - } - if (GOKZ_GetCoreOption(client, Option_CheckpointMessages) == CheckpointMessages_Enabled) - { - GOKZ_PrintToChat(client, true, "%t", "Make Checkpoint", checkpointCount[client]); - } - - if (!GetTimerRunning(client) && AntiCpTriggerIsTouched(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Anti Checkpoint Area Warning"); - } - - // Call Post Forward - Call_GOKZ_OnMakeCheckpoint_Post(client); -} - -bool CanMakeCheckpoint(int client, bool showError = false) -{ - if (!IsPlayerAlive(client)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Must Be Alive"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (GetTimerRunning(client) && AntiCpTriggerIsTouched(client)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Checkpoint (Anti Checkpoint Area)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (!Movement_GetOnGround(client) && Movement_GetMovetype(client) != MOVETYPE_LADDER) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Checkpoint (Midair)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (BhopTriggersJustTouched(client)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Checkpoint (Just Landed)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - return true; -} - -ArrayList GetCheckpointData(int client) -{ - // Don't clone the entire thing, return an ordered list of checkpoints. - // Doing this should be cleaner, saves memory and should be faster than a full Clone(). - ArrayList checkpointData = new ArrayList(sizeof(Checkpoint)); - if (checkpointIndex[client] == -1) - { - // No checkpoint was made, return empty ArrayList - return checkpointData; - } - for (int i = checkpointIndexStart[client]; i != checkpointIndexEnd[client]; i = NextIndex(i, GOKZ_MAX_CHECKPOINTS)) - { - Checkpoint cp; - checkpoints[client].GetArray(i, cp); - checkpointData.PushArray(cp); - } - return checkpointData; -} - -bool SetCheckpointData(int client, ArrayList cps, int version) -{ - if (version != GOKZ_CHECKPOINT_VERSION) - { - return false; - } - // cps is assumed to be ordered. - if (cps != INVALID_HANDLE) - { - delete checkpoints[client]; - checkpoints[client] = cps.Clone(); - if (cps.Length == 0) - { - checkpointIndexStart[client] = -1; - checkpointIndexEnd[client] = -1; - } - else - { - checkpointIndexStart[client] = 0; - checkpointIndexEnd[client] = checkpoints[client].Length - 1; - } - checkpointIndex[client] = checkpointIndexEnd[client]; - return true; - } - return false; -} - -ArrayList GetUndoTeleportData(int client) -{ - // Enum structs cannot be sent directly over natives, we put it in an ArrayList of one instead. - // We use another struct instead of reusing Checkpoint so normal checkpoints don't use more memory than needed. - ArrayList undoTeleportDataArray = new ArrayList(sizeof(UndoTeleportData)); - undoTeleportDataArray.PushArray(undoTeleportData[client]); - return undoTeleportDataArray; -} - -bool SetUndoTeleportData(int client, ArrayList undoTeleportDataArray, int version) -{ - if (version != GOKZ_CHECKPOINT_VERSION) - { - return false; - } - if (undoTeleportDataArray != INVALID_HANDLE && undoTeleportDataArray.Length == 1) - { - undoTeleportDataArray.GetArray(0, undoTeleportData[client], sizeof(UndoTeleportData)); - return true; - } - return false; -} -// TELEPORT - -void TeleportToCheckpoint(int client) -{ - if (!CanTeleportToCheckpoint(client, true)) - { - return; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnTeleportToCheckpoint(client, result); - if (result != Plugin_Continue) - { - return; - } - - CheckpointTeleportDo(client); - - // Call Post Forward - Call_GOKZ_OnTeleportToCheckpoint_Post(client); -} - -bool CanTeleportToCheckpoint(int client, bool showError = false) -{ - // Safeguard Check - if (GOKZ_GetCoreOption(client, Option_Safeguard) == Safeguard_EnabledPRO && GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client) && GOKZ_GetTeleportCount(client) == 0) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Safeguard - Blocked"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (GetCurrentMapPrefix() == MapPrefix_KZPro && GetTimerRunning(client)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Teleport (Map)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (checkpoints[client] == INVALID_HANDLE || checkpoints[client].Length <= 0) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Teleport (No Checkpoints)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - return true; -} - - -// PREV CP - -void PrevCheckpoint(int client) -{ - if (!CanPrevCheckpoint(client, true)) - { - return; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnPrevCheckpoint(client, result); - if (result != Plugin_Continue) - { - return; - } - - checkpointIndex[client] = PrevIndex(checkpointIndex[client], GOKZ_MAX_CHECKPOINTS); - CheckpointTeleportDo(client); - - // Call Post Forward - Call_GOKZ_OnPrevCheckpoint_Post(client); -} - -bool CanPrevCheckpoint(int client, bool showError = false) -{ - // Safeguard Check - if (GOKZ_GetCoreOption(client, Option_Safeguard) == Safeguard_EnabledPRO && GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Safeguard - Blocked"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (GetCurrentMapPrefix() == MapPrefix_KZPro && GetTimerRunning(client)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Teleport (Map)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (checkpointIndex[client] == checkpointIndexStart[client]) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Prev CP (No Checkpoints)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - return true; -} - - -// NEXT CP - -void NextCheckpoint(int client) -{ - if (!CanNextCheckpoint(client, true)) - { - return; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnNextCheckpoint(client, result); - if (result != Plugin_Continue) - { - return; - } - checkpointIndex[client] = NextIndex(checkpointIndex[client], GOKZ_MAX_CHECKPOINTS); - CheckpointTeleportDo(client); - - // Call Post Forward - Call_GOKZ_OnNextCheckpoint_Post(client); -} - -bool CanNextCheckpoint(int client, bool showError = false) -{ - if (GetCurrentMapPrefix() == MapPrefix_KZPro && GetTimerRunning(client)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Teleport (Map)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (checkpointIndex[client] == checkpointIndexEnd[client]) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Next CP (No Checkpoints)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - return true; -} - - -// RESTART & RESPAWN - -bool CanTeleportToStart(int client, bool showError = false) -{ - // Safeguard Check - if (GOKZ_GetCoreOption(client, Option_Safeguard) > Safeguard_Disabled && GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client)) - { - float currentTime = GetEngineTime(); - float timeSinceLastAttempt = currentTime - lastRestartAttemptTime[client]; - float cooldown; - // If the client restarts for the first time or the last attempt is too long ago, restart the cooldown. - if (lastRestartAttemptTime[client] == 0.0 || timeSinceLastAttempt > GOKZ_SAFEGUARD_RESTART_MAX_DELAY) - { - lastRestartAttemptTime[client] = currentTime; - cooldown = GOKZ_SAFEGUARD_RESTART_MIN_DELAY; - } - else - { - cooldown = GOKZ_SAFEGUARD_RESTART_MIN_DELAY - timeSinceLastAttempt; - } - if (cooldown <= 0.0) - { - lastRestartAttemptTime[client] = 0.0; - return true; - } - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Safeguard - Blocked (Temp)", cooldown); - GOKZ_PlayErrorSound(client); - } - return false; - } - return true; -} - -void TeleportToStart(int client) -{ - if (!CanTeleportToStart(client, true)) - { - return; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnTeleportToStart(client, GetCurrentCourse(client), result); - if (result != Plugin_Continue) - { - return; - } - - // Teleport to Start - if (startType[client] == StartPositionType_Spawn) - { - GOKZ_RespawnPlayer(client, .restorePos = false); - // Respawning alone does not guarantee a valid spawn. - float spawnOrigin[3]; - float spawnAngles[3]; - GetValidSpawn(spawnOrigin, spawnAngles); - TeleportPlayer(client, spawnOrigin, spawnAngles); - } - else if (startType[client] == StartPositionType_Custom) - { - TeleportDo(client, customStartOrigin[client], customStartAngles[client]); - } - else - { - TeleportDo(client, nonCustomStartOrigin[client], nonCustomStartAngles[client]); - } - - if (startType[client] != StartPositionType_MapButton - && (!InRangeOfVirtualStart(client) || !CanReachVirtualStart(client))) - { - GOKZ_StopTimer(client, false); - } - - // Call Post Forward - Call_GOKZ_OnTeleportToStart_Post(client, GetCurrentCourse(client)); -} - -void TeleportToSearchStart(int client, int course) -{ - if (!CanTeleportToStart(client, true)) - { - return; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnTeleportToStart(client, course, result); - if (result != Plugin_Continue) - { - return; - } - - float origin[3], angles[3]; - if (!GetSearchStartPosition(course, origin, angles)) - { - if (course == 0) - { - GOKZ_PrintToChat(client, true, "%t", "No Start Found"); - } - else - { - GOKZ_PrintToChat(client, true, "%t", "No Start Found (Bonus)", course); - } - return; - } - GOKZ_StopTimer(client, false); - - TeleportDo(client, origin, angles); - // Call Post Forward - Call_GOKZ_OnTeleportToStart_Post(client, course); -} - -StartPositionType GetStartPosition(int client, float position[3], float angles[3]) -{ - if (startType[client] == StartPositionType_Custom) - { - position = customStartOrigin[client]; - angles = customStartAngles[client]; - } - else if (startType[client] != StartPositionType_Spawn) - { - position = nonCustomStartOrigin[client]; - angles = nonCustomStartAngles[client]; - } - - return startType[client]; -} - -bool TeleportToCourseStart(int client, int course) -{ - if (!CanTeleportToStart(client, true)) - { - return false; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnTeleportToStart(client, course, result); - if (result != Plugin_Continue) - { - return false; - } - float origin[3], angles[3]; - - if (!GetMapStartPosition(course, origin, angles)) - { - if (!GetSearchStartPosition(course, origin, angles)) - { - if (course == 0) - { - GOKZ_PrintToChat(client, true, "%t", "No Start Found"); - } - else - { - GOKZ_PrintToChat(client, true, "%t", "No Start Found (Bonus)", course); - } - return false; - } - } - - GOKZ_StopTimer(client); - - TeleportDo(client, origin, angles); - - // Call Post Forward - Call_GOKZ_OnTeleportToStart_Post(client, course); - return true; -} - -StartPositionType GetStartPositionType(int client) -{ - return startType[client]; -} - -// Note: Use ClearStartPosition to switch off StartPositionType_Custom -void SetStartPosition(int client, StartPositionType type, const float origin[3] = NULL_VECTOR, const float angles[3] = NULL_VECTOR) -{ - if (type == StartPositionType_Custom) - { - startType[client] = StartPositionType_Custom; - - if (!IsNullVector(origin)) - { - customStartOrigin[client] = origin; - } - - if (!IsNullVector(angles)) - { - customStartAngles[client] = angles; - } - - // Call Post Forward - Call_GOKZ_OnStartPositionSet_Post(client, startType[client], customStartOrigin[client], customStartAngles[client]); - } - else - { - nonCustomStartType[client] = type; - - if (!IsNullVector(origin)) - { - nonCustomStartOrigin[client] = origin; - } - - if (!IsNullVector(angles)) - { - nonCustomStartAngles[client] = angles; - } - - if (startType[client] != StartPositionType_Custom) - { - startType[client] = type; - - // Call Post Forward - Call_GOKZ_OnStartPositionSet_Post(client, startType[client], nonCustomStartOrigin[client], nonCustomStartAngles[client]); - } - } -} - -void SetStartPositionToCurrent(int client, StartPositionType type) -{ - float origin[3], angles[3]; - Movement_GetOrigin(client, origin); - Movement_GetEyeAngles(client, angles); - - SetStartPosition(client, type, origin, angles); -} - -bool SetStartPositionToMapStart(int client, int course) -{ - float origin[3], angles[3]; - - if (!GetMapStartPosition(course, origin, angles)) - { - return false; - } - - SetStartPosition(client, StartPositionType_MapStart, origin, angles); - - return true; -} - -bool ClearCustomStartPosition(int client) -{ - if (GetStartPositionType(client) != StartPositionType_Custom) - { - return false; - } - - startType[client] = nonCustomStartType[client]; - - // Call Post Forward - Call_GOKZ_OnStartPositionSet_Post(client, startType[client], nonCustomStartOrigin[client], nonCustomStartAngles[client]); - - return true; -} - - -// TELEPORT TO END - -bool CanTeleportToEnd(int client, bool showError = false) -{ - // Safeguard Check - if (GOKZ_GetCoreOption(client, Option_Safeguard) > Safeguard_Disabled && GOKZ_GetTimerRunning(client) && GOKZ_GetValidTimer(client)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Safeguard - Blocked"); - GOKZ_PlayErrorSound(client); - } - return false; - } - return true; -} - -void TeleportToEnd(int client, int course) -{ - if (!CanTeleportToEnd(client, true)) - { - return; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnTeleportToEnd(client, course, result); - if (result != Plugin_Continue) - { - return; - } - - GOKZ_StopTimer(client, false); - - if (!GetMapEndPosition(course, endOrigin[client], endAngles[client])) - { - if (course == 0) - { - GOKZ_PrintToChat(client, true, "%t", "No End Found"); - } - else - { - GOKZ_PrintToChat(client, true, "%t", "No End Found (Bonus)", course); - } - return; - } - TeleportDo(client, endOrigin[client], endAngles[client]); - - // Call Post Forward - Call_GOKZ_OnTeleportToEnd_Post(client, course); -} - -void SetEndPosition(int client, const float origin[3] = NULL_VECTOR, const float angles[3] = NULL_VECTOR) -{ - if (!IsNullVector(origin)) - { - endOrigin[client] = origin; - } - if (!IsNullVector(angles)) - { - endAngles[client] = angles; - } -} - -bool SetEndPositionToMapEnd(int client, int course) -{ - float origin[3], angles[3]; - - if (!GetMapEndPosition(course, origin, angles)) - { - return false; - } - - SetEndPosition(client, origin, angles); - - return true; -} - - -// UNDO TP - -void UndoTeleport(int client) -{ - if (!CanUndoTeleport(client, true)) - { - return; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnUndoTeleport(client, result); - if (result != Plugin_Continue) - { - return; - } - - // Undo Teleport - TeleportDo(client, undoTeleportData[client].origin, undoTeleportData[client].angles); - - // Call Post Forward - Call_GOKZ_OnUndoTeleport_Post(client); -} - -bool CanUndoTeleport(int client, bool showError = false) -{ - if (teleportCount[client] <= 0) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Undo (No Teleports)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (!undoTeleportData[client].lastTeleportOnGround) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Undo (TP Was Midair)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (undoTeleportData[client].lastTeleportInBhopTrigger) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Undo (Just Landed)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - if (undoTeleportData[client].lastTeleportInAntiCpTrigger) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Undo (AntiCp)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - return true; -} - - - -// =====[ EVENTS ]===== - -void OnClientPutInServer_Teleports(int client) -{ - checkpointCount[client] = 0; - checkpointIndex[client] = -1; - checkpointIndexStart[client] = -1; - checkpointIndexEnd[client] = -1; - teleportCount[client] = 0; - startType[client] = StartPositionType_Spawn; - nonCustomStartType[client] = StartPositionType_Spawn; - lastRestartAttemptTime[client] = 0.0; - if (checkpoints[client] != INVALID_HANDLE) - { - checkpoints[client].Clear(); - } - // Set start and end position to main course if we know of it - SetStartPositionToMapStart(client, 0); - SetEndPositionToMapEnd(client, 0); - -} - -void OnTimerStart_Teleports(int client) -{ - checkpointCount[client] = 0; - checkpointIndex[client] = -1; - checkpointIndexStart[client] = -1; - checkpointIndexEnd[client] = -1; - teleportCount[client] = 0; - checkpoints[client].Clear(); -} - -void OnStartButtonPress_Teleports(int client, int course) -{ - SetStartPositionToCurrent(client, StartPositionType_MapButton); - SetEndPositionToMapEnd(client, course); -} - -void OnVirtualStartButtonPress_Teleports(int client) -{ - SetStartPositionToCurrent(client, StartPositionType_MapButton); -} - -void OnStartZoneStartTouch_Teleports(int client, int course) -{ - SetStartPositionToMapStart(client, course); - SetEndPositionToMapEnd(client, course); -} - - - -// =====[ PRIVATE ]===== - -static int PrevIndex(int current, int maximum) -{ - int prev = current - 1; - if (prev < 0) - { - return maximum - 1; - } - return prev; -} - -static void TeleportDo(int client, const float destOrigin[3], const float destAngles[3]) -{ - if (!IsPlayerAlive(client)) - { - GOKZ_RespawnPlayer(client); - } - - // Store information about where player is teleporting from - undoTeleportData[client].Init(client, BhopTriggersJustTouched(client), Movement_GetOnGround(client), AntiCpTriggerIsTouched(client)); - - teleportCount[client]++; - TeleportPlayer(client, destOrigin, destAngles); - // TeleportPlayer needs to be done before undo TP data can be fully updated. - undoTeleportData[client].Update(); - if (GOKZ_GetCoreOption(client, Option_TeleportSounds) == TeleportSounds_Enabled) - { - GOKZ_EmitSoundToClient(client, GOKZ_SOUND_TELEPORT, _, "Teleport"); - } - - // Call Post Foward - Call_GOKZ_OnCountedTeleport_Post(client); -} - -static void CheckpointTeleportDo(int client) -{ - Checkpoint cp; - checkpoints[client].GetArray(checkpointIndex[client], cp); - - TeleportDo(client, cp.origin, cp.angles); - if (cp.groundEnt != INVALID_ENT_REFERENCE) - { - SetEntPropEnt(client, Prop_Data, "m_hGroundEntity", cp.groundEnt); - SetEntityFlags(client, GetEntityFlags(client) | FL_ONGROUND); - } - // Handle ladder stuff - if (cp.onLadder) - { - SetEntPropVector(client, Prop_Send, "m_vecLadderNormal", cp.ladderNormal); - if (!GOKZ_GetPaused(client)) - { - Movement_SetMovetype(client, MOVETYPE_LADDER); - } - else - { - SetPausedOnLadder(client, true); - } - } - else if (GOKZ_GetPaused(client)) - { - SetPausedOnLadder(client, false); - } -} diff --git a/sourcemod/scripting/gokz-core/timer/pause.sp b/sourcemod/scripting/gokz-core/timer/pause.sp deleted file mode 100644 index 92ab1fb..0000000 --- a/sourcemod/scripting/gokz-core/timer/pause.sp +++ /dev/null @@ -1,257 +0,0 @@ -static bool paused[MAXPLAYERS + 1]; -static bool pausedOnLadder[MAXPLAYERS + 1]; -static float lastPauseTime[MAXPLAYERS + 1]; -static bool hasPausedInThisRun[MAXPLAYERS + 1]; -static float lastResumeTime[MAXPLAYERS + 1]; -static bool hasResumedInThisRun[MAXPLAYERS + 1]; -static float lastDuckValue[MAXPLAYERS + 1]; -static float lastStaminaValue[MAXPLAYERS + 1]; - - - -// =====[ PUBLIC ]===== - -bool GetPaused(int client) -{ - return paused[client]; -} - -void SetPausedOnLadder(int client, bool onLadder) -{ - pausedOnLadder[client] = onLadder; -} - -void Pause(int client) -{ - if (!CanPause(client, true)) - { - return; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnPause(client, result); - if (result != Plugin_Continue) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Pause (Generic)"); - GOKZ_PlayErrorSound(client); - return; - } - - // Pause - paused[client] = true; - pausedOnLadder[client] = Movement_GetMovetype(client) == MOVETYPE_LADDER; - lastDuckValue[client] = Movement_GetDuckSpeed(client); - lastStaminaValue[client] = GetEntPropFloat(client, Prop_Send, "m_flStamina"); - Movement_SetVelocity(client, view_as<float>( { 0.0, 0.0, 0.0 } )); - Movement_SetMovetype(client, MOVETYPE_NONE); - if (GetTimerRunning(client)) - { - hasPausedInThisRun[client] = true; - lastPauseTime[client] = GetEngineTime(); - } - - // Call Post Forward - Call_GOKZ_OnPause_Post(client); -} - -bool CanPause(int client, bool showError = false) -{ - if (paused[client]) - { - return false; - } - - if (GetTimerRunning(client)) - { - if (hasResumedInThisRun[client] - && GetEngineTime() - lastResumeTime[client] < GOKZ_PAUSE_COOLDOWN) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Pause (Just Resumed)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - else if (!Movement_GetOnGround(client) - && !(Movement_GetSpeed(client) == 0 && Movement_GetVerticalVelocity(client) == 0)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Pause (Midair)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - else if (BhopTriggersJustTouched(client)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Pause (Just Landed)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - else if (AntiPauseTriggerIsTouched(client)) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Pause (Anti Pause Area)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - } - - return true; -} - -void Resume(int client, bool force = false) -{ - if (!paused[client]) - { - return; - } - if (!force && !CanResume(client, true)) - { - return; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnResume(client, result); - if (result != Plugin_Continue) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Resume (Generic)"); - GOKZ_PlayErrorSound(client); - return; - } - - // Resume - if (pausedOnLadder[client]) - { - Movement_SetMovetype(client, MOVETYPE_LADDER); - } - else - { - Movement_SetMovetype(client, MOVETYPE_WALK); - } - - // Prevent noclip exploit - SetEntProp(client, Prop_Send, "m_CollisionGroup", GOKZ_COLLISION_GROUP_STANDARD); - paused[client] = false; - if (GetTimerRunning(client)) - { - hasResumedInThisRun[client] = true; - lastResumeTime[client] = GetEngineTime(); - } - Movement_SetDuckSpeed(client, lastDuckValue[client]); - SetEntPropFloat(client, Prop_Send, "m_flStamina", lastStaminaValue[client]); - - // Call Post Forward - Call_GOKZ_OnResume_Post(client); -} - -bool CanResume(int client, bool showError = false) -{ - if (GetTimerRunning(client) && hasPausedInThisRun[client] - && GetEngineTime() - lastPauseTime[client] < GOKZ_PAUSE_COOLDOWN) - { - if (showError) - { - GOKZ_PrintToChat(client, true, "%t", "Can't Resume (Just Paused)"); - GOKZ_PlayErrorSound(client); - } - return false; - } - return true; -} - -void TogglePause(int client) -{ - if (paused[client]) - { - Resume(client); - } - else - { - Pause(client); - } -} - - - -// =====[ EVENTS ]===== - -void OnClientPutInServer_Pause(int client) -{ - paused[client] = false; -} - -void OnTimerStart_Pause(int client) -{ - hasPausedInThisRun[client] = false; - hasResumedInThisRun[client] = false; - Resume(client, true); -} - -void OnChangeMovetype_Pause(int client, MoveType newMovetype) -{ - // Check if player has escaped MOVETYPE_NONE - if (!paused[client] || newMovetype == MOVETYPE_NONE) - { - return; - } - - // Player has escaped MOVETYPE_NONE, so resume - paused[client] = false; - if (GetTimerRunning(client)) - { - hasResumedInThisRun[client] = true; - lastResumeTime[client] = GetEngineTime(); - } - - // Call Post Forward - Call_GOKZ_OnResume_Post(client); -} - -void OnPlayerSpawn_Pause(int client) -{ - if (!paused[client]) - { - return; - } - - // Player has left paused state by spawning in, so resume - paused[client] = false; - if (GetTimerRunning(client)) - { - hasResumedInThisRun[client] = true; - lastResumeTime[client] = GetEngineTime(); - } - - Movement_SetDuckSpeed(client, lastDuckValue[client]); - SetEntPropFloat(client, Prop_Send, "m_flStamina", lastStaminaValue[client]); - - // Call Post Forward - Call_GOKZ_OnResume_Post(client); -} - -void OnJoinTeam_Pause(int client, int team) -{ - // Only handle joining spectators. Joining other teams is handled by OnPlayerSpawn. - if (team == CS_TEAM_SPECTATOR) - { - paused[client] = true; - - if (GetTimerRunning(client)) - { - hasPausedInThisRun[client] = true; - lastPauseTime[client] = GetEngineTime(); - } - - // Call Post Forward - Call_GOKZ_OnPause_Post(client); - } -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/timer/timer.sp b/sourcemod/scripting/gokz-core/timer/timer.sp deleted file mode 100644 index f6696ac..0000000 --- a/sourcemod/scripting/gokz-core/timer/timer.sp +++ /dev/null @@ -1,368 +0,0 @@ -static bool timerRunning[MAXPLAYERS + 1]; -static float currentTime[MAXPLAYERS + 1]; -static int currentCourse[MAXPLAYERS + 1]; -static float lastEndTime[MAXPLAYERS + 1]; -static float lastFalseEndTime[MAXPLAYERS + 1]; -static float lastStartSoundTime[MAXPLAYERS + 1]; -static int lastStartMode[MAXPLAYERS + 1]; -static bool validTime[MAXPLAYERS + 1]; - - -// =====[ PUBLIC ]===== - -bool GetTimerRunning(int client) -{ - return timerRunning[client]; -} - -bool GetValidTimer(int client) -{ - return validTime[client]; -} - -float GetCurrentTime(int client) -{ - return currentTime[client]; -} - -void SetCurrentTime(int client, float time) -{ - currentTime[client] = time; - // The timer should be running if time is not negative. - timerRunning[client] = time >= 0.0; -} - -int GetCurrentCourse(int client) -{ - return currentCourse[client]; -} - -void SetCurrentCourse(int client, int course) -{ - currentCourse[client] = course; -} - -int GetCurrentTimeType(int client) -{ - if (GetTeleportCount(client) == 0) - { - return TimeType_Pro; - } - return TimeType_Nub; -} - -bool TimerStart(int client, int course, bool allowMidair = false, bool playSound = true) -{ - if (!IsPlayerAlive(client) - || JustStartedTimer(client) - || JustTeleported(client) - || JustNoclipped(client) - || !IsPlayerValidMoveType(client) - || !allowMidair && (!Movement_GetOnGround(client) || JustLanded(client)) - || allowMidair && !Movement_GetOnGround(client) && (!GOKZ_GetValidJump(client) || GOKZ_GetHitPerf(client)) - || (GOKZ_GetTimerRunning(client) && GOKZ_GetCourse(client) != course)) - { - return false; - } - - // Call Pre Forward - Action result; - Call_GOKZ_OnTimerStart(client, course, result); - if (result != Plugin_Continue) - { - return false; - } - - // Prevent noclip exploit - SetEntProp(client, Prop_Send, "m_CollisionGroup", GOKZ_COLLISION_GROUP_STANDARD); - - // Start Timer - currentTime[client] = 0.0; - timerRunning[client] = true; - currentCourse[client] = course; - lastStartMode[client] = GOKZ_GetCoreOption(client, Option_Mode); - validTime[client] = true; - if (playSound) - { - PlayTimerStartSound(client); - } - - // Call Post Forward - Call_GOKZ_OnTimerStart_Post(client, course); - - return true; -} - -bool TimerEnd(int client, int course) -{ - if (!IsPlayerAlive(client)) - { - return false; - } - - if (!timerRunning[client] || course != currentCourse[client]) - { - PlayTimerFalseEndSound(client); - lastFalseEndTime[client] = GetGameTime(); - return false; - } - - float time = GetCurrentTime(client); - int teleportsUsed = GetTeleportCount(client); - - // Call Pre Forward - Action result; - Call_GOKZ_OnTimerEnd(client, course, time, teleportsUsed, result); - if (result != Plugin_Continue) - { - return false; - } - - if (!validTime[client]) - { - PlayTimerFalseEndSound(client); - lastFalseEndTime[client] = GetGameTime(); - TimerStop(client, false); - return false; - } - // End Timer - timerRunning[client] = false; - lastEndTime[client] = GetGameTime(); - PlayTimerEndSound(client); - - if (!IsFakeClient(client)) - { - // Print end timer message - Call_GOKZ_OnTimerEndMessage(client, course, time, teleportsUsed, result); - if (result == Plugin_Continue) - { - PrintEndTimeString(client); - } - } - - // Call Post Forward - Call_GOKZ_OnTimerEnd_Post(client, course, time, teleportsUsed); - - return true; -} - -bool TimerStop(int client, bool playSound = true) -{ - if (!timerRunning[client]) - { - return false; - } - - timerRunning[client] = false; - if (playSound) - { - PlayTimerStopSound(client); - } - - Call_GOKZ_OnTimerStopped(client); - - return true; -} - -void TimerStopAll(bool playSound = true) -{ - for (int client = 1; client <= MaxClients; client++) - { - if (IsValidClient(client)) - { - TimerStop(client, playSound); - } - } -} - -void PlayTimerStartSound(int client) -{ - if (GetGameTime() - lastStartSoundTime[client] > GOKZ_TIMER_SOUND_COOLDOWN) - { - GOKZ_EmitSoundToClient(client, gC_ModeStartSounds[GOKZ_GetCoreOption(client, Option_Mode)], _, "Timer Start"); - GOKZ_EmitSoundToClientSpectators(client, gC_ModeStartSounds[GOKZ_GetCoreOption(client, Option_Mode)], _, "Timer Start"); - lastStartSoundTime[client] = GetGameTime(); - } -} - -void InvalidateRun(int client) -{ - if (validTime[client]) - { - validTime[client] = false; - Call_GOKZ_OnRunInvalidated(client); - } -} - -// =====[ EVENTS ]===== - -void OnClientPutInServer_Timer(int client) -{ - timerRunning[client] = false; - currentTime[client] = 0.0; - currentCourse[client] = 0; - lastEndTime[client] = 0.0; - lastFalseEndTime[client] = 0.0; - lastStartSoundTime[client] = 0.0; - lastStartMode[client] = MODE_COUNT; // So it won't equal any mode -} - -void OnPlayerRunCmdPost_Timer(int client) -{ - if (IsPlayerAlive(client) && GetTimerRunning(client) && !GetPaused(client)) - { - currentTime[client] += GetTickInterval(); - } -} - -void OnChangeMovetype_Timer(int client, MoveType newMovetype) -{ - if (!IsValidMovetype(newMovetype)) - { - if (TimerStop(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Timer Stopped (Noclipped)"); - } - } -} - -void OnTeleportToStart_Timer(int client) -{ - if (GetCurrentMapPrefix() == MapPrefix_KZPro) - { - TimerStop(client, false); - } -} - -void OnClientDisconnect_Timer(int client) -{ - TimerStop(client); -} - -void OnPlayerDeath_Timer(int client) -{ - TimerStop(client); -} - -void OnOptionChanged_Timer(int client, Option option) -{ - if (option == Option_Mode) - { - if (TimerStop(client)) - { - GOKZ_PrintToChat(client, true, "%t", "Timer Stopped (Changed Mode)"); - } - } -} - -void OnRoundStart_Timer() -{ - TimerStopAll(); -} - - - -// =====[ PRIVATE ]===== - -static bool IsPlayerValidMoveType(int client) -{ - return IsValidMovetype(Movement_GetMovetype(client)); -} - -static bool IsValidMovetype(MoveType movetype) -{ - return movetype == MOVETYPE_WALK - || movetype == MOVETYPE_LADDER - || movetype == MOVETYPE_NONE - || movetype == MOVETYPE_OBSERVER; -} - -static bool JustTeleported(int client) -{ - return gB_OriginTeleported[client] || gB_VelocityTeleported[client] - || gI_CmdNum[client] - gI_TeleportCmdNum[client] <= GOKZ_TIMER_START_GROUND_TICKS; -} - -static bool JustLanded(int client) -{ - return !gB_OldOnGround[client] - || gI_CmdNum[client] - Movement_GetLandingCmdNum(client) <= GOKZ_TIMER_START_NO_TELEPORT_TICKS; -} - -static bool JustStartedTimer(int client) -{ - return timerRunning[client] && GetCurrentTime(client) < EPSILON; -} - -static bool JustEndedTimer(int client) -{ - return GetGameTime() - lastEndTime[client] < 1.0; -} - -static void PlayTimerEndSound(int client) -{ - GOKZ_EmitSoundToClient(client, gC_ModeEndSounds[GOKZ_GetCoreOption(client, Option_Mode)], _, "Timer End"); - GOKZ_EmitSoundToClientSpectators(client, gC_ModeEndSounds[GOKZ_GetCoreOption(client, Option_Mode)], _, "Timer End"); -} - -static void PlayTimerFalseEndSound(int client) -{ - if (!JustEndedTimer(client) - && (GetGameTime() - lastFalseEndTime[client]) > GOKZ_TIMER_SOUND_COOLDOWN) - { - GOKZ_EmitSoundToClient(client, gC_ModeFalseEndSounds[GOKZ_GetCoreOption(client, Option_Mode)], _, "Timer False End"); - GOKZ_EmitSoundToClientSpectators(client, gC_ModeFalseEndSounds[GOKZ_GetCoreOption(client, Option_Mode)], _, "Timer False End"); - } -} - -static void PlayTimerStopSound(int client) -{ - GOKZ_EmitSoundToClient(client, GOKZ_SOUND_TIMER_STOP, _, "Timer Stop"); - GOKZ_EmitSoundToClientSpectators(client, GOKZ_SOUND_TIMER_STOP, _, "Timer Stop"); -} - -static void PrintEndTimeString(int client) -{ - if (GetCurrentCourse(client) == 0) - { - switch (GetCurrentTimeType(client)) - { - case TimeType_Nub: - { - GOKZ_PrintToChatAll(true, "%t", "Beat Map (NUB)", - client, - GOKZ_FormatTime(GetCurrentTime(client)), - gC_ModeNamesShort[GOKZ_GetCoreOption(client, Option_Mode)]); - } - case TimeType_Pro: - { - GOKZ_PrintToChatAll(true, "%t", "Beat Map (PRO)", - client, - GOKZ_FormatTime(GetCurrentTime(client)), - gC_ModeNamesShort[GOKZ_GetCoreOption(client, Option_Mode)]); - } - } - } - else - { - switch (GetCurrentTimeType(client)) - { - case TimeType_Nub: - { - GOKZ_PrintToChatAll(true, "%t", "Beat Bonus (NUB)", - client, - currentCourse[client], - GOKZ_FormatTime(GetCurrentTime(client)), - gC_ModeNamesShort[GOKZ_GetCoreOption(client, Option_Mode)]); - } - case TimeType_Pro: - { - GOKZ_PrintToChatAll(true, "%t", "Beat Bonus (PRO)", - client, - currentCourse[client], - GOKZ_FormatTime(GetCurrentTime(client)), - gC_ModeNamesShort[GOKZ_GetCoreOption(client, Option_Mode)]); - } - } - } -}
\ No newline at end of file diff --git a/sourcemod/scripting/gokz-core/timer/virtual_buttons.sp b/sourcemod/scripting/gokz-core/timer/virtual_buttons.sp deleted file mode 100644 index aa88a9d..0000000 --- a/sourcemod/scripting/gokz-core/timer/virtual_buttons.sp +++ /dev/null @@ -1,322 +0,0 @@ -/* - Most commonly referred to in the KZ community as timer tech. - Lets players press 'virtual' start and end buttons without looking. -*/ - - - -static int beamSprite; -static int haloSprite; -static float lastUsePressTime[MAXPLAYERS + 1]; -static int lastTeleportTick[MAXPLAYERS + 1]; -static bool startedTimerLastTick[MAXPLAYERS + 1]; -static bool onlyNaturalButtonPressed[MAXPLAYERS + 1]; -static int startTimerButtonPressTick[MAXPLAYERS + 1]; -static bool hasEndedTimerSincePressingUse[MAXPLAYERS + 1]; -static bool hasTeleportedSincePressingUse[MAXPLAYERS + 1]; -static bool hasVirtualStartButton[MAXPLAYERS + 1]; -static bool hasVirtualEndButton[MAXPLAYERS + 1]; -static bool wasInEndZone[MAXPLAYERS + 1]; -static float virtualStartOrigin[MAXPLAYERS + 1][3]; -static float virtualEndOrigin[MAXPLAYERS + 1][3]; -static int virtualStartCourse[MAXPLAYERS + 1]; -static int virtualEndCourse[MAXPLAYERS + 1]; -static bool virtualButtonsLocked[MAXPLAYERS + 1]; - - - -// =====[ PUBLIC ]===== - -bool GetHasVirtualStartButton(int client) -{ - return hasVirtualStartButton[client]; -} - -bool GetHasVirtualEndButton(int client) -{ - return hasVirtualEndButton[client]; -} - -bool ToggleVirtualButtonsLock(int client) -{ - virtualButtonsLocked[client] = !virtualButtonsLocked[client]; - return virtualButtonsLocked[client]; -} - -void LockVirtualButtons(int client) -{ - virtualButtonsLocked[client] = true; -} - -int GetVirtualButtonPosition(int client, float position[3], bool isStart) -{ - if (isStart && hasVirtualStartButton[client]) - { - position = virtualStartOrigin[client]; - return virtualStartCourse[client]; - } - else if (!isStart && hasVirtualEndButton[client]) - { - position = virtualEndOrigin[client]; - return virtualEndCourse[client]; - } - - return -1; -} - -void SetVirtualButtonPosition(int client, float position[3], int course, bool isStart) -{ - if (isStart) - { - virtualStartCourse[client] = course; - virtualStartOrigin[client] = position; - hasVirtualStartButton[client] = true; - } - else - { - virtualEndCourse[client] = course; - virtualEndOrigin[client] = position; - hasVirtualEndButton[client] = true; - } -} - -void ResetVirtualButtonPosition(int client, bool isStart) -{ - if (isStart) - { - virtualStartCourse[client] = -1; - virtualStartOrigin[client] = {0.0, 0.0, 0.0}; - hasVirtualStartButton[client] = false; - } - else - { - virtualEndCourse[client] = -1; - virtualEndOrigin[client] = {0.0, 0.0, 0.0}; - hasVirtualEndButton[client] = false; - } -} - -// =====[ EVENTS ]===== - -void OnMapStart_VirtualButtons() -{ - beamSprite = PrecacheModel("materials/sprites/laserbeam.vmt"); - haloSprite = PrecacheModel("materials/sprites/glow01.vmt"); -} - -void OnClientPutInServer_VirtualButtons(int client) -{ - startedTimerLastTick[client] = false; - hasVirtualEndButton[client] = false; - hasVirtualStartButton[client] = false; - virtualButtonsLocked[client] = false; - onlyNaturalButtonPressed[client] = false; - wasInEndZone[client] = false; - startTimerButtonPressTick[client] = 0; -} - -void OnStartButtonPress_VirtualButtons(int client, int course) -{ - if (!virtualButtonsLocked[client] && - lastTeleportTick[client] + GOKZ_TIMER_START_NO_TELEPORT_TICKS < GetGameTickCount()) - { - Movement_GetOrigin(client, virtualStartOrigin[client]); - virtualStartCourse[client] = course; - hasVirtualStartButton[client] = true; - startTimerButtonPressTick[client] = GetGameTickCount(); - } -} - -void OnEndButtonPress_VirtualButtons(int client, int course) -{ - // Prevent setting end virtual button to where it would usually be unreachable - if (IsPlayerStuck(client)) - { - return; - } - - if (!virtualButtonsLocked[client] && - lastTeleportTick[client] + GOKZ_TIMER_START_NO_TELEPORT_TICKS < GetGameTickCount()) - { - Movement_GetOrigin(client, virtualEndOrigin[client]); - virtualEndCourse[client] = course; - hasVirtualEndButton[client] = true; - } -} - -void OnPlayerRunCmdPost_VirtualButtons(int client, int buttons, int cmdnum) -{ - CheckForAndHandleUsage(client, buttons); - UpdateIndicators(client, cmdnum); -} - -void OnCountedTeleport_VirtualButtons(int client) -{ - hasTeleportedSincePressingUse[client] = true; -} - -void OnTeleport_DelayVirtualButtons(int client) -{ - lastTeleportTick[client] = GetGameTickCount(); -} - - - -// =====[ PRIVATE ]===== - -static void CheckForAndHandleUsage(int client, int buttons) -{ - if (buttons & IN_USE && !(gI_OldButtons[client] & IN_USE)) - { - lastUsePressTime[client] = GetGameTime(); - hasEndedTimerSincePressingUse[client] = false; - hasTeleportedSincePressingUse[client] = false; - onlyNaturalButtonPressed[client] = startTimerButtonPressTick[client] == GetGameTickCount(); - } - - bool useCheck = PassesUseCheck(client); - - // Start button - if ((useCheck || GOKZ_GetCoreOption(client, Option_TimerButtonZoneType) == TimerButtonZoneType_BothZones) - && GetHasVirtualStartButton(client) && InRangeOfVirtualStart(client) && CanReachVirtualStart(client)) - { - if (TimerStart(client, virtualStartCourse[client], .playSound = false)) - { - startedTimerLastTick[client] = true; - OnVirtualStartButtonPress_Teleports(client); - } - } - else if (startedTimerLastTick[client]) - { - // Without that check you get two sounds when pressing the natural timer button - if (!onlyNaturalButtonPressed[client]) - { - PlayTimerStartSound(client); - } - onlyNaturalButtonPressed[client] = false; - startedTimerLastTick[client] = false; - } - - // End button - if ((useCheck || GOKZ_GetCoreOption(client, Option_TimerButtonZoneType) != TimerButtonZoneType_BothButtons) - && GetHasVirtualEndButton(client) && InRangeOfVirtualEnd(client) && CanReachVirtualEnd(client)) - { - if (!wasInEndZone[client]) - { - TimerEnd(client, virtualEndCourse[client]); - hasEndedTimerSincePressingUse[client] = true; // False end counts as well - wasInEndZone[client] = true; - } - } - else - { - wasInEndZone[client] = false; - } -} - -static bool PassesUseCheck(int client) -{ - if (GetGameTime() - lastUsePressTime[client] < GOKZ_VIRTUAL_BUTTON_USE_DETECTION_TIME + EPSILON - && !hasEndedTimerSincePressingUse[client] - && !hasTeleportedSincePressingUse[client]) - { - return true; - } - - return false; -} - -bool InRangeOfVirtualStart(int client) -{ - return InRangeOfButton(client, virtualStartOrigin[client]); -} - -static bool InRangeOfVirtualEnd(int client) -{ - return InRangeOfButton(client, virtualEndOrigin[client]); -} - -static bool InRangeOfButton(int client, const float buttonOrigin[3]) -{ - float origin[3]; - Movement_GetOrigin(client, origin); - float distanceToButton = GetVectorDistance(origin, buttonOrigin); - return distanceToButton <= gF_ModeVirtualButtonRanges[GOKZ_GetCoreOption(client, Option_Mode)]; -} - -bool CanReachVirtualStart(int client) -{ - return CanReachButton(client, virtualStartOrigin[client]); -} - -static bool CanReachVirtualEnd(int client) -{ - return CanReachButton(client, virtualEndOrigin[client]); -} - -static bool CanReachButton(int client, const float buttonOrigin[3]) -{ - float origin[3]; - Movement_GetOrigin(client, origin); - Handle trace = TR_TraceRayFilterEx(origin, buttonOrigin, MASK_PLAYERSOLID, RayType_EndPoint, TraceEntityFilterPlayers); - bool didHit = TR_DidHit(trace); - delete trace; - return !didHit; -} - - - -// ===== [ INDICATOR ] ===== - -static void UpdateIndicators(int client, int cmdnum) -{ - if (cmdnum % 128 != 0 || !IsPlayerAlive(client) - || GOKZ_GetCoreOption(client, Option_VirtualButtonIndicators) == VirtualButtonIndicators_Disabled) - { - return; - } - - if (hasVirtualStartButton[client]) - { - DrawIndicator(client, virtualStartOrigin[client], { 0, 255, 0, 255 } ); - } - - if (hasVirtualEndButton[client]) - { - DrawIndicator(client, virtualEndOrigin[client], { 255, 0, 0, 255 } ); - } -} - -static void DrawIndicator(int client, const float origin[3], const int colour[4]) -{ - float radius = gF_ModeVirtualButtonRanges[GOKZ_GetCoreOption(client, Option_Mode)]; - if (radius <= EPSILON) // Don't draw circle of radius 0 - { - return; - } - - float x, y, start[3], end[3]; - - // Create the start position for the first part of the beam - start[0] = origin[0] + radius; - start[1] = origin[1]; - start[2] = origin[2]; - - for (int i = 1; i <= 31; i++) // Circle is broken into 31 segments - { - float angle = 2 * PI / 31 * i; - x = radius * Cosine(angle); - y = radius * Sine(angle); - - end[0] = origin[0] + x; - end[1] = origin[1] + y; - end[2] = origin[2]; - - TE_SetupBeamPoints(start, end, beamSprite, haloSprite, 0, 0, 0.97, 0.2, 0.2, 0, 0.0, colour, 0); - TE_SendToClient(client); - - start[0] = end[0]; - start[1] = end[1]; - start[2] = end[2]; - } -} diff --git a/sourcemod/scripting/gokz-core/triggerfix.sp b/sourcemod/scripting/gokz-core/triggerfix.sp deleted file mode 100644 index 424928d..0000000 --- a/sourcemod/scripting/gokz-core/triggerfix.sp +++ /dev/null @@ -1,622 +0,0 @@ - - -// Credits: -// RNGFix made by rio https://github.com/jason-e/rngfix - - -// Engine constants, NOT settings (do not change) -#define LAND_HEIGHT 2.0 // Maximum height above ground at which you can "land" -#define MIN_STANDABLE_ZNRM 0.7 // Minimum surface normal Z component of a walkable surface - -static int processMovementTicks[MAXPLAYERS+1]; -static float playerFrameTime[MAXPLAYERS+1]; - -static bool touchingTrigger[MAXPLAYERS+1][2048]; -static int triggerTouchFired[MAXPLAYERS+1][2048]; -static int lastGroundEnt[MAXPLAYERS + 1]; -static bool duckedLastTick[MAXPLAYERS + 1]; -static bool mapTeleportedSequentialTicks[MAXPLAYERS+1]; -static bool jumpBugged[MAXPLAYERS + 1]; -static float jumpBugOrigin[MAXPLAYERS + 1][3]; - -static ConVar cvGravity; - -static Handle acceptInputHookPre; -static Handle processMovementHookPre; -static Address serverGameEnts; -static Handle markEntitiesAsTouching; -static Handle passesTriggerFilters; - -public void OnPluginStart_Triggerfix() -{ - HookEvent("player_jump", Event_PlayerJump); - - cvGravity = FindConVar("sv_gravity"); - if (cvGravity == null) - { - SetFailState("Could not find sv_gravity"); - } - - GameData gamedataConf = LoadGameConfigFile("gokz-core.games"); - if (gamedataConf == null) - { - SetFailState("Failed to load gokz-core gamedata"); - } - - // PassesTriggerFilters - StartPrepSDKCall(SDKCall_Entity); - if (!PrepSDKCall_SetFromConf(gamedataConf, SDKConf_Virtual, "CBaseTrigger::PassesTriggerFilters")) - { - SetFailState("Failed to get CBaseTrigger::PassesTriggerFilters offset"); - } - PrepSDKCall_SetReturnInfo(SDKType_Bool, SDKPass_Plain); - PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer); - passesTriggerFilters = EndPrepSDKCall(); - - if (passesTriggerFilters == null) SetFailState("Unable to prepare SDKCall for CBaseTrigger::PassesTriggerFilters"); - - // CreateInterface - // Thanks SlidyBat and ici - StartPrepSDKCall(SDKCall_Static); - if (!PrepSDKCall_SetFromConf(gamedataConf, SDKConf_Signature, "CreateInterface")) - { - SetFailState("Failed to get CreateInterface"); - } - PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer); - PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Pointer, VDECODE_FLAG_ALLOWNULL); - PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain); - Handle CreateInterface = EndPrepSDKCall(); - - if (CreateInterface == null) - { - SetFailState("Unable to prepare SDKCall for CreateInterface"); - } - - char interfaceName[64]; - - // ProcessMovement - if (!GameConfGetKeyValue(gamedataConf, "IGameMovement", interfaceName, sizeof(interfaceName))) - { - SetFailState("Failed to get IGameMovement interface name"); - } - Address IGameMovement = SDKCall(CreateInterface, interfaceName, 0); - if (!IGameMovement) - { - SetFailState("Failed to get IGameMovement pointer"); - } - - int offset = GameConfGetOffset(gamedataConf, "ProcessMovement"); - if (offset == -1) - { - SetFailState("Failed to get ProcessMovement offset"); - } - - processMovementHookPre = DHookCreate(offset, HookType_Raw, ReturnType_Void, ThisPointer_Ignore, DHook_ProcessMovementPre); - DHookAddParam(processMovementHookPre, HookParamType_CBaseEntity); - DHookAddParam(processMovementHookPre, HookParamType_ObjectPtr); - DHookRaw(processMovementHookPre, false, IGameMovement); - - // MarkEntitiesAsTouching - if (!GameConfGetKeyValue(gamedataConf, "IServerGameEnts", interfaceName, sizeof(interfaceName))) - { - SetFailState("Failed to get IServerGameEnts interface name"); - } - serverGameEnts = SDKCall(CreateInterface, interfaceName, 0); - if (!serverGameEnts) - { - SetFailState("Failed to get IServerGameEnts pointer"); - } - - StartPrepSDKCall(SDKCall_Raw); - if (!PrepSDKCall_SetFromConf(gamedataConf, SDKConf_Virtual, "IServerGameEnts::MarkEntitiesAsTouching")) - { - SetFailState("Failed to get IServerGameEnts::MarkEntitiesAsTouching offset"); - } - PrepSDKCall_AddParameter(SDKType_Edict, SDKPass_Pointer); - PrepSDKCall_AddParameter(SDKType_Edict, SDKPass_Pointer); - markEntitiesAsTouching = EndPrepSDKCall(); - - if (markEntitiesAsTouching == null) - { - SetFailState("Unable to prepare SDKCall for IServerGameEnts::MarkEntitiesAsTouching"); - } - - gamedataConf = LoadGameConfigFile("sdktools.games/engine.csgo"); - offset = gamedataConf.GetOffset("AcceptInput"); - if (offset == -1) - { - SetFailState("Failed to get AcceptInput offset"); - } - - acceptInputHookPre = DHookCreate(offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, DHooks_AcceptInput); - DHookAddParam(acceptInputHookPre, HookParamType_CharPtr); - DHookAddParam(acceptInputHookPre, HookParamType_CBaseEntity); - DHookAddParam(acceptInputHookPre, HookParamType_CBaseEntity); - //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20 - DHookAddParam(acceptInputHookPre, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP); - DHookAddParam(acceptInputHookPre, HookParamType_Int); - - delete CreateInterface; - delete gamedataConf; - - if (gB_LateLoad) - { - for (int client = 1; client <= MaxClients; client++) - { - if (IsClientInGame(client)) OnClientPutInServer(client); - } - - char classname[64]; - for (int entity = MaxClients+1; entity < sizeof(touchingTrigger[]); entity++) - { - if (!IsValidEntity(entity)) continue; - GetEntPropString(entity, Prop_Data, "m_iClassname", classname, sizeof(classname)); - HookTrigger(entity, classname); - } - } -} - -public void OnEntityCreated_Triggerfix(int entity, const char[] classname) -{ - if (entity >= sizeof(touchingTrigger[])) - { - return; - } - HookTrigger(entity, classname); -} - -public void OnClientConnected_Triggerfix(int client) -{ - processMovementTicks[client] = 0; - for (int i = 0; i < sizeof(touchingTrigger[]); i++) - { - touchingTrigger[client][i] = false; - triggerTouchFired[client][i] = 0; - } -} - -public void OnClientPutInServer_Triggerfix(int client) -{ - SDKHook(client, SDKHook_PostThink, Hook_PlayerPostThink); - DHookEntity(acceptInputHookPre, false, client); -} - -public void OnGameFrame_Triggerfix() -{ - // Loop through all the players and make sure that triggers that are supposed to be fired but weren't now - // get fired properly. - // This must be run OUTSIDE of usercmd, because sometimes usercmd gets delayed heavily. - for (int client = 1; client <= MaxClients; client++) - { - if (IsValidClient(client) && IsPlayerAlive(client) && !CheckWater(client) && - (GetEntityMoveType(client) == MOVETYPE_WALK || GetEntityMoveType(client) == MOVETYPE_LADDER)) - { - DoTriggerFix(client); - - // Reset the Touch tracking. - // We save a bit of performance by putting this inside the loop - // Even if triggerTouchFired is not correct, touchingTrigger still is. - // That should prevent DoTriggerFix from activating the wrong triggers. - // Plus, players respawn where they previously are as well with a timer on, - // so this should not be a big problem. - for (int trigger = 0; trigger < sizeof(triggerTouchFired[]); trigger++) - { - triggerTouchFired[client][trigger] = 0; - } - } - } -} - -void OnPlayerRunCmd_Triggerfix(int client) -{ - // Reset the Touch tracking. - // While this is mostly unnecessary, it can also happen that the server runs multiple ticks of player movement at once, - // therefore the triggers need to be checked again. - for (int trigger = 0; trigger < sizeof(triggerTouchFired[]); trigger++) - { - triggerTouchFired[client][trigger] = 0; - } -} - -static void Event_PlayerJump(Event event, const char[] name, bool dontBroadcast) -{ - int client = GetClientOfUserId(event.GetInt("userid")); - - jumpBugged[client] = !!lastGroundEnt[client]; - if (jumpBugged[client]) - { - GetClientAbsOrigin(client, jumpBugOrigin[client]); - // if player's origin is still in the ducking position then adjust for that. - if (duckedLastTick[client] && !Movement_GetDucking(client)) - { - jumpBugOrigin[client][2] -= 9.0; - } - } -} - -static Action Hook_TriggerStartTouch(int entity, int other) -{ - if (1 <= other <= MaxClients) - { - touchingTrigger[other][entity] = true; - } - - return Plugin_Continue; -} - -static Action Hook_TriggerEndTouch(int entity, int other) -{ - if (1 <= other <= MaxClients) - { - touchingTrigger[other][entity] = false; - } - return Plugin_Continue; -} - -static Action Hook_TriggerTouch(int entity, int other) -{ - if (1 <= other <= MaxClients) - { - triggerTouchFired[other][entity]++; - } - return Plugin_Continue; -} - -static MRESReturn DHook_ProcessMovementPre(Handle hParams) -{ - int client = DHookGetParam(hParams, 1); - - processMovementTicks[client]++; - playerFrameTime[client] = GetTickInterval() * GetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue"); - mapTeleportedSequentialTicks[client] = false; - - if (IsPlayerAlive(client)) - { - if (GetEntityMoveType(client) == MOVETYPE_WALK - && !CheckWater(client)) - { - lastGroundEnt[client] = GetEntPropEnt(client, Prop_Data, "m_hGroundEntity"); - } - duckedLastTick[client] = Movement_GetDucking(client); - } - - return MRES_Ignored; -} - -static MRESReturn DHooks_AcceptInput(int client, DHookReturn hReturn, DHookParam hParams) -{ - if (!IsValidClient(client) || !IsPlayerAlive(client) || CheckWater(client) || - (GetEntityMoveType(client) != MOVETYPE_WALK && GetEntityMoveType(client) != MOVETYPE_LADDER)) - { - return MRES_Ignored; - } - - // Get args - static char param[64]; - static char command[64]; - DHookGetParamString(hParams, 1, command, sizeof(command)); - if (StrEqual(command, "AddOutput")) - { - DHookGetParamObjectPtrString(hParams, 4, 0, ObjectValueType_String, param, sizeof(param)); - char kv[16]; - SplitString(param, " ", kv, sizeof(kv)); - // KVs are case insensitive. - // Any of these inputs can change the filter behavior. - if (StrEqual(kv[0], "targetname", false) || StrEqual(kv[0], "teamnumber", false) || StrEqual(kv[0], "classname", false) || StrEqual(command, "ResponseContext", false)) - { - DoTriggerFix(client, true); - } - } - else if (StrEqual(command, "AddContext") || StrEqual(command, "RemoveContext") || StrEqual(command, "ClearContext")) - { - DoTriggerFix(client, true); - } - return MRES_Ignored; -} - -static bool DoTriggerFix(int client, bool filterFix = false) -{ - // Adapted from DoTriggerjumpFix right below. - float landingMins[3], landingMaxs[3]; - float origin[3]; - - GetEntPropVector(client, Prop_Data, "m_vecAbsOrigin", origin); - GetEntPropVector(client, Prop_Data, "m_vecMins", landingMins); - GetEntPropVector(client, Prop_Data, "m_vecMaxs", landingMaxs); - - ArrayList triggers = new ArrayList(); - // Get a list of triggers that we are touching now. - - TR_EnumerateEntitiesHull(origin, origin, landingMins, landingMaxs, true, AddTrigger, triggers); - - bool didSomething = false; - - for (int i = 0; i < triggers.Length; i++) - { - int trigger = triggers.Get(i); - if (!touchingTrigger[client][trigger]) - { - // Normally this wouldn't happen, because the trigger should be colliding with the player's hull if it gets here. - continue; - } - char className[64]; - GetEntityClassname(trigger, className, sizeof(className)); - if (StrEqual(className, "trigger_push")) - { - // Completely ignore push triggers. - continue; - } - if (filterFix && SDKCall(passesTriggerFilters, trigger, client) && triggerTouchFired[client][trigger] < GOKZ_MAX_RETOUCH_TRIGGER_COUNT) - { - // MarkEntitiesAsTouching always fires the Touch function even if it was already fired this tick. - SDKCall(markEntitiesAsTouching, serverGameEnts, client, trigger); - - // Player properties might be changed right after this so it will need to be triggered again. - // Triggers changing this filter will loop onto itself infintely so we need to avoid that. - triggerTouchFired[client][trigger]++; - didSomething = true; - } - else if (!triggerTouchFired[client][trigger]) - { - // If the player is still touching the trigger on this tick, and Touch was not called for whatever reason - // in the last tick, we make sure that it is called now. - SDKCall(markEntitiesAsTouching, serverGameEnts, client, trigger); - triggerTouchFired[client][trigger]++; - didSomething = true; - } - } - - delete triggers; - - return didSomething; -} - -static bool DoTriggerjumpFix(int client, const float landingPoint[3], const float landingMins[3], const float landingMaxs[3]) -{ - // It's possible to land above a trigger but also in another trigger_teleport, have the teleport move you to - // another location, and then the trigger jumping fix wouldn't fire the other trigger you technically landed above, - // but I can't imagine a mapper would ever actually stack triggers like that. - - float origin[3]; - GetEntPropVector(client, Prop_Data, "m_vecAbsOrigin", origin); - - float landingMaxsBelow[3]; - landingMaxsBelow[0] = landingMaxs[0]; - landingMaxsBelow[1] = landingMaxs[1]; - landingMaxsBelow[2] = origin[2] - landingPoint[2]; - - ArrayList triggers = new ArrayList(); - - // Find triggers that are between us and the ground (using the bounding box quadrant we landed with if applicable). - // This will fail on triggers thinner than 0.03125 unit thick, but it's highly unlikely that a mapper would put a trigger that thin. - TR_EnumerateEntitiesHull(landingPoint, landingPoint, landingMins, landingMaxsBelow, true, AddTrigger, triggers); - - bool didSomething = false; - - for (int i = 0; i < triggers.Length; i++) - { - int trigger = triggers.Get(i); - - // MarkEntitiesAsTouching always fires the Touch function even if it was already fired this tick. - // In case that could cause side-effects, manually keep track of triggers we are actually touching - // and don't re-touch them. - if (touchingTrigger[client][trigger]) - { - continue; - } - - SDKCall(markEntitiesAsTouching, serverGameEnts, client, trigger); - didSomething = true; - } - - delete triggers; - - return didSomething; -} - -// PostThink works a little better than a ProcessMovement post hook because we need to wait for ProcessImpacts (trigger activation) -static void Hook_PlayerPostThink(int client) -{ - if (!IsPlayerAlive(client) - || GetEntityMoveType(client) != MOVETYPE_WALK - || CheckWater(client)) - { - return; - } - - bool landed = (GetEntPropEnt(client, Prop_Data, "m_hGroundEntity") != -1 - && lastGroundEnt[client] == -1) - || jumpBugged[client]; - - float landingMins[3], landingMaxs[3], landingPoint[3]; - - // Get info about the ground we landed on (if we need to do landing fixes). - if (landed) - { - float origin[3], nrm[3], velocity[3]; - GetEntPropVector(client, Prop_Data, "m_vecAbsOrigin", origin); - GetEntPropVector(client, Prop_Data, "m_vecVelocity", velocity); - - if (jumpBugged[client]) - { - origin = jumpBugOrigin[client]; - } - - GetEntPropVector(client, Prop_Data, "m_vecMins", landingMins); - GetEntPropVector(client, Prop_Data, "m_vecMaxs", landingMaxs); - - float originBelow[3]; - originBelow[0] = origin[0]; - originBelow[1] = origin[1]; - originBelow[2] = origin[2] - LAND_HEIGHT; - - TR_TraceHullFilter(origin, originBelow, landingMins, landingMaxs, MASK_PLAYERSOLID, PlayerFilter); - - if (!TR_DidHit()) - { - // This should never happen, since we know we are on the ground. - landed = false; - } - else - { - TR_GetPlaneNormal(null, nrm); - - if (nrm[2] < MIN_STANDABLE_ZNRM) - { - // This is rare, and how the incline fix should behave isn't entirely clear because maybe we should - // collide with multiple faces at once in this case, but let's just get the ground we officially - // landed on and use that for our ground normal. - - // landingMins and landingMaxs will contain the final values used to find the ground after returning. - if (TracePlayerBBoxForGround(origin, originBelow, landingMins, landingMaxs)) - { - TR_GetPlaneNormal(null, nrm); - } - else - { - // This should also never happen. - landed = false; - } - } - - TR_GetEndPosition(landingPoint); - } - } - - // reset it here because we don't need it again - jumpBugged[client] = false; - - // Must use TR_DidHit because if the unduck origin is closer than 0.03125 units from the ground, - // the trace fraction would return 0.0. - if (landed && TR_DidHit()) - { - DoTriggerjumpFix(client, landingPoint, landingMins, landingMaxs); - // Check if a trigger we just touched put us in the air (probably due to a teleport). - if (GetEntityFlags(client) & FL_ONGROUND == 0) - { - landed = false; - } - } -} - -static bool PlayerFilter(int entity, int mask) -{ - return !(1 <= entity <= MaxClients); -} - -static void HookTrigger(int entity, const char[] classname) -{ - if (StrContains(classname, "trigger_") != -1) - { - SDKHook(entity, SDKHook_StartTouchPost, Hook_TriggerStartTouch); - SDKHook(entity, SDKHook_EndTouchPost, Hook_TriggerEndTouch); - SDKHook(entity, SDKHook_TouchPost, Hook_TriggerTouch); - } -} - -static bool CheckWater(int client) -{ - // The cached water level is updated multiple times per tick, including after movement happens, - // so we can just check the cached value here. - return GetEntProp(client, Prop_Data, "m_nWaterLevel") > 1; -} - -public bool AddTrigger(int entity, ArrayList triggers) -{ - TR_ClipCurrentRayToEntity(MASK_ALL, entity); - if (TR_DidHit()) - { - triggers.Push(entity); - } - - return true; -} - -static bool TracePlayerBBoxForGround(const float origin[3], const float originBelow[3], float mins[3], float maxs[3]) -{ - // See CGameMovement::TracePlayerBBoxForGround() - - float origMins[3], origMaxs[3]; - origMins = mins; - origMaxs = maxs; - - float nrm[3]; - - mins = origMins; - - // -x -y - maxs[0] = origMaxs[0] > 0.0 ? 0.0 : origMaxs[0]; - maxs[1] = origMaxs[1] > 0.0 ? 0.0 : origMaxs[1]; - maxs[2] = origMaxs[2]; - - TR_TraceHullFilter(origin, originBelow, mins, maxs, MASK_PLAYERSOLID, PlayerFilter); - - if (TR_DidHit()) - { - TR_GetPlaneNormal(null, nrm); - if (nrm[2] >= MIN_STANDABLE_ZNRM) - { - return true; - } - } - - // +x +y - mins[0] = origMins[0] < 0.0 ? 0.0 : origMins[0]; - mins[1] = origMins[1] < 0.0 ? 0.0 : origMins[1]; - mins[2] = origMins[2]; - - maxs = origMaxs; - - TR_TraceHullFilter(origin, originBelow, mins, maxs, MASK_PLAYERSOLID, PlayerFilter); - - if (TR_DidHit()) - { - TR_GetPlaneNormal(null, nrm); - if (nrm[2] >= MIN_STANDABLE_ZNRM) - { - return true; - } - } - - // -x +y - mins[0] = origMins[0]; - mins[1] = origMins[1] < 0.0 ? 0.0 : origMins[1]; - mins[2] = origMins[2]; - - maxs[0] = origMaxs[0] > 0.0 ? 0.0 : origMaxs[0]; - maxs[1] = origMaxs[1]; - maxs[2] = origMaxs[2]; - - TR_TraceHullFilter(origin, originBelow, mins, maxs, MASK_PLAYERSOLID, PlayerFilter); - - if (TR_DidHit()) - { - TR_GetPlaneNormal(null, nrm); - if (nrm[2] >= MIN_STANDABLE_ZNRM) - { - return true; - } - } - - // +x -y - mins[0] = origMins[0] < 0.0 ? 0.0 : origMins[0]; - mins[1] = origMins[1]; - mins[2] = origMins[2]; - - maxs[0] = origMaxs[0]; - maxs[1] = origMaxs[1] > 0.0 ? 0.0 : origMaxs[1]; - maxs[2] = origMaxs[2]; - - TR_TraceHullFilter(origin, originBelow, mins, maxs, MASK_PLAYERSOLID, PlayerFilter); - - if (TR_DidHit()) - { - TR_GetPlaneNormal(null, nrm); - if (nrm[2] >= MIN_STANDABLE_ZNRM) - { - return true; - } - } - - return false; -} |
