diff options
Diffstat (limited to 'sourcemod/scripting/gokz-jumpstats/jump_reporting.sp')
| -rw-r--r-- | sourcemod/scripting/gokz-jumpstats/jump_reporting.sp | 508 |
1 files changed, 508 insertions, 0 deletions
diff --git a/sourcemod/scripting/gokz-jumpstats/jump_reporting.sp b/sourcemod/scripting/gokz-jumpstats/jump_reporting.sp new file mode 100644 index 0000000..31a1bb2 --- /dev/null +++ b/sourcemod/scripting/gokz-jumpstats/jump_reporting.sp @@ -0,0 +1,508 @@ +/* + Chat and console reports for jumpstats. +*/ + +static char sounds[DISTANCETIER_COUNT][256]; + + + +// =====[ PUBLIC ]===== + +void PlayJumpstatSound(int client, int tier) +{ + int soundOption = GOKZ_JS_GetOption(client, JSOption_MinSoundTier); + if (tier <= DistanceTier_Meh || soundOption == DistanceTier_None || soundOption > tier) + { + return; + } + + GOKZ_EmitSoundToClient(client, sounds[tier], _, "Jumpstats"); +} + + + +// =====[ EVENTS ]===== + +void OnMapStart_JumpReporting() +{ + if (!LoadSounds()) + { + SetFailState("Failed to load file: \"%s\".", JS_CFG_SOUNDS); + } +} + +void OnLanding_JumpReporting(Jump jump) +{ + int minTier; + int tier = GetDistanceTier(jump.type, GOKZ_GetCoreOption(jump.jumper, Option_Mode), jump.distance, jump.offset); + if (tier == DistanceTier_None) + { + return; + } + + // Report the jumpstat to the client and their spectators + DoJumpstatsReport(jump.jumper, jump, tier); + + for (int client = 1; client <= MaxClients; client++) + { + if (IsValidClient(client) && client != jump.jumper) + { + if (GetObserverTarget(client) == jump.jumper) + { + DoJumpstatsReport(client, jump, tier); + } + else + { + minTier = GOKZ_JS_GetOption(client, JSOption_MinChatBroadcastTier); + if (minTier != 0 && tier >= minTier) + { + GOKZ_PrintToChat(client, true, "%t", "Broadcast Jumpstat Chat Report", + gC_DistanceTierChatColours[tier], + jump.jumper, + jump.distance, + gC_JumpTypes[jump.originalType]); + DoConsoleReport(client, false, jump, tier, "Console Jump Header"); + } + + minTier = GOKZ_JS_GetOption(client, JSOption_MinSoundBroadcastTier); + if (minTier != 0 && tier >= minTier) + { + PlayJumpstatSound(client, tier); + } + } + } + } +} + +void OnFailstat_FailstatReporting(Jump jump) +{ + int tier = GetDistanceTier(jump.type, GOKZ_GetCoreOption(jump.jumper, Option_Mode), jump.distance); + if (tier == DistanceTier_None) + { + return; + } + + // Report the failstat to the client and their spectators + DoFailstatReport(jump.jumper, jump, tier); + + for (int client = 1; client <= MaxClients; client++) + { + if (IsValidClient(client) && GetObserverTarget(client) == jump.jumper) + { + DoFailstatReport(client, jump, tier); + } + } +} + +void OnJumpstatAlways_JumpstatAlwaysReporting(Jump jump) +{ + DoJumpstatAlwaysReport(jump.jumper, jump); + + for (int client = 1; client <= MaxClients; client++) + { + if (IsValidClient(client) && GetObserverTarget(client) == jump.jumper) + { + DoJumpstatAlwaysReport(client, jump); + } + } +} + + +void OnFailstatAlways_FailstatAlwaysReporting(Jump jump) +{ + DoFailstatAlwaysReport(jump.jumper, jump); + + for (int client = 1; client <= MaxClients; client++) + { + if (IsValidClient(client) && GetObserverTarget(client) == jump.jumper) + { + DoFailstatAlwaysReport(client, jump); + } + } +} + + + +// =====[ PRIVATE ]===== + +static void DoJumpstatsReport(int client, Jump jump, int tier) +{ + if (GOKZ_JS_GetOption(client, JSOption_JumpstatsMaster) == JSToggleOption_Disabled) + { + return; + } + + DoChatReport(client, false, jump, tier); + DoConsoleReport(client, false, jump, tier, "Console Jump Header"); + PlayJumpstatSound(client, tier); +} + +static void DoFailstatReport(int client, Jump jump, int tier) +{ + if (GOKZ_JS_GetOption(client, JSOption_JumpstatsMaster) == JSToggleOption_Disabled) + { + return; + } + + DoChatReport(client, true, jump, tier); + DoConsoleReport(client, true, jump, tier, "Console Failstat Header"); +} + +static void DoJumpstatAlwaysReport(int client, Jump jump) +{ + if (GOKZ_JS_GetOption(client, JSOption_JumpstatsMaster) == JSToggleOption_Disabled || + GOKZ_JS_GetOption(client, JSOption_JumpstatsAlways) == JSToggleOption_Disabled) + { + return; + } + + DoChatReport(client, false, jump, 1); + DoConsoleReport(client, false, jump, 1, "Console Jump Header"); +} + +static void DoFailstatAlwaysReport(int client, Jump jump) +{ + if (GOKZ_JS_GetOption(client, JSOption_JumpstatsMaster) == JSToggleOption_Disabled || + GOKZ_JS_GetOption(client, JSOption_JumpstatsAlways) == JSToggleOption_Disabled) + { + return; + } + + DoChatReport(client, true, jump, 1); + DoConsoleReport(client, true, jump, 1, "Console Failstat Header"); +} + + + + +// CONSOLE REPORT + +static void DoConsoleReport(int client, bool isFailstat, Jump jump, int tier, char[] header) +{ + int minConsoleTier = GOKZ_JS_GetOption(client, JSOption_MinConsoleTier); + if ((minConsoleTier == 0 || minConsoleTier > tier) && GOKZ_JS_GetOption(client, JSOption_JumpstatsAlways) == JSToggleOption_Disabled + || isFailstat && GOKZ_JS_GetOption(client, JSOption_FailstatsConsole) == JSToggleOption_Disabled) + { + return; + } + + char releaseWString[32], blockString[32], edgeString[32], deviationString[32], missString[32]; + + if (jump.originalType == JumpType_LongJump || + jump.originalType == JumpType_LadderJump || + jump.originalType == JumpType_WeirdJump || + jump.originalType == JumpType_LowpreWeirdJump) + { + FormatEx(releaseWString, sizeof(releaseWString), " %s", GetIntConsoleString(client, "W Release", jump.releaseW)); + } + else if (jump.crouchRelease < 20 && jump.crouchRelease > -20) + { + FormatEx(releaseWString, sizeof(releaseWString), " %s", GetIntConsoleString(client, "Crouch Release", jump.crouchRelease)); + } + + if (jump.miss > 0.0) + { + FormatEx(missString, sizeof(missString), " %s", GetFloatConsoleString2(client, "Miss", jump.miss)); + } + + if (jump.block > 0) + { + FormatEx(blockString, sizeof(blockString), " %s", GetIntConsoleString(client, "Block", jump.block)); + FormatEx(deviationString, sizeof(deviationString), " %s", GetFloatConsoleString1(client, "Deviation", jump.deviation)); + } + + if (jump.edge > 0.0 || (jump.block > 0 && jump.edge == 0.0)) + { + FormatEx(edgeString, sizeof(edgeString), " %s", GetFloatConsoleString2(client, "Edge", jump.edge)); + } + + PrintToConsole(client, "%t", header, jump.jumper, jump.distance, gC_JumpTypes[jump.originalType]); + + PrintToConsole(client, "%s%s%s%s %s %s %s %s%s %s %s%s %s %s %s %s %s", + gC_ModeNamesShort[GOKZ_GetCoreOption(jump.jumper, Option_Mode)], + blockString, + edgeString, + missString, + GetIntConsoleString(client, jump.strafes == 1 ? "Strafe" : "Strafes", jump.strafes), + GetSyncConsoleString(client, jump.sync), + GetFloatConsoleString2(client, "Pre", jump.preSpeed), + GetFloatConsoleString2(client, "Max", jump.maxSpeed), + releaseWString, + GetIntConsoleString(client, "Overlap", jump.overlap), + GetIntConsoleString(client, "Dead Air", jump.deadair), + deviationString, + GetWidthConsoleString(client, jump.width, jump.strafes), + GetFloatConsoleString1(client, "Height", jump.height), + GetIntConsoleString(client, "Airtime", jump.duration), + GetFloatConsoleString1(client, "Offset", jump.offset), + GetIntConsoleString(client, "Crouch Ticks", jump.crouchTicks)); + + PrintToConsole(client, " #. %12t%12t%12t%12t%12t%9t%t", "Sync (Table)", "Gain (Table)", "Loss (Table)", "Airtime (Table)", "Width (Table)", "Overlap (Table)", "Dead Air (Table)"); + if (jump.strafes_ticks[0] > 0) + { + PrintToConsole(client, " 0. ---- ----- ----- %3.0f%% ----- -- --", GetStrafeAirtime(jump, 0)); + } + for (int strafe = 1; strafe <= jump.strafes && strafe < JS_MAX_TRACKED_STRAFES; strafe++) + { + PrintToConsole(client, + " %2d. %3.0f%% %5.2f %5.2f %3.0f%% %5.1f° %2d %2d", + strafe, + GetStrafeSync(jump, strafe), + jump.strafes_gain[strafe], + jump.strafes_loss[strafe], + GetStrafeAirtime(jump, strafe), + FloatAbs(jump.strafes_width[strafe]), + jump.strafes_overlap[strafe], + jump.strafes_deadair[strafe]); + } + PrintToConsole(client, ""); // New line +} + +static char[] GetSyncConsoleString(int client, float sync) +{ + char resultString[32]; + FormatEx(resultString, sizeof(resultString), "| %.0f%% %T", sync, "Sync", client); + return resultString; +} + +static char[] GetWidthConsoleString(int client, float width, int strafes) +{ + char resultString[32]; + FormatEx(resultString, sizeof(resultString), "| %.1f° %T", GetAverageStrafeWidth(strafes, width), "Width", client); + return resultString; +} + +// I couldn't really merge those together +static char[] GetFloatConsoleString1(int client, const char[] stat, float value) +{ + char resultString[32]; + FormatEx(resultString, sizeof(resultString), "| %.1f %T", value, stat, client); + return resultString; +} + +static char[] GetFloatConsoleString2(int client, const char[] stat, float value) +{ + char resultString[32]; + FormatEx(resultString, sizeof(resultString), "| %.2f %T", value, stat, client); + return resultString; +} + +static char[] GetIntConsoleString(int client, const char[] stat, int value) +{ + char resultString[32]; + FormatEx(resultString, sizeof(resultString), "| %d %T", value, stat, client); + return resultString; +} + + + +// CHAT REPORT + +static void DoChatReport(int client, bool isFailstat, Jump jump, int tier) +{ + int minChatTier = GOKZ_JS_GetOption(client, JSOption_MinChatTier); + if ((minChatTier == 0 || minChatTier > tier) // 0 means disabled + && GOKZ_JS_GetOption(client, JSOption_JumpstatsAlways) == JSToggleOption_Disabled) + { + return; + } + + char typePostfix[3], color[16], blockStats[32], extBlockStats[32]; + char releaseStats[32], edgeOffset[64], offsetEdge[32], missString[32]; + + if (isFailstat) + { + if (GOKZ_JS_GetOption(client, JSOption_FailstatsChat) == JSToggleOption_Disabled + && GOKZ_JS_GetOption(client, JSOption_JumpstatsAlways) == JSToggleOption_Disabled) + { + return; + } + strcopy(typePostfix, sizeof(typePostfix), "-F"); + strcopy(color, sizeof(color), "{grey}"); + } + else + { + strcopy(color, sizeof(color), gC_DistanceTierChatColours[tier]); + } + + if (jump.block > 0) + { + FormatEx(blockStats, sizeof(blockStats), " | %s", GetFloatChatString(client, "Edge", jump.edge)); + FormatEx(extBlockStats, sizeof(extBlockStats), " | %s", GetFloatChatString(client, "Deviation", jump.deviation)); + } + + if (jump.miss > 0.0) + { + FormatEx(missString, sizeof(missString), " | %s", GetFloatChatString(client, "Miss", jump.miss)); + } + + if (jump.edge > 0.0 || (jump.block > 0 && jump.edge == 0.0)) + { + if (jump.originalType == JumpType_LadderJump) + { + FormatEx(offsetEdge, sizeof(offsetEdge), " | %s", GetFloatChatString(client, "Edge", jump.edge)); + } + else + { + FormatEx(edgeOffset, sizeof(edgeOffset), " | %s", GetFloatChatString(client, "Edge", jump.edge)); + } + } + + if (jump.originalType == JumpType_LongJump || + jump.originalType == JumpType_LadderJump || + jump.originalType == JumpType_WeirdJump) + { + if (jump.releaseW >= 20 || jump.releaseW <= -20) + { + FormatEx(releaseStats, sizeof(releaseStats), " | {red}✗ {grey}W", GetReleaseChatString(client, "W Release", jump.releaseW)); + } + else + { + FormatEx(releaseStats, sizeof(releaseStats), " | %s", GetReleaseChatString(client, "W Release", jump.releaseW)); + } + } + else if (jump.crouchRelease < 20 && jump.crouchRelease > -20) + { + FormatEx(releaseStats, sizeof(releaseStats), " | %s", GetReleaseChatString(client, "Crouch Release", jump.crouchRelease)); + } + + if (jump.originalType == JumpType_LadderJump) + { + FormatEx(edgeOffset, sizeof(edgeOffset), " | %s", GetFloatChatString(client, "Offset Short", jump.offset)); + } + else + { + FormatEx(offsetEdge, sizeof(offsetEdge), " | %s", GetFloatChatString(client, "Offset", jump.offset)); + } + + GOKZ_PrintToChat(client, true, + "%s%s%s{grey}: %s%.1f{grey} | %s | %s%s%s", + color, + gC_JumpTypesShort[jump.originalType], + typePostfix, + color, + jump.distance, + GetStrafesSyncChatString(client, jump.strafes, jump.sync), + GetSpeedChatString(client, jump.preSpeed, jump.maxSpeed), + edgeOffset, + releaseStats); + + if (GOKZ_JS_GetOption(client, JSOption_ExtendedChatReport) == JSToggleOption_Enabled) + { + GOKZ_PrintToChat(client, false, + "%s | %s%s%s | %s | %s%s", + GetIntChatString(client, "Overlap", jump.overlap), + GetIntChatString(client, "Dead Air", jump.deadair), + offsetEdge, + extBlockStats, + GetWidthChatString(client, jump.width, jump.strafes), + GetFloatChatString(client, "Height", jump.height), + missString); + } +} + +static char[] GetStrafesSyncChatString(int client, int strafes, float sync) +{ + char resultString[64]; + FormatEx(resultString, sizeof(resultString), + "{lime}%d{grey} %T ({lime}%.0f%%%%{grey})", + strafes, "Strafes", client, sync); + return resultString; +} + +static char[] GetSpeedChatString(int client, float preSpeed, float maxSpeed) +{ + char resultString[64]; + FormatEx(resultString, sizeof(resultString), + "{lime}%.0f{grey} / {lime}%.0f{grey} %T", + preSpeed, maxSpeed, "Speed", client); + return resultString; +} + +static char[] GetReleaseChatString(int client, char[] releaseType, int release) +{ + char resultString[32]; + if (release == 0) + { + FormatEx(resultString, sizeof(resultString), + "{green}✓{grey} %T", + releaseType, client); + } + else if (release > 0) + { + FormatEx(resultString, sizeof(resultString), + "{red}+%d{grey} %T", + release, + releaseType, client); + } + else + { + FormatEx(resultString, sizeof(resultString), + "{blue}%d{grey} %T", + release, + releaseType, client); + } + return resultString; +} + +static char[] GetWidthChatString(int client, float width, int strafes) +{ + char resultString[32]; + FormatEx(resultString, sizeof(resultString), + "{lime}%.1f°{grey} %T", + GetAverageStrafeWidth(strafes, width), "Width", client); + return resultString; +} + +static float GetAverageStrafeWidth(int strafes, float totalWidth) +{ + if (strafes == 0) + { + return 0.0; + } + + return totalWidth / strafes; +} + +static char[] GetFloatChatString(int client, const char[] stat, float value) +{ + char resultString[32]; + FormatEx(resultString, sizeof(resultString), + "{lime}%.1f{grey} %T", + value, stat, client); + return resultString; +} + +static char[] GetIntChatString(int client, const char[] stat, int value) +{ + char resultString[32]; + FormatEx(resultString, sizeof(resultString), + "{lime}%d{grey} %T", + value, stat, client); + return resultString; +} + + + +// SOUNDS + +static bool LoadSounds() +{ + KeyValues kv = new KeyValues("sounds"); + if (!kv.ImportFromFile(JS_CFG_SOUNDS)) + { + return false; + } + + char downloadPath[256]; + for (int tier = DistanceTier_Impressive; tier < DISTANCETIER_COUNT; tier++) + { + kv.GetString(gC_DistanceTierKeys[tier], sounds[tier], sizeof(sounds[])); + FormatEx(downloadPath, sizeof(downloadPath), "sound/%s", sounds[tier]); + AddFileToDownloadsTable(downloadPath); + PrecacheSound(sounds[tier], true); + } + + delete kv; + return true; +} |
