mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
Add Dynamo, Add Overheat, fixed some bugs
This commit is contained in:
1 parent
62457c87fd
commit
6ba06c0199
22 files changed
+334
-93
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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!",
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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]);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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")));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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" },
|
||||
|
||||
Reference in new issue
Block a user