add Influencer (SpiritGuide 💀)

This commit is contained in:
Gurge44 committed 2026-09-29 20:25:12 +02:00
1 parent aa8391c542
commit 4333ec4a02
17 files changed
+58 -12

No files matched your search

+2
View File
@@ -145,6 +145,7 @@ public enum CustomRoles
Tracker, Tracker,
Detective, Detective,
Judge, Judge,
SpiritGuide,
// Vanilla Remakes // Vanilla Remakes
CrewmateEHR, CrewmateEHR,
@@ -155,6 +156,7 @@ public enum CustomRoles
TrackerEHR, TrackerEHR,
DetectiveEHR, DetectiveEHR,
JudgeEHR, JudgeEHR,
SpiritGuideEHR,
// Crewmates // Crewmates
+2
View File
@@ -145,6 +145,7 @@ public enum CustomRoles
Tracker, Tracker,
Detective, Detective,
Judge, Judge,
SpiritGuide,
// Vanilla Remakes // Vanilla Remakes
CrewmateEHR, CrewmateEHR,
@@ -155,6 +156,7 @@ public enum CustomRoles
TrackerEHR, TrackerEHR,
DetectiveEHR, DetectiveEHR,
JudgeEHR, JudgeEHR,
SpiritGuideEHR,
// Crewmates // Crewmates
+2
View File
@@ -487,6 +487,7 @@ public class Main : BaseUnityPlugin
{ CustomRoles.Noisemaker, "#ff4a62" }, { CustomRoles.Noisemaker, "#ff4a62" },
{ CustomRoles.Detective, "#625EEE" }, { CustomRoles.Detective, "#625EEE" },
{ CustomRoles.Judge, "#f8d85a" }, { CustomRoles.Judge, "#f8d85a" },
{ CustomRoles.SpiritGuide, "#D8E3E6" },
// Vanilla Remakes // Vanilla Remakes
{ CustomRoles.CrewmateEHR, "#8cffff" }, { CustomRoles.CrewmateEHR, "#8cffff" },
{ CustomRoles.EngineerEHR, "#FF6A00" }, { CustomRoles.EngineerEHR, "#FF6A00" },
@@ -496,6 +497,7 @@ public class Main : BaseUnityPlugin
{ CustomRoles.NoisemakerEHR, "#ff4a62" }, { CustomRoles.NoisemakerEHR, "#ff4a62" },
{ CustomRoles.DetectiveEHR, "#625EEE" }, { CustomRoles.DetectiveEHR, "#625EEE" },
{ CustomRoles.JudgeEHR, "#f8d85a" }, { CustomRoles.JudgeEHR, "#f8d85a" },
{ CustomRoles.SpiritGuideEHR, "#D8E3E6" },
// Crewmates // Crewmates
{ CustomRoles.DoubleAgent, "#ff1919" }, { CustomRoles.DoubleAgent, "#ff1919" },
{ CustomRoles.Luckey, "#b8d7a3" }, { CustomRoles.Luckey, "#b8d7a3" },
+6
View File
@@ -138,6 +138,12 @@ public static class AURoleOptions
set => Opt.SetFloat(FloatOptionNames.JudgeTaskRequirementPercentage, value); set => Opt.SetFloat(FloatOptionNames.JudgeTaskRequirementPercentage, value);
} }
public static float SpiritGuideCooldown
{
get => Opt.GetFloat(FloatOptionNames.SpiritGuideCooldownSeconds);
set => Opt.SetFloat(FloatOptionNames.SpiritGuideCooldownSeconds, value);
}
public static void SetOpt(IGameOptions opt) public static void SetOpt(IGameOptions opt)
{ {
Opt = opt; Opt = opt;
+3 -1
View File
@@ -21,7 +21,8 @@ internal static class CustomRoleSelector
[RoleTypes.Phantom] = 0, [RoleTypes.Phantom] = 0,
[RoleTypes.Viper] = 0, [RoleTypes.Viper] = 0,
[RoleTypes.Detective] = 0, [RoleTypes.Detective] = 0,
[RoleTypes.Judge] = 0 [RoleTypes.Judge] = 0,
[RoleTypes.SpiritGuide] = 0
}; };
public static readonly Dictionary<CustomGameMode, CustomRoles> GameModeRoles = new() public static readonly Dictionary<CustomGameMode, CustomRoles> GameModeRoles = new()
@@ -523,6 +524,7 @@ internal static class CustomRoleSelector
[RoleTypes.Viper] = 0, [RoleTypes.Viper] = 0,
[RoleTypes.Detective] = 0, [RoleTypes.Detective] = 0,
[RoleTypes.Judge] = 0, [RoleTypes.Judge] = 0,
[RoleTypes.SpiritGuide] = 0
}; };
foreach (CustomRoles role in RoleResult.Values) foreach (CustomRoles role in RoleResult.Values)
+5
View File
@@ -412,6 +412,7 @@ internal static class CustomRolesHelper
CustomRoles.DetectiveEHR => CustomRoles.Detective, CustomRoles.DetectiveEHR => CustomRoles.Detective,
CustomRoles.ViperEHR => CustomRoles.Viper, CustomRoles.ViperEHR => CustomRoles.Viper,
CustomRoles.JudgeEHR => CustomRoles.Judge, CustomRoles.JudgeEHR => CustomRoles.Judge,
CustomRoles.SpiritGuideEHR => CustomRoles.SpiritGuide,
// Hide And Seek // Hide And Seek
CustomRoles.Hider => CustomRoles.Crewmate, CustomRoles.Hider => CustomRoles.Crewmate,
@@ -470,6 +471,7 @@ internal static class CustomRolesHelper
CustomRoles.Detective => CustomRoles.DetectiveEHR, CustomRoles.Detective => CustomRoles.DetectiveEHR,
CustomRoles.Viper => CustomRoles.ViperEHR, CustomRoles.Viper => CustomRoles.ViperEHR,
CustomRoles.Judge => CustomRoles.JudgeEHR, CustomRoles.Judge => CustomRoles.JudgeEHR,
CustomRoles.SpiritGuide => CustomRoles.SpiritGuideEHR,
_ => role.IsImpostor() ? CustomRoles.ImpostorEHR : CustomRoles.CrewmateEHR _ => role.IsImpostor() ? CustomRoles.ImpostorEHR : CustomRoles.CrewmateEHR
}; };
} }
@@ -1379,6 +1381,8 @@ internal static class CustomRolesHelper
CustomRoles.DetectiveEHR => RoleOptionType.Crewmate_Miscellaneous, CustomRoles.DetectiveEHR => RoleOptionType.Crewmate_Miscellaneous,
CustomRoles.Judge => RoleOptionType.Crewmate_Miscellaneous, CustomRoles.Judge => RoleOptionType.Crewmate_Miscellaneous,
CustomRoles.JudgeEHR => RoleOptionType.Crewmate_Miscellaneous, CustomRoles.JudgeEHR => RoleOptionType.Crewmate_Miscellaneous,
CustomRoles.SpiritGuide => RoleOptionType.Crewmate_Miscellaneous,
CustomRoles.SpiritGuideEHR => RoleOptionType.Crewmate_Miscellaneous,
CustomRoles.Addict => RoleOptionType.Crewmate_Miscellaneous, CustomRoles.Addict => RoleOptionType.Crewmate_Miscellaneous,
CustomRoles.CameraMan => RoleOptionType.Crewmate_Miscellaneous, CustomRoles.CameraMan => RoleOptionType.Crewmate_Miscellaneous,
CustomRoles.Carrier => RoleOptionType.Crewmate_Miscellaneous, CustomRoles.Carrier => RoleOptionType.Crewmate_Miscellaneous,
@@ -1686,6 +1690,7 @@ internal static class CustomRolesHelper
CustomRoles.Impostor or CustomRoles.Impostor or
CustomRoles.Detective or CustomRoles.Detective or
CustomRoles.Judge or CustomRoles.Judge or
CustomRoles.SpiritGuide or
CustomRoles.Viper or CustomRoles.Viper or
CustomRoles.Phantom or CustomRoles.Phantom or
CustomRoles.Shapeshifter; CustomRoles.Shapeshifter;
@@ -673,6 +673,9 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
case CustomRoles.JudgeEHR: case CustomRoles.JudgeEHR:
AURoleOptions.JudgeTaskRequirementPercentage = CrewmateVanillaRoles.JudgeTaskRequirementPercentage.GetFloat(); AURoleOptions.JudgeTaskRequirementPercentage = CrewmateVanillaRoles.JudgeTaskRequirementPercentage.GetFloat();
break; break;
case CustomRoles.SpiritGuideEHR:
AURoleOptions.SpiritGuideCooldown = CrewmateVanillaRoles.SpiritGuideCooldown.GetFloat();
break;
} }
if (player.UsesJudgeAbilityAsTrigger()) if (player.UsesJudgeAbilityAsTrigger())
+1 -1
View File
@@ -42,7 +42,7 @@ public class OptionBackupData
// Since TryGetUInt is not implemented, get it separately // Since TryGetUInt is not implemented, get it separately
AllValues.Add(new UIntOptionBackupValue(UInt32OptionNames.Keywords, (uint)option.Keywords)); AllValues.Add(new UIntOptionBackupValue(UInt32OptionNames.Keywords, (uint)option.Keywords));
RoleTypes[] array = [RoleTypes.Scientist, RoleTypes.Engineer, RoleTypes.GuardianAngel, RoleTypes.Shapeshifter, RoleTypes.Noisemaker, RoleTypes.Phantom, RoleTypes.Tracker, RoleTypes.Viper, RoleTypes.Detective, RoleTypes.Judge]; RoleTypes[] array = [RoleTypes.Scientist, RoleTypes.Engineer, RoleTypes.GuardianAngel, RoleTypes.Shapeshifter, RoleTypes.Noisemaker, RoleTypes.Phantom, RoleTypes.Tracker, RoleTypes.Viper, RoleTypes.Detective, RoleTypes.Judge, RoleTypes.SpiritGuide];
foreach (RoleTypes role in array) AllValues.Add(new RoleRateBackupValue(role, option.RoleOptions.GetNumPerGame(role), option.RoleOptions.GetChancePerGame(role))); foreach (RoleTypes role in array) AllValues.Add(new RoleRateBackupValue(role, option.RoleOptions.GetNumPerGame(role), option.RoleOptions.GetChancePerGame(role)));
} }
+4 -2
View File
@@ -580,7 +580,8 @@ internal static class ChatCommands
ClientData client = x.GetClient(); ClientData client = x.GetClient();
string name = Main.AllPlayerNames.GetValueOrDefault(x.PlayerId, string.Empty); string name = Main.AllPlayerNames.GetValueOrDefault(x.PlayerId, string.Empty);
string id = string.IsNullOrEmpty(name) ? $"ID {x.PlayerId}" : $" (ID {x.PlayerId})"; string id = string.IsNullOrEmpty(name) ? $"ID {x.PlayerId}" : $" (ID {x.PlayerId})";
return $"{name}{id} - {x.FriendCode} | {client?.GetHashedPuid()} | {client?.PlatformData.Platform}"; string platform = (int?)client?.PlatformData.Platform == 112 ? "Starlight" : client?.PlatformData.Platform.ToString();
return $"{name}{id} - {x.FriendCode} | {client?.GetHashedPuid()} | {platform}";
}) + "</size>", player.PlayerId); }) + "</size>", player.PlayerId);
} }
else if (byte.TryParse(args[1], out byte playerId)) else if (byte.TryParse(args[1], out byte playerId))
@@ -590,7 +591,8 @@ internal static class ChatCommands
ClientData client = pc.GetClient(); ClientData client = pc.GetClient();
string name = Main.AllPlayerNames.GetValueOrDefault(pc.PlayerId, string.Empty); string name = Main.AllPlayerNames.GetValueOrDefault(pc.PlayerId, string.Empty);
string id = string.IsNullOrEmpty(name) ? $"ID {pc.PlayerId}" : $" (ID {pc.PlayerId})"; string id = string.IsNullOrEmpty(name) ? $"ID {pc.PlayerId}" : $" (ID {pc.PlayerId})";
Utils.SendMessage($"<b>{name}{id}:</b>\n{pc.FriendCode}\n{client?.GetHashedPuid()}\n{client?.PlatformData.Platform}", player.PlayerId); string platform = (int?)client?.PlatformData.Platform == 112 ? "Starlight" : client?.PlatformData.Platform.ToString();
Utils.SendMessage($"<b>{name}{id}:</b>\n{pc.FriendCode}\n{client?.GetHashedPuid()}\n{platform}", player.PlayerId);
} }
} }
+1
View File
@@ -1450,6 +1450,7 @@ internal static class GameEndChecker
or RoleTypes.Tracker or RoleTypes.Tracker
or RoleTypes.Detective or RoleTypes.Detective
or RoleTypes.Judge or RoleTypes.Judge
or RoleTypes.SpiritGuide
or RoleTypes.CrewmateGhost or RoleTypes.CrewmateGhost
or RoleTypes.GuardianAngel) or RoleTypes.GuardianAngel)
{ {
+5 -1
View File
@@ -842,7 +842,11 @@ internal static class BeginCrewmatePatch
CustomRoles.Judge CustomRoles.Judge
or CustomRoles.JudgeEHR or CustomRoles.JudgeEHR
or CustomRoles.Prosecutor or CustomRoles.Prosecutor
=> GetIntroSound(RoleTypes.Judge), => GetIntroSound(RoleTypes.Judge),
CustomRoles.SpiritGuide
or CustomRoles.SpiritGuideEHR
=> GetIntroSound(RoleTypes.SpiritGuide),
CustomRoles.Phantom CustomRoles.Phantom
or CustomRoles.PhantomEHR or CustomRoles.PhantomEHR
+3 -2
View File
@@ -57,7 +57,8 @@ internal static class ChangeRoleSettings
RoleTypes.Tracker, RoleTypes.Tracker,
RoleTypes.Detective, RoleTypes.Detective,
RoleTypes.Viper, RoleTypes.Viper,
RoleTypes.Judge RoleTypes.Judge,
RoleTypes.SpiritGuide
}.Do(x => Main.NormalOptions.roleOptions.SetRoleRate(x, 0, 0)); }.Do(x => Main.NormalOptions.roleOptions.SetRoleRate(x, 0, 0));
if (Main.NormalOptions.MapId > 5 && !(Main.NormalOptions.MapId == 6 && SubmergedCompatibility.Loaded) && !Main.LIMap) if (Main.NormalOptions.MapId > 5 && !(Main.NormalOptions.MapId == 6 && SubmergedCompatibility.Loaded) && !Main.LIMap)
@@ -1200,7 +1201,7 @@ internal static class StartGameHostPatch
if (Options.CurrentGameMode == CustomGameMode.Standard) if (Options.CurrentGameMode == CustomGameMode.Standard)
{ {
if (target.Is(Team.Crewmate) && roleType is not (RoleTypes.Crewmate or RoleTypes.Scientist or RoleTypes.Engineer or RoleTypes.Noisemaker or RoleTypes.Tracker or RoleTypes.Detective or RoleTypes.Judge or RoleTypes.CrewmateGhost or RoleTypes.GuardianAngel)) if (target.Is(Team.Crewmate) && roleType is not (RoleTypes.Crewmate or RoleTypes.Scientist or RoleTypes.Engineer or RoleTypes.Noisemaker or RoleTypes.Tracker or RoleTypes.Detective or RoleTypes.Judge or RoleTypes.SpiritGuide or RoleTypes.CrewmateGhost or RoleTypes.GuardianAngel))
displayRole = RoleTypes.Crewmate; displayRole = RoleTypes.Crewmate;
if (target.Is(Team.Impostor) && roleType is not (RoleTypes.Impostor or RoleTypes.Shapeshifter or RoleTypes.Phantom or RoleTypes.Viper or RoleTypes.ImpostorGhost)) if (target.Is(Team.Impostor) && roleType is not (RoleTypes.Impostor or RoleTypes.Shapeshifter or RoleTypes.Phantom or RoleTypes.Viper or RoleTypes.ImpostorGhost))
+1
View File
@@ -2633,6 +2633,7 @@ internal static class PlayerControlLocalSetRolePatch
RoleTypes.Detective => CustomRoles.DetectiveEHR, RoleTypes.Detective => CustomRoles.DetectiveEHR,
RoleTypes.Viper => CustomRoles.ViperEHR, RoleTypes.Viper => CustomRoles.ViperEHR,
RoleTypes.Judge => CustomRoles.JudgeEHR, RoleTypes.Judge => CustomRoles.JudgeEHR,
RoleTypes.SpiritGuide => CustomRoles.SpiritGuideEHR,
_ => CustomRoles.NotAssigned _ => CustomRoles.NotAssigned
}; };
+6
View File
@@ -630,10 +630,16 @@
"DetectiveEHRInfoLong": "(Crewmates):\\nAs the Detective, you can write down notes about each crime scene and interrogate suspects.\n\n<color=#ff0000><size=75%>This role currently does not work due to a basis reset issue.</size></color>", "DetectiveEHRInfoLong": "(Crewmates):\\nAs the Detective, you can write down notes about each crime scene and interrogate suspects.\n\n<color=#ff0000><size=75%>This role currently does not work due to a basis reset issue.</size></color>",
"AbilityButtonText.Detective": "Notes", "AbilityButtonText.Detective": "Notes",
"SecondaryAbilityButtonText.Detective": "Interrogate", "SecondaryAbilityButtonText.Detective": "Interrogate",
"Judge": "Judge",
"JudgeEHR": "Judge", "JudgeEHR": "Judge",
"JudgeEHRInfo": "Silence in the courtroom!", "JudgeEHRInfo": "Silence in the courtroom!",
"JudgeEHRInfoLong": "(Crewmates):\\nOverrule a meeting to eject an Impostor.\\nIf wrong, you get ejected.", "JudgeEHRInfoLong": "(Crewmates):\\nOverrule a meeting to eject an Impostor.\\nIf wrong, you get ejected.",
"JudgeTaskRequirementPercentage": "Task Unlock", "JudgeTaskRequirementPercentage": "Task Unlock",
"SpiritGuide": "Influencer",
"SpiritGuideEHR": "Influencer",
"SpiritGuideEHRInfo": "Send messages to living Crewmates.",
"SpiritGuideEHRInfoLong": "(Crewmate Ghost):\\nSend messages to living Crewmates.",
"SpiritGuideCooldown": "Message Cooldown",
"Detour": "Detour", "Detour": "Detour",
"DetourInfo": "Pass Kills Onto Nearest Player", "DetourInfo": "Pass Kills Onto Nearest Player",
"DetourInfoLong": "(Crewmate):\\nAs the Detour, all kill button related actions on you will be blocked and instead happen on the closest player to you.", "DetourInfoLong": "(Crewmate):\\nAs the Detour, all kill button related actions on you will be blocked and instead happen on the closest player to you.",
@@ -84,6 +84,7 @@ internal class Analyst : RoleBase
CustomRoles.Tracker or CustomRoles.TrackerEHR => CustomRoles.Scout.ColoredTextByRole(GetString("Tracker")), CustomRoles.Tracker or CustomRoles.TrackerEHR => CustomRoles.Scout.ColoredTextByRole(GetString("Tracker")),
CustomRoles.Detective or CustomRoles.DetectiveEHR => CustomRoles.Forensic.ColoredTextByRole(GetString("Detective")), CustomRoles.Detective or CustomRoles.DetectiveEHR => CustomRoles.Forensic.ColoredTextByRole(GetString("Detective")),
CustomRoles.Judge or CustomRoles.JudgeEHR => CustomRoles.Prosecutor.ColoredTextByRole(GetString("Judge")), CustomRoles.Judge or CustomRoles.JudgeEHR => CustomRoles.Prosecutor.ColoredTextByRole(GetString("Judge")),
CustomRoles.SpiritGuide or CustomRoles.SpiritGuideEHR => CustomRoles.SpiritGuide.ColoredTextByRole(GetString("SpiritGuide")),
_ => string.Empty _ => string.Empty
} }
: string.Empty; : string.Empty;
@@ -16,6 +16,7 @@ internal class CrewmateVanillaRoles : IVanillaSettingHolder
public static OptionItem TrackerDelay; public static OptionItem TrackerDelay;
public static OptionItem DetectiveSuspectLimit; public static OptionItem DetectiveSuspectLimit;
public static OptionItem JudgeTaskRequirementPercentage; public static OptionItem JudgeTaskRequirementPercentage;
public static OptionItem SpiritGuideCooldown;
public TabGroup Tab => TabGroup.CrewmateRoles; public TabGroup Tab => TabGroup.CrewmateRoles;
public void SetupCustomOption() public void SetupCustomOption()
@@ -79,5 +80,11 @@ internal class CrewmateVanillaRoles : IVanillaSettingHolder
JudgeTaskRequirementPercentage = new FloatOptionItem(5092, "JudgeTaskRequirementPercentage", new(0f, 100f, 25f), 50f, Tab) JudgeTaskRequirementPercentage = new FloatOptionItem(5092, "JudgeTaskRequirementPercentage", new(0f, 100f, 25f), 50f, Tab)
.SetParent(CustomRoleSpawnChances[CustomRoles.JudgeEHR]) .SetParent(CustomRoleSpawnChances[CustomRoles.JudgeEHR])
.SetValueFormat(OptionFormat.Percent); .SetValueFormat(OptionFormat.Percent);
SetupRoleOptions(5095, Tab, CustomRoles.SpiritGuideEHR);
SpiritGuideCooldown = new FloatOptionItem(5097, "SpiritGuideCooldown", new(0f, 250f, 1f), 5f, Tab)
.SetParent(CustomRoleSpawnChances[CustomRoles.SpiritGuideEHR])
.SetValueFormat(OptionFormat.Seconds);
} }
} }
+6 -5
View File
@@ -221,13 +221,14 @@ public class Jackal : RoleBase
public static void OnAnyoneDead() public static void OnAnyoneDead()
{ {
Instances.ForEach(x => for (var index = Instances.Count - 1; index >= 0; index--)
{ {
var pc = x.JackalId.GetPlayer(); Jackal instance = Instances[index];
var pc = instance.JackalId.GetPlayer();
if (pc && pc.IsAlive()) return; if (pc && pc.IsAlive()) return;
x.PromoteSidekick(); instance.PromoteSidekick();
}); }
} }
} }