mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
98e36e8883
13 files changed
+112
-52
No files matched your search
@@ -48,7 +48,7 @@ public static class AntiBlackout
|
||||
}
|
||||
|
||||
dummyImp.RpcChangeRoleBasis(CustomRoles.ImpostorEHR, forced: true);
|
||||
players.Without(dummyImp).Do(x => x.RpcChangeRoleBasis(CustomRoles.CrewmateEHR, forced: true));
|
||||
players.Without(dummyImp).Where(x => x.GetRoleMap().RoleType != RoleTypes.Detective).Do(x => x.RpcChangeRoleBasis(CustomRoles.CrewmateEHR, forced: true));
|
||||
}
|
||||
|
||||
// After the ejection screen, we revert the role types to their actual values.
|
||||
|
||||
@@ -997,6 +997,7 @@ internal static class CustomRolesHelper
|
||||
public static bool ForceCancelShapeshift(this CustomRoles role)
|
||||
{
|
||||
return role is
|
||||
CustomRoles.Glitch or
|
||||
CustomRoles.Illusionist or
|
||||
CustomRoles.Swapster or
|
||||
CustomRoles.Echo or
|
||||
@@ -1007,6 +1008,7 @@ internal static class CustomRolesHelper
|
||||
public static bool IsNoAnimationShifter(this CustomRoles role)
|
||||
{
|
||||
return role is
|
||||
CustomRoles.Glitch or
|
||||
CustomRoles.Generator or
|
||||
CustomRoles.Echo;
|
||||
}
|
||||
@@ -1256,27 +1258,14 @@ internal static class CustomRolesHelper
|
||||
|
||||
CustomRoles.Augmenter or
|
||||
CustomRoles.BallLightning or
|
||||
CustomRoles.Blackmailer or
|
||||
CustomRoles.Cantankerous or
|
||||
CustomRoles.Capitalism or
|
||||
CustomRoles.Consort or
|
||||
CustomRoles.Echo or
|
||||
CustomRoles.EvilDiviner or
|
||||
CustomRoles.FireWorks or
|
||||
CustomRoles.Framer or
|
||||
CustomRoles.Gangster or
|
||||
CustomRoles.Generator or
|
||||
CustomRoles.Hangman or
|
||||
CustomRoles.Inhibitor or
|
||||
CustomRoles.Kamikaze or
|
||||
CustomRoles.Mastermind or
|
||||
CustomRoles.Morphling or
|
||||
CustomRoles.Ninja or
|
||||
CustomRoles.Nullifier or
|
||||
CustomRoles.Penguin or
|
||||
CustomRoles.Postponer or
|
||||
CustomRoles.Puppeteer or
|
||||
CustomRoles.Saboteur or
|
||||
CustomRoles.Sapper or
|
||||
CustomRoles.Scavenger or
|
||||
CustomRoles.Swooper or
|
||||
@@ -1284,9 +1273,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Vampire or
|
||||
CustomRoles.Warlock or
|
||||
CustomRoles.Wasp or
|
||||
CustomRoles.Wiper or
|
||||
CustomRoles.Witch or
|
||||
CustomRoles.YinYanger => true,
|
||||
CustomRoles.Wiper => true,
|
||||
|
||||
_ => false
|
||||
};
|
||||
|
||||
@@ -1489,7 +1489,13 @@ internal static class ExtendedPlayerControl
|
||||
{
|
||||
player.MakeInvisible();
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)CustomRPC.Invisibility, SendOption.Reliable);
|
||||
writer.Write(true);
|
||||
writer.WritePacked(1);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)CustomRPC.Invisibility, SendOption.Reliable);
|
||||
writer.WritePacked(11);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
@@ -1526,7 +1532,13 @@ internal static class ExtendedPlayerControl
|
||||
{
|
||||
player.MakeVisible();
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)CustomRPC.Invisibility, SendOption.Reliable);
|
||||
writer.Write(false);
|
||||
writer.WritePacked(0);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)CustomRPC.Invisibility, SendOption.Reliable);
|
||||
writer.WritePacked(10);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
|
||||
@@ -733,6 +733,7 @@ public static class Options
|
||||
public static OptionItem AutoMessageSendInterval;
|
||||
public static OptionItem DraftMaxRolesPerPlayer;
|
||||
public static OptionItem LargerRoleTextSize;
|
||||
public static OptionItem DynamicTaskCountColor;
|
||||
public static OptionItem ShowTaskCountWhenAlive;
|
||||
public static OptionItem ShowTaskCountWhenDead;
|
||||
public static OptionItem IntegrateNaturalDisasters;
|
||||
@@ -2938,6 +2939,10 @@ public static class Options
|
||||
LargerRoleTextSize = new BooleanOptionItem(24451, "LargerRoleTextSize", false, TabGroup.GameSettings)
|
||||
.SetGameMode(CustomGameMode.Standard)
|
||||
.SetColor(new Color32(193, 255, 209, byte.MaxValue));
|
||||
|
||||
DynamicTaskCountColor = new BooleanOptionItem(24557, "DynamicTaskCountColor", false, TabGroup.GameSettings)
|
||||
.SetGameMode(CustomGameMode.Standard)
|
||||
.SetColor(new Color32(193, 255, 209, byte.MaxValue));
|
||||
|
||||
ShowTaskCountWhenAlive = new BooleanOptionItem(24452, "ShowTaskCountWhenAlive", true, TabGroup.GameSettings)
|
||||
.SetGameMode(CustomGameMode.Standard)
|
||||
|
||||
+17
-8
@@ -1325,15 +1325,24 @@ internal static class RPCHandlerPatch
|
||||
}
|
||||
case CustomRPC.Invisibility:
|
||||
{
|
||||
if (reader.ReadBoolean())
|
||||
int num = reader.ReadPackedInt32();
|
||||
|
||||
switch (num)
|
||||
{
|
||||
__instance.MakeInvisible();
|
||||
Main.Invisible.Add(__instance.PlayerId);
|
||||
}
|
||||
else
|
||||
{
|
||||
__instance.MakeVisible();
|
||||
Main.Invisible.Remove(__instance.PlayerId);
|
||||
case 1:
|
||||
__instance.MakeInvisible();
|
||||
Main.Invisible.Add(__instance.PlayerId);
|
||||
break;
|
||||
case 0:
|
||||
__instance.MakeVisible();
|
||||
Main.Invisible.Remove(__instance.PlayerId);
|
||||
break;
|
||||
case 11:
|
||||
Main.Invisible.Add(__instance.PlayerId);
|
||||
break;
|
||||
case 10:
|
||||
Main.Invisible.Remove(__instance.PlayerId);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
+36
-15
@@ -1183,24 +1183,30 @@ public static class Utils
|
||||
if (!taskState.HasTasks) return string.Empty;
|
||||
|
||||
NetworkedPlayerInfo info = GetPlayerInfoById(playerId);
|
||||
Color taskCompleteColor = HasTasks(info) ? Color.green : GetRoleColor(state.MainRole).ShadeColor(0.5f);
|
||||
Color nonCompleteColor = HasTasks(info) ? Color.yellow : Color.white;
|
||||
bool hasTasks = HasTasks(info);
|
||||
Color taskCompleteColor;
|
||||
Color nonCompleteColor;
|
||||
|
||||
if (!Options.DynamicTaskCountColor.GetBool())
|
||||
{
|
||||
taskCompleteColor = hasTasks ? Color.green : GetRoleColor(state.MainRole).ShadeColor(0.5f);
|
||||
nonCompleteColor = hasTasks ? Color.yellow : Color.white;
|
||||
}
|
||||
else
|
||||
{
|
||||
taskCompleteColor = Color.green;
|
||||
Color nonCompleteColorStart = hasTasks ? Color.red : Color.white;
|
||||
Color nonCompleteColorEnd = Color.green;
|
||||
float progress = (float)taskState.CompletedTasksCount / taskState.AllTasksCount;
|
||||
nonCompleteColor = Color.Lerp(nonCompleteColorStart, nonCompleteColorEnd, progress);
|
||||
}
|
||||
|
||||
if (Workhorse.IsThisRole(playerId)) nonCompleteColor = Workhorse.RoleColor;
|
||||
|
||||
Color normalColor = taskState.IsTaskFinished ? taskCompleteColor : nonCompleteColor;
|
||||
|
||||
if (Main.PlayerStates.TryGetValue(playerId, out PlayerState ps))
|
||||
{
|
||||
normalColor = ps.MainRole switch
|
||||
{
|
||||
CustomRoles.Hypocrite => Color.red,
|
||||
CustomRoles.Crewpostor => Color.red,
|
||||
CustomRoles.Cherokious => GetRoleColor(CustomRoles.Cherokious),
|
||||
CustomRoles.Pawn => GetRoleColor(CustomRoles.Pawn),
|
||||
_ => normalColor
|
||||
};
|
||||
}
|
||||
if (Main.PlayerStates.TryGetValue(playerId, out PlayerState ps) && ps.MainRole is CustomRoles.Hypocrite or CustomRoles.Crewpostor or CustomRoles.Cherokious or CustomRoles.Pawn)
|
||||
normalColor = GetRoleColor(ps.MainRole);
|
||||
|
||||
Color textColor = comms ? Color.gray : normalColor;
|
||||
string completed = comms ? "?" : $"{taskState.CompletedTasksCount}";
|
||||
@@ -2432,13 +2438,13 @@ public static class Utils
|
||||
return true;
|
||||
}
|
||||
|
||||
if (seer.Is(CustomRoles.Car) && !forMeeting)
|
||||
if (seer.Is(CustomRoles.Car) && !forMeeting && !GameStates.IsEnded)
|
||||
{
|
||||
sender.RpcSetName(seer, Car.Name);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Main.PlayerStates.TryGetValue(seer.PlayerId, out var seerState) && seerState.Role is Tree { TreeSpriteActive: true })
|
||||
if (Main.PlayerStates.TryGetValue(seer.PlayerId, out var seerState) && seerState.Role is Tree { TreeSpriteActive: true } && !forMeeting && !GameStates.IsEnded)
|
||||
{
|
||||
sender.RpcSetName(seer, Tree.Sprite);
|
||||
return true;
|
||||
@@ -2722,6 +2728,18 @@ public static class Utils
|
||||
sender.RpcSetName(target, "<size=0%>", seer);
|
||||
else
|
||||
{
|
||||
if (target.Is(CustomRoles.Car) && !forMeeting && !GameStates.IsEnded)
|
||||
{
|
||||
sender.RpcSetName(target, Car.Name, seer);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Main.PlayerStates.TryGetValue(target.PlayerId, out var targetState) && targetState.Role is Tree { TreeSpriteActive: true } && !forMeeting && !GameStates.IsEnded)
|
||||
{
|
||||
sender.RpcSetName(target, Tree.Sprite, seer);
|
||||
return true;
|
||||
}
|
||||
|
||||
TargetMark.Clear();
|
||||
|
||||
if (Options.CurrentGameMode != CustomGameMode.Standard || GameStates.IsLobby) goto BeforeEnd2;
|
||||
@@ -2923,6 +2941,9 @@ public static class Utils
|
||||
|
||||
if (!forMeeting)
|
||||
additionalSuffixes.Add(AFKDetector.GetSuffix(seer, target));
|
||||
|
||||
if (!forMeeting && seer.IsImpostor() && Main.Invisible.Contains(target.PlayerId))
|
||||
additionalSuffixes.Add(ColorString(Palette.White_75Alpha, GetString("Invisible")));
|
||||
|
||||
TargetSuffix.Append(BuildSuffix(seer, target, meeting: forMeeting));
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ internal static class ChatCommands
|
||||
new(["deletevip", "удвип", "убрвип", "удалитьвип", "убратьвип", "删除会员", "vip-remover"], "{id}", GetString("CommandDescription.DeleteVIP"), Command.UsageLevels.Host, Command.UsageTimes.Always, DeleteVIPCommand, true, false, [GetString("CommandArgs.DeleteVIP.Id")]),
|
||||
new(["assume", "предположить", "传销头目预测投票", "assumir"], "{id} {number}", GetString("CommandDescription.Assume"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, AssumeCommand, true, true, [GetString("CommandArgs.Assume.Id"), GetString("CommandArgs.Assume.Number")]),
|
||||
new(["note", "заметка", "记者管理笔记", "nota", "anotar"], "{action} [?]", GetString("CommandDescription.Note"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, NoteCommand, true, true, [GetString("CommandArgs.Note.Action"), GetString("CommandArgs.Note.UnknownValue")]),
|
||||
new(["os", "optionset", "шансроли", "设置职业生成概率"], "{chance} {role}", GetString("CommandDescription.OS"), Command.UsageLevels.Host, Command.UsageTimes.InLobby, OSCommand, true, false, [GetString("CommandArgs.OS.Chance"), GetString("CommandArgs.OS.Role")]),
|
||||
new(["os", "optionset", "шансроли", "设置职业生成概率"], "{chance} {role}", GetString("CommandDescription.OS"), Command.UsageLevels.HostOrAdmin, Command.UsageTimes.InLobby, OSCommand, true, false, [GetString("CommandArgs.OS.Chance"), GetString("CommandArgs.OS.Role")]),
|
||||
new(["negotiation", "neg", "наказание", "谈判方式", "negociar", "negociação"], "{number}", GetString("CommandDescription.Negotiation"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, NegotiationCommand, true, false, [GetString("CommandArgs.Negotiation.Number")]),
|
||||
new(["mute", "замутить", "мут", "禁言", "mutar", "silenciar"], "{id} [duration]", GetString("CommandDescription.Mute"), Command.UsageLevels.HostOrModerator, Command.UsageTimes.AfterDeathOrLobby, MuteCommand, true, false, [GetString("CommandArgs.Mute.Id"), GetString("CommandArgs.Mute.Duration")]),
|
||||
new(["unmute", "размутить", "размут", "解禁", "desmutar", "desilenciar"], "{id}", GetString("CommandDescription.Unmute"), Command.UsageLevels.HostOrAdmin, Command.UsageTimes.Always, UnmuteCommand, true, false, [GetString("CommandArgs.Unmute.Id")]),
|
||||
@@ -1509,6 +1509,12 @@ internal static class ChatCommands
|
||||
|
||||
private static void OSCommand(PlayerControl player, string text, string[] args)
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
RequestCommandProcessingFromHost(nameof(OSCommand), text, adminCommand: true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GameStates.IsLobby || args.Length < 3 || !byte.TryParse(args[1], out byte chance) || chance > 100 || chance % 5 != 0 || !GetRoleByName(string.Join(' ', args[2..]), out CustomRoles role) || !Options.CustomRoleSpawnChances.TryGetValue(role, out StringOptionItem option)) return;
|
||||
|
||||
if (role.IsAdditionRole())
|
||||
@@ -2049,8 +2055,6 @@ internal static class ChatCommands
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.IsHost() && !IsPlayerAdmin(player.FriendCode)) return;
|
||||
|
||||
if (GameStates.IsLobby)
|
||||
{
|
||||
Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId, sendOption: SendOption.None);
|
||||
|
||||
@@ -1314,7 +1314,7 @@ internal static class ReportDeadBodyPatch
|
||||
pc.FixMixedUpOutfit();
|
||||
|
||||
if (Main.Invisible.Contains(pc.PlayerId))
|
||||
pc.RpcMakeVisible();
|
||||
LateTask.New(() => pc.RpcMakeVisible(), 1f, log: false);
|
||||
|
||||
PhantomRolePatch.OnReportDeadBody(pc);
|
||||
}
|
||||
@@ -1840,6 +1840,9 @@ internal static class FixedUpdatePatch
|
||||
if (self) additionalSuffixes.Add(CustomTeamManager.GetSuffix(seer));
|
||||
|
||||
additionalSuffixes.Add(AFKDetector.GetSuffix(seer, target));
|
||||
|
||||
if (!GameStates.IsMeeting && Main.Invisible.Contains(target.PlayerId) && (self || !seer.AmOwner || (seer.IsImpostor() && target.IsImpostor())))
|
||||
additionalSuffixes.Add(ColorString(Palette.White_75Alpha, GetString("Invisible")));
|
||||
|
||||
switch (target.GetCustomRole())
|
||||
{
|
||||
|
||||
@@ -75,6 +75,12 @@ internal static class OnGameJoinedPatch
|
||||
|
||||
Main.Instance.StartCoroutine(OptionShower.GetText());
|
||||
}, 1f, "OnGameJoinedPatch");
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
if (Main.NormalOptions != null && Mathf.Approximately(Main.NormalOptions.KillCooldown, 25f))
|
||||
Main.NormalOptions.KillCooldown = Options.FallBackKillCooldownValue?.GetFloat() ?? 25f;
|
||||
}, 5f, log: false);
|
||||
|
||||
Main.SetRoles = [];
|
||||
Main.SetAddOns = [];
|
||||
|
||||
@@ -3301,6 +3301,7 @@
|
||||
"GG": "GG! No more killers remain. <#8cffff>Crewmates</color> win!",
|
||||
"SubText.Bloodlust": "With a secret....",
|
||||
"LargerRoleTextSize": "Larger Role Text Size",
|
||||
"DynamicTaskCountColor": "Dynamic Task Count Color",
|
||||
"ShowTaskCountWhenAlive": "Show Task Count When Alive",
|
||||
"ShowTaskCountWhenDead": "Show Task Count When Dead",
|
||||
"IntegrateNaturalDisasters": "Integrate the Natural Disasters game mode into the current game mode",
|
||||
|
||||
@@ -124,8 +124,14 @@ public class President : RoleBase
|
||||
public static void OnAnyoneApplyGameOptions(IGameOptions opt)
|
||||
{
|
||||
bool value = Main.RealOptionsData.GetBool(BoolOptionNames.AnonymousVotes);
|
||||
if (Instances.Any(x => x.IsDeclassification)) value = false;
|
||||
|
||||
if (!GameStates.IsMeeting)
|
||||
{
|
||||
opt.SetBool(BoolOptionNames.AnonymousVotes, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Instances.Any(x => x.IsDeclassification)) value = false;
|
||||
opt.SetBool(BoolOptionNames.AnonymousVotes, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ public class Abyssbringer : RoleBase
|
||||
private static OptionItem BlackHoleMoveSpeed;
|
||||
private static OptionItem BlackHoleRadius;
|
||||
private static OptionItem KillCooldown;
|
||||
private static OptionItem CanSabotage;
|
||||
|
||||
private byte AbyssbringerId;
|
||||
private List<BlackHoleData> BlackHoles = [];
|
||||
@@ -58,6 +59,9 @@ public class Abyssbringer : RoleBase
|
||||
KillCooldown = new IntegerOptionItem(++id, "KillCooldown", new(0, 120, 1), 30, tab)
|
||||
.SetParent(Options.CustomRoleSpawnChances[role])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
|
||||
CanSabotage = new BooleanOptionItem(++id, "CanSabotage", false, tab)
|
||||
.SetParent(Options.CustomRoleSpawnChances[role]);
|
||||
}
|
||||
|
||||
public override void Add(byte playerId)
|
||||
@@ -83,6 +87,11 @@ public class Abyssbringer : RoleBase
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanUseSabotage(PlayerControl pc)
|
||||
{
|
||||
return CanSabotage.GetBool();
|
||||
}
|
||||
|
||||
public override void SetKillCooldown(byte id)
|
||||
{
|
||||
Main.AllPlayerKillCooldown[id] = KillCooldown.GetInt();
|
||||
|
||||
@@ -161,7 +161,7 @@ public class Ambusher : RoleBase
|
||||
if (LastRPCTS != now)
|
||||
{
|
||||
pc.RpcResetAbilityCooldown();
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, AmbusherId, TargetId, TargetTimer, AbilityEndTimer, DontCheck, AmbusherId, Main.Invisible.Contains(AmbusherId));
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, AmbusherId, TargetId, TargetTimer, AbilityEndTimer, DontCheck);
|
||||
LastRPCTS = now;
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ public class Ambusher : RoleBase
|
||||
TargetTimer = FollowDuration.GetFloat();
|
||||
AbilityEndTimer = AbilityDuration.GetFloat();
|
||||
DontCheck = false;
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, AmbusherId, TargetId, TargetTimer, AbilityEndTimer, DontCheck, AmbusherId, Main.Invisible.Contains(AmbusherId));
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, AmbusherId, TargetId, TargetTimer, AbilityEndTimer, DontCheck);
|
||||
}
|
||||
|
||||
public void ReceiveRPC(MessageReader reader)
|
||||
@@ -193,9 +193,6 @@ public class Ambusher : RoleBase
|
||||
TargetTimer = reader.ReadSingle();
|
||||
AbilityEndTimer = reader.ReadSingle();
|
||||
DontCheck = reader.ReadBoolean();
|
||||
byte ambusherId = reader.ReadByte();
|
||||
if (reader.ReadBoolean()) Main.Invisible.Add(ambusherId);
|
||||
else Main.Invisible.Remove(ambusherId);
|
||||
}
|
||||
|
||||
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
|
||||
|
||||
Reference in new issue
Block a user