diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs
index a95066212..0a8657eb2 100644
--- a/Modules/CustomRolesHelper.cs
+++ b/Modules/CustomRolesHelper.cs
@@ -61,9 +61,9 @@ internal static class CustomRolesHelper
CustomRoles.Puppeteer => CustomRoles.Impostor,
CustomRoles.TimeThief => CustomRoles.Impostor,
CustomRoles.EvilTracker => CustomRoles.Shapeshifter,
- CustomRoles.Paranoia => CustomRoles.Engineer,
+ CustomRoles.Paranoia => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.EngineerTOHE => CustomRoles.Engineer,
- CustomRoles.TimeMaster => CustomRoles.Engineer,
+ CustomRoles.TimeMaster => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.CrewmateTOHE => CustomRoles.Crewmate,
CustomRoles.Cleanser => CustomRoles.Crewmate,
CustomRoles.Miner => CustomRoles.Shapeshifter,
@@ -82,11 +82,11 @@ internal static class CustomRolesHelper
CustomRoles.Express => CustomRoles.Crewmate,
CustomRoles.NiceEraser => CustomRoles.Crewmate,
CustomRoles.TaskManager => CustomRoles.Crewmate,
- CustomRoles.NiceHacker => CustomRoles.Engineer,
+ CustomRoles.NiceHacker => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Spy => CustomRoles.Crewmate,
CustomRoles.Ricochet => CustomRoles.Crewmate,
- CustomRoles.Tether => CustomRoles.Engineer,
- CustomRoles.Doormaster => CustomRoles.Engineer,
+ CustomRoles.Tether => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
+ CustomRoles.Doormaster => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Aid => CustomRoles.Impostor,
CustomRoles.Escapee => CustomRoles.Shapeshifter,
CustomRoles.NiceGuesser => CustomRoles.Crewmate,
@@ -103,12 +103,12 @@ internal static class CustomRolesHelper
CustomRoles.BoobyTrap => CustomRoles.Impostor,
CustomRoles.Scavenger => CustomRoles.Impostor,
CustomRoles.Transporter => CustomRoles.Crewmate,
- CustomRoles.Veteran => CustomRoles.Engineer,
+ CustomRoles.Veteran => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Capitalism => CustomRoles.Impostor,
CustomRoles.Bodyguard => CustomRoles.Crewmate,
- CustomRoles.Grenadier => CustomRoles.Engineer,
- CustomRoles.Lighter => CustomRoles.Engineer,
- CustomRoles.SecurityGuard => CustomRoles.Engineer,
+ CustomRoles.Grenadier => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
+ CustomRoles.Lighter => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
+ CustomRoles.SecurityGuard => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Gangster => CustomRoles.Impostor,
CustomRoles.Cleaner => CustomRoles.Impostor,
CustomRoles.Konan => CustomRoles.Crewmate,
@@ -135,7 +135,7 @@ internal static class CustomRolesHelper
CustomRoles.Swooper => CustomRoles.Impostor,
CustomRoles.Crewpostor => CustomRoles.Engineer,
CustomRoles.Observer => CustomRoles.Crewmate,
- CustomRoles.DovesOfNeace => CustomRoles.Engineer,
+ CustomRoles.DovesOfNeace => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Disperser => CustomRoles.Shapeshifter,
CustomRoles.Camouflager => CustomRoles.Shapeshifter,
CustomRoles.Dazzler => CustomRoles.Shapeshifter,
@@ -148,7 +148,7 @@ internal static class CustomRolesHelper
CustomRoles.Retributionist => CustomRoles.Crewmate,
CustomRoles.Guardian => CustomRoles.Crewmate,
CustomRoles.Addict => CustomRoles.Engineer,
- CustomRoles.Alchemist => CustomRoles.Engineer,
+ CustomRoles.Alchemist => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Chameleon => CustomRoles.Engineer,
CustomRoles.EvilSpirit => CustomRoles.GuardianAngel,
CustomRoles.Lurker => CustomRoles.Impostor,
@@ -176,12 +176,12 @@ internal static class CustomRolesHelper
CustomRoles.Mediumshiper => CustomRoles.CrewmateTOHE,
CustomRoles.Bodyguard => CustomRoles.CrewmateTOHE,
CustomRoles.ParityCop => CustomRoles.CrewmateTOHE,
- CustomRoles.Grenadier => CustomRoles.EngineerTOHE,
- CustomRoles.SecurityGuard => CustomRoles.EngineerTOHE,
- CustomRoles.Lighter => CustomRoles.EngineerTOHE,
- CustomRoles.Ignitor => CustomRoles.EngineerTOHE,
+ CustomRoles.Grenadier => Options.UsePets.GetBool() ? CustomRoles.CrewmateTOHE : CustomRoles.EngineerTOHE,
+ CustomRoles.SecurityGuard => Options.UsePets.GetBool() ? CustomRoles.CrewmateTOHE : CustomRoles.EngineerTOHE,
+ CustomRoles.Lighter => Options.UsePets.GetBool() ? CustomRoles.CrewmateTOHE : CustomRoles.EngineerTOHE,
+ CustomRoles.Ignitor => CustomRoles.CrewmateTOHE,
CustomRoles.Transporter => CustomRoles.CrewmateTOHE,
- CustomRoles.Veteran => CustomRoles.CrewmateTOHE,
+ CustomRoles.Veteran => Options.UsePets.GetBool() ? CustomRoles.CrewmateTOHE : CustomRoles.EngineerTOHE,
CustomRoles.GuardianAngelTOHE => CustomRoles.GuardianAngel,
CustomRoles.Detective => CustomRoles.CrewmateTOHE,
CustomRoles.NiceGuesser => CustomRoles.CrewmateTOHE,
@@ -193,19 +193,19 @@ internal static class CustomRolesHelper
CustomRoles.Ventguard => CustomRoles.EngineerTOHE,
CustomRoles.Express => CustomRoles.CrewmateTOHE,
CustomRoles.NiceEraser => CustomRoles.CrewmateTOHE,
- CustomRoles.TaskManager => CustomRoles.EngineerTOHE, // can't check if player is modded or not
- CustomRoles.NiceHacker => CustomRoles.CrewmateTOHE,
+ CustomRoles.TaskManager => CustomRoles.CrewmateTOHE,
+ CustomRoles.NiceHacker => Options.UsePets.GetBool() ? CustomRoles.CrewmateTOHE : CustomRoles.EngineerTOHE,
CustomRoles.Spy => CustomRoles.CrewmateTOHE,
CustomRoles.Ricochet => CustomRoles.CrewmateTOHE,
CustomRoles.Aid => CustomRoles.CrewmateTOHE,
- CustomRoles.Doormaster => CustomRoles.EngineerTOHE,
- CustomRoles.Tether => CustomRoles.EngineerTOHE,
+ CustomRoles.Doormaster => Options.UsePets.GetBool() ? CustomRoles.CrewmateTOHE : CustomRoles.EngineerTOHE,
+ CustomRoles.Tether => Options.UsePets.GetBool() ? CustomRoles.CrewmateTOHE : CustomRoles.EngineerTOHE,
CustomRoles.Psychic => CustomRoles.CrewmateTOHE,
CustomRoles.Needy => CustomRoles.CrewmateTOHE,
CustomRoles.SuperStar => CustomRoles.CrewmateTOHE,
- CustomRoles.Paranoia => CustomRoles.EngineerTOHE,
+ CustomRoles.Paranoia => Options.UsePets.GetBool() ? CustomRoles.CrewmateTOHE : CustomRoles.EngineerTOHE,
CustomRoles.EngineerTOHE => CustomRoles.EngineerTOHE,
- CustomRoles.TimeMaster => CustomRoles.EngineerTOHE,
+ CustomRoles.TimeMaster => Options.UsePets.GetBool() ? CustomRoles.CrewmateTOHE : CustomRoles.EngineerTOHE,
CustomRoles.CrewmateTOHE => CustomRoles.CrewmateTOHE,
CustomRoles.Doctor => CustomRoles.ScientistTOHE,
CustomRoles.ScientistTOHE => CustomRoles.ScientistTOHE,
@@ -219,7 +219,7 @@ internal static class CustomRolesHelper
CustomRoles.Witness => CustomRoles.CrewmateTOHE,
CustomRoles.Guardian => CustomRoles.CrewmateTOHE,
CustomRoles.Addict => CustomRoles.EngineerTOHE,
- CustomRoles.Alchemist => CustomRoles.EngineerTOHE,
+ CustomRoles.Alchemist => Options.UsePets.GetBool() ? CustomRoles.CrewmateTOHE : CustomRoles.EngineerTOHE,
CustomRoles.Oracle => CustomRoles.CrewmateTOHE,
CustomRoles.Chameleon => CustomRoles.EngineerTOHE,
_ => role.IsImpostor() ? CustomRoles.ImpostorTOHE : CustomRoles.CrewmateTOHE,
diff --git a/Modules/Extensions/IGameManagerEx.cs b/Modules/Extensions/IGameManagerEx.cs
index 74d0c6e4d..468aa8c5b 100644
--- a/Modules/Extensions/IGameManagerEx.cs
+++ b/Modules/Extensions/IGameManagerEx.cs
@@ -5,7 +5,11 @@ namespace TOHE.Modules.Extensions;
public static class IGameManagerEx
{
public static void Set(this BoolOptionNames name, bool value, IGameOptions opt) => opt.SetBool(name, value);
- public static void Set(this BoolOptionNames name, bool value, NormalGameOptionsV07 opt) => opt.SetBool(name, value);
+ public static void Set(this BoolOptionNames name, bool value, NormalGameOptionsV07 opt)
+ {
+ if (name != BoolOptionNames.GhostsDoTasks) opt.SetBool(name, value);
+ }
+
public static void Set(this BoolOptionNames name, bool value, HideNSeekGameOptionsV07 opt) => opt.SetBool(name, value);
public static void Set(this Int32OptionNames name, int value, IGameOptions opt) => opt.SetInt(name, value);
diff --git a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs
index a3c8131d9..aa54ddea8 100644
--- a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs
+++ b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs
@@ -153,6 +153,10 @@ public class PlayerGameOptionsSender : GameOptionsSender
opt.SetFloat(FloatOptionNames.ImpostorLightMod, Gambler.LowVision.GetFloat());
}
break;
+ case CustomRoles.NiceHacker:
+ AURoleOptions.EngineerCooldown = NiceHacker.AbilityCD.GetFloat();
+ AURoleOptions.EngineerInVentMaxTime = 1f;
+ break;
case CustomRoles.Warlock:
AURoleOptions.ShapeshifterCooldown = Main.isCursed ? 1f : Options.DefaultKillCooldown;
AURoleOptions.ShapeshifterDuration = Options.WarlockShiftDuration.GetFloat();
diff --git a/Modules/GameState.cs b/Modules/GameState.cs
index 653ad5e6d..8043c411d 100644
--- a/Modules/GameState.cs
+++ b/Modules/GameState.cs
@@ -483,7 +483,8 @@ public class TaskState
Spy.UseLimit[player.PlayerId] += Spy.SpyAbilityUseGainWithEachTaskCompleted.GetFloat();
break;
case CustomRoles.NiceHacker:
- NiceHacker.UseLimit[player.PlayerId] += NiceHacker.NiceHackerAbilityUseGainWithEachTaskCompleted.GetFloat();
+ if (!player.IsModClient()) NiceHacker.UseLimit[player.PlayerId] += NiceHacker.NiceHackerAbilityUseGainWithEachTaskCompleted.GetFloat();
+ else NiceHacker.UseLimitSeconds[player.PlayerId] += NiceHacker.NiceHackerAbilityUseGainWithEachTaskCompleted.GetInt() * NiceHacker.ModdedClientAbilityUseSecondsMultiplier.GetInt();
break;
}
}
diff --git a/Modules/Utils.cs b/Modules/Utils.cs
index f7ad135a2..ee6769852 100644
--- a/Modules/Utils.cs
+++ b/Modules/Utils.cs
@@ -623,6 +623,8 @@ public static class Utils
break;
case CustomRoles.Alchemist:
ProgressText.Append(Alchemist.GetProgressText(playerId));
+ if (Options.UsePets.GetBool() && Main.AlchemistCD.TryGetValue(playerId, out var time) && !GetPlayerById(playerId).IsModClient())
+ ProgressText.Append(" " + string.Format(GetString("CDPT"), Alchemist.VentCooldown.GetInt() - (GetTimeStamp() - time)));
break;
case CustomRoles.Bandit:
ProgressText.Append(Bandit.GetStealLimit(playerId));
@@ -713,6 +715,8 @@ public static class Utils
else TextColor21 = Color.white;
ProgressText.Append(ColorString(TextColor2, $"- {Completed2}/{taskState2.AllTasksCount}"));
ProgressText.Append(ColorString(TextColor21, $" - {Math.Round(Main.VeteranNumOfUsed[playerId], 1)}"));
+ if (Options.UsePets.GetBool() && Main.VeteranCD.TryGetValue(playerId, out var time2) && !GetPlayerById(playerId).IsModClient())
+ ProgressText.Append(" " + string.Format(GetString("CDPT"), Options.VeteranSkillCooldown.GetInt() - (GetTimeStamp() - time2)));
break;
case CustomRoles.Grenadier:
var taskState3 = Main.PlayerStates?[playerId].GetTaskState();
@@ -728,6 +732,8 @@ public static class Utils
else TextColor31 = Color.white;
ProgressText.Append(ColorString(TextColor3, $"- {Completed3}/{taskState3.AllTasksCount}"));
ProgressText.Append(ColorString(TextColor31, $" - {Math.Round(Main.GrenadierNumOfUsed[playerId], 1)}"));
+ if (Options.UsePets.GetBool() && Main.GrenadierCD.TryGetValue(playerId, out var time3) && !GetPlayerById(playerId).IsModClient())
+ ProgressText.Append(" " + string.Format(GetString("CDPT"), Options.GrenadierSkillCooldown.GetInt() - (GetTimeStamp() - time3)));
break;
case CustomRoles.Divinator:
var taskState4 = Main.PlayerStates?[playerId].GetTaskState();
@@ -756,6 +762,8 @@ public static class Utils
else TextColor51 = Color.white;
ProgressText.Append(ColorString(TextColor5, $"- {Completed5}/{taskState5.AllTasksCount}"));
ProgressText.Append(ColorString(TextColor51, $" - {Math.Round(Main.DovesOfNeaceNumOfUsed[playerId], 1)}"));
+ if (Options.UsePets.GetBool() && Main.DovesOfNeaceCD.TryGetValue(playerId, out var time4) && !GetPlayerById(playerId).IsModClient())
+ ProgressText.Append(" " + string.Format(GetString("CDPT"), Options.DovesOfNeaceCooldown.GetInt() - (GetTimeStamp() - time4)));
break;
case CustomRoles.TimeMaster:
var taskState6 = Main.PlayerStates?[playerId].GetTaskState();
@@ -771,6 +779,8 @@ public static class Utils
else TextColor61 = Color.white;
ProgressText.Append(ColorString(TextColor6, $"- {Completed6}/{taskState6.AllTasksCount}"));
ProgressText.Append(ColorString(TextColor61, $" - {Math.Round(Main.TimeMasterNumOfUsed[playerId], 1)}"));
+ if (Options.UsePets.GetBool() && Main.TimeMasterCD.TryGetValue(playerId, out var time5) && !GetPlayerById(playerId).IsModClient())
+ ProgressText.Append(" " + string.Format(GetString("CDPT"), Options.TimeMasterSkillCooldown.GetInt() - (GetTimeStamp() - time5)));
break;
case CustomRoles.Mediumshiper:
var taskState7 = Main.PlayerStates?[playerId].GetTaskState();
@@ -885,6 +895,8 @@ public static class Utils
else TextColor141 = Color.white;
ProgressText.Append(ColorString(TextColor14, $"- {Completed14}/{taskState14.AllTasksCount}"));
ProgressText.Append(ColorString(TextColor141, $" - {Math.Round(Main.LighterNumOfUsed[playerId], 1)}"));
+ if (Options.UsePets.GetBool() && Main.LighterCD.TryGetValue(playerId, out var time6) && !GetPlayerById(playerId).IsModClient())
+ ProgressText.Append(" " + string.Format(GetString("CDPT"), Options.LighterSkillCooldown.GetInt() - (GetTimeStamp() - time6)));
break;
case CustomRoles.Ventguard:
var taskState15 = Main.PlayerStates?[playerId].GetTaskState();
@@ -914,6 +926,8 @@ public static class Utils
else TextColor161 = Color.white;
ProgressText.Append(ColorString(TextColor16, $"- {Completed16}/{taskState16.AllTasksCount}"));
ProgressText.Append(ColorString(TextColor161, $" - {Math.Round(Main.SecurityGuardNumOfUsed[playerId], 1)}"));
+ if (Options.UsePets.GetBool() && Main.SecurityGuardCD.TryGetValue(playerId, out var time7) && !GetPlayerById(playerId).IsModClient())
+ ProgressText.Append(" " + string.Format(GetString("CDPT"), Options.SecurityGuardSkillCooldown.GetInt() - (GetTimeStamp() - time7)));
break;
//case CustomRoles.Pirate:
// ProgressText.Append(ColorString(GetRoleColor(CustomRoles.Pirate).ShadeColor(0.25f), $"({Pirate.NumWin}/{Pirate.SuccessfulDuelsToWin.GetInt()})"));
@@ -935,6 +949,8 @@ public static class Utils
break;
case CustomRoles.NiceHacker:
ProgressText.Append(NiceHacker.GetProgressText(playerId, comms));
+ if (Options.UsePets.GetBool() && Main.HackerCD.TryGetValue(playerId, out var time8) && !GetPlayerById(playerId).IsModClient())
+ ProgressText.Append(" " + string.Format(GetString("CDPT"), NiceHacker.AbilityCD.GetInt() - (GetTimeStamp() - time8)));
break;
case CustomRoles.RiftMaker:
ProgressText.Append(RiftMaker.GetProgressText());
@@ -947,6 +963,8 @@ public static class Utils
break;
case CustomRoles.Doormaster:
ProgressText.Append(Doormaster.GetProgressText(playerId, comms));
+ if (Options.UsePets.GetBool() && Main.DoormasterCD.TryGetValue(playerId, out var time9) && !GetPlayerById(playerId).IsModClient())
+ ProgressText.Append(" " + string.Format(GetString("CDPT"), Doormaster.VentCooldown.GetInt() - (GetTimeStamp() - time9)));
break;
case CustomRoles.CopyCat:
ProgressText.Append(ColorString(GetRoleColor(CustomRoles.CopyCat).ShadeColor(0.25f), $"({(CopyCat.MiscopyLimit.TryGetValue(playerId, out var count2) ? count2 : 0)})"));
@@ -992,6 +1010,8 @@ public static class Utils
// break;
case CustomRoles.Tether:
ProgressText.Append(Tether.GetProgressText(playerId, comms));
+ if (Options.UsePets.GetBool() && Main.TetherCD.TryGetValue(playerId, out var time10) && !GetPlayerById(playerId).IsModClient())
+ ProgressText.Append(" " + string.Format(GetString("CDPT"), Tether.VentCooldown.GetInt() - (GetTimeStamp() - time10)));
break;
case CustomRoles.Spy:
ProgressText.Append(Spy.GetProgressText(playerId, comms));
@@ -2493,13 +2513,13 @@ public static class Utils
Main.ParanoiaCD.TryAdd(pc.PlayerId, GetTimeStamp());
break;
case CustomRoles.Grenadier:
- Main.GrenadierCD.TryAdd(pc.PlayerId, GetTimeStamp());
+ Main.GrenadierCD.TryAdd(pc.PlayerId, GetTimeStamp() - Options.GrenadierSkillDuration.GetInt());
break;
case CustomRoles.Lighter:
- Main.LighterCD.TryAdd(pc.PlayerId, GetTimeStamp());
+ Main.LighterCD.TryAdd(pc.PlayerId, GetTimeStamp() - Options.LighterSkillDuration.GetInt());
break;
case CustomRoles.SecurityGuard:
- Main.SecurityGuardCD.TryAdd(pc.PlayerId, GetTimeStamp());
+ Main.SecurityGuardCD.TryAdd(pc.PlayerId, GetTimeStamp() - Options.SecurityGuardSkillDuration.GetInt());
break;
case CustomRoles.DovesOfNeace:
Main.DovesOfNeaceCD.TryAdd(pc.PlayerId, GetTimeStamp());
@@ -2508,10 +2528,13 @@ public static class Utils
Main.AlchemistCD.TryAdd(pc.PlayerId, GetTimeStamp());
break;
case CustomRoles.TimeMaster:
- Main.TimeMasterCD.TryAdd(pc.PlayerId, GetTimeStamp());
+ Main.TimeMasterCD.TryAdd(pc.PlayerId, GetTimeStamp() - Options.TimeMasterSkillDuration.GetInt());
break;
case CustomRoles.Veteran:
- Main.VeteranCD.TryAdd(pc.PlayerId, GetTimeStamp());
+ Main.VeteranCD.TryAdd(pc.PlayerId, GetTimeStamp() - Options.VeteranSkillDuration.GetInt());
+ break;
+ case CustomRoles.NiceHacker:
+ Main.HackerCD.TryAdd(pc.PlayerId, GetTimeStamp());
break;
}
}
diff --git a/Patches/HudPatch.cs b/Patches/HudPatch.cs
index 01d522bd7..2bd6adc81 100644
--- a/Patches/HudPatch.cs
+++ b/Patches/HudPatch.cs
@@ -632,14 +632,15 @@ class MapBehaviourShowPatch
{
if (GameStates.IsMeeting) return true;
- if (PlayerControl.LocalPlayer.Is(CustomRoles.NiceHacker) && !NiceHacker.MapHandle(PlayerControl.LocalPlayer, __instance, opts))
- {
- return false;
- }
+ var player = PlayerControl.LocalPlayer;
- if (opts.Mode is MapOptions.Modes.Normal or MapOptions.Modes.Sabotage)
+ if (player.GetCustomRole() == CustomRoles.NiceHacker && NiceHacker.playerIdList.ContainsKey(player.PlayerId))
+ {
+ Logger.Info("Mod Client uses Map", "NiceHacker");
+ NiceHacker.MapHandle(player, __instance, opts);
+ }
+ else if (opts.Mode is MapOptions.Modes.Normal or MapOptions.Modes.Sabotage)
{
- var player = PlayerControl.LocalPlayer;
if (player.Is(CustomRoleTypes.Impostor) || player.Is(CustomRoles.Glitch) || player.Is(CustomRoles.Parasite) || player.Is(CustomRoles.Refugee) || (player.Is(CustomRoles.Jackal) && Jackal.CanUseSabotage.GetBool()) || (player.Is(CustomRoles.Traitor) && Traitor.CanUseSabotage.GetBool()))
opts.Mode = MapOptions.Modes.Sabotage;
else
diff --git a/Patches/PetActionsPatch.cs b/Patches/PetActionsPatch.cs
index bf075d5d3..ec1dca46d 100644
--- a/Patches/PetActionsPatch.cs
+++ b/Patches/PetActionsPatch.cs
@@ -8,12 +8,11 @@ using TOHE.Roles.Impostor;
using static TOHE.Translator;
namespace TOHE;
+
/*
* HUGE THANKS TO
- * ImaMapleTree / 단풍잎
+ * ImaMapleTree / 단풍잎 / Tealeaf
* FOR THE CODE
- *
- * THIS IS JUST SMALL FOR NOW BUT MAY EVENTUALLY BE BIG
*/
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.TryPet))]
@@ -75,6 +74,7 @@ class ExternalRpcPetPatch
}
Doormaster.OnEnterVent(pc);
pc.RpcResetAbilityCooldown();
+ pc.MyPhysics.CancelPet();
break;
case CustomRoles.Tether:
if (Main.TetherCD.ContainsKey(pc.PlayerId))
@@ -88,6 +88,7 @@ class ExternalRpcPetPatch
case CustomRoles.Mayor:
if (Main.MayorUsedButtonCount.TryGetValue(pc.PlayerId, out var count) && count < Options.MayorNumOfUseButton.GetInt() && !Main.MayorCD.ContainsKey(pc.PlayerId))
{
+ pc.MyPhysics.CancelPet();
pc?.ReportDeadBody(null);
}
break;
@@ -102,6 +103,7 @@ class ExternalRpcPetPatch
Utils.SendMessage(GetString("SkillUsedLeft") + (Options.ParanoiaNumOfUseButton.GetInt() - Main.ParaUsedButtonCount[pc.PlayerId]).ToString(), pc.PlayerId);
}, 4.0f, "Skill Remain Message");
}
+ pc.MyPhysics.CancelPet();
pc?.NoCheckStartMeeting(pc?.Data);
}
break;
@@ -122,6 +124,7 @@ class ExternalRpcPetPatch
Main.VeteranCD.TryAdd(pc.PlayerId, Utils.GetTimeStamp());
pc.RpcResetAbilityCooldown();
pc.MarkDirtySettings();
+ pc.MyPhysics.CancelPet();
}
else
{
@@ -155,6 +158,7 @@ class ExternalRpcPetPatch
pc.RpcResetAbilityCooldown();
Main.GrenadierNumOfUsed[pc.PlayerId] -= 1;
Utils.MarkEveryoneDirtySettingsV3();
+ pc.MyPhysics.CancelPet();
}
else
{
@@ -176,6 +180,7 @@ class ExternalRpcPetPatch
pc.RpcResetAbilityCooldown();
Main.LighterNumOfUsed[pc.PlayerId] -= 1;
pc.MarkDirtySettings();
+ pc.MyPhysics.CancelPet();
}
else
{
@@ -196,6 +201,7 @@ class ExternalRpcPetPatch
Main.SecurityGuardCD.TryAdd(pc.PlayerId, Utils.GetTimeStamp());
pc.RpcResetAbilityCooldown();
Main.SecurityGuardNumOfUsed[pc.PlayerId] -= 1;
+ pc.MyPhysics.CancelPet();
}
else
{
@@ -232,11 +238,13 @@ class ExternalRpcPetPatch
pc.Notify(string.Format(GetString("DovesOfNeaceOnGuard"), Main.DovesOfNeaceNumOfUsed[pc.PlayerId]));
Main.DovesOfNeaceCD.TryAdd(pc.PlayerId, Utils.GetTimeStamp());
pc.RpcResetAbilityCooldown();
+ pc.MyPhysics.CancelPet();
}
break;
case CustomRoles.Alchemist:
Alchemist.OnEnterVent(pc, 0, true);
pc.RpcResetAbilityCooldown();
+ pc.MyPhysics.CancelPet();
break;
case CustomRoles.TimeMaster:
if (Main.TimeMasterNumOfUsed[pc.PlayerId] >= 1)
@@ -248,12 +256,12 @@ class ExternalRpcPetPatch
}
Main.TimeMasterNumOfUsed[pc.PlayerId] -= 1;
Main.TimeMasterInProtect.Remove(pc.PlayerId);
- Main.TimeMasterNumOfUsed[pc.PlayerId] -= 1;
Main.TimeMasterInProtect.Add(pc.PlayerId, Utils.GetTimeStamp());
//if (!pc.IsModClient()) pc.RpcGuardAndKill(pc);
pc.Notify(GetString("TimeMasterOnGuard"), Options.TimeMasterSkillDuration.GetFloat());
Main.TimeMasterCD.TryAdd(pc.PlayerId, Utils.GetTimeStamp());
pc.RpcResetAbilityCooldown();
+ pc.MyPhysics.CancelPet();
foreach (var player in Main.AllPlayerControls)
{
if (Main.TimeMasterBackTrack.ContainsKey(player.PlayerId))
@@ -275,6 +283,11 @@ class ExternalRpcPetPatch
pc.Notify(GetString("OutOfAbilityUsesDoMoreTasks"));
}
break;
+ case CustomRoles.NiceHacker:
+ NiceHacker.OnEnterVent(pc);
+ pc.RpcResetAbilityCooldown();
+ pc.MyPhysics.CancelPet();
+ break;
}
}
diff --git a/Patches/PlayerContorolPatch.cs b/Patches/PlayerContorolPatch.cs
index 88f48900f..7d1fc6dbc 100644
--- a/Patches/PlayerContorolPatch.cs
+++ b/Patches/PlayerContorolPatch.cs
@@ -14,7 +14,6 @@ using TOHE.Roles.Impostor;
using TOHE.Roles.Neutral;
using UnityEngine;
using static TOHE.Translator;
-using static UnityEngine.ParticleSystem.PlaybackState;
namespace TOHE;
@@ -1955,67 +1954,97 @@ class FixedUpdatePatch
if (Main.DoormasterCD.TryGetValue(player.PlayerId, out var dm) && dm + Doormaster.VentCooldown.GetInt() < Utils.GetTimeStamp())
{
Main.DoormasterCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.DoormasterCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
break;
case CustomRoles.Tether:
if (Main.TetherCD.TryGetValue(player.PlayerId, out var th) && th + Tether.VentCooldown.GetInt() < Utils.GetTimeStamp())
{
Main.TetherCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.TetherCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
break;
case CustomRoles.Mayor:
if (Main.MayorCD.TryGetValue(player.PlayerId, out var my) && my + Options.DefaultKillCooldown < Utils.GetTimeStamp())
{
Main.MayorCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.MayorCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
break;
case CustomRoles.Paranoia:
if (Main.ParanoiaCD.TryGetValue(player.PlayerId, out var pn) && pn + Options.ParanoiaVentCooldown.GetInt() < Utils.GetTimeStamp())
{
Main.ParanoiaCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.ParanoiaCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
break;
case CustomRoles.Grenadier:
if (Main.GrenadierCD.TryGetValue(player.PlayerId, out var gd) && gd + Options.GrenadierSkillCooldown.GetInt() + Options.GrenadierSkillDuration.GetInt() < Utils.GetTimeStamp())
{
Main.GrenadierCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.GrenadierCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
break;
case CustomRoles.Lighter:
if (Main.LighterCD.TryGetValue(player.PlayerId, out var lt) && lt + Options.LighterSkillCooldown.GetInt() + Options.LighterSkillDuration.GetInt() < Utils.GetTimeStamp())
{
Main.LighterCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.LighterCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
break;
case CustomRoles.SecurityGuard:
if (Main.SecurityGuardCD.TryGetValue(player.PlayerId, out var sg) && sg + Options.SecurityGuardSkillCooldown.GetInt() + Options.SecurityGuardSkillDuration.GetInt() < Utils.GetTimeStamp())
{
Main.SecurityGuardCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.SecurityGuardCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
break;
case CustomRoles.DovesOfNeace:
if (Main.DovesOfNeaceCD.TryGetValue(player.PlayerId, out var don) && don + Options.DovesOfNeaceCooldown.GetInt() < Utils.GetTimeStamp())
{
Main.DovesOfNeaceCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.DovesOfNeaceCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
break;
case CustomRoles.Alchemist:
if (Main.AlchemistCD.TryGetValue(player.PlayerId, out var ac) && ac + Alchemist.VentCooldown.GetInt() < Utils.GetTimeStamp())
{
Main.AlchemistCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.AlchemistCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
break;
case CustomRoles.TimeMaster:
if (Main.TimeMasterCD.TryGetValue(player.PlayerId, out var tm) && tm + Options.TimeMasterSkillCooldown.GetInt() + Options.TimeMasterSkillDuration.GetInt() < Utils.GetTimeStamp())
{
Main.TimeMasterCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.TimeMasterCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
break;
case CustomRoles.Veteran:
if (Main.VeteranCD.TryGetValue(player.PlayerId, out var vr) && vr + Options.VeteranSkillCooldown.GetInt() + Options.VeteranSkillDuration.GetInt() < Utils.GetTimeStamp())
{
Main.VeteranCD.Remove(player.PlayerId);
+ Utils.NotifyRoles(SpecifySeer: player);
}
+ if (Main.VeteranCD.ContainsKey(player.PlayerId)) Utils.NotifyRoles(SpecifySeer: player);
+ break;
+ case CustomRoles.NiceHacker:
+ if (Main.HackerCD.TryGetValue(player.PlayerId, out var nh) && nh + NiceHacker.AbilityCD.GetInt() < Utils.GetTimeStamp())
+ {
+ Main.HackerCD.Remove(player.PlayerId);
+ if (!player.IsModClient()) Utils.NotifyRoles(SpecifySeer: player);
+ }
+ if (Main.HackerCD.ContainsKey(player.PlayerId) && !player.IsModClient()) Utils.NotifyRoles(SpecifySeer: player);
break;
}
}
@@ -2310,6 +2339,7 @@ class FixedUpdatePatch
if (player.Is(CustomRoles.Wraith)) Wraith.OnFixedUpdate(player);
if (player.Is(CustomRoles.Chameleon)) Chameleon.OnFixedUpdate(player);
if (player.Is(CustomRoles.Werewolf)) Werewolf.OnFixedUpdate(player);
+ if (player.Is(CustomRoles.NiceHacker)) NiceHacker.OnFixedUpdate(player);
if (player.Is(CustomRoles.Alchemist)) Alchemist.OnFixedUpdate(player);
if (player.Is(CustomRoles.BloodKnight)) BloodKnight.OnFixedUpdate(player);
if (player.Is(CustomRoles.Spiritcaller)) Spiritcaller.OnFixedUpdate(player);
@@ -2974,6 +3004,7 @@ class EnterVentPatch
if (Tether.IsEnable) Tether.OnEnterVent(pc, __instance.Id);
if (Werewolf.IsEnable) Werewolf.OnEnterVent(pc);
if (Lurker.IsEnable()) Lurker.OnEnterVent(pc);
+ if (NiceHacker.IsEnable) NiceHacker.OnEnterVent(pc);
if (Doormaster.IsEnable) Doormaster.OnEnterVent(pc);
if (pc.GetCustomRole() == CustomRoles.Ventguard)
@@ -3111,7 +3142,6 @@ class EnterVentPatch
{
Main.TimeMasterNumOfUsed[pc.PlayerId] -= 1;
Main.TimeMasterInProtect.Remove(pc.PlayerId);
- Main.TimeMasterNumOfUsed[pc.PlayerId] -= 1;
Main.TimeMasterInProtect.Add(pc.PlayerId, Utils.GetTimeStamp());
//if (!pc.IsModClient()) pc.RpcGuardAndKill(pc);
pc.Notify(GetString("TimeMasterOnGuard"), Options.TimeMasterSkillDuration.GetFloat());
diff --git a/Resources/String.csv b/Resources/String.csv
index 723480216..8904ed162 100644
--- a/Resources/String.csv
+++ b/Resources/String.csv
@@ -1387,7 +1387,7 @@
"NotifyGodAlive","如果神存活则在会议上通知所有人","Inform players at meetings that God is still alive","Сообщать игрокам на встрече что Дьявол ещё жив","若神存活則在會議上通知所有人","如果神存活则在会议上通知所有人"
"TransporterTeleportMax","传送次数上限","Max number of teleports","Максимальное колличество телепортов","傳送次數上限","传送次数上限"
"TriggerKill","击杀","Kill","Убийство","殺死","击杀"
-"UsePets","","Crewmates use Pet button to activate their ability when possible","","",""
+"UsePets","","Crewmates Use Pet button instead of Vent","","",""
"AbilityOnCooldown","","Ability on cooldown!","","",""
"KillCooldownOnStrangle","","Kill Cooldown after Strangling","","",""
"CDPT","","CD: {0}s","","",""
@@ -2503,13 +2503,13 @@
"VentBlockSuccess","","This vent is now blocked","","",""
"## Hacker"
-"Hacker","","Hacker","","",""
-"HackerInfo","","Watch Admin Table from anywhere","","",""
-"HackerInfoLong","","(Hacker):\nThis role 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 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","","",""
-
+"NiceHacker","","Hacker","","",""
+"NiceHackerInfo","","Watch Admin Table from anywhere","","",""
+"NiceHackerInfoLong","","(Hacker):\nThis role 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 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","","",""
"AbilityChargesWhenFinishedTasks","","Ability Use Gains every 5s when tasks are done","","",""
@@ -2576,7 +2576,17 @@
"GamblerIgnoreCursedWolfAndJinx","","Kill Cursed Wolf and Jinx","","",""
"GamblerIgnoreCursedWolfAndJinx","","Kill Pestilence","","",""
"GamblerPositiveEffectChance","","Positive Effect Chance","","",""
-
+"GamblerGet.DelayedKill","","Effect: Delayed Kill ({0}s)","","",""
+"GamblerGet.Shield","","Effect: Temporary Shield ({0}s)","","",""
+"GamblerGet.NoLunge","","Effect: No Lunge","","",""
+"GamblerGet.Swap","","Effect: Swap Places with Someone","","",""
+"GamblerGet.IgnoreDefense","","Effect: Break Through Defense","","",""
+"GamblerGet.LowKCD","","Effect: Lower Kill Cooldown ({0}s)","","",""
+"GamblerGet.Speedup","","Effect: Higher Speed ({1}x, for {0}s)","","",""
+"GamblerGet.BSR","","Effect: Self-Report (in {0}s)","","",""
+"GamblerGet.Freeze","","Effect: Freeze (for {0}s)","","",""
+"GamblerGet.LowVision","","Effect: Lower Vision ({1}x, for {0}s)","","",""
+"GamblerGet.HighKCD","","Effect: Higher Kill Cooldown ({0}s)","","",""
"## Hitman"
"Hitman","","Hitman","","",""
diff --git a/Roles/Crewmate/NiceHacker.cs b/Roles/Crewmate/NiceHacker.cs
index 4a23c6005..22555ca20 100644
--- a/Roles/Crewmate/NiceHacker.cs
+++ b/Roles/Crewmate/NiceHacker.cs
@@ -4,8 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
- using TOHE.Modules;
- using UnityEngine;
+ using TOHE;
using static TOHE.Options;
using static TOHE.Translator;
using static TOHE.Utils;
@@ -13,9 +12,11 @@
public static class NiceHacker
{
private static readonly int Id = 641000;
- private static Dictionary playerIdList = new();
+ public static Dictionary playerIdList = new();
public static Dictionary UseLimit = new();
- private static Dictionary abilityInUse = new();
+ public static Dictionary UseLimitSeconds = new();
+
+ private static Dictionary LastUpdate = new();
public static OptionItem AbilityCD;
public static OptionItem UseLimitOpt;
@@ -27,34 +28,36 @@
public static void SetupCustomOption()
{
- SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Hacker, 1);
- AbilityCD = FloatOptionItem.Create(Id + 10, "AbilityCD", new(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
+ SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.NiceHacker, 1);
+ AbilityCD = FloatOptionItem.Create(Id + 10, "AbilityCD", new(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
.SetValueFormat(OptionFormat.Seconds);
- UseLimitOpt = IntegerOptionItem.Create(Id + 11, "AbilityUseLimit", new(1, 20, 1), 2, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
+ UseLimitOpt = IntegerOptionItem.Create(Id + 11, "AbilityUseLimit", new(1, 20, 1), 2, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
.SetValueFormat(OptionFormat.Times);
NiceHackerAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 12, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, false)
- .SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
+ .SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
.SetValueFormat(OptionFormat.Times);
AbilityChargesWhenFinishedTasks = FloatOptionItem.Create(Id + 13, "AbilityChargesWhenFinishedTasks", new(0f, 5f, 0.1f), 0.2f, TabGroup.CrewmateRoles, false)
- .SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
+ .SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
.SetValueFormat(OptionFormat.Times);
- ModdedClientAbilityUseSecondsMultiplier = FloatOptionItem.Create(Id + 14, "HackerModdedClientAbilityUseSecondsMultiplier", new(0f, 70f, 1f), 3f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
+ ModdedClientAbilityUseSecondsMultiplier = FloatOptionItem.Create(Id + 14, "NiceHackerModdedClientAbilityUseSecondsMultiplier", new(0f, 70f, 1f), 3f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
.SetValueFormat(OptionFormat.Seconds);
- ModdedClientCanMoveWhileViewingMap = BooleanOptionItem.Create(Id + 15, "HackerModdedClientCanMoveWhileViewingMap", false, TabGroup.CrewmateRoles, false)
+ ModdedClientCanMoveWhileViewingMap = BooleanOptionItem.Create(Id + 15, "NiceHackerModdedClientCanMoveWhileViewingMap", false, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker]);
- VanillaClientSeesInfoFor = FloatOptionItem.Create(Id + 16, "HackerVanillaClientSeesInfoFor", new(0f, 70f, 1f), 4f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Hacker])
+ VanillaClientSeesInfoFor = FloatOptionItem.Create(Id + 16, "NiceHackerVanillaClientSeesInfoFor", new(0f, 70f, 1f), 4f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.NiceHacker])
.SetValueFormat(OptionFormat.Seconds);
}
public static void Init()
{
playerIdList = new();
UseLimit = new();
- abilityInUse = new();
+ UseLimitSeconds = new();
+ LastUpdate = new();
}
public static void Add(byte playerId)
{
playerIdList.TryAdd(playerId, GetPlayerById(playerId).IsModClient());
- UseLimit.Add(playerId, UseLimitOpt.GetInt());
+ if (!GetPlayerById(playerId).IsModClient()) UseLimit.Add(playerId, UseLimitOpt.GetInt());
+ else UseLimitSeconds.Add(playerId, UseLimitOpt.GetInt() * ModdedClientAbilityUseSecondsMultiplier.GetInt());
}
public static bool IsEnable => playerIdList.Any();
public static void OnEnterVent(PlayerControl pc)
@@ -65,15 +68,22 @@
if (UseLimit[pc.PlayerId] >= 1)
{
- UseLimit[pc.PlayerId] -= 1;
- Main.HackerCD.TryAdd(pc.PlayerId, GetTimeStamp());
- var list = ExtendedPlayerControl.GetAllPlayerLocationsCount();
- var sb = new StringBuilder();
- foreach (var location in list)
+ if (Main.HackerCD.ContainsKey(pc.PlayerId))
{
- sb.Append($"\n{location.Key}: {location.Value}");
+ pc.Notify(GetString("AbilityOnCooldown"));
+ }
+ else
+ {
+ UseLimit[pc.PlayerId] -= 1;
+ Main.HackerCD.TryAdd(pc.PlayerId, GetTimeStamp());
+ var list = ExtendedPlayerControl.GetAllPlayerLocationsCount();
+ var sb = new StringBuilder();
+ foreach (var location in list)
+ {
+ sb.Append($"\n{location.Key}: {location.Value}");
+ }
+ pc.Notify(sb.ToString(), VanillaClientSeesInfoFor.GetFloat());
}
- pc.Notify(sb.ToString(), VanillaClientSeesInfoFor.GetFloat());
}
else
{
@@ -84,51 +94,79 @@
{
if (pc == null) return;
if (!pc.Is(CustomRoles.NiceHacker)) return;
+ if (GameStates.IsMeeting) return;
- if (pc.GetPlayerTaskState().IsTaskFinished)
+ if (Main.PlayerStates[pc.PlayerId].GetTaskState().IsTaskFinished)
{
-
+ LastUpdate.TryAdd(pc.PlayerId, GetTimeStamp());
+ if (LastUpdate[pc.PlayerId] + 5 < GetTimeStamp())
+ {
+ if (pc.IsModClient()) UseLimitSeconds[pc.PlayerId] += AbilityChargesWhenFinishedTasks.GetFloat() * ModdedClientAbilityUseSecondsMultiplier.GetInt();
+ else UseLimit[pc.PlayerId] += AbilityChargesWhenFinishedTasks.GetFloat();
+ LastUpdate[pc.PlayerId] = GetTimeStamp();
+ }
}
}
- public static bool MapHandle(PlayerControl pc, MapBehaviour map, MapOptions opts)
+ public static void MapHandle(PlayerControl pc, MapBehaviour map, MapOptions opts)
{
- if (pc == null) return true;
- if (map == null) return true;
- if (opts == null) return true;
+ if (pc.GetCustomRole() != CustomRoles.Hacker) return;
- if (!pc.Is(CustomRoles.Hacker)) return true;
+ map.countOverlayAllowsMovement = ModdedClientCanMoveWhileViewingMap.GetBool();
- if (UseLimit[pc.PlayerId] >= 1)
+ if (UseLimitSeconds[pc.PlayerId] >= 1)
{
- UseLimit[pc.PlayerId] -= 1;
+ UseLimitSeconds[pc.PlayerId] -= 1; // Remove 1s for opening the map, so they can't utilize spamming
opts.Mode = MapOptions.Modes.CountOverlay;
- abilityInUse.TryAdd(pc.PlayerId, GetTimeStamp());
+ _ = new LateTask(() => { MapCountdown(pc, map, opts, (int)UseLimitSeconds[pc.PlayerId]); }, 1f, "NiceHacker.StartCountdown");
}
else
{
opts.Mode = MapOptions.Modes.Normal;
pc.Notify(GetString("OutOfAbilityUsesDoMoreTasks"));
}
+
+ return;
+ }
+ public static void MapCountdown(PlayerControl pc, MapBehaviour map, MapOptions opts, int seconds)
+ {
+ if (!map.IsOpen)
+ {
+ return;
+ }
+ if (seconds <= 0)
+ {
+ map.Close();
+ pc.Notify(GetString("OutOfAbilityUsesDoMoreTasks"));
+ opts.Mode = MapOptions.Modes.Normal;
+ return;
+ }
+ UseLimitSeconds[pc.PlayerId] -= 1;
+ new LateTask(() => { MapCountdown(pc, map, opts, seconds - 1); }, 1f, "NiceHackerAbilityCountdown");
}
public static string GetHudText(PlayerControl pc)
{
if (pc == null) return string.Empty;
+ if (!pc.Is(CustomRoles.NiceHacker)) return string.Empty;
+
+ return $"{GetString("NiceHackerAbilitySecondsLeft")}: {Math.Round(UseLimitSeconds[pc.PlayerId])}s";
}
public static string GetProgressText(byte playerId, bool comms)
{
+ if (GetPlayerById(playerId).IsModClient()) return string.Empty;
+
var sb = new StringBuilder();
var taskState = Main.PlayerStates?[playerId].GetTaskState();
- Color TextColor;
- var TaskCompleteColor = Color.green;
- var NonCompleteColor = Color.yellow;
+ UnityEngine.Color TextColor;
+ var TaskCompleteColor = UnityEngine.Color.green;
+ var NonCompleteColor = UnityEngine.Color.yellow;
var NormalColor = taskState.IsTaskFinished ? TaskCompleteColor : NonCompleteColor;
- TextColor = comms ? Color.gray : NormalColor;
+ TextColor = comms ? UnityEngine.Color.gray : NormalColor;
string Completed = comms ? "?" : $"{taskState.CompletedTasksCount}";
- Color TextColor1;
- if (UseLimit[playerId] < 1) TextColor1 = Color.red;
- else TextColor1 = Color.white;
+ UnityEngine.Color TextColor1;
+ if (UseLimit[playerId] < 1) TextColor1 = UnityEngine.Color.red;
+ else TextColor1 = UnityEngine.Color.white;
sb.Append(ColorString(TextColor, $"- {Completed}/{taskState.AllTasksCount}"));
sb.Append(ColorString(TextColor1, $" - {Math.Round(UseLimit[playerId], 1)}"));
diff --git a/Roles/Impostor/Gambler.cs b/Roles/Impostor/Gambler.cs
index 68ae87782..6095d9bed 100644
--- a/Roles/Impostor/Gambler.cs
+++ b/Roles/Impostor/Gambler.cs
@@ -112,11 +112,11 @@ namespace TOHE.Roles.Impostor
switch (EffectID)
{
case 1: // Delayed kill
- killer.Notify(GetString("GamblerGet.DelayedKill"));
+ killer.Notify(string.Format(GetString("GamblerGet.DelayedKill"), KillDelay.GetInt()));
waitingDelayedKills.TryAdd(target.PlayerId, GetTimeStamp());
return false;
case 2: // Shield
- killer.Notify(GetString("GamblerGet.Shield"));
+ killer.Notify(string.Format(GetString("GamblerGet.Shield"), ShieldDur.GetInt()));
isShielded.TryAdd(killer.PlayerId, GetTimeStamp());
break;
case 3: // No lunge (Swift kill)
@@ -157,14 +157,14 @@ namespace TOHE.Roles.Impostor
return false;
}
case 6: // Low KCD
- killer.Notify(GetString("GamblerGet.LowKCD"));
+ killer.Notify(string.Format(GetString("GamblerGet.LowKCD"), LowKCD.GetFloat()));
_ = new LateTask(() =>
{
killer.SetKillCooldown(LowKCD.GetFloat());
}, 0.1f, "Gambler SetLowKCD");
break;
case 7: // Speed
- killer.Notify(GetString("GamblerGet.Speedup"));
+ killer.Notify(string.Format(GetString("GamblerGet.Speedup"), SpeedDur.GetInt(), Speed.GetFloat()));
isSpeedChange.TryAdd(killer.PlayerId, (Main.AllPlayerSpeed[killer.PlayerId], GetTimeStamp()));
Main.AllPlayerSpeed[killer.PlayerId] = Speed.GetFloat();
killer.SyncSettings();
@@ -183,23 +183,23 @@ namespace TOHE.Roles.Impostor
var delay = Math.Max(0.15f, BSRDelay.GetFloat());
if (delay >= 1f)
{
- killer.Notify(GetString("GamblerGet.BSR"));
+ killer.Notify(string.Format(GetString("GamblerGet.BSR"), BSRDelay.GetInt()));
}
_ = new LateTask(() => { if (GameStates.IsInTask) killer.CmdReportDeadBody(target.Data); }, delay, "Gambler Self Report");
break;
case 2: // Freeze
- killer.Notify(GetString("GamblerGet.Freeze"));
+ killer.Notify(string.Format(GetString("GamblerGet.Freeze"), FreezeDur.GetInt()));
isSpeedChange.TryAdd(killer.PlayerId, (Main.AllPlayerSpeed[killer.PlayerId], GetTimeStamp()));
Main.AllPlayerSpeed[killer.PlayerId] = Main.MinSpeed;
killer.SyncSettings();
break;
case 3: // Low vision
- killer.Notify(GetString("GamblerGet.LowVision"));
+ killer.Notify(string.Format(GetString("GamblerGet.LowVision"), LowVisionDur.GetInt(), LowVision.GetFloat()));
isVisionChange.TryAdd(killer.PlayerId, GetTimeStamp());
killer.SyncSettings();
break;
case 4: // High KCD
- killer.Notify(GetString("GamblerGet.HighKCD"));
+ killer.Notify(string.Format(GetString("GamblerGet.HighKCD"), HighKCD.GetFloat()));
_ = new LateTask(() =>
{
killer.SetKillCooldown(HighKCD.GetFloat());
diff --git a/TOHE.csproj b/TOHE.csproj
index fa6581100..91525588a 100644
--- a/TOHE.csproj
+++ b/TOHE.csproj
@@ -7,7 +7,7 @@
Town Of Host Edited
KARPED1EM
latest
- D:\Epic Games\AmongUs
+ E:\Program Files\AmongUs
true
diff --git a/main.cs b/main.cs
index 712034935..600e7aec4 100644
--- a/main.cs
+++ b/main.cs
@@ -33,8 +33,8 @@ public class Main : BasePlugin
public static ConfigEntry DebugKeyInput { get; private set; }
public static readonly string MainMenuText = " ";
public const string PluginGuid = "com.gurge44.toheplus";
- public const string PluginVersion = "1.0.7";
- public const string PluginDisplayVersion = "1.0.7";
+ public const string PluginVersion = "1.1.0";
+ public const string PluginDisplayVersion = "1.1.0";
public const int PluginCreate = 3;
public const bool Canary = false;