Merge pull request #50 from xChipseq/dummy-improvements

Dummy Voting Improvements
This commit is contained in:
XtraCube authored and GitHub committed 2025-08-04 21:19:18 -04:00
commit 9c1ef70ea7
2 files changed
+105 -6

No files matched your search

@@ -0,0 +1,44 @@
using System;
using MiraAPI.Utilities;
using MiraAPI.Voting;
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
/// <summary>
/// Invoked before the dummy selects their vote. If canceled, the dummy won't vote.
/// </summary>
public class DummyVoteEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the dummy that needs to vote
/// </summary>
public DummyBehaviour Dummy { get; }
/// <summary>
/// Gets the instance of the dummy's vote data.
/// </summary>
public PlayerVoteData VoteData { get; }
/// <summary>
/// Gets or sets a value indicating whether the dummy can vote to skip the meeting.
/// </summary>
public bool CanSkip { get; set; }
/// <summary>
/// Gets or sets a predicate for validating whether the dummy can vote on a player.
/// By default, excludes dead and disconnected players.
/// </summary>
public Predicate<PlayerControl> PlayerIsValid { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="DummyVoteEvent"/> class.
/// </summary>
/// <param name="dummy">The voting dummy.</param>
public DummyVoteEvent(DummyBehaviour dummy)
{
Dummy = dummy;
VoteData = dummy.myPlayer.GetVoteData();
CanSkip = true;
PlayerIsValid = x => !x.Data.IsDead && !x.Data.Disconnected;
}
}
+61 -6
View File
@@ -1,16 +1,71 @@
using HarmonyLib;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using MiraAPI.Events;
using MiraAPI.Events.Vanilla.Meeting.Voting;
using MiraAPI.Utilities;
using MiraAPI.Voting;
using Reactor.Utilities;
using Reactor.Utilities.Extensions;
using UnityEngine;
namespace MiraAPI.Patches.Voting;
[HarmonyPatch(typeof(DummyBehaviour), nameof(DummyBehaviour.Update))]
internal static class DummyBehaviourPatch
[HarmonyPatch(typeof(DummyBehaviour))]
internal static class DummyBehaviourPatches
{
public static void Postfix(DummyBehaviour __instance)
[HarmonyPrefix]
[HarmonyPatch(nameof(DummyBehaviour.Update))]
public static bool DummyUpdatePatch(DummyBehaviour __instance)
{
if (MeetingHud.Instance && __instance.myPlayer.GetVoteData())
NetworkedPlayerInfo data = __instance.myPlayer.Data;
if (data == null || data.IsDead) return false;
if (MeetingHud.Instance && !__instance.DidVote())
{
__instance.voted = __instance.myPlayer.GetVoteData().VotesRemaining == 0;
Coroutines.Start(CoDoVote(__instance));
}
return false;
}
private static IEnumerator CoDoVote(DummyBehaviour dummy)
{
dummy.voted = true;
yield return new WaitForSeconds(dummy.voteTime.Next());
if (DidVote(dummy)) yield break;
var dummyVoteEvent = new DummyVoteEvent(dummy);
MiraEventManager.InvokeEvent(dummyVoteEvent);
if (dummyVoteEvent.IsCancelled)
{
dummy.voted = false;
yield break;
}
List<byte> potentialSuspects = new();
potentialSuspects.AddRange(PlayerControl.AllPlayerControls
.ToArray()
.Where(p => p != dummy.myPlayer)
.Where(p => dummyVoteEvent.PlayerIsValid(p))
.Select(p => p.PlayerId));
if (dummyVoteEvent.CanSkip)
{
potentialSuspects.Add(253);
}
if (dummy.myPlayer.GetVoteData().VotesRemaining > 0)
{
VotingUtils.RpcCastVote(PlayerControl.LocalPlayer, dummy.myPlayer.PlayerId, potentialSuspects.Random());
}
}
private static bool DidVote(this DummyBehaviour dummy)
{
var dummyVoteData = dummy.myPlayer.GetVoteData();
return dummyVoteData.VotesRemaining > 0;
}
}