Skip to content

Commit 56e9ca4

Browse files
Merge pull request #218 from shobhit-pathak/dev
0.8.4
2 parents 9be075e + 1b56de1 commit 56e9ca4

File tree

7 files changed

+145
-74
lines changed

7 files changed

+145
-74
lines changed

BackupManagement.cs

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -200,34 +200,6 @@ private void RestoreRoundBackup(CCSPlayerController? player, string fileName) {
200200
matchConfig = Newtonsoft.Json.JsonConvert.DeserializeObject<MatchConfig>(matchConfigValue)!;
201201
SetupRoundBackupFile();
202202
}
203-
if (backupData.TryGetValue("map_name", out var map_name))
204-
{
205-
if (map_name != Server.MapName)
206-
{
207-
ChangeMap(map_name, 0);
208-
isRoundRestorePending = true;
209-
pendingRestoreFileName = fileName;
210-
// Returning from here, backup will be restored again once the map is changed.
211-
return;
212-
}
213-
}
214-
215-
// This is done after checking map_name so that we load the correct map first
216-
if (gameRules.WarmupPeriod)
217-
{
218-
if (!isRoundRestorePending)
219-
{
220-
isRoundRestorePending = true;
221-
pendingRestoreFileName = fileName;
222-
PrintToAllChat(Localizer["matchzy.restore.loadedsuccessfully", fileName]);
223-
return;
224-
}
225-
else
226-
{
227-
liveSetupRequired = true;
228-
}
229-
}
230-
231203
if (backupData.TryGetValue("team1", out var team1config))
232204
{
233205
matchzyTeam1 = Newtonsoft.Json.JsonConvert.DeserializeObject<Team>(team1config)!;
@@ -236,7 +208,6 @@ private void RestoreRoundBackup(CCSPlayerController? player, string fileName) {
236208
{
237209
matchzyTeam2 = Newtonsoft.Json.JsonConvert.DeserializeObject<Team>(team2config)!;
238210
}
239-
240211
if (backupData.TryGetValue("team1_side", out var team1Side))
241212
{
242213

@@ -257,7 +228,33 @@ private void RestoreRoundBackup(CCSPlayerController? player, string fileName) {
257228
// SwapSidesInTeamData(false);
258229
}
259230
}
231+
if (backupData.TryGetValue("map_name", out var map_name))
232+
{
233+
if (map_name != Server.MapName)
234+
{
235+
ChangeMap(map_name, 0);
236+
isRoundRestorePending = true;
237+
pendingRestoreFileName = fileName;
238+
// Returning from here, backup will be restored again once the map is changed.
239+
return;
240+
}
241+
}
260242

243+
// This is done after checking map_name so that we load the correct map first
244+
if (gameRules.WarmupPeriod)
245+
{
246+
if (!isRoundRestorePending)
247+
{
248+
isRoundRestorePending = true;
249+
pendingRestoreFileName = fileName;
250+
PrintToAllChat(Localizer["matchzy.restore.loadedsuccessfully", fileName]);
251+
return;
252+
}
253+
else
254+
{
255+
liveSetupRequired = true;
256+
}
257+
}
261258
if (backupData.TryGetValue("TerroristTimeOuts", out var terroristTimeouts))
262259
{
263260
gameRules.TerroristTimeOuts = int.Parse(terroristTimeouts);

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# MatchZy Changelog
22

3+
# 0.8.4
4+
5+
#### August 27, 2024
6+
7+
- Fixes in coach system, where players would spawn into each other.
8+
- Improved backup loading (teams will be locked automatically with the first restore if match setup was being used.)
9+
- Fixed veto bug where ready system would not work after the veto.
10+
- Updated Uzbek translations
11+
312
# 0.8.3
413

514
#### August 25, 2024

Coach.cs

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -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};");

EventHandlers.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,41 @@ public HookResult EventRoundStartHandler(EventRoundStart @event, GameEventInfo i
160160
}
161161
}
162162

163+
public HookResult EventRoundFreezeEndHandler(EventRoundFreezeEnd @event, GameEventInfo info)
164+
{
165+
try
166+
{
167+
if (!matchStarted) return HookResult.Continue;
168+
HashSet<CCSPlayerController> coaches = GetAllCoaches();
169+
170+
foreach (var coach in coaches)
171+
{
172+
if (!IsPlayerValid(coach)) continue;
173+
// If coaches are still left alive after freezetime ends, this code will force them to spectate their team again.
174+
if (coach.PlayerPawn.Value?.LifeState != (byte)LifeState_t.LIFE_ALIVE) continue;
175+
176+
Position coachPosition = new(coach.PlayerPawn.Value!.CBodyComponent!.SceneNode!.AbsOrigin, coach.PlayerPawn.Value!.CBodyComponent!.SceneNode!.AbsRotation);
177+
coach!.PlayerPawn.Value!.Teleport(new Vector(coachPosition.PlayerPosition.X, coachPosition.PlayerPosition.Y, coachPosition.PlayerPosition.Z + 20.0f), coachPosition.PlayerAngle, new Vector(0, 0, 0));
178+
// Dropping the C4 if it was picked up or passed to the coach.
179+
DropWeaponByDesignerName(coach, "weapon_c4");
180+
AddTimer(1.5f, () =>
181+
{
182+
coach!.PlayerPawn.Value!.Teleport(new Vector(coachPosition.PlayerPosition.X, coachPosition.PlayerPosition.Y, coachPosition.PlayerPosition.Z + 20.0f), coachPosition.PlayerAngle, new Vector(0, 0, 0));
183+
DropWeaponByDesignerName(coach, "weapon_c4");
184+
CsTeam oldTeam = GetCoachTeam(coach);
185+
coach.ChangeTeam(CsTeam.Spectator);
186+
AddTimer(0.01f, () => coach.ChangeTeam(oldTeam));
187+
});
188+
}
189+
return HookResult.Continue;
190+
}
191+
catch (Exception e)
192+
{
193+
Log($"[EventRoundFreezeEnd FATAL] An error occurred: {e.Message}");
194+
return HookResult.Continue;
195+
}
196+
}
197+
163198
public void OnEntitySpawnedHandler(CEntityInstance entity)
164199
{
165200
try

MatchZy.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public partial class MatchZy : BasePlugin
1313
{
1414

1515
public override string ModuleName => "MatchZy";
16-
public override string ModuleVersion => "0.8.3";
16+
public override string ModuleVersion => "0.8.4";
1717

1818
public override string ModuleAuthor => "WD- (https://github.com/shobhit-pathak/)";
1919

@@ -204,6 +204,7 @@ public override void Load(bool hotReload) {
204204
RegisterEventHandler<EventCsWinPanelRound>(EventCsWinPanelRoundHandler, hookMode: HookMode.Pre);
205205
RegisterEventHandler<EventCsWinPanelMatch>(EventCsWinPanelMatchHandler);
206206
RegisterEventHandler<EventRoundStart>(EventRoundStartHandler);
207+
RegisterEventHandler<EventRoundFreezeEnd>(EventRoundFreezeEndHandler);
207208
RegisterEventHandler<EventPlayerDeath>(EventPlayerDeathPreHandler, hookMode: HookMode.Pre);
208209
RegisterListener<Listeners.OnClientDisconnectPost>(playerSlot => {
209210
// May not be required, but just to be on safe side so that player data is properly updated in dictionaries

Utility.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ private void StartKnifeRound()
227227
}
228228

229229
// Setting match phases bools
230+
matchStarted = true;
230231
isKnifeRound = true;
231232
readyAvailable = false;
232233
isWarmup = false;
@@ -426,12 +427,15 @@ private void ResetMatch(bool warmupCfgRequired = true)
426427

427428
foreach (var coach in coaches)
428429
{
430+
if (!IsPlayerValid(coach)) continue;
429431
coach.Clan = "";
430432
SetPlayerVisible(coach);
431433
}
432434

433435
matchzyTeam1.coach = new();
434436
matchzyTeam2.coach = new();
437+
coachKillTimer?.Kill();
438+
coachKillTimer = null;
435439

436440
matchzyTeam1.seriesScore = 0;
437441
matchzyTeam2.seriesScore = 0;
@@ -693,7 +697,6 @@ private void HandleMatchStart()
693697
{
694698
isPractice = false;
695699
isDryRun = false;
696-
matchStarted = true;
697700
if (isRoundRestorePending)
698701
{
699702
RestoreRoundBackup(null, pendingRestoreFileName);
@@ -1013,6 +1016,8 @@ private void HandlePostRoundEndEvent(EventRoundEnd @event)
10131016
{
10141017
if (isMatchLive)
10151018
{
1019+
coachKillTimer?.Kill();
1020+
coachKillTimer = null;
10161021
(int t1score, int t2score) = GetTeamsScore();
10171022
Server.PrintToChatAll($"{chatPrefix} {ChatColors.Green}{matchzyTeam1.teamName} [{t1score} - {t2score}] {matchzyTeam2.teamName}");
10181023

@@ -1260,6 +1265,9 @@ private void UnpauseMatch()
12601265

12611266
private void SetMatchPausedFlags()
12621267
{
1268+
coachKillTimer?.Kill();
1269+
coachKillTimer = null;
1270+
12631271
Server.ExecuteCommand("mp_pause_match;");
12641272
isPaused = true;
12651273

0 commit comments

Comments
 (0)