mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
Add "Died First in Last Game" Warning, fix a few minor bugs
This commit is contained in:
1 parent
06334cdf8f
commit
93e7053405
12 files changed
+103
-82
No files matched your search
@@ -58,7 +58,7 @@ namespace EHR
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
TimeLeft = MaxGameLength.GetInt() + 8;
|
||||
TimeLeft = MaxGameLength.GetInt();
|
||||
LastUpdate = Utils.TimeStamp;
|
||||
|
||||
Type[] types = GetAllHnsRoleTypes();
|
||||
@@ -114,6 +114,7 @@ namespace EHR
|
||||
{
|
||||
Dictionary<PlayerControl, CustomRoles> result = [];
|
||||
List<PlayerControl> allPlayers = [.. Main.AllAlivePlayerControls];
|
||||
if (Main.GM.Value) allPlayers.RemoveAll(x => x.IsHost());
|
||||
allPlayers = allPlayers.Shuffle();
|
||||
|
||||
Dictionary<Team, int> memberNum = new()
|
||||
@@ -328,10 +329,9 @@ namespace EHR
|
||||
return true;
|
||||
}
|
||||
|
||||
// If time is up, the game is over and crewmates win
|
||||
if (TimeLeft <= 0)
|
||||
// If time is up or there are no impostors in the game, the game is over and crewmates win
|
||||
if (TimeLeft <= 0 || PlayerRoles.Values.All(x => x.Interface.Team != Team.Impostor))
|
||||
{
|
||||
reason = GameOverReason.HumansByTask;
|
||||
SetWinners(CustomWinner.Hider, Team.Crewmate);
|
||||
return true;
|
||||
}
|
||||
@@ -409,7 +409,7 @@ namespace EHR
|
||||
{
|
||||
public static void Postfix(PlayerControl __instance)
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost || !GameStates.IsInTask || Options.CurrentGameMode != CustomGameMode.HideAndSeek) return;
|
||||
if (!AmongUsClient.Instance.AmHost || !GameStates.IsInTask || Options.CurrentGameMode != CustomGameMode.HideAndSeek || Main.HasJustStarted) return;
|
||||
|
||||
long now = Utils.TimeStamp;
|
||||
if (LastUpdate == now) return;
|
||||
@@ -417,14 +417,14 @@ namespace EHR
|
||||
|
||||
TimeLeft--;
|
||||
|
||||
if (DangerMeter.GetBool() || (TimeLeft + 1) % 60 == 0 || TimeLeft <= 60) Utils.NotifyRoles();
|
||||
|
||||
PlayerRoles = PlayerRoles.Where(x => Utils.GetPlayerById(x.Key) != null).ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
var imps = PlayerRoles.Where(x => x.Value.Interface.Team == Team.Impostor).ToDictionary(x => x.Key, x => Utils.GetPlayerById(x.Key).Pos());
|
||||
var nonImps = PlayerRoles.Where(x => x.Value.Interface.Team is Team.Crewmate or Team.Neutral).ToArray();
|
||||
ClosestImpostor = nonImps.ToDictionary(x => x.Key, x => imps.MinBy(y => Vector2.Distance(y.Value, Utils.GetPlayerById(x.Key).Pos())).Key);
|
||||
Danger = nonImps.ToDictionary(x => x.Key, x => Math.Clamp(((1 + (int)Math.Ceiling(Vector2.Distance(Utils.GetPlayerById(x.Key).Pos(), Utils.GetPlayerById(ClosestImpostor[x.Key]).Pos()))) / 3) - 1, 0, 5));
|
||||
|
||||
if (DangerMeter.GetBool() || (TimeLeft + 1) % 60 == 0 || TimeLeft <= 60) Utils.NotifyRoles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EHR.Roles.Crewmate;
|
||||
@@ -5,6 +6,7 @@ using HarmonyLib;
|
||||
using Hazel;
|
||||
using InnerNet;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
// Credit: https://github.com/Rabek009/MoreGamemodes/blob/e054eb498094dfca0a365fc6b6fea8d17f9974d7/Modules/CustomObjects
|
||||
// Huge thanks to Rabek009 for this code!
|
||||
@@ -234,11 +236,25 @@ namespace EHR
|
||||
|
||||
protected override void OnFixedUpdate()
|
||||
{
|
||||
if (Gone) return;
|
||||
if (SpawnTimeStamp + Tornado.TornadoDuration.GetInt() < Utils.TimeStamp)
|
||||
try
|
||||
{
|
||||
Gone = true;
|
||||
Despawn();
|
||||
if (Gone) return;
|
||||
if (SpawnTimeStamp + Tornado.TornadoDuration.GetInt() < Utils.TimeStamp)
|
||||
{
|
||||
Gone = true;
|
||||
Despawn();
|
||||
}
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
try
|
||||
{
|
||||
Despawn();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Gone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2300,6 +2300,9 @@ public static class Utils
|
||||
|
||||
Main.PlayerStates.Values.Do(x => TargetSuffix.Append(x.Role.GetSuffix(seer, target, isMeeting: isForMeeting)));
|
||||
|
||||
if (Main.FirstDied != int.MaxValue && Main.FirstDied == target.GetClientId())
|
||||
TargetSuffix.Append(GetString("DiedR1Warning"));
|
||||
|
||||
string TargetDeathReason = string.Empty;
|
||||
if (seer.KnowDeathReason(target))
|
||||
TargetDeathReason = $"\n<size=1.7>({ColorString(GetRoleColor(CustomRoles.Doctor), GetVitalText(target.PlayerId))})</size>";
|
||||
|
||||
@@ -35,7 +35,7 @@ internal class ControllerManagerUpdatePatch
|
||||
}
|
||||
}
|
||||
|
||||
if (GetKeysDown(KeyCode.LeftShift, KeyCode.LeftControl, KeyCode.X) && Main.CurrentMap == MapNames.Airship)
|
||||
if (GetKeysDown(KeyCode.LeftShift, KeyCode.LeftControl, KeyCode.X))
|
||||
{
|
||||
ExileController.Instance?.ReEnableGameplay();
|
||||
}
|
||||
|
||||
@@ -11,72 +11,70 @@ namespace EHR.Patches
|
||||
internal static class CreateGameOptionsPatches
|
||||
{
|
||||
[HarmonyPatch(typeof(CreateOptionsPicker), nameof(CreateOptionsPicker.Awake))]
|
||||
public static class CreateOptionsPicker_Awake
|
||||
public static class CreateOptionsPickerAwakePatch
|
||||
{
|
||||
public static void Postfix(CreateOptionsPicker __instance)
|
||||
{
|
||||
if (__instance.mode != SettingsMode.Host) return;
|
||||
|
||||
var firstButtonRenderer = __instance.MaxPlayerButtons[0];
|
||||
firstButtonRenderer.GetComponentInChildren<TextMeshPro>().text = "-";
|
||||
firstButtonRenderer.enabled = false;
|
||||
|
||||
var firstButtonButton = firstButtonRenderer.GetComponent<PassiveButton>();
|
||||
firstButtonButton.OnClick.RemoveAllListeners();
|
||||
firstButtonButton.OnClick.AddListener((Action)(() =>
|
||||
{
|
||||
var firstButtonRenderer = __instance.MaxPlayerButtons[0];
|
||||
firstButtonRenderer.GetComponentInChildren<TextMeshPro>().text = "-";
|
||||
firstButtonRenderer.enabled = false;
|
||||
|
||||
var firstButtonButton = firstButtonRenderer.GetComponent<PassiveButton>();
|
||||
firstButtonButton.OnClick.RemoveAllListeners();
|
||||
firstButtonButton.OnClick.AddListener((Action)(() =>
|
||||
{
|
||||
for (var i = 1; i < 11; i++)
|
||||
{
|
||||
var playerButton = __instance.MaxPlayerButtons[i];
|
||||
var tmp = playerButton.GetComponentInChildren<TextMeshPro>();
|
||||
var newValue = Mathf.Max(byte.Parse(tmp.text) - 10, byte.Parse(playerButton.name) - 2);
|
||||
tmp.text = newValue.ToString();
|
||||
}
|
||||
|
||||
__instance.UpdateMaxPlayersButtons(__instance.GetTargetOptions());
|
||||
}));
|
||||
|
||||
var lastButtonRenderer = __instance.MaxPlayerButtons[^1];
|
||||
lastButtonRenderer.GetComponentInChildren<TextMeshPro>().text = "+";
|
||||
lastButtonRenderer.enabled = false;
|
||||
|
||||
var lastButtonButton = lastButtonRenderer.GetComponent<PassiveButton>();
|
||||
lastButtonButton.OnClick.RemoveAllListeners();
|
||||
lastButtonButton.OnClick.AddListener((Action)(() =>
|
||||
{
|
||||
for (var i = 1; i < 11; i++)
|
||||
{
|
||||
var playerButton = __instance.MaxPlayerButtons[i];
|
||||
var tmp = playerButton.GetComponentInChildren<TextMeshPro>();
|
||||
var newValue = Mathf.Min(byte.Parse(tmp.text) + 10,
|
||||
127 - 14 + byte.Parse(playerButton.name));
|
||||
tmp.text = newValue.ToString();
|
||||
}
|
||||
|
||||
__instance.UpdateMaxPlayersButtons(__instance.GetTargetOptions());
|
||||
}));
|
||||
|
||||
for (var i = 1; i < 11; i++)
|
||||
{
|
||||
var playerButton = __instance.MaxPlayerButtons[i].GetComponent<PassiveButton>();
|
||||
var text = playerButton.GetComponentInChildren<TextMeshPro>();
|
||||
|
||||
playerButton.OnClick.RemoveAllListeners();
|
||||
playerButton.OnClick.AddListener((Action)(() =>
|
||||
{
|
||||
var maxPlayers = byte.Parse(text.text);
|
||||
var maxImp = Mathf.Min(__instance.GetTargetOptions().NumImpostors, maxPlayers / 2);
|
||||
__instance.GetTargetOptions().SetInt(Int32OptionNames.NumImpostors, maxImp);
|
||||
__instance.ImpostorButtons[1].TextMesh.text = maxImp.ToString();
|
||||
__instance.SetMaxPlayersButtons(maxPlayers);
|
||||
}));
|
||||
var playerButton = __instance.MaxPlayerButtons[i];
|
||||
var tmp = playerButton.GetComponentInChildren<TextMeshPro>();
|
||||
var newValue = Mathf.Max(byte.Parse(tmp.text) - 10, byte.Parse(playerButton.name) - 2);
|
||||
tmp.text = newValue.ToString();
|
||||
}
|
||||
|
||||
foreach (var button in __instance.MaxPlayerButtons)
|
||||
__instance.UpdateMaxPlayersButtons(__instance.GetTargetOptions());
|
||||
}));
|
||||
|
||||
var lastButtonRenderer = __instance.MaxPlayerButtons[^1];
|
||||
lastButtonRenderer.GetComponentInChildren<TextMeshPro>().text = "+";
|
||||
lastButtonRenderer.enabled = false;
|
||||
|
||||
var lastButtonButton = lastButtonRenderer.GetComponent<PassiveButton>();
|
||||
lastButtonButton.OnClick.RemoveAllListeners();
|
||||
lastButtonButton.OnClick.AddListener((Action)(() =>
|
||||
{
|
||||
for (var i = 1; i < 11; i++)
|
||||
{
|
||||
button.enabled = button.GetComponentInChildren<TextMeshPro>().text == __instance.GetTargetOptions().MaxPlayers.ToString();
|
||||
var playerButton = __instance.MaxPlayerButtons[i];
|
||||
var tmp = playerButton.GetComponentInChildren<TextMeshPro>();
|
||||
var newValue = Mathf.Min(byte.Parse(tmp.text) + 10,
|
||||
127 - 14 + byte.Parse(playerButton.name));
|
||||
tmp.text = newValue.ToString();
|
||||
}
|
||||
|
||||
__instance.UpdateMaxPlayersButtons(__instance.GetTargetOptions());
|
||||
}));
|
||||
|
||||
for (var i = 1; i < 11; i++)
|
||||
{
|
||||
var playerButton = __instance.MaxPlayerButtons[i].GetComponent<PassiveButton>();
|
||||
var text = playerButton.GetComponentInChildren<TextMeshPro>();
|
||||
|
||||
playerButton.OnClick.RemoveAllListeners();
|
||||
playerButton.OnClick.AddListener((Action)(() =>
|
||||
{
|
||||
var maxPlayers = byte.Parse(text.text);
|
||||
var maxImp = Mathf.Min(__instance.GetTargetOptions().NumImpostors, maxPlayers / 2);
|
||||
__instance.GetTargetOptions().SetInt(Int32OptionNames.NumImpostors, maxImp);
|
||||
__instance.ImpostorButtons[1].TextMesh.text = maxImp.ToString();
|
||||
__instance.SetMaxPlayersButtons(maxPlayers);
|
||||
}));
|
||||
}
|
||||
|
||||
foreach (var button in __instance.MaxPlayerButtons)
|
||||
{
|
||||
button.enabled = button.GetComponentInChildren<TextMeshPro>().text == __instance.GetTargetOptions().MaxPlayers.ToString();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -124,7 +122,7 @@ namespace EHR.Patches
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(CreateOptionsPicker), nameof(CreateOptionsPicker.UpdateMaxPlayersButtons))]
|
||||
public static class CreateOptionsPicker_UpdateMaxPlayersButtons
|
||||
public static class CreateOptionsPickerUpdateMaxPlayersButtonsPatch
|
||||
{
|
||||
public static bool Prefix(CreateOptionsPicker __instance, [HarmonyArgument(0)] IGameOptions opts)
|
||||
{
|
||||
@@ -144,7 +142,7 @@ namespace EHR.Patches
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(CreateOptionsPicker), nameof(CreateOptionsPicker.UpdateImpostorsButtons))]
|
||||
public static class CreateOptionsPicker_UpdateImpostorsButtons
|
||||
public static class CreateOptionsPickerUpdateImpostorsButtonsPatch
|
||||
{
|
||||
public static bool Prefix()
|
||||
{
|
||||
|
||||
@@ -348,7 +348,6 @@ class CheckForEndVotingPatch
|
||||
var exileId = exiledPlayer.PlayerId;
|
||||
if (exileId > 254) return;
|
||||
var realName = exiledPlayer.Object.GetRealName(isMeeting: true);
|
||||
Main.LastVotedPlayer = realName;
|
||||
|
||||
var player = Utils.GetPlayerById(exiledPlayer.PlayerId);
|
||||
var crole = exiledPlayer.GetCustomRole();
|
||||
|
||||
@@ -64,8 +64,8 @@ internal class ChangeRoleSettings
|
||||
Main.ClientIdList = [];
|
||||
Main.CheckShapeshift = [];
|
||||
Main.ShapeshiftTarget = [];
|
||||
Main.ShieldPlayer = Options.ShieldPersonDiedFirst.GetBool() ? Main.FirstDied : byte.MaxValue;
|
||||
Main.FirstDied = byte.MaxValue;
|
||||
Main.ShieldPlayer = Options.ShieldPersonDiedFirst.GetBool() ? Main.FirstDied : int.MaxValue;
|
||||
Main.FirstDied = int.MaxValue;
|
||||
Main.MadmateNum = 0;
|
||||
|
||||
Mayor.MayorUsedButtonCount = [];
|
||||
|
||||
@@ -401,9 +401,9 @@ class CheckMurderPatch
|
||||
break;
|
||||
}
|
||||
|
||||
if (Main.ShieldPlayer != byte.MaxValue && Main.ShieldPlayer == target.PlayerId && IsAllAlive)
|
||||
if (Main.ShieldPlayer != int.MaxValue && Main.ShieldPlayer == target.GetClientId() && IsAllAlive)
|
||||
{
|
||||
Main.ShieldPlayer = byte.MaxValue;
|
||||
Main.ShieldPlayer = int.MaxValue;
|
||||
killer.SetKillCooldown(15f);
|
||||
killer.Notify(GetString("TriedToKillLastGameFirstKill"), 10f);
|
||||
return false;
|
||||
@@ -485,16 +485,16 @@ class MurderPlayerPatch
|
||||
}
|
||||
|
||||
// Let’s see if Youtuber was stabbed first
|
||||
if (Main.FirstDied == byte.MaxValue && target.Is(CustomRoles.Youtuber))
|
||||
if (Main.FirstDied == int.MaxValue && target.Is(CustomRoles.Youtuber))
|
||||
{
|
||||
CustomSoundsManager.RPCPlayCustomSoundAll("Congrats");
|
||||
CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Youtuber);
|
||||
CustomWinnerHolder.WinnerIds.Add(target.PlayerId);
|
||||
}
|
||||
|
||||
// Record the first blow
|
||||
if (Main.FirstDied == byte.MaxValue)
|
||||
Main.FirstDied = target.PlayerId;
|
||||
// Record the first death
|
||||
if (Main.FirstDied == int.MaxValue)
|
||||
Main.FirstDied = target.GetClientId();
|
||||
|
||||
Postman.CheckAndResetTargets(target, isDeath: true);
|
||||
|
||||
@@ -1522,6 +1522,9 @@ class FixedUpdatePatch
|
||||
if (Options.CurrentGameMode == CustomGameMode.SoloKombat)
|
||||
Suffix.Append(SoloKombatManager.GetDisplayHealth(target));
|
||||
|
||||
if (Main.FirstDied != int.MaxValue && Main.FirstDied == target.GetClientId() && !self)
|
||||
Suffix.Append(GetString("DiedR1Warning"));
|
||||
|
||||
// Devourer
|
||||
if (Devourer.HideNameOfConsumedPlayer.GetBool() && Devourer.playerIdList.Any(x => Main.PlayerStates[x].Role is Devourer { IsEnable: true } dv && dv.PlayerSkinsCosumed.Contains(seer.PlayerId)))
|
||||
RealName = GetString("DevouredName");
|
||||
|
||||
@@ -133,9 +133,11 @@ class OnPlayerLeftPatch
|
||||
{
|
||||
if (GameStates.IsInGame)
|
||||
{
|
||||
if (Options.CurrentGameMode == CustomGameMode.HideAndSeek) HnSManager.PlayerRoles.Remove(data.Character.PlayerId);
|
||||
|
||||
if (data.Character.Is(CustomRoles.Lovers) && !data.Character.Data.IsDead)
|
||||
{
|
||||
foreach (var lovers in Main.LoversPlayers)
|
||||
foreach (var lovers in Main.LoversPlayers.ToArray())
|
||||
{
|
||||
Main.IsLoversDead = true;
|
||||
Main.LoversPlayers.Remove(lovers);
|
||||
|
||||
@@ -1740,6 +1740,7 @@
|
||||
"Alive": "Alive",
|
||||
"Win": " Wins!",
|
||||
"Last-": "Last ",
|
||||
"DiedR1Warning": "<#ffff00>(Died First in Last Game)</color>",
|
||||
"DeputyHandcuffCooldown": "Handcuff Cooldown",
|
||||
"DeputyHandcuffMax": "Maximum Handcuffs",
|
||||
"CanHandcuffSheriff": "Can Handcuff <color=#f8cd46>Sheriff</color>",
|
||||
|
||||
+1
-1
@@ -171,7 +171,7 @@ namespace EHR
|
||||
|
||||
public virtual bool KnowRole(PlayerControl seer, PlayerControl target)
|
||||
{
|
||||
return false;
|
||||
return seer.GetCustomRole() == target.GetCustomRole() && seer.GetTeam() == target.GetTeam();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,6 @@ public class Main : BasePlugin
|
||||
public static readonly Dictionary<byte, (long START_TIMESTAMP, int TOTALCD)> AbilityCD = [];
|
||||
public static Dictionary<byte, float> AbilityUseLimit = [];
|
||||
public static List<byte> DontCancelVoteList = [];
|
||||
public static string LastVotedPlayer;
|
||||
public static byte NimblePlayer = byte.MaxValue;
|
||||
public static byte PhysicistPlayer = byte.MaxValue;
|
||||
public static byte BloodlustPlayer = byte.MaxValue;
|
||||
@@ -102,8 +101,8 @@ public class Main : BasePlugin
|
||||
public static float DefaultImpostorVision;
|
||||
public static readonly bool IsAprilFools = DateTime.Now.Month == 4 && DateTime.Now.Day is 1;
|
||||
public static bool ResetOptions = true;
|
||||
public static byte FirstDied = byte.MaxValue;
|
||||
public static byte ShieldPlayer = byte.MaxValue;
|
||||
public static int FirstDied = int.MaxValue;
|
||||
public static int ShieldPlayer = int.MaxValue;
|
||||
|
||||
public static readonly List<PlayerControl> LoversPlayers = [];
|
||||
public static bool IsLoversDead = true;
|
||||
|
||||
Reference in new issue
Block a user