#pragma semicolon 1 #include #include #include #include #include #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_oneChanceDone = false; 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 Handle:g_h_mp_buytime = INVALID_HANDLE; new Handle:g_h_nh_warmup = INVALID_HANDLE; new Handle:g_h_nh_teamlimit = INVALID_HANDLE; new Handle:g_h_mp_ignoreconditions = INVALID_HANDLE; new g_mp_startmoney; new bool:g_doReset = false; new g_CtScore, g_TScore; new Handle:g_h_roundExtentTimer = INVALID_HANDLE; new Handle:g_h_execServerCfgTimer = INVALID_HANDLE; new Float:g_buytime = 0.5; new g_lastDmMode = 0; /* forwards */ new Handle:g_f_on_ht = INVALID_HANDLE; // Offsets new g_iAccount = -1; public OnMapStart(){ halftime = false; g_roundCount = 0; g_mp_startmoney = GetConVarInt( g_h_mp_startmoney ); g_maxrounds = GetConVarInt( g_h_mp_maxrounds ); g_buytime = GetConVarFloat( g_h_mp_buytime ); g_lastDmMode = 0; OnDmModeChanged( g_h_nh_warmup, "", "" ); } public OnConfigsExecuted() { halftime = false; } public OnPluginStart() { HookEvent("round_start", Event_RoundStart); HookEvent("round_end", Event_RoundEnd); HookEvent("player_death", Event_PlayerDeath); HookEvent("player_spawn", Event_PlayerSpawn); HookEvent("player_team", Event_PlayerTeam); AddCommandListener( Listener_JoinTeam, "jointeam" ); g_h_mp_startmoney = FindConVar( "mp_startmoney" ); g_h_mp_maxrounds = FindConVar( "mp_maxrounds" ); g_h_mp_buytime = FindConVar( "mp_buytime"); g_h_mp_ignoreconditions = FindConVar( "mp_ignore_round_win_conditions" ); g_h_nh_warmup = CreateConVar( "nh_warmup", "0", "set warmup time. -1 for infinite.", 0 ); g_h_nh_teamlimit = CreateConVar( "nh_teamlimit", "5", "player limit per team", 0 ); if( g_h_nh_warmup != INVALID_HANDLE ) { HookConVarChange( g_h_nh_warmup, OnDmModeChanged ); } 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"); } public OnDmModeChanged( Handle:cvar, const String:oldVal[], const String:newVal[]) { new dm = GetConVarInt( cvar ); if( !!dm != !!g_lastDmMode ) { SetConVarInt( g_h_mp_ignoreconditions, dm ); for( new i = 1; i < MaxClients; ++i ) { if( IsClientConnected( i ) && IsClientInGame( i ) ) ForcePlayerSuicide( i ); } ServerCommand( "mp_restartgame 1" ); g_CtScore = g_TScore = g_roundCount = 0; SetTeamScore( CS_TEAM_CT, g_CtScore ); SetTeamScore( CS_TEAM_T, g_TScore ); } if( !dm ) { SetConVarFloat( g_h_mp_buytime, g_buytime ); if( g_h_roundExtentTimer ) { KillTimer( g_h_roundExtentTimer ); g_h_roundExtentTimer = INVALID_HANDLE; } PrintToChatAll( "\x04===========[ game live ]===========" ); } else { if( g_h_roundExtentTimer == INVALID_HANDLE ) { g_buytime = GetConVarFloat( g_h_mp_buytime ); g_h_roundExtentTimer = CreateTimer( 1.0, WarmupTimer, 0, TIMER_REPEAT ); SetConVarFloat( g_h_mp_buytime, 420.0 ); } } g_lastDmMode = dm; } public Action:WarmupTimer( Handle:timer, any:userid ) { new dm = GetConVarInt( g_h_nh_warmup ); if( dm > 0 ) { if( dm <= 5 ) { PrintToChatAll( "\x04========[ warmup ending in %d ]========", dm ); } SetConVarInt( g_h_nh_warmup, dm - 1 ); } new time = GameRules_GetProp( "m_iRoundTime" ); if( time < 420 * 60 ) time = 420 * 60 + 1; GameRules_SetProp( "m_iRoundTime", time + 1, 4, 0, true ); new String:name[65]; for( new i = 1; i < GetMaxEntities(); ++i ) { if( !IsValidEdict(i) || !IsValidEntity(i) ) continue; if( i < MaxClients && IsClientConnected( i ) && IsClientInGame( i ) ) { if( dm > 0 ) { new secs = dm % 60; new mins = (dm - secs) / 60; PrintHintText( i, "---[ WARMUP %d:%02d ]---", mins, secs ); } else { PrintHintText( i, "---[ WARMUP ]---" ); } continue; } GetEdictClassname( i, name, sizeof(name) ); if( StrContains( name, "weapon_c4" ) != -1 ) { RemoveEdict( i ); } } } public OnClientPutInServer( client ) { if( g_h_execServerCfgTimer != INVALID_HANDLE ) { KillTimer( g_h_execServerCfgTimer ); g_h_execServerCfgTimer = INVALID_HANDLE; } SDKHook( client, SDKHook_PostThinkPost, Hook_PostThinkPost ); } public Hook_PostThinkPost( entity ) { new dm = GetConVarInt( g_h_nh_warmup ); if( dm ) SetEntProp( entity, Prop_Send, "m_bInBuyZone", 1 ); } public OnClientDisconnect( client ) { if( IsFakeClient( client ) ) return; for( new i = 1; i < MaxClients; ++i ) { if( i == client ) continue; if( IsClientConnected( i ) && IsClientInGame( i ) && !IsFakeClient( i ) ) return; } SetConVarInt( g_h_nh_warmup, 0 ); if( g_h_execServerCfgTimer != INVALID_HANDLE ) KillTimer( g_h_execServerCfgTimer ); g_h_execServerCfgTimer = CreateTimer( 30.0, ExecServerCfg, _ ); } public Action:ExecServerCfg( Handle:timer, any:unused ) { ServerCommand( "exec server.cfg" ); g_h_execServerCfgTimer = INVALID_HANDLE; } public Event_PlayerSpawn( Handle:event, const String:name[], bool dontBroadcast ) { new dmmode = GetConVarInt( g_h_nh_warmup ); new uid = GetEventInt( event, "userid" ); new id = GetClientOfUserId( uid ); if( dmmode ) SetEntData( id, g_iAccount, 16000, 4, true ); } public Event_PlayerDeath( Handle:event, const String:name[], bool dontBroadcast ) { CreateTimer( 0.15, OneChance, 0 ); CreateTimer( 1.5, RespawnPlayerDeathmatch, GetEventInt( event, "userid" ) ); } public Action:RespawnPlayerDeathmatch( Handle:timer, any:userid ) { new dmmode = GetConVarInt( g_h_nh_warmup ); if( !dmmode ) return; new id = GetClientOfUserId( userid ); if( !id ) return; CS_RespawnPlayer( id ); } public VerifyTeamCounts() { new entToKickT = 0; new entToKickCT = 0; new countCT = 0; new countT = 0; new maxTeam = GetConVarInt( g_h_nh_teamlimit ); for( new i = 1; i < MaxClients; ++i ) { if( !IsClientConnected( i ) || !IsClientInGame( i ) ) continue; new playerTeam = GetClientTeam(i); if( playerTeam == CS_TEAM_T ) { ++countT; if( IsFakeClient( i ) && (!entToKickCT || !IsPlayerAlive( i )) ) { entToKickT = i; } } if( playerTeam == CS_TEAM_CT ) { ++countCT; if( IsFakeClient( i ) && (!entToKickCT || !IsPlayerAlive( i )) ) { entToKickCT = i; } } } if( countCT > maxTeam && entToKickCT ) { KickClient( entToKickCT, "kicked for game balance" ); } if( countT > maxTeam && entToKickT ) { KickClient( entToKickT, "kicked for game balance" ); } } public bool:CanJoinTeam( id, oldTeam, newTeam ) { new countT = 0; new countCT = 0; new maxTeam = GetConVarInt( g_h_nh_teamlimit ); for( new i = 1; i < MaxClients; ++i ) { if( i == id ) continue; if( !IsClientConnected( i ) || !IsClientInGame( i ) || IsFakeClient( i ) ) continue; new playerTeam = GetClientTeam(i); if( playerTeam == CS_TEAM_T ) ++countT; if( playerTeam == CS_TEAM_CT ) ++countCT; } if( (newTeam == CS_TEAM_T && countT >= maxTeam) || (newTeam == CS_TEAM_CT && countCT >= maxTeam) ) { return false; } return true; } public Action:Listener_JoinTeam( id, const String: command[], args ) { new String:sArg1[3]; GetCmdArg(1, sArg1, sizeof(sArg1)); new newTeam = StringToInt(sArg1); new oldTeam = GetClientTeam( id ); if( !CanJoinTeam( id, oldTeam, newTeam ) ) { ChangeClientTeam( id, oldTeam ); PrintHintText( id, "team is full" ); return Plugin_Handled; } VerifyTeamCounts(); return Plugin_Continue; } public Action:Event_PlayerTeam( Handle:event, const String:name[], bool dontBroadcast ) { new uid = GetEventInt( event, "userid" ); new id = GetClientOfUserId( uid ); new oldTeam = GetEventInt( event, "oldteam" ); new newTeam = GetEventInt( event, "team" ); if( !CanJoinTeam( id, oldTeam, newTeam ) ) { PrintCenterText( id, "team is full" ); SetEventBroadcast( event, true ); return Plugin_Handled; } VerifyTeamCounts(); return Plugin_Continue; } public Action:OneChance(Handle:timer, any:unused) { if( g_roundCount != g_maxrounds ) return; if( g_oneChanceDone ) return; new dm = GetConVarInt( g_h_nh_warmup ); if( dm ) return; new ctAlive = 0; new tAlive = 0; new clutcherT = 0; new clutcherCT = 0; for( new i = 1; i <= MaxClients; ++i ) { if( !IsClientInGame(i) || !IsPlayerAlive(i) ) continue; new playerTeam = GetClientTeam(i); if( playerTeam == CS_TEAM_CT ) { ++ctAlive; if( ctAlive > 1 ) clutcherCT = 0; else clutcherCT = i; } else if( playerTeam == CS_TEAM_T ) { ++tAlive; if( tAlive > 1 ) clutcherT = 0; else clutcherT = i; } } if( !(tAlive == 1 && ctAlive > 2) && !(ctAlive == 1 && tAlive > 2) ) return; new clutcher = clutcherT ? clutcherT : clutcherCT; decl String:clutcherName[64]; GetClientName( clutcher, clutcherName, sizeof(clutcherName) ); PrintToChatAll( "\x01%s \x04has one chance, one opportunity. will they seize it, or will they let it slip?", clutcherName ); Client_RemoveAllWeapons( clutcher ); Client_GiveWeapon( clutcher, "weapon_awp", false ); Client_GiveWeapon( clutcher, "weapon_deagle", false ); Client_GiveWeapon( clutcher, "weapon_knife", true ); GivePlayerItem( clutcher, "weapon_flashbang" ); GivePlayerItem( clutcher, "weapon_flashbang" ); GivePlayerItem( clutcher, "weapon_hegrenade" ); SetEntityHealth( clutcher, 100 ); Client_SetArmor( clutcher, 100 ); SetEntProp( clutcher, Prop_Send, "m_bHasHelmet", 1, 1); g_oneChanceDone = true; } public Event_RoundStart( Handle:event, const String:name[], bool:dontBroadcast ) { new wepIdx; new playerTeam; g_oneChanceDone = false; g_CtScore = GetTeamScore( CS_TEAM_CT ); g_TScore = GetTeamScore( CS_TEAM_T ); new newRoundCount = g_CtScore = g_TScore + 1; if( newRoundCount < g_roundCount ) { halftime = false; g_CtScore = 0; g_TScore = 0; g_roundCount = 0; g_doReset = true; } else { g_roundCount = newRoundCount; } for( new client = 1; client <= MaxClients; client++ ) { if( !IsClientConnected( client ) || !IsClientInGame( client ) ) continue; else if( g_doReset ) { 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 OnGameFrame() { } 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"); } } 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 <= MaxClients; i++ ) { if( IsClientInGame( i ) && IsClientConnected( 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 ); }