Skip to content

Commit 970849b

Browse files
committed
Fix Commander Lottery Freecam Bug
- Fixes bug where commander applicants were in freecam for ~15 seconds, which could potentially be abused to scout locations before the round starts - Now all applicants are spawned into a unit at their HQ/Nest - Right before the round starts all applicants will be put in freecam for added suspense on who will get promoted - As soon as the round starts, only the lottery winner is promoted and smoothly switches to RTS view while all other applicants are returned to their team's default spawn unit
1 parent 621cdb6 commit 970849b

File tree

3 files changed

+56
-31
lines changed

3 files changed

+56
-31
lines changed

Si_CommManagement/CommanderApplications.cs

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,21 +267,11 @@ private static class CommanderManager_Patch_Strategy_TimerUpdate
267267
{
268268
private static void Postfix(MP_Strategy __instance)
269269
{
270-
if (!CommanderManager._BlockRoundStartUntilEnoughApplicants.Value)
271-
{
272-
return;
273-
}
274-
275270
if (__instance.GameOver)
276271
{
277272
return;
278273
}
279274

280-
if (AllTeamsHaveCommanderApplicants())
281-
{
282-
return;
283-
}
284-
285275
float timerValue;
286276

287277
#if NET6_0
@@ -292,14 +282,66 @@ private static void Postfix(MP_Strategy __instance)
292282
timerValue = (float)timerField.GetValue(__instance);
293283
#endif
294284

285+
// the last second before the round is about to start
286+
if (timerValue <= 1f && timerValue > 0f)
287+
{
288+
// switch all applicants to freecam
289+
for (int i = 0; i < SiConstants.MaxPlayableTeams; i++)
290+
{
291+
if (commanderApplicants[i].Count == 0)
292+
{
293+
continue;
294+
}
295+
296+
foreach (Player applicantPlayer in commanderApplicants[i])
297+
{
298+
if (applicantPlayer == null)
299+
{
300+
continue;
301+
}
302+
303+
// send to role NONE
304+
CommanderPrimitives.SendToRole(applicantPlayer, GameModeExt.ETeamRole.NONE);
305+
MelonLogger.Msg("Player " + applicantPlayer.PlayerName + " is being sent to role NONE.");
306+
307+
// force switching to role NONE
308+
GameMode.CurrentGameMode.DestroyAllUnitsForPlayer(applicantPlayer);
309+
#if NET6_0
310+
if (__instance.PlayerRespawnTracker.ContainsKey(applicantPlayer))
311+
{
312+
__instance.PlayerRespawnTracker.Remove(applicantPlayer);
313+
}
314+
#else
315+
FieldInfo playerRespawnTrackerField = typeof(MP_Strategy).GetField("PlayerRespawnTracker", BindingFlags.NonPublic | BindingFlags.Instance);
316+
Dictionary<Player, float> localPlayerRespawnTracker = (Dictionary<Player, float>)playerRespawnTrackerField.GetValue(__instance);
317+
if (localPlayerRespawnTracker.ContainsKey(applicantPlayer))
318+
{
319+
localPlayerRespawnTracker.Remove(applicantPlayer);
320+
playerRespawnTrackerField.SetValue(__instance, localPlayerRespawnTracker);
321+
}
322+
#endif
323+
}
324+
}
325+
}
326+
327+
if (!CommanderManager._BlockRoundStartUntilEnoughApplicants.Value)
328+
{
329+
return;
330+
}
331+
332+
if (AllTeamsHaveCommanderApplicants())
333+
{
334+
return;
335+
}
336+
295337
if (timerValue <= 5f && timerValue > 4f)
296338
{
297339
HelperMethods.ReplyToCommand("Round cannot start because all teams don't have a commander. Chat !commander to apply.");
298340

299341
#if NET6_0
300-
__instance.Timer = 21f;
342+
__instance.Timer = 26f;
301343
#else
302-
timerField.SetValue(__instance, 21f);
344+
timerField.SetValue(__instance, 26f);
303345
#endif
304346
}
305347
}

Si_CommManagement/CommanderPrimitives.cs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,6 @@ public static void PromoteToCommander(Player CommanderPlayer)
5959
{
6060
MP_Strategy strategyInstance = GameObject.FindObjectOfType<MP_Strategy>();
6161

62-
// mimic switching to role NONE first
63-
GameMode.CurrentGameMode.DestroyAllUnitsForPlayer(CommanderPlayer);
64-
#if NET6_0
65-
if (strategyInstance.PlayerRespawnTracker.ContainsKey(CommanderPlayer))
66-
{
67-
strategyInstance.PlayerRespawnTracker.Remove(CommanderPlayer);
68-
}
69-
#else
70-
FieldInfo playerRespawnTrackerField = typeof(MP_Strategy).GetField("PlayerRespawnTracker", BindingFlags.NonPublic | BindingFlags.Instance);
71-
Dictionary<Player, float> localPlayerRespawnTracker = (Dictionary<Player, float>)playerRespawnTrackerField.GetValue(strategyInstance);
72-
if (localPlayerRespawnTracker.ContainsKey(CommanderPlayer))
73-
{
74-
localPlayerRespawnTracker.Remove(CommanderPlayer);
75-
playerRespawnTrackerField.SetValue(strategyInstance, localPlayerRespawnTracker);
76-
}
77-
#endif
78-
7962
// now mimic switching to COMMANDER role
8063
BaseTeamSetup strategyTeamInstance = strategyInstance.GetTeamSetup(CommanderPlayer.Team);
8164
MelonLogger.Msg("Trying to promote " + CommanderPlayer.PlayerName + " on team " + CommanderPlayer.Team.TeamShortName);

Si_CommManagement/Si_CommanderManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ You should have received a copy of the GNU General Public License
3333
using SilicaAdminMod;
3434
using System.Linq;
3535

36-
[assembly: MelonInfo(typeof(CommanderManager), "Commander Management", "1.6.12", "databomb", "https://github.com/data-bomb/Silica")]
36+
[assembly: MelonInfo(typeof(CommanderManager), "Commander Management", "1.7.0", "databomb", "https://github.com/data-bomb/Silica")]
3737
[assembly: MelonGame("Bohemia Interactive", "Silica")]
3838
[assembly: MelonOptionalDependencies("Admin Mod")]
3939

@@ -131,7 +131,7 @@ public void OnRequestCommander(object? sender, OnRequestCommanderArgs args)
131131

132132
MelonLogger.Msg("Denied early game commander join for " + args.Requester.PlayerName);
133133
args.Block = true;
134-
args.PreventSpawnWhenBlocked = true;
134+
args.PreventSpawnWhenBlocked = false;
135135
return;
136136
}
137137
}

0 commit comments

Comments
 (0)