Add Captain

This commit is contained in:
Gurge44 committed 2025-09-18 14:44:45 +02:00
1 parent 87312219de
commit 76a425a3a0
7 files changed
+127 -2

No files matched your search

+1
View File
@@ -157,6 +157,7 @@ public enum CustomRoles
Benefactor,
Bodyguard,
CameraMan,
Captain,
Car,
Catcher,
Chameleon,
+1
View File
@@ -417,6 +417,7 @@ public class Main : BasePlugin
{ CustomRoles.Gardener, "#00ff00" },
{ CustomRoles.Farmer, "#FFDE59" },
{ CustomRoles.Transmitter, "#c9a11e" },
{ CustomRoles.Captain, "#53B3EF" },
{ CustomRoles.Tree, "#00ff00" },
{ CustomRoles.Inquisitor, "#7726B6" },
{ CustomRoles.Imitator, "#c99e28" },
+3
View File
@@ -235,6 +235,7 @@ internal static class CustomRolesHelper
CustomRoles.MeetingManager => CustomRoles.Crewmate,
CustomRoles.Bane => CustomRoles.Crewmate,
CustomRoles.Farmer => CustomRoles.Crewmate,
CustomRoles.Captain => CustomRoles.Crewmate,
CustomRoles.Transmitter => CustomRoles.Crewmate,
CustomRoles.Tree => CustomRoles.Crewmate,
CustomRoles.Inquisitor => CustomRoles.Crewmate,
@@ -839,6 +840,7 @@ internal static class CustomRolesHelper
public static bool UsesMeetingShapeshift(this CustomRoles role)
{
if (!Options.UseMeetingShapeshift.GetBool()) return false;
Type type = role.GetRoleClass().GetType();
return type.GetMethod("OnMeetingShapeshift")?.DeclaringType == type;
}
@@ -1745,6 +1747,7 @@ internal static class CustomRolesHelper
CustomRoles.Tracefinder => RoleOptionType.Crewmate_Miscellaneous,
CustomRoles.Tunneler => RoleOptionType.Crewmate_Miscellaneous,
CustomRoles.Analyst => RoleOptionType.Crewmate_Investigate,
CustomRoles.Captain => RoleOptionType.Crewmate_Investigate,
CustomRoles.Catcher => RoleOptionType.Crewmate_Investigate,
CustomRoles.Chameleon => RoleOptionType.Crewmate_Investigate,
CustomRoles.Clairvoyant => RoleOptionType.Crewmate_Investigate,
+1 -1
View File
@@ -162,7 +162,7 @@ public class GrabOxygenMaskSabotage : CustomSabotage
if (LastReactorFlash + 2 <= now)
{
LastReactorFlash = now;
aapc.ExceptBy(HasMask, x => x.PlayerId).Do(x => x.ReactorFlash(flashDuration: 0.1f));
aapc.ExceptBy(HasMask, x => x.PlayerId).Do(x => x.ReactorFlash(flashDuration: 0.5f));
}
if (LastNotify != now)
+5
View File
@@ -9262,6 +9262,11 @@
"Listener.FullMessageHearChance": "Full Message Hear Chance",
"Listener.FullMessage": "{0}\\n{1} whispers to {2}:\\n{3}",
"Listener.FromTo": "{0}\\n{1} whispers to {2}",
"Captain": "Captain",
"CaptainInfo": "Track Players' Movements",
"CaptainInfoLong": "(Crewmates):\\nAs the Captain, you always see who is in the same room as you. Additionally, your vote target will be tracked, and you'll get a list of rooms they've entered (in order) in the next round in the next meeting.",
"Captain.TargetInfo": "{0} entered the following rooms this round, in this order:\\n{1}",
"Captain.Suffix": "<size=80%>Players in the same room as you:\\n{0}</size>",
"Ambusher": "Ambusher",
"AmbusherInfo": "Ambush Players to Make Them Fragile",
"AmbusherInfoLong": "(Impostors):\\nAs the Ambusher, use your ability to become invisible. Follow someone for a few seconds to ambush them. If you succeed, the player gets Fragile effects. Otherwise, you become visible once your invisibility duration runs out and nothing happens.",
+115
View File
@@ -0,0 +1,115 @@
using System.Collections.Generic;
using System.Linq;
using EHR.Modules;
using EHR.Neutral;
using Hazel;
namespace EHR.Crewmate;
public class Captain : RoleBase
{
public static bool On;
public override bool IsEnable => On;
private static OptionItem CancelVote;
private string LastNotify;
private byte CaptainId;
private int Count;
private byte TargetId;
private List<SystemTypes> TargetRooms;
public override void SetupCustomOption()
{
StartSetup(655300)
.CreateVoteCancellingUseSetting(ref CancelVote);
}
public override void Init()
{
On = false;
}
public override void Add(byte playerId)
{
On = true;
LastNotify = string.Empty;
CaptainId = playerId;
Count = 0;
TargetId = byte.MaxValue;
TargetRooms = [];
}
public override bool OnVote(PlayerControl voter, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (voter == null || target == null || voter.PlayerId == target.PlayerId || Main.DontCancelVoteList.Contains(voter.PlayerId)) return false;
TargetId = target.PlayerId;
Main.DontCancelVoteList.Add(voter.PlayerId);
return true;
}
public override void OnMeetingShapeshift(PlayerControl shapeshifter, PlayerControl target)
{
OnVote(shapeshifter, target);
}
public override void OnGlobalFixedUpdate(PlayerControl pc, bool lowLoad)
{
if (lowLoad || pc.PlayerId != TargetId || !GameStates.IsInTask || ExileController.Instance || AntiBlackout.SkipTasks) return;
var room = pc.GetPlainShipRoom();
if (room != null && (TargetRooms.Count == 0 || TargetRooms[^1] != room.RoomId))
TargetRooms.Add(room.RoomId);
}
public override void OnReportDeadBody()
{
if (TargetRooms.Count == 0) return;
LateTask.New(() =>
{
string msg = string.Format(Translator.GetString("Captain.TargetInfo"), TargetId.ColoredPlayerName(), string.Join(" ➔ ", TargetRooms.ConvertAll(x => Translator.GetString(x.ToString()))));
Utils.SendMessage(msg, CaptainId, CustomRoles.Captain.ToColoredString());
TargetRooms = [];
}, 10f, "Captain Message");
}
public override void OnFixedUpdate(PlayerControl pc)
{
if (!GameStates.IsInTask || ExileController.Instance || AntiBlackout.SkipTasks || Count++ < 20) return;
Count = 0;
var room = pc.GetPlainShipRoom();
if (room == null)
{
if (string.IsNullOrEmpty(LastNotify)) return;
LastNotify = string.Empty;
Utils.SendRPC(CustomRPC.SyncRoleData, CaptainId, LastNotify);
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
return;
}
string notify = string.Join(", ", Main.AllAlivePlayerControls.Without(pc).Where(x => x.GetPlainShipRoom() == room).Select(x => x.PlayerId.ColoredPlayerName()));
if (notify == LastNotify) return;
LastNotify = notify;
Utils.SendRPC(CustomRPC.SyncRoleData, CaptainId, LastNotify);
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
}
public void ReceiveRPC(MessageReader reader)
{
LastNotify = reader.ReadString();
}
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
{
if (seer.PlayerId != CaptainId || seer.PlayerId != target.PlayerId || (seer.IsModdedClient() && !hud) || meeting) return string.Empty;
return string.Format(Translator.GetString("Captain.Suffix"), LastNotify);
}
}
+1 -1
View File
@@ -33,7 +33,7 @@ public class Psychopath : RoleBase
public override void OnFixedUpdate(PlayerControl pc)
{
if (!GameStates.IsInTask || ExileController.Instance || AntiBlackout.SkipTasks || Main.KillTimers[pc.PlayerId] > 0f || Count++ < 10) return;
if (!GameStates.IsInTask || ExileController.Instance || AntiBlackout.SkipTasks || !pc.IsAlive() || Main.KillTimers[pc.PlayerId] > 0f || Count++ < 10) return;
var pos = pc.Pos();
var killRange = NormalGameOptionsV10.KillDistances[Mathf.Clamp(Main.NormalOptions.KillDistance, 0, 2)];
PlayerControl closestPlayer = Main.AllAlivePlayerControls.Without(pc).Select(x => (pc: x, distance: Vector2.Distance(x.Pos(), pos))).Where(x => x.distance <= killRange).MinBy(x => x.distance).pc;