Skip to content

Commit

Permalink
Add Mutiny for Commander Management Mod
Browse files Browse the repository at this point in the history
- Adds player !mutiny command which can demote the current commander
- Votes for mutiny are not broadcast to the current commander (only other FPS teammates)
  • Loading branch information
data-bomb committed Jul 20, 2024
1 parent 3b1d987 commit 9c8a60f
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Si_CommManagement/CommanderApplications.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ public static void Postfix(MusicJukeboxHandler __instance, GameMode __0)
{
try
{
Mutineer.ClearMutineerList();

if (CommanderApplications.commanderApplicants == null || CommanderApplications.previousCommanders == null || promotedCommanders == null)
{
return;
Expand Down
143 changes: 143 additions & 0 deletions Si_CommManagement/Mutineer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
Silica Commander Management Mod
Copyright (C) 2023-2024 by databomb
* License *
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#if NET6_0
using Il2Cpp;
#endif

using HarmonyLib;
using SilicaAdminMod;
using System;
using System.Collections.Generic;
using UnityEngine;
using MelonLoader;

namespace Si_CommanderManagement
{
public class Mutineer
{
public static void InitializeMutineerList()
{
CommanderManager.mutineerPlayers = new List<Player>[SiConstants.MaxPlayableTeams + 1];
for (int i = 0; i < SiConstants.MaxPlayableTeams; i++)
{
CommanderManager.mutineerPlayers[i] = new List<Player>();
}
}

public static void ClearMutineerList()
{
for (int i = 0; i < SiConstants.MaxPlayableTeams; i++)
{
CommanderManager.mutineerPlayers[i].Clear();
}
}

public static void Command_Mutiny(Player? callerPlayer, String args)
{
if (callerPlayer == null)
{
HelperMethods.SendChatMessageToPlayer(callerPlayer, HelperMethods.chatPrefix, " Console not supported.");
return;
}

if (callerPlayer.Team == null)
{
HelperMethods.SendChatMessageToPlayer(callerPlayer, HelperMethods.chatPrefix, " On invalid team.");
return;
}

if (!GameMode.CurrentGameMode.GameOngoing)
{
HelperMethods.SendChatMessageToPlayer(callerPlayer, HelperMethods.chatPrefix, " Cannot mutiny at this time.");
return;
}

if (callerPlayer.IsCommander)
{
HelperMethods.SendChatMessageToPlayer(callerPlayer, HelperMethods.chatPrefix, " Cannot mutiny when commader.");
return;
}

MP_Strategy strategyInstance = GameObject.FindObjectOfType<MP_Strategy>();
if (strategyInstance.GetCommanderForTeam(callerPlayer.Team) == null)
{
HelperMethods.SendChatMessageToPlayer(callerPlayer, HelperMethods.chatPrefix, " Cannot mutiny when no one is commander.");
return;
}

// did the player already vote for surrender?
if (CommanderManager.mutineerPlayers[callerPlayer.Team.Index].Contains(callerPlayer))
{
HelperMethods.SendChatMessageToPlayer(callerPlayer, HelperMethods.chatPrefix, " Already voted to mutiny. ", MoreMutinyVotesNeeded(callerPlayer.Team).ToString(), " more players needed.");
return;
}

CommanderManager.mutineerPlayers[callerPlayer.Team.Index].Add(callerPlayer);

// if we haven't met the threshold then send a message to the teammates
if (CommanderManager.mutineerPlayers[callerPlayer.Team.Index].Count < TeammatesNeededForMutiny(callerPlayer.Team))
{
HelperMethods.SendChatMessageToTeamNoCommander(callerPlayer.Team, HelperMethods.chatPrefix, HelperMethods.GetTeamColor(callerPlayer), " ", callerPlayer.PlayerName, "</color> wants to mutiny. ", MoreMutinyVotesNeeded(callerPlayer.Team).ToString(), " more players needed.");

Check failure on line 97 in Si_CommManagement/Mutineer.cs

View workflow job for this annotation

GitHub Actions / build (Si_CommManagement)

'HelperMethods' does not contain a definition for 'SendChatMessageToTeamNoCommander'

Check failure on line 97 in Si_CommManagement/Mutineer.cs

View workflow job for this annotation

GitHub Actions / build (Si_CommManagement)

'HelperMethods' does not contain a definition for 'SendChatMessageToTeamNoCommander'

Check failure on line 97 in Si_CommManagement/Mutineer.cs

View workflow job for this annotation

GitHub Actions / build (Si_CommManagement)

'HelperMethods' does not contain a definition for 'SendChatMessageToTeamNoCommander'

Check failure on line 97 in Si_CommManagement/Mutineer.cs

View workflow job for this annotation

GitHub Actions / build (Si_CommManagement)

'HelperMethods' does not contain a definition for 'SendChatMessageToTeamNoCommander'
return;
}

Mutiny(strategyInstance, callerPlayer.Team);
}
public static int TeammatesNeededForMutiny(Team team)
{
int playerCount = team.GetNumPlayers();

// don't count the commander as a player here
MP_Strategy strategyInstance = GameObject.FindObjectOfType<MP_Strategy>();
playerCount -= (strategyInstance.GetCommanderForTeam(team) != null ? 1 : 0);

int teammatesNeeded = (int)Math.Ceiling(playerCount * 0.54f);
if (teammatesNeeded < 1)
{
return 1;
}

return teammatesNeeded;
}

public static int MoreMutinyVotesNeeded(Team team)
{
int teammatesNeeded = TeammatesNeededForMutiny(team);
int moreNeeded = teammatesNeeded - CommanderManager.mutineerPlayers[team.Index].Count;
if (moreNeeded < 1)
{
return 1;
}

return moreNeeded;
}

public static void Mutiny(MP_Strategy strategyInstance, Team team)
{
// notify all players
HelperMethods.ReplyToCommand(HelperMethods.GetTeamColor(team) + team.TeamShortName + "</color> had a mutiny against the current commander.");

CommanderPrimitives.DemoteTeamsCommander(strategyInstance, team);

// clear all people who voted for a mutiny
ClearMutineerList();
}
}
}
13 changes: 12 additions & 1 deletion Si_CommManagement/Si_CommanderManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ You should have received a copy of the GNU General Public License
using System;
using SilicaAdminMod;
using System.Linq;
using System.Collections.Generic;

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

Expand All @@ -45,6 +46,8 @@ public class CommanderManager : MelonMod
public static MelonPreferences_Entry<bool> _BlockRoundStartUntilEnoughApplicants = null!;
public static MelonPreferences_Entry<bool> _TeamOnlyResponses = null!;

public static List<Player>[] mutineerPlayers = null!;

public override void OnInitializeMelon()
{
_modCategory ??= MelonPreferences.CreateCategory("Silica");
Expand All @@ -55,6 +58,7 @@ public override void OnInitializeMelon()
{
CommanderBans.InitializeList();
CommanderApplications.InitializeApplications();
Mutineer.InitializeMutineerList();
}
catch (Exception error)
{
Expand All @@ -80,6 +84,9 @@ public override void OnLateInitializeMelon()
HelperMethods.CommandCallback commanderCallback = CommanderApplications.Command_Commander;
HelperMethods.RegisterPlayerCommand("commander", commanderCallback, true);

HelperMethods.CommandCallback mutinyCallback = Mutineer.Command_Mutiny;
HelperMethods.RegisterPlayerCommand("mutiny", mutinyCallback, true);

// subscribe to the OnRequestCommander event
Event_Roles.OnRequestCommander += OnRequestCommander;

Expand All @@ -95,6 +102,10 @@ public override void OnLateInitializeMelon()
QList.Options.AddOption(dontStartWithoutCommanders);
#endif
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
Mutineer.ClearMutineerList();
}

public void OnRequestCommander(object? sender, OnRequestCommanderArgs args)
{
Expand Down

0 comments on commit 9c8a60f

Please sign in to comment.