Add Anchor, some fixes, /anagram

This commit is contained in:
Gurge44 committed 2024-12-20 10:56:21 +01:00
1 parent 8ac5a01821
commit fb1e0ee76e
15 files changed
+137 -50

No files matched your search

+1
View File
@@ -406,6 +406,7 @@ public enum CustomRoles
// Sub-role after 500
NotAssigned = 500,
Allergic,
Anchor,
Antidote,
AntiTP,
Asthmatic,
+2 -2
View File
@@ -1,12 +1,12 @@
<wpf:ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xml:space="preserve">
<s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">SOLUTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ExtractCommonBranchingCode/@EntryIndexedValue">SUGGESTION</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_STATEMENT_CONDITIONS/@EntryValue">False</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AFTER_MULTILINE_STATEMENTS/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_BEFORE_BLOCK_STATEMENTS/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_BEFORE_MULTILINE_STATEMENTS/@EntryValue">1</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/EMPTY_BLOCK_STYLE/@EntryValue">TOGETHER_SAME_LINE</s:String>
<s:Boolean
x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_BRACES_INSIDE_STATEMENT_CONDITIONS/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_BRACES_INSIDE_STATEMENT_CONDITIONS/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_BLOCK_ON_SAME_LINE/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AFK/@EntryIndexedValue">AFK</s:String>
+2 -2
View File
@@ -205,12 +205,12 @@ internal static class CustomRoleSelector
.ToList();
}
Logger.Msg("======================================================", "PreSelectedRoles");
Logger.Msg("===================================================", "PreSelectedRoles");
Logger.Info(string.Join(", ", Roles[RoleAssignType.Impostor].Select(x => x.Role.ToString())), "PreSelectedImpostorRoles");
Logger.Info(string.Join(", ", Roles[RoleAssignType.NeutralKilling].Select(x => x.Role.ToString())), "PreSelectedNKRoles");
Logger.Info(string.Join(", ", Roles[RoleAssignType.NonKillingNeutral].Select(x => x.Role.ToString())), "PreSelectedNNKRoles");
Logger.Info(string.Join(", ", Roles[RoleAssignType.Crewmate].Select(x => x.Role.ToString())), "PreSelectedCrewRoles");
Logger.Msg("======================================================", "PreSelectedRoles");
Logger.Msg("===================================================", "PreSelectedRoles");
try
{
-1
View File
@@ -595,7 +595,6 @@ internal static class CustomRolesHelper
public static bool IsImpostor(this CustomRoles role)
{
return (role == CustomRoles.DoubleAgent && !Main.IntroDestroyed) || role is
CustomRoles.DoubleAgent or
CustomRoles.Impostor or
CustomRoles.ImpostorEHR or
CustomRoles.Phantom or
+4 -3
View File
@@ -187,7 +187,7 @@ internal static class ExtendedPlayerControl
{
MethodBase callerMethod = new StackFrame(1, false).GetMethod();
string callerMethodName = callerMethod?.Name;
Logger.Warn(callerMethod?.DeclaringType?.FullName + "." + callerMethodName + " tried to get a CustomRole, but the target was null.", "GetCustomRole");
Logger.Warn($"{callerMethod?.DeclaringType?.FullName}.{callerMethodName} tried to get a CustomRole, but the target was null.", "GetCustomRole");
return CustomRoles.Crewmate;
}
@@ -877,7 +877,8 @@ internal static class ExtendedPlayerControl
if (realKiller != null)
{
pc.SetRealKiller(realKiller);
if (realKiller.Is(CustomRoles.Damocles)) Damocles.OnMurder(realKiller.PlayerId);
if (realKiller.Is(CustomRoles.Damocles))
Damocles.OnMurder(realKiller.PlayerId);
IncreaseAbilityUseLimitOnKill(realKiller);
}
@@ -1477,7 +1478,7 @@ internal static class ExtendedPlayerControl
public static (Vector2 Location, string RoomName) GetPositionInfo(this PlayerControl pc)
{
PlainShipRoom room = pc.GetPlainShipRoom();
string roomName = room == null ? "Outside" : $"@{GetString($"{room.RoomId}")}";
string roomName = GetString(room == null ? "Outside" : $"{room.RoomId}");
Vector2 pos = pc.Pos();
return (pos, roomName);
@@ -431,7 +431,7 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
AURoleOptions.ProtectionDurationSeconds = 0f;
AURoleOptions.ImpostorsCanSeeProtect = false;
Logger.Info($"Updated settings for {player.GetNameWithRole()}: Crew Vision = {opt.GetFloat(FloatOptionNames.CrewLightMod)}, Impostor Vision = {opt.GetFloat(FloatOptionNames.ImpostorLightMod)}, Speed = {opt.GetFloat(FloatOptionNames.PlayerSpeedMod)}", "BuildGameOptions");
Logger.Info($"Updated settings for {player.GetNameWithRole()}: Crew Vision = {opt.GetFloat(FloatOptionNames.CrewLightMod):N2}, Impostor Vision = {opt.GetFloat(FloatOptionNames.ImpostorLightMod):N2}, Speed = {opt.GetFloat(FloatOptionNames.PlayerSpeedMod):N2}", "BuildGameOptions");
return opt;
+5 -4
View File
@@ -94,15 +94,16 @@ internal static class GhostRolesManager
try
{
if (!CustomGameMode.Standard.IsActiveOrIntegrated()) return false;
if (AssignedGhostRoles.Count >= GhostRoles.Count) return false;
if (pc.IsAlive() || pc.GetCountTypes() is CountTypes.None or CountTypes.OutOfGame || pc.Is(CustomRoles.EvilSpirit) || pc.Is(CustomRoles.Curser)) return false;
if (pc.IsAlive() || pc.GetCountTypes() is CountTypes.None or CountTypes.OutOfGame || pc.Is(CustomRoles.EvilSpirit) || pc.Is(CustomRoles.Anchor)) return false;
switch (pc.GetCustomRole())
{
case CustomRoles.Backstabber: return false;
case CustomRoles.Workaholic when !Workaholic.WorkaholicCannotWinAtDeath.GetBool(): return false;
case CustomRoles.Curser:
case CustomRoles.Backstabber:
case CustomRoles.Workaholic when !Workaholic.WorkaholicCannotWinAtDeath.GetBool():
return false;
}
CustomRoles suitableRole = GetSuitableGhostRole(pc);
+44
View File
@@ -12,7 +12,9 @@ using EHR.Modules;
using EHR.Neutral;
using HarmonyLib;
using Hazel;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Networking;
using static EHR.Translator;
// ReSharper disable InconsistentNaming
@@ -109,6 +111,8 @@ internal static class ChatCommands
private static HashSet<byte> ReadyPlayers = [];
private static string CurrentAnagram = string.Empty;
public static void LoadCommands()
{
AllCommands =
@@ -183,6 +187,7 @@ internal static class ChatCommands
new(["dn", "deathnote", "заметкамертвого", "死亡笔记"], "{name}", GetString("CommandDescription.DeathNote"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, DeathNoteCommand, true, [GetString("CommandArgs.DeathNote.Name")]),
new(["w", "whisper", "шепот", "ш", "私聊", "sussurrar"], "{id} {message}", GetString("CommandDescription.Whisper"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, WhisperCommand, true, [GetString("CommandArgs.Whisper.Id"), GetString("CommandArgs.Whisper.Message")]),
new(["spectate", "спектейт", "观战", "espectar"], "", GetString("CommandDescription.Spectate"), Command.UsageLevels.Everyone, Command.UsageTimes.InLobby, SpectateCommand, false),
new(["anagram", "анаграмма"], "", GetString("CommandDescription.Anagram"), Command.UsageLevels.Everyone, Command.UsageTimes.Always, AnagramCommand, true),
// Commands with action handled elsewhere
new(["shoot", "guess", "bet", "bt", "st", "угадать", "бт", "猜测", "赌", "adivinhar"], "{id} {role}", GetString("CommandDescription.Guess"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, (_, _, _, _) => { }, true, [GetString("CommandArgs.Guess.Id"), GetString("CommandArgs.Guess.Role")]),
@@ -241,6 +246,8 @@ internal static class ChatCommands
__instance.timeSinceLastMessage = 3f;
string text = __instance.freeChatField.textArea.text.Trim();
CheckAnagramGuess(PlayerControl.LocalPlayer.PlayerId, text);
if (ChatHistory.Count == 0 || ChatHistory[^1] != text)
ChatHistory.Add(text);
@@ -327,6 +334,15 @@ internal static class ChatCommands
return !canceled;
}
private static void CheckAnagramGuess(byte id, string text)
{
if (text.Contains(CurrentAnagram))
{
Utils.SendMessage("\n", title: string.Format(GetString("Anagram.CorrectGuess"), id.ColoredPlayerName(), CurrentAnagram));
CurrentAnagram = string.Empty;
}
}
private static void RequestCommandProcessingFromHost(string methodName, string text)
{
PlayerControl pc = PlayerControl.LocalPlayer;
@@ -339,6 +355,32 @@ internal static class ChatCommands
// ---------------------------------------------------------------------------------------------------------------------------------------------
private static void AnagramCommand(ChatController __instance, PlayerControl player, string text, string[] args)
{
Main.Instance.StartCoroutine(Fetch());
return;
IEnumerator Fetch()
{
const string api = "https://random-word.ryanrk.com/api/en/word/random";
var request = UnityWebRequest.Get(api);
yield return request.SendWebRequest();
while (!request.isDone) yield return null;
if (request.result != UnityWebRequest.Result.Success) yield break;
string response = request.downloadHandler.text;
int firstQuote = response.IndexOf("\"", StringComparison.Ordinal);
int lastQuote = response.LastIndexOf("\"", StringComparison.Ordinal);
string word = response.Substring(firstQuote + 1, lastQuote - firstQuote - 1);
string scrambled = new(word.ToLower().ToCharArray().Shuffle());
CurrentAnagram = word;
byte sendTo = GameStates.InGame && !player.IsAlive() ? player.PlayerId : byte.MaxValue;
Utils.SendMessage(string.Format(GetString("Anagram"), scrambled), sendTo, GetString("AnagramTitle"));
}
}
private static void SpectateCommand(ChatController __instance, PlayerControl player, string text, string[] args)
{
if (!AmongUsClient.Instance.AmHost)
@@ -2389,6 +2431,8 @@ internal static class ChatCommands
}
if (text.StartsWith("\n")) text = text[1..];
CheckAnagramGuess(player.PlayerId, text.ToLower());
string[] args = text.Split(' ');
+27 -32
View File
@@ -139,44 +139,32 @@ public static class GameOptionsMenuPatch
OptionBehaviour optionBehaviour;
switch (baseGameSetting.Type)
try
{
case OptionTypes.Checkbox:
optionBehaviour = baseGameSetting.Type switch
{
optionBehaviour = Object.Instantiate(__instance.checkboxOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer);
optionBehaviour.transform.localPosition = new(posX, num, posZ);
OptionTypes.Checkbox => Object.Instantiate(__instance.checkboxOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer),
OptionTypes.String => Object.Instantiate(__instance.stringOptionOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer),
OptionTypes.Float or OptionTypes.Int => Object.Instantiate(__instance.numberOptionOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer),
_ => throw new Exception("Skipped option type")
};
}
catch { continue; }
OptionBehaviourSetSizeAndPosition(optionBehaviour, option, baseGameSetting.Type);
optionBehaviour.transform.localPosition = new(posX, num, posZ);
OptionBehaviourSetSizeAndPosition(optionBehaviour, option, baseGameSetting.Type);
break;
}
case OptionTypes.String:
if (!ModGameOptionsMenu.OptionList.ContainsValue(index))
{
switch (option.Name)
{
optionBehaviour = Object.Instantiate(__instance.stringOptionOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer);
optionBehaviour.transform.localPosition = new(posX, num, posZ);
OptionBehaviourSetSizeAndPosition(optionBehaviour, option, baseGameSetting.Type);
if (option.Name == "GameMode" && !ModGameOptionsMenu.OptionList.ContainsValue(index))
case "GameMode":
GameSettingMenuPatch.GameModeBehaviour = (StringOption)optionBehaviour;
break;
}
case OptionTypes.Float:
case OptionTypes.Int:
{
optionBehaviour = Object.Instantiate(__instance.numberOptionOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer);
optionBehaviour.transform.localPosition = new(posX, num, posZ);
OptionBehaviourSetSizeAndPosition(optionBehaviour, option, baseGameSetting.Type);
if (option.Name == "Preset" && !ModGameOptionsMenu.OptionList.ContainsValue(index))
break;
case "Preset":
GameSettingMenuPatch.PresetBehaviour = (NumberOption)optionBehaviour;
break;
break;
}
default:
continue;
}
optionBehaviour.SetClickMask(__instance.ButtonClickMask);
@@ -859,6 +847,8 @@ public class GameSettingMenuPatch
public static NumberOption PresetBehaviour;
public static StringOption GameModeBehaviour;
public static long LastPresetChange;
public static FreeChatInputField InputField;
private static System.Collections.Generic.List<OptionItem> HiddenBySearch = [];
@@ -973,8 +963,10 @@ public class GameSettingMenuPatch
minus.OnClick.AddListener((Action)(() =>
{
if (PresetBehaviour == null) __instance.ChangeTab(3, false);
if (PresetBehaviour == null)
__instance.ChangeTab(3, false);
LastPresetChange = Utils.TimeStamp;
PresetBehaviour.Decrease();
}));
@@ -1004,7 +996,10 @@ public class GameSettingMenuPatch
plus.OnClick.AddListener((Action)(() =>
{
if (PresetBehaviour == null) __instance.ChangeTab(3, false);
if (PresetBehaviour == null)
__instance.ChangeTab(3, false);
LastPresetChange = Utils.TimeStamp;
PresetBehaviour.Increase();
}));
+1 -1
View File
@@ -1332,7 +1332,7 @@ internal static class FixedUpdatePatch
if (GameStates.IsLobby && ((ModUpdater.HasUpdate && ModUpdater.ForceUpdate) || ModUpdater.IsBroken || !Main.AllowPublicRoom) && AmongUsClient.Instance.IsGamePublic) AmongUsClient.Instance.ChangeGamePublic(false);
// Kick low level people
if (!lowLoad && GameStates.IsLobby && !player.AmOwner && Options.KickLowLevelPlayer.GetInt() != 0 && (
if (!lowLoad && GameSettingMenuPatch.LastPresetChange + 5 < TimeStamp && GameStates.IsLobby && !player.AmOwner && Options.KickLowLevelPlayer.GetInt() != 0 && (
(player.Data.PlayerLevel != 0 && player.Data.PlayerLevel < Options.KickLowLevelPlayer.GetInt()) ||
player.Data.FriendCode == string.Empty
))
+8
View File
@@ -2332,6 +2332,7 @@
"CommandDescription.DeathNote": "Guess someone's real name as the Note Killer.",
"CommandDescription.Whisper": "Whisper a message to a player.",
"CommandDescription.Spectate": "Makes you a spectator for the next game. You should just enable Game Master as the host.",
"CommandDescription.Anagram": "Get a random scrambled word, then try to guess the original word.",
"CommandArgs.ChangeSetting.Name": "The setting's name to change (leave blank to view all settings)",
"CommandArgs.ChangeSetting.UnknownValue": "(leave blank to view what to put here)",
"CommandArgs.Rename.Name": "Your new name",
@@ -2423,6 +2424,9 @@
"DisableWhisperCommand": "Disable /whisper command",
"DisableSpectateCommand": "Disable /spectate command",
"WhisperDisabled": "<#ff0000>X</color> The /whisper command is disabled in this lobby.",
"Anagram.CorrectGuess": "<#00ffa5>✓</color> {0} has guessed the anagram correctly (<b>{1}</b>)!",
"Anagram": "The scrambled word is <b>{0}</b>! Guess the original word!",
"AnagramTitle": "<#888888>➡ ANAGRAM ⬅</color>",
"ThankYouForUsingEHR": "Thank you for using EHR!",
"GMRoles": "<color=#ff5b70>【 ★ Roles ★ 】</color>",
"ImpostorRoles": "【 ★ Impostor Roles ★ 】",
@@ -4763,6 +4767,10 @@
"AADelay": "Time to Leave Device",
"AAWarning": "<#ffff00>You must move away from this device or you die!</color>",
"AADone": "The process has finished",
"Anchor": "Anchor",
"AnchorInfo": "You Can't Get Ghost Roles",
"AnchorInfoLogin": "(Add-ons):\\nYou cannot be assigned any ghost roles.",
"Prefix.Anchor": "Anchor",
"Wizard": "Wizard",
"WizardInfo": "Change Players' Stats",
"WizardInfoLong": "(Crewmates):\\nAs the Wizard, you have 3 stats you can change for each player: Speed, Vision, and Kill Cooldown. Pet to cycle between these stats. Press Unshift to increase the value of the stat. To give the selected stat with its value to a player, use your kill button on them.\\n\\nThink twice before applying an effect, as it is <b><u>permanent</u></b>! You can override it by applying the same effect on them with a different value, but that removes another ability use!",
+11
View File
@@ -0,0 +1,11 @@
namespace EHR.AddOns;
public class Anchor : IAddon
{
public AddonTypes Type => AddonTypes.Harmful;
public void SetupCustomOption()
{
Options.SetupAdtRoleOptions(649093, CustomRoles.Anchor, canSetNum: true, teamSpawnOptions: true);
}
}
+21 -2
View File
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using EHR.AddOns.Impostor;
using EHR.Crewmate;
using static EHR.Options;
using static EHR.Utils;
@@ -91,11 +93,28 @@ internal class Kamikaze : RoleBase
PlayerControl victim = GetPlayerById(id);
if (victim == null || !victim.IsAlive()) continue;
victim.Suicide(PlayerState.DeathReason.Kamikazed, kamikazePc);
if (GameStates.IsInTask && !ExileController.Instance)
victim.Suicide(PlayerState.DeathReason.Kamikazed, kamikazePc);
else
{
victim.SetRealKiller(kamikazePc);
var state = Main.PlayerStates[victim.PlayerId];
state.IsDead = true;
state.deathReason = PlayerState.DeathReason.Kamikazed;
Medic.IsDead(victim);
if (kamikazePc.Is(CustomRoles.Damocles))
Damocles.OnMurder(kamikazePc.PlayerId);
IncreaseAbilityUseLimitOnKill(kamikazePc);
victim.RpcExileV2();
FixedUpdatePatch.LoversSuicide(victim.PlayerId, guess: true);
}
}
kk.MarkedPlayers.Clear();
Logger.Info($"Murder {kamikazePc.GetRealName()}'s targets: {string.Join(", ", kk.MarkedPlayers.Select(x => GetPlayerById(x).GetNameWithRole()))}", "Kamikaze");
kk.MarkedPlayers.Clear();
}
}
}
+9 -2
View File
@@ -127,8 +127,15 @@ public class Occultist : RoleBase
var player = id.GetPlayer();
if (player == null) continue;
if (!player.Is(Team.Impostor))
player.RpcSetCustomRole(RevivedPlayers.GetValue() == 0 ? CustomRoles.Refugee : CustomRoles.Madmate);
switch (player.GetCustomSubRoles().FindFirst(x => x.IsConverted(), out var convertedAddon))
{
case false when !player.Is(Team.Impostor):
player.RpcSetCustomRole(RevivedPlayers.GetValue() == 0 ? CustomRoles.Refugee : CustomRoles.Madmate);
break;
case true:
player.RpcSetCustomRole(convertedAddon);
break;
}
player.RpcRevive();
player.TP(data.Position);
+1
View File
@@ -580,6 +580,7 @@ public class Main : BasePlugin
{ CustomRoles.Messenger, "#28b573" },
{ CustomRoles.Dynamo, "#ebe534" },
{ CustomRoles.AntiTP, "#fcba03" },
{ CustomRoles.Anchor, "#6B4CE4" },
{ CustomRoles.Fragile, "#debe66" },
{ CustomRoles.Allergic, "#e3bd56" },
{ CustomRoles.Introvert, "#6293e3" },