diff --git a/MiraAPI.Example/ExampleEventHandlers.cs b/MiraAPI.Example/ExampleEventHandlers.cs
index 618ea2f..2e8fdf2 100644
--- a/MiraAPI.Example/ExampleEventHandlers.cs
+++ b/MiraAPI.Example/ExampleEventHandlers.cs
@@ -1,5 +1,4 @@
using System.Linq;
-using HarmonyLib;
using MiraAPI.Events;
using MiraAPI.Events.Mira;
using MiraAPI.Events.Vanilla.Gameplay;
@@ -43,7 +42,7 @@ public static class ExampleEventHandlers
{
if (plr.Data.Role is MayorRole)
{
- plr.GetVoteData().AddVotes(1);
+ plr.GetVoteData().IncreaseRemainingVotes(1);
}
}
}
@@ -52,9 +51,9 @@ public static class ExampleEventHandlers
[RegisterEvent(15)]
public static void HandleVoteEvent(HandleVoteEvent @event)
{
- if (@event.VoteData.Owner?.Data.Role is not NeutralKillerRole) return;
+ if (@event.VoteData.Owner.Data.Role is not NeutralKillerRole) return;
- @event.VoteData.SetVotesRemaining(0);
+ @event.VoteData.SetRemainingVotes(0);
for (var i = 0; i < 5; i++)
{
@@ -63,7 +62,7 @@ public static class ExampleEventHandlers
foreach (var plr in PlayerControl.AllPlayerControls.ToArray().Where(player => player != @event.VoteData.Owner))
{
- plr.GetVoteData().VotedPlayers.Clear();
+ plr.GetVoteData().Votes.Clear();
plr.GetVoteData().VotesRemaining = 0;
}
diff --git a/MiraAPI/Events/Vanilla/Meeting/Voting/HandleVoteEvent.cs b/MiraAPI/Events/Vanilla/Meeting/Voting/HandleVoteEvent.cs
index 9dc9659..a0c7f75 100644
--- a/MiraAPI/Events/Vanilla/Meeting/Voting/HandleVoteEvent.cs
+++ b/MiraAPI/Events/Vanilla/Meeting/Voting/HandleVoteEvent.cs
@@ -1,5 +1,4 @@
-using MiraAPI.Utilities;
-using MiraAPI.Voting;
+using MiraAPI.Voting;
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
diff --git a/MiraAPI/Events/Vanilla/Meeting/Voting/MeetingSelectEvent.cs b/MiraAPI/Events/Vanilla/Meeting/Voting/MeetingSelectEvent.cs
index 58f6eeb..71d8a23 100644
--- a/MiraAPI/Events/Vanilla/Meeting/Voting/MeetingSelectEvent.cs
+++ b/MiraAPI/Events/Vanilla/Meeting/Voting/MeetingSelectEvent.cs
@@ -1,5 +1,4 @@
-using MiraAPI.Utilities;
-using MiraAPI.Voting;
+using MiraAPI.Voting;
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
diff --git a/MiraAPI/Networking/MiraRpc.cs b/MiraAPI/Networking/MiraRpc.cs
index 1a3fa66..6d51e2a 100644
--- a/MiraAPI/Networking/MiraRpc.cs
+++ b/MiraAPI/Networking/MiraRpc.cs
@@ -39,6 +39,14 @@ public enum MiraRpc : uint
/// Custom Game Over RPC.
///
CustomGameOver,
+
+ ///
+ /// Custom RPC to handle populating vote results.
+ ///
PopulateResults,
+
+ ///
+ /// Custom RPC to undo a player's vote.
+ ///
RemoveVote,
}
diff --git a/MiraAPI/Patches/PlayerControlPatches.cs b/MiraAPI/Patches/PlayerControlPatches.cs
index 6036209..feb2921 100644
--- a/MiraAPI/Patches/PlayerControlPatches.cs
+++ b/MiraAPI/Patches/PlayerControlPatches.cs
@@ -6,7 +6,6 @@ using MiraAPI.Events.Vanilla.Player;
using MiraAPI.Hud;
using MiraAPI.Modifiers;
using MiraAPI.Roles;
-using MiraAPI.Utilities;
using MiraAPI.Voting;
using Reactor.Utilities.Extensions;
diff --git a/MiraAPI/Patches/Voting/MeetingHudPatches.cs b/MiraAPI/Patches/Voting/MeetingHudPatches.cs
index f3db9cd..c437b36 100644
--- a/MiraAPI/Patches/Voting/MeetingHudPatches.cs
+++ b/MiraAPI/Patches/Voting/MeetingHudPatches.cs
@@ -10,7 +10,7 @@ using Reactor.Networking.Rpc;
namespace MiraAPI.Patches.Voting;
[HarmonyPatch(typeof(MeetingHud))]
-public static class MeetingHudPatches
+internal static class MeetingHudPatches
{
[HarmonyPostfix]
[HarmonyPatch(nameof(MeetingHud.Start))]
@@ -19,12 +19,12 @@ public static class MeetingHudPatches
foreach (var plr in PlayerControl.AllPlayerControls)
{
var voteData = plr.GetVoteData();
- voteData.VotedPlayers.Clear();
- voteData.SetVotesRemaining(1);
+ voteData.Votes.Clear();
+ voteData.SetRemainingVotes(1);
if (plr.Data.IsDead || plr.Data.Disconnected)
{
- voteData.SetVotesRemaining(0);
+ voteData.SetRemainingVotes(0);
}
}
var @event = new StartMeetingEvent(__instance);
@@ -46,7 +46,7 @@ public static class MeetingHudPatches
}
var hasVotes = voteData.VotesRemaining > 0;
- var hasVotedFor = voteData.VotedPlayers.Contains((byte)suspectStateIdx);
+ var hasVotedFor = voteData.VotedFor((byte)suspectStateIdx);
return hasVotes && !hasVotedFor;
}
@@ -69,12 +69,12 @@ public static class MeetingHudPatches
var pva = __instance.playerStates.First(pv => pv.TargetPlayerId == player.PlayerId);
var voteData = player.GetVoteData();
- if (pva.AmDead || !voteData.VotedPlayers.Contains(pc.PlayerId))
+ if (pva.AmDead || !voteData.VotedFor(pc.PlayerId))
{
continue;
}
- voteData.VotedPlayers.Remove(pc.PlayerId);
+ voteData.Votes.RemoveAll(x=>x.Suspect==pc.PlayerId);
voteData.VotesRemaining += 1;
VotingUtils.RpcRemoveVote(PlayerControl.LocalPlayer, player.PlayerId, pc.PlayerId);
@@ -104,7 +104,7 @@ public static class MeetingHudPatches
var voteData = plr.Object.GetVoteData();
if (voteData == null || voteData.VotesRemaining == 0 ||
- voteData.VotedPlayers.Contains(suspectPlayerId))
+ voteData.VotedFor(suspectPlayerId))
{
return false;
}
@@ -135,7 +135,7 @@ public static class MeetingHudPatches
if (!AmongUsClient.Instance.AmHost)
{
if (voteData == null || voteData.VotesRemaining == 0 ||
- voteData.VotedPlayers.Contains(suspectIdx))
+ voteData.VotedFor(suspectIdx))
{
return;
}
@@ -173,7 +173,7 @@ public static class MeetingHudPatches
[HarmonyPatch(nameof(MeetingHud.CheckForEndVoting))]
public static bool EndCheck(MeetingHud __instance)
{
- if (Helpers.GetAlivePlayers().Any(plr => plr.GetVoteData()!.VotesRemaining > 0))
+ if (Helpers.GetAlivePlayers().Exists(plr => plr.GetVoteData()!.VotesRemaining > 0))
{
return false;
}
@@ -193,7 +193,6 @@ public static class MeetingHudPatches
return false;
}
-
[HarmonyPrefix]
[HarmonyPatch(nameof(MeetingHud.PopulateResults))]
public static bool PopulateResultsPatch(MeetingHud __instance)
@@ -204,7 +203,7 @@ public static class MeetingHudPatches
}
var votes = VotingUtils.CalculateVotes();
- Rpc.Instance.Send(votes.ToArray());
+ Rpc.Instance.Send([.. votes]);
return false;
}
diff --git a/MiraAPI/Voting/PlayerVoteData.cs b/MiraAPI/Voting/PlayerVoteData.cs
index 0b0f099..023c83e 100644
--- a/MiraAPI/Voting/PlayerVoteData.cs
+++ b/MiraAPI/Voting/PlayerVoteData.cs
@@ -9,17 +9,17 @@ namespace MiraAPI.Voting;
/// Handles player votes, and removing/adding additional votes.
///
[RegisterInIl2Cpp]
-public class PlayerVoteData(nint ptr) : MonoBehaviour(ptr)
+public class PlayerVoteData(nint cppPtr) : MonoBehaviour(cppPtr)
{
///
/// Gets the owner of this component.
///
- public PlayerControl? Owner { get; private set; }
+ public PlayerControl Owner { get; private set; } = null!;
///
- /// Gets the players which the owner has voted for.
+ /// Gets the list of votes the owner has.
///
- public List VotedPlayers { get; private set; } = [];
+ public List Votes { get; private set; } = [];
///
/// Gets or sets the amount of votes the owner has left.
@@ -43,29 +43,48 @@ public class PlayerVoteData(nint ptr) : MonoBehaviour(ptr)
}
///
- /// Adds the voted player to the list.
+ /// Returns whether the owner has voted for the specified player.
///
/// The target's playerId.
- public void VoteForPlayer(byte playerId)
+ /// True if the owner voted for the specified player, false otherwise.
+ public bool VotedFor(byte playerId)
{
- VotedPlayers.Add(playerId);
+ return Votes.Exists(x => x.Suspect == playerId);
}
///
- /// Removes the voted player from the list.
+ /// Adds the voted player to the list.
+ ///
+ /// The target's playerId.
+ /// The weight of the vote.
+ public void VoteForPlayer(byte playerId, float weight=1f)
+ {
+ Votes.Add(new CustomVote(Owner.PlayerId, playerId, weight));
+ }
+
+ ///
+ /// Removes the specified vote.
+ ///
+ /// The vote you would like to remove.
+ public void RemovePlayerVote(CustomVote vote)
+ {
+ Votes.Remove(vote);
+ }
+
+ ///
+ /// Removes a single vote from the owner.
///
/// The target's playerId.
public void RemovePlayerVote(byte playerId)
{
- if (!VotedPlayers.Contains(playerId)) return;
- VotedPlayers.Remove(playerId);
+ Votes.Remove(Votes.Find(x=>x.Suspect==playerId));
}
///
/// Sets the player's votes remaining.
///
/// The amount of votes you would like to set it to.
- public void SetVotesRemaining(int votesRemaining)
+ public void SetRemainingVotes(int votesRemaining)
{
VotesRemaining = votesRemaining;
}
@@ -74,17 +93,17 @@ public class PlayerVoteData(nint ptr) : MonoBehaviour(ptr)
/// Adds votes to the owner.
///
/// The amount of votes you would like to add.
- public void AddVotes(int amount)
+ public void IncreaseRemainingVotes(int amount)
{
- SetVotesRemaining(VotesRemaining + amount);
+ SetRemainingVotes(VotesRemaining + amount);
}
///
/// Removes votes from the owner.
///
/// The amount of votes you would like to remove.
- public void RemoveVotes(int amount)
+ public void DecreaseRemainingVotes(int amount)
{
- SetVotesRemaining(VotesRemaining - amount);
+ SetRemainingVotes(VotesRemaining - amount);
}
}
diff --git a/MiraAPI/Voting/PopulateResultsRpc.cs b/MiraAPI/Voting/PopulateResultsRpc.cs
index ea4963f..042fb43 100644
--- a/MiraAPI/Voting/PopulateResultsRpc.cs
+++ b/MiraAPI/Voting/PopulateResultsRpc.cs
@@ -1,5 +1,4 @@
-using System.Linq;
-using Hazel;
+using Hazel;
using MiraAPI.Networking;
using Reactor.Networking.Attributes;
using Reactor.Networking.Rpc;
@@ -29,6 +28,7 @@ public class PopulateResultsRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc
{
writer.Write(t.Voter);
writer.Write(t.Suspect);
+ writer.Write(t.Weight);
}
}
@@ -39,7 +39,7 @@ public class PopulateResultsRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc
for (var i = 0; i < votes.Length; i++)
{
- votes[i] = new CustomVote(reader.ReadByte(), reader.ReadByte());
+ votes[i] = new CustomVote(reader.ReadByte(), reader.ReadByte(), reader.ReadSingle());
}
return votes;
diff --git a/MiraAPI/Voting/VotingUtils.cs b/MiraAPI/Voting/VotingUtils.cs
index f2fb6c0..d152589 100644
--- a/MiraAPI/Voting/VotingUtils.cs
+++ b/MiraAPI/Voting/VotingUtils.cs
@@ -23,7 +23,7 @@ public static class VotingUtils
/// Who the player voted for.
public static void HandleVote(PlayerVoteData voteData, byte suspectIdx)
{
- HandleVoteEvent @event = new HandleVoteEvent(voteData, suspectIdx);
+ var @event = new HandleVoteEvent(voteData, suspectIdx);
MiraEventManager.InvokeEvent(@event);
if (@event.IsCancelled)
@@ -31,7 +31,7 @@ public static class VotingUtils
return;
}
- voteData.RemoveVotes(1);
+ voteData.DecreaseRemainingVotes(1);
voteData.VoteForPlayer(suspectIdx);
}
@@ -61,7 +61,7 @@ public static class VotingUtils
if (!AmongUsClient.Instance.AmHost)
{
var voteData = PlayerControl.LocalPlayer.GetVoteData();
- voteData.RemoveVotes(1);
+ voteData.DecreaseRemainingVotes(1);
voteData.RemovePlayerVote(votedFor);
}
@@ -100,9 +100,11 @@ public static class VotingUtils
/// The list of votes.
public static List CalculateVotes()
{
- return (from player in Helpers.GetAlivePlayers()
- from vote in player.GetVoteData()!.VotedPlayers
- select new CustomVote(player.PlayerId, vote)).ToList();
+ return
+ [
+ .. Helpers.GetAlivePlayers()
+ .SelectMany(player => player.GetVoteData().Votes)
+ ];
}
///