Merge pull request #348

Hacker and Anonymous no more confusion, Greedier CD limits
This commit is contained in:
HyperAtill authored and GitHub committed 2025-09-07 12:28:05 +02:00
commit 06d6f0aa9c
14 files changed
+167 -167

No files matched your search

+2 -2
View File
@@ -18,7 +18,7 @@ public enum CustomRoles
// Impostors
Abyssbringer,
Hacker, // Anonymous
Anonymous,
AntiAdminer,
Sans, // Arrogance
Assumer,
@@ -189,6 +189,7 @@ public enum CustomRoles
Grenadier,
MeetingManager,
Guardian,
Hacker,
Helper,
Ignitor,
Imitator,
@@ -218,7 +219,6 @@ public enum CustomRoles
Mortician,
NiceEraser,
NiceGuesser,
NiceHacker,
NiceSwapper,
Nightmare,
Negotiator,
+1 -1
View File
@@ -443,7 +443,7 @@ public class Main : BasePlugin
{ CustomRoles.Benefactor, "#4aeaff" },
{ CustomRoles.MeetingManager, "#d4ff00" },
{ CustomRoles.Drainer, "#149627" },
{ CustomRoles.NiceHacker, "#75fa4c" },
{ CustomRoles.Hacker, "#75fa4c" },
{ CustomRoles.Aid, "#D7BDE2" },
{ CustomRoles.DonutDelivery, "#a46efa" },
{ CustomRoles.Analyst, "#33ddff" },
+5 -5
View File
@@ -198,7 +198,7 @@ internal static class CustomRolesHelper
CustomRoles.Needy => CustomRoles.Crewmate,
CustomRoles.Twister => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.SuperStar => CustomRoles.Crewmate,
CustomRoles.Hacker => CustomRoles.Shapeshifter,
CustomRoles.Anonymous => CustomRoles.Shapeshifter,
CustomRoles.Visionary => CustomRoles.Shapeshifter,
CustomRoles.Ninja => CustomRoles.Phantom,
CustomRoles.Undertaker => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
@@ -684,7 +684,7 @@ internal static class CustomRolesHelper
CustomRoles.Warlock or
CustomRoles.Ninja or
CustomRoles.Undertaker or
CustomRoles.Hacker or
CustomRoles.Anonymous or
CustomRoles.Visionary or
CustomRoles.Miner or
CustomRoles.Escapee or
@@ -1345,7 +1345,7 @@ internal static class CustomRolesHelper
public static bool IsDevFavoriteRole(this CustomRoles role)
{
return role is CustomRoles.Adventurer or CustomRoles.Chef or CustomRoles.Detour or CustomRoles.NiceHacker or CustomRoles.NiceSwapper or CustomRoles.Sentinel or CustomRoles.Sentry or CustomRoles.Tornado or CustomRoles.Tunneler or CustomRoles.Whisperer or CustomRoles.Wizard or
return role is CustomRoles.Adventurer or CustomRoles.Chef or CustomRoles.Detour or CustomRoles.Hacker or CustomRoles.NiceSwapper or CustomRoles.Sentinel or CustomRoles.Sentry or CustomRoles.Tornado or CustomRoles.Tunneler or CustomRoles.Whisperer or CustomRoles.Wizard or
CustomRoles.Abyssbringer or CustomRoles.Assumer or CustomRoles.Chronomancer or CustomRoles.Echo or CustomRoles.Escapee or CustomRoles.Hypnotist or CustomRoles.Librarian or CustomRoles.Mafioso or CustomRoles.Mastermind or CustomRoles.Mercenary or CustomRoles.Penguin or CustomRoles.RiftMaker or CustomRoles.Sapper or CustomRoles.Wiper or
CustomRoles.Bargainer or CustomRoles.Bubble or CustomRoles.Doomsayer or CustomRoles.Enderman or CustomRoles.Evolver or CustomRoles.HeadHunter or CustomRoles.Impartial or CustomRoles.Patroller or CustomRoles.Pawn or CustomRoles.PlagueDoctor or CustomRoles.Postman or CustomRoles.Pyromaniac or CustomRoles.Revolutionist or CustomRoles.Rogue or CustomRoles.Romantic or CustomRoles.RoomRusher or CustomRoles.RouleteGrandeur or CustomRoles.Simon or CustomRoles.SoulHunter or CustomRoles.Sprayer or CustomRoles.Technician or CustomRoles.Tank or CustomRoles.Tiger or CustomRoles.Tremor or CustomRoles.Vengeance or CustomRoles.Vortex or CustomRoles.Werewolf or CustomRoles.WeaponMaster or
CustomRoles.Reaper or CustomRoles.VoodooMaster or CustomRoles.Dreamweaver or CustomRoles.Banshee or
@@ -1604,7 +1604,7 @@ internal static class CustomRolesHelper
CustomRoles.Ventriloquist => RoleOptionType.Impostor_Support,
CustomRoles.Vindicator => RoleOptionType.Impostor_Support,
CustomRoles.YinYanger => RoleOptionType.Impostor_Support,
CustomRoles.Hacker => RoleOptionType.Impostor_Concealing,
CustomRoles.Anonymous => RoleOptionType.Impostor_Concealing,
CustomRoles.Duellist => RoleOptionType.Impostor_Concealing,
CustomRoles.Echo => RoleOptionType.Impostor_Concealing,
CustomRoles.Escapee => RoleOptionType.Impostor_Concealing,
@@ -1705,7 +1705,7 @@ internal static class CustomRolesHelper
CustomRoles.Mediumshiper => RoleOptionType.Crewmate_Investigate,
CustomRoles.Monitor => RoleOptionType.Crewmate_Investigate,
CustomRoles.Mortician => RoleOptionType.Crewmate_Investigate,
CustomRoles.NiceHacker => RoleOptionType.Crewmate_Investigate,
CustomRoles.Hacker => RoleOptionType.Crewmate_Investigate,
CustomRoles.Observer => RoleOptionType.Crewmate_Investigate,
CustomRoles.Oracle => RoleOptionType.Crewmate_Investigate,
CustomRoles.Perceiver => RoleOptionType.Crewmate_Investigate,
+5 -5
View File
@@ -477,12 +477,12 @@ public class TaskState
sm.UsedSkillCount -= SabotageMaster.SmAbilityUseGainWithEachTaskCompleted.GetFloat();
sm.SendRPC();
break;
case CustomRoles.NiceHacker:
if (!player.IsModdedClient() && NiceHacker.UseLimit.ContainsKey(player.PlayerId))
NiceHacker.UseLimit[player.PlayerId] += NiceHacker.NiceHackerAbilityUseGainWithEachTaskCompleted.GetFloat();
else if (NiceHacker.UseLimitSeconds.ContainsKey(player.PlayerId)) NiceHacker.UseLimitSeconds[player.PlayerId] += NiceHacker.NiceHackerAbilityUseGainWithEachTaskCompleted.GetInt() * NiceHacker.ModdedClientAbilityUseSecondsMultiplier.GetInt();
case CustomRoles.Hacker:
if (!player.IsModdedClient() && Hacker.UseLimit.ContainsKey(player.PlayerId))
Hacker.UseLimit[player.PlayerId] += Hacker.HackerAbilityUseGainWithEachTaskCompleted.GetFloat();
else if (Hacker.UseLimitSeconds.ContainsKey(player.PlayerId)) Hacker.UseLimitSeconds[player.PlayerId] += Hacker.HackerAbilityUseGainWithEachTaskCompleted.GetInt() * Hacker.ModdedClientAbilityUseSecondsMultiplier.GetInt();
if (NiceHacker.UseLimitSeconds.ContainsKey(player.PlayerId)) NiceHacker.SendRPC(player.PlayerId, NiceHacker.UseLimitSeconds[player.PlayerId]);
if (Hacker.UseLimitSeconds.ContainsKey(player.PlayerId)) Hacker.SendRPC(player.PlayerId, Hacker.UseLimitSeconds[player.PlayerId]);
break;
}
+3 -3
View File
@@ -103,7 +103,7 @@ public enum CustomRPC
SyncGlitchTimers,
SyncSpy,
SetSabotageMasterLimit,
SetNiceHackerLimit,
SetHackerLimit,
SetCurrentDrawTarget,
SetCpTasksDone,
SetDemonHealth,
@@ -875,9 +875,9 @@ internal static class RPCHandlerPatch
SabotageMaster.ReceiveRPC(reader);
break;
}
case CustomRPC.SetNiceHackerLimit:
case CustomRPC.SetHackerLimit:
{
NiceHacker.ReceiveRPC(reader);
Hacker.ReceiveRPC(reader);
break;
}
case CustomRPC.SetLoversPlayers:
+2 -2
View File
@@ -3236,7 +3236,7 @@ public static class Utils
CustomRoles.Convener => Convener.CD.GetInt(),
CustomRoles.DovesOfNeace => Options.DovesOfNeaceCooldown.GetInt(),
CustomRoles.Alchemist => Alchemist.VentCooldown.GetInt(),
CustomRoles.NiceHacker => playerId.IsPlayerModdedClient() ? -1 : NiceHacker.AbilityCD.GetInt(),
CustomRoles.Hacker => playerId.IsPlayerModdedClient() ? -1 : Hacker.AbilityCD.GetInt(),
CustomRoles.CameraMan => CameraMan.VentCooldown.GetInt(),
CustomRoles.Tornado => Tornado.TornadoCooldown.GetInt(),
CustomRoles.Sentinel => Sentinel.PatrolCooldown.GetInt(),
@@ -3500,7 +3500,7 @@ public static class Utils
if (!onMeeting && !disconnect)
{
Hacker.AddDeadBody(target);
Anonymous.AddDeadBody(target);
Mortician.OnPlayerDead(target);
Tracefinder.OnPlayerDead(target);
Scout.OnPlayerDeath(target);
+3 -3
View File
@@ -647,10 +647,10 @@ internal static class MapBehaviourShowPatch
PlayerControl player = PlayerControl.LocalPlayer;
if (player.GetCustomRole() == CustomRoles.NiceHacker && NiceHacker.PlayerIdList.ContainsKey(player.PlayerId))
if (player.GetCustomRole() == CustomRoles.Hacker && Hacker.PlayerIdList.ContainsKey(player.PlayerId))
{
Logger.Info("Modded Client uses Map", "NiceHacker");
NiceHacker.MapHandle(player, __instance, opts);
Logger.Info("Modded Client uses Map", "Hacker");
Hacker.MapHandle(player, __instance, opts);
}
else if (opts.Mode is MapOptions.Modes.Normal or MapOptions.Modes.Sabotage)
{
+1 -1
View File
@@ -301,7 +301,7 @@ public static class HudSpritePatch
newAbilityButton = CustomButton.Get(fw.nowFireWorksCount == 0 ? "FireworkD" : "FireworkP");
break;
}
case CustomRoles.Hacker:
case CustomRoles.Anonymous:
{
newAbilityButton = CustomButton.Get("Hack");
break;
+11 -11
View File
@@ -182,7 +182,7 @@
"Warlock": "Warlock",
"Assassin": "Ninja",
"Zombie": "Zombie",
"Hacker": "Anonymous",
"Anonymous": "Anonymous",
"Miner": "Miner",
"Minimalism": "Killing Machine",
"Escapee": "Escapist",
@@ -461,7 +461,7 @@
"WarlockInfo": "Curse crewmates & shift to make them kill",
"NinjaInfo": "Mark a target, then shift to kill them",
"ZombieInfo": "You're very slow",
"HackerInfo": "Force a player to report a body",
"AnonymousInfo": "Force a player to report a body",
"MinerInfo": "Warp to your last used vent by shifting",
"MinimalismInfo": "You can ONLY kill, but low cooldown",
"EscapeeInfo": "Shift to mark places and warp back to them",
@@ -691,7 +691,7 @@
"WarlockInfoLong": "(Impostors):\\nWarlock can curse a player while not Shapeshifted. If they vanish/pet after cursing, the closest player to the cursed one is killed, regardless of distance. Only one player can be cursed at a time.\\n\\nKilling, shapeshifting/petting, and cursing all have separate cooldowns. The Warlock may freeze in place for a few seconds after killing via cursed player.",
"ZombieInfoLong": "(Impostors):\\nZombie has a short kill cooldown but moves very slowly and has very little vision. Zombie will not be voted out by anyone other than the Dictator, and the movement speed of Zombie will gradually slow down as they make kills or time passes.",
"NinjaInfoLong": "(Impostors):\\nNinja can use the kill button to mark a target, and if the mark is successful, a shield animation will show as a reminder. The Ninja can then use the vanish/pet to teleport to the marked person and kill the marked person. Ninja cannot kill regularly, but may be able to kill regularly after assassination according to the host's settings.",
"HackerInfoLong": "(Impostors):\\nAnonymous can use Shapeshift to hack into a target. The hacked target will report the body killed by Anonymous or its own if there is none. Hacking ignores whether a body can be reported. Hacking Lazy Guy is a waste of time.",
"AnonymousInfoLong": "(Impostors):\\nAnonymous can use Shapeshift to hack into a target. The hacked target will report the body killed by Anonymous or its own if there is none. Hacking ignores whether a body can be reported. Hacking Lazy Guy is a waste of time.",
"MinerInfoLong": "(Impostors):\\nMiner can vanish/pet to teleport back to the last vent they were in.",
"MinimalismInfoLong": "(Impostors):\\nThe Killing Machine has a very short kill cooldown, but cannot vent, has lower vision, cannot sabotage, cannot report, and cannot call emergency meetings.",
"EscapeeInfoLong": "(Impostors):\\nEscapist can mark a location by shapeshifting/petting, and they will be teleported to the marked location when they vanish/pet again (not when unshifting).",
@@ -3158,7 +3158,7 @@
"BomberShapeshiftText": "Explode",
"QuickShooterShapeshiftText": "Keep",
"CamouflagerShapeshiftText": "Disguise",
"HackerShapeshiftText": "Hack",
"AnonymousShapeshiftText": "Hack",
"DefaultShapeshiftText": "Shift",
"DefaultRevertShapeshiftText": "Revert",
"CleanerReportButtonText": "Clean",
@@ -4132,13 +4132,13 @@
"EchoInfoLong": "(Impostors):\\nAs the Echo, you can shapeshift into a player to swap locations and skins with them. During the shapeshift, your target cannot move. When you unshift, the swap reverts and the target dies exactly where you were.\\n\\nYou cannot kill normally.",
"EchoShapeshiftButtonText": "Control",
"Echo.DisableVentingWhileControlling": "Disable Venting While Controlling",
"NiceHacker": "Hacker",
"NiceHackerInfo": "Watch Admin Table from anywhere",
"NiceHackerInfoLong": "(Crewmates):\\nThis role allows you to see the admin map from anywhere, but is different for modded clients and vanilla clients.\\n\\nAs a modded client, whenever you open the map (and have ability uses left), the admin map will show up. You may be able to move while having the map open depending on settings.\\n\\nAs a vanilla client, you may enter a vent/pet to get a notification saying how many people are in different rooms on the ship (essentially admin map).",
"NiceHackerModdedClientAbilityUseSecondsMultiplier": "Modded clients, for 1 ability use, can view Admin map for",
"NiceHackerModdedClientCanMoveWhileViewingMap": "Modded clients can move while looking at Admin map",
"NiceHackerVanillaClientSeesInfoFor": "Vanilla clients see admin info notify for",
"NiceHackerAbilitySecondsLeft": "Ability uses left in seconds",
"Hacker": "Hacker",
"HackerInfo": "Watch Admin Table from anywhere",
"HackerInfoLong": "(Crewmates):\\nThis role allows you to see the admin map from anywhere, but is different for modded clients and vanilla clients.\\n\\nAs a modded client, whenever you open the map (and have ability uses left), the admin map will show up. You may be able to move while having the map open depending on settings.\\n\\nAs a vanilla client, you may enter a vent/pet to get a notification saying how many people are in different rooms on the ship (essentially admin map).",
"HackerModdedClientAbilityUseSecondsMultiplier": "Modded clients, for 1 ability use, can view Admin map for",
"HackerModdedClientCanMoveWhileViewingMap": "Modded clients can move while looking at Admin map",
"HackerVanillaClientSeesInfoFor": "Vanilla clients see admin info notify for",
"HackerAbilitySecondsLeft": "Ability uses left in seconds",
"AbilityChargesWhenFinishedTasks": "<color=#00ffff>Ability <color=#7FFFD2>Use Gains</color> <color=#ffa500>every 5s</color> when tasks are done</color>",
"Vengeance": "Vengeance",
"VengeanceInfo": "Kill your killer to live",
@@ -11,7 +11,7 @@ using static Options;
using static Translator;
using static Utils;
public class NiceHacker : RoleBase
public class Hacker : RoleBase
{
private const int Id = 641000;
public static Dictionary<byte, bool> PlayerIdList = [];
@@ -22,7 +22,7 @@ public class NiceHacker : RoleBase
public static OptionItem AbilityCD;
public static OptionItem UseLimitOpt;
public static OptionItem NiceHackerAbilityUseGainWithEachTaskCompleted;
public static OptionItem HackerAbilityUseGainWithEachTaskCompleted;
public static OptionItem AbilityChargesWhenFinishedTasks;
public static OptionItem ModdedClientAbilityUseSecondsMultiplier;
public static OptionItem ModdedClientCanMoveWhileViewingMap;
@@ -32,29 +32,29 @@ public class NiceHacker : RoleBase
public override void SetupCustomOption()
{
SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.NiceHacker);
SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Hacker);
AbilityCD = new FloatOptionItem(Id + 10, "AbilityCD", new(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles).SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
AbilityCD = new FloatOptionItem(Id + 10, "AbilityCD", new(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
.SetValueFormat(OptionFormat.Seconds);
UseLimitOpt = new IntegerOptionItem(Id + 11, "AbilityUseLimit", new(1, 20, 1), 2, TabGroup.CrewmateRoles).SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
UseLimitOpt = new IntegerOptionItem(Id + 11, "AbilityUseLimit", new(1, 20, 1), 2, TabGroup.CrewmateRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
.SetValueFormat(OptionFormat.Times);
NiceHackerAbilityUseGainWithEachTaskCompleted = new FloatOptionItem(Id + 12, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.05f), 1f, TabGroup.CrewmateRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
HackerAbilityUseGainWithEachTaskCompleted = new FloatOptionItem(Id + 12, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.05f), 1f, TabGroup.CrewmateRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
.SetValueFormat(OptionFormat.Times);
AbilityChargesWhenFinishedTasks = new FloatOptionItem(Id + 13, "AbilityChargesWhenFinishedTasks", new(0f, 5f, 0.05f), 0.2f, TabGroup.CrewmateRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
.SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
.SetValueFormat(OptionFormat.Times);
ModdedClientAbilityUseSecondsMultiplier = new FloatOptionItem(Id + 14, "NiceHackerModdedClientAbilityUseSecondsMultiplier", new(0f, 70f, 1f), 3f, TabGroup.CrewmateRoles).SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
ModdedClientAbilityUseSecondsMultiplier = new FloatOptionItem(Id + 14, "HackerModdedClientAbilityUseSecondsMultiplier", new(0f, 70f, 1f), 3f, TabGroup.CrewmateRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
.SetValueFormat(OptionFormat.Seconds);
ModdedClientCanMoveWhileViewingMap = new BooleanOptionItem(Id + 15, "NiceHackerModdedClientCanMoveWhileViewingMap", false, TabGroup.CrewmateRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker]);
ModdedClientCanMoveWhileViewingMap = new BooleanOptionItem(Id + 15, "HackerModdedClientCanMoveWhileViewingMap", false, TabGroup.CrewmateRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.Hacker]);
VanillaClientSeesInfoFor = new FloatOptionItem(Id + 16, "NiceHackerVanillaClientSeesInfoFor", new(0f, 70f, 1f), 4f, TabGroup.CrewmateRoles).SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
VanillaClientSeesInfoFor = new FloatOptionItem(Id + 16, "HackerVanillaClientSeesInfoFor", new(0f, 70f, 1f), 4f, TabGroup.CrewmateRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
.SetValueFormat(OptionFormat.Seconds);
}
@@ -93,7 +93,7 @@ public class NiceHacker : RoleBase
{
if (!DoRPC) return;
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetNiceHackerLimit, SendOption.Reliable);
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetHackerLimit, SendOption.Reliable);
writer.Write(playerId);
writer.Write(secondsLeft);
AmongUsClient.Instance.FinishRpcImmediately(writer);
@@ -172,7 +172,7 @@ public class NiceHacker : RoleBase
UseLimitSeconds[pc.PlayerId] -= 1; // Remove 1s for opening the map, so they can't utilize spamming
SendRPC(pc.PlayerId, UseLimitSeconds[pc.PlayerId]);
opts.Mode = MapOptions.Modes.CountOverlay;
LateTask.New(() => { MapCountdown(pc, map, opts, (int)UseLimitSeconds[pc.PlayerId]); }, 1f, "NiceHacker.StartCountdown");
LateTask.New(() => { MapCountdown(pc, map, opts, (int)UseLimitSeconds[pc.PlayerId]); }, 1f, "Hacker.StartCountdown");
}
else
{
@@ -195,14 +195,14 @@ public class NiceHacker : RoleBase
UseLimitSeconds[pc.PlayerId] -= 1;
SendRPC(pc.PlayerId, UseLimitSeconds[pc.PlayerId]);
LateTask.New(() => { MapCountdown(pc, map, opts, seconds - 1); }, 1f, "NiceHackerAbilityCountdown");
LateTask.New(() => { MapCountdown(pc, map, opts, seconds - 1); }, 1f, "HackerAbilityCountdown");
}
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
{
if (!hud || seer == null) return string.Empty;
return !seer.Is(CustomRoles.NiceHacker) ? string.Empty : $"<color=#00ffa5>{GetString("NiceHackerAbilitySecondsLeft")}:</color> <b>{(int)UseLimitSeconds[seer.PlayerId]}</b>s";
return !seer.Is(CustomRoles.Hacker) ? string.Empty : $"<color=#00ffa5>{GetString("HackerAbilitySecondsLeft")}:</color> <b>{(int)UseLimitSeconds[seer.PlayerId]}</b>s";
}
public override string GetProgressText(byte playerId, bool comms)
+2 -2
View File
@@ -184,8 +184,8 @@ public class President : RoleBase
case SabotageMaster sm:
sm.UsedSkillCount--;
break;
case NiceHacker when NiceHacker.UseLimit.ContainsKey(player.PlayerId):
NiceHacker.UseLimit[player.PlayerId]++;
case Hacker when Hacker.UseLimit.ContainsKey(player.PlayerId):
Hacker.UseLimit[player.PlayerId]++;
break;
default:
player.RpcIncreaseAbilityUseLimitBy(1f);
@@ -1,110 +1,110 @@
using System.Collections.Generic;
using AmongUs.GameOptions;
using static EHR.Options;
using static EHR.Translator;
namespace EHR.Impostor;
public class Hacker : RoleBase
{
private const int Id = 2200;
private static List<byte> PlayerIdList = [];
private static OptionItem HackLimitOpt;
private static OptionItem KillCooldown;
public static OptionItem HackerAbilityUseGainWithEachKill;
private static List<byte> DeadBodyList = [];
public override bool IsEnable => PlayerIdList.Count > 0;
public override void SetupCustomOption()
{
SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Hacker);
KillCooldown = new FloatOptionItem(Id + 2, "KillCooldown", new(0f, 180f, 0.5f), 30f, TabGroup.ImpostorRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
.SetValueFormat(OptionFormat.Seconds);
HackLimitOpt = new IntegerOptionItem(Id + 3, "HackLimit", new(0, 5, 1), 0, TabGroup.ImpostorRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
.SetValueFormat(OptionFormat.Times);
HackerAbilityUseGainWithEachKill = new FloatOptionItem(Id + 4, "AbilityUseGainWithEachKill", new(0f, 5f, 0.1f), 0.4f, TabGroup.ImpostorRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
.SetValueFormat(OptionFormat.Times);
}
public override void Init()
{
PlayerIdList = [];
DeadBodyList = [];
}
public override void Add(byte playerId)
{
PlayerIdList.Add(playerId);
playerId.SetAbilityUseLimit(HackLimitOpt.GetFloat());
}
public override void Remove(byte playerId)
{
PlayerIdList.Remove(playerId);
}
public override void SetKillCooldown(byte id)
{
Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat();
}
public override void ApplyGameOptions(IGameOptions opt, byte id)
{
AURoleOptions.ShapeshifterCooldown = 15f;
AURoleOptions.ShapeshifterDuration = 1f;
}
public override void SetButtonTexts(HudManager __instance, byte playerId)
{
if (playerId.GetAbilityUseLimit() >= 1)
{
__instance.AbilityButton.OverrideText(GetString("HackerShapeshiftText"));
__instance.AbilityButton.SetUsesRemaining((int)playerId.GetAbilityUseLimit());
}
}
public override void OnReportDeadBody()
{
DeadBodyList = [];
}
public static void AddDeadBody(PlayerControl target)
{
if (target != null && !DeadBodyList.Contains(target.PlayerId)) DeadBodyList.Add(target.PlayerId);
}
public override bool OnShapeshift(PlayerControl pc, PlayerControl ssTarget, bool shapeshifting)
{
if (!shapeshifting || pc.GetAbilityUseLimit() < 1 || ssTarget == null || ssTarget.Is(CustomRoles.Needy) || ssTarget.Is(CustomRoles.Lazy)) return false;
pc.RpcRemoveAbilityUse();
var targetId = byte.MaxValue;
foreach (byte db in DeadBodyList.ToArray())
{
PlayerControl dp = Utils.GetPlayerById(db);
if (dp == null || dp.GetRealKiller() == null) continue;
if (dp.GetRealKiller().PlayerId == pc.PlayerId) targetId = db;
}
if (targetId == byte.MaxValue && DeadBodyList.Count > 0) targetId = DeadBodyList.RandomElement();
if (targetId == byte.MaxValue)
LateTask.New(() => ssTarget.NoCheckStartMeeting(ssTarget.Data), 0.15f, "Hacker Hacking Report Self");
else
LateTask.New(() => ssTarget.NoCheckStartMeeting(Utils.GetPlayerById(targetId)?.Data), 0.15f, "Hacker Hacking Report");
return false;
}
using System.Collections.Generic;
using AmongUs.GameOptions;
using static EHR.Options;
using static EHR.Translator;
namespace EHR.Impostor;
public class Anonymous : RoleBase
{
private const int Id = 2200;
private static List<byte> PlayerIdList = [];
private static OptionItem HackLimitOpt;
private static OptionItem KillCooldown;
public static OptionItem AnonymousAbilityUseGainWithEachKill;
private static List<byte> DeadBodyList = [];
public override bool IsEnable => PlayerIdList.Count > 0;
public override void SetupCustomOption()
{
SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Anonymous);
KillCooldown = new FloatOptionItem(Id + 2, "KillCooldown", new(0f, 180f, 0.5f), 30f, TabGroup.ImpostorRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.Anonymous])
.SetValueFormat(OptionFormat.Seconds);
HackLimitOpt = new IntegerOptionItem(Id + 3, "HackLimit", new(0, 5, 1), 0, TabGroup.ImpostorRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.Anonymous])
.SetValueFormat(OptionFormat.Times);
AnonymousAbilityUseGainWithEachKill = new FloatOptionItem(Id + 4, "AbilityUseGainWithEachKill", new(0f, 5f, 0.1f), 0.4f, TabGroup.ImpostorRoles)
.SetParent(CustomRoleSpawnChances[CustomRoles.Anonymous])
.SetValueFormat(OptionFormat.Times);
}
public override void Init()
{
PlayerIdList = [];
DeadBodyList = [];
}
public override void Add(byte playerId)
{
PlayerIdList.Add(playerId);
playerId.SetAbilityUseLimit(HackLimitOpt.GetFloat());
}
public override void Remove(byte playerId)
{
PlayerIdList.Remove(playerId);
}
public override void SetKillCooldown(byte id)
{
Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat();
}
public override void ApplyGameOptions(IGameOptions opt, byte id)
{
AURoleOptions.ShapeshifterCooldown = 15f;
AURoleOptions.ShapeshifterDuration = 1f;
}
public override void SetButtonTexts(HudManager __instance, byte playerId)
{
if (playerId.GetAbilityUseLimit() >= 1)
{
__instance.AbilityButton.OverrideText(GetString("AnonymousShapeshiftText"));
__instance.AbilityButton.SetUsesRemaining((int)playerId.GetAbilityUseLimit());
}
}
public override void OnReportDeadBody()
{
DeadBodyList = [];
}
public static void AddDeadBody(PlayerControl target)
{
if (target != null && !DeadBodyList.Contains(target.PlayerId)) DeadBodyList.Add(target.PlayerId);
}
public override bool OnShapeshift(PlayerControl pc, PlayerControl ssTarget, bool shapeshifting)
{
if (!shapeshifting || pc.GetAbilityUseLimit() < 1 || ssTarget == null || ssTarget.Is(CustomRoles.Needy) || ssTarget.Is(CustomRoles.Lazy)) return false;
pc.RpcRemoveAbilityUse();
var targetId = byte.MaxValue;
foreach (byte db in DeadBodyList.ToArray())
{
PlayerControl dp = Utils.GetPlayerById(db);
if (dp == null || dp.GetRealKiller() == null) continue;
if (dp.GetRealKiller().PlayerId == pc.PlayerId) targetId = db;
}
if (targetId == byte.MaxValue && DeadBodyList.Count > 0) targetId = DeadBodyList.RandomElement();
if (targetId == byte.MaxValue)
LateTask.New(() => ssTarget.NoCheckStartMeeting(ssTarget.Data), 0.15f, "Anonymous Hacking Report Self");
else
LateTask.New(() => ssTarget.NoCheckStartMeeting(Utils.GetPlayerById(targetId)?.Data), 0.15f, "Anonymous Hacking Report");
return false;
}
}
+3 -3
View File
@@ -32,15 +32,15 @@ public class Greedier : RoleBase // Also used for Pulse as the NK version of thi
{
Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Greedier);
OddKillCooldown = new FloatOptionItem(Id + 10, "OddKillCooldown", new(0f, 60f, 0.5f), 27.5f, TabGroup.ImpostorRoles)
OddKillCooldown = new FloatOptionItem(Id + 10, "OddKillCooldown", new(0f, 180f, 0.5f), 27.5f, TabGroup.ImpostorRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedier])
.SetValueFormat(OptionFormat.Seconds);
EvenKillCooldown = new FloatOptionItem(Id + 11, "EvenKillCooldown", new(0f, 30f, 0.5f), 15f, TabGroup.ImpostorRoles)
EvenKillCooldown = new FloatOptionItem(Id + 11, "EvenKillCooldown", new(0f, 180f, 0.5f), 15f, TabGroup.ImpostorRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedier])
.SetValueFormat(OptionFormat.Seconds);
AfterMeetingKillCooldown = new FloatOptionItem(Id + 12, "AfterMeetingKillCooldown", new(0f, 30f, 0.5f), 25f, TabGroup.ImpostorRoles)
AfterMeetingKillCooldown = new FloatOptionItem(Id + 12, "AfterMeetingKillCooldown", new(0f, 180f, 0.5f), 27.5f, TabGroup.ImpostorRoles)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedier])
.SetValueFormat(OptionFormat.Seconds);
}
+4 -4
View File
@@ -71,14 +71,14 @@ internal class Nullifier : RoleBase
cs.CleanserUses++;
cs.SendRPC(target.PlayerId);
break;
case CustomRoles.NiceHacker:
case CustomRoles.Hacker:
if (target.IsModdedClient())
{
NiceHacker.UseLimitSeconds[target.PlayerId] -= NiceHacker.ModdedClientAbilityUseSecondsMultiplier.GetInt();
NiceHacker.SendRPC(target.PlayerId, NiceHacker.UseLimitSeconds[target.PlayerId]);
Hacker.UseLimitSeconds[target.PlayerId] -= Hacker.ModdedClientAbilityUseSecondsMultiplier.GetInt();
Hacker.SendRPC(target.PlayerId, Hacker.UseLimitSeconds[target.PlayerId]);
}
else
NiceHacker.UseLimit[target.PlayerId]--;
Hacker.UseLimit[target.PlayerId]--;
break;
case CustomRoles.SabotageMaster: