mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
New role Echo, Fix settings menu not opening on main menu
This commit is contained in:
1 parent
cf353162f4
commit
2769500674
10 files changed
+171
-42
No files matched your search
@@ -41,6 +41,7 @@ public enum CustomRoles
|
||||
Disperser,
|
||||
Duellist,
|
||||
Dazzler,
|
||||
Echo,
|
||||
Escapee,
|
||||
Eraser,
|
||||
EvilGuesser,
|
||||
|
||||
@@ -41,6 +41,7 @@ public enum CustomRoles
|
||||
Disperser,
|
||||
Duellist,
|
||||
Dazzler,
|
||||
Echo,
|
||||
Escapee,
|
||||
Eraser,
|
||||
EvilGuesser,
|
||||
|
||||
@@ -113,6 +113,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Dictator => CustomRoles.Crewmate,
|
||||
CustomRoles.Inhibitor => CustomRoles.Impostor,
|
||||
CustomRoles.Kidnapper => CustomRoles.Shapeshifter,
|
||||
CustomRoles.Echo => CustomRoles.Shapeshifter,
|
||||
CustomRoles.Abyssbringer => CustomRoles.Shapeshifter,
|
||||
CustomRoles.Overheat => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
|
||||
CustomRoles.Generator => CustomRoles.Shapeshifter,
|
||||
@@ -585,6 +586,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Overheat or
|
||||
CustomRoles.Underdog or
|
||||
CustomRoles.Abyssbringer or
|
||||
CustomRoles.Echo or
|
||||
CustomRoles.Inhibitor or
|
||||
CustomRoles.Kidnapper or
|
||||
CustomRoles.Generator or
|
||||
@@ -783,9 +785,13 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.TicketsStealer;
|
||||
|
||||
public static bool ForceCancelShapeshift(this CustomRoles role) => role is
|
||||
CustomRoles.Echo or
|
||||
CustomRoles.Hangman or
|
||||
CustomRoles.Generator;
|
||||
|
||||
public static bool IsNoAnimationShifter(this CustomRoles role) => role is
|
||||
CustomRoles.Echo;
|
||||
|
||||
public static bool CheckAddonConflict(CustomRoles role, PlayerControl pc) => role.IsAdditionRole() && (!Main.NeverSpawnTogetherCombos.TryGetValue(pc.GetCustomRole(), out var bannedAddonList) || !bannedAddonList.Contains(role)) && pc.GetCustomRole() is not CustomRoles.GuardianAngelEHR and not CustomRoles.God && !pc.Is(CustomRoles.Madmate) && !pc.Is(CustomRoles.GM) && role is not CustomRoles.Lovers && !pc.Is(CustomRoles.Needy) && (!pc.HasSubRole() || pc.GetCustomSubRoles().Count < Options.NoLimitAddonsNumMax.GetInt()) && (!Options.AddonCanBeSettings.TryGetValue(role, out var o) || ((o.Imp.GetBool() || !pc.GetCustomRole().IsImpostor()) && (o.Neutral.GetBool() || !pc.GetCustomRole().IsNeutral()) && (o.Crew.GetBool() || !pc.IsCrewmate()))) && role switch
|
||||
{
|
||||
CustomRoles.Energetic when !Options.UsePets.GetBool() => false,
|
||||
|
||||
+40
-39
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
@@ -776,46 +777,46 @@ public static class Options
|
||||
GroupOptions();
|
||||
GroupAddons();
|
||||
|
||||
#if DEBUG
|
||||
// Used for generating the table of roles for the README
|
||||
// This is commented out because it's not needed for the mod to function
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// var sb = new StringBuilder();
|
||||
// var grouped = Enum.GetValues<CustomRoles>().GroupBy(x =>
|
||||
// {
|
||||
// if (x is CustomRoles.GM or CustomRoles.Philantropist or CustomRoles.Konan or CustomRoles.KB_Normal or CustomRoles.Killer or CustomRoles.Potato or CustomRoles.Tasker or CustomRoles.NotAssigned or CustomRoles.LovingCrewmate or CustomRoles.LovingImpostor or CustomRoles.Convict || HnSManager.AllHnSRoles.Contains(x) || x.IsVanilla() || x.ToString().Contains("EHR")) return 4;
|
||||
// if (x.IsAdditionRole()) return 3;
|
||||
// if (x.IsImpostor() || x.IsMadmate()) return 0;
|
||||
// if (x.IsNeutral()) return 1;
|
||||
// if (x.IsCrewmate()) return 2;
|
||||
// return 4;
|
||||
// }).ToDictionary(x => x.Key, x => x.ToArray());
|
||||
// var max = grouped.Max(x => x.Value.Length);
|
||||
// for (int i = 0; i < max; i++)
|
||||
// {
|
||||
// var cr = grouped[2].ElementAtOrDefault(i);
|
||||
// var crew = Translator.GetString(cr.ToString());
|
||||
// var ir = grouped[0].ElementAtOrDefault(i);
|
||||
// var imp = Translator.GetString(ir.ToString());
|
||||
// if (ir == default) imp = string.Empty;
|
||||
// var nr = grouped[1].ElementAtOrDefault(i);
|
||||
// var neu = Translator.GetString(nr.ToString());
|
||||
// if (nr == default) neu = string.Empty;
|
||||
// var a = grouped[3].ElementAtOrDefault(i);
|
||||
// var add = Translator.GetString(a.ToString());
|
||||
// if (a == default) add = string.Empty;
|
||||
// sb.AppendLine($"| {crew, 17} | {imp, 17} | {neu, 17} | {add, 17} |");
|
||||
// }
|
||||
//
|
||||
// const string path = "./roles.txt";
|
||||
// if (!File.Exists(path)) File.Create(path).Close();
|
||||
// File.WriteAllText(path, sb.ToString());
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// Utils.ThrowException(e);
|
||||
// }
|
||||
try
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
var grouped = Enum.GetValues<CustomRoles>().GroupBy(x =>
|
||||
{
|
||||
if (x is CustomRoles.GM or CustomRoles.Philantropist or CustomRoles.Konan or CustomRoles.KB_Normal or CustomRoles.Killer or CustomRoles.Potato or CustomRoles.Tasker or CustomRoles.NotAssigned or CustomRoles.LovingCrewmate or CustomRoles.LovingImpostor or CustomRoles.Convict || HnSManager.AllHnSRoles.Contains(x) || x.IsVanilla() || x.ToString().Contains("EHR")) return 4;
|
||||
if (x.IsAdditionRole()) return 3;
|
||||
if (x.IsImpostor() || x.IsMadmate()) return 0;
|
||||
if (x.IsNeutral()) return 1;
|
||||
if (x.IsCrewmate()) return 2;
|
||||
return 4;
|
||||
}).ToDictionary(x => x.Key, x => x.ToArray());
|
||||
var max = grouped.Max(x => x.Value.Length);
|
||||
for (int i = 0; i < max; i++)
|
||||
{
|
||||
var cr = grouped[2].ElementAtOrDefault(i);
|
||||
var crew = Translator.GetString(cr.ToString());
|
||||
var ir = grouped[0].ElementAtOrDefault(i);
|
||||
var imp = Translator.GetString(ir.ToString());
|
||||
if (ir == default) imp = string.Empty;
|
||||
var nr = grouped[1].ElementAtOrDefault(i);
|
||||
var neu = Translator.GetString(nr.ToString());
|
||||
if (nr == default) neu = string.Empty;
|
||||
var a = grouped[3].ElementAtOrDefault(i);
|
||||
var add = Translator.GetString(a.ToString());
|
||||
if (a == default) add = string.Empty;
|
||||
sb.AppendLine($"| {crew,17} | {imp,17} | {neu,17} | {add,17} |");
|
||||
}
|
||||
|
||||
const string path = "./roles.txt";
|
||||
if (!File.Exists(path)) File.Create(path).Close();
|
||||
File.WriteAllText(path, sb.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.ThrowException(e);
|
||||
}
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1382,7 +1382,7 @@ internal class ChatCommands
|
||||
return;
|
||||
}
|
||||
|
||||
if ((player.IsAlive() || ExileController.Instance) && Lovers.PrivateChat.GetBool() && (ExileController.Instance || !GameStates.IsMeeting))
|
||||
if (GameStates.IsInGame && ((player.IsAlive() || ExileController.Instance) && Lovers.PrivateChat.GetBool() && (ExileController.Instance || !GameStates.IsMeeting)))
|
||||
{
|
||||
ChatManager.SendPreviousMessagesToAll();
|
||||
canceled = true;
|
||||
|
||||
@@ -283,4 +283,44 @@ internal class ModManagerLateUpdatePatch
|
||||
new(0.4f, offsetY, __instance.localCamera.nearClipPlane + 0.1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(OptionsMenuBehaviour), nameof(OptionsMenuBehaviour.Open))]
|
||||
class OptionsMenuBehaviourOpenPatch
|
||||
{
|
||||
public static bool Prefix(OptionsMenuBehaviour __instance)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DestroyableSingleton<HudManager>.InstanceExists && !DestroyableSingleton<HudManager>.Instance.SettingsButton.activeSelf)
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
__instance.ResetText();
|
||||
if (__instance.gameObject.activeSelf)
|
||||
{
|
||||
if (!__instance.Toggle) return false;
|
||||
__instance.GetComponent<TransitionOpen>().Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Minigame.Instance != null) Minigame.Instance.Close();
|
||||
__instance.OpenTabGroup(0);
|
||||
__instance.UpdateButtons();
|
||||
__instance.gameObject.SetActive(true);
|
||||
if (DestroyableSingleton<HudManager>.InstanceExists) ConsoleJoystick.SetMode_MenuAdditive();
|
||||
if (!__instance.grabbedControllerButtons)
|
||||
{
|
||||
__instance.grabbedControllerButtons = true;
|
||||
__instance.GrabControllerButtons();
|
||||
}
|
||||
|
||||
ControllerManager.Instance.OpenOverlayMenu("OptionsMenu", __instance.BackButton, __instance.DefaultButtonSelected, __instance.ControllerSelectable);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,9 @@ public static class HudSpritePatch
|
||||
|
||||
switch (player.GetCustomRole())
|
||||
{
|
||||
case CustomRoles.Echo:
|
||||
newAbilityButton = player.IsShifted() ? Kill : CustomButton.Get("Puttpuer");
|
||||
break;
|
||||
case CustomRoles.Shifter:
|
||||
newKillButton = CustomButton.Get("Swap");
|
||||
break;
|
||||
|
||||
@@ -652,7 +652,8 @@ class ShapeshiftPatch
|
||||
isSSneeded = false;
|
||||
}
|
||||
|
||||
bool forceCancel = shapeshifter.GetCustomRole().ForceCancelShapeshift();
|
||||
var role = shapeshifter.GetCustomRole();
|
||||
bool forceCancel = role.ForceCancelShapeshift();
|
||||
|
||||
if (shapeshifter.Is(CustomRoles.Camouflager) && !shapeshifting) Camouflager.Reset();
|
||||
if (Changeling.ChangedRole.TryGetValue(shapeshifter.PlayerId, out var changed) && changed && shapeshifter.GetRoleTypes() != RoleTypes.Shapeshifter)
|
||||
@@ -665,8 +666,10 @@ class ShapeshiftPatch
|
||||
bool shouldAlwaysCancel = shouldCancel && Options.DisableAllShapeshiftAnimations.GetBool();
|
||||
bool doSSwithoutAnim = isSSneeded && shouldAlwaysCancel;
|
||||
|
||||
doSSwithoutAnim |= isSSneeded && role.IsNoAnimationShifter();
|
||||
isSSneeded &= !shouldAlwaysCancel;
|
||||
forceCancel |= shouldAlwaysCancel;
|
||||
isSSneeded &= !doSSwithoutAnim;
|
||||
|
||||
// Forced rewriting in case the name cannot be corrected due to the timing of canceling the transformation being off.
|
||||
if (!shapeshifting && !shapeshifter.Is(CustomRoles.Glitch) && isSSneeded)
|
||||
@@ -674,7 +677,7 @@ class ShapeshiftPatch
|
||||
LateTask.New(() => { NotifyRoles(NoCache: true); }, 1.2f, "ShapeShiftNotify");
|
||||
}
|
||||
|
||||
if ((!shapeshifting || !isSSneeded) && !Swapster.FirstSwapTarget.ContainsKey(shapeshifter.PlayerId))
|
||||
if (!(shapeshifting && doSSwithoutAnim) && !isSSneeded && !Swapster.FirstSwapTarget.ContainsKey(shapeshifter.PlayerId))
|
||||
{
|
||||
LateTask.New(shapeshifter.RpcResetAbilityCooldown, 0.01f, log: false);
|
||||
}
|
||||
|
||||
@@ -3047,6 +3047,10 @@
|
||||
"CameraManInfo": "View Cameras anytime",
|
||||
"CameraManInfoLong": "(Crewmates):\\nAs the Camera Man, you can vent/pet to instantly teleport to the security room.",
|
||||
"TPBackWhenMoveAway": "Teleport Back When Moving Away From Cameras",
|
||||
"Echo": "Echo",
|
||||
"EchoInfo": "Make Players Die Where You Want",
|
||||
"EchoInfoLong": "(Impostors):\\nAs the Echo, you can shapeshift into a player to swap locations and skins with them. During the shapeshift, your target cannot move. When you unshift, the swap reverts and the target dies exactly where you were.\\n\\nYou cannot kill normally.",
|
||||
"EchoShapeshiftButtonText": "Control",
|
||||
"NiceHacker": "Hacker",
|
||||
"NiceHackerInfo": "Watch Admin Table from anywhere",
|
||||
"NiceHackerInfoLong": "(Hacker):\\nThis role is different for modded clients and vanilla clients.\\n\\nAs a modded client, whenever you open the map (and have ability uses left), the admin map will show up. You may be able to move while having the map open depending on settings.\\n\\nAs a vanilla client, you may enter a vent/pet your pet to get a notification saying how many people are in different rooms on the ship (essentially admin map).",
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
namespace EHR.Roles.Impostor
|
||||
{
|
||||
public class Echo : RoleBase
|
||||
{
|
||||
public static bool On;
|
||||
|
||||
private static OptionItem ShapeshiftCooldown;
|
||||
private static OptionItem ShapeshiftDuration;
|
||||
public override bool IsEnable => On;
|
||||
|
||||
public static void SetupCustomOption()
|
||||
{
|
||||
int id = 647600;
|
||||
const TabGroup tab = TabGroup.ImpostorRoles;
|
||||
const CustomRoles role = CustomRoles.Echo;
|
||||
Options.SetupRoleOptions(id++, tab, role);
|
||||
var parent = Options.CustomRoleSpawnChances[role];
|
||||
ShapeshiftCooldown = new FloatOptionItem(++id, "ShapeshiftCooldown", new(0f, 180f, 0.5f), 30f, tab)
|
||||
.SetParent(parent)
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
ShapeshiftDuration = new FloatOptionItem(++id, "ShapeshiftDuration", new(0f, 180f, 0.5f), 10f, tab)
|
||||
.SetParent(parent)
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
}
|
||||
|
||||
public override void Add(byte playerId)
|
||||
{
|
||||
On = true;
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
On = false;
|
||||
}
|
||||
|
||||
public override void SetButtonTexts(HudManager hud, byte id)
|
||||
{
|
||||
bool shifted = id.IsPlayerShifted();
|
||||
string text = !shifted ? "EchoShapeshiftButtonText" : "KillButtonText";
|
||||
hud.AbilityButton.OverrideText(Translator.GetString(text));
|
||||
}
|
||||
|
||||
public override bool CanUseKillButton(PlayerControl pc) => false;
|
||||
|
||||
public override bool OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool shapeshifting)
|
||||
{
|
||||
if (shapeshifting)
|
||||
{
|
||||
var pos = target.Pos();
|
||||
if (!shapeshifter.RpcCheckAndMurder(target, check: true) || !target.TP(shapeshifter)) return false;
|
||||
target.RpcShapeshift(shapeshifter, false);
|
||||
Main.AllPlayerSpeed[target.PlayerId] = Main.MinSpeed;
|
||||
target.MarkDirtySettings();
|
||||
shapeshifter.TP(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
target = Utils.GetPlayerById(shapeshifter.shapeshiftTargetPlayerId);
|
||||
if (target == null) return true;
|
||||
target.RpcShapeshift(target, false);
|
||||
var pos = shapeshifter.Pos();
|
||||
shapeshifter.TP(target);
|
||||
target.TP(pos);
|
||||
LateTask.New(() => target.Suicide(PlayerState.DeathReason.Kill, shapeshifter), 0.2f, "Echo Unshift Kill");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user