diff options
| author | navewindre <nw@moneybot.cc> | 2023-11-15 02:20:31 +0100 |
|---|---|---|
| committer | navewindre <nw@moneybot.cc> | 2023-11-15 02:20:31 +0100 |
| commit | d4d5482b5f66209d17b9d786ffe0a13cf352fb15 (patch) | |
| tree | b379882c13bdeb64d1009ce64733a8f0b7d1054c /sourcemod | |
| parent | 405737846f73753ade746b0506020f6720269a51 (diff) | |
cleanup halftime plugin, remove money string from bot plugin, push website
Diffstat (limited to 'sourcemod')
| -rw-r--r-- | sourcemod/scripting/bot2player_public.sp | 2 | ||||
| -rw-r--r-- | sourcemod/scripting/game_manager.sp | 180 | ||||
| -rw-r--r-- | sourcemod/scripting/gem_damage_report.sp | 699 | ||||
| -rw-r--r-- | sourcemod/scripting/gem_halftime_teamswap.sp | 234 |
4 files changed, 880 insertions, 235 deletions
diff --git a/sourcemod/scripting/bot2player_public.sp b/sourcemod/scripting/bot2player_public.sp index 5faab4f..a9ca0b3 100644 --- a/sourcemod/scripting/bot2player_public.sp +++ b/sourcemod/scripting/bot2player_public.sp @@ -315,7 +315,7 @@ public Action:DisplayTakeOverMessage(Handle:timer, any:iClient) { if (ClientCash >= BotTakeverCost[iClient]) { - PrintHintText(iClient, "For $%i - Press the Use key [default E] to take control of %s", BotTakeverCost[iClient], BOTName) + PrintHintText(iClient, "Press the Use key [default E] to take control of %s", BotTakeverCost[iClient], BOTName) return Plugin_Continue } else diff --git a/sourcemod/scripting/game_manager.sp b/sourcemod/scripting/game_manager.sp new file mode 100644 index 0000000..5d0c250 --- /dev/null +++ b/sourcemod/scripting/game_manager.sp @@ -0,0 +1,180 @@ +#pragma semicolon 1 +#include <sourcemod> +#include <sdktools> +#include <cstrike> + +#define PLUGIN_VERSION "1.0.0" +#define MAX_FILE_LEN 80 + +public Plugin:myinfo = +{ + name = "networkheaven game manager", + author = "networkheaven.net", + description = "", + version = PLUGIN_VERSION, + url = "networkheaven.net" +}; + +new g_maxrounds; +new g_roundCount; +new bool:halftime; +new Handle:g_h_mp_startmoney = INVALID_HANDLE; +new Handle:g_h_mp_maxrounds = INVALID_HANDLE; +new g_mp_startmoney; +new bool:g_doReset = false; +new g_CtScore, g_TScore; + +/* forwards */ +new Handle:g_f_on_ht = INVALID_HANDLE; + +// Offsets +new g_iAccount = -1; + + +// Setting halftime to false +public OnMapStart(){ + halftime = false; + g_roundCount = 0; + + g_mp_startmoney = GetConVarInt(g_h_mp_startmoney); + g_maxrounds = GetConVarInt(g_h_mp_maxrounds); +} + +public OnConfigsExecuted(){ + halftime = false; +} + +// Hooking events at plugin start +public OnPluginStart() { + HookEvent("round_start", Event_RoundStart); + HookEvent("round_end", Event_RoundEnd); + + g_h_mp_startmoney = FindConVar("mp_startmoney"); + g_h_mp_maxrounds = FindConVar("mp_maxrounds"); + + g_f_on_ht = CreateGlobalForward("nthvnHalftime", ET_Ignore); + + // Finding offset for CS cash + g_iAccount = FindSendPropOffs("CCSPlayer", "m_iAccount"); + if (g_iAccount == -1) + SetFailState("m_iAccount offset not found"); +} + +// RoundStart gets the maptime +// Checks to see if halftime has passed, if not then make sure halftime is 0 +// Setting halftime false here as well since in some occasions when extending map +// team switch can occur again. +public Event_RoundStart( Handle:event, const String:name[], bool:dontBroadcast ) +{ + new wepIdx; + new playerTeam; + + g_CtScore = GetTeamScore(CS_TEAM_CT); + g_TScore = GetTeamScore(CS_TEAM_T); + + g_roundCount = g_CtScore + g_TScore + 1; + + if( g_doReset ) { + for( new client = 1; client <= GetMaxClients(); client++ ) { + if (IsClientInGame (client) && IsClientConnected(client)) { + for( new w = 0; w < 6; w++ ) { + if( w != 2 && w != 4 ) + while( ( wepIdx = GetPlayerWeaponSlot(client, w) ) != -1 ) + RemovePlayerItem(client, wepIdx); + } + + playerTeam = GetClientTeam( client ); + if( playerTeam == CS_TEAM_T ) { + GivePlayerItem( client, "weapon_glock" ); + } + else if( playerTeam == CS_TEAM_CT ) { + GivePlayerItem( client, "weapon_usp" ); + if ((wepIdx = GetPlayerWeaponSlot( client, 6 ) ) != -1) + RemovePlayerItem(client, wepIdx); + } + SetEntProp(client, Prop_Send, "m_ArmorValue", 0, 1); + SetEntProp(client, Prop_Send, "m_bHasHelmet", 0, 1); + + SetEntData(client, g_iAccount, g_mp_startmoney, 4, true); + } + } + } + g_doReset = false; +} + +public Event_RoundEnd (Handle:event, const String:name[], bool:dontBroadcast) +{ + new reason = GetEventInt(event, "reason"); + new winner = GetEventInt(event, "winner"); + + g_mp_startmoney = GetConVarInt(g_h_mp_startmoney); + g_maxrounds = GetConVarInt(g_h_mp_maxrounds); + + // game commencing + if( reason == 15 ) { + g_CtScore = 0; + g_TScore = 0; + g_roundCount = 0; + return; + } + + if( winner==CS_TEAM_T ) + g_TScore++; + else if( winner==CS_TEAM_CT ) + g_CtScore++; + + if( g_TScore > g_maxrounds/2 || g_CtScore > g_maxrounds/2 ) { + SetConVarInt( g_h_mp_maxrounds, 1, true, false ); + PrintToChatAll("\x04============[ game end ]============"); + + if( g_TScore > g_CtScore ) { + PrintToChatAll("\x04Winner: T"); + } + else { + PrintToChatAll("\x04Winner: CT"); + } + } + + LogMessage( "roundEnd: ct: %d t: %d rounds: %d max: %d", g_CtScore, g_TScore, g_roundCount, g_maxrounds/2 ); + if( halftime || g_roundCount < g_maxrounds/2 ) { + SetTeamScore( CS_TEAM_CT, g_CtScore ); + SetTeamScore( CS_TEAM_T, g_TScore ); + return; + } + + new playerTeam; + + Call_StartForward(g_f_on_ht); + Call_Finish(); + + halftime = true; + for( new i = 1; i <= GetMaxClients(); i++ ) { + if( IsClientInGame( i ) && IsClientConnected( i ) ) { + + // kill bots + if( IsFakeClient( i ) ) { + ForcePlayerSuicide( i ); + } + + g_doReset = true; + + playerTeam = GetClientTeam(i); + if( playerTeam == CS_TEAM_T ) { + CS_SwitchTeam( i, CS_TEAM_CT ); + } + else if( playerTeam == CS_TEAM_CT ) { + CS_SwitchTeam( i, CS_TEAM_T ); + } + } + } + + new tmp; + tmp = g_CtScore; + g_CtScore = g_TScore; + g_TScore = tmp; + + PrintToChatAll("\x04==========[ halftime switch ]=========="); + + SetTeamScore( CS_TEAM_CT, g_CtScore ); + SetTeamScore( CS_TEAM_T, g_TScore ); +} diff --git a/sourcemod/scripting/gem_damage_report.sp b/sourcemod/scripting/gem_damage_report.sp new file mode 100644 index 0000000..334b398 --- /dev/null +++ b/sourcemod/scripting/gem_damage_report.sp @@ -0,0 +1,699 @@ +/* + Description: + When you die or round ends and you are still alive + A left side menu shows who and how much you did damage to and who damaged you. + + Developed: + 2007-12-20 + + By: + [30+]Gemeni (gemeni@30plus.ownit.se) + + Version history: + 1.0.0 - First Version + 1.0.1 - Added number of hits + 1.0.2 - Added hitgroup information + 1.0.3 - Created a long and short version of the report. + If the Long version that includes hitgroups does not fit + in the panel, the short version is displayed + Added coloring in the panel + 1.1.0 - Added option so you can turn damage report on and off, and also + decide if it should be printed in menu or chat. Use /damage_report help to get info + Big thanks to death_beam team since I used their code to learn about + KeyValues! + 1.1.1 - Stripped chat output. + Resetting damage data on round start + 1.1.2 - Added total dmg taken/given and X indicator for kill/killed + 1.1.3 - Removed errors from translation stuff that was not completed + Still looking at getting translation to work + 1.1.5 - Added support to show again the last report that was shown to a player + 1.1.6 - Fixed saving of settings on map end + 1.1.7 - Problem with bogus entries in damagereportsetting file + 1.1.8 - Added most kills info + 1.1.9 - Fixed memory leak + 1.1.10 - Checking if player still ingame before trying to display. + 1.1.11 - Sometimes it seems that the settings for the users isnt written to file. Forcing this more often now. + 1.1.12 - Making sure damage data is not shown to surviving players if they have switched it off. + 1.1.13 - Added extra option, /damage_report long|short - If hitboxdata should be shown or not +*/ + +#pragma semicolon 1 +#include <sourcemod> +#include <sdktools> + +// Definitions +#define MAXHITGROUPS 7 +#define NROFOPTIONS 3 +#define MAX_FILE_LEN 80 + +#define DrON 1 +#define DrOFF 0 +#define DrPop 1 +#define DrChat 0 +#define DrLong 1 +#define DrShort 0 + +#define propOnOff 0 +#define propPopChat 1 +#define propShortLong 2 + +#define PLUGIN_VERSION "1.1.13" + +public Plugin:myinfo = +{ + name = "Damage report", + author = "[30+]Gemeni", + description = "Reports who damaged you and who you damaged", + version = PLUGIN_VERSION, + url = "http://30plus.ownit.se/" +}; + +// Global variables +new g_DamageDone[MAXPLAYERS+1][MAXPLAYERS+1]; +new g_HitsDone[MAXPLAYERS+1][MAXPLAYERS+1]; +new g_HitboxDone[MAXPLAYERS+1][MAXPLAYERS+1][MAXHITGROUPS+1]; + +new g_DamageTaken[MAXPLAYERS+1][MAXPLAYERS+1]; +new g_HitsTaken[MAXPLAYERS+1][MAXPLAYERS+1]; +new g_HitboxTaken[MAXPLAYERS+1][MAXPLAYERS+1][MAXHITGROUPS+1]; + +new String:g_PlayerName[MAXPLAYERS+1][32]; + +new g_KilledPlayer[MAXPLAYERS+1][MAXPLAYERS+1]; + +new g_PlayerDROption[MAXPLAYERS+1][NROFOPTIONS]; +new String:g_filenameSettings[MAX_FILE_LEN]; +new Handle:KVSettings = INVALID_HANDLE; + +new g_defaultPropOnOff = DrON; +new g_defaultPropChatPop = DrChat; +new g_defaultPropShortLong = DrShort; + +new bool:g_lateLoaded; + +// History stats +new String:g_HistDamageDone[MAXPLAYERS+1][512]; +new String:g_HistDamageDoneLong[MAXPLAYERS+1][512]; +new g_HistTotalDamageDone[MAXPLAYERS+1]; +new String:g_HistDamageTaken[MAXPLAYERS+1][512]; +new String:g_HistDamageTakenLong[MAXPLAYERS+1][512]; +new g_HistTotalDamageTaken[MAXPLAYERS+1]; + + +new Handle:g_versionConVar; + +new g_maxClients; + +new String:g_HitboxName[MAXHITGROUPS+1][20]; + +// Variable for Temp fix +new g_MenuCleared[MAXPLAYERS+1]; + + +public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max) +{ + g_lateLoaded = late; + return true; +} + +// Hook events on plugin start +public OnPluginStart(){ + g_versionConVar = CreateConVar("sm_damage_report_version", PLUGIN_VERSION, "Damage report version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY); + SetConVarString(g_versionConVar, PLUGIN_VERSION); + HookEvent("player_death", Event_PlayerDeath); + HookEvent("player_hurt", Event_PlayerHurt); + HookEvent("player_spawn", Event_PlayerSpawn); + HookEvent("round_end", Event_RoundEnd); + HookEvent("round_start", EventRoundStart); + + HookEvent("player_disconnect", Event_PlayerDisconnect); + HookEvent("player_connect", Event_PlayerConnect); + + RegConsoleCmd("damage_report", Command_DamageReport); + RegConsoleCmd("last_damage_report", Command_LastDamageReport); + RegConsoleCmd("ldr", Command_LastDamageReport); + + KVSettings=CreateKeyValues("DamageReportSetting"); + BuildPath(Path_SM, g_filenameSettings, MAX_FILE_LEN, "data/damagereportsetting.txt"); + if(!FileToKeyValues(KVSettings, g_filenameSettings)) + { + KeyValuesToFile(KVSettings, g_filenameSettings); + } + + if(g_lateLoaded) + { + // Plugin was not loaded at beginning of round + // Find settings for all players already connected + for(new i = 1; i < g_maxClients; i++) + { + if(IsClientInGame(i) && !IsFakeClient(i)) + { + FindSettingsForClient(i); + } + } + } + g_HitboxName[0] = "Body"; + g_HitboxName[1] = "Head"; + g_HitboxName[2] = "Chest"; + g_HitboxName[3] = "Stomach"; + g_HitboxName[4] = "Left arm"; + g_HitboxName[5] = "Right arm"; + g_HitboxName[6] = "Left leg"; + g_HitboxName[7] = "Right leg"; +} + +public Action:Command_LastDamageReport(client, args) +{ + // Dont do anything if command comes from server + if (client == 0) { + return Plugin_Handled; + } + + if ((strcmp(g_HistDamageDone[client], "") != 0) || (strcmp(g_HistDamageTaken[client], "") != 0)) { + DisplayDamageReport(client, g_HistDamageDone[client] ,g_HistDamageDoneLong[client] ,g_HistDamageTaken[client], g_HistDamageTakenLong[client], g_HistTotalDamageDone[client], g_HistTotalDamageTaken[client]); + } + else { + PrintToChat(client, "\x04No history to display"); + } + + return Plugin_Handled; +} +public Action:Command_DamageReport(client, args) +{ + // Dont do anything if command comes from server + if (client == 0) { + return Plugin_Handled; + } + + // If you send in to few or to many arguments. Tell them to ask for help + if (args != 1) + { + PrintToChat(client, "\x04Usage: /damage_report help"); + return Plugin_Handled; + } + + new String:option[20]; + GetCmdArg(1, option, sizeof(option)); + + if (strcmp(option, "on", false) == 0) { + g_PlayerDROption[client][propOnOff] = DrON; + PrintToChat(client, "\x04Damage report switched on"); + } + else if (strcmp(option, "off", false) == 0) { + g_PlayerDROption[client][propOnOff] = DrOFF; + PrintToChat(client, "\x04Damage report switched off"); + } + else if (strcmp(option, "popup", false) == 0) { + g_PlayerDROption[client][propPopChat] = DrPop; + PrintToChat(client, "\x04Damage report printed in popup menu"); + } + else if (strcmp(option, "chat", false) == 0) { + g_PlayerDROption[client][propPopChat] = DrChat; + PrintToChat(client, "\x04Damage report printed in chat"); + } + else if (strcmp(option, "short", false) == 0) { + g_PlayerDROption[client][propShortLong] = DrShort; + PrintToChat(client, "\x04Hitbox data will not be shown"); + } + else if (strcmp(option, "long", false) == 0) { + g_PlayerDROption[client][propShortLong] = DrLong; + PrintToChat(client, "\x04Hitbox data will be shown"); + } + else if (strcmp(option, "status", false) == 0) { + if(g_PlayerDROption[client][propOnOff] == DrON) { + PrintToChat(client, "\x04Damage report is switched on"); + if(g_PlayerDROption[client][propPopChat] == DrPop) { + PrintToChat(client, "\x04Damage report is printed in popup menu"); + } + else { + PrintToChat(client, "\x04Damage report is printed in chat"); + } + if(g_PlayerDROption[client][propShortLong] == DrShort) { + PrintToChat(client, "\x04Hitbox data is not shown"); + } + else { + PrintToChat(client, "\x04Hitbox data is shown"); + } + } + else { + PrintToChat(client, "\x04Damage report is switched off"); + } + } + else { + new String:helpString1[200] = "/damage_report on (Turn it on) /damage_report off (Turn it off)\n"; + new String:helpString2[200] = "/damage_report popup (It will show as a left menu) /damage_report chat (It will show up in the chat)"; + new String:helpString3[200] = "/damage_report short (Will remove hitbox info)"; + new String:helpString4[200] = "/damage_report long (Will display hitbox info)"; + new String:helpString5[200] = "/damage_report status (See current damage report settings)"; + new String:helpString6[200] = "/last_damage_report or /ldr will display the last damage report that was shown to you"; + PrintToChat(client, "\x04%s", helpString1); + PrintToChat(client, "\x04%s", helpString2); + PrintToChat(client, "\x04%s", helpString3); + PrintToChat(client, "\x04%s", helpString4); + PrintToChat(client, "\x04%s", helpString5); + PrintToChat(client, "\x04%s", helpString6); + } + + StoreSettingsForClient(client); + + return Plugin_Handled; +} + + +// Save all settings on map end +public OnMapEnd() { + // Save user settings to a file + KvRewind(KVSettings); + KeyValuesToFile(KVSettings, g_filenameSettings); + + clearAllDamageData(); +} + +public OnMapStart() { + g_maxClients = GetMaxClients(); + + + // Temp fix to for clearing menues on start + for (new i=1; i<=g_maxClients; i++) + { + g_MenuCleared[i] = 0; + } +} + +// Initializations to be done at the beginning of the round +public EventRoundStart(Handle:event, const String:name[], bool:dontBroadcast) +{ + clearAllDamageData(); +} + + +// In this event we store how much damage attacker did to victim in one array +// and how much damage victim took from attacker in another array +public Event_PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast) +{ + new healthDmg = GetEventInt(event,"dmg_health"); + new hitgroup = GetEventInt(event, "hitgroup"); + + new victim_id = GetEventInt(event, "userid"); + new attacker_id = GetEventInt(event, "attacker"); + + new victim = GetClientOfUserId(victim_id); + new attacker = GetClientOfUserId(attacker_id); + + // Log damage taken to the vicitm and damage done to the attacker + g_DamageDone[attacker][victim] += healthDmg; + g_HitsDone[attacker][victim]++; + g_HitboxDone[attacker][victim][hitgroup]++; + + g_DamageTaken[victim][attacker] += healthDmg; + g_HitsTaken[victim][attacker]++; + g_HitboxTaken[victim][attacker][hitgroup]++; +} + + +// Upon player dead, check who is the victim and attacker and +// Call up on the buildDamageString function +public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) +{ + new victim_id = GetEventInt(event, "userid"); + new attacker_id = GetEventInt(event, "attacker"); + + new victim = GetClientOfUserId(victim_id); + new attacker = GetClientOfUserId(attacker_id); + + g_KilledPlayer[attacker][victim]=1; + + if ((g_PlayerDROption[victim][propOnOff] == DrON) && (!IsFakeClient(victim)) && IsClientInGame(victim)) { + BuildDamageString(victim, attacker); + } +} + +// Local Function where we loop through all attackers and victims for a client. +// if any damage is taken or done a timer is called that will display a Panel with the info. +BuildDamageString (in_victim, in_attacker) { + new String:damageReport[512]; + new String:damageReportLong[600]; + new String:damageDone[512]; + new String:damageTaken[512]; + new String:damageDoneLong[512]; + new String:damageTakenLong[512]; + new String:killer[10]; + new String:xkiller[10]; + new String:killed[10]; + new String:xkilled[10]; + new totalDmgTaken, totalDmgDone; + + // Loop through all damage where you inflicted damage + for (new i=1; i<=g_maxClients; i++) + { + if(g_DamageDone[in_victim][i] >0) + { + if (g_KilledPlayer[in_victim][i] == 1) { + killed=" (Killed)"; + xkilled=" X"; + } + else { + killed=""; + xkilled=""; + } + + Format(damageDone, sizeof(damageDone), "%s%s [%d dmg, %d hits]%s\n", damageDone, g_PlayerName[i], g_DamageDone[in_victim][i], g_HitsDone[in_victim][i], xkilled); + Format(damageDoneLong, sizeof(damageDoneLong), "%s%s%s [%d dmg, %d hits]%s\n", damageDoneLong, xkilled, g_PlayerName[i], g_DamageDone[in_victim][i], g_HitsDone[in_victim][i], killed); + Format(damageDoneLong, sizeof(damageDoneLong), "%s ", damageDoneLong); + totalDmgDone += g_DamageDone[in_victim][i]; + for(new j=0; j<=MAXHITGROUPS; j++) { + if (g_HitboxDone[in_victim][i][j] > 0) { + Format(damageDoneLong, sizeof(damageDoneLong), "%s%s:%d ", damageDoneLong, g_HitboxName[j], g_HitboxDone[in_victim][i][j]); + } + } + Format(damageDoneLong, sizeof(damageDoneLong), "%s\n", damageDoneLong); + } + } + + // If you did any damage, add it to the report + if (strcmp(damageDone, "", false) != 0) { + Format(damageReport, sizeof(damageReport), "%s\n%s", "Damage done:", damageDone); + Format(damageReportLong, sizeof(damageReportLong), "%s\n%s", "Damage done:", damageDoneLong); + } + + // Loop through all damage where you took damage + for (new i=1; i<=g_maxClients; i++) + { + if(g_DamageTaken[in_victim][i] >0) + { + if (i == in_attacker) { + killer=" (Killer)"; + xkiller=" X"; + } + else { + killer=""; + xkiller=""; + } + + Format(damageTaken, sizeof(damageTaken), "%s%s [%d dmg, %d hits]%s\n", damageTaken, g_PlayerName[i], g_DamageTaken[in_victim][i], g_HitsTaken[in_victim][i], xkiller); + + Format(damageTakenLong, sizeof(damageTakenLong), "%s%s%s [%d dmg, %d hits]%s\n", damageTakenLong, xkiller, g_PlayerName[i], g_DamageTaken[in_victim][i], g_HitsTaken[in_victim][i], killer); + Format(damageTakenLong, sizeof(damageTakenLong), "%s ", damageTakenLong); + totalDmgTaken += g_DamageTaken[in_victim][i]; + for(new j=0; j<=MAXHITGROUPS; j++) { + if (g_HitboxTaken[in_victim][i][j] > 0) { + Format(damageTakenLong, sizeof(damageTakenLong), "%s%s:%d ", damageTakenLong, g_HitboxName[j], g_HitboxTaken[in_victim][i][j]); + } + } + Format(damageTakenLong, sizeof(damageTakenLong), "%s\n", damageTakenLong); + } + } + + // If you took any damage, add it to the report + if (strcmp(damageTaken, "") != 0) { + Format(damageReport, sizeof(damageReport), "%s%s\n%s", damageReport, "Damage taken:", damageTaken); + Format(damageReportLong, sizeof(damageReportLong), "%s%s\n%s", damageReportLong, "Damage taken:", damageTakenLong); + } + + // If damageReport is not empy + if (strcmp(damageReport, "") != 0) { + // store values if players what to view the last stats shown + g_HistDamageDone[in_victim] = damageDone; + g_HistDamageDoneLong[in_victim] = damageDoneLong; + g_HistTotalDamageDone[in_victim] = totalDmgDone; + + g_HistDamageTaken[in_victim] = damageTaken; + g_HistDamageTakenLong[in_victim] = damageTakenLong; + g_HistTotalDamageTaken[in_victim] = totalDmgTaken; + + DisplayDamageReport(in_victim, damageDone ,damageDoneLong ,damageTaken, damageTakenLong, totalDmgDone, totalDmgTaken); + } +} + +DisplayDamageReport(in_victim, String:damageDone[512] ,String:damageDoneLong[512] ,String:damageTaken[512], String:damageTakenLong[512], totalDmgDone, totalDmgTaken) { + if (g_PlayerDROption[in_victim][propPopChat] == DrPop) { + // Display damage report to the dead vicitm + new Handle:pack; + CreateDataTimer(1.0,DisplayDamageReportMenu, pack, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE); + WritePackCell(pack, in_victim); + //LogToGame("%s", damageReport); + if (strlen(damageTakenLong)+strlen(damageDoneLong)<512-30 && (g_PlayerDROption[in_victim][propShortLong] == DrLong)) { + WritePackString(pack, damageDoneLong); + WritePackString(pack, damageTakenLong); + WritePackCell(pack, totalDmgDone); + WritePackCell(pack, totalDmgTaken); + } + else { + WritePackString(pack, damageDone); + WritePackString(pack, damageTaken); + WritePackCell(pack, totalDmgDone); + WritePackCell(pack, totalDmgTaken); + } + } + else { + if (strcmp(damageDone, "", false) != 0) { + PrintToChat(in_victim, "\n\x04==Victims (Total dmg:%d)]==\n", totalDmgDone); + PrintToChat(in_victim, "\x04%s", damageDone); + } + if (strcmp(damageTaken, "", false) != 0) { + PrintToChat(in_victim, "\x0E==[Attackers (Total dmg:%d)]==\n", totalDmgTaken); + PrintToChat(in_victim, "\x0E%s", damageTaken); + } + } +} + +// This is called by the timer. +// It checks if a menu/panel already is displayed ... if so +// let the timer try again after the delay, hoping the menu is closed +public Action:DisplayDamageReportMenu(Handle:timer, Handle:pack) { + new String:p_damageDone[512]; + new String:p_damageTaken[512]; + new String:victimItem[100]; + new String:attackerItem[100]; + new p_victim; + new p_totalDmgDone; + new p_totalDmgTaken; + + ResetPack(pack); + p_victim = ReadPackCell(pack); + ReadPackString(pack, p_damageDone, sizeof(p_damageDone)); + ReadPackString(pack, p_damageTaken, sizeof(p_damageTaken)); + p_totalDmgDone = ReadPackCell(pack); + p_totalDmgTaken = ReadPackCell(pack); + + if (!IsClientInGame(p_victim)) { + return Plugin_Stop; + } + + + if (GetClientMenu(p_victim)!=MenuSource_None) { + return Plugin_Continue; + } + + new Handle:damageReportPanel = CreatePanel(); + + if (strcmp(p_damageDone, "") != 0) { + //LogToGame("%s", p_damageReport); + + Format(victimItem, sizeof(victimItem), "Victims (Total dmg:%d)", p_totalDmgDone); + DrawPanelItem(damageReportPanel, victimItem); + DrawPanelText(damageReportPanel, p_damageDone); + } + if (strcmp(p_damageTaken, "") != 0) { + //LogToGame("%s", p_damageReport); + Format(attackerItem, sizeof(attackerItem), "Attackers (Total dmg:%d)", p_totalDmgTaken); + DrawPanelItem(damageReportPanel, attackerItem); + DrawPanelText(damageReportPanel, p_damageTaken); + } + DrawPanelItem(damageReportPanel, "Exit"); + DrawPanelText(damageReportPanel, "Type \"/damage_report help\" in chat for settings"); + + SendPanelToClient(damageReportPanel, p_victim, Handler_MyPanel, 8); + CloseHandle(damageReportPanel); + return Plugin_Stop; +} + + +// Display time timer will close my panel ... no need to handle anything +// CloseHandle seems to be called when the timer for the panel runs out +public Handler_MyPanel(Handle:menu, MenuAction:action, param1, param2) { +} + + +// Store the name of the player at time of spawn. If player disconnects before +// round end, the name can still be displayed in the damage reports. +public Event_PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast){ + new userid = GetEventInt(event,"userid"); + new client = GetClientOfUserId(userid); + // Temp fix menu + if (g_MenuCleared[client] == 0) { + new Handle:TempPanel = CreatePanel(); + DrawPanelText(TempPanel, "welcome to networkheaven"); + SendPanelToClient(TempPanel, client, Handler_MyPanel, 1); + g_MenuCleared[client] = 1; + CloseHandle(TempPanel); + } + // Store Player names if they disconnect before round has ended + new String:clientName[32]; + GetClientName(client, clientName, sizeof(clientName)); + strcopy(g_PlayerName[client], sizeof(g_PlayerName[]), clientName); + + // This shows that there is something strange when you spawn for the first time. +} + +// Temp Fix +public Event_PlayerDisconnect(Handle:event, const String:name[], bool:dontBroadcast){ + new userid = GetEventInt(event,"userid"); + new client = GetClientOfUserId(userid); + g_MenuCleared[client] = 0; + + g_HistDamageDone[client] = ""; + g_HistDamageDoneLong[client] = ""; + g_HistTotalDamageDone[client] = 0; + + g_HistDamageTaken[client] = ""; + g_HistDamageTakenLong[client] = ""; + g_HistTotalDamageTaken[client] = 0; +} + +public Event_PlayerConnect(Handle:event, const String:name[], bool:dontBroadcast){ + new userid = GetEventInt(event,"userid"); + new client = GetClientOfUserId(userid); + g_MenuCleared[client] = 0; + + g_HistDamageDone[client] = ""; + g_HistDamageDoneLong[client] = ""; + g_HistTotalDamageDone[client] = 0; + + g_HistDamageTaken[client] = ""; + g_HistDamageTakenLong[client] = ""; + g_HistTotalDamageTaken[client] = 0; +} + +public OnClientPostAdminCheck(client) { + FindSettingsForClient(client); +} + +FindSettingsForClient(client) { + new String:steamId[20]; + GetClientAuthString(client, steamId, 20); + + KvRewind(KVSettings); + if(KvJumpToKey(KVSettings, steamId)) + { + g_PlayerDROption[client][propOnOff] = KvGetNum(KVSettings, "OnOff", g_defaultPropOnOff); + g_PlayerDROption[client][propPopChat] = KvGetNum(KVSettings, "PopChat", g_defaultPropChatPop); + g_PlayerDROption[client][propShortLong] = KvGetNum(KVSettings, "ShortLong", g_defaultPropChatPop); + } else { + g_PlayerDROption[client][propOnOff] = g_defaultPropOnOff; + g_PlayerDROption[client][propPopChat] = g_defaultPropChatPop; + g_PlayerDROption[client][propShortLong] = g_defaultPropShortLong; + } + KvRewind(KVSettings); +} + +StoreSettingsForClient(client) { + new String:steamId[40]; + GetClientAuthString(client, steamId, 20); + + if(StrContains(steamId, "steam", false) != -1) { + + KvRewind(KVSettings); + if ((g_PlayerDROption[client][propOnOff] == g_defaultPropOnOff) && (g_PlayerDROption[client][propPopChat] == g_defaultPropChatPop) && (g_PlayerDROption[client][propShortLong] == g_defaultPropShortLong)) { + if(KvJumpToKey(KVSettings, steamId)) + { + KvDeleteThis(KVSettings); + } + } + else { + KvJumpToKey(KVSettings, steamId, true); + KvSetNum(KVSettings, "OnOff", g_PlayerDROption[client][propOnOff]); + KvSetNum(KVSettings, "PopChat", g_PlayerDROption[client][propPopChat]); + KvSetNum(KVSettings, "ShortLong", g_PlayerDROption[client][propShortLong]); + } + KvRewind(KVSettings); + KeyValuesToFile(KVSettings, g_filenameSettings); + } +} + +// Check if there are any living players. If so, trigger a timer for them so they will see their damage report +// Calculate who did max damage and display it as a hint. +// clear global damage done/taken arrays +public Event_RoundEnd (Handle:event, const String:name[], bool:dontBroadcast) +{ + // Make sure that we have a normal round end + // reason 16 is game commencing + // other reasons are real round ends + new reason = GetEventInt(event, "reason"); + if(reason == 16) { + return; + } + + new damage, hits, mostDamage, mostDamagePlayer, mostHits, kills, mostKills, mostKillsPlayer; + + // Display damage report to living players + // -1 in the damage string will make sure noone will be shown as the (Killer) + for (new i=1; i<=g_maxClients; i++) + { + if(IsClientInGame (i)) { + if ((g_PlayerDROption[i][propOnOff] == DrON) && IsClientConnected (i) && !IsFakeClient (i) && IsPlayerAlive (i)) { + BuildDamageString(i, -1); + } + } + } + + // Finding out who did the most damage + for (new i=1; i<=g_maxClients; i++) + { + damage = 0; + hits = 0; + for (new j=1; j<=g_maxClients; j++) + { + damage = damage + g_DamageDone[i][j]; + hits = hits + g_HitsDone[i][j]; + } + if (damage > mostDamage) { + mostDamage = damage; + mostDamagePlayer = i; + mostHits = hits; + } + } + + mostKills = 0; + for (new i=1; i<=g_maxClients; i++) + { + kills = 0; + for (new j=1; j<=g_maxClients; j++) + { + kills = kills + g_KilledPlayer[i][j]; + } + if (kills > mostKills) { + mostKills = kills; + mostKillsPlayer = i; + } + } + + // Display to all the player that did the most damage this round + if(mostDamage > 0) { + //PrintToChatAll("\x01%s\x04 inflicted most damage, \x01%d\x04 dmg in \x01%d\x04 hits!", g_PlayerName[mostDamagePlayer], mostDamage, mostHits); + } + if(mostKills > 0) { + //PrintToChatAll("\x04Most kills: \x01%s\x04 with \x01%d\x04 kills" ,g_PlayerName[mostKillsPlayer], mostKills); + } +} + +clearAllDamageData() +{ + // Clear all logged damage + for (new i=1; i<=g_maxClients; i++) + { + for (new j=1; j<=g_maxClients; j++) + { + g_DamageDone[i][j]=0; + g_DamageTaken[i][j]=0; + g_HitsDone[i][j]=0; + g_HitsTaken[i][j]=0; + g_KilledPlayer[i][j]=0; + for (new k=0; k<=MAXHITGROUPS; k++) + { + g_HitboxDone[i][j][k]=0; + g_HitboxTaken[i][j][k]=0; + } + } + } +} diff --git a/sourcemod/scripting/gem_halftime_teamswap.sp b/sourcemod/scripting/gem_halftime_teamswap.sp deleted file mode 100644 index 9333d58..0000000 --- a/sourcemod/scripting/gem_halftime_teamswap.sp +++ /dev/null @@ -1,234 +0,0 @@ -#pragma semicolon 1 -#include <sourcemod> -#include <sdktools> -#include <cstrike> - -#define PLUGIN_VERSION "1.0.11" -#define MAX_FILE_LEN 80 - -public Plugin:myinfo = -{ - name = "Halftime teamswitch", - author = "[30+]Gemeni", - description = "Moves all players to the opposite team at halftime", - version = PLUGIN_VERSION, - url = "http://30plus.ownit.se/" -}; - -// Global variables -new mapTime; -new g_maxrounds; -new g_roundCount; -new bool:halftime; -new Handle:g_h_moneyReset = INVALID_HANDLE; -new Handle:g_h_mp_startmoney = INVALID_HANDLE; -new Handle:g_h_mp_maxrounds = INVALID_HANDLE; -new g_mp_startmoney; -new bool:g_resetMoney; -new bool:g_halftime_do_resetMoney = false; -new Handle:g_CvarHalfTimeType = INVALID_HANDLE; -new String:g_HalfTimeType[MAX_FILE_LEN]; -new g_CtScore, g_TScore; - -/* forwards */ -new Handle:g_f_on_ht = INVALID_HANDLE; - -// Offsets -new g_iAccount = -1; - - -// Setting halftime to false -public OnMapStart(){ - //LogToGame(">>>>>Setting halftime to false, OnMapStart<<<<<"); - halftime = false; - g_roundCount = 0; - - GetConVarString(g_CvarHalfTimeType, g_HalfTimeType, MAX_FILE_LEN); - - new tmp; - tmp = GetConVarInt(g_h_moneyReset); - if (tmp == 1) { - g_resetMoney = true; - } - else { - g_resetMoney = false; - } - - g_mp_startmoney = GetConVarInt(g_h_mp_startmoney); - g_maxrounds = GetConVarInt(g_h_mp_maxrounds); -} - -public OnConfigsExecuted(){ - //LogToGame(">>>>>Setting halftime to false, OnConfigsExecuted<<<<<"); - halftime = false; -} - -// Hooking events at plugin start -public OnPluginStart(){ - CreateConVar("sm_halftime_teamswitch_version", PLUGIN_VERSION, "Halftime teamswitch version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY); - HookEvent("round_start", Event_RoundStart); - HookEvent("round_end", Event_RoundEnd); - - g_h_moneyReset = CreateConVar("sm_halftime_money_reset", "1", "If weapons should be removed and money reset to mp_startmoney"); - g_h_mp_startmoney = FindConVar("mp_startmoney"); - g_h_mp_maxrounds = FindConVar("mp_maxrounds"); - - g_CvarHalfTimeType = CreateConVar("sm_halftime_teamswitch_type", "timelimit", "timelimit|maxrounds to determin what critera halftime should be based on"); - - g_f_on_ht = CreateGlobalForward("gemHalftime", ET_Ignore); - - // Finding offset for CS cash - g_iAccount = FindSendPropOffs("CCSPlayer", "m_iAccount"); - if (g_iAccount == -1) - SetFailState("m_iAccount offset not found"); - -} - -// RoundStart gets the maptime -// Checks to see if halftime has passed, if not then make sure halftime is 0 -// Setting halftime false here as well since in some occasions when extending map -// team switch can occur again. -public Event_RoundStart (Handle:event, const String:name[], bool:dontBroadcast) -{ - new wepIdx; - new playerTeam; - - GetMapTimeLimit(mapTime); - mapTime=mapTime*60; - - g_CtScore = GetTeamScore(CS_TEAM_CT); - g_TScore = GetTeamScore(CS_TEAM_T); - - g_roundCount = g_CtScore + g_TScore + 1; - - if (g_halftime_do_resetMoney) { - for (new client=1; client<=GetMaxClients(); client++) - { - if (IsClientInGame (client) && IsClientConnected(client)) { - for (new w = 0; w < 6; w++) - { - if (w != 2 && w != 4 ) - while((wepIdx = GetPlayerWeaponSlot(client, w)) != -1) - RemovePlayerItem(client, wepIdx); - } - playerTeam = GetClientTeam(client); - if (playerTeam == CS_TEAM_T) { - GivePlayerItem(client, "weapon_glock"); - } - else if (playerTeam == CS_TEAM_CT) { - GivePlayerItem(client, "weapon_usp"); - if ((wepIdx = GetPlayerWeaponSlot(client, 6)) != -1) - RemovePlayerItem(client, wepIdx); - } - SetEntProp(client, Prop_Send, "m_ArmorValue", 0, 1); - SetEntProp(client, Prop_Send, "m_bHasHelmet", 0, 1); - - SetEntData(client, g_iAccount, g_mp_startmoney, 4, true); - } - } - } - g_halftime_do_resetMoney = false; -} - -public Event_RoundEnd (Handle:event, const String:name[], bool:dontBroadcast) -{ - new mapTimeLeft; - new bool:doSwap = false; - - new reason = GetEventInt(event, "reason"); - new winner = GetEventInt(event, "winner"); - - g_mp_startmoney = GetConVarInt(g_h_mp_startmoney); - g_maxrounds = GetConVarInt(g_h_mp_maxrounds); - - // Make sure that we have a normal round end - // reason 16 is game commencing - // other reasons are real round ends - if(reason == 15) { - g_CtScore = 0; - g_TScore = 0; - g_roundCount = 0; - return; - } - - if (winner==CS_TEAM_T) - g_TScore++; - if (winner==CS_TEAM_CT) - g_CtScore++; - - GetMapTimeLeft(mapTimeLeft); - LogMessage( "roundEnd: ct: %d t: %d rounds: %d max: %d", g_CtScore, g_TScore, g_roundCount, g_maxrounds/2 ); - if ((g_roundCount>=g_maxrounds/2)) { - //LogMessage(">>> Halftime, Swap maxrounds %d %d<<<", g_roundCount, g_maxrounds); - doSwap = true; - } - else { - doSwap = false; - } - - if( g_TScore > g_maxrounds/2 || g_CtScore > g_maxrounds/2 ) { - SetConVarInt( g_h_mp_maxrounds, 1, true, false ); - PrintToChatAll("\x04============[ game end ]============"); - - if( g_TScore > g_CtScore ) { - PrintToChatAll("\x04Winner: T"); - } - else { - PrintToChatAll("\x04Winner: CT"); - } - } - - if(doSwap && (halftime == false)) { - new playerTeam; - - Call_StartForward(g_f_on_ht); - Call_Finish(); - - halftime = true; - for (new i=1; i<=GetMaxClients(); i++) - { - if (IsClientInGame (i) && IsClientConnected(i)) { - - if (IsClientInGame (i) && IsClientConnected(i) && IsFakeClient(i)) { - ForcePlayerSuicide(i); - } - - g_halftime_do_resetMoney = true; - - //LogMessage("Player %d is InGame", i); - playerTeam = GetClientTeam(i); - if (playerTeam == CS_TEAM_T) { - //LogMessage("Before switch of %d to CT", i); - CS_SwitchTeam(i, CS_TEAM_CT); - //LogMessage("After switch of %d to CT", i); - } - else if (playerTeam == CS_TEAM_CT) { - //LogMessage("Before switch of %d to T", i); - CS_SwitchTeam(i, CS_TEAM_T); - //LogMessage("After switch of %d to T", i); - } - else { - //LogMessage("No switch, not CT not T"); - } - } - else { - //LogMessage("Player %d is *NOT* InGame", i); - } - } - - new tmp; - tmp = g_CtScore; - g_CtScore = g_TScore; - g_TScore = tmp; - - //LogMessage(">>>>>halftime switch completed<<<<<"); - - PrintToChatAll("\x04==========[ halftime switch ]=========="); - } - // Else just advertise that teamswitch will occur at half time - else if ((mapTimeLeft>mapTime/2) && (halftime == false)) { - //PrintToChatAll(">>> Players will switch teams at halftime <<<"); - } - SetTeamScore(CS_TEAM_CT, g_CtScore); - SetTeamScore(CS_TEAM_T, g_TScore); -} |
