mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
....
This commit is contained in:
1 parent
fcfeea2ffc
commit
ca3d3939ff
22 files changed
+350
-118
No files matched your search
@@ -137,6 +137,7 @@ public enum CustomRoles
|
||||
Bodyguard,
|
||||
CameraMan,
|
||||
Car,
|
||||
Catcher,
|
||||
CyberStar, // Celebrity
|
||||
Chameleon,
|
||||
Chef,
|
||||
|
||||
@@ -19,7 +19,7 @@ internal static class SoloKombatManager
|
||||
public static Dictionary<byte, float> PlayerDF = [];
|
||||
|
||||
private static Dictionary<byte, float> OriginalSpeed = [];
|
||||
private static Dictionary<byte, int> KBScore = [];
|
||||
public static Dictionary<byte, int> KBScore = [];
|
||||
public static int RoundTime;
|
||||
|
||||
private static readonly Dictionary<byte, (string TEXT, long TIMESTAMP)> NameNotify = [];
|
||||
@@ -219,7 +219,7 @@ internal static class SoloKombatManager
|
||||
|
||||
if (!target.SoloAlive())
|
||||
{
|
||||
OnPlyaerDead(target);
|
||||
OnPlayerDead(target);
|
||||
OnPlayerKill(killer);
|
||||
}
|
||||
|
||||
@@ -254,25 +254,21 @@ internal static class SoloKombatManager
|
||||
|
||||
private static void PlayerRandomSpwan(PlayerControl pc)
|
||||
{
|
||||
SpawnMap map;
|
||||
switch (Main.NormalOptions.MapId)
|
||||
SpawnMap map = Main.CurrentMap switch
|
||||
{
|
||||
case 0:
|
||||
map = new SkeldSpawnMap();
|
||||
map.RandomTeleport(pc);
|
||||
break;
|
||||
case 1:
|
||||
map = new MiraHQSpawnMap();
|
||||
map.RandomTeleport(pc);
|
||||
break;
|
||||
case 2:
|
||||
map = new PolusSpawnMap();
|
||||
map.RandomTeleport(pc);
|
||||
break;
|
||||
}
|
||||
MapNames.Skeld => new SkeldSpawnMap(),
|
||||
MapNames.Mira => new MiraHQSpawnMap(),
|
||||
MapNames.Polus => new PolusSpawnMap(),
|
||||
MapNames.Airship => new AirshipSpawnMap(),
|
||||
MapNames.Fungle => new FungleSpawnMap(),
|
||||
MapNames.Dleks => new DleksSpawnMap(),
|
||||
_ => null
|
||||
};
|
||||
|
||||
map?.RandomTeleport(pc);
|
||||
}
|
||||
|
||||
private static void OnPlyaerDead(PlayerControl target)
|
||||
private static void OnPlayerDead(PlayerControl target)
|
||||
{
|
||||
OriginalSpeed.Remove(target.PlayerId);
|
||||
OriginalSpeed.Add(target.PlayerId, Main.AllPlayerSpeed[target.PlayerId]);
|
||||
@@ -296,7 +292,7 @@ internal static class SoloKombatManager
|
||||
float addRate = IRandom.Instance.Next(3, 5 + GetRankOfScore(killer.PlayerId)) / 100f;
|
||||
addRate *= KB_KillBonusMultiplier.GetFloat();
|
||||
float addin;
|
||||
switch (IRandom.Instance.Next(0, 3))
|
||||
switch (IRandom.Instance.Next(0, 4))
|
||||
{
|
||||
case 0:
|
||||
addin = PlayerHPMax[killer.PlayerId] * addRate;
|
||||
@@ -313,6 +309,11 @@ internal static class SoloKombatManager
|
||||
PlayerATK[killer.PlayerId] += addin;
|
||||
AddNameNotify(killer, string.Format(Translator.GetString("KB_Buff_ATK"), addin.ToString("0.0#####")));
|
||||
break;
|
||||
case 3:
|
||||
addin = Math.Max(PlayerDF[killer.PlayerId], 1f) * addRate;
|
||||
PlayerDF[killer.PlayerId] += addin;
|
||||
AddNameNotify(killer, string.Format(Translator.GetString("KB_Buff_DF"), addin.ToString("0.0#####")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -375,6 +375,7 @@ namespace EHR
|
||||
Toilet,
|
||||
BlackHole,
|
||||
SprayedArea,
|
||||
CatcherTrap
|
||||
}
|
||||
|
||||
internal sealed class Explosion : CustomNetObject
|
||||
@@ -555,4 +556,13 @@ namespace EHR
|
||||
Main.AllAlivePlayerControls.ExceptBy(visibleList, x => x.PlayerId).Do(Hide);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class CatcherTrap : CustomNetObject
|
||||
{
|
||||
public CatcherTrap(Vector2 position, PlayerControl catcher)
|
||||
{
|
||||
CreateNetObject("<size=100%><font=\"VCR SDF\"><line-height=72%><alpha=#00>\u2588<alpha=#00>\u2588<#ccffda>\u2588<#ccffda>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<alpha=#00>\u2588<br><#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<br><#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<br><alpha=#00>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<#ccffda>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<#ccffda>\u2588<#ccffda>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br></line-height></size>", position, CustomObjectTypes.CatcherTrap);
|
||||
Main.AllAlivePlayerControls.Without(catcher).Do(Hide);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,6 +189,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Philantropist => CustomRoles.Crewmate,
|
||||
CustomRoles.Tornado => CustomRoles.Crewmate,
|
||||
CustomRoles.Druid => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer,
|
||||
CustomRoles.Catcher => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer,
|
||||
CustomRoles.Insight => CustomRoles.Crewmate,
|
||||
CustomRoles.Tunneler => CustomRoles.Crewmate,
|
||||
CustomRoles.Detour => CustomRoles.Crewmate,
|
||||
@@ -562,39 +563,37 @@ internal static class CustomRolesHelper
|
||||
|
||||
public static bool IsNE(this CustomRoles role) => role is
|
||||
CustomRoles.Jester or
|
||||
CustomRoles.Gamer or
|
||||
CustomRoles.Arsonist or
|
||||
CustomRoles.God or
|
||||
CustomRoles.Executioner or
|
||||
CustomRoles.Doomsayer or
|
||||
CustomRoles.Mario or
|
||||
CustomRoles.Terrorist or
|
||||
CustomRoles.Collector or
|
||||
CustomRoles.Vulture or
|
||||
CustomRoles.Workaholic or
|
||||
CustomRoles.Deathknight or
|
||||
CustomRoles.Innocent;
|
||||
|
||||
public static bool IsNB(this CustomRoles role) => role is
|
||||
CustomRoles.Opportunist or
|
||||
CustomRoles.Lawyer or
|
||||
CustomRoles.Amnesiac or
|
||||
CustomRoles.God or
|
||||
CustomRoles.Postman or
|
||||
CustomRoles.SchrodingersCat or
|
||||
CustomRoles.Predator or
|
||||
CustomRoles.Pursuer or
|
||||
CustomRoles.FFF or
|
||||
CustomRoles.Revolutionist or
|
||||
CustomRoles.Impartial or
|
||||
CustomRoles.Shifter or
|
||||
CustomRoles.Sunnyboy or
|
||||
CustomRoles.Maverick or
|
||||
CustomRoles.Romantic or
|
||||
CustomRoles.VengefulRomantic or
|
||||
CustomRoles.Totocalcio;
|
||||
|
||||
public static bool IsNC(this CustomRoles role) => role is
|
||||
CustomRoles.Mario or
|
||||
CustomRoles.Shifter or
|
||||
CustomRoles.Terrorist or
|
||||
CustomRoles.Revolutionist or
|
||||
CustomRoles.Impartial or
|
||||
CustomRoles.Vulture or
|
||||
CustomRoles.Phantasm or
|
||||
CustomRoles.Workaholic or
|
||||
CustomRoles.Collector or
|
||||
CustomRoles.Provocateur;
|
||||
CustomRoles.Provocateur or
|
||||
CustomRoles.SoulHunter or
|
||||
CustomRoles.Totocalcio;
|
||||
|
||||
public static bool IsCK(this CustomRoles role) => role is
|
||||
CustomRoles.SwordsMan or
|
||||
@@ -1150,8 +1149,8 @@ internal static class CustomRolesHelper
|
||||
{
|
||||
if (role.IsImpostor()) return RoleOptionType.Impostor;
|
||||
if (role.IsCrewmate()) return role.GetDYRole(load: true) == RoleTypes.Impostor ? RoleOptionType.Crewmate_ImpostorBased : RoleOptionType.Crewmate_Normal;
|
||||
if (role.IsNeutral(check: true)) return role.IsNK(check: true) ? RoleOptionType.Neutral_Killing : RoleOptionType.Neutral_NonKilling;
|
||||
return RoleOptionType.Crewmate_Normal;
|
||||
if (role.IsNeutral(check: true)) return role.IsNK(check: true) ? RoleOptionType.Neutral_Killing : role.IsNB() ? RoleOptionType.Neutral_Benign : RoleOptionType.Neutral_Evil;
|
||||
return RoleOptionType.Crewmate_Miscellaneous;
|
||||
}
|
||||
|
||||
public static Color GetRoleOptionTypeColor(this RoleOptionType type) => type switch
|
||||
@@ -1159,7 +1158,8 @@ internal static class CustomRolesHelper
|
||||
RoleOptionType.Impostor => Palette.ImpostorRed,
|
||||
RoleOptionType.Crewmate_Normal => Palette.CrewmateBlue,
|
||||
RoleOptionType.Crewmate_ImpostorBased => Utils.GetRoleColor(CustomRoles.Sheriff),
|
||||
RoleOptionType.Neutral_NonKilling => Utils.GetRoleColor(CustomRoles.Sprayer),
|
||||
RoleOptionType.Neutral_Evil => Utils.GetRoleColor(CustomRoles.Sprayer),
|
||||
RoleOptionType.Neutral_Benign => Utils.GetRoleColor(CustomRoles.TaskManager),
|
||||
RoleOptionType.Neutral_Killing => Utils.GetRoleColor(CustomRoles.Traitor),
|
||||
_ => Utils.GetRoleColor(CustomRoles.SwordsMan)
|
||||
};
|
||||
@@ -1169,7 +1169,8 @@ internal static class CustomRolesHelper
|
||||
RoleOptionType.Impostor => TabGroup.ImpostorRoles,
|
||||
RoleOptionType.Crewmate_Normal => TabGroup.CrewmateRoles,
|
||||
RoleOptionType.Crewmate_ImpostorBased => TabGroup.CrewmateRoles,
|
||||
RoleOptionType.Neutral_NonKilling => TabGroup.NeutralRoles,
|
||||
RoleOptionType.Neutral_Evil => TabGroup.NeutralRoles,
|
||||
RoleOptionType.Neutral_Benign => TabGroup.NeutralRoles,
|
||||
RoleOptionType.Neutral_Killing => TabGroup.NeutralRoles,
|
||||
_ => TabGroup.OtherRoles
|
||||
};
|
||||
@@ -1179,7 +1180,8 @@ internal static class CustomRolesHelper
|
||||
RoleOptionType.Impostor => SimpleRoleOptionType.Impostor,
|
||||
RoleOptionType.Crewmate_Normal => SimpleRoleOptionType.Crewmate,
|
||||
RoleOptionType.Crewmate_ImpostorBased => SimpleRoleOptionType.Crewmate,
|
||||
RoleOptionType.Neutral_NonKilling => SimpleRoleOptionType.NNK,
|
||||
RoleOptionType.Neutral_Evil => SimpleRoleOptionType.NNK,
|
||||
RoleOptionType.Neutral_Benign => SimpleRoleOptionType.NNK,
|
||||
RoleOptionType.Neutral_Killing => SimpleRoleOptionType.NK,
|
||||
_ => SimpleRoleOptionType.Crewmate
|
||||
};
|
||||
@@ -1219,10 +1221,18 @@ internal static class CustomRolesHelper
|
||||
#pragma warning restore IDE0079
|
||||
public enum RoleOptionType
|
||||
{
|
||||
Impostor,
|
||||
Crewmate_Normal,
|
||||
Crewmate_ImpostorBased,
|
||||
Neutral_NonKilling,
|
||||
Impostor_Killing,
|
||||
Impostor_Support,
|
||||
Impostor_Concealing,
|
||||
Impostor_Miscellaneous,
|
||||
Crewmate_Investigate,
|
||||
Crewmate_Support,
|
||||
Crewmate_Power,
|
||||
Crewmate_Killing,
|
||||
Crewmate_Chaos,
|
||||
Crewmate_Miscellaneous,
|
||||
Neutral_Evil,
|
||||
Neutral_Benign,
|
||||
Neutral_Killing
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ public static class DevManager
|
||||
new(code: "cleardress#6310", color: "#ffffff", tag: "<#00BFFF>一</color><#48D1CC>个</color><#7CFC00>热狗</color><#32CD32>uwu</color>", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "ABoringCat"),
|
||||
new(code: "rainypearl#9545", color: "#A020F0", tag: "YouTuber", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "bielModzs"),
|
||||
new(code: "kiltedbill#4145", color: "null", tag: "null", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "tsaki84"),
|
||||
new(code: "onlyfax#3941", color: "#ff0000", tag: "YouTuber", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "The Nick AG"),
|
||||
|
||||
// Sponsor
|
||||
new(code: "recentduct#6068", color: "#FF00FF", tag: "高冷男模法师", isUp: false, isDev: false, colorCmd: false, deBug: true, upName: null),
|
||||
|
||||
@@ -729,7 +729,6 @@ static class ExtendedPlayerControl
|
||||
public static bool CanUseSabotage(this PlayerControl pc)
|
||||
{
|
||||
if (!pc.IsAlive() || pc.Data.Role.Role == RoleTypes.GuardianAngel) return false;
|
||||
|
||||
return Main.PlayerStates.TryGetValue(pc.PlayerId, out var state) && state.Role.CanUseSabotage(pc);
|
||||
}
|
||||
|
||||
@@ -972,7 +971,6 @@ static class ExtendedPlayerControl
|
||||
public static bool IsNeutralKiller(this PlayerControl player) => player.Is(CustomRoles.Bloodlust) || player.GetCustomRole().IsNK();
|
||||
public static bool IsNeutralBenign(this PlayerControl player) => player.GetCustomRole().IsNB();
|
||||
public static bool IsNeutralEvil(this PlayerControl player) => player.GetCustomRole().IsNE();
|
||||
public static bool IsNeutralChaos(this PlayerControl player) => player.GetCustomRole().IsNC();
|
||||
public static bool IsSnitchTarget(this PlayerControl player) => player.Is(CustomRoles.Bloodlust) || player.GetCustomRole().IsSnitchTarget();
|
||||
public static bool IsMadmate(this PlayerControl player) => player.Is(CustomRoles.Madmate) || player.GetCustomRole().IsMadmate();
|
||||
|
||||
|
||||
@@ -541,6 +541,7 @@ public static class Options
|
||||
public static OptionItem DisableAirshipViewingDeckLightsPanel;
|
||||
public static OptionItem DisableAirshipGapRoomLightsPanel;
|
||||
public static OptionItem DisableAirshipCargoLightsPanel;
|
||||
public static OptionItem NKWinsBySabotageIfNoImpAlive;
|
||||
|
||||
// Guesser Mode
|
||||
public static OptionItem GuesserMode;
|
||||
@@ -1085,7 +1086,8 @@ public static class Options
|
||||
var categorySuffix = roleClasses.Key switch
|
||||
{
|
||||
RoleOptionType.Neutral_Killing => "NK",
|
||||
RoleOptionType.Neutral_NonKilling => "NNK",
|
||||
RoleOptionType.Neutral_Evil => "NNK",
|
||||
RoleOptionType.Neutral_Benign => "NNK",
|
||||
_ => string.Empty
|
||||
};
|
||||
new TextOptionItem(titleId, $"ROT.Basic{categorySuffix}", tab)
|
||||
@@ -1521,6 +1523,10 @@ public static class Options
|
||||
.SetParent(LightsOutSpecialSettings)
|
||||
.SetGameMode(CustomGameMode.Standard);
|
||||
|
||||
NKWinsBySabotageIfNoImpAlive = new BooleanOptionItem(22520, "NKWinsBySabotageIfNoImpAlive", false, TabGroup.GameSettings)
|
||||
.SetColor(new Color32(243, 96, 96, byte.MaxValue))
|
||||
.SetGameMode(CustomGameMode.Standard);
|
||||
|
||||
LoadingPercentage = 73;
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -1774,7 +1774,7 @@ public static class Utils
|
||||
return add;
|
||||
}
|
||||
|
||||
public static string ColoredPlayerName(this byte id) => ColorString(Main.PlayerColors.GetValueOrDefault(id, Color.white), Main.AllPlayerNames.GetValueOrDefault(id, $"Someone (ID {id})"));
|
||||
public static string ColoredPlayerName(this byte id) => ColorString(Main.PlayerColors.GetValueOrDefault(id, Color.white), Main.AllPlayerNames.GetValueOrDefault(id, GetPlayerById(id)?.GetRealName() ?? $"Someone (ID {id})"));
|
||||
|
||||
public static PlayerControl GetPlayerById(int PlayerId, bool fast = true)
|
||||
{
|
||||
@@ -2426,6 +2426,7 @@ public static class Utils
|
||||
CustomRoles.Tornado => Tornado.TornadoCooldown.GetInt(),
|
||||
CustomRoles.Sentinel => Sentinel.PatrolCooldown.GetInt(),
|
||||
CustomRoles.Druid => Druid.VentCooldown.GetInt(),
|
||||
CustomRoles.Catcher => Catcher.AbilityCooldown.GetInt(),
|
||||
CustomRoles.Sentry => EHR.Impostor.Sentry.ShowInfoCooldown.GetInt(),
|
||||
CustomRoles.ToiletMaster => ToiletMaster.AbilityCooldown.GetInt(),
|
||||
CustomRoles.Sniper => Options.DefaultShapeshiftCooldown.GetInt(),
|
||||
|
||||
@@ -55,12 +55,14 @@ class GameEndChecker
|
||||
|
||||
Main.AllPlayerControls.Do(pc => Camouflage.RpcSetSkin(pc, ForceRevert: true, RevertToDefault: true, GameEnd: true));
|
||||
|
||||
if (reason == GameOverReason.ImpostorBySabotage && (CustomRoles.Jackal.RoleExist() || CustomRoles.Sidekick.RoleExist()) && Jackal.CanWinBySabotageWhenNoImpAlive.GetBool() && !Main.AllAlivePlayerControls.Any(x => x.GetCustomRole().IsImpostorTeam()))
|
||||
if (reason == GameOverReason.ImpostorBySabotage && Options.NKWinsBySabotageIfNoImpAlive.GetBool() && !Main.AllAlivePlayerControls.Any(x => x.IsImpostor()) && Main.AllAlivePlayerControls.Count(x => x.IsNeutralKiller()) == 1)
|
||||
{
|
||||
reason = GameOverReason.ImpostorByKill;
|
||||
WinnerIds.Clear();
|
||||
ResetAndSetWinner(CustomWinner.Jackal);
|
||||
WinnerRoles.Add(CustomRoles.Jackal);
|
||||
var winner = Main.AllAlivePlayerControls.First(x => x.IsNeutralKiller());
|
||||
var winnerRole = winner.GetCustomRole();
|
||||
|
||||
ResetAndSetWinner((CustomWinner)winnerRole);
|
||||
WinnerRoles.Add(winnerRole);
|
||||
WinnerIds.Add(winner.PlayerId);
|
||||
}
|
||||
|
||||
switch (WinnerTeam)
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using BepInEx.Unity.IL2CPP.Utils.Collections;
|
||||
using EHR.Modules;
|
||||
using EHR.Patches;
|
||||
using HarmonyLib;
|
||||
using Il2CppSystem.Collections.Generic;
|
||||
@@ -603,6 +604,7 @@ public static class StringOptionPatch
|
||||
name = name.RemoveHtmlTags();
|
||||
if (Options.UsePets.GetBool() && role.PetActivatedAbility()) name += Translator.GetString("SupportsPetIndicator");
|
||||
if (!Options.UsePets.GetBool() && role.OnlySpawnsWithPets()) name += Translator.GetString("RequiresPetIndicator");
|
||||
name += GetGhostRoleTeam();
|
||||
__instance.TitleText.fontWeight = FontWeight.Black;
|
||||
__instance.TitleText.outlineColor = new(255, 255, 255, 255);
|
||||
__instance.TitleText.outlineWidth = 0.04f;
|
||||
@@ -610,6 +612,23 @@ public static class StringOptionPatch
|
||||
__instance.TitleText.color = Color.white;
|
||||
name = $"<size=3.5>{name}</size>";
|
||||
SetupHelpIcon(role, __instance);
|
||||
|
||||
string GetGhostRoleTeam()
|
||||
{
|
||||
var instance = GhostRolesManager.CreateGhostRoleInstance(role);
|
||||
if (instance == null) return string.Empty;
|
||||
var team = instance.Team;
|
||||
if ((int)team is 1 or 2 or 4) return Utils.ColorString(team.GetTeamColor(), Translator.GetString($"{team}"));
|
||||
Team[] teams = (int)team switch
|
||||
{
|
||||
3 => [Team.Impostor, Team.Neutral],
|
||||
5 => [Team.Impostor, Team.Crewmate],
|
||||
6 => [Team.Neutral, Team.Crewmate],
|
||||
7 => [Team.Impostor, Team.Neutral, Team.Crewmate],
|
||||
_ => []
|
||||
};
|
||||
return $"<size=2>{string.Join('/', teams.Select(x => Utils.ColorString(x.GetTeamColor(), Translator.GetString($"ShortTeamName.{x}"))))}</size>";
|
||||
}
|
||||
}
|
||||
|
||||
__instance.TitleText.text = name;
|
||||
@@ -917,10 +936,10 @@ public class GameSettingMenuPatch
|
||||
GameSettingsLabel.text = Translator.GetString($"Mode{Options.CurrentGameMode}").Split(':').Last().TrimStart(' ');
|
||||
if (IsRussian)
|
||||
{
|
||||
|
||||
GameSettingsLabel.transform.localScale = new(0.7f, 0.7f, 1f);
|
||||
GameSettingsLabel.transform.localPosition = new Vector3(-3.77f, 1.62f, -4);
|
||||
}
|
||||
|
||||
var GameSettingsLabelPos = GameSettingsLabel.transform.localPosition;
|
||||
|
||||
var gmCycler = Object.Instantiate(GMinus, GameSettingsLabel.transform, true);
|
||||
|
||||
+4
-30
@@ -644,42 +644,16 @@ class TaskPanelBehaviourPatch
|
||||
AllText += $"\r\n{GetString("PVP.RCO")}: {SoloKombatManager.PlayerHPReco[lpc.PlayerId]}";
|
||||
AllText += "\r\n";
|
||||
|
||||
Dictionary<byte, string> SummaryText = [];
|
||||
foreach (var id in Main.PlayerStates.Keys)
|
||||
{
|
||||
string name = Main.AllPlayerNames[id].RemoveHtmlTags().Replace("\r\n", string.Empty);
|
||||
string summary = $"{Utils.GetProgressText(id)} {Utils.ColorString(Main.PlayerColors[id], name)}";
|
||||
if (Utils.GetProgressText(id).Trim() == string.Empty) continue;
|
||||
SummaryText[id] = summary;
|
||||
}
|
||||
|
||||
List<(int, byte)> list = [];
|
||||
foreach (var id in Main.PlayerStates.Keys) list.Add((SoloKombatManager.GetRankOfScore(id), id));
|
||||
list.Sort();
|
||||
AllText = list.Where(x => SummaryText.ContainsKey(x.Item2)).Aggregate(AllText, (current, id) => current + "\r\n" + SummaryText[id.Item2]);
|
||||
|
||||
AllText = $"<size=70%>{AllText}</size>";
|
||||
AllText += Main.PlayerStates.Keys.OrderBy(SoloKombatManager.GetRankOfScore).Aggregate("<size=70%>", (s, x) => $"{s}\r\n{SoloKombatManager.GetRankOfScore(x)}. {x.ColoredPlayerName()} -{string.Format(GetString("KillCount"), SoloKombatManager.KBScore.GetValueOrDefault(x, 0))}");
|
||||
|
||||
AllText += "</size>";
|
||||
break;
|
||||
|
||||
case CustomGameMode.FFA:
|
||||
|
||||
Dictionary<byte, string> SummaryText2 = [];
|
||||
foreach (var id in Main.PlayerStates.Keys)
|
||||
{
|
||||
string name = Main.AllPlayerNames[id].RemoveHtmlTags().Replace("\r\n", string.Empty);
|
||||
string summary = $"{Utils.GetProgressText(id)} {Utils.ColorString(Main.PlayerColors[id], name)}";
|
||||
if (Utils.GetProgressText(id).Trim() == string.Empty) continue;
|
||||
SummaryText2[id] = summary;
|
||||
}
|
||||
|
||||
List<(int, byte)> list2 = [];
|
||||
foreach (var id in Main.PlayerStates.Keys) list2.Add((FFAManager.GetRankOfScore(id), id));
|
||||
list2.Sort();
|
||||
AllText = list2.Where(x => SummaryText2.ContainsKey(x.Item2)).Aggregate(AllText, (current, id) => current + "\r\n" + SummaryText2[id.Item2]);
|
||||
|
||||
AllText = $"<size=70%>{AllText}</size>";
|
||||
AllText += Main.PlayerStates.Keys.OrderBy(FFAManager.GetRankOfScore).Aggregate("<size=70%>", (s, x) => $"{s}\r\n{FFAManager.GetRankOfScore(x)}. {x.ColoredPlayerName()} -{string.Format(GetString("KillCount"), FFAManager.KillCount.GetValueOrDefault(x, 0))}");
|
||||
|
||||
AllText += "</size>";
|
||||
break;
|
||||
|
||||
case CustomGameMode.MoveAndStop:
|
||||
|
||||
@@ -376,6 +376,7 @@ public static class SabotageSystemTypeRepairDamagePatch
|
||||
}
|
||||
|
||||
if (player.Is(Team.Impostor) && !player.IsAlive() && Options.DeadImpCantSabotage.GetBool()) return false;
|
||||
if (!player.Is(Team.Impostor) && !player.IsAlive()) return false;
|
||||
bool allow = player.GetCustomRole() switch
|
||||
{
|
||||
CustomRoles.Jackal when Jackal.CanSabotage.GetBool() => true,
|
||||
|
||||
@@ -131,6 +131,7 @@ class RepairSystemPatch
|
||||
}
|
||||
|
||||
if (player.Is(Team.Impostor) && !player.IsAlive() && Options.DeadImpCantSabotage.GetBool()) return false;
|
||||
if (!player.Is(Team.Impostor) && !player.IsAlive()) return false;
|
||||
return player.GetCustomRole() switch
|
||||
{
|
||||
CustomRoles.Jackal when Jackal.CanSabotage.GetBool() => true,
|
||||
|
||||
@@ -389,8 +389,8 @@
|
||||
- Dx (PT-BR)
|
||||
- PH_Gaming (PT-BR)
|
||||
- Tomix (PT-BR)
|
||||
- aviiiv (PT-BR)
|
||||
- HyperAtill (RU)
|
||||
- ABoringCat (ZH-CN)
|
||||
|
||||
# License for the Custom Team Assigner application
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
"TeamCrewmate": "Crewmate",
|
||||
"TeamMadmate": "Madmate",
|
||||
"Neutral": "Neutral",
|
||||
"ShortTeamName.Impostor": "Imp",
|
||||
"ShortTeamName.Crewmate": "Crew",
|
||||
"ShortTeamName.Neutral": "Neut",
|
||||
"YouAreCrewmate": "<size=1.7><color=#ffffff>TEAM:</color> CREWMATES</size>",
|
||||
"YouAreImpostor": "<size=0>.</size>",
|
||||
"YouAreNeutral": "<size=1.7><color=#ffffff>TEAM:</color> NEUTRAL</size>",
|
||||
@@ -55,7 +58,8 @@
|
||||
"ROT.MadMates": "★ Madmate Roles",
|
||||
"ROT.Crewmate_Normal": "★ Non-Killing Crewmate Roles",
|
||||
"ROT.Crewmate_ImpostorBased": "★ Crewmate Roles With Kill Buttons",
|
||||
"ROT.Neutral_NonKilling": "★ Non-Killing Neutral Roles",
|
||||
"ROT.Neutral_Evil": "★ Neutral Evil Roles",
|
||||
"ROT.Neutral_Benign": "★ Neutral Benign Roles",
|
||||
"ROT.Neutral_Killing": "★ Neutral Killing Roles",
|
||||
"ROT.Vanilla": "★ Vanilla Roles",
|
||||
"ROT.Basic": "★ Basic Roles",
|
||||
@@ -1329,7 +1333,6 @@
|
||||
"ExecutionerChangeRolesAfterTargetKilled": "When Target Dies, <color=#c0c0c0>Executioner</color> becomes",
|
||||
"CanTargetNeutralBenign": "Can Target <color=#ffab1b>Neutral</color> <color=#046300>Benign</color>",
|
||||
"CanTargetNeutralEvil": "Can Target <color=#ffab1b>Neutral</color> <color=#912900>Evil</color>",
|
||||
"CanTargetNeutralChaos": "Can Target <color=#ffab1b>Neutral</color> <color=#D4AF37>Chaos</color>",
|
||||
"SidekickSheriffCanGoBerserk": "<color=#00b4eb>Recruited</color> <color=#f8cd46>Sheriff</color> Can Go Nuts",
|
||||
"LawyerCanTargetImpostor": "Can Target <color=#ff1919>Impostors</color>",
|
||||
"LawyerCanTargetNeutralKiller": "Can Target <color=#ffab1b>Neutral Killers</color>",
|
||||
@@ -1648,7 +1651,6 @@
|
||||
"CharmedCountMode.None": "Nothing",
|
||||
"CharmedCountMode.Succubus": "<color=#cf6acd>Cultist</color>",
|
||||
"CharmedCountMode.Original": "Original Team",
|
||||
"JackalCanWinBySabotageWhenNoImpAlive": "When all <color=#ff1919>Impostors</color> are dead, the <color=#00b4eb>Jackal</color> wins by sabotage instead",
|
||||
"ResetKillCooldownWhenPlayerGetKilled": "Reset kill cooldown if someone gets killed by another player",
|
||||
"ResetKillCooldownOn": "Kill Cooldown On Reset",
|
||||
"JackalCanRecruitSidekick": "Can recruit <color=#00b4eb>Sidekick</color>",
|
||||
@@ -1930,6 +1932,8 @@
|
||||
"KB_Buff_HPMax": "Gain: HP Max +{0}",
|
||||
"KB_Buff_HPReco": "Gain: Recover HP Per Second +{0}",
|
||||
"KB_Buff_ATK": "Gain: Attack +{0}",
|
||||
"KB_Buff_DF": "Gain: Defense +{0}",
|
||||
"NKWinsBySabotageIfNoImpAlive": "<#ffab1b>Neutral</color> <#ff1919>Killers</color> win by critical sabotage time limit if there are no <#ff1919>Impostors</color> alive",
|
||||
"MorticianGetNoInfo": "According to your inspection, <b>{0}</b> did not seem to have contact with anyone during their lifetime.",
|
||||
"MorticianGetInfo": "According to your inspection, the last person <b>{0}</b> came into contact with during their lifetime was <b>{1}</b>.",
|
||||
"MediumshipHelp": "<b>/ms yes</b> to agree\\n<b>/ms no</b> to disagree",
|
||||
@@ -2370,7 +2374,6 @@
|
||||
"JudgeCanTrialNeutralB": "Can trial <color=#ffab1b>Neutral</color> <color=#046300>Benign</color>",
|
||||
"JudgeCanTrialNeutralK": "Can trial <color=#ffab1b>Neutral</color> <color=#ff1919>Killing</color>",
|
||||
"JudgeCanTrialNeutralE": "Can trial <color=#ffab1b>Neutral</color> <color=#912900>Evil</color>",
|
||||
"JudgeCanTrialNeutralC": "Can trial <color=#ffab1b>Neutral</color> <color=#D4AF37>Chaos</color>",
|
||||
"JudgeCanTrialSidekick": "Can trial <color=#00b4eb>Sidekick</color>",
|
||||
"JudgeCanTrialInfected": "Can trial <color=#7B8968>Infected</color>",
|
||||
"JudgeCanTrialContagious": "Can trial <color=#2E8B57>Contagious</color>",
|
||||
@@ -4010,6 +4013,16 @@
|
||||
"SimonDontShort": "<#ffa500>Must not do instruction</color>",
|
||||
"SimonDoMode": "<#00ffa5>Mode:</color> Do instruction",
|
||||
"SimonDontMode": "<#00ffa5>Mode:</color> Do NOT do instruction",
|
||||
"Catcher": "Catcher",
|
||||
"CatcherInfo": "Catch Players' Roles",
|
||||
"CatcherInfoLong": "(Crewmates):\\nAs the Catcher, you can place traps by venting/petting. When a player steps on a trap, their role will be recorded. In the next meeting, you'll get a message of the list of roles caught in your trap.<size=80%>\\n\\nNote: You don't know who stepped on your trap and who has which role.\\nYou can place multiple traps, and you'll get a message of all roles caught in all traps.</size>",
|
||||
"Catcher.TrapPlaceDelay": "Trap Placement Delay (after venting) (if not using pets)",
|
||||
"Catcher.CatchRange": "Trap Catch Range",
|
||||
"Catcher.MinPlayersTrappedToShowInfo": "Minimum Number of Players Trapped to Show Info",
|
||||
"Catcher.TrapPlaced": "Trap placed",
|
||||
"Catcher.CaughtRoles": "Roles caught in your traps:\\n",
|
||||
"Catcher.NotEnoughCaughtRoles": "Not enough players have stepped on your traps to show the roles.",
|
||||
"Catcher.Suffix": "<#00ffa5>Placing trap in</color> {0}s",
|
||||
"Generator": "Generator",
|
||||
"GeneratorInfo": "Power up the ship",
|
||||
"GeneratorInfoLong": "(Impostors):\\nAs the Generator, you generate charges every second. You can only kill/vent/shapeshift/sabotage if you have enough charges to do so. You also lose charges while shapeshifted.",
|
||||
|
||||
@@ -36,6 +36,8 @@ namespace EHR.Crewmate
|
||||
|
||||
public static bool OnAnyoneCheckMurder(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
if (killer.IsCrewmate()) return true;
|
||||
|
||||
if (killer.PlayerId != target.PlayerId)
|
||||
{
|
||||
foreach (var bodyguard in Instances)
|
||||
|
||||
+52
-19
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace EHR.Crewmate
|
||||
{
|
||||
@@ -7,7 +8,9 @@ namespace EHR.Crewmate
|
||||
public static bool On;
|
||||
|
||||
private static OptionItem PropelDistance;
|
||||
|
||||
private int Count;
|
||||
private HashSet<byte> CurrentlyPropelling;
|
||||
private Vector2 LastPosition;
|
||||
|
||||
public static string Name => "<size=100%><font=\"VCR SDF\"><line-height=72%><br><alpha=#00>\u2588<#628d85>\u2588<#628d85>\u2588<#628d85>\u2588<#628d85>\u2588<#628d85>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br><#586874>\u2588<#586874>\u2588<#547a96>\u2588<#547a96>\u2588<#6894b6>\u2588<#6894b6>\u2588<#586874>\u2588<alpha=#00>\u2588<br><#586874>\u2588<#586874>\u2588<#586874>\u2588<#547a96>\u2588<#547a96>\u2588<#586874>\u2588<#586874>\u2588<#f5ee2e>\u2588<br><#000000>\u2588<#0d233f>\u2588<#586874>\u2588<#586874>\u2588<#586874>\u2588<#f5ee2e>\u2588<#586874>\u2588<#517a9a>\u2588<br><#000000>\u2588<#000000>\u2588<alpha=#00>\u2588<#000000>\u2588<#0d233f>\u2588<#586874>\u2588<#517a9a>\u2588<alpha=#00>\u2588<br><alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<#000000>\u2588<#000000>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<alpha=#00>\u2588<br></color></line-height></font></size>";
|
||||
@@ -31,6 +34,7 @@ namespace EHR.Crewmate
|
||||
On = true;
|
||||
LastPosition = Utils.GetPlayerById(playerId).Pos();
|
||||
Count = 0;
|
||||
CurrentlyPropelling = [];
|
||||
}
|
||||
|
||||
public override void OnFixedUpdate(PlayerControl pc)
|
||||
@@ -41,47 +45,76 @@ namespace EHR.Crewmate
|
||||
Count = 0;
|
||||
|
||||
var pos = pc.Pos();
|
||||
var direction = pos.x > LastPosition.x ? Direction.Right : pos.x < LastPosition.x ? Direction.Left : pos.y > LastPosition.y ? Direction.Up : Direction.Down;
|
||||
if (Vector2.Distance(pos, LastPosition) < 0.1f) return;
|
||||
|
||||
var direction = pos.x < LastPosition.x
|
||||
? pos.y < LastPosition.y
|
||||
? Direction.DownLeft
|
||||
: pos.y > LastPosition.y
|
||||
? Direction.UpLeft
|
||||
: Direction.Left
|
||||
: pos.x > LastPosition.x
|
||||
? pos.y < LastPosition.y
|
||||
? Direction.DownRight
|
||||
: pos.y > LastPosition.y
|
||||
? Direction.UpRight
|
||||
: Direction.Right
|
||||
: pos.y < LastPosition.y
|
||||
? Direction.Down
|
||||
: pos.y > LastPosition.y
|
||||
? Direction.Up
|
||||
: Direction.Left;
|
||||
|
||||
LastPosition = pos;
|
||||
|
||||
if (Main.AllAlivePlayerControls.Without(pc).Find(x => Vector2.Distance(pos, x.Pos()) < 1f, out var target))
|
||||
if (Main.AllAlivePlayerControls.Without(pc).Find(x => Vector2.Distance(pos, x.Pos()) < 1f, out var target) && CurrentlyPropelling.Add(target.PlayerId))
|
||||
Main.Instance.StartCoroutine(Propel(pc, target, direction));
|
||||
}
|
||||
|
||||
static System.Collections.IEnumerator Propel(PlayerControl car, PlayerControl target, Direction direction)
|
||||
System.Collections.IEnumerator Propel(PlayerControl car, PlayerControl target, Direction direction)
|
||||
{
|
||||
var oldSpeed = Main.AllPlayerSpeed[target.PlayerId];
|
||||
Main.AllPlayerSpeed[target.PlayerId] = Main.MinSpeed;
|
||||
target.MarkDirtySettings();
|
||||
|
||||
var pos = car.Pos();
|
||||
for (Vector2 newPos = target.Pos();
|
||||
Vector2.Distance(pos, newPos) < PropelDistance.GetFloat() &&
|
||||
!PhysicsHelpers.AnythingBetween(target.Collider, target.Collider.bounds.center, newPos, Constants.ShipOnlyMask, false) &&
|
||||
GameStates.IsInTask;
|
||||
newPos += direction switch
|
||||
{
|
||||
Direction.Left => Vector2.left,
|
||||
Direction.Right => Vector2.right,
|
||||
Direction.Up => Vector2.up,
|
||||
Direction.Down => Vector2.down,
|
||||
_ => Vector2.zero
|
||||
})
|
||||
var addVector = direction switch
|
||||
{
|
||||
Direction.Left => new(-0.25f, 0),
|
||||
Direction.UpLeft => new(-0.25f, 0.25f),
|
||||
Direction.Up => new(0, 0.25f),
|
||||
Direction.UpRight => new(0.25f, 0.25f),
|
||||
Direction.Right => new(0.25f, 0),
|
||||
Direction.DownRight => new(0.25f, -0.25f),
|
||||
Direction.Down => new(0, -0.25f),
|
||||
Direction.DownLeft => new(-0.25f, -0.25f),
|
||||
_ => Vector2.zero
|
||||
};
|
||||
|
||||
var distance = PropelDistance.GetFloat();
|
||||
var collider = target.Collider;
|
||||
for (var newPos = target.Pos(); Vector2.Distance(pos, newPos) < distance && !PhysicsHelpers.AnythingBetween(collider, collider.bounds.center, newPos, Constants.ShipOnlyMask, false) && GameStates.IsInTask; newPos += addVector)
|
||||
{
|
||||
target.TP(newPos, log: false);
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
yield return new WaitForSeconds(0.05f);
|
||||
}
|
||||
|
||||
Main.AllPlayerSpeed[target.PlayerId] = oldSpeed;
|
||||
target.MarkDirtySettings();
|
||||
|
||||
CurrentlyPropelling.Remove(target.PlayerId);
|
||||
}
|
||||
|
||||
enum Direction
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
UpLeft,
|
||||
Up,
|
||||
Down
|
||||
UpRight,
|
||||
Right,
|
||||
DownRight,
|
||||
Down,
|
||||
DownLeft
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using UnityEngine;
|
||||
|
||||
namespace EHR.Crewmate
|
||||
{
|
||||
public class Catcher : RoleBase
|
||||
{
|
||||
public static bool On;
|
||||
|
||||
public static OptionItem AbilityCooldown;
|
||||
public static OptionItem TrapPlaceDelay;
|
||||
public static OptionItem CatchRange;
|
||||
public static OptionItem MinPlayersTrappedToShowInfo;
|
||||
public static OptionItem AbilityUseLimit;
|
||||
public static OptionItem AbilityUseGainWithEachTaskCompleted;
|
||||
public static OptionItem AbilityChargesWhenFinishedTasks;
|
||||
private byte CatcherId;
|
||||
private Dictionary<byte, CustomRoles> CaughtRoles;
|
||||
private long DelayStartTS;
|
||||
private long LastUpdate;
|
||||
private Dictionary<Vector2, CatcherTrap> Traps;
|
||||
|
||||
public override bool IsEnable => On;
|
||||
|
||||
public static void SetupCustomOption()
|
||||
{
|
||||
int id = 648650;
|
||||
const TabGroup tab = TabGroup.CrewmateRoles;
|
||||
const CustomRoles role = CustomRoles.Catcher;
|
||||
|
||||
Options.SetupRoleOptions(id++, tab, role);
|
||||
|
||||
var parent = Options.CustomRoleSpawnChances[role];
|
||||
|
||||
AbilityCooldown = new FloatOptionItem(++id, "AbilityCooldown", new(0f, 180f, 0.5f), 10f, tab)
|
||||
.SetParent(parent)
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
TrapPlaceDelay = new FloatOptionItem(++id, "Catcher.TrapPlaceDelay", new(0f, 180f, 1f), 5f, tab)
|
||||
.SetParent(parent)
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
CatchRange = new FloatOptionItem(++id, "Catcher.CatchRange", new(0f, 10f, 0.25f), 1.5f, tab)
|
||||
.SetParent(parent)
|
||||
.SetValueFormat(OptionFormat.Multiplier);
|
||||
MinPlayersTrappedToShowInfo = new IntegerOptionItem(++id, "Catcher.MinPlayersTrappedToShowInfo", new(1, 10, 1), 2, tab)
|
||||
.SetParent(parent)
|
||||
.SetValueFormat(OptionFormat.Players);
|
||||
AbilityUseLimit = new IntegerOptionItem(++id, "AbilityUseLimit", new(0, 20, 1), 3, tab)
|
||||
.SetParent(parent)
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
AbilityUseGainWithEachTaskCompleted = new FloatOptionItem(++id, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.05f), 1f, tab)
|
||||
.SetParent(parent)
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
AbilityChargesWhenFinishedTasks = new FloatOptionItem(++id, "AbilityChargesWhenFinishedTasks", new(0f, 5f, 0.05f), 0.2f, tab)
|
||||
.SetParent(parent)
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
On = false;
|
||||
}
|
||||
|
||||
public override void Add(byte playerId)
|
||||
{
|
||||
On = true;
|
||||
CatcherId = playerId;
|
||||
Traps = [];
|
||||
DelayStartTS = 0;
|
||||
LastUpdate = Utils.TimeStamp;
|
||||
CaughtRoles = [];
|
||||
playerId.SetAbilityUseLimit(AbilityUseLimit.GetInt());
|
||||
}
|
||||
|
||||
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
|
||||
{
|
||||
if (Options.UsePets.GetBool()) return;
|
||||
AURoleOptions.EngineerCooldown = AbilityCooldown.GetFloat();
|
||||
AURoleOptions.EngineerInVentMaxTime = 1f;
|
||||
}
|
||||
|
||||
void PlaceTrap(PlayerControl pc)
|
||||
{
|
||||
if (pc.GetAbilityUseLimit() < 1) return;
|
||||
pc.RpcRemoveAbilityUse();
|
||||
|
||||
var pos = pc.Pos();
|
||||
Traps[pos] = new(pos, pc);
|
||||
|
||||
pc.Notify(Translator.GetString("Catcher.TrapPlaced"));
|
||||
}
|
||||
|
||||
public override void OnPet(PlayerControl pc)
|
||||
{
|
||||
PlaceTrap(pc);
|
||||
}
|
||||
|
||||
public override void OnEnterVent(PlayerControl pc, Vent vent)
|
||||
{
|
||||
DelayStartTS = Utils.TimeStamp + 1;
|
||||
SendRPC();
|
||||
}
|
||||
|
||||
public override void OnFixedUpdate(PlayerControl pc)
|
||||
{
|
||||
if (!pc.IsAlive() || !GameStates.IsInTask || ExileController.Instance || Options.UsePets.GetBool() || DelayStartTS == 0) return;
|
||||
|
||||
long now = Utils.TimeStamp;
|
||||
if (now == LastUpdate) return;
|
||||
LastUpdate = now;
|
||||
|
||||
if (DelayStartTS + TrapPlaceDelay.GetInt() <= now)
|
||||
{
|
||||
PlaceTrap(pc);
|
||||
DelayStartTS = 0;
|
||||
SendRPC();
|
||||
}
|
||||
|
||||
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
|
||||
pc.RpcResetAbilityCooldown();
|
||||
}
|
||||
|
||||
public override void OnCheckPlayerPosition(PlayerControl pc)
|
||||
{
|
||||
if (CaughtRoles.ContainsKey(pc.PlayerId)) return;
|
||||
|
||||
var pos = pc.Pos();
|
||||
var range = CatchRange.GetFloat();
|
||||
if (Traps.Keys.Any(x => Vector2.Distance(x, pos) <= range))
|
||||
CaughtRoles[pc.PlayerId] = pc.GetCustomRole();
|
||||
}
|
||||
|
||||
public override void OnReportDeadBody()
|
||||
{
|
||||
LateTask.New(() =>
|
||||
{
|
||||
if (CaughtRoles.Count >= MinPlayersTrappedToShowInfo.GetInt())
|
||||
{
|
||||
var roles = string.Join(", ", CaughtRoles.Values.Select(x => x.ToColoredString()));
|
||||
Utils.SendMessage("\n", CatcherId, Translator.GetString("Catcher.CaughtRoles") + roles);
|
||||
}
|
||||
else Utils.SendMessage("\n", CatcherId, Translator.GetString("Catcher.NotEnoughCaughtRoles"));
|
||||
|
||||
CaughtRoles = [];
|
||||
}, 10f, "Send Catcher Caught Roles");
|
||||
}
|
||||
|
||||
void SendRPC() => Utils.SendRPC(CustomRPC.SyncRoleData, CatcherId, DelayStartTS);
|
||||
public void ReceiveRPC(Hazel.MessageReader reader) => DelayStartTS = long.Parse(reader.ReadString());
|
||||
|
||||
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool isHUD = false, bool isMeeting = false)
|
||||
{
|
||||
if (seer.PlayerId != target.PlayerId || seer.PlayerId != CatcherId || isMeeting || (seer.IsModClient() && !isHUD) || DelayStartTS == 0 || Options.UsePets.GetBool()) return string.Empty;
|
||||
return string.Format(Translator.GetString("Catcher.Suffix"), TrapPlaceDelay.GetInt() - (Utils.TimeStamp - DelayStartTS));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ public class Judge : RoleBase
|
||||
private static OptionItem CanTrialNeutralB;
|
||||
private static OptionItem CanTrialNeutralK;
|
||||
private static OptionItem CanTrialNeutralE;
|
||||
private static OptionItem CanTrialNeutralC;
|
||||
public static OptionItem JudgeAbilityUseGainWithEachTaskCompleted;
|
||||
public static OptionItem AbilityChargesWhenFinishedTasks;
|
||||
|
||||
@@ -46,7 +45,6 @@ public class Judge : RoleBase
|
||||
CanTrialCrewKilling = new BooleanOptionItem(Id + 13, "JudgeCanTrialnCrewKilling", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]);
|
||||
CanTrialNeutralB = new BooleanOptionItem(Id + 14, "JudgeCanTrialNeutralB", false, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]);
|
||||
CanTrialNeutralE = new BooleanOptionItem(Id + 17, "JudgeCanTrialNeutralE", false, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]);
|
||||
CanTrialNeutralC = new BooleanOptionItem(Id + 18, "JudgeCanTrialNeutralC", false, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]);
|
||||
CanTrialNeutralK = new BooleanOptionItem(Id + 15, "JudgeCanTrialNeutralK", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]);
|
||||
TryHideMsg = new BooleanOptionItem(Id + 11, "JudgeTryHideMsg", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]).SetColor(Color.green);
|
||||
JudgeAbilityUseGainWithEachTaskCompleted = new FloatOptionItem(Id + 19, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.05f), 0.3f, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]).SetValueFormat(OptionFormat.Times);
|
||||
@@ -152,8 +150,7 @@ public class Judge : RoleBase
|
||||
if (targetRole.IsCK() && CanTrialCrewKilling.GetBool()) judgeSuicide = false;
|
||||
else if (targetRole.IsNB() && CanTrialNeutralB.GetBool()) judgeSuicide = false;
|
||||
else if (targetRole.IsNE() && CanTrialNeutralE.GetBool()) judgeSuicide = false;
|
||||
else if (targetRole.IsNC() && CanTrialNeutralC.GetBool()) judgeSuicide = false;
|
||||
else if (targetRole.IsNonNK() && !CanTrialNeutralB.GetBool() && !CanTrialNeutralE.GetBool() && !CanTrialNeutralC.GetBool() && !targetRole.IsNB() && !targetRole.IsNC() && !targetRole.IsNE() && CanTrialNeutralK.GetBool()) judgeSuicide = false;
|
||||
else if (targetRole.IsNonNK() && !CanTrialNeutralB.GetBool() && !CanTrialNeutralE.GetBool() && !targetRole.IsNB() && !targetRole.IsNE() && CanTrialNeutralK.GetBool()) judgeSuicide = false;
|
||||
else if (targetRole.IsImpostor()) judgeSuicide = false;
|
||||
else if (targetRole.IsMadmate() && CanTrialMadmate.GetBool()) judgeSuicide = false;
|
||||
else if (targetRole is CustomRoles.Necromancer or CustomRoles.Deathknight && CanTrialNeutralK.GetBool()) judgeSuicide = false;
|
||||
|
||||
@@ -16,7 +16,6 @@ public class Executioner : RoleBase
|
||||
private static OptionItem CanTargetNeutralKiller;
|
||||
private static OptionItem CanTargetNeutralBenign;
|
||||
private static OptionItem CanTargetNeutralEvil;
|
||||
private static OptionItem CanTargetNeutralChaos;
|
||||
public static OptionItem KnowTargetRole;
|
||||
public static OptionItem CanGuessTarget;
|
||||
public static OptionItem ChangeRolesAfterTargetKilled;
|
||||
@@ -46,7 +45,6 @@ public class Executioner : RoleBase
|
||||
CanTargetNeutralKiller = new BooleanOptionItem(Id + 12, "ExecutionerCanTargetNeutralKiller", false, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Executioner]);
|
||||
CanTargetNeutralBenign = new BooleanOptionItem(Id + 14, "CanTargetNeutralBenign", false, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Executioner]);
|
||||
CanTargetNeutralEvil = new BooleanOptionItem(Id + 15, "CanTargetNeutralEvil", false, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Executioner]);
|
||||
CanTargetNeutralChaos = new BooleanOptionItem(Id + 16, "CanTargetNeutralChaos", false, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Executioner]);
|
||||
KnowTargetRole = new BooleanOptionItem(Id + 13, "KnowTargetRole", false, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Executioner]);
|
||||
CanGuessTarget = new BooleanOptionItem(Id + 17, "CanGuessTarget", false, TabGroup.NeutralRoles).SetParent(KnowTargetRole);
|
||||
ChangeRolesAfterTargetKilled = new StringOptionItem(Id + 11, "ExecutionerChangeRolesAfterTargetKilled", CRoleChangeRoles.Select(x => x.ToColoredString()).ToArray(), 1, TabGroup.NeutralRoles, noTranslation: true).SetParent(CustomRoleSpawnChances[CustomRoles.Executioner]);
|
||||
@@ -67,8 +65,8 @@ public class Executioner : RoleBase
|
||||
try
|
||||
{
|
||||
List<PlayerControl> targetList = [];
|
||||
targetList.AddRange(from target in Main.AllPlayerControls where playerId != target.PlayerId where CanTargetImpostor.GetBool() || !target.Is(CustomRoleTypes.Impostor) where CanTargetNeutralKiller.GetBool() || !target.IsNeutralKiller() where CanTargetNeutralBenign.GetBool() || !target.IsNeutralBenign() where CanTargetNeutralEvil.GetBool() || !target.IsNeutralEvil() where CanTargetNeutralChaos.GetBool() || !target.IsNeutralChaos() where target.GetCustomRole() is not (CustomRoles.GM or CustomRoles.SuperStar) where Main.LoversPlayers.TrueForAll(x => x.PlayerId != playerId) select target);
|
||||
if (!CanTargetNeutralBenign.GetBool() && !CanTargetNeutralChaos.GetBool() && !CanTargetNeutralEvil.GetBool() && !CanTargetNeutralKiller.GetBool()) targetList.RemoveAll(x => x.GetCustomRole().IsNeutral() || x.Is(CustomRoles.Bloodlust));
|
||||
targetList.AddRange(from target in Main.AllPlayerControls where playerId != target.PlayerId where CanTargetImpostor.GetBool() || !target.Is(CustomRoleTypes.Impostor) where CanTargetNeutralKiller.GetBool() || !target.IsNeutralKiller() where CanTargetNeutralBenign.GetBool() || !target.IsNeutralBenign() where CanTargetNeutralEvil.GetBool() || !target.IsNeutralEvil() where target.GetCustomRole() is not (CustomRoles.GM or CustomRoles.SuperStar) where Main.LoversPlayers.TrueForAll(x => x.PlayerId != playerId) select target);
|
||||
if (!CanTargetNeutralBenign.GetBool() && !CanTargetNeutralEvil.GetBool() && !CanTargetNeutralKiller.GetBool()) targetList.RemoveAll(x => x.GetCustomRole().IsNeutral() || x.Is(CustomRoles.Bloodlust));
|
||||
|
||||
if (targetList.Count == 0)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,6 @@ public class Jackal : RoleBase
|
||||
private static OptionItem KillCooldown;
|
||||
private static OptionItem CanVent;
|
||||
public static OptionItem CanSabotage;
|
||||
public static OptionItem CanWinBySabotageWhenNoImpAlive;
|
||||
public static OptionItem HasImpostorVision;
|
||||
public static OptionItem ResetKillCooldownWhenSbGetKilled;
|
||||
private static OptionItem ResetKillCooldownOn;
|
||||
@@ -42,8 +41,6 @@ public class Jackal : RoleBase
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Jackal]);
|
||||
CanSabotage = new BooleanOptionItem(Id + 4, "CanSabotage", true, TabGroup.NeutralRoles)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Jackal]);
|
||||
CanWinBySabotageWhenNoImpAlive = new BooleanOptionItem(Id + 5, "JackalCanWinBySabotageWhenNoImpAlive", true, TabGroup.NeutralRoles)
|
||||
.SetParent(CanSabotage);
|
||||
HasImpostorVision = new BooleanOptionItem(Id + 6, "ImpostorVision", true, TabGroup.NeutralRoles)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Jackal]);
|
||||
ResetKillCooldownWhenSbGetKilled = new BooleanOptionItem(Id + 7, "ResetKillCooldownWhenPlayerGetKilled", false, TabGroup.NeutralRoles)
|
||||
|
||||
@@ -345,6 +345,7 @@ public class Main : BasePlugin
|
||||
{ CustomRoles.Detour, "#ffd35c" },
|
||||
{ CustomRoles.Gaulois, "#42d1f5" },
|
||||
{ CustomRoles.Druid, "#ffb694" },
|
||||
{ CustomRoles.Catcher, "#aaf2cf" },
|
||||
{ CustomRoles.Autocrat, "#e2ed64" },
|
||||
{ CustomRoles.LovingCrewmate, "#ff9ace" },
|
||||
{ CustomRoles.LovingImpostor, "#ff9ace" },
|
||||
@@ -727,6 +728,13 @@ public enum Team
|
||||
Impostor = 1,
|
||||
Neutral = 2,
|
||||
Crewmate = 4
|
||||
|
||||
/*
|
||||
* Impostor | Neutral = 3
|
||||
* Impostor | Crewmate = 5
|
||||
* Neutral | Crewmate = 6
|
||||
* Impostor | Neutral | Crewmate = 7
|
||||
*/
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0079 // Remove unnecessary suppression
|
||||
|
||||
Reference in new issue
Block a user