summaryrefslogtreecommitdiff
path: root/sourcemod/scripting/game_manager.sp
diff options
context:
space:
mode:
Diffstat (limited to 'sourcemod/scripting/game_manager.sp')
-rw-r--r--sourcemod/scripting/game_manager.sp379
1 files changed, 321 insertions, 58 deletions
diff --git a/sourcemod/scripting/game_manager.sp b/sourcemod/scripting/game_manager.sp
index ec6d198..90c83e9 100644
--- a/sourcemod/scripting/game_manager.sp
+++ b/sourcemod/scripting/game_manager.sp
@@ -23,9 +23,17 @@ 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;
@@ -34,29 +42,42 @@ new Handle:g_f_on_ht = INVALID_HANDLE;
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);
+ 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(){
+public OnConfigsExecuted() {
halftime = false;
}
-// Hooking events at plugin start
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_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 );
- g_f_on_ht = CreateGlobalForward("nthvnHalftime", ET_Ignore);
// Finding offset for CS cash
g_iAccount = FindSendPropOffs("CCSPlayer", "m_iAccount");
@@ -64,8 +85,241 @@ public OnPluginStart() {
SetFailState("m_iAccount offset not found");
}
-public Event_PlayerDeath( Handle:event, const String:name[], bool dontBroadcast ) {
+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) {
@@ -74,6 +328,10 @@ public Action:OneChance(Handle:timer, any:unused) {
if( g_oneChanceDone )
return;
+
+ new dm = GetConVarInt( g_h_nh_warmup );
+ if( dm )
+ return;
new ctAlive = 0;
new tAlive = 0;
@@ -107,27 +365,24 @@ public Action:OneChance(Handle:timer, any:unused) {
new clutcher = clutcherT ? clutcherT : clutcherCT;
decl String:clutcherName[64];
- GetClientName(clutcher, clutcherName, sizeof(clutcherName));
+ 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_knife", true);
- Client_GiveWeapon( clutcher, "weapon_awp", false);
- Client_GiveWeapon( clutcher, "weapon_deagle", false);
- GivePlayerItem( clutcher, "weapon_flashbang");
- GivePlayerItem( clutcher, "weapon_flashbang");
-
- SetEntityHealth( clutcher, 100);
- Client_SetArmor( clutcher, 100);
+ 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;
}
-// 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;
@@ -135,40 +390,55 @@ public Event_RoundStart( Handle:event, const String:name[], bool:dontBroadcast )
g_oneChanceDone = false;
- 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_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 Event_RoundEnd (Handle:event, const String:name[], bool:dontBroadcast)
+public OnGameFrame() {
+}
+
+public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
new reason = GetEventInt(event, "reason");
new winner = GetEventInt(event, "winner");
@@ -201,7 +471,6 @@ public Event_RoundEnd (Handle:event, const String:name[], bool:dontBroadcast)
}
}
- 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 );
@@ -214,14 +483,8 @@ public Event_RoundEnd (Handle:event, const String:name[], bool:dontBroadcast)
Call_Finish();
halftime = true;
- for( new i = 1; i <= GetMaxClients(); i++ ) {
+ for( new i = 1; i <= MaxClients; i++ ) {
if( IsClientInGame( i ) && IsClientConnected( i ) ) {
-
- // kill bots
- if( IsFakeClient( i ) ) {
- ForcePlayerSuicide( i );
- }
-
g_doReset = true;
playerTeam = GetClientTeam(i);