mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
some changes
This commit is contained in:
1 parent
d8a5f1ec61
commit
4e791b5fa2
17 files changed
+212
-110
No files matched your search
+19
-30
@@ -147,20 +147,19 @@ internal static class FreeForAll
|
||||
if (Main.GM.Value && AmongUsClient.Instance.AmHost) allPlayers = allPlayers.Without(PlayerControl.LocalPlayer).ToArray();
|
||||
allPlayers = allPlayers.ExceptBy(ChatCommands.Spectators, x => x.PlayerId).ToArray();
|
||||
|
||||
foreach (PlayerControl pc in allPlayers) KillCount[pc.PlayerId] = 0;
|
||||
foreach (PlayerControl pc in allPlayers)
|
||||
{
|
||||
KillCount[pc.PlayerId] = 0;
|
||||
Utils.SendRPC(CustomRPC.FFASync, pc.PlayerId, 0);
|
||||
}
|
||||
|
||||
if (FFATeamMode.GetBool())
|
||||
{
|
||||
int teamNum = FFATeamNumber.GetInt();
|
||||
int playerNum = allPlayers.Length;
|
||||
int memberNum = (teamNum > 5 && playerNum >= 15) || playerNum % teamNum == 0 ? playerNum / teamNum : (playerNum / teamNum) + 1;
|
||||
List<byte[]> teamMembers = allPlayers.Select(x => x.PlayerId).Shuffle().Chunk(memberNum).ToList();
|
||||
int i = 0;
|
||||
|
||||
for (var i = 0; i < teamMembers.Count; i++)
|
||||
{
|
||||
foreach (byte id in teamMembers[i])
|
||||
PlayerTeams.Add(id, i);
|
||||
}
|
||||
foreach (IEnumerable<byte> ids in allPlayers.Select(x => x.PlayerId).Shuffle().Partition(FFATeamNumber.GetInt()))
|
||||
foreach (byte id in ids)
|
||||
PlayerTeams[id] = i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,17 +290,14 @@ internal static class FreeForAll
|
||||
// De-Buff
|
||||
case 8:
|
||||
{
|
||||
var EffectID = (byte)IRandom.Instance.Next(0, 3);
|
||||
if (Main.NormalOptions.MapId == 4) EffectID = 1;
|
||||
var effectID = (byte)IRandom.Instance.Next(0, 3);
|
||||
if (Main.NormalOptions.MapId == 4) effectID = 1;
|
||||
|
||||
switch (EffectID)
|
||||
switch (effectID)
|
||||
{
|
||||
case 0:
|
||||
if (FFADecreasedSpeedList.ContainsKey(killer.PlayerId))
|
||||
{
|
||||
FFADecreasedSpeedList.Remove(killer.PlayerId);
|
||||
if (FFADecreasedSpeedList.Remove(killer.PlayerId))
|
||||
FFADecreasedSpeedList.Add(killer.PlayerId, Utils.TimeStamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
FFADecreasedSpeedList.TryAdd(killer.PlayerId, Utils.TimeStamp);
|
||||
@@ -361,25 +357,18 @@ internal static class FreeForAll
|
||||
ChatCommands.Spectators.ToValidPlayers().Do(x => x.KillFlash());
|
||||
|
||||
KillCount[killer.PlayerId]++;
|
||||
Utils.SendRPC(CustomRPC.FFASync, killer.PlayerId, KillCount[killer.PlayerId]);
|
||||
}
|
||||
|
||||
public static string GetPlayerArrow(PlayerControl seer, PlayerControl target = null)
|
||||
{
|
||||
if (GameStates.IsMeeting) return string.Empty;
|
||||
if (GameStates.IsMeeting || target != null && seer.PlayerId != target.PlayerId || Main.AllAlivePlayerControls.Length != 2) return string.Empty;
|
||||
|
||||
if (target != null && seer.PlayerId != target.PlayerId) return string.Empty;
|
||||
|
||||
if (Main.AllAlivePlayerControls.Length != 2) return string.Empty;
|
||||
|
||||
var arrows = string.Empty;
|
||||
PlayerControl otherPlayer = Main.AllAlivePlayerControls.FirstOrDefault(pc => pc.IsAlive() && pc.PlayerId != seer.PlayerId);
|
||||
|
||||
if (otherPlayer == null) return string.Empty;
|
||||
|
||||
string arrow = TargetArrow.GetArrows(seer, otherPlayer.PlayerId);
|
||||
arrows += Utils.ColorString(Utils.GetRoleColor(CustomRoles.Killer), arrow);
|
||||
|
||||
return arrows;
|
||||
return Utils.ColorString(Utils.GetRoleColor(CustomRoles.Killer), arrow);
|
||||
}
|
||||
|
||||
public static void UpdateLastChatMessage(string playerName, string message)
|
||||
@@ -405,10 +394,10 @@ internal static class FreeForAll
|
||||
RoundTime--;
|
||||
|
||||
var rd = IRandom.Instance;
|
||||
var FFAdoTPdecider = (byte)rd.Next(0, 100);
|
||||
bool FFAdoTP = FFAdoTPdecider == 0;
|
||||
var ffaDoTPdecider = (byte)rd.Next(0, 100);
|
||||
bool ffaDoTP = ffaDoTPdecider == 0;
|
||||
|
||||
if (FFAEnableRandomTwists.GetBool() && FFAdoTP)
|
||||
if (FFAEnableRandomTwists.GetBool() && ffaDoTP)
|
||||
{
|
||||
Logger.Info("Swap everyone with someone", "FFA");
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ internal static class SoloPVP
|
||||
PlayerDF.TryAdd(pc.PlayerId, 0f);
|
||||
|
||||
KBScore.TryAdd(pc.PlayerId, 0);
|
||||
Utils.SendRPC(CustomRPC.SoloPVPSync, pc.PlayerId, 0);
|
||||
|
||||
LastHurt.TryAdd(pc.PlayerId, Utils.TimeStamp);
|
||||
LastCountdownTime.TryAdd(pc.PlayerId, Utils.TimeStamp);
|
||||
@@ -268,6 +269,7 @@ internal static class SoloPVP
|
||||
ChatCommands.Spectators.ToValidPlayers().Do(x => x.KillFlash());
|
||||
|
||||
KBScore[killer.PlayerId]++;
|
||||
Utils.SendRPC(CustomRPC.SoloPVPSync, killer.PlayerId, KBScore[killer.PlayerId]);
|
||||
|
||||
if (Options.CurrentGameMode == CustomGameMode.AllInOne)
|
||||
Speedrun.ResetTimer(killer);
|
||||
|
||||
@@ -65,6 +65,9 @@ public static class AFKDetector
|
||||
|
||||
if (Vector2.Distance(pc.Pos(), data.LastPosition) > 0.1f && !TempIgnoredPlayers.Contains(pc.PlayerId))
|
||||
{
|
||||
if (ExtendedPlayerControl.BlackScreenWaitingPlayers.Contains(pc.PlayerId))
|
||||
ExtendedPlayerControl.CancelBlackScreenFix.Add(pc.PlayerId);
|
||||
|
||||
PlayerData.Remove(pc.PlayerId);
|
||||
ShieldedPlayers.Remove(pc.PlayerId);
|
||||
return;
|
||||
|
||||
@@ -25,7 +25,8 @@ internal static class ExtendedPlayerControl
|
||||
{
|
||||
public const MurderResultFlags ResultFlags = MurderResultFlags.Succeeded;
|
||||
|
||||
private static readonly HashSet<byte> BlackScreenWaitingPlayers = [];
|
||||
public static readonly HashSet<byte> BlackScreenWaitingPlayers = [];
|
||||
public static readonly HashSet<byte> CancelBlackScreenFix = [];
|
||||
|
||||
public static void SetRole(this PlayerControl player, RoleTypes role, bool canOverride = true)
|
||||
{
|
||||
@@ -943,9 +944,16 @@ internal static class ExtendedPlayerControl
|
||||
{
|
||||
Logger.Warn($"FixBlackScreen was called for {pc.GetNameWithRole()}, but the conditions are not met to execute this code right now, waiting until it becomes possible to do so", "FixBlackScreen");
|
||||
|
||||
while (GameStates.InGame && !GameStates.IsEnded && (GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks || Main.AllPlayerControls.All(x => x.IsAlive())))
|
||||
while (GameStates.InGame && !GameStates.IsEnded && !CancelBlackScreenFix.Contains(pc.PlayerId) && (GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks || Main.AllPlayerControls.All(x => x.IsAlive())))
|
||||
yield return null;
|
||||
|
||||
if (CancelBlackScreenFix.Remove(pc.PlayerId))
|
||||
{
|
||||
Logger.Msg($"The black screen fix was canceled for {pc.GetNameWithRole()}", "FixBlackScreen");
|
||||
BlackScreenWaitingPlayers.Remove(pc.PlayerId);
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (!GameStates.InGame || GameStates.IsEnded)
|
||||
{
|
||||
Logger.Msg($"During the waiting, the game ended, so the black screen fix will not be executed for {pc.GetNameWithRole()}", "FixBlackScreen");
|
||||
@@ -1001,7 +1009,7 @@ internal static class ExtendedPlayerControl
|
||||
dummyGhost.NetTransform.SnapTo(murderPos, (ushort)(dummyGhost.NetTransform.lastSequenceId + 328));
|
||||
dummyGhost.NetTransform.SetDirtyBit(uint.MaxValue);
|
||||
|
||||
sender.AutoStartRpc(dummyGhost.NetTransform.NetId, (byte)RpcCalls.SnapTo);
|
||||
sender.AutoStartRpc(dummyGhost.NetTransform.NetId, 21);
|
||||
sender.WriteVector2(murderPos);
|
||||
sender.Write((ushort)(dummyGhost.NetTransform.lastSequenceId + 8));
|
||||
sender.EndRpc();
|
||||
@@ -1032,7 +1040,7 @@ internal static class ExtendedPlayerControl
|
||||
dummyGhost.NetTransform.SnapTo(ghostPos, (ushort)(dummyGhost.NetTransform.lastSequenceId + 328));
|
||||
dummyGhost.NetTransform.SetDirtyBit(uint.MaxValue);
|
||||
|
||||
sender.AutoStartRpc(dummyGhost.NetTransform.NetId, (byte)RpcCalls.SnapTo);
|
||||
sender.AutoStartRpc(dummyGhost.NetTransform.NetId, 21);
|
||||
sender.WriteVector2(ghostPos);
|
||||
sender.Write((ushort)(dummyGhost.NetTransform.lastSequenceId + 8));
|
||||
sender.EndRpc();
|
||||
|
||||
@@ -139,7 +139,7 @@ public class PlayerState(byte playerId)
|
||||
|
||||
Logger.Info($"ID {PlayerId} ({Player.GetRealName()}) => {role}, CountTypes => {countTypes}", "SetMainRole");
|
||||
|
||||
if (Main.IntroDestroyed)
|
||||
if (Main.IntroDestroyed && GameStates.InGame)
|
||||
{
|
||||
if (!previousHasTasks && Utils.HasTasks(Player.Data, false))
|
||||
{
|
||||
@@ -150,7 +150,7 @@ public class PlayerState(byte playerId)
|
||||
|
||||
if (!AmongUsClient.Instance.AmHost) return;
|
||||
|
||||
if (Main.IntroDestroyed)
|
||||
if (Main.IntroDestroyed && GameStates.InGame)
|
||||
{
|
||||
Player.ResetKillCooldown();
|
||||
|
||||
@@ -185,6 +185,8 @@ public class PlayerState(byte playerId)
|
||||
|
||||
Utils.NotifyRoles(SpecifySeer: Player);
|
||||
Utils.NotifyRoles(SpecifyTarget: Player);
|
||||
|
||||
HudSpritePatch.ResetButtonIcons = true;
|
||||
}
|
||||
|
||||
CheckMurderPatch.TimeSinceLastKill.Remove(PlayerId);
|
||||
@@ -210,6 +212,9 @@ public class PlayerState(byte playerId)
|
||||
|
||||
SetAddonCountTypes(role);
|
||||
|
||||
if (Main.IntroDestroyed && GameStates.InGame)
|
||||
HudSpritePatch.ResetButtonIcons = true;
|
||||
|
||||
Logger.Info($" ID {PlayerId} ({Player?.GetRealName()}) => {role}, CountTypes => {countTypes}", "SetSubRole");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EHR.AddOns.Common;
|
||||
using EHR.AddOns.GhostRoles;
|
||||
@@ -42,7 +43,8 @@ public static class NameColorManager
|
||||
switch (Options.CurrentGameMode)
|
||||
{
|
||||
case CustomGameMode.FFA when FreeForAll.FFATeamMode.GetBool():
|
||||
color = FreeForAll.TeamColors[FreeForAll.PlayerTeams[target.PlayerId]];
|
||||
if (FreeForAll.PlayerTeams.TryGetValue(target.PlayerId, out int team))
|
||||
color = FreeForAll.TeamColors.GetValueOrDefault(team, "#00ffff");
|
||||
return true;
|
||||
case CustomGameMode.RoomRush:
|
||||
case CustomGameMode.NaturalDisasters:
|
||||
|
||||
+19
-2
@@ -71,7 +71,6 @@ public enum CustomRPC
|
||||
SyncRabbit,
|
||||
SyncSoulHunter,
|
||||
|
||||
// BAU should always be 150
|
||||
BAU = 150,
|
||||
|
||||
SyncMycologist,
|
||||
@@ -143,12 +142,15 @@ public enum CustomRPC
|
||||
SyncOverheat,
|
||||
SyncIntrovert,
|
||||
SyncAllergic,
|
||||
SyncAsthmatic,
|
||||
|
||||
// Game Modes
|
||||
RoomRushDataSync,
|
||||
FFAKill,
|
||||
FFASync,
|
||||
QuizSync,
|
||||
HotPotatoSync
|
||||
HotPotatoSync,
|
||||
SoloPVPSync
|
||||
}
|
||||
|
||||
public enum Sounds
|
||||
@@ -595,6 +597,11 @@ internal static class RPCHandlerPatch
|
||||
Allergic.ReceiveRPC(reader);
|
||||
break;
|
||||
}
|
||||
case CustomRPC.SyncAsthmatic:
|
||||
{
|
||||
Asthmatic.ReceiveRPC(reader);
|
||||
break;
|
||||
}
|
||||
case CustomRPC.SetBountyTarget:
|
||||
{
|
||||
byte bountyId = reader.ReadByte();
|
||||
@@ -1133,6 +1140,11 @@ internal static class RPCHandlerPatch
|
||||
FreeForAll.OnPlayerAttack(killer, target);
|
||||
break;
|
||||
}
|
||||
case CustomRPC.FFASync:
|
||||
{
|
||||
FreeForAll.KillCount[reader.ReadByte()] = reader.ReadPackedInt32();
|
||||
break;
|
||||
}
|
||||
case CustomRPC.QuizSync:
|
||||
{
|
||||
Quiz.AllowKills = reader.ReadBoolean();
|
||||
@@ -1143,6 +1155,11 @@ internal static class RPCHandlerPatch
|
||||
HotPotato.ReceiveRPC(reader);
|
||||
break;
|
||||
}
|
||||
case CustomRPC.SoloPVPSync:
|
||||
{
|
||||
SoloPVP.KBScore[reader.ReadByte()] = reader.ReadPackedInt32();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
|
||||
+6
-6
@@ -62,7 +62,6 @@ public static class Utils
|
||||
|
||||
private static readonly Dictionary<byte, (string Text, int Duration, bool Long)> LongRoleDescriptions = [];
|
||||
|
||||
private static int NumSnapToRPCsThisRound;
|
||||
public static long TimeStamp => (long)(DateTime.Now.ToUniversalTime() - TimeStampStartTime).TotalSeconds;
|
||||
public static bool DoRPC => AmongUsClient.Instance.AmHost && Main.AllPlayerControls.Any(x => x.IsModdedClient() && !x.IsHost());
|
||||
public static int TotalTaskCount => Main.RealOptionsData.GetInt(Int32OptionNames.NumCommonTasks) + Main.RealOptionsData.GetInt(Int32OptionNames.NumLongTasks) + Main.RealOptionsData.GetInt(Int32OptionNames.NumShortTasks);
|
||||
@@ -154,8 +153,7 @@ public static class Utils
|
||||
}
|
||||
|
||||
var newSid = (ushort)(nt.lastSequenceId + 8);
|
||||
SendOption sendOption = NumSnapToRPCsThisRound < 100 || GameStates.CurrentServerType != GameStates.ServerType.Vanilla || DateTime.UtcNow.Month < 4 ? SendOption.Reliable : SendOption.None;
|
||||
MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(nt.NetId, (byte)RpcCalls.SnapTo, sendOption);
|
||||
MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(nt.NetId, (byte)RpcCalls.SnapTo, SendOption.Reliable);
|
||||
NetHelpers.WriteVector2(location, messageWriter);
|
||||
messageWriter.Write(newSid);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(messageWriter);
|
||||
@@ -165,7 +163,6 @@ public static class Utils
|
||||
CheckInvalidMovementPatch.LastPosition[pc.PlayerId] = location;
|
||||
CheckInvalidMovementPatch.ExemptedPlayers.Add(pc.PlayerId);
|
||||
|
||||
NumSnapToRPCsThisRound++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3482,8 +3479,11 @@ public static class Utils
|
||||
summary = $"{ColorString(Main.PlayerColors[id], name)} - <#e8cd46>{GetString("SurvivedTimePrefix")}: <#ffffff>{(time2 == 0 ? $"{GetString("SurvivedUntilTheEnd")}</color>" : $"{time2}</color>s")}</color> ({GetVitalText(id, true)})";
|
||||
break;
|
||||
case CustomGameMode.RoomRush:
|
||||
int time3 = RoomRush.GetSurvivalTime(id);
|
||||
summary = $"{ColorString(Main.PlayerColors[id], name)} - <#e8cd46>{GetString("SurvivedTimePrefix")}: <#ffffff>{(time3 == 0 ? RoomRush.PointsSystem ? string.Empty : $"{GetString("SurvivedUntilTheEnd")}</color>" : $"{time3}</color>s")}</color> ({(RoomRush.PointsSystem ? RoomRush.GetPoints(id) : GetVitalText(id, true))})";
|
||||
int rrSurvivalTime = RoomRush.GetSurvivalTime(id);
|
||||
string rrSurvivalTimeText = rrSurvivalTime == 0 ? $"{GetString("SurvivedUntilTheEnd")}</color>" : $"{rrSurvivalTime}</color>s";
|
||||
string rrSurvivedText = RoomRush.PointsSystem ? RoomRush.GetPoints(id) : $"{GetString("SurvivedTimePrefix")}: <#ffffff>{rrSurvivalTimeText}</color>";
|
||||
string vitalText = RoomRush.PointsSystem ? string.Empty : $" ({GetVitalText(id, true)})";
|
||||
summary = $"{ColorString(Main.PlayerColors[id], name)} - <#e8cd46>{rrSurvivedText}{vitalText}";
|
||||
break;
|
||||
case CustomGameMode.CaptureTheFlag:
|
||||
summary = $"{ColorString(Main.PlayerColors[id], name)}: {CaptureTheFlag.GetStatistics(id)}";
|
||||
|
||||
@@ -282,7 +282,8 @@ internal static class GameEndChecker
|
||||
|
||||
if ((WinnerTeam == CustomWinner.Lovers || WinnerIds.Any(x => Main.PlayerStates[x].SubRoles.Contains(CustomRoles.Lovers))) && Main.LoversPlayers.TrueForAll(x => x.IsAlive()) && reason != GameOverReason.CrewmatesByTask)
|
||||
{
|
||||
if (WinnerTeam != CustomWinner.Lovers) AdditionalWinnerTeams.Add(AdditionalWinners.Lovers);
|
||||
if (WinnerTeam != CustomWinner.Lovers)
|
||||
AdditionalWinnerTeams.Add(AdditionalWinners.Lovers);
|
||||
|
||||
WinnerIds.UnionWith(Main.LoversPlayers.Select(x => x.PlayerId));
|
||||
}
|
||||
@@ -404,6 +405,50 @@ internal static class GameEndChecker
|
||||
GameManager.Instance.RpcEndGame(reason, false);
|
||||
}
|
||||
|
||||
private static bool WouldWinIfCrewLost(PlayerState state)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (state.MainRole)
|
||||
{
|
||||
case CustomRoles.Phantasm when state.TaskState.RemainingTasksCount <= 0 && state.IsDead:
|
||||
case CustomRoles.VengefulRomantic when VengefulRomantic.HasKilledKiller:
|
||||
case CustomRoles.SchrodingersCat when !state.SubRoles.Any(x => x.IsConverted()):
|
||||
case CustomRoles.Opportunist when !state.IsDead:
|
||||
case CustomRoles.Sunnyboy when state.IsDead:
|
||||
case CustomRoles.Maverick when !state.IsDead && state.Role is Maverick mr && mr.NumOfKills >= Maverick.MinKillsToWin.GetInt():
|
||||
case CustomRoles.Provocateur when Provocateur.Provoked.TryGetValue(state.Player.PlayerId, out byte tar) && !WinnerIds.Contains(tar):
|
||||
case CustomRoles.FFF when ((FFF)state.Role).IsWon:
|
||||
case CustomRoles.Postman when ((Postman)state.Role).IsFinished:
|
||||
case CustomRoles.Dealer when ((Dealer)state.Role).IsWon:
|
||||
case CustomRoles.Impartial when ((Impartial)state.Role).IsWon:
|
||||
case CustomRoles.Tank when ((Tank)state.Role).IsWon:
|
||||
case CustomRoles.Technician when ((Technician)state.Role).IsWon:
|
||||
case CustomRoles.Backstabber when ((Backstabber)state.Role).CheckWin():
|
||||
case CustomRoles.Predator when ((Predator)state.Role).IsWon:
|
||||
case CustomRoles.Gaslighter when ((Gaslighter)state.Role).AddAsAdditionalWinner():
|
||||
case CustomRoles.SoulHunter when ((SoulHunter)state.Role).Souls >= SoulHunter.NumOfSoulsToWin.GetInt():
|
||||
case CustomRoles.Curser:
|
||||
case CustomRoles.NoteKiller when !NoteKiller.CountsAsNeutralKiller && NoteKiller.Kills >= NoteKiller.NumKillsNeededToWin:
|
||||
case CustomRoles.NecroGuesser when ((NecroGuesser)state.Role).GuessedPlayers >= NecroGuesser.NumGuessesToWin.GetInt():
|
||||
case CustomRoles.RoomRusher when ((RoomRusher)state.Role).Won:
|
||||
case CustomRoles.Auditor:
|
||||
case CustomRoles.Magistrate:
|
||||
case CustomRoles.Seamstress:
|
||||
case CustomRoles.Spirit:
|
||||
case CustomRoles.Starspawn:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ThrowException(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetPredicateToNormal()
|
||||
{
|
||||
Predicate = new NormalGameEndPredicate();
|
||||
@@ -495,7 +540,7 @@ internal static class GameEndChecker
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aapc.All(x => Main.LoversPlayers.Exists(l => l.PlayerId == x.PlayerId)) && (!Main.LoversPlayers.TrueForAll(x => x.Is(Team.Crewmate)) || !Lovers.CrewLoversWinWithCrew.GetBool()))
|
||||
if (aapc.Length > 0 && aapc.All(x => Main.LoversPlayers.Exists(l => l.PlayerId == x.PlayerId)) && (!Main.LoversPlayers.TrueForAll(x => x.Is(Team.Crewmate)) || !Lovers.CrewLoversWinWithCrew.GetBool()))
|
||||
{
|
||||
ResetAndSetWinner(CustomWinner.Lovers);
|
||||
WinnerIds.UnionWith(Main.LoversPlayers.ConvertAll(x => x.PlayerId));
|
||||
@@ -504,11 +549,16 @@ internal static class GameEndChecker
|
||||
|
||||
if (Main.AllAlivePlayerControls.Any(x => x.GetCountTypes() == CountTypes.CustomTeam)) return false;
|
||||
|
||||
var statesCoutingAsCrew = Main.PlayerStates.Values.Where(x => x.countTypes == CountTypes.Crew).ToList();
|
||||
|
||||
if (statesCoutingAsCrew.Count > 0 && statesCoutingAsCrew.TrueForAll(WouldWinIfCrewLost))
|
||||
statesCoutingAsCrew.ForEach(x => x.countTypes = CountTypes.None);
|
||||
|
||||
int sheriffCount = AlivePlayersCount(CountTypes.Sheriff);
|
||||
|
||||
int Imp = AlivePlayersCount(CountTypes.Impostor);
|
||||
int Crew = AlivePlayersCount(CountTypes.Crew) + sheriffCount;
|
||||
int Coven = AlivePlayersCount(CountTypes.Coven);
|
||||
int imp = AlivePlayersCount(CountTypes.Impostor);
|
||||
int crew = AlivePlayersCount(CountTypes.Crew) + sheriffCount;
|
||||
int coven = AlivePlayersCount(CountTypes.Coven);
|
||||
|
||||
Dictionary<(CustomRoles? Role, CustomWinner Winner), int> roleCounts = [];
|
||||
|
||||
@@ -532,9 +582,9 @@ internal static class GameEndChecker
|
||||
{
|
||||
if (!x.Is(CustomRoles.DualPersonality)) continue;
|
||||
|
||||
if (x.Is(Team.Impostor)) Imp++;
|
||||
else if (x.Is(Team.Crewmate)) Crew++;
|
||||
else if (x.Is(Team.Coven)) Coven++;
|
||||
if (x.Is(Team.Impostor)) imp++;
|
||||
else if (x.Is(Team.Crewmate)) crew++;
|
||||
else if (x.Is(Team.Coven)) coven++;
|
||||
|
||||
if (x.Is(CustomRoles.Charmed)) roleCounts[(null, CustomWinner.Succubus)]++;
|
||||
if (x.Is(CustomRoles.Undead)) roleCounts[(null, CustomWinner.Necromancer)]++;
|
||||
@@ -551,19 +601,19 @@ internal static class GameEndChecker
|
||||
|
||||
if (totalNKAlive == 0)
|
||||
{
|
||||
if (Coven == 0)
|
||||
if (coven == 0)
|
||||
{
|
||||
if (Crew == 0 && Imp == 0)
|
||||
if (crew == 0 && imp == 0)
|
||||
{
|
||||
reason = GameOverReason.ImpostorsByKill;
|
||||
winner = CustomWinner.None;
|
||||
}
|
||||
else if (Crew <= Imp && sheriffCount == 0)
|
||||
else if (crew <= imp && sheriffCount == 0)
|
||||
{
|
||||
reason = GameOverReason.ImpostorsByKill;
|
||||
winner = CustomWinner.Impostor;
|
||||
}
|
||||
else if (Imp == 0)
|
||||
else if (imp == 0)
|
||||
{
|
||||
reason = GameOverReason.CrewmatesByVote;
|
||||
winner = CustomWinner.Crewmate;
|
||||
@@ -571,7 +621,7 @@ internal static class GameEndChecker
|
||||
else
|
||||
return false;
|
||||
|
||||
Logger.Info($"Crew: {Crew}, Imp: {Imp}, Coven: {Coven}", "CheckGameEndPatch.CheckGameEndByLivingPlayers");
|
||||
Logger.Info($"Crew: {crew}, Imp: {imp}, Coven: {coven}", "CheckGameEndPatch.CheckGameEndByLivingPlayers");
|
||||
ResetAndSetWinner((CustomWinner)winner);
|
||||
|
||||
if (winner == CustomWinner.Crewmate && Main.AllAlivePlayerControls.All(x => x.GetCustomRole().IsNeutral()))
|
||||
@@ -582,11 +632,11 @@ internal static class GameEndChecker
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Imp >= 1) return false;
|
||||
if (Crew > Coven) return false;
|
||||
if (imp >= 1) return false;
|
||||
if (crew > coven) return false;
|
||||
if (sheriffCount > 0) return false;
|
||||
|
||||
Logger.Info($"Crew: {Crew}, Imp: {Imp}, Coven: {Coven}", "CheckGameEndPatch.CheckGameEndByLivingPlayers");
|
||||
Logger.Info($"Crew: {crew}, Imp: {imp}, Coven: {coven}", "CheckGameEndPatch.CheckGameEndByLivingPlayers");
|
||||
reason = GameOverReason.ImpostorsByKill;
|
||||
ResetAndSetWinner(CustomWinner.Coven);
|
||||
}
|
||||
@@ -594,9 +644,9 @@ internal static class GameEndChecker
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Imp >= 1) return false; // both imps and NKs are alive, game must continue
|
||||
if (Coven >= 1) return false; // both covens and NKs are alive, game must continue
|
||||
if (Crew > totalNKAlive) return false; // Imps are dead, but crew still outnumbers NKs, game must continue
|
||||
if (imp >= 1) return false; // both imps and NKs are alive, game must continue
|
||||
if (coven >= 1) return false; // both covens and NKs are alive, game must continue
|
||||
if (crew > totalNKAlive) return false; // Imps are dead, but crew still outnumbers NKs, game must continue
|
||||
|
||||
// Imps dead, Crew <= NK, Checking if all NKs alive are in 1 team
|
||||
List<int> aliveCounts = roleCounts.Values.Where(x => x > 0).ToList();
|
||||
@@ -631,9 +681,7 @@ internal static class GameEndChecker
|
||||
}
|
||||
|
||||
if (winner != null) ResetAndSetWinner((CustomWinner)winner);
|
||||
|
||||
if (rl != null) WinnerRoles.Add((CustomRoles)rl);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -773,7 +821,7 @@ internal static class GameEndChecker
|
||||
case 0:
|
||||
MoveAndStop.RoundTime = 0;
|
||||
Logger.Warn("No players alive. Force ending the game", "MoveAndStop");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -1029,23 +1077,23 @@ internal static class GameEndChecker
|
||||
}
|
||||
|
||||
/// <summary>Determines whether sabotage victory is possible based on the elements in ShipStatus.Systems.</summary>
|
||||
public virtual bool CheckGameEndBySabotage(out GameOverReason reason)
|
||||
protected virtual bool CheckGameEndBySabotage(out GameOverReason reason)
|
||||
{
|
||||
reason = GameOverReason.ImpostorsByKill;
|
||||
if (ShipStatus.Instance.Systems == null) return false;
|
||||
|
||||
// TryGetValue is not available
|
||||
Il2CppSystem.Collections.Generic.Dictionary<SystemTypes, ISystemType> systems = ShipStatus.Instance.Systems;
|
||||
LifeSuppSystemType LifeSupp;
|
||||
LifeSuppSystemType lifeSupp;
|
||||
|
||||
if (systems.ContainsKey(SystemTypes.LifeSupp) && // Confirmation of sabotage existence
|
||||
(LifeSupp = systems[SystemTypes.LifeSupp].CastFast<LifeSuppSystemType>()) != null && // Confirmation that cast is possible
|
||||
LifeSupp.Countdown <= 0f) // Time up confirmation
|
||||
(lifeSupp = systems[SystemTypes.LifeSupp].CastFast<LifeSuppSystemType>()) != null && // Confirmation that cast is possible
|
||||
lifeSupp.Countdown <= 0f) // Time up confirmation
|
||||
{
|
||||
// oxygen sabotage
|
||||
ResetAndSetWinner(CustomWinner.Impostor);
|
||||
reason = GameOverReason.ImpostorsBySabotage;
|
||||
LifeSupp.Countdown = 10000f;
|
||||
lifeSupp.Countdown = 10000f;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1055,7 +1103,8 @@ internal static class GameEndChecker
|
||||
sys = systems[SystemTypes.Reactor];
|
||||
else if (systems.ContainsKey(SystemTypes.Laboratory))
|
||||
sys = systems[SystemTypes.Laboratory];
|
||||
else if (systems.ContainsKey(SystemTypes.HeliSabotage)) sys = systems[SystemTypes.HeliSabotage];
|
||||
else if (systems.ContainsKey(SystemTypes.HeliSabotage))
|
||||
sys = systems[SystemTypes.HeliSabotage];
|
||||
|
||||
ICriticalSabotage critical;
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ public static class HudSpritePatch
|
||||
|
||||
private static long LastErrorTime;
|
||||
|
||||
public static bool ResetButtonIcons;
|
||||
|
||||
public static void Postfix(HudManager __instance)
|
||||
{
|
||||
try
|
||||
@@ -39,7 +41,7 @@ public static class HudSpritePatch
|
||||
if (!Main.EnableCustomButton.Value || !Main.ProcessShapeshifts || Mastermind.ManipulatedPlayers.ContainsKey(player.PlayerId) || ExileController.Instance || GameStates.IsMeeting) return;
|
||||
if ((!SetHudActivePatch.IsActive && !MeetingStates.FirstMeeting) || !player.IsAlive() || Options.CurrentGameMode is not CustomGameMode.Standard and not CustomGameMode.CaptureTheFlag) return;
|
||||
|
||||
if (!AmongUsClient.Instance.IsGameStarted || !Main.IntroDestroyed)
|
||||
if (ResetButtonIcons || !AmongUsClient.Instance.IsGameStarted || !Main.IntroDestroyed)
|
||||
{
|
||||
Kill = null;
|
||||
Ability = null;
|
||||
@@ -47,6 +49,8 @@ public static class HudSpritePatch
|
||||
Sabotage = null;
|
||||
Pet = null;
|
||||
Report = null;
|
||||
|
||||
ResetButtonIcons = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -466,15 +470,11 @@ public static class HudSpritePatch
|
||||
}
|
||||
case CustomRoles.Warlock:
|
||||
{
|
||||
if (Options.UsePets.GetBool())
|
||||
if (Options.UsePets.GetBool() || !shapeshifting)
|
||||
{
|
||||
newKillButton = CustomButton.Get("Curse");
|
||||
if (Warlock.IsCurseAndKill.TryGetValue(player.PlayerId, out bool curse) && curse) newAbilityButton = CustomButton.Get("CurseKill");
|
||||
}
|
||||
else if (!shapeshifting)
|
||||
{
|
||||
newKillButton = CustomButton.Get("Curse");
|
||||
if (Warlock.IsCurseAndKill.TryGetValue(player.PlayerId, out bool curse) && curse) newAbilityButton = CustomButton.Get("CurseKill");
|
||||
if (Warlock.IsCurseAndKill.TryGetValue(player.PlayerId, out bool curse) && curse)
|
||||
newAbilityButton = CustomButton.Get("CurseKill");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -654,7 +654,7 @@ internal static class BeginCrewmatePatch
|
||||
case CustomGameMode.FFA:
|
||||
{
|
||||
__instance.TeamTitle.text = GetString("Killer");
|
||||
Color color = FreeForAll.PlayerTeams.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out int team) && ColorUtility.TryParseHtmlString(FreeForAll.TeamColors[team], out Color teamColor) ? teamColor : new(0, 255, 255, byte.MaxValue);
|
||||
Color color = FreeForAll.PlayerTeams.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out int team) && FreeForAll.TeamColors.TryGetValue(team, out var teamColorHex) && ColorUtility.TryParseHtmlString(teamColorHex, out Color teamColor) ? teamColor : new(0, 255, 255, byte.MaxValue);
|
||||
__instance.TeamTitle.color = __instance.BackgroundBar.material.color = color;
|
||||
PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Shapeshifter);
|
||||
__instance.ImpostorText.gameObject.SetActive(true);
|
||||
|
||||
@@ -1089,6 +1089,8 @@ internal static class ReportDeadBodyPatch
|
||||
Damocles.CountRepairSabotage = false;
|
||||
Stressed.CountRepairSabotage = false;
|
||||
|
||||
HudSpritePatch.ResetButtonIcons = true;
|
||||
|
||||
if (Options.CurrentGameMode == CustomGameMode.Standard)
|
||||
{
|
||||
foreach (byte id in Main.DiedThisRound)
|
||||
@@ -1858,9 +1860,6 @@ internal static class FixedUpdatePatch
|
||||
if (!self && CustomGameMode.KingOfTheZones.IsActiveOrIntegrated() && Main.IntroDestroyed && !KingOfTheZones.GameGoing)
|
||||
realName = EmptyMessage;
|
||||
|
||||
if (Magistrate.CallCourtNextMeeting)
|
||||
realName = target.Is(CustomRoles.Magistrate) ? GetString("Magistrate.CourtName") : GetString("Magistrate.JuryName");
|
||||
|
||||
string deathReason = seer.Data.IsDead && seer.KnowDeathReason(target) ? $"\n<size=1.5>『{ColorString(GetRoleColor(CustomRoles.Doctor), GetVitalText(target.PlayerId))}』</size>" : string.Empty;
|
||||
|
||||
string currentText = target.cosmetics.nameText.text;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using AmongUs.Data;
|
||||
@@ -92,8 +92,8 @@ internal static class OnGameJoinedPatch
|
||||
if (Options.AutoGMPollCommandAfterJoin.GetBool())
|
||||
{
|
||||
Main.Instance.StartCoroutine(CoRoutine());
|
||||
|
||||
System.Collections.IEnumerator CoRoutine()
|
||||
|
||||
IEnumerator CoRoutine()
|
||||
{
|
||||
float timer = Options.AutoGMPollCommandCooldown.GetInt();
|
||||
|
||||
@@ -103,7 +103,7 @@ internal static class OnGameJoinedPatch
|
||||
timer -= Time.deltaTime;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
ChatCommands.GameModePollCommand(PlayerControl.LocalPlayer, "/gmpoll", ["/gmpoll"]);
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ internal static class OnGameJoinedPatch
|
||||
{
|
||||
Main.Instance.StartCoroutine(CoRoutine());
|
||||
|
||||
System.Collections.IEnumerator CoRoutine()
|
||||
IEnumerator CoRoutine()
|
||||
{
|
||||
float timer = Options.AutoDraftStartCommandCooldown.GetInt();
|
||||
|
||||
@@ -189,7 +189,7 @@ internal static class OnPlayerJoinedPatch
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}, 4f, "green bean kick late task", false);
|
||||
}, 4.5f, "green bean kick late task", false);
|
||||
|
||||
if (AmongUsClient.Instance.AmHost && client.FriendCode == "" && Options.KickPlayerFriendCodeNotExist.GetBool() && !GameStates.IsLocalGame && GameStates.CurrentServerType is not GameStates.ServerType.ModdedWithCNOSupport and not GameStates.ServerType.ModdedWithoutCNOSupport)
|
||||
{
|
||||
@@ -208,12 +208,6 @@ internal static class OnPlayerJoinedPatch
|
||||
Logger.Info(msg, "Android Kick");
|
||||
}
|
||||
|
||||
if (AmongUsClient.Instance.AmHost && (client.PlayerName.EndsWith("cm", StringComparison.OrdinalIgnoreCase) || client.PlayerName.EndsWith("sm", StringComparison.OrdinalIgnoreCase)) && (client.PlayerName.Length == 4 || client.PlayerName.Count(x => x is 'i' or 'I') >= 2))
|
||||
{
|
||||
AmongUsClient.Instance.KickPlayer(client.Id, false);
|
||||
Logger.SendInGame("They were probably hacking tbh");
|
||||
}
|
||||
|
||||
if (FastDestroyableSingleton<FriendsListManager>.Instance.IsPlayerBlockedUsername(client.FriendCode) && AmongUsClient.Instance.AmHost && GameStates.CurrentServerType is not GameStates.ServerType.ModdedWithCNOSupport and not GameStates.ServerType.ModdedWithoutCNOSupport)
|
||||
{
|
||||
AmongUsClient.Instance.KickPlayer(client.Id, true);
|
||||
@@ -549,7 +543,7 @@ internal static class SetColorPatch
|
||||
AmongUsClient.Instance.KickPlayer(client.Id, false);
|
||||
}
|
||||
}
|
||||
}, 4.5f, "fortegreen bean color kick");
|
||||
}, 5f, "fortegreen bean color kick");
|
||||
}
|
||||
|
||||
if (bodyColor == 255) return;
|
||||
|
||||
@@ -3491,6 +3491,7 @@
|
||||
"WWRampageDur": "Rampage Duration",
|
||||
"WWCanRampage": "Vent to begin Rampaging",
|
||||
"WWCanRampageUnshift": "Press Unshift (shapeshift button) to begin Rampaging",
|
||||
"WWCanRampageVanish": "Press Vanish to begin Rampaging",
|
||||
"WWRampageOut": "You're no longer Rampaging",
|
||||
"WWRampageCountdown": "<color=#00ffa5>Rampage ends in</color> <b>{0}</b>s",
|
||||
"WWRampaging": "Rampaging",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EHR.Modules;
|
||||
using Hazel;
|
||||
using UnityEngine;
|
||||
using static EHR.Options;
|
||||
|
||||
@@ -97,7 +99,7 @@ internal class Asthmatic : IAddon
|
||||
|
||||
public static void OnCheckPlayerPosition(PlayerControl pc)
|
||||
{
|
||||
if (!pc.Is(CustomRoles.Asthmatic) || ExileController.Instance || !RunChecks || !Timers.TryGetValue(pc.PlayerId, out Counter counter)) return;
|
||||
if (!Main.IntroDestroyed || !pc.Is(CustomRoles.Asthmatic) || ExileController.Instance || !RunChecks || !Timers.TryGetValue(pc.PlayerId, out Counter counter)) return;
|
||||
|
||||
Vector2 currentPosition = pc.transform.position;
|
||||
|
||||
@@ -138,13 +140,32 @@ internal class Asthmatic : IAddon
|
||||
|
||||
string suffix = GetSuffixText(pc.PlayerId);
|
||||
|
||||
if (!pc.IsModdedClient() && (!LastSuffix.TryGetValue(pc.PlayerId, out string beforeSuffix) || beforeSuffix != suffix)) Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
|
||||
if (!pc.IsModdedClient() && (!LastSuffix.TryGetValue(pc.PlayerId, out string beforeSuffix) || beforeSuffix != suffix))
|
||||
{
|
||||
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
|
||||
Utils.SendRPC(CustomRPC.SyncAsthmatic, pc.PlayerId, suffix);
|
||||
}
|
||||
|
||||
LastSuffix[pc.PlayerId] = suffix;
|
||||
}
|
||||
|
||||
public static void ReceiveRPC(MessageReader reader)
|
||||
{
|
||||
LastSuffix[reader.ReadByte()] = reader.ReadString();
|
||||
}
|
||||
|
||||
public static string GetSuffixText(byte id)
|
||||
{
|
||||
return id.GetPlayer().IsAlive() && Timers.TryGetValue(id, out Counter counter) ? $"{counter.ColoredArrow} {counter.ColoredTimerString}" : string.Empty;
|
||||
if (Main.PlayerStates.TryGetValue(id, out var state) && !state.IsDead)
|
||||
{
|
||||
if (Timers.TryGetValue(id, out Counter counter))
|
||||
return $"{counter.ColoredArrow} {counter.ColoredTimerString}";
|
||||
else if (id.IsPlayerModClient() && !id.IsHost())
|
||||
return LastSuffix[id];
|
||||
else
|
||||
return string.Empty;
|
||||
}
|
||||
else
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
|
||||
namespace EHR.Impostor;
|
||||
|
||||
@@ -60,7 +61,15 @@ internal class Minimalism : RoleBase
|
||||
|
||||
if (BypassShields.GetBool())
|
||||
{
|
||||
killer.Kill(target);
|
||||
if (killer.Is(CustomRoles.Swift))
|
||||
{
|
||||
target.Suicide(PlayerState.DeathReason.Kill, killer);
|
||||
killer.SetKillCooldown();
|
||||
RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound);
|
||||
}
|
||||
else
|
||||
killer.Kill(target);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public class Werewolf : RoleBase
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
if (UseUnshiftTrigger.GetBool() && UseUnshiftTriggerForNKs.GetBool())
|
||||
if (UseUnshiftTrigger.GetBool() && UseUnshiftTriggerForNKs.GetBool() || UsePhantomBasis.GetBool() && UsePhantomBasisForNKs.GetBool())
|
||||
Utils.GetPlayerById(playerId).RpcResetAbilityCooldown();
|
||||
}, 12f, log: false);
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public class Werewolf : RoleBase
|
||||
|
||||
public override bool CanUseImpostorVentButton(PlayerControl pc)
|
||||
{
|
||||
return (CanRampage && (!UseUnshiftTrigger.GetBool() || !UseUnshiftTriggerForNKs.GetBool())) || IsRampaging || pc.inVent;
|
||||
return (CanRampage && (!UsePhantomBasis.GetBool() || !UsePhantomBasisForNKs.GetBool()) && (!UseUnshiftTrigger.GetBool() || !UseUnshiftTriggerForNKs.GetBool())) || IsRampaging || pc.inVent;
|
||||
}
|
||||
|
||||
public override bool CanUseKillButton(PlayerControl pc)
|
||||
@@ -98,9 +98,12 @@ public class Werewolf : RoleBase
|
||||
public override void ApplyGameOptions(IGameOptions opt, byte id)
|
||||
{
|
||||
opt.SetVision(HasImpostorVision.GetBool());
|
||||
if (UsePhantomBasis.GetBool() && UsePhantomBasisForNKs.GetBool()) AURoleOptions.PhantomCooldown = 1f;
|
||||
|
||||
if (UseUnshiftTrigger.GetBool() && UseUnshiftTriggerForNKs.GetBool()) AURoleOptions.ShapeshifterCooldown = RampageDur.GetFloat() + 0.5f;
|
||||
if (UsePhantomBasis.GetBool() && UsePhantomBasisForNKs.GetBool())
|
||||
AURoleOptions.PhantomCooldown = 1f;
|
||||
|
||||
if (UseUnshiftTrigger.GetBool() && UseUnshiftTriggerForNKs.GetBool())
|
||||
AURoleOptions.ShapeshifterCooldown = RampageDur.GetFloat() + 0.5f;
|
||||
|
||||
AURoleOptions.EngineerCooldown = 0f;
|
||||
AURoleOptions.EngineerInVentMaxTime = 0f;
|
||||
@@ -149,12 +152,12 @@ public class Werewolf : RoleBase
|
||||
if (lastTime + (long)RampageCD.GetFloat() < now)
|
||||
{
|
||||
lastTime = -10;
|
||||
bool unshift = UseUnshiftTrigger.GetBool() && UseUnshiftTriggerForNKs.GetBool();
|
||||
bool otherTrigger = UseUnshiftTrigger.GetBool() && UseUnshiftTriggerForNKs.GetBool() || UsePhantomBasis.GetBool() && UsePhantomBasisForNKs.GetBool();
|
||||
|
||||
if (!player.IsModdedClient())
|
||||
{
|
||||
player.Notify(GetString(unshift ? "WWCanRampageUnshift" : "WWCanRampage"));
|
||||
player.RpcChangeRoleBasis(unshift ? CustomRoles.Werewolf : CustomRoles.EngineerEHR);
|
||||
player.Notify(GetString(otherTrigger ? "WWCanRampageUnshift" : "WWCanRampage"));
|
||||
player.RpcChangeRoleBasis(otherTrigger ? CustomRoles.Werewolf : CustomRoles.EngineerEHR);
|
||||
}
|
||||
|
||||
SendRPC();
|
||||
@@ -246,7 +249,7 @@ public class Werewolf : RoleBase
|
||||
str.Append(string.Format(GetString("WWCD"), cooldown + 1));
|
||||
}
|
||||
else
|
||||
str.Append(GetString(UseUnshiftTrigger.GetBool() && UseUnshiftTriggerForNKs.GetBool() ? "WWCanRampageUnshift" : "WWCanRampage"));
|
||||
str.Append(GetString(UseUnshiftTrigger.GetBool() && UseUnshiftTriggerForNKs.GetBool() ? "WWCanRampageUnshift" : UsePhantomBasis.GetBool() && UsePhantomBasisForNKs.GetBool() ? "WWCanRampageVanish" : "WWCanRampage"));
|
||||
|
||||
return str.ToString();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user