mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
Add Siren & a few fixes & improvements
This commit is contained in:
1 parent
b5e51df3a2
commit
de2356995b
35 files changed
+439
-103
No files matched your search
@@ -387,6 +387,7 @@ public enum CustomRoles
|
||||
Illusionist,
|
||||
Timelord,
|
||||
Enchanter,
|
||||
Siren,
|
||||
|
||||
// Solo Kombat
|
||||
KB_Normal,
|
||||
@@ -472,6 +473,7 @@ public enum CustomRoles
|
||||
DoubleShot,
|
||||
Egoist,
|
||||
Energetic,
|
||||
Entranced,
|
||||
EvilSpirit,
|
||||
Finder,
|
||||
Flashman,
|
||||
|
||||
@@ -387,6 +387,7 @@ public enum CustomRoles
|
||||
Illusionist,
|
||||
Timelord,
|
||||
Enchanter,
|
||||
Siren,
|
||||
|
||||
// Solo Kombat
|
||||
KB_Normal,
|
||||
@@ -472,6 +473,7 @@ public enum CustomRoles
|
||||
DoubleShot,
|
||||
Egoist,
|
||||
Energetic,
|
||||
Entranced,
|
||||
EvilSpirit,
|
||||
Finder,
|
||||
Flashman,
|
||||
|
||||
+46
-29
@@ -317,8 +317,12 @@ public static class CaptureTheFlag
|
||||
NetworkedPlayerInfo.PlayerOutfit blueOutfit = BlueOutfit;
|
||||
NetworkedPlayerInfo.PlayerOutfit yellowOutfit = YellowOutfit;
|
||||
|
||||
var sender = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable);
|
||||
var hasValue = false;
|
||||
// var sender = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable);
|
||||
// var hasValue = false;
|
||||
Dictionary<byte, CustomRpcSender> senders = [];
|
||||
Dictionary<byte, bool> hasValue = [];
|
||||
players.ForEach(x => senders[x.PlayerId] = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable));
|
||||
players.ForEach(x => hasValue[x.PlayerId] = false);
|
||||
|
||||
for (var i = 0; i < blueCount; i++)
|
||||
{
|
||||
@@ -328,13 +332,17 @@ public static class CaptureTheFlag
|
||||
bluePlayers.Add(player.PlayerId);
|
||||
blueOutfit.PlayerName = player.GetRealName();
|
||||
blueOutfit.PetId = player.Data.DefaultOutfit.PetId;
|
||||
hasValue |= Utils.RpcChangeSkin(player, blueOutfit, sender);
|
||||
|
||||
if (sender.stream.Length > 800)
|
||||
if (senders.TryGetValue(player.PlayerId, out CustomRpcSender sender) && hasValue.ContainsKey(player.PlayerId))
|
||||
{
|
||||
sender.SendMessage();
|
||||
sender = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable);
|
||||
hasValue = false;
|
||||
hasValue[player.PlayerId] |= Utils.RpcChangeSkin(player, blueOutfit, sender);
|
||||
|
||||
if (sender.stream.Length > 800)
|
||||
{
|
||||
sender.SendMessage();
|
||||
senders[player.PlayerId] = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable);
|
||||
hasValue[player.PlayerId] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,13 +352,17 @@ public static class CaptureTheFlag
|
||||
yellowPlayers.Add(player.PlayerId);
|
||||
yellowOutfit.PlayerName = player.GetRealName();
|
||||
yellowOutfit.PetId = player.Data.DefaultOutfit.PetId;
|
||||
hasValue |= Utils.RpcChangeSkin(player, yellowOutfit, sender);
|
||||
|
||||
if (sender.stream.Length > 800)
|
||||
if (senders.TryGetValue(player.PlayerId, out CustomRpcSender sender) && hasValue.ContainsKey(player.PlayerId))
|
||||
{
|
||||
sender.SendMessage();
|
||||
sender = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable);
|
||||
hasValue = false;
|
||||
hasValue[player.PlayerId] |= Utils.RpcChangeSkin(player, yellowOutfit, sender);
|
||||
|
||||
if (sender.stream.Length > 800)
|
||||
{
|
||||
sender.SendMessage();
|
||||
senders[player.PlayerId] = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable);
|
||||
hasValue[player.PlayerId] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,29 +380,31 @@ public static class CaptureTheFlag
|
||||
// Teleport players to their respective bases
|
||||
foreach (PlayerControl pc in Main.AllAlivePlayerControls)
|
||||
{
|
||||
if (!senders.TryGetValue(pc.PlayerId, out CustomRpcSender sender) || !hasValue.ContainsKey(pc.PlayerId)) continue;
|
||||
|
||||
if (PlayerTeams.TryGetValue(pc.PlayerId, out CTFTeam team))
|
||||
{
|
||||
switch (team)
|
||||
{
|
||||
case CTFTeam.Blue:
|
||||
hasValue |= sender.TP(pc, blueFlagBase.Position);
|
||||
hasValue |= sender.Notify(pc, string.Format(Translator.GetString("CTF_Notify_EnemyTeamRoom"), yellowFlagBase.RoomName));
|
||||
hasValue[pc.PlayerId] |= sender.TP(pc, blueFlagBase.Position);
|
||||
hasValue[pc.PlayerId] |= sender.Notify(pc, string.Format(Translator.GetString("CTF_Notify_EnemyTeamRoom"), yellowFlagBase.RoomName));
|
||||
break;
|
||||
case CTFTeam.Yellow:
|
||||
hasValue |= sender.TP(pc, yellowFlagBase.Position);
|
||||
hasValue |= sender.Notify(pc, string.Format(Translator.GetString("CTF_Notify_EnemyTeamRoom"), blueFlagBase.RoomName));
|
||||
hasValue[pc.PlayerId] |= sender.TP(pc, yellowFlagBase.Position);
|
||||
hasValue[pc.PlayerId] |= sender.Notify(pc, string.Format(Translator.GetString("CTF_Notify_EnemyTeamRoom"), blueFlagBase.RoomName));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hasValue |= pc.RpcChangeRoleBasis(CustomRoles.CTFPlayer, sender: sender);
|
||||
hasValue |= sender.RpcResetAbilityCooldown(pc);
|
||||
hasValue[pc.PlayerId] |= pc.RpcChangeRoleBasis(CustomRoles.CTFPlayer, sender: sender);
|
||||
hasValue[pc.PlayerId] |= sender.RpcResetAbilityCooldown(pc);
|
||||
|
||||
if (sender.stream.Length > 800)
|
||||
{
|
||||
sender.SendMessage();
|
||||
sender = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable);
|
||||
hasValue = false;
|
||||
senders[pc.PlayerId] = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable);
|
||||
hasValue[pc.PlayerId] = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,6 +423,8 @@ public static class CaptureTheFlag
|
||||
|
||||
int targetClientId = pc1.GetClientId();
|
||||
|
||||
if (!senders.TryGetValue(id1, out CustomRpcSender sender) || !hasValue.ContainsKey(id1)) continue;
|
||||
|
||||
foreach (byte id2 in data.Players)
|
||||
{
|
||||
try
|
||||
@@ -418,13 +434,13 @@ public static class CaptureTheFlag
|
||||
var pc2 = id2.GetPlayer();
|
||||
if (pc2 == null) continue;
|
||||
|
||||
hasValue |= sender.RpcSetRole(pc2, RoleTypes.Phantom, targetClientId);
|
||||
|
||||
hasValue[id1] |= sender.RpcSetRole(pc2, RoleTypes.Phantom, targetClientId);
|
||||
|
||||
if (sender.stream.Length > 800)
|
||||
{
|
||||
sender.SendMessage();
|
||||
sender = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable);
|
||||
hasValue = false;
|
||||
senders[id1] = CustomRpcSender.Create("CTF - OnGameStart", SendOption.Reliable);
|
||||
hasValue[id1] = false;
|
||||
}
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
@@ -438,7 +454,7 @@ public static class CaptureTheFlag
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
|
||||
sender.SendMessage(!hasValue);
|
||||
senders.IntersectBy(hasValue.Keys, x => x.Key).Do(x => x.Value.SendMessage(!hasValue[x.Key]));
|
||||
|
||||
ValidTag = true;
|
||||
GameStartTS = Utils.TimeStamp;
|
||||
@@ -501,7 +517,7 @@ public static class CaptureTheFlag
|
||||
}
|
||||
|
||||
if (PlayerData.TryGetValue(killer.PlayerId, out CTFPlayerData data)) data.TagCount++;
|
||||
sender.NotifyRolesSpecific(killer, killer);
|
||||
sender.NotifyRolesSpecific(killer, killer, out sender, out _);
|
||||
|
||||
sender.SendMessage();
|
||||
}
|
||||
@@ -650,7 +666,7 @@ public static class CaptureTheFlag
|
||||
{
|
||||
if (arrow) TargetArrow.Add(x.PlayerId, id);
|
||||
hasValue |= sender.Notify(x, Utils.ColorString(Color.yellow, Translator.GetString("CTF_FlagTaken")));
|
||||
|
||||
|
||||
if (sender.stream.Length > 800)
|
||||
{
|
||||
sender.SendMessage();
|
||||
@@ -670,7 +686,7 @@ public static class CaptureTheFlag
|
||||
{
|
||||
if (arrow) TargetArrow.Add(x.PlayerId, id);
|
||||
hasValue |= sender.Notify(x, Translator.GetString("CTF_EnemyFlagTaken"));
|
||||
|
||||
|
||||
if (sender.stream.Length > 800)
|
||||
{
|
||||
sender.SendMessage();
|
||||
@@ -774,7 +790,8 @@ public static class CaptureTheFlag
|
||||
}
|
||||
else if (GameEndCriteria.GetValue() != 2)
|
||||
{
|
||||
hasValue |= sender.NotifyRolesSpecific(__instance, __instance);
|
||||
hasValue |= sender.NotifyRolesSpecific(__instance, __instance, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
if (Vector2.Distance(pos, blackRoomPS) > 2f) hasValue |= sender.TP(__instance, blackRoomPS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,7 +716,7 @@ public class Main : BasePlugin
|
||||
|
||||
CustomRoles[] allRoles = Enum.GetValues<CustomRoles>();
|
||||
allRoles.Where(x => x.GetCustomRoleTypes() == CustomRoleTypes.Impostor).Do(x => RoleColors.TryAdd(x, ImpostorColor));
|
||||
allRoles.Where(x => x.IsCoven()).Do(x => RoleColors.TryAdd(x, CovenColor));
|
||||
allRoles.Where(x => x.IsCoven() || x == CustomRoles.Entranced).Do(x => RoleColors.TryAdd(x, CovenColor));
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
|
||||
@@ -542,6 +542,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Illusionist => RoleTypes.Shapeshifter,
|
||||
CustomRoles.Timelord => RoleTypes.Impostor,
|
||||
CustomRoles.Enchanter => RoleTypes.Impostor,
|
||||
CustomRoles.Siren => RoleTypes.Phantom,
|
||||
|
||||
_ => RoleTypes.GuardianAngel
|
||||
};
|
||||
@@ -762,7 +763,8 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Charmed or
|
||||
CustomRoles.Recruit or
|
||||
CustomRoles.Contagious or
|
||||
CustomRoles.Rascal;
|
||||
CustomRoles.Rascal or
|
||||
CustomRoles.Entranced;
|
||||
}
|
||||
|
||||
public static bool IsRecruitingRole(this CustomRoles role)
|
||||
@@ -870,7 +872,8 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Lovers or
|
||||
CustomRoles.Madmate or
|
||||
CustomRoles.Undead or
|
||||
CustomRoles.Egoist;
|
||||
CustomRoles.Egoist or
|
||||
CustomRoles.Entranced;
|
||||
}
|
||||
|
||||
public static bool IsImpOnlyAddon(this CustomRoles role)
|
||||
@@ -1164,7 +1167,8 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Banshee or
|
||||
CustomRoles.Illusionist or
|
||||
CustomRoles.Timelord or
|
||||
CustomRoles.Enchanter;
|
||||
CustomRoles.Enchanter or
|
||||
CustomRoles.Siren;
|
||||
}
|
||||
|
||||
public static RoleTypes GetRoleTypes(this CustomRoles role)
|
||||
@@ -1209,7 +1213,8 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Charmed or
|
||||
CustomRoles.Recruit or
|
||||
CustomRoles.Contagious or
|
||||
CustomRoles.Undead;
|
||||
CustomRoles.Undead or
|
||||
CustomRoles.Entranced;
|
||||
}
|
||||
|
||||
public static bool IsRevealingRole(this CustomRoles role, PlayerControl target)
|
||||
|
||||
@@ -671,10 +671,14 @@ public static class CustomRpcSenderExtensions
|
||||
return sender.TP(pc, new(vent.transform.position.x, vent.transform.position.y + 0.3636f), log);
|
||||
}
|
||||
|
||||
public static bool NotifyRolesSpecific(this CustomRpcSender sender, PlayerControl seer, PlayerControl target)
|
||||
public static bool NotifyRolesSpecific(this CustomRpcSender sender, PlayerControl seer, PlayerControl target, out CustomRpcSender newSender, out bool senderWasCleared)
|
||||
{
|
||||
senderWasCleared = false;
|
||||
newSender = sender;
|
||||
if (seer == null || seer.Data.Disconnected || (seer.IsModdedClient() && (seer.IsHost() || CustomGameMode.Standard.IsActiveOrIntegrated())) || (!SetUpRoleTextPatch.IsInIntro && GameStates.IsLobby)) return false;
|
||||
return Utils.WriteSetNameRpcsToSender(ref sender, false, false, false, false, false, false, seer, [seer], [target], out bool senderWasCleared) && !senderWasCleared;
|
||||
var hasValue = Utils.WriteSetNameRpcsToSender(ref sender, false, false, false, false, false, false, seer, [seer], [target], out senderWasCleared) && !senderWasCleared;
|
||||
newSender = sender;
|
||||
return hasValue;
|
||||
}
|
||||
|
||||
public static bool SyncSettings(this CustomRpcSender sender, PlayerControl player)
|
||||
|
||||
@@ -1724,7 +1724,7 @@ internal static class ExtendedPlayerControl
|
||||
|
||||
public static bool IsCrewmate(this PlayerControl pc)
|
||||
{
|
||||
return !pc.Is(CustomRoles.Bloodlust) && pc.GetCustomRole().IsCrewmate() && !pc.Is(Team.Coven);
|
||||
return !pc.Is(CustomRoles.Bloodlust) && pc.GetCustomRole().IsCrewmate() && !pc.Is(CustomRoleTypes.Coven);
|
||||
}
|
||||
|
||||
public static CustomRoleTypes GetCustomRoleTypes(this PlayerControl pc)
|
||||
@@ -1777,7 +1777,7 @@ internal static class ExtendedPlayerControl
|
||||
{
|
||||
return team switch
|
||||
{
|
||||
Team.Coven => target.GetCustomRole().IsCoven(),
|
||||
Team.Coven => target.GetCustomRole().IsCoven() || target.Is(CustomRoles.Entranced),
|
||||
Team.Impostor => (target.IsMadmate() || target.GetCustomRole().IsImpostorTeamV2() || Framer.FramedPlayers.Contains(target.PlayerId)) && !target.Is(CustomRoles.Bloodlust),
|
||||
Team.Neutral => target.GetCustomRole().IsNeutralTeamV2() || target.Is(CustomRoles.Bloodlust) || target.IsConverted(),
|
||||
Team.Crewmate => target.GetCustomRole().IsCrewmateTeamV2(),
|
||||
|
||||
@@ -4,6 +4,7 @@ using AmongUs.GameOptions;
|
||||
using EHR.AddOns.Common;
|
||||
using EHR.AddOns.Crewmate;
|
||||
using EHR.AddOns.GhostRoles;
|
||||
using EHR.Coven;
|
||||
using EHR.Crewmate;
|
||||
using EHR.Impostor;
|
||||
using EHR.Neutral;
|
||||
@@ -293,6 +294,7 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
|
||||
AURoleOptions.NoisemakerAlertDuration = 300f;
|
||||
}
|
||||
|
||||
Siren.ApplyGameOptionsForOthers(opt, player.PlayerId);
|
||||
Chef.ApplyGameOptionsForOthers(opt, player.PlayerId);
|
||||
President.OnAnyoneApplyGameOptions(opt);
|
||||
Negotiator.OnAnyoneApplyGameOptions(opt, player.PlayerId);
|
||||
|
||||
@@ -233,6 +233,7 @@ public class PlayerState(byte playerId)
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
SubRoles.Remove(CustomRoles.Entranced);
|
||||
SubRoles.Remove(CustomRoles.Charmed);
|
||||
SubRoles.Remove(CustomRoles.Recruit);
|
||||
SubRoles.Remove(CustomRoles.Contagious);
|
||||
@@ -255,6 +256,7 @@ public class PlayerState(byte playerId)
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
SubRoles.Remove(CustomRoles.Entranced);
|
||||
SubRoles.Remove(CustomRoles.Madmate);
|
||||
SubRoles.Remove(CustomRoles.Recruit);
|
||||
SubRoles.Remove(CustomRoles.Contagious);
|
||||
@@ -277,6 +279,7 @@ public class PlayerState(byte playerId)
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
SubRoles.Remove(CustomRoles.Entranced);
|
||||
SubRoles.Remove(CustomRoles.Madmate);
|
||||
SubRoles.Remove(CustomRoles.Recruit);
|
||||
SubRoles.Remove(CustomRoles.Contagious);
|
||||
@@ -287,6 +290,29 @@ public class PlayerState(byte playerId)
|
||||
Utils.NotifyRoles(SpecifySeer: Player);
|
||||
Utils.NotifyRoles(SpecifyTarget: Player);
|
||||
break;
|
||||
case CustomRoles.Entranced:
|
||||
TaskState.HasTasks = false;
|
||||
TaskState.AllTasksCount = 0;
|
||||
|
||||
countTypes = Siren.EntrancedCountMode.GetInt() switch
|
||||
{
|
||||
0 => CountTypes.OutOfGame,
|
||||
1 => CountTypes.Coven,
|
||||
2 => countTypes,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
SubRoles.Remove(CustomRoles.Charmed);
|
||||
SubRoles.Remove(CustomRoles.Madmate);
|
||||
SubRoles.Remove(CustomRoles.Recruit);
|
||||
SubRoles.Remove(CustomRoles.Contagious);
|
||||
SubRoles.Remove(CustomRoles.Rascal);
|
||||
SubRoles.Remove(CustomRoles.Loyal);
|
||||
SubRoles.Remove(CustomRoles.Undead);
|
||||
SubRoles.Remove(CustomRoles.Stressed);
|
||||
Utils.NotifyRoles(SpecifySeer: Player);
|
||||
Utils.NotifyRoles(SpecifyTarget: Player);
|
||||
break;
|
||||
case CustomRoles.LastImpostor:
|
||||
SubRoles.Remove(CustomRoles.Mare);
|
||||
break;
|
||||
@@ -302,6 +328,7 @@ public class PlayerState(byte playerId)
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
SubRoles.Remove(CustomRoles.Entranced);
|
||||
SubRoles.Remove(CustomRoles.Madmate);
|
||||
SubRoles.Remove(CustomRoles.Charmed);
|
||||
SubRoles.Remove(CustomRoles.Contagious);
|
||||
@@ -324,6 +351,7 @@ public class PlayerState(byte playerId)
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
SubRoles.Remove(CustomRoles.Entranced);
|
||||
SubRoles.Remove(CustomRoles.Madmate);
|
||||
SubRoles.Remove(CustomRoles.Recruit);
|
||||
SubRoles.Remove(CustomRoles.Charmed);
|
||||
|
||||
@@ -97,7 +97,7 @@ public static class GuessManager
|
||||
|
||||
if ((pc.IsCrewmate() && !Options.CrewmatesCanGuess.GetBool()) ||
|
||||
(pc.IsImpostor() && !Options.ImpostorsCanGuess.GetBool()) ||
|
||||
(pc.Is(Team.Coven) && !Options.CovenCanGuess.GetBool()) ||
|
||||
(pc.Is(CustomRoleTypes.Coven) && !Options.CovenCanGuess.GetBool()) ||
|
||||
(pc.IsNeutralKiller() && !Options.NeutralKillersCanGuess.GetBool()) ||
|
||||
(pc.GetCustomRole().IsNonNK() && !Options.PassiveNeutralsCanGuess.GetBool()) ||
|
||||
(pc.Is(CustomRoles.Lyncher) && Lyncher.GuessMode.GetValue() == 0) ||
|
||||
@@ -177,6 +177,7 @@ public static class GuessManager
|
||||
CustomRoles.Contagious => Options.ContagiousCanBeGuessed,
|
||||
CustomRoles.Undead => Options.UndeadCanBeGuessed,
|
||||
CustomRoles.Egoist => Options.EgoistCanBeGuessed,
|
||||
CustomRoles.Entranced => Options.EntrancedCanBeGuessed,
|
||||
_ => null
|
||||
};
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public static class NameColorManager
|
||||
if (Stained.VioletNameList.Contains(target.PlayerId) && !isMeeting) color = "#ff00ff";
|
||||
|
||||
// Coven
|
||||
if (seer.Is(Team.Coven) && target.Is(Team.Coven)) color = Main.CovenColor;
|
||||
if (seer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoleTypes.Coven)) color = Main.CovenColor;
|
||||
|
||||
// Impostors and Madmates
|
||||
if (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoleTypes.Impostor)) color = target.Is(CustomRoles.Egoist) && Options.ImpEgoistVisibalToAllies.GetBool() && seer != target ? Main.RoleColors[CustomRoles.Egoist] : Main.ImpostorColor;
|
||||
@@ -107,6 +107,9 @@ public static class NameColorManager
|
||||
if (target.Is(CustomRoles.Mare) && Utils.IsActive(SystemTypes.Electrical) && !isMeeting) color = Main.RoleColors[CustomRoles.Mare];
|
||||
if (seer.Is(CustomRoles.Contagious) && target.Is(CustomRoles.Contagious) && Virus.TargetKnowOtherTarget.GetBool()) color = Main.RoleColors[CustomRoles.Virus];
|
||||
if (seer.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Charmed) && Succubus.TargetKnowOtherTarget.GetBool()) color = Main.RoleColors[CustomRoles.Charmed];
|
||||
if (seer.Is(CustomRoles.Entranced) && target.Is(CustomRoles.Entranced) && Siren.EntrancedKnowEntranced.GetBool()) color = Main.RoleColors[CustomRoles.Siren];
|
||||
if (seer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoles.Entranced) && Siren.CovenKnowEntranced.GetValue() == 1) color = Main.RoleColors[CustomRoles.Entranced];
|
||||
if (target.Is(CustomRoleTypes.Coven) && seer.Is(CustomRoles.Entranced) && Siren.EntrancedKnowCoven.GetValue() == 1) color = Main.RoleColors[CustomRoles.Entranced];
|
||||
if (seer.Is(CustomRoles.Undead) && target.Is(CustomRoles.Undead)) color = Main.RoleColors[CustomRoles.Undead];
|
||||
|
||||
// Ghost roles
|
||||
@@ -138,6 +141,7 @@ public static class NameColorManager
|
||||
CustomRoles.Crewpostor when target.Is(CustomRoleTypes.Impostor) && Options.CrewpostorKnowsAllies.GetBool() => Main.ImpostorColor,
|
||||
CustomRoles.Hypocrite when target.Is(CustomRoleTypes.Impostor) && Hypocrite.KnowsAllies.GetBool() => Main.ImpostorColor,
|
||||
CustomRoles.Succubus when target.Is(CustomRoles.Charmed) => Main.RoleColors[CustomRoles.Charmed],
|
||||
CustomRoles.Siren when target.Is(CustomRoles.Entranced) => Main.RoleColors[CustomRoles.Siren],
|
||||
CustomRoles.Necromancer or CustomRoles.Deathknight when target.Is(CustomRoles.Undead) => Main.RoleColors[CustomRoles.Undead],
|
||||
CustomRoles.Necromancer or CustomRoles.Deathknight when Necromancer.PartiallyRecruitedIds.Contains(target.PlayerId) => Main.RoleColors[CustomRoles.Deathknight],
|
||||
CustomRoles.Virus when target.Is(CustomRoles.Contagious) => Main.RoleColors[CustomRoles.Contagious],
|
||||
@@ -190,6 +194,7 @@ public static class NameColorManager
|
||||
CustomRoles.SoulHunter when SoulHunter.IsSoulHunterTarget(seer.PlayerId) => Main.RoleColors[CustomRoles.SoulHunter],
|
||||
CustomRoles.Necromancer or CustomRoles.Deathknight when seer.Is(CustomRoles.Undead) => Main.RoleColors[targetRole],
|
||||
CustomRoles.Succubus when seer.Is(CustomRoles.Charmed) => Main.RoleColors[CustomRoles.Succubus],
|
||||
CustomRoles.Siren when seer.Is(CustomRoles.Entranced) => Main.RoleColors[CustomRoles.Siren],
|
||||
CustomRoles.Crewpostor when seer.Is(CustomRoleTypes.Impostor) && Options.AlliesKnowCrewpostor.GetBool() => Main.RoleColors[CustomRoles.Madmate],
|
||||
CustomRoles.Hypocrite when seer.Is(CustomRoleTypes.Impostor) && Hypocrite.AlliesKnowHypocrite.GetBool() => Main.RoleColors[CustomRoles.Madmate],
|
||||
CustomRoles.President when ((President)targetRoleClass).IsRevealed => Main.RoleColors[CustomRoles.President],
|
||||
@@ -211,6 +216,7 @@ public static class NameColorManager
|
||||
if (target.Is(CustomRoles.Contagious)) color = Main.NeutralColor;
|
||||
if (target.Is(CustomRoles.Egoist)) color = Main.NeutralColor;
|
||||
if (target.Is(CustomRoles.Recruit)) color = Main.NeutralColor;
|
||||
if (target.Is(CustomRoles.Entranced)) color = Main.CovenColor;
|
||||
}
|
||||
|
||||
// Global (important)
|
||||
@@ -227,7 +233,7 @@ public static class NameColorManager
|
||||
|| target.Is(CustomRoles.GM)
|
||||
|| seer.Is(CustomRoles.GM)
|
||||
|| (seer.Is(CustomRoles.God) && God.KnowInfo.GetValue() == 2)
|
||||
|| (seer.Is(Team.Coven) && target.Is(Team.Coven))
|
||||
|| (seer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoleTypes.Coven))
|
||||
|| (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoleTypes.Impostor))
|
||||
|| (seer.Is(CustomRoles.Traitor) && target.Is(Team.Impostor))
|
||||
|| (seer.Is(CustomRoles.Jackal) && target.Is(CustomRoles.Sidekick))
|
||||
|
||||
@@ -66,7 +66,8 @@ public static class NameNotifyManager
|
||||
|
||||
toNotify.ToValidPlayers().ForEach(x =>
|
||||
{
|
||||
hasValue |= sender.NotifyRolesSpecific(x, x);
|
||||
hasValue |= sender.NotifyRolesSpecific(x, x, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
if (sender.stream.Length > 800)
|
||||
{
|
||||
|
||||
@@ -736,6 +736,7 @@ public static class Options
|
||||
public static OptionItem ContagiousCanBeGuessed;
|
||||
public static OptionItem UndeadCanBeGuessed;
|
||||
public static OptionItem EgoistCanBeGuessed;
|
||||
public static OptionItem EntrancedCanBeGuessed;
|
||||
|
||||
public static OptionItem BewilderVision;
|
||||
public static OptionItem SunglassesVision;
|
||||
@@ -1252,6 +1253,10 @@ public static class Options
|
||||
.SetGameMode(CustomGameMode.Standard)
|
||||
.AddReplacement(("{role}", CustomRoles.Egoist.ToColoredString()));
|
||||
|
||||
EntrancedCanBeGuessed = new StringOptionItem(218, "ConvertedAddonCanBeGuessed", AddonGuessOptions, 2, TabGroup.Addons)
|
||||
.SetGameMode(CustomGameMode.Standard)
|
||||
.AddReplacement(("{role}", CustomRoles.Entranced.ToColoredString()));
|
||||
|
||||
|
||||
RoleLoadingText = "Add-ons\n.";
|
||||
|
||||
@@ -1448,16 +1453,16 @@ public static class Options
|
||||
|
||||
AutoPlayAgainCountdown = new IntegerOptionItem(44425, "AutoPlayAgainCountdown", new(1, 90, 1), 10, TabGroup.SystemSettings)
|
||||
.SetParent(AutoPlayAgain);
|
||||
|
||||
|
||||
AutoGMPollCommandAfterJoin = new BooleanOptionItem(19309, "AutoGMPollCommandAfterJoin", false, TabGroup.SystemSettings)
|
||||
.SetHeader(true);
|
||||
|
||||
|
||||
AutoGMPollCommandCooldown = new IntegerOptionItem(19307, "AutoGMPollCommandCooldown", new(10, 600, 5), 30, TabGroup.SystemSettings)
|
||||
.SetParent(AutoGMPollCommandAfterJoin)
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
|
||||
AutoDraftStartCommandAfterJoin = new BooleanOptionItem(19426, "AutoDraftStartCommandAfterJoin", false, TabGroup.SystemSettings);
|
||||
|
||||
|
||||
AutoDraftStartCommandCooldown = new IntegerOptionItem(19427, "AutoDraftStartCommandCooldown", new(10, 600, 5), 90, TabGroup.SystemSettings)
|
||||
.SetParent(AutoDraftStartCommandAfterJoin)
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
|
||||
+10
-3
@@ -511,7 +511,7 @@ public static class Utils
|
||||
{
|
||||
foreach (CustomRoles subRole in targetSubRoles)
|
||||
{
|
||||
if (subRole is not CustomRoles.LastImpostor and not CustomRoles.Madmate and not CustomRoles.Charmed and not CustomRoles.Recruit and not CustomRoles.Lovers and not CustomRoles.Contagious and not CustomRoles.Bloodlust)
|
||||
if (subRole is not CustomRoles.LastImpostor and not CustomRoles.Madmate and not CustomRoles.Charmed and not CustomRoles.Recruit and not CustomRoles.Lovers and not CustomRoles.Contagious and not CustomRoles.Bloodlust and not CustomRoles.Entranced)
|
||||
{
|
||||
string str = GetString("Prefix." + subRole);
|
||||
if (!subRole.IsAdditionRole()) str = GetString(subRole.ToString());
|
||||
@@ -542,6 +542,12 @@ public static class Utils
|
||||
roleText = GetRoleString("Charmed-") + roleText;
|
||||
}
|
||||
|
||||
if (targetSubRoles.Contains(CustomRoles.Entranced) && (self || pure || seeTargetBetrayalAddons || seerMainRole == CustomRoles.Siren || (Siren.CovenKnowEntranced.GetValue() == 1 && seerMainRole.IsCoven()) || (Siren.EntrancedKnowEntranced.GetBool() && seerSubRoles.Contains(CustomRoles.Entranced))))
|
||||
{
|
||||
roleColor = GetRoleColor(CustomRoles.Entranced);
|
||||
roleText = GetRoleString("Entranced-") + roleText;
|
||||
}
|
||||
|
||||
if (targetSubRoles.Contains(CustomRoles.Contagious) && (self || pure || seeTargetBetrayalAddons || seerMainRole == CustomRoles.Virus || (Virus.TargetKnowOtherTarget.GetBool() && seerSubRoles.Contains(CustomRoles.Contagious))))
|
||||
{
|
||||
roleColor = GetRoleColor(CustomRoles.Contagious);
|
||||
@@ -923,6 +929,7 @@ public static class Utils
|
||||
{
|
||||
switch (subRole)
|
||||
{
|
||||
case CustomRoles.Entranced:
|
||||
case CustomRoles.Madmate:
|
||||
case CustomRoles.Charmed:
|
||||
case CustomRoles.Recruit:
|
||||
@@ -1011,7 +1018,7 @@ public static class Utils
|
||||
(__instance.Is(CustomRoleTypes.Impostor) && PlayerControl.LocalPlayer.Is(CustomRoles.Crewpostor) && Options.AlliesKnowCrewpostor.GetBool()) ||
|
||||
(__instance.Is(CustomRoleTypes.Impostor) && PlayerControl.LocalPlayer.Is(CustomRoles.Hypocrite) && Hypocrite.AlliesKnowHypocrite.GetBool()) ||
|
||||
(__instance.Is(CustomRoleTypes.Impostor) && PlayerControl.LocalPlayer.Is(CustomRoleTypes.Impostor) && Options.ImpKnowAlliesRole.GetBool() && CustomTeamManager.GetCustomTeam(PlayerControl.LocalPlayer.PlayerId) == null && CustomTeamManager.GetCustomTeam(__instance.PlayerId) == null) ||
|
||||
(__instance.Is(Team.Coven) && PlayerControl.LocalPlayer.Is(Team.Coven)) ||
|
||||
(__instance.Is(CustomRoleTypes.Coven) && PlayerControl.LocalPlayer.Is(CustomRoleTypes.Coven)) ||
|
||||
(Main.LoversPlayers.TrueForAll(x => x.PlayerId == __instance.PlayerId || x.IsLocalPlayer()) && Main.LoversPlayers.Count == 2 && Lovers.LoverKnowRoles.GetBool()) ||
|
||||
(CustomTeamManager.AreInSameCustomTeam(__instance.PlayerId, PlayerControl.LocalPlayer.PlayerId) && CustomTeamManager.IsSettingEnabledForPlayerTeam(__instance.PlayerId, CTAOption.KnowRoles)) ||
|
||||
Main.PlayerStates.Values.Any(x => x.Role.KnowRole(PlayerControl.LocalPlayer, __instance)) ||
|
||||
@@ -2657,7 +2664,7 @@ public static class Utils
|
||||
(seer.Is(CustomRoles.Mimic) && target.Data.IsDead && Options.MimicCanSeeDeadRoles.GetBool()) ||
|
||||
(target.Is(CustomRoles.Gravestone) && target.Data.IsDead) ||
|
||||
(Main.LoversPlayers.TrueForAll(x => x.PlayerId == seer.PlayerId || x.PlayerId == target.PlayerId) && Main.LoversPlayers.Count == 2 && Lovers.LoverKnowRoles.GetBool()) ||
|
||||
(seer.Is(Team.Coven) && target.Is(Team.Coven)) ||
|
||||
(seer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoleTypes.Coven)) ||
|
||||
(seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoleTypes.Impostor) && Options.ImpKnowAlliesRole.GetBool() && CustomTeamManager.GetCustomTeam(seer.PlayerId) == null && CustomTeamManager.GetCustomTeam(target.PlayerId) == null) ||
|
||||
(seer.IsMadmate() && target.Is(CustomRoleTypes.Impostor) && Options.MadmateKnowWhosImp.GetBool()) ||
|
||||
(seer.Is(CustomRoleTypes.Impostor) && target.IsMadmate() && Options.ImpKnowWhosMadmate.GetBool()) ||
|
||||
|
||||
@@ -917,6 +917,8 @@ internal static class ChatCommands
|
||||
|
||||
public static void DraftStartCommand(PlayerControl player, string text, string[] args)
|
||||
{
|
||||
if (Options.CurrentGameMode != CustomGameMode.Standard) return;
|
||||
|
||||
if (!AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
RequestCommandProcessingFromHost(nameof(DraftStartCommand), text, true);
|
||||
@@ -955,7 +957,7 @@ internal static class ChatCommands
|
||||
|
||||
IEnumerator RepeatedlySendMessage()
|
||||
{
|
||||
for (var index = 0; index < 3; index++)
|
||||
for (var index = 0; index < 5; index++)
|
||||
{
|
||||
List<Message> messages = [];
|
||||
|
||||
@@ -968,8 +970,8 @@ internal static class ChatCommands
|
||||
|
||||
messages.SendMultipleMessages(index == 0 ? SendOption.Reliable : SendOption.None);
|
||||
|
||||
yield return new WaitForSeconds(20f);
|
||||
if (DraftResult.Count >= DraftRoles.Count || GameStates.InGame) yield break;
|
||||
yield return new WaitForSeconds(30f);
|
||||
if (DraftResult.Count >= DraftRoles.Count || !GameStates.IsLobby || GameStates.InGame) yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1242,8 +1244,6 @@ internal static class ChatCommands
|
||||
PollAnswers[choiceLetter] = $"<size=70%>〖 {answers[i]} 〗</size>";
|
||||
}
|
||||
|
||||
if (gmPoll) PollVotes['A'] = Main.AllPlayerControls.Length / 4;
|
||||
|
||||
msg += $"\n{GetString("Poll.Begin")}\n<size=60%><i>";
|
||||
string title = GetString("Poll.Title");
|
||||
Utils.SendMessage(msg + $"{string.Format(GetString("Poll.TimeInfo"), (int)Math.Round(PollTimer))}</i></size>", title: title);
|
||||
|
||||
@@ -126,7 +126,7 @@ internal static class GameEndChecker
|
||||
break;
|
||||
case CustomWinner.Coven:
|
||||
WinnerIds.UnionWith(Main.AllPlayerControls
|
||||
.Where(pc => pc.Is(Team.Coven) && !pc.IsMadmate() && !pc.IsConverted() && !pc.Is(CustomRoles.EvilSpirit))
|
||||
.Where(pc => pc.Is(Team.Coven) && !pc.IsMadmate() && (!pc.IsConverted() || pc.Is(CustomRoles.Entranced)) && !pc.Is(CustomRoles.EvilSpirit))
|
||||
.Select(pc => pc.PlayerId));
|
||||
|
||||
break;
|
||||
|
||||
@@ -932,7 +932,7 @@ internal static class IntroCutsceneDestroyPatch
|
||||
lp.RpcChangeRoleBasis(lp.GetCustomRole());
|
||||
lp.RpcResetAbilityCooldown();
|
||||
LateTask.New(() => lp.SetKillCooldown(), 0.2f, log: false);
|
||||
}, 1f, log: false);
|
||||
}, 0.1f, log: false);
|
||||
|
||||
if (Options.UsePets.GetBool() && Options.CurrentGameMode is CustomGameMode.Standard or CustomGameMode.HideAndSeek or CustomGameMode.CaptureTheFlag or CustomGameMode.AllInOne)
|
||||
{
|
||||
|
||||
@@ -850,7 +850,7 @@ internal static class MeetingHudStartPatch
|
||||
(seer.Is(CustomRoles.Mimic) && Main.VisibleTasksCount && target.Data.IsDead && Options.MimicCanSeeDeadRoles.GetBool()) ||
|
||||
(target.Is(CustomRoles.Gravestone) && Main.VisibleTasksCount && target.Data.IsDead) ||
|
||||
(Main.LoversPlayers.TrueForAll(x => x.PlayerId == target.PlayerId || x.PlayerId == seer.PlayerId) && Main.LoversPlayers.Count == 2 && Lovers.LoverKnowRoles.GetBool()) ||
|
||||
(seer.Is(Team.Coven) && target.Is(Team.Coven)) ||
|
||||
(seer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoleTypes.Coven)) ||
|
||||
(target.Is(CustomRoleTypes.Impostor) && seer.Is(CustomRoleTypes.Impostor) && Options.ImpKnowAlliesRole.GetBool() && CustomTeamManager.GetCustomTeam(seer.PlayerId) == null && CustomTeamManager.GetCustomTeam(target.PlayerId) == null) ||
|
||||
(target.Is(CustomRoleTypes.Impostor) && seer.IsMadmate() && Options.MadmateKnowWhosImp.GetBool()) ||
|
||||
(target.IsMadmate() && seer.Is(CustomRoleTypes.Impostor) && Options.ImpKnowWhosMadmate.GetBool()) ||
|
||||
|
||||
@@ -1227,7 +1227,7 @@ internal static class StartGameHostPatch
|
||||
return;
|
||||
}
|
||||
|
||||
List<PlayerControl> allPlayers = Main.AllPlayerControls.Where(pc => (!Main.NeverSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary<CustomRoles, List<CustomRoles>> bannedCombos) || bannedCombos.All(x => !pc.Is(x.Key) || !x.Value.Contains(CustomRoles.Lovers))) && !pc.Is(CustomRoles.GM) && (!pc.HasSubRole() || pc.GetCustomSubRoles().Count < Options.NoLimitAddonsNumMax.GetInt()) && !pc.Is(CustomRoles.Dictator) && !pc.Is(CustomRoles.God) && !pc.Is(CustomRoles.FFF) && !pc.Is(CustomRoles.Bomber) && !pc.Is(CustomRoles.Nuker) && !pc.Is(CustomRoles.Curser) && !pc.Is(CustomRoles.Provocateur) && !pc.Is(CustomRoles.Altruist) && (!pc.IsCrewmate() || Lovers.CrewCanBeInLove.GetBool()) && (!pc.GetCustomRole().IsNeutral() || Lovers.NeutralCanBeInLove.GetBool()) && (!pc.Is(Team.Coven) || Lovers.CovenCanBeInLove.GetBool()) && (!pc.IsImpostor() || Lovers.ImpCanBeInLove.GetBool())).ToList();
|
||||
List<PlayerControl> allPlayers = Main.AllPlayerControls.Where(pc => (!Main.NeverSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary<CustomRoles, List<CustomRoles>> bannedCombos) || bannedCombos.All(x => !pc.Is(x.Key) || !x.Value.Contains(CustomRoles.Lovers))) && !pc.Is(CustomRoles.GM) && (!pc.HasSubRole() || pc.GetCustomSubRoles().Count < Options.NoLimitAddonsNumMax.GetInt()) && !pc.Is(CustomRoles.Dictator) && !pc.Is(CustomRoles.God) && !pc.Is(CustomRoles.FFF) && !pc.Is(CustomRoles.Bomber) && !pc.Is(CustomRoles.Nuker) && !pc.Is(CustomRoles.Curser) && !pc.Is(CustomRoles.Provocateur) && !pc.Is(CustomRoles.Altruist) && (!pc.IsCrewmate() || Lovers.CrewCanBeInLove.GetBool()) && (!pc.GetCustomRole().IsNeutral() || Lovers.NeutralCanBeInLove.GetBool()) && (!pc.Is(CustomRoleTypes.Coven) || Lovers.CovenCanBeInLove.GetBool()) && (!pc.IsImpostor() || Lovers.ImpCanBeInLove.GetBool())).ToList();
|
||||
const CustomRoles role = CustomRoles.Lovers;
|
||||
int count = Math.Clamp(RawCount, 0, allPlayers.Count);
|
||||
if (RawCount == -1) count = Math.Clamp(role.GetCount(), 0, allPlayers.Count);
|
||||
|
||||
+48
-2
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BepInEx.Unity.IL2CPP.Utils.Collections;
|
||||
using EHR.AddOns.GhostRoles;
|
||||
using EHR.Crewmate;
|
||||
using EHR.Modules;
|
||||
@@ -506,6 +507,51 @@ internal static class SetEverythingUpPatch
|
||||
roleSummaryRectTransform.anchoredPosition = new(pos.x + 3.5f, pos.y - 0.7f);
|
||||
roleSummary.text = sb.ToString();
|
||||
|
||||
string[] lines = sb.ToString().Split('\n');
|
||||
List<TextMeshPro> roleSummaryObjects = [];
|
||||
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
GameObject lineObj = Object.Instantiate(roleSummaryObject, roleSummaryObject.transform.parent);
|
||||
TextMeshPro lineText = lineObj.GetComponent<TextMeshPro>();
|
||||
lineText.text = "<font=\"DIN_Pro_Bold_700 SDF\">" + lines[i];
|
||||
lineText.alignment = TextAlignmentOptions.TopLeft;
|
||||
|
||||
RectTransform lineRect = lineObj.GetComponent<RectTransform>();
|
||||
lineRect.anchoredPosition = new(pos.x + 3.5f - 5f, pos.y - 0.7f - (i * 0.15f)); // slide from the left
|
||||
lineText.alpha = 0f;
|
||||
|
||||
roleSummaryObjects.Add(lineText);
|
||||
|
||||
__instance.StartCoroutine(SlideAndFadeIn(lineRect, lineText, i * 0.15f).WrapToIl2Cpp()); // stagger animation
|
||||
continue;
|
||||
|
||||
static IEnumerator SlideAndFadeIn(RectTransform rect, TextMeshPro text, float delay)
|
||||
{
|
||||
yield return new WaitForSeconds(delay);
|
||||
|
||||
Vector2 start = rect.anchoredPosition;
|
||||
Vector2 end = start + new Vector2(5f, 0); // target pos
|
||||
const float duration = 0.5f;
|
||||
float elapsed = 0f;
|
||||
|
||||
while (elapsed < duration)
|
||||
{
|
||||
elapsed += Time.deltaTime;
|
||||
float t = elapsed / duration;
|
||||
rect.anchoredPosition = Vector2.Lerp(start, end, Mathf.SmoothStep(0, 1, t));
|
||||
text.alpha = t;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
rect.anchoredPosition = end;
|
||||
text.alpha = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
Object.Destroy(roleSummaryObject);
|
||||
|
||||
|
||||
bool showInitially = Main.ShowResult;
|
||||
|
||||
ResultsToggleButton = new SimpleButton(
|
||||
@@ -516,8 +562,8 @@ internal static class SetEverythingUpPatch
|
||||
new(0, 255, 255, 255),
|
||||
() =>
|
||||
{
|
||||
bool setToActive = !roleSummary.gameObject.activeSelf;
|
||||
roleSummary.gameObject.SetActive(setToActive);
|
||||
bool setToActive = !roleSummaryObjects[0].gameObject.activeSelf;
|
||||
roleSummaryObjects.ForEach(x => x.gameObject.SetActive(setToActive));
|
||||
Main.ShowResult = setToActive;
|
||||
ResultsToggleButton.Label.text = GetString(setToActive ? "HideResults" : "ShowResults");
|
||||
},
|
||||
|
||||
@@ -410,12 +410,24 @@ internal static class CheckMurderPatch
|
||||
return false;
|
||||
}
|
||||
|
||||
if (killer.Is(Team.Coven) && target.Is(Team.Coven))
|
||||
if (killer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoleTypes.Coven))
|
||||
{
|
||||
Notify("CovenKillEachOther");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (killer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoles.Entranced) && !Siren.CovenCanKillEntranced.GetBool())
|
||||
{
|
||||
Notify("CovenKillEntranced");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (killer.Is(CustomRoles.Entranced) && target.Is(CustomRoleTypes.Coven) && !Siren.EntrancedCanKillCoven.GetBool())
|
||||
{
|
||||
Notify("EntrancedKillCoven");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((Romantic.PartnerId == target.PlayerId && Romantic.IsPartnerProtected) ||
|
||||
Medic.OnAnyoneCheckMurder(killer, target) ||
|
||||
Randomizer.IsShielded(target) ||
|
||||
@@ -2244,7 +2256,7 @@ public static class PlayerControlCheckUseZiplinePatch
|
||||
if (Options.DisableZiplineFromTop.GetBool() && fromTop) return false;
|
||||
if (Options.DisableZiplineFromUnder.GetBool() && !fromTop) return false;
|
||||
|
||||
if (__instance.Is(Team.Coven) && Options.DisableZiplineForCoven.GetBool()) return false;
|
||||
if (__instance.Is(CustomRoleTypes.Coven) && Options.DisableZiplineForCoven.GetBool()) return false;
|
||||
if (__instance.IsImpostor() && Options.DisableZiplineForImps.GetBool()) return false;
|
||||
if (__instance.GetCustomRole().IsNeutral() && Options.DisableZiplineForNeutrals.GetBool()) return false;
|
||||
if (__instance.IsCrewmate() && Options.DisableZiplineForCrew.GetBool()) return false;
|
||||
|
||||
@@ -1831,6 +1831,8 @@
|
||||
"SocialiteTarget": "The target of the Socialite cannot be killed\\nYou were added to their Guest List",
|
||||
"BodyguardProtected": "The Bodyguard protected your target and died for them",
|
||||
"CovenKillEachOther": "As a Coven member, you cannot (and shouldn't) kill other Coven members",
|
||||
"CovenKillEntranced": "Coven members cannot kill Entranced players",
|
||||
"EntrancedKillCoven": "As an Entranced player, you cannot kill Coven members",
|
||||
"SomeSortOfProtection": "This player is shielded due to a role-specific action",
|
||||
"HexButtonText": "Hex",
|
||||
"EscapeeAbilityButtonText": "TP",
|
||||
@@ -2858,8 +2860,8 @@
|
||||
"ERR-002-000-2": "You're using an unsupported map, i.e. Submerged.",
|
||||
"FixBlackScreenWaitForDead": "Everyone is alive, and the black screen fix requires a ghost, so it will wait until someone dies.",
|
||||
"DraftNotEnoughRoles": "There are not enough roles enabled to choose from, so drafting cannot be started. Please enable more roles and try again.",
|
||||
"DraftStart": "<size=90%>Drafting has started! You now have a chance to pick a role from the list below if you'd like to get one of them for the next game. The roles you get to choose from, with their indexes, are:</size>\\n\\n{0}\\n\\n<size=90%>Chat commands to use:</size>\\n- Pick role: <b>/draft [index]</b>\\n- View description of role: <b>/dd [index]</b>\\nReplace [index] with the number of the role you want to pick.\\n<size=70%>If you don't pick a role, you get a random one like you normally would.</size>",
|
||||
"DraftResend": "<size=90%>Your drafting choices are:</size>\\n\\n{0}\\n\\n<size=90%>Chat commands to use:</size>\\n- Pick role: <b>/draft [index]</b>\\n- View description of role: <b>/dd [index]</b>\\n<size=90%>Replace [index] with the number of the role you want to pick.</size>",
|
||||
"DraftStart": "<size=90%>Drafting has started! You now have a chance to pick a role from the list below if you'd like to get one of them for the next game. The roles you get to choose from, with their indexes, are:</size>\\n\\n{0}\\n\\n<size=90%>Chat commands to use:</size>\\n- Pick role: <b>/draft [index]</b>\\n- View description of role: <b>/dd [index]</b>\\nReplace [index] with the number of the role you want to pick. Example: <b>/draft 4</b>\\n<size=70%>If you don't pick a role, you get a random one like you normally would.</size>",
|
||||
"DraftResend": "<size=90%>Your drafting choices are:</size>\\n\\n{0}\\n\\n<size=90%>Chat commands to use:</size>\\n- Pick role: <b>/draft [index]</b>\\n- View description of role: <b>/dd [index]</b>\\n<size=90%>Replace [index] with the number of the role you want to pick. Example: <b>/draft 4</b></size>",
|
||||
"DraftTitle": "<#00a5ff>➡</color> <#00ffa5>Drafting</color> <#00a5ff>⬅</color>",
|
||||
"DraftChosen": "You have chosen the <b>{0}</b> role for the next game.\\n<size=70%>You can still change your choice by typing /draft [index] again.</size>",
|
||||
"DeathCommand": "<#ffffff>You were killed by </color>{0}<#ffffff>\\nTheir role is </color>{1}",
|
||||
@@ -9271,6 +9273,28 @@
|
||||
"Enchanter": "Enchanter",
|
||||
"EnchanterInfo": "Alter investigations; kill with Necronomicon",
|
||||
"EnchanterInfoLong": "(Coven):\\nEnchant a player, making them appear as a Coven member to crew investigators. When an enchanted player is killed, their death reason will be random. When enhanced by the Necronomicon, you gain the ability to kill (by double clicking with your kill button on someone).",
|
||||
"Siren": "Siren",
|
||||
"SirenInfo": "Sing to convert with stages",
|
||||
"SirenInfoLong": "(Coven):\\nThe Siren has an entrancing voice. Use the Sing ability (via the Vanish button) to affect nearby players.\\n- On the first hearing, non-Coven players are blinded and slowed for a short time.\\n- On the second, they are again blinded and slowed, and cannot report bodies temporarily.\\n- On the third, they become Entranced, converting to the Coven.\\nWith the Necronomicon, the Siren gains the ability to kill normally, and her Sing is boosted by two stages:\\n- Players who've heard no songs are treated as if they've heard two.\\n- Players who've heard one song are treated as if they've heard three and become Entranced.\\nThe Siren sees a tracker near each player's name showing their current stage (0/3, 1/3, 2/3, Entranced).",
|
||||
"Siren.Stage1EffectsLength": "Length of Stage 1 Effects",
|
||||
"Siren.Stage2EffectsLength": "Length of Stage 2 Effects",
|
||||
"Siren.ReducedVision": "Reduced Vision",
|
||||
"Siren.ReducedSpeed": "Reduced Speed",
|
||||
"Siren.EntrancedCanKillCoven": "<#7b3fbb>Entranced</color> players can kill <#7b3fbb>Coven</color> Members",
|
||||
"Siren.CovenKnowEntranced": "Who sees <#7b3fbb>Entranced</color> players",
|
||||
"Siren.EntrancedKnowEntranced": "<#7b3fbb>Entranced</color> players know each other",
|
||||
"Siren.CovenCanKillEntranced": "<#7b3fbb>Coven</color> Members can kill <#7b3fbb>Entranced</color> players",
|
||||
"Siren.EntrancedCountMode": "<#7b3fbb>Entranced</color> players count as",
|
||||
"Siren.EntrancedKnowCoven": "<#7b3fbb>Entranced</color> players see",
|
||||
"CKEO.SirenOnly": "<#7b3fbb>Siren</color> Only",
|
||||
"CKEO.AllCoven": "All <#7b3fbb>Coven</color> Members",
|
||||
"ECMO.Nothing": "Nothing",
|
||||
"ECMO.Coven": "<#7b3fbb>Coven</color>",
|
||||
"ECMO.OriginalTeam": "Original Team",
|
||||
"Entranced": "Entranced",
|
||||
"EntrancedInfo": "You're on the Coven team",
|
||||
"EntrancedInfoLong": "(Add-ons):\\nYou are a non-Coven player who has been entranced by the Siren. You are now on the Coven team and win with them at the end.",
|
||||
"Entranced-": "Entranced ",
|
||||
"DCNotify.Hacking": "You were <color=#ff1919>banned</color> for hacking.\\n\\nPlease stop.",
|
||||
"DCNotify.Banned": "You were <color=#ff1919>banned</color> from this lobby.\\n\\nContact the host if this was a mistake.",
|
||||
"DCNotify.Kicked": "You were <color=#ffff00>kicked</color> from this lobby.\\n\\nYou may still rejoin.",
|
||||
|
||||
@@ -60,15 +60,17 @@ public class LastImpostor : IAddon
|
||||
SetKillCooldown();
|
||||
|
||||
var sender = CustomRpcSender.Create("LastImpostor", SendOption.Reliable);
|
||||
sender.SyncSettings(pc);
|
||||
sender.NotifyRolesSpecific(pc, pc);
|
||||
var hasValue = false;
|
||||
hasValue |= sender.SyncSettings(pc);
|
||||
hasValue |= sender.NotifyRolesSpecific(pc, pc, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
if (Main.KillTimers.TryGetValue(pc.PlayerId, out float timer) &&
|
||||
Main.AllPlayerKillCooldown.TryGetValue(pc.PlayerId, out float cd) &&
|
||||
timer > cd)
|
||||
sender.SetKillCooldown(pc);
|
||||
hasValue |= sender.SetKillCooldown(pc);
|
||||
|
||||
sender.SendMessage();
|
||||
sender.SendMessage(!hasValue);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -111,11 +111,12 @@ public class PotionMaster : Coven
|
||||
ShieldedPlayers.Remove(x);
|
||||
PlayerControl player = x.GetPlayer();
|
||||
|
||||
sender.NotifyRolesSpecific(pc, player);
|
||||
hasValue |= sender.NotifyRolesSpecific(pc, player, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
sender = RestartMessageIfTooLong();
|
||||
|
||||
sender.NotifyRolesSpecific(player, player);
|
||||
hasValue = true;
|
||||
hasValue |= sender.NotifyRolesSpecific(player, player, out sender, out cleared);
|
||||
if (cleared) hasValue = false;
|
||||
sender = RestartMessageIfTooLong();
|
||||
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, PotionMasterId, 2, x);
|
||||
@@ -125,12 +126,12 @@ public class PotionMaster : Coven
|
||||
{
|
||||
PlayerControl player = shieldedId.GetPlayer();
|
||||
|
||||
sender.NotifyRolesSpecific(pc, player);
|
||||
hasValue = true;
|
||||
hasValue |= sender.NotifyRolesSpecific(pc, player, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
sender = RestartMessageIfTooLong();
|
||||
|
||||
sender.NotifyRolesSpecific(player, player);
|
||||
hasValue = true;
|
||||
hasValue |= sender.NotifyRolesSpecific(player, player, out sender, out cleared);
|
||||
if (cleared) hasValue = false;
|
||||
sender = RestartMessageIfTooLong();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using Hazel;
|
||||
|
||||
namespace EHR.Coven;
|
||||
|
||||
public class Siren : Coven
|
||||
{
|
||||
public static bool On;
|
||||
private static List<Siren> Instances = [];
|
||||
|
||||
public static OptionItem AbilityCooldown;
|
||||
public static OptionItem SingRange;
|
||||
public static OptionItem Stage1EffectsLength;
|
||||
public static OptionItem Stage2EffectsLength;
|
||||
public static OptionItem ReducedVision;
|
||||
public static OptionItem ReducedSpeed;
|
||||
public static OptionItem EntrancedCanKillCoven;
|
||||
public static OptionItem CovenKnowEntranced;
|
||||
public static OptionItem EntrancedKnowEntranced;
|
||||
public static OptionItem CovenCanKillEntranced;
|
||||
public static OptionItem EntrancedCountMode;
|
||||
public static OptionItem EntrancedKnowCoven;
|
||||
|
||||
private static readonly string[] CovenKnowEntrancedOptions =
|
||||
[
|
||||
"CKEO.SirenOnly",
|
||||
"CKEO.AllCoven"
|
||||
];
|
||||
|
||||
private static readonly string[] EntrancedCountModeOptions =
|
||||
[
|
||||
"ECMO.Nothing",
|
||||
"ECMO.Coven",
|
||||
"ECMO.OriginalTeam"
|
||||
];
|
||||
|
||||
private Dictionary<byte, long> EffectEndTS;
|
||||
private byte SirenId;
|
||||
|
||||
private Dictionary<byte, int> Stages;
|
||||
|
||||
protected override NecronomiconReceivePriorities NecronomiconReceivePriority => NecronomiconReceivePriorities.Random;
|
||||
|
||||
public override bool IsEnable => On;
|
||||
|
||||
public override void SetupCustomOption()
|
||||
{
|
||||
StartSetup(650130)
|
||||
.AutoSetupOption(ref AbilityCooldown, 30f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref SingRange, 4f, new FloatValueRule(0.25f, 10f, 0.25f), OptionFormat.Multiplier)
|
||||
.AutoSetupOption(ref Stage1EffectsLength, 10, new IntegerValueRule(0, 60, 1), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref Stage2EffectsLength, 10, new IntegerValueRule(0, 60, 1), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref ReducedVision, 0.25f, new FloatValueRule(0f, 1f, 0.05f), OptionFormat.Multiplier)
|
||||
.AutoSetupOption(ref ReducedSpeed, 0.25f, new FloatValueRule(0f, 2f, 0.05f), OptionFormat.Multiplier)
|
||||
.AutoSetupOption(ref EntrancedCanKillCoven, false)
|
||||
.AutoSetupOption(ref CovenKnowEntranced, 1, CovenKnowEntrancedOptions)
|
||||
.AutoSetupOption(ref EntrancedKnowEntranced, false)
|
||||
.AutoSetupOption(ref CovenCanKillEntranced, true)
|
||||
.AutoSetupOption(ref EntrancedCountMode, 1, EntrancedCountModeOptions)
|
||||
.AutoSetupOption(ref EntrancedKnowCoven, 1, CovenKnowEntrancedOptions);
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
On = false;
|
||||
Instances = [];
|
||||
}
|
||||
|
||||
public override void Add(byte playerId)
|
||||
{
|
||||
On = true;
|
||||
Stages = [];
|
||||
EffectEndTS = [];
|
||||
SirenId = playerId;
|
||||
Instances.Add(this);
|
||||
}
|
||||
|
||||
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
|
||||
{
|
||||
AURoleOptions.PhantomCooldown = AbilityCooldown.GetFloat();
|
||||
}
|
||||
|
||||
public static void ApplyGameOptionsForOthers(IGameOptions opt, byte playerId)
|
||||
{
|
||||
foreach (Siren instance in Instances)
|
||||
{
|
||||
if (instance.EffectEndTS.ContainsKey(playerId))
|
||||
{
|
||||
float vision = ReducedVision.GetFloat();
|
||||
opt.SetVision(false);
|
||||
opt.SetFloat(FloatOptionNames.CrewLightMod, vision);
|
||||
opt.SetFloat(FloatOptionNames.ImpostorLightMod, vision);
|
||||
Main.AllPlayerSpeed[playerId] = ReducedSpeed.GetFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanUseKillButton(PlayerControl pc)
|
||||
{
|
||||
return HasNecronomicon;
|
||||
}
|
||||
|
||||
public override bool OnVanish(PlayerControl pc)
|
||||
{
|
||||
PlayerControl[] nearbyPlayers = Utils.GetPlayersInRadius(SingRange.GetFloat(), pc.Pos()).Without(pc).ToArray();
|
||||
|
||||
var sender = CustomRpcSender.Create("Siren.OnVanish", SendOption.Reliable);
|
||||
var hasValue = false;
|
||||
|
||||
foreach (PlayerControl player in nearbyPlayers)
|
||||
{
|
||||
if (!Stages.TryGetValue(player.PlayerId, out var stage))
|
||||
Stages[player.PlayerId] = stage = HasNecronomicon ? 2 : 1;
|
||||
|
||||
switch (stage)
|
||||
{
|
||||
case 1:
|
||||
EffectEndTS[player.PlayerId] = Utils.TimeStamp + Stage1EffectsLength.GetInt();
|
||||
player.MarkDirtySettings();
|
||||
hasValue |= sender.NotifyRolesSpecific(pc, player, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
break;
|
||||
case 2:
|
||||
ReportDeadBodyPatch.CanReport[player.PlayerId] = false;
|
||||
EffectEndTS[player.PlayerId] = Utils.TimeStamp + Stage2EffectsLength.GetInt();
|
||||
player.MarkDirtySettings();
|
||||
hasValue |= sender.NotifyRolesSpecific(pc, player, out sender, out cleared);
|
||||
if (cleared) hasValue = false;
|
||||
break;
|
||||
case 3:
|
||||
player.RpcSetCustomRole(CustomRoles.Entranced);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sender.SendMessage(!hasValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnGlobalFixedUpdate(PlayerControl pc, bool lowLoad)
|
||||
{
|
||||
if (lowLoad || !GameStates.IsInTask || ExileController.Instance || !pc.IsAlive() || !EffectEndTS.TryGetValue(pc.PlayerId, out var endTS) || endTS > Utils.TimeStamp) return;
|
||||
|
||||
ReportDeadBodyPatch.CanReport[pc.PlayerId] = true;
|
||||
EffectEndTS.Remove(pc.PlayerId);
|
||||
pc.MarkDirtySettings();
|
||||
}
|
||||
|
||||
public override bool KnowRole(PlayerControl player, PlayerControl target)
|
||||
{
|
||||
if (base.KnowRole(player, target)) return true;
|
||||
if (player.Is(CustomRoles.Entranced) && (target.Is(CustomRoles.Siren) || (target.Is(CustomRoleTypes.Coven) && EntrancedKnowCoven.GetValue() == 1))) return true;
|
||||
return EntrancedKnowEntranced.GetBool() && player.Is(CustomRoles.Entranced) && target.Is(CustomRoles.Entranced);
|
||||
}
|
||||
|
||||
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
|
||||
{
|
||||
if (seer.PlayerId != SirenId || hud || seer.PlayerId == target.PlayerId) return string.Empty;
|
||||
return $"{Stages.GetValueOrDefault(target.PlayerId, 0)}/3";
|
||||
}
|
||||
}
|
||||
@@ -202,9 +202,10 @@ public class Medic : RoleBase
|
||||
|
||||
var sender = CustomRpcSender.Create("Medic.OnAnyoneCheckMurder", SendOption.Reliable);
|
||||
var hasValue = false;
|
||||
|
||||
|
||||
hasValue |= sender.SetKillCooldown(killer, ResetCooldown.GetFloat());
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer);
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
switch (KnowShieldBroken.GetInt())
|
||||
{
|
||||
@@ -238,7 +239,8 @@ public class Medic : RoleBase
|
||||
if ((Visible)ShieldBreakIsVisible.GetInt() == Visible.Immediately)
|
||||
{
|
||||
TempMarkProtectedList.Remove(target.PlayerId);
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target);
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target, out sender, out cleared);
|
||||
if (cleared) hasValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,8 +89,10 @@ public class Monarch : RoleBase
|
||||
hasValue |= sender.RpcGuardAndKill(target, killer);
|
||||
hasValue |= sender.RpcGuardAndKill(target, target);
|
||||
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target);
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer);
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer, out sender, out cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
sender.SendMessage(!hasValue);
|
||||
|
||||
|
||||
@@ -223,7 +223,8 @@ public class Wizard : RoleBase
|
||||
|
||||
hasValue |= sender.Notify(killer, string.Format(Translator.GetString("Wizard.BuffGivenNotify"), target.PlayerId.ColoredPlayerName(), Translator.GetString($"Wizard.Buff.{SelectedBuff}"), Math.Round(value, 1)));
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, 3, target.PlayerId);
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target);
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
sender.SendMessage(!hasValue);
|
||||
return false;
|
||||
|
||||
@@ -89,12 +89,13 @@ internal class AntiAdminer : RoleBase
|
||||
if (IsMonitor || !EnableExtraAbility.GetBool() || ExtraAbilityStartTimeStamp > 0 || (CanOnlyUseWhileAnyWatch.GetBool() && !IsAdminWatch && !IsVitalWatch && !IsDoorLogWatch && !IsCameraWatch)) return false;
|
||||
|
||||
ExtraAbilityStartTimeStamp = Utils.TimeStamp;
|
||||
|
||||
|
||||
var sender = CustomRpcSender.Create("AntiAdminer.OnShapeshift", SendOption.Reliable);
|
||||
var hasValue = false;
|
||||
|
||||
|
||||
hasValue |= sender.RpcResetAbilityCooldown(shapeshifter);
|
||||
hasValue |= sender.NotifyRolesSpecific(shapeshifter, shapeshifter);
|
||||
hasValue |= sender.NotifyRolesSpecific(shapeshifter, shapeshifter, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
hasValue = PlayersNearDevices.Keys.ToValidPlayers().Where(x => x.IsAlive()).Aggregate(hasValue, (current, pc) => current || sender.Notify(pc, Translator.GetString("AAWarning"), Delay.GetFloat()));
|
||||
|
||||
|
||||
@@ -96,8 +96,10 @@ public class Gangster : RoleBase
|
||||
hasValue |= sender.RpcGuardAndKill(target, killer);
|
||||
hasValue |= sender.RpcGuardAndKill(target, target);
|
||||
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target);
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer);
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer, out sender, out cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
sender.SendMessage(!hasValue);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using static EHR.Options;
|
||||
|
||||
namespace EHR.Impostor;
|
||||
@@ -63,4 +64,4 @@ internal class ImperiusCurse : RoleBase
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,25 +373,20 @@ public class Penguin : RoleBase
|
||||
Penguin_.Kill(abductVictim);
|
||||
|
||||
var sender = CustomRpcSender.Create("PenguinMurder", SendOption.Reliable);
|
||||
|
||||
{
|
||||
sender.AutoStartRpc(abductVictim.NetTransform.NetId, (byte)RpcCalls.SnapTo);
|
||||
|
||||
{
|
||||
NetHelpers.WriteVector2(Penguin_.transform.position, sender.stream);
|
||||
sender.Write(abductVictim.NetTransform.lastSequenceId);
|
||||
}
|
||||
|
||||
sender.EndRpc();
|
||||
sender.AutoStartRpc(Penguin_.NetId, (byte)RpcCalls.MurderPlayer);
|
||||
|
||||
sender.AutoStartRpc(Penguin_.NetId, (byte)RpcCalls.MurderPlayer);
|
||||
{
|
||||
sender.WriteNetObject(abductVictim);
|
||||
}
|
||||
|
||||
sender.EndRpc();
|
||||
}
|
||||
|
||||
sender.SendMessage();
|
||||
}, 0.3f, "PenguinMurder");
|
||||
|
||||
|
||||
@@ -176,8 +176,10 @@ public class Jackal : RoleBase
|
||||
hasValue |= sender.RpcGuardAndKill(target, killer);
|
||||
hasValue |= sender.RpcGuardAndKill(target, target);
|
||||
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target);
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer);
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer, out sender, out cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
sender.SendMessage(!hasValue);
|
||||
|
||||
|
||||
@@ -101,7 +101,8 @@ internal class Necromancer : RoleBase
|
||||
|
||||
target.ResetKillCooldown();
|
||||
hasValue |= sender.Notify(target, GetString("RecruitedToDeathknight"), setName: false);
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target);
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
sender.SendMessage(!hasValue);
|
||||
|
||||
@@ -229,8 +230,10 @@ internal class Deathknight : RoleBase
|
||||
hasValue |= sender.RpcGuardAndKill(target, killer);
|
||||
hasValue |= sender.RpcGuardAndKill(target, target);
|
||||
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target);
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer);
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer, out sender, out cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
sender.SendMessage(!hasValue);
|
||||
|
||||
|
||||
@@ -118,9 +118,11 @@ public class Succubus : RoleBase
|
||||
hasValue |= sender.SetKillCooldown(killer);
|
||||
hasValue |= sender.RpcGuardAndKill(target, killer);
|
||||
hasValue |= sender.RpcGuardAndKill(target, target);
|
||||
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target);
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer);
|
||||
|
||||
hasValue |= sender.NotifyRolesSpecific(killer, target, out sender, out bool cleared);
|
||||
if (cleared) hasValue = false;
|
||||
hasValue |= sender.NotifyRolesSpecific(target, killer, out sender, out cleared);
|
||||
if (cleared) hasValue = false;
|
||||
|
||||
sender.SendMessage(!hasValue);
|
||||
|
||||
@@ -140,11 +142,8 @@ public class Succubus : RoleBase
|
||||
public override bool KnowRole(PlayerControl player, PlayerControl target)
|
||||
{
|
||||
if (base.KnowRole(player, target)) return true;
|
||||
|
||||
if (player.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Succubus)) return true;
|
||||
|
||||
if (KnowTargetRole.GetBool() && player.Is(CustomRoles.Succubus) && target.Is(CustomRoles.Charmed)) return true;
|
||||
|
||||
return TargetKnowOtherTarget.GetBool() && player.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Charmed);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user