summaryrefslogtreecommitdiff
path: root/sourcemod
diff options
context:
space:
mode:
Diffstat (limited to 'sourcemod')
-rw-r--r--sourcemod/scripting/bot2player_public.sp2
-rw-r--r--sourcemod/scripting/game_manager.sp180
-rw-r--r--sourcemod/scripting/gem_damage_report.sp699
-rw-r--r--sourcemod/scripting/gem_halftime_teamswap.sp234
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);
-}