@@ -73,10 +73,13 @@ public void HandleCoaches()
7373 coachKillTimer ? . Kill ( ) ;
7474 coachKillTimer = null ;
7575 int freezeTime = ConVar . Find ( "mp_freezetime" ) ! . GetPrimitiveValue < int > ( ) ;
76+ freezeTime = freezeTime > 2 ? freezeTime : 2 ;
7677 coachKillTimer ??= AddTimer ( freezeTime - 1.5f , KillCoaches ) ;
7778 HashSet < CCSPlayerController > coaches = GetAllCoaches ( ) ;
79+ HashSet < CCSPlayerController > competitiveSpawnCoaches = new ( ) ;
80+ if ( spawnsData . Values . Any ( list => list . Count == 0 ) ) GetSpawns ( ) ;
7881
79- foreach ( var coach in coaches )
82+ foreach ( CCSPlayerController coach in coaches )
8083 {
8184 if ( ! IsPlayerValid ( coach ) ) continue ;
8285 Team coachTeam = matchzyTeam1 . coach . Contains ( coach ) ? matchzyTeam1 : matchzyTeam2 ;
@@ -90,53 +93,64 @@ public void HandleCoaches()
9093 coach . ActionTrackingServices ! . MatchStats . Assists = 0 ;
9194 coach . ActionTrackingServices ! . MatchStats . Damage = 0 ;
9295
93- bool isCompetitiveSpawn = false ;
94-
96+ List < Position > teamPositions = spawnsData [ coach . TeamNum ] ;
9597 Position coachPosition = new ( coach . PlayerPawn . Value ! . CBodyComponent ! . SceneNode ! . AbsOrigin , coach . PlayerPawn . Value ! . CBodyComponent ! . SceneNode ! . AbsRotation ) ;
96- List < Position > teamPositions = spawnsData [ ( byte ) coachTeamNum ] ;
97-
98- // Elevating the coach so that they don't block the players.
99- coach ! . PlayerPawn . Value ! . Teleport ( new Vector ( coach . PlayerPawn . Value . CBodyComponent ! . SceneNode ! . AbsOrigin . X , coach . PlayerPawn . Value . CBodyComponent ! . SceneNode ! . AbsOrigin . Y , coach . PlayerPawn . Value . CBodyComponent ! . SceneNode ! . AbsOrigin . Z + 75.0f ) , coach . PlayerPawn . Value . EyeAngles , new Vector ( 0 , 0 , 0 ) ) ;
100- coach . PlayerPawn . Value ! . MoveType = MoveType_t . MOVETYPE_NONE ;
101- coach . PlayerPawn . Value ! . ActualMoveType = MoveType_t . MOVETYPE_NONE ;
102-
103- SetPlayerInvisible ( player : coach , setWeaponsInvisible : false ) ;
10498
10599 foreach ( Position position in teamPositions )
106100 {
107101 if ( position . Equals ( coachPosition ) )
108102 {
109- isCompetitiveSpawn = true ;
103+ competitiveSpawnCoaches . Add ( coach ) ;
110104 break ;
111105 }
112106 }
113- if ( isCompetitiveSpawn )
107+ SetPlayerInvisible ( player : coach , setWeaponsInvisible : false ) ;
108+ // Elevating coach before dropping the C4 to prevent it going inside the ground.
109+ AddTimer ( 0.05f , ( ) =>
110+ {
111+ coach ! . PlayerPawn . Value ! . Teleport ( new Vector ( coachPosition . PlayerPosition . X , coachPosition . PlayerPosition . Y , coachPosition . PlayerPosition . Z + 20.0f ) , coachPosition . PlayerAngle , new Vector ( 0 , 0 , 0 ) ) ;
112+ HandleCoachWeapons ( coach ) ;
113+ coach ! . PlayerPawn . Value . Teleport ( coachPosition . PlayerPosition , coachPosition . PlayerAngle , new Vector ( 0 , 0 , 0 ) ) ;
114+ } ) ;
115+
116+ }
117+
118+ var playerEntities = Utilities . FindAllEntitiesByDesignerName < CCSPlayerController > ( "cs_player_controller" ) ;
119+
120+ // foreach (var key in playerData.Keys)
121+ // {
122+ foreach ( var player in playerEntities )
123+ {
124+ if ( ! IsPlayerValid ( player ) ) continue ;
125+ // CCSPlayerController player = playerData[key];
126+ List < Position > teamPositions = spawnsData [ player . TeamNum ] ;
127+ Position playerPosition = new ( player . PlayerPawn . Value ! . CBodyComponent ! . SceneNode ! . AbsOrigin , player . PlayerPawn . Value ! . CBodyComponent ! . SceneNode ! . AbsRotation ) ;
128+ bool isCompetitiveSpawn = false ;
129+ foreach ( Position position in teamPositions )
114130 {
115- foreach ( var key in playerData . Keys )
131+ if ( position . Equals ( playerPosition ) )
116132 {
117- CCSPlayerController player = playerData [ key ] ;
118- if ( ! IsPlayerValid ( player ) || coaches . Contains ( player ) || player . TeamNum != ( byte ) coachTeamNum ) continue ;
119- bool playerOnCompetitiveSpawn = false ;
120- Position playerPosition = new ( player . PlayerPawn . Value ! . CBodyComponent ! . SceneNode ! . AbsOrigin , player . PlayerPawn . Value ! . CBodyComponent ! . SceneNode ! . AbsRotation ) ;
121- foreach ( Position position in teamPositions )
122- {
123- if ( position . Equals ( playerPosition ) )
124- {
125- playerOnCompetitiveSpawn = true ;
126- break ;
127- }
128- }
129- // No need to swap the player if they are already on a competitive spawn.
130- if ( playerOnCompetitiveSpawn ) continue ;
131- // Swapping positions of the coach and the player so that the coach doesn't take any competitive spawn.
132- AddTimer ( 0.1f , ( ) =>
133- {
134- coach ! . PlayerPawn . Value . Teleport ( new Vector ( playerPosition . PlayerPosition . X , playerPosition . PlayerPosition . Y , playerPosition . PlayerPosition . Z + 150.0f ) , playerPosition . PlayerAngle , new Vector ( 0 , 0 , 0 ) ) ;
135- player ! . PlayerPawn . Value . Teleport ( coachPosition . PlayerPosition , coachPosition . PlayerAngle , new Vector ( 0 , 0 , 0 ) ) ;
136- } ) ;
133+ isCompetitiveSpawn = true ;
134+ break ;
137135 }
138136 }
139- HandleCoachWeapons ( coach ) ;
137+ // Player is already on a competitive spawn, no need to swap.
138+ if ( isCompetitiveSpawn ) continue ;
139+
140+ CCSPlayerController ? coach = competitiveSpawnCoaches . FirstOrDefault ( ( CCSPlayerController coach ) => coach . Team == player . Team ) ;
141+ if ( coach is null ) continue ;
142+ competitiveSpawnCoaches . Remove ( coach ) ;
143+
144+ Position coachPosition = new ( coach . PlayerPawn . Value ! . CBodyComponent ! . SceneNode ! . AbsOrigin , coach . PlayerPawn . Value ! . CBodyComponent ! . SceneNode ! . AbsRotation ) ;
145+ AddTimer ( 0.1f , ( ) =>
146+ {
147+ coach ! . PlayerPawn . Value ! . Teleport ( new Vector ( playerPosition . PlayerPosition . X , playerPosition . PlayerPosition . Y , playerPosition . PlayerPosition . Z ) , playerPosition . PlayerAngle , new Vector ( 0 , 0 , 0 ) ) ;
148+ player ! . PlayerPawn . Value . Teleport ( coachPosition . PlayerPosition , coachPosition . PlayerAngle , new Vector ( 0 , 0 , 0 ) ) ;
149+ } ) ;
150+
151+ // Stopping the coaches from moving, so that they don't block the players.
152+ coach . PlayerPawn . Value ! . MoveType = MoveType_t . MOVETYPE_NONE ;
153+ coach . PlayerPawn . Value ! . ActualMoveType = MoveType_t . MOVETYPE_NONE ;
140154 }
141155 }
142156
@@ -187,6 +201,7 @@ private void HandleCoachTeam(CCSPlayerController playerController)
187201
188202 private void KillCoaches ( )
189203 {
204+ if ( isPaused || IsTacticalTimeoutActive ( ) ) return ;
190205 HashSet < CCSPlayerController > coaches = GetAllCoaches ( ) ;
191206 string suicidePenalty = GetConvarStringValue ( ConVar . Find ( "mp_suicide_penalty" ) ) ;
192207 string deathDropGunEnabled = GetConvarStringValue ( ConVar . Find ( "mp_death_drop_gun" ) ) ;
@@ -201,6 +216,12 @@ private void KillCoaches()
201216 foreach ( var coach in coaches )
202217 {
203218 if ( ! IsPlayerValid ( coach ) ) continue ;
219+ if ( isPaused || IsTacticalTimeoutActive ( ) ) continue ;
220+
221+ Position coachPosition = new ( coach . PlayerPawn . Value ! . CBodyComponent ! . SceneNode ! . AbsOrigin , coach . PlayerPawn . Value ! . CBodyComponent ! . SceneNode ! . AbsRotation ) ;
222+ coach ! . PlayerPawn . Value ! . Teleport ( new Vector ( coachPosition . PlayerPosition . X , coachPosition . PlayerPosition . Y , coachPosition . PlayerPosition . Z + 20.0f ) , coachPosition . PlayerAngle , new Vector ( 0 , 0 , 0 ) ) ;
223+ // Dropping the C4 if it was picked up or passed to the coach.
224+ DropWeaponByDesignerName ( coach , "weapon_c4" ) ;
204225 coach . PlayerPawn . Value ! . CommitSuicide ( explode : false , force : true ) ;
205226 }
206227 Server . ExecuteCommand ( $ "mp_suicide_penalty { suicidePenalty } ; mp_death_drop_gun { deathDropGunEnabled } ; spec_freeze_time { specFreezeTime } ; spec_freeze_time_lock { specFreezeTimeLock } ; spec_freeze_deathanim_time { specFreezeDeathanim } ;") ;
0 commit comments