Add Dynamo, Add Overheat, fixed some bugs

This commit is contained in:
Gurge44 committed 2024-04-23 21:44:03 +02:00
1 parent 62457c87fd
commit 6ba06c0199
22 files changed
+334 -93

No files matched your search

+2
View File
@@ -69,6 +69,7 @@ public enum CustomRoles
Assassin, // Ninja
Nuker,
Nullifier,
Overheat,
Parasite,
Penguin,
Puppeteer,
@@ -344,6 +345,7 @@ public enum CustomRoles
DeadlyQuota,
Disco,
Diseased,
Dynamo,
Unreportable, // Disregarded
DoubleShot,
Egoist,
+8 -2
View File
@@ -86,22 +86,28 @@ namespace EHR
if (allPlayers.Count == 0) return;
int neutralNum = IRandom.Instance.Next(MinNeutrals.GetInt(), MaxNeutrals.GetInt() + 1);
int assignedCount = 0;
bool stop = false;
foreach (var role in HideAndSeekRoles)
{
int mode = role.Key.GetMode();
if (IRandom.Instance.Next(100) >= mode) continue;
for (int i = 0; i < role.Value; i++)
{
var pc = allPlayers[0];
result[pc] = role.Key;
allPlayers.Remove(pc);
assignedCount++;
if (allPlayers.Count == 0)
if (allPlayers.Count == 0 || assignedCount >= neutralNum)
{
stop = true;
break;
}
if (IRandom.Instance.Next(100) >= role.Key.GetMode()) break;
if (IRandom.Instance.Next(100) >= mode) break;
}
if (stop) break;
+2
View File
@@ -96,6 +96,7 @@ internal static class CustomRolesHelper
CustomRoles.Dictator => CustomRoles.Crewmate,
CustomRoles.Inhibitor => CustomRoles.Impostor,
CustomRoles.Kidnapper => CustomRoles.Shapeshifter,
CustomRoles.Overheat => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Generator => CustomRoles.Shapeshifter,
CustomRoles.Blackmailer => CustomRoles.Impostor,
CustomRoles.Commander => CustomRoles.Shapeshifter,
@@ -539,6 +540,7 @@ internal static class CustomRolesHelper
CustomRoles.Miner or
CustomRoles.Escapee or
CustomRoles.SerialKiller or
CustomRoles.Overheat or
CustomRoles.Underdog or
CustomRoles.Inhibitor or
CustomRoles.Kidnapper or
-8
View File
@@ -998,14 +998,6 @@ static class ExtendedPlayerControl
public static bool Is(this PlayerControl target, CustomRoles role) =>
role > CustomRoles.NotAssigned ? target.GetCustomSubRoles().Contains(role) : target.GetCustomRole() == role;
/// <summary>
/// Determines whether the player has the specified role class. Doesn't work with subroles.
/// </summary>
/// <param name="target">The player to check</param>
/// <param name="role">The type of role class</param>
/// <returns>True, if the player has the specified role class, otherwise, false. This method returns false if the player to check doesn't have a PlayerState assigned.</returns>
public static bool Is(this PlayerControl target, RoleBase role) => Main.PlayerStates.TryGetValue(target.PlayerId, out var state) && state.Role.GetType() == role.GetType();
public static bool Is(this PlayerControl target, CustomRoleTypes type) => target.GetCustomRoleTypes() == type;
public static bool Is(this PlayerControl target, RoleTypes type) => (target.Is(CustomRoles.Bloodlust) && type == RoleTypes.Impostor) || target.GetCustomRole().GetRoleTypes() == type;
public static bool Is(this PlayerControl target, CountTypes type) => target.GetCountTypes() == type;
+2 -2
View File
@@ -42,8 +42,8 @@ public static class NameNotifyManager
public static bool GetNameNotify(PlayerControl player, out string name)
{
name = string.Empty;
if (!Notice.ContainsKey(player.PlayerId)) return false;
name = Notice[player.PlayerId].TEXT;
if (!Notice.TryGetValue(player.PlayerId, out (string TEXT, long TIMESTAMP) value)) return false;
name = value.TEXT;
return true;
}
+4 -1
View File
@@ -1862,6 +1862,9 @@ public static class Utils
case CustomRoles.Penguin:
SelfSuffix.Append(Penguin.GetSuffix(seer));
break;
case CustomRoles.Overheat:
SelfSuffix.Append(Overheat.GetSuffix(seer));
break;
case CustomRoles.BountyHunter:
SelfSuffix.Append(BountyHunter.GetTargetText(seer, false));
SelfSuffix.Append(BountyHunter.GetTargetArrow(seer));
@@ -2537,7 +2540,7 @@ public static class Utils
switch (target.GetCustomRole())
{
case CustomRoles.Terrorist:
Logger.Info(target?.Data?.PlayerName + "はTerroristだった", "MurderPlayer");
Logger.Info(target?.Data?.PlayerName + "Terrorist died", "MurderPlayer");
CheckTerroristWin(target?.Data);
break;
case CustomRoles.Executioner:
+20 -16
View File
@@ -14,10 +14,10 @@ namespace EHR;
internal class ControllerManagerUpdatePatch
{
private static readonly (int, int)[] Resolutions = [(480, 270), (640, 360), (800, 450), (1280, 720), (1600, 900), (1920, 1080)];
private static int resolutionIndex;
private static int ResolutionIndex;
public static List<string> addDes = [];
public static int addonIndex = -1;
private static List<string> AddDes = [];
private static int AddonIndex = -1;
public static void Postfix( /*ControllerManager __instance*/)
{
@@ -30,11 +30,16 @@ internal class ControllerManagerUpdatePatch
for (var i = 0; i < 9; i++)
{
if (ORGetKeysDown(KeyCode.Alpha1 + i, KeyCode.Keypad1 + i) && OptionShower.Pages.Count >= i + 1)
if (OrGetKeysDown(KeyCode.Alpha1 + i, KeyCode.Keypad1 + i) && OptionShower.Pages.Count >= i + 1)
OptionShower.CurrentPage = i;
}
}
if (GetKeysDown(KeyCode.LeftShift, KeyCode.LeftControl, KeyCode.X) && Main.CurrentMap == MapNames.Airship)
{
ExileController.Instance?.ReEnableGameplay();
}
if (GetKeysDown(KeyCode.LeftAlt, KeyCode.Return))
{
_ = new LateTask(SetResolutionManager.Postfix, 0.01f, "Fix Button Position");
@@ -66,13 +71,13 @@ internal class ControllerManagerUpdatePatch
var lp = PlayerControl.LocalPlayer;
if (Main.PlayerStates[lp.PlayerId].SubRoles.Count == 0) return;
addDes = [];
AddDes = [];
foreach (var subRole in Main.PlayerStates[lp.PlayerId].SubRoles.Where(x => x is not CustomRoles.Charmed))
addDes.Add(GetString($"{subRole}") + Utils.GetRoleMode(subRole) + GetString($"{subRole}InfoLong"));
AddDes.Add(GetString($"{subRole}") + Utils.GetRoleMode(subRole) + GetString($"{subRole}InfoLong"));
addonIndex++;
if (addonIndex >= addDes.Count) addonIndex = 0;
HudManager.Instance.ShowPopUp(addDes[addonIndex]);
AddonIndex++;
if (AddonIndex >= AddDes.Count) AddonIndex = 0;
HudManager.Instance.ShowPopUp(AddDes[AddonIndex]);
}
catch (Exception ex)
{
@@ -83,9 +88,9 @@ internal class ControllerManagerUpdatePatch
if (Input.GetKeyDown(KeyCode.F11))
{
resolutionIndex++;
if (resolutionIndex >= Resolutions.Length) resolutionIndex = 0;
ResolutionManager.SetResolution(Resolutions[resolutionIndex].Item1, Resolutions[resolutionIndex].Item2, false);
ResolutionIndex++;
if (ResolutionIndex >= Resolutions.Length) ResolutionIndex = 0;
ResolutionManager.SetResolution(Resolutions[ResolutionIndex].Item1, Resolutions[ResolutionIndex].Item2, false);
SetResolutionManager.Postfix();
}
@@ -135,13 +140,12 @@ internal class ControllerManagerUpdatePatch
if (Input.GetKeyDown(KeyCode.LeftShift) && GameStates.IsCountDown && !HudManager.Instance.Chat.IsOpenOrOpening)
{
Logger.Info("倒计时修改为0", "KeyCommand");
Logger.Info("Countdown timer set to 0", "KeyCommand");
GameStartManager.Instance.countDownTimer = 0;
}
if (Input.GetKeyDown(KeyCode.C) && GameStates.IsCountDown)
{
Logger.Info("重置倒计时", "KeyCommand");
GameStartManager.Instance.ResetStartState();
Logger.SendInGame(GetString("CancelStartCountDown"));
}
@@ -286,7 +290,7 @@ internal class ControllerManagerUpdatePatch
return false;
}
private static bool ORGetKeysDown(params KeyCode[] keys) => keys.Any(Input.GetKeyDown);
private static bool OrGetKeysDown(params KeyCode[] keys) => keys.Any(Input.GetKeyDown);
}
[HarmonyPatch(typeof(ConsoleJoystick), nameof(ConsoleJoystick.HandleHUD))]
@@ -307,7 +311,7 @@ internal class KeyboardJoystickHandleHUDPatch
}
}
internal class HandleHUDPatch
internal static class HandleHUDPatch
{
public static void Postfix(Player player)
{
+3 -2
View File
@@ -396,12 +396,13 @@ class HudManagerPatch
CustomRoles.Mafioso => Mafioso.GetHUDText(player),
CustomRoles.Druid => Druid.GetHUDText(player),
CustomRoles.Rabbit => Rabbit.GetSuffix(player),
CustomRoles.Predator => Predator.GetSuffixAndHudText(player, hud: true),
CustomRoles.Warlock => Warlock.GetSuffixAndHudText(player, hud: true),
CustomRoles.Commander => Commander.GetSuffixText(player, player, hud: true),
CustomRoles.Librarian => Librarian.GetSelfSuffixAndHudText(player.PlayerId),
CustomRoles.PlagueDoctor => PlagueDoctor.GetLowerTextOthers(player, isForHud: true),
CustomRoles.Stealth => Stealth.GetSuffix(player, isHUD: true),
CustomRoles.Overheat => Overheat.GetSuffix(player),
CustomRoles.Predator => Predator.GetSuffixAndHudText(player, hud: true),
CustomRoles.PlagueDoctor => PlagueDoctor.GetLowerTextOthers(player, isForHud: true),
CustomRoles.Hookshot => Hookshot.SuffixText(player.PlayerId),
CustomRoles.Simon => Simon.GetSuffix(player, player, hud: true),
CustomRoles.Chemist => Chemist.GetSuffix(player, player, hud: true),
@@ -544,6 +544,7 @@ internal class SelectRolesPatch
Stressed.Add();
Asthmatic.Add();
Circumvent.Add();
Dynamo.Add();
_ = new LateTask(CustomTeamManager.InitializeCustomTeamPlayers, 7f, log: false);
+11 -7
View File
@@ -1167,15 +1167,19 @@ class FixedUpdatePatch
Asthmatic.OnCheckPlayerPosition(player);
}
if (!lowLoad && Main.PlayerStates.TryGetValue(playerId, out var playerState) && GameStates.IsInTask && player.IsAlive())
if (Main.PlayerStates.TryGetValue(playerId, out var playerState) && GameStates.IsInTask && player.IsAlive())
{
var subRoles = playerState.SubRoles;
if (subRoles.Contains(CustomRoles.Damocles)) Damocles.Update(player);
if (subRoles.Contains(CustomRoles.Stressed)) Stressed.Update(player);
if (subRoles.Contains(CustomRoles.Asthmatic)) Asthmatic.OnFixedUpdate();
if (subRoles.Contains(CustomRoles.Disco)) Disco.OnFixedUpdate(player);
if (subRoles.Contains(CustomRoles.Clumsy)) Clumsy.OnFixedUpdate(player);
if (subRoles.Contains(CustomRoles.Sonar)) Sonar.OnFixedUpdate(player);
if (subRoles.Contains(CustomRoles.Dynamo)) Dynamo.OnFixedUpdate(player);
if (!lowLoad)
{
if (subRoles.Contains(CustomRoles.Damocles)) Damocles.Update(player);
if (subRoles.Contains(CustomRoles.Stressed)) Stressed.Update(player);
if (subRoles.Contains(CustomRoles.Asthmatic)) Asthmatic.OnFixedUpdate();
if (subRoles.Contains(CustomRoles.Disco)) Disco.OnFixedUpdate(player);
if (subRoles.Contains(CustomRoles.Clumsy)) Clumsy.OnFixedUpdate(player);
if (subRoles.Contains(CustomRoles.Sonar)) Sonar.OnFixedUpdate(player);
}
}
if (GhostRolesManager.AssignedGhostRoles.TryGetValue(player.PlayerId, out var ghostRole))
+13
View File
@@ -2645,12 +2645,25 @@
"Sentry.Notify.Shapeshifted": "{0} shapeshifted into {1} in your monitored room",
"Sentry.Notify.Vented": "{0} vented in your monitored room",
"Sentry.Notify.InvalidRoom": "You are not in a room",
"Dynamo": "Dynamo",
"DynamoInfo": "You get faster by walking",
"DynamoInfoLong": "(Add-ons):\\nAs the Dynamo, you get faster by walking. The longer you walk, the faster you get. Stopping will reset your speed.",
"Prefix.Dynamo": "Dynamo",
"Samurai": "Samurai",
"SamuraiInfo": "Kill Players in Unique Ways",
"SamuraiInfoLong": "(Neutrals):\\nAs the Samurai, you can do delayed kills and normal kills. What decides? Well, if you click your kill button on someone (the kill won't occur immediately) and you stay near them for a few seconds (like an arsonist douse), you get a lower kill cooldown and the kill will be delayed. If you fail to stay near them, you do a normal kill, lunge included.",
"Samurai.NearbyDuration": "Time to Stay Near Target",
"Samurai.SuccessKCD": "Kill Cooldown for Delayed Kills",
"Samurai.KillDelay": "Kill Delay",
"Overheat": "Overheat",
"OverheatInfo": "Hot = Low Kill Cooldown",
"OverheatInfoLong": "(Impostors):\\nAs the Overheat, your kill cooldown is based on your temperature. The more you wat, the hotter you get, and the lower your kill cooldown becomes, but your chance of overheating is also increasing. You can shapeshift or pet your pet to cool down to reset your temperature. This freezes you in place for a few seconds.",
"Overheat.Suffix": "<size=80%>Temperature: {0}</size>",
"Overheat.ChanceIncrease": "Temperature Increase Rate",
"Overheat.ChanceIncreaseFrequency": "Temperature Increase Frequency",
"Overheat.RollChanceFrequency": "Frequency of Rolling for Overheat",
"Overheat.CoolDownTime": "Cool Down Time",
"Overheat.KCDDecreasePerIncreasedTemperature": "Kill Cooldown Decrease per Increased Temperature",
"QuizMaster": "Quiz Master",
"QuizMasterInfo": "Ask Questions to Players",
"QuizMasterInfoLong": "(Neutrals):\\nAs the Quiz Master, you can ask questions to players. If they answer correctly, nothing happens. If they answer incorrectly, they die.\\n\\nKill everyone to win!",
+70
View File
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace EHR.Roles.AddOns.Common
{
public class Dynamo : IAddon
{
private static OptionItem IncreaseSpeedBy;
private static OptionItem IncreaseSpeedFrequency;
private static readonly Dictionary<byte, Vector2> LastPosition = [];
private static readonly Dictionary<byte, float> StartingSpeed = [];
private static readonly Dictionary<byte, float> SpeedIncreaseTimer = [];
public AddonTypes Type => AddonTypes.Helpful;
public void SetupCustomOption()
{
const int id = 19392;
Options.SetupAdtRoleOptions(id, CustomRoles.Dynamo, canSetNum: true, teamSpawnOptions: true);
IncreaseSpeedBy = FloatOptionItem.Create(id + 6, "Dynamo.IncreaseSpeedBy", new(0.1f, 1f, 0.1f), 0.1f, TabGroup.CrewmateRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Dynamo])
.SetValueFormat(OptionFormat.Percent);
IncreaseSpeedFrequency = FloatOptionItem.Create(id + 7, "Dynamo.IncreaseSpeedFrequency", new(0.5f, 30f, 0.5f), 5f, TabGroup.CrewmateRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Dynamo])
.SetValueFormat(OptionFormat.Seconds);
}
public static void Add()
{
foreach ((PlayerControl pc, float speed) in Main.AllAlivePlayerControls.Zip(Main.AllPlayerSpeed.Values))
{
if (pc.Is(CustomRoles.Dynamo))
{
LastPosition[pc.PlayerId] = pc.Pos();
SpeedIncreaseTimer[pc.PlayerId] = -8f;
StartingSpeed[pc.PlayerId] = speed;
}
}
}
public static void OnFixedUpdate(PlayerControl pc)
{
var pos = pc.Pos();
bool moving = Vector2.Distance(pos, LastPosition[pc.PlayerId]) > 0.1f;
LastPosition[pc.PlayerId] = pos;
if (!moving || !pc.IsAlive() || !GameStates.IsInTask)
{
var speed = Main.AllPlayerSpeed[pc.PlayerId];
var defaultSpeed = StartingSpeed[pc.PlayerId];
if (Math.Abs(speed - defaultSpeed) > 0.1f)
{
Main.AllPlayerSpeed[pc.PlayerId] = defaultSpeed;
pc.MarkDirtySettings();
}
return;
}
SpeedIncreaseTimer[pc.PlayerId] += Time.fixedDeltaTime;
if (SpeedIncreaseTimer[pc.PlayerId] < IncreaseSpeedFrequency.GetFloat()) return;
SpeedIncreaseTimer[pc.PlayerId] = 0f;
Main.AllPlayerSpeed[pc.PlayerId] += IncreaseSpeedBy.GetFloat();
pc.MarkDirtySettings();
}
}
}
+4 -4
View File
@@ -13,15 +13,15 @@
public void SetupCustomOption()
{
Options.SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Goose);
OptionAbductTimerLimit = FloatOptionItem.Create(Id + 11, "GooseAbductTimerLimit", new(1f, 20f, 1f), 10f, TabGroup.CrewmateRoles)
OptionAbductTimerLimit = FloatOptionItem.Create(Id + 11, "PenguinAbductTimerLimit", new(1f, 20f, 1f), 10f, TabGroup.CrewmateRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Goose])
.SetValueFormat(OptionFormat.Seconds);
OptionMeetingKill = BooleanOptionItem.Create(Id + 12, "GooseMeetingKill", false, TabGroup.CrewmateRoles)
OptionMeetingKill = BooleanOptionItem.Create(Id + 12, "PenguinMeetingKill", false, TabGroup.CrewmateRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Goose]);
OptionSpeedDuringDrag = FloatOptionItem.Create(Id + 13, "GooseSpeedDuringDrag", new(0.1f, 3f, 0.1f), 1f, TabGroup.CrewmateRoles)
OptionSpeedDuringDrag = FloatOptionItem.Create(Id + 13, "PenguinSpeedDuringDrag", new(0.1f, 3f, 0.1f), 1f, TabGroup.CrewmateRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Goose])
.SetValueFormat(OptionFormat.Multiplier);
OptionVictimCanUseAbilities = BooleanOptionItem.Create(Id + 14, "GooseVictimCanUseAbilities", false, TabGroup.CrewmateRoles)
OptionVictimCanUseAbilities = BooleanOptionItem.Create(Id + 14, "PenguinVictimCanUseAbilities", false, TabGroup.CrewmateRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Goose]);
CanBeGuessed = BooleanOptionItem.Create(Id + 15, "CanBeGuessed", true, TabGroup.CrewmateRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Goose]);
+43 -43
View File
@@ -390,48 +390,6 @@ namespace EHR.Roles.Crewmate
internal class Randomizer : RoleBase
{
private static int Id => 643490;
private static List<byte> PlayerIdList = [];
private static OptionItem EffectFrequencyOpt;
private static OptionItem EffectDurMin;
private static OptionItem EffectDurMax;
private static OptionItem NotifyOpt;
private static int EffectFrequency;
public static int MinimumEffectDuration;
public static int MaximumEffectDuration;
private static bool Notify;
public static Dictionary<byte, Dictionary<Effect, (long StartTimeStamp, int Duration)>> CurrentEffects = [];
public static Dictionary<byte, float> AllPlayerDefaultSpeed = [];
public static Dictionary<Vector2, Vector2> Rifts = [];
public static Dictionary<Vector2, (long PlaceTimeStamp, int ExplosionDelay)> Bombs = [];
public static float TimeSinceLastMeeting;
private static Dictionary<byte, long> LastEffectPick = [];
private static Dictionary<byte, long> LastTP = [];
private static long LastDeathEffect;
private static string RNGString => Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), Translator.GetString("RNGHasSpoken"));
public static void NotifyAboutRNG(PlayerControl pc)
{
if (!Notify) return;
pc.Notify(text: RNGString, time: IRandom.Instance.Next(2, 7), log: false);
}
public static bool Exists;
public static float RandomFloat => IRandom.Instance.Next(0, 5) + (IRandom.Instance.Next(0, 10) / 10f);
public override bool IsEnable => Exists;
public static bool IsShielded(PlayerControl pc) => CurrentEffects.TryGetValue(pc.PlayerId, out var effects) && (effects.ContainsKey(Effect.ShieldRandomPlayer) || effects.ContainsKey(Effect.ShieldAll));
public static bool HasSuperVision(PlayerControl pc) => CurrentEffects.TryGetValue(pc.PlayerId, out var effects) && (effects.ContainsKey(Effect.SuperVisionForRandomPlayer) || effects.ContainsKey(Effect.SuperVisionForAll));
public static bool IsBlind(PlayerControl pc) => CurrentEffects.TryGetValue(pc.PlayerId, out var effects) && (effects.ContainsKey(Effect.BlindnessForRandomPlayer) || effects.ContainsKey(Effect.BlindnessForAll));
public enum Effect
{
ShieldRandomPlayer,
@@ -470,6 +428,48 @@ namespace EHR.Roles.Crewmate
Duel
}
private static List<byte> PlayerIdList = [];
private static OptionItem EffectFrequencyOpt;
private static OptionItem EffectDurMin;
private static OptionItem EffectDurMax;
private static OptionItem NotifyOpt;
private static int EffectFrequency;
public static int MinimumEffectDuration;
public static int MaximumEffectDuration;
private static bool Notify;
public static Dictionary<byte, Dictionary<Effect, (long StartTimeStamp, int Duration)>> CurrentEffects = [];
public static Dictionary<byte, float> AllPlayerDefaultSpeed = [];
public static Dictionary<Vector2, Vector2> Rifts = [];
public static Dictionary<Vector2, (long PlaceTimeStamp, int ExplosionDelay)> Bombs = [];
public static float TimeSinceLastMeeting;
private static Dictionary<byte, long> LastEffectPick = [];
private static Dictionary<byte, long> LastTP = [];
private static long LastDeathEffect;
public static bool Exists;
private static int Id => 643490;
private static string RNGString => Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), Translator.GetString("RNGHasSpoken"));
public static float RandomFloat => IRandom.Instance.Next(0, 5) + (IRandom.Instance.Next(0, 10) / 10f);
public override bool IsEnable => Exists;
public static void NotifyAboutRNG(PlayerControl pc)
{
if (!Notify) return;
pc.Notify(text: RNGString, time: IRandom.Instance.Next(2, 7), log: false);
}
public static bool IsShielded(PlayerControl pc) => CurrentEffects.TryGetValue(pc.PlayerId, out var effects) && (effects.ContainsKey(Effect.ShieldRandomPlayer) || effects.ContainsKey(Effect.ShieldAll));
public static bool HasSuperVision(PlayerControl pc) => CurrentEffects.TryGetValue(pc.PlayerId, out var effects) && (effects.ContainsKey(Effect.SuperVisionForRandomPlayer) || effects.ContainsKey(Effect.SuperVisionForAll));
public static bool IsBlind(PlayerControl pc) => CurrentEffects.TryGetValue(pc.PlayerId, out var effects) && (effects.ContainsKey(Effect.BlindnessForRandomPlayer) || effects.ContainsKey(Effect.BlindnessForAll));
public static void SetupCustomOption()
{
Options.SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Randomizer);
@@ -514,7 +514,7 @@ namespace EHR.Roles.Crewmate
{
Exists = true;
PlayerIdList.Add(playerId);
AllPlayerDefaultSpeed = Main.AllPlayerSpeed;
AllPlayerDefaultSpeed = Main.AllPlayerSpeed.ToDictionary(x => x.Key, x => x.Value);
}
public static PlayerControl PickRandomPlayer()
+1 -1
View File
@@ -108,7 +108,7 @@ namespace EHR.Roles.Impostor
var text = "\n" + string.Format(
Translator.GetString("Sentry.Notify.Shapeshifted"),
Utils.ColorString(Main.PlayerColors[ss.PlayerId], ss.GetRealName()),
Utils.ColorString(Main.PlayerColors[ssTarget.PlayerId], ssTarget.GetRealName()));
Utils.ColorString(Main.PlayerColors[ssTarget.PlayerId], Main.AllPlayerNames[ssTarget.PlayerId]));
SentryPC.Notify($"{notify.TEXT}{text}", ShowInfoDuration.GetInt() - (Utils.TimeStamp - notify.TIMESTAMP));
+141
View File
@@ -0,0 +1,141 @@
using AmongUs.GameOptions;
using UnityEngine;
namespace EHR.Roles.Impostor
{
public class Overheat : RoleBase
{
private const int StartingTemperature = 35;
public static bool On;
private static OptionItem OverheatChanceIncrease;
private static OptionItem OverheatChanceIncreaseFrequency;
private static OptionItem OverheatRollChanceFrequency;
private static OptionItem CoolDownTime;
private static OptionItem KCDDecreasePerIncreasedTemperature;
private float ChanceIncreaseTimer;
private float RollChanceTimer;
private int Temperature;
public override bool IsEnable => On;
public static void SetupCustomOption()
{
const int id = 11332;
Options.SetupRoleOptions(id, TabGroup.ImpostorRoles, CustomRoles.Overheat);
OverheatChanceIncrease = FloatOptionItem.Create(id + 2, "Overheat.ChanceIncrease", new(1f, 10f, 1f), 1f, TabGroup.ImpostorRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Overheat])
.SetValueFormat(OptionFormat.Percent);
OverheatChanceIncreaseFrequency = FloatOptionItem.Create(id + 3, "Overheat.ChanceIncreaseFrequency", new(0.5f, 30f, 0.5f), 5f, TabGroup.ImpostorRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Overheat])
.SetValueFormat(OptionFormat.Seconds);
OverheatRollChanceFrequency = FloatOptionItem.Create(id + 4, "Overheat.RollChanceFrequency", new(0.5f, 60f, 0.5f), 3f, TabGroup.ImpostorRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Overheat])
.SetValueFormat(OptionFormat.Seconds);
CoolDownTime = FloatOptionItem.Create(id + 5, "Overheat.CoolDownTime", new(0.5f, 30f, 0.5f), 4f, TabGroup.ImpostorRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Overheat])
.SetValueFormat(OptionFormat.Seconds);
KCDDecreasePerIncreasedTemperature = FloatOptionItem.Create(id + 6, "Overheat.KCDDecreasePerIncreasedTemperature", new(0.5f, 15f, 0.5f), 3f, TabGroup.ImpostorRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Overheat])
.SetValueFormat(OptionFormat.Seconds);
}
static Color GetTemperatureColor(int temperature) => temperature switch
{
<= 35 => Color.blue,
36 => Color.cyan,
37 => Color.green,
38 => Color.yellow,
39 => Palette.Orange,
>= 40 => Color.red
};
public override void Add(byte playerId)
{
On = true;
Temperature = StartingTemperature;
ChanceIncreaseTimer = -8f;
RollChanceTimer = -8f;
}
public override void Init()
{
On = false;
}
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
if (Options.UsePets.GetBool()) return;
AURoleOptions.ShapeshifterCooldown = 1f;
AURoleOptions.ShapeshifterDuration = 1f;
}
public override void SetKillCooldown(byte id)
{
var kcd = Options.DefaultKillCooldown;
kcd -= KCDDecreasePerIncreasedTemperature.GetFloat() * (Temperature - StartingTemperature);
Main.AllPlayerKillCooldown[id] = kcd;
}
public override void OnFixedUpdate(PlayerControl pc)
{
if (!GameStates.IsInTask || !pc.IsAlive()) return;
ChanceIncreaseTimer += Time.fixedDeltaTime;
RollChanceTimer += Time.fixedDeltaTime;
if (ChanceIncreaseTimer >= OverheatChanceIncreaseFrequency.GetFloat())
{
ChanceIncreaseTimer = 0f;
Temperature += OverheatChanceIncrease.GetInt();
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
}
if (RollChanceTimer >= OverheatRollChanceFrequency.GetFloat())
{
RollChanceTimer = 0f;
if (IRandom.Instance.Next(100) < Temperature - StartingTemperature)
{
pc.Suicide();
}
}
}
void CoolDown(PlayerControl pc)
{
Temperature = StartingTemperature;
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
float speed = Main.AllPlayerSpeed[pc.PlayerId];
Main.AllPlayerSpeed[pc.PlayerId] = Main.MinSpeed;
pc.MarkDirtySettings();
_ = new LateTask(() =>
{
Main.AllPlayerSpeed[pc.PlayerId] = speed;
pc.MarkDirtySettings();
}, CoolDownTime.GetFloat(), "Overheat Cool Down");
}
public override bool OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool shapeshifting)
{
CoolDown(shapeshifter);
return false;
}
public override void OnPet(PlayerControl pc)
{
CoolDown(pc);
}
public static string GetSuffix(PlayerControl seer)
{
if (Main.PlayerStates[seer.PlayerId].Role is not Overheat oh) return string.Empty;
var color = GetTemperatureColor(oh.Temperature);
var str = Translator.GetString("Overheat.Suffix");
return string.Format(str, Utils.ColorString(color, $"{oh.Temperature}°C"));
}
}
}
+1
View File
@@ -96,6 +96,7 @@ namespace EHR.Roles.Impostor
public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = Options.DefaultKillCooldown;
public override bool CanUseImpostorVentButton(PlayerControl pc) => AbductVictim == null;
public override bool CanUseKillButton(PlayerControl pc) => pc.IsAlive();
void SendRPC()
{
+1
View File
@@ -48,6 +48,7 @@ namespace EHR.Roles.Impostor
if (Vector2.Distance(killer.Pos(), target.Pos()) > 2f) return;
target.TP(Pelican.GetBlackRoomPS());
target.Suicide(PlayerState.DeathReason.Kill, killer);
if (target.Is(CustomRoles.Pelican)) Pelican.OnPelicanDied(target.PlayerId);
killer.SetKillCooldown();
RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound);
target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Scavenger), Translator.GetString("KilledByScavenger")));
+3 -4
View File
@@ -182,13 +182,12 @@ public class Pelican : RoleBase
public static void OnPelicanDied(byte pc)
{
if (!eatenList.ContainsKey(pc)) return;
foreach (byte tar in eatenList[pc])
if (!eatenList.TryGetValue(pc, out List<byte> value)) return;
foreach (byte tar in value)
{
var target = Utils.GetPlayerById(tar);
var player = Utils.GetPlayerById(pc);
if (player == null || target == null)
continue;
if (player == null || target == null) continue;
target.TP(player);
Main.AllPlayerSpeed[tar] = Main.AllPlayerSpeed[tar] - 0.5f + OriginalSpeed[tar];
ReportDeadBodyPatch.CanReport[tar] = true;
+2 -2
View File
@@ -73,8 +73,8 @@ public class Pursuer : RoleBase
{
foreach (var id in playerIdList)
{
if (!Main.PlayerStates.ContainsKey(id)) continue;
if (Main.PlayerStates[id].Role is not Pursuer { IsEnable: true } ps) continue;
if (!Main.PlayerStates.TryGetValue(id, out PlayerState state)) continue;
if (state.Role is not Pursuer { IsEnable: true } ps) continue;
if (!ps.clientList.Contains(pc.PlayerId) || notActiveList.Contains(pc.PlayerId)) continue;
// Get rid of this nonsense of killing the player for no reason
+1 -1
View File
@@ -59,7 +59,7 @@ public class Vulture : RoleBase
.SetParent(CustomRoleSpawnChances[CustomRoles.Vulture]);
ChangeRoleWhenCantWin = BooleanOptionItem.Create(Id + 16, "VultureChangeRoleWhenCantWin", true, TabGroup.NeutralRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.Vulture]);
ChangeRole = StringOptionItem.Create(Id + 17, "VultureChangeRole", ChangeRoles.Select(x => x.ToColoredString()).ToArray(), 0, TabGroup.NeutralRoles)
ChangeRole = StringOptionItem.Create(Id + 17, "VultureChangeRole", ChangeRoles.Select(x => x.ToColoredString()).ToArray(), 0, TabGroup.NeutralRoles, noTranslation: true)
.SetParent(CustomRoleSpawnChances[CustomRoles.Vulture]);
}
+1
View File
@@ -493,6 +493,7 @@ public class Main : BasePlugin
{ CustomRoles.Madmate, "#ff1919" },
{ CustomRoles.Watcher, "#800080" },
{ CustomRoles.Sleuth, "#30221c" },
{ CustomRoles.Dynamo, "#ebe534" },
{ CustomRoles.AntiTP, "#fcba03" },
{ CustomRoles.Taskcounter, "#ff1919" },
{ CustomRoles.Stained, "#e6bf91" },