mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
Finish Door Master, Ricochet, Spy, Tether and Aid
This commit is contained in:
1 parent
0b9d767a51
commit
a8f1d0c985
26 files changed
+541
-62
No files matched your search
@@ -471,7 +471,7 @@ static class ExtendedPlayerControl
|
||||
CustomRoles.Pelican => pc.IsAlive(),
|
||||
CustomRoles.Arsonist => Options.ArsonistCanIgniteAnytime.GetBool() ? Utils.GetDousedPlayerCount(pc.PlayerId).Item1 < Options.ArsonistMaxPlayersToIgnite.GetInt() : !pc.IsDouseDone(),
|
||||
CustomRoles.Revolutionist => !pc.IsDrawDone(),
|
||||
CustomRoles.SwordsMan => pc.IsAlive(),
|
||||
CustomRoles.SwordsMan => pc.IsAlive() && !SwordsMan.IsKilled(pc.PlayerId),
|
||||
CustomRoles.Jackal => pc.IsAlive(),
|
||||
CustomRoles.Sidekick => pc.IsAlive(),
|
||||
CustomRoles.HexMaster => pc.IsAlive(),
|
||||
@@ -502,6 +502,7 @@ static class ExtendedPlayerControl
|
||||
CustomRoles.Nuker => false,
|
||||
CustomRoles.Innocent => pc.IsAlive(),
|
||||
//CustomRoles.Counterfeiter => Counterfeiter.CanUseKillButton(pc.PlayerId),
|
||||
CustomRoles.Aid => pc.IsAlive() && Aid.UseLimit[pc.PlayerId] >= 1,
|
||||
CustomRoles.Witness => pc.IsAlive(),
|
||||
CustomRoles.Pursuer => Pursuer.CanUseKillButton(pc.PlayerId),
|
||||
CustomRoles.Morphling => Morphling.CanUseKillButton(pc.PlayerId),
|
||||
@@ -509,7 +510,7 @@ static class ExtendedPlayerControl
|
||||
CustomRoles.Medic => Medic.CanUseKillButton(pc.PlayerId),
|
||||
CustomRoles.Gamer => pc.IsAlive(),
|
||||
CustomRoles.DarkHide => DarkHide.CanUseKillButton(pc),
|
||||
CustomRoles.Provocateur => pc.IsAlive(),
|
||||
CustomRoles.Provocateur => pc.IsAlive() && !Main.Provoked.ContainsKey(pc.PlayerId),
|
||||
CustomRoles.Assassin => Assassin.CanUseKillButton(pc),
|
||||
CustomRoles.Undertaker => Undertaker.CanUseKillButton(pc),
|
||||
CustomRoles.BloodKnight => pc.IsAlive(),
|
||||
@@ -633,6 +634,7 @@ static class ExtendedPlayerControl
|
||||
CustomRoles.Innocent or
|
||||
CustomRoles.Pelican or
|
||||
//CustomRoles.Counterfeiter or
|
||||
CustomRoles.Aid or
|
||||
CustomRoles.Pursuer or
|
||||
CustomRoles.Revolutionist or
|
||||
CustomRoles.FFF or
|
||||
@@ -878,6 +880,9 @@ static class ExtendedPlayerControl
|
||||
//case CustomRoles.Counterfeiter:
|
||||
// Counterfeiter.SetKillCooldown(player.PlayerId);
|
||||
// break;
|
||||
case CustomRoles.Aid:
|
||||
Aid.SetKillCooldown(player.PlayerId);
|
||||
break;
|
||||
case CustomRoles.Witness:
|
||||
Main.AllPlayerKillCooldown[player.PlayerId] = Options.WitnessCD.GetFloat();
|
||||
break;
|
||||
|
||||
@@ -187,6 +187,7 @@ public class PlayerGameOptionsSender : GameOptionsSender
|
||||
case CustomRoles.Jailor:
|
||||
case CustomRoles.Deputy:
|
||||
//case CustomRoles.Counterfeiter:
|
||||
case CustomRoles.Aid:
|
||||
case CustomRoles.Witness:
|
||||
case CustomRoles.Succubus:
|
||||
case CustomRoles.CursedSoul:
|
||||
@@ -204,6 +205,14 @@ public class PlayerGameOptionsSender : GameOptionsSender
|
||||
case CustomRoles.Refugee:
|
||||
opt.SetVision(true);
|
||||
break;
|
||||
case CustomRoles.Doormaster:
|
||||
AURoleOptions.EngineerCooldown = Doormaster.VentCooldown.GetFloat();
|
||||
AURoleOptions.EngineerInVentMaxTime = 1f;
|
||||
break;
|
||||
case CustomRoles.Tether:
|
||||
AURoleOptions.EngineerCooldown = Tether.VentCooldown.GetFloat();
|
||||
AURoleOptions.EngineerInVentMaxTime = 1f;
|
||||
break;
|
||||
case CustomRoles.Monitor:
|
||||
AURoleOptions.EngineerCooldown = 0f;
|
||||
AURoleOptions.EngineerInVentMaxTime = 0f;
|
||||
|
||||
@@ -476,6 +476,12 @@ public class TaskState
|
||||
case CustomRoles.Ricochet:
|
||||
Ricochet.UseLimit[player.PlayerId] += Ricochet.RicochetAbilityUseGainWithEachTaskCompleted.GetFloat();
|
||||
break;
|
||||
case CustomRoles.Tether:
|
||||
Tether.UseLimit[player.PlayerId] += Tether.TetherAbilityUseGainWithEachTaskCompleted.GetFloat();
|
||||
break;
|
||||
case CustomRoles.Spy:
|
||||
Spy.UseLimit[player.PlayerId] += Spy.SpyAbilityUseGainWithEachTaskCompleted.GetFloat();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (player.Is(CustomRoles.Express) && player.IsAlive())
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Hazel;
|
||||
using TOHE.Roles.Crewmate;
|
||||
using TOHE.Roles.Impostor;
|
||||
using TOHE.Roles.Neutral;
|
||||
|
||||
@@ -88,8 +89,9 @@ public static class NameColorManager
|
||||
if (seer.Is(CustomRoles.BountyHunter) && BountyHunter.GetTarget(seer) == target.PlayerId) color = "000000";
|
||||
|
||||
if (seer.Is(CustomRoles.Pyromaniac) && Pyromaniac.DousedList.Contains(target.PlayerId)) color = "#BA4A00";
|
||||
|
||||
if (seer.Is(CustomRoles.Glitch) && Glitch.hackedIdList.ContainsKey(target.PlayerId)) color = Main.roleColors[CustomRoles.Glitch];
|
||||
if (seer.Is(CustomRoles.Aid) && Aid.ShieldedPlayers.ContainsKey(target.PlayerId)) color = Main.roleColors[CustomRoles.Aid];
|
||||
if (seer.Is(CustomRoles.Spy) && Spy.SpyRedNameList.ContainsKey(target.PlayerId)) color = "#BA4A00";
|
||||
|
||||
if (seer.Is(CustomRoles.Refugee) && target.Is(CustomRoleTypes.Impostor)) color = Main.roleColors[CustomRoles.ImpostorTOHE];
|
||||
if (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoles.Refugee)) color = Main.roleColors[CustomRoles.Refugee];
|
||||
|
||||
@@ -1317,6 +1317,12 @@ public static class Options
|
||||
Doormaster.SetupCustomOption();
|
||||
RoleLoadingText = "Crewmate roles\nRicochet";
|
||||
Ricochet.SetupCustomOption();
|
||||
RoleLoadingText = "Crewmate roles\nAid";
|
||||
Aid.SetupCustomOption();
|
||||
RoleLoadingText = "Crewmate roles\nTether";
|
||||
Tether.SetupCustomOption();
|
||||
RoleLoadingText = "Crewmate roles\nSpy";
|
||||
Spy.SetupCustomOption();
|
||||
RoleLoadingText = "Crewmate roles\nExpress";
|
||||
SetupRoleOptions(5585, TabGroup.CrewmateRoles, CustomRoles.Express);
|
||||
ExpressSpeed = FloatOptionItem.Create(5587, "ExpressSpeed", new(0.25f, 5f, 0.25f), 1.5f, TabGroup.CrewmateRoles, false)
|
||||
|
||||
@@ -900,6 +900,12 @@ internal static class RPC
|
||||
//case CustomRoles.Counterfeiter:
|
||||
// Counterfeiter.Add(targetId);
|
||||
// break;
|
||||
case CustomRoles.Tether:
|
||||
Tether.Add(targetId);
|
||||
break;
|
||||
case CustomRoles.Aid:
|
||||
Aid.Add(targetId);
|
||||
break;
|
||||
case CustomRoles.Pursuer:
|
||||
Pursuer.Add(targetId);
|
||||
break;
|
||||
@@ -915,6 +921,12 @@ internal static class RPC
|
||||
case CustomRoles.Divinator:
|
||||
Divinator.Add(targetId);
|
||||
break;
|
||||
case CustomRoles.Doormaster:
|
||||
Doormaster.Add(targetId);
|
||||
break;
|
||||
case CustomRoles.Ricochet:
|
||||
Ricochet.Add(targetId);
|
||||
break;
|
||||
case CustomRoles.Oracle:
|
||||
Oracle.Add(targetId);
|
||||
break;
|
||||
@@ -946,6 +958,9 @@ internal static class RPC
|
||||
case CustomRoles.Eraser:
|
||||
Eraser.Add(targetId);
|
||||
break;
|
||||
case CustomRoles.Spy:
|
||||
Spy.Add(targetId);
|
||||
break;
|
||||
case CustomRoles.Assassin:
|
||||
Assassin.Add(targetId);
|
||||
break;
|
||||
|
||||
@@ -511,6 +511,7 @@ public static class Utils
|
||||
case CustomRoles.Virus:
|
||||
case CustomRoles.Farseer:
|
||||
//case CustomRoles.Counterfeiter:
|
||||
case CustomRoles.Aid:
|
||||
case CustomRoles.Witness:
|
||||
case CustomRoles.Pursuer:
|
||||
case CustomRoles.Spiritcaller:
|
||||
@@ -980,6 +981,15 @@ public static class Utils
|
||||
//case CustomRoles.Counterfeiter:
|
||||
// ProgressText.Append(Counterfeiter.GetSeelLimit(playerId));
|
||||
// break;
|
||||
case CustomRoles.Tether:
|
||||
ProgressText.Append(Tether.GetProgressText(playerId, comms));
|
||||
break;
|
||||
case CustomRoles.Spy:
|
||||
ProgressText.Append(Spy.GetProgressText(playerId, comms));
|
||||
break;
|
||||
case CustomRoles.Aid:
|
||||
ProgressText.Append(Aid.GetProgressText(playerId, comms));
|
||||
break;
|
||||
case CustomRoles.Pursuer:
|
||||
ProgressText.Append(Pursuer.GetSeelLimit(playerId));
|
||||
break;
|
||||
|
||||
@@ -160,6 +160,8 @@ class ExileControllerWrapUpPatch
|
||||
CustomRoles.Chameleon or
|
||||
CustomRoles.Engineer or
|
||||
CustomRoles.Grenadier or
|
||||
CustomRoles.Doormaster or
|
||||
CustomRoles.Tether or
|
||||
CustomRoles.Lighter or
|
||||
CustomRoles.SecurityGuard or
|
||||
CustomRoles.Ventguard or
|
||||
|
||||
@@ -180,6 +180,7 @@ class HudManagerPatch
|
||||
case CustomRoles.FFF:
|
||||
__instance.KillButton.OverrideText(GetString("FFFButtonText"));
|
||||
break;
|
||||
case CustomRoles.Aid:
|
||||
case CustomRoles.Medic:
|
||||
__instance.KillButton.OverrideText(GetString("MedicalerButtonText"));
|
||||
break;
|
||||
|
||||
@@ -131,6 +131,7 @@ public static class HudSpritePatch
|
||||
case CustomRoles.Puppeteer:
|
||||
newKillButton = CustomButton.Get("Puttpuer");
|
||||
break;
|
||||
case CustomRoles.Aid:
|
||||
case CustomRoles.Medic:
|
||||
newKillButton = CustomButton.Get("Shield");
|
||||
break;
|
||||
|
||||
@@ -447,7 +447,7 @@ class BeginImpostorPatch
|
||||
__instance.overlayHandle.color = Palette.ImpostorRed;
|
||||
return true;
|
||||
}
|
||||
else if (role is CustomRoles.Sheriff or CustomRoles.Jailor or CustomRoles.SwordsMan or CustomRoles.Medic/* or CustomRoles.Counterfeiter*/ or CustomRoles.Witness or CustomRoles.Monarch or CustomRoles.Farseer or CustomRoles.Admirer or CustomRoles.Deputy)
|
||||
else if (role is CustomRoles.Sheriff or CustomRoles.Jailor or CustomRoles.SwordsMan or CustomRoles.Medic/* or CustomRoles.Counterfeiter*/ or CustomRoles.Witness or CustomRoles.Aid or CustomRoles.Monarch or CustomRoles.Farseer or CustomRoles.Admirer or CustomRoles.Deputy)
|
||||
{
|
||||
yourTeam = new Il2CppSystem.Collections.Generic.List<PlayerControl>();
|
||||
yourTeam.Add(PlayerControl.LocalPlayer);
|
||||
|
||||
@@ -96,6 +96,12 @@ class CheckForEndVotingPatch
|
||||
case CustomRoles.Eraser:
|
||||
Eraser.OnVote(pc, voteTarget);
|
||||
break;
|
||||
case CustomRoles.Tether:
|
||||
Tether.OnVote(pc, voteTarget);
|
||||
break;
|
||||
case CustomRoles.Ricochet:
|
||||
Ricochet.OnVote(pc, voteTarget);
|
||||
break;
|
||||
case CustomRoles.Cleanser:
|
||||
Cleanser.OnVote(pc, voteTarget);
|
||||
break;
|
||||
|
||||
@@ -159,6 +159,8 @@ class CheckMurderPatch
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.Is(CustomRoles.Spy)) Spy.OnKillAttempt(killer, target);
|
||||
|
||||
//実際のキラーとkillerが違う場合の入れ替え処理
|
||||
if (Sniper.IsEnable) Sniper.TryGetSniper(target.PlayerId, ref killer);
|
||||
if (killer != __instance) Logger.Info($"Real Killer={killer.GetNameWithRole()}", "CheckMurder");
|
||||
@@ -178,7 +180,9 @@ class CheckMurderPatch
|
||||
}
|
||||
if (Pursuer.IsEnable && Pursuer.OnClientMurder(killer)) return false;
|
||||
if (Addict.IsEnable && Addict.IsImmortal(target)) return false;
|
||||
if (Aid.ShieldedPlayers.ContainsKey(target.PlayerId)) return false;
|
||||
if (target.Is(CustomRoles.Vengeance) && !Vengeance.OnKillAttempt(killer, target)) return false;
|
||||
if (target.Is(CustomRoles.Ricochet) && !Ricochet.OnKillAttempt(killer, target)) return false;
|
||||
if (Alchemist.IsProtected && target.Is(CustomRoles.Alchemist))
|
||||
{
|
||||
killer.SetKillCooldown(time: 5f);
|
||||
@@ -195,7 +199,7 @@ class CheckMurderPatch
|
||||
case CustomRoles.BountyHunter: //必须在击杀发生前处理
|
||||
BountyHunter.OnCheckMurder(killer, target);
|
||||
break;
|
||||
case CustomRoles.Vengeance: //必须在击杀发生前处理
|
||||
case CustomRoles.Vengeance:
|
||||
if (!Vengeance.OnCheckMurder(killer, target)) return false;
|
||||
break;
|
||||
case CustomRoles.Inhibitor:
|
||||
@@ -212,6 +216,9 @@ class CheckMurderPatch
|
||||
killer.SyncSettings();
|
||||
}
|
||||
break;
|
||||
case CustomRoles.Aid:
|
||||
if (!Aid.OnCheckMurder(killer, target)) return false;
|
||||
break;
|
||||
case CustomRoles.HeadHunter:
|
||||
HeadHunter.OnCheckMurder(killer, target);
|
||||
break;
|
||||
@@ -1659,6 +1666,7 @@ class ReportDeadBodyPatch
|
||||
if (Pelican.IsEnable) Pelican.OnReportDeadBody();
|
||||
if (Agitater.IsEnable) Agitater.OnReportDeadBody();
|
||||
//if (Counterfeiter.IsEnable) Counterfeiter.OnReportDeadBody();
|
||||
if (Tether.IsEnable) Tether.OnReportDeadBody();
|
||||
if (QuickShooter.IsEnable) QuickShooter.OnReportDeadBody();
|
||||
if (Eraser.IsEnable) Eraser.OnReportDeadBody();
|
||||
if (NiceEraser.IsEnable) NiceEraser.OnReportDeadBody();
|
||||
@@ -1675,6 +1683,7 @@ class ReportDeadBodyPatch
|
||||
if (BallLightning.IsEnable) BallLightning.OnReportDeadBody();
|
||||
if (Romantic.IsEnable) Romantic.OnReportDeadBody();
|
||||
if (Jailor.IsEnable) Jailor.OnReportDeadBody();
|
||||
if (Ricochet.IsEnable) Ricochet.OnReportDeadBody();
|
||||
|
||||
if (Mortician.IsEnable) Mortician.OnReportDeadBody(player, target);
|
||||
if (Tracefinder.IsEnable) Tracefinder.OnReportDeadBody(player, target);
|
||||
@@ -1832,6 +1841,8 @@ class FixedUpdatePatch
|
||||
if (player.Is(CustomRoles.Poisoner)) Poisoner.OnFixedUpdate(player);
|
||||
if (player.Is(CustomRoles.BountyHunter) && !lowLoad) BountyHunter.FixedUpdate(player);
|
||||
if (player.Is(CustomRoles.Glitch) && !lowLoad) Glitch.UpdateHackCooldown(player);
|
||||
if (player.Is(CustomRoles.Aid) && !lowLoad) Aid.OnFixedUpdate(player);
|
||||
if (player.Is(CustomRoles.Spy) && !lowLoad) Spy.OnFixedUpdate(player);
|
||||
if (player.Is(CustomRoles.SerialKiller)) SerialKiller.FixedUpdate(player);
|
||||
if (GameStates.IsInTask && PlagueBearer.IsEnable)
|
||||
if (player.Is(CustomRoles.PlagueBearer) && PlagueBearer.IsPlaguedAll(player))
|
||||
@@ -2796,8 +2807,10 @@ class EnterVentPatch
|
||||
if (Addict.IsEnable) Addict.OnEnterVent(pc, __instance);
|
||||
if (Alchemist.IsEnable) Alchemist.OnEnterVent(pc, __instance.Id);
|
||||
if (Chameleon.IsEnable) Chameleon.OnEnterVent(pc, __instance);
|
||||
if (Tether.IsEnable) Tether.OnEnterVent(pc, __instance.Id);
|
||||
if (Werewolf.IsEnable) Werewolf.OnEnterVent(pc);
|
||||
if (Lurker.IsEnable()) Lurker.OnEnterVent(pc);
|
||||
if (Doormaster.IsEnable) Doormaster.OnEnterVent(pc);
|
||||
|
||||
if (pc.GetCustomRole() == CustomRoles.Ventguard)
|
||||
{
|
||||
|
||||
@@ -223,6 +223,8 @@ internal class ChangeRoleSettings
|
||||
Workhorse.Init();
|
||||
Pelican.Init();
|
||||
//Counterfeiter.Init();
|
||||
Tether.Init();
|
||||
Aid.Init();
|
||||
Pursuer.Init();
|
||||
Gangster.Init();
|
||||
Medic.Init();
|
||||
@@ -235,8 +237,11 @@ internal class ChangeRoleSettings
|
||||
QuickShooter.Init();
|
||||
Camouflager.Init();
|
||||
Divinator.Init();
|
||||
Doormaster.Init();
|
||||
Ricochet.Init();
|
||||
Oracle.Init();
|
||||
Eraser.Init();
|
||||
Spy.Init();
|
||||
NiceEraser.Init();
|
||||
Assassin.Init();
|
||||
Undertaker.Init();
|
||||
@@ -622,9 +627,15 @@ internal class SelectRolesPatch
|
||||
case CustomRoles.Pelican:
|
||||
Pelican.Add(pc.PlayerId);
|
||||
break;
|
||||
case CustomRoles.Tether:
|
||||
Tether.Add(pc.PlayerId);
|
||||
break;
|
||||
//case CustomRoles.Counterfeiter:
|
||||
// Counterfeiter.Add(pc.PlayerId);
|
||||
// break;
|
||||
case CustomRoles.Aid:
|
||||
Aid.Add(pc.PlayerId);
|
||||
break;
|
||||
case CustomRoles.Pursuer:
|
||||
Pursuer.Add(pc.PlayerId);
|
||||
break;
|
||||
@@ -643,6 +654,12 @@ internal class SelectRolesPatch
|
||||
case CustomRoles.Divinator:
|
||||
Divinator.Add(pc.PlayerId);
|
||||
break;
|
||||
case CustomRoles.Ricochet:
|
||||
Ricochet.Add(pc.PlayerId);
|
||||
break;
|
||||
case CustomRoles.Doormaster:
|
||||
Doormaster.Add(pc.PlayerId);
|
||||
break;
|
||||
case CustomRoles.Oracle:
|
||||
Oracle.Add(pc.PlayerId);
|
||||
break;
|
||||
@@ -680,6 +697,9 @@ internal class SelectRolesPatch
|
||||
case CustomRoles.Eraser:
|
||||
Eraser.Add(pc.PlayerId);
|
||||
break;
|
||||
case CustomRoles.Spy:
|
||||
Spy.Add(pc.PlayerId);
|
||||
break;
|
||||
case CustomRoles.NiceEraser:
|
||||
NiceEraser.Add(pc.PlayerId);
|
||||
break;
|
||||
|
||||
+34
-5
@@ -2404,16 +2404,16 @@
|
||||
"DivinatorCheck.Result2","<b>{0}</b>是十字军、预言家、纵火犯、刺客、球状闪电或集票者其中之一","<b>{0}</b> is either Crusader, Investigator, Arsonist, Ninja, Undertaker, Lightning, or Collector","","",""
|
||||
"DivinatorCheck.Result3","<b>{0}</b>是资本家、赝品商、贪婪者、商人或魔术师其中之一","<b>{0}</b> is either Capitalist, Witness, Ventguard, Greedy, Merchant, or Trickster","","",""
|
||||
"DivinatorCheck.Result4","<b>{0}</b>是瘟疫使者、瘟疫、观察者、嗜血骑士、守护者或饥荒其中之一","<b>{0}</b> is either Pestilence, Plaguebearer, Observer, Blood Knight, Guardian, or Wildling","","",""
|
||||
"DivinatorCheck.Result5","<b>{0}</b>是吟游诗人、天启、遐想者、狂妄杀手、杀戳机器或肢解者其中之一","<b>{0}</b> is either Bard, Juggernaut, Security Guard, Arrogance, Killing Machine, or Butcher","","",""
|
||||
"DivinatorCheck.Result5","<b>{0}</b>是吟游诗人、天启、遐想者、狂妄杀手、杀戳机器或肢解者其中之一","<b>{0}</b> is either Bard, Ricochet, Juggernaut, Security Guard, Arrogance, Killing Machine, or Butcher","","",""
|
||||
"DivinatorCheck.Result6","<b>{0}</b>是验尸官、邪恶追踪者、验尸官、寻迹者或正义追踪者其中之一","<b>{0}</b> is either Coroner, Agent, Mortician, Tracefinder, Romantic, or Tracker","","",""
|
||||
"DivinatorCheck.Result7","<b>{0}</b>是保镖、自爆兵、烟花商人或核武器其中之一","<b>{0}</b> is either Bodyguard, Bomber, Lookout, Vengeful Romantic, Ruthless Romantic, Fireworker, or Nuker","","",""
|
||||
"DivinatorCheck.Result8","<b>{0}</b>是赏金猎人、侦探、FFF团、清理工、美杜莎或愚者其中之一","<b>{0}</b> is either Bounty Hunter, Detective, Hater, Cleaner, Medusa, or Psychic","","",""
|
||||
"DivinatorCheck.Result9","<b>{0}</b>是罪犯、处刑者、律师、告密者、分散者或法医其中之一","<b>{0}</b> is either Convict, Executioner, Lawyer, Snitch, Disperser, or Doctor","","",""
|
||||
"DivinatorCheck.Result10","<b>{0}</b>是议员、独裁者、法官、被诅咒的灵魂或呪狼其中之一","<b>{0}</b> is either Councillor, Dictator, Judge, Cursed Soul, Cleanser, or Cursed Wolf","","",""
|
||||
"DivinatorCheck.Result11","<b>{0}</b>是瘾君子、逃亡者、矿工或化形者其中之一","<b>{0}</b> is either Addict, Alchemist, Escapist, Miner, Demolitionist, or Morphling","","",""
|
||||
"DivinatorCheck.Result12","<b>{0}</b>是玩家、僵尸、网红、大明星、死亡契约或吞噬者其中之一","<b>{0}</b> is either Demon, Zombie, Celebrity, Super Star, Deathpact, or Devourer","","",""
|
||||
"DivinatorCheck.Result12","<b>{0}</b>是玩家、僵尸、网红、大明星、死亡契约或吞噬者其中之一","<b>{0}</b> is either Demon, Doormaster, Zombie, Celebrity, Super Star, Deathpact, or Devourer","","",""
|
||||
"DivinatorCheck.Result13","<b>{0}</b>是神,神谕,幻想家,检查员其中之一","<b>{0}</b> is either God, Oracle, Visionary, Nice Eraser, Swapper, or Inspector","","",""
|
||||
"DivinatorCheck.Result14","<b>{0}</b>是隐匿者、市长、被害妄想症、小偷或卫道士其中之一","<b>{0}</b> is either Anonymous, Mayor, Paranoid, Pickpocket, or Vindicator","","",""
|
||||
"DivinatorCheck.Result14","<b>{0}</b>是隐匿者、市长、被害妄想症、小偷或卫道士其中之一","<b>{0}</b> is either Anonymous, Spy, Mayor, Paranoid, Pickpocket, or Vindicator","","",""
|
||||
"DivinatorCheck.Result15","<b>{0}</b>是传染性的、病毒的、君主的、革命者的或魅魔的其中之一","<b>{0}</b> is either Infectious, Virus, Agitater, Monarch, Revolutionist, Express, or Cultist","","",""
|
||||
"DivinatorCheck.Result16","<b>{0}</b>是冤罪师、受虐狂、抑制者、修理工或破坏者其中之一","<b>{0}</b> is either Innocent, Refugee, Bandit, Inhibitor, Mechanic, or Saboteur","","",""
|
||||
"DivinatorCheck.Result17","<b>{0}</b>是医生、马里奥、小丑、潜伏者还是阳光开朗大男孩其中之一","<b>{0}</b> is either Medic, Vector, Jester, The Glitch, Lurker, or Sunnyboy","","",""
|
||||
@@ -2426,8 +2426,8 @@
|
||||
"DivinatorCheck.Result24","<b>{0}</b>是懒人、跟随者、鹈鹕、清道夫或秃鹫其中之一","<b>{0}</b> is either Lazy Guy, Follower, Pelican, Vengeance, Scavenger, or Vulture","","",""
|
||||
"DivinatorCheck.Result25","<b>{0}</b>是扫把星、骑士、老兵或刽子手其中之一","<b>{0}</b> is either Jinx, Vigilante, Veteran, Task Manager, Pyromaniac, or Hangman","","",""
|
||||
"DivinatorCheck.Result26","<b>{0}</b>是通灵师、灵魂召唤师、灵魂论者、寄生虫、隐匿者或魅影其中之一","<b>{0}</b> is either Medium, Spiritcaller, Spiritualist, Parasite, Swooper, or Wraith","","",""
|
||||
"DivinatorCheck.Result27","<b>{0}</b>可能是时间操控者, 时间之主, 蚀时者, 千面鬼, 或者狙击手其中之一","<b>{0}</b> is either Time Manager, Time Master, Time Thief, Shapemaster, or Sniper"
|
||||
"DivinatorCheck.Result28","<b>{0}</b>可能是傀儡师, 巫婆, 捕快, 传送师, 龙卷风, 或者嗜血杀手其中之一","<b>{0}</b> is either Puppeteer, Deputy, Transporter, Twister, Mercenary","","",""
|
||||
"DivinatorCheck.Result27","<b>{0}</b>可能是时间操控者, 时间之主, 蚀时者, 千面鬼, 或者狙击手其中之一","<b>{0}</b> is either Time Manager, Time Master, Time Thief, Tether, Shapemaster, or Sniper"
|
||||
"DivinatorCheck.Result28","<b>{0}</b>可能是傀儡师, 巫婆, 捕快, 传送师, 龙卷风, 或者嗜血杀手其中之一","<b>{0}</b> is either Puppeteer, Deputy, Aid, Transporter, Twister, Mercenary","","",""
|
||||
"DivinatorCheck.Result29","<b>{0}</b>可能是船鬼, 展现者, 工作狂, 幻影, 或者恐怖分子其中之一","<b>{0}</b> is either Crewpostor, Marshall, Workaholic, Phantom, Speedrunner, or Terrorist","","",""
|
||||
|
||||
"## Hidden Role Chances"
|
||||
@@ -2580,6 +2580,35 @@
|
||||
"SecurityGuardSkillInUse","","Ability in use","","",""
|
||||
"SecurityGuardSkillStop","","Ability expired","","",""
|
||||
|
||||
"## Doormaster"
|
||||
"Doormaster","","Door Master","","",""
|
||||
"DoormasterInfo","","Vent to Open All Doors","","",""
|
||||
"DoormasterInfoLong","","(Crewmates):\nAs the Door Master, you can vent to open all closed doors.\n\nDue to technical difficulties, this may not work on some maps.","","",""
|
||||
|
||||
"## Ricochet"
|
||||
"Ricochet","","Ricochet","","",""
|
||||
"RicochetInfo","","Protect yourself from someone specific","","",""
|
||||
"RicochetInfoLong","","(Crewmates):\nAs the Ricochat, you may vote someone in a meeting to make them your target.\nIn the next round, your target will not be able to kill you.","","",""
|
||||
|
||||
"## Spy"
|
||||
"Spy","","Spy","","",""
|
||||
"SpyInfo","","You know who interacts with you","","",""
|
||||
"SpyInfoLong","","(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability that is used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you have no ability uses left, you won't see orange names at all!","","",""
|
||||
"SpyRedNameDur","","Colored Name Duration","","",""
|
||||
|
||||
"## Tether"
|
||||
"Tether","","Tether","","",""
|
||||
"TetherInfo","","Teleport to your target","","",""
|
||||
"TetherInfoLong","","(Crewmates):\nAs the Tether, you may vote someone in a meeting to make them your target. In the next round, you can vent to teleport to them anytime.\nYour targets reset every meeting.","","",""
|
||||
"TetherNoTarget","","You have no target","","",""
|
||||
|
||||
"## Aid"
|
||||
"Aid","","Aid","","",""
|
||||
"AidInfo","","Protect players temporarily","","",""
|
||||
"AidInfoLong","","(Crewmates):\nAs the Aid, you may use your kill button on someone to protect them from direct attacks temporarily. Neither you or your target will know if someone tried to kill your target.","","",""
|
||||
"AidDur","","Shield Duration","","",""
|
||||
"AidCD","","Shield Cooldown","","",""
|
||||
|
||||
"## FFA"
|
||||
"FFA","","Basic FFA","","",""
|
||||
"ModeFFA","","Gamemode: FFA","","",""
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -0,0 +1,108 @@
|
||||
namespace TOHE.Roles.Crewmate
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using static TOHE.Options;
|
||||
using static TOHE.Utils;
|
||||
|
||||
public static class Aid
|
||||
{
|
||||
private static readonly int Id = 640200;
|
||||
private static List<byte> playerIdList = new();
|
||||
public static Dictionary<byte, float> UseLimit = new();
|
||||
public static Dictionary<byte, long> ShieldedPlayers = new();
|
||||
|
||||
public static OptionItem AidDur;
|
||||
public static OptionItem AidCD;
|
||||
public static OptionItem UseLimitOpt;
|
||||
|
||||
public static void SetupCustomOption()
|
||||
{
|
||||
SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Aid);
|
||||
AidCD = FloatOptionItem.Create(Id + 10, "AidCD", new(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Aid])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
AidDur = FloatOptionItem.Create(Id + 11, "AidDur", new(0f, 70f, 1f), 10f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Aid])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
UseLimitOpt = IntegerOptionItem.Create(Id + 12, "AbilityUseLimit", new(1, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Aid])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
}
|
||||
public static void Init()
|
||||
{
|
||||
playerIdList = new();
|
||||
UseLimit = new();
|
||||
ShieldedPlayers = new();
|
||||
}
|
||||
public static void Add(byte playerId)
|
||||
{
|
||||
playerIdList.Add(playerId);
|
||||
UseLimit.Add(playerId, UseLimitOpt.GetInt());
|
||||
|
||||
if (!AmongUsClient.Instance.AmHost) return;
|
||||
if (!Main.ResetCamPlayerList.Contains(playerId))
|
||||
Main.ResetCamPlayerList.Add(playerId);
|
||||
}
|
||||
public static void SetKillCooldown(byte playerId) => Main.AllPlayerKillCooldown[playerId] = AidCD.GetInt();
|
||||
public static bool IsEnable => playerIdList.Any();
|
||||
public static bool OnCheckMurder(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
if (killer == null) return false;
|
||||
if (target == null) return false;
|
||||
if (!killer.Is(CustomRoles.Aid)) return true;
|
||||
|
||||
if (UseLimit[killer.PlayerId] >= 1)
|
||||
{
|
||||
UseLimit[killer.PlayerId] -= 1;
|
||||
ShieldedPlayers.TryAdd(target.PlayerId, GetTimeStamp());
|
||||
NotifyRoles(SpecifySeer: killer);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static void OnFixedUpdate(PlayerControl pc)
|
||||
{
|
||||
if (pc == null) return;
|
||||
if (!pc.Is(CustomRoles.Aid)) return;
|
||||
if (!ShieldedPlayers.Any()) return;
|
||||
|
||||
bool change = false;
|
||||
|
||||
foreach (var x in ShieldedPlayers)
|
||||
{
|
||||
if (x.Value + AidDur.GetInt() < GetTimeStamp() || !GameStates.IsInTask)
|
||||
{
|
||||
ShieldedPlayers.Remove(x.Key);
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (change && GameStates.IsInTask) { NotifyRoles(SpecifySeer: pc); }
|
||||
}
|
||||
public static string GetProgressText(byte playerId, bool comms)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var taskState = Main.PlayerStates?[playerId].GetTaskState();
|
||||
Color TextColor;
|
||||
var TaskCompleteColor = Color.green;
|
||||
var NonCompleteColor = Color.yellow;
|
||||
var NormalColor = taskState.IsTaskFinished ? TaskCompleteColor : NonCompleteColor;
|
||||
TextColor = comms ? Color.gray : NormalColor;
|
||||
string Completed = comms ? "?" : $"{taskState.CompletedTasksCount}";
|
||||
|
||||
Color TextColor1;
|
||||
if (UseLimit[playerId] < 1) TextColor1 = Color.red;
|
||||
else TextColor1 = Color.white;
|
||||
|
||||
sb.Append(ColorString(TextColor, $"<color=#777777>-</color> {Completed}/{taskState.AllTasksCount}"));
|
||||
sb.Append(ColorString(TextColor1, $" <color=#777777>-</color> {Math.Round(UseLimit[playerId], 1)}"));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,6 +117,9 @@ public static class CopyCat
|
||||
case CustomRoles.Paranoia:
|
||||
Main.ParaUsedButtonCount.Remove(player);
|
||||
break;
|
||||
case CustomRoles.Aid:
|
||||
Aid.UseLimit.Remove(player);
|
||||
break;
|
||||
case CustomRoles.Snitch:
|
||||
Snitch.IsExposed.Remove(player);
|
||||
Snitch.IsComplete.Remove(player);
|
||||
@@ -268,6 +271,9 @@ public static class CopyCat
|
||||
Merchant.addonsSold.Add(pc.PlayerId, 0);
|
||||
Merchant.bribedKiller.Add(pc.PlayerId, new List<byte>());
|
||||
break;
|
||||
case CustomRoles.Aid:
|
||||
Aid.UseLimit.Add(pc.PlayerId, Aid.UseLimitOpt.GetInt());
|
||||
break;
|
||||
case CustomRoles.Oracle:
|
||||
Oracle.CheckLimit.TryAdd(pc.PlayerId, Oracle.CheckLimitOpt.GetInt());
|
||||
break;
|
||||
|
||||
@@ -122,6 +122,7 @@ public static class Divinator
|
||||
//CustomRoles.Reverie or
|
||||
CustomRoles.SecurityGuard or
|
||||
CustomRoles.Sans or
|
||||
CustomRoles.Ricochet or
|
||||
CustomRoles.Minimalism or
|
||||
CustomRoles.OverKiller
|
||||
=> "Result5",
|
||||
@@ -181,6 +182,7 @@ public static class Divinator
|
||||
CustomRoles.Zombie or
|
||||
CustomRoles.CyberStar or
|
||||
CustomRoles.SuperStar or
|
||||
CustomRoles.Doormaster or
|
||||
CustomRoles.Deathpact or
|
||||
CustomRoles.Devourer
|
||||
=> "Result12",
|
||||
@@ -197,6 +199,7 @@ public static class Divinator
|
||||
CustomRoles.Mayor or
|
||||
CustomRoles.Paranoia or
|
||||
CustomRoles.Pickpocket or
|
||||
CustomRoles.Spy or
|
||||
CustomRoles.Vindicator
|
||||
=> "Result14",
|
||||
|
||||
@@ -304,6 +307,7 @@ public static class Divinator
|
||||
CustomRoles.TimeMaster or
|
||||
CustomRoles.TimeThief or
|
||||
CustomRoles.ShapeMaster or
|
||||
CustomRoles.Tether or
|
||||
CustomRoles.Sniper
|
||||
=> "Result27",
|
||||
|
||||
@@ -312,6 +316,7 @@ public static class Divinator
|
||||
CustomRoles.Deputy or
|
||||
CustomRoles.Transporter or
|
||||
CustomRoles.Twister or
|
||||
CustomRoles.Aid or
|
||||
CustomRoles.SerialKiller
|
||||
=> "Result28",
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
namespace TOHE.Roles.Crewmate
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TOHE.Modules;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using static TOHE.Options;
|
||||
using static TOHE.Utils;
|
||||
using System.Text;
|
||||
|
||||
public static class Doormaster
|
||||
{
|
||||
private static readonly int Id = 6400;
|
||||
private static readonly int Id = 640000;
|
||||
private static List<byte> playerIdList = new();
|
||||
public static Dictionary<byte, float> UseLimit = new();
|
||||
|
||||
@@ -22,11 +22,11 @@ namespace TOHE.Roles.Crewmate
|
||||
public static void SetupCustomOption()
|
||||
{
|
||||
SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Doormaster);
|
||||
VentCooldown = FloatOptionItem.Create(Id + 11, "VentCooldown", new(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Doormaster])
|
||||
VentCooldown = FloatOptionItem.Create(Id + 10, "VentCooldown", new(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Doormaster])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
UseLimitOpt = IntegerOptionItem.Create(Id + 12, "AbilityUseLimit", new(1, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Doormaster])
|
||||
UseLimitOpt = IntegerOptionItem.Create(Id + 11, "AbilityUseLimit", new(1, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Doormaster])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
DoormasterAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 13, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 0.2f, TabGroup.CrewmateRoles, false)
|
||||
DoormasterAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 12, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, false)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Doormaster])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
}
|
||||
@@ -44,9 +44,17 @@ namespace TOHE.Roles.Crewmate
|
||||
public static void OnEnterVent(PlayerControl pc)
|
||||
{
|
||||
if (pc == null) return;
|
||||
if (!pc.Is(CustomRoles.Doormaster)) return;
|
||||
|
||||
DoorsReset.OpenAllDoors();
|
||||
UseLimit[pc.PlayerId] -= 1;
|
||||
if (UseLimit[pc.PlayerId] >= 1)
|
||||
{
|
||||
UseLimit[pc.PlayerId] -= 1;
|
||||
DoorsReset.OpenAllDoors();
|
||||
}
|
||||
else
|
||||
{
|
||||
pc.Notify(Translator.GetString("OutOfAbilityUsesDoMoreTasks"));
|
||||
}
|
||||
}
|
||||
public static string GetProgressText(byte playerId, bool comms)
|
||||
{
|
||||
@@ -59,9 +67,11 @@ namespace TOHE.Roles.Crewmate
|
||||
var NormalColor = taskState.IsTaskFinished ? TaskCompleteColor : NonCompleteColor;
|
||||
TextColor = comms ? Color.gray : NormalColor;
|
||||
string Completed = comms ? "?" : $"{taskState.CompletedTasksCount}";
|
||||
|
||||
Color TextColor1;
|
||||
if (UseLimit[playerId] < 1) TextColor1 = Color.red;
|
||||
else TextColor1 = Color.white;
|
||||
|
||||
sb.Append(ColorString(TextColor, $"<color=#777777>-</color> {Completed}/{taskState.AllTasksCount}"));
|
||||
sb.Append(ColorString(TextColor1, $" <color=#777777>-</color> {Math.Round(UseLimit[playerId], 1)}"));
|
||||
|
||||
|
||||
@@ -31,6 +31,11 @@ namespace TOHE.Roles.Crewmate
|
||||
CustomRoles.Express,
|
||||
CustomRoles.NiceEraser,
|
||||
CustomRoles.TaskManager,
|
||||
CustomRoles.Aid,
|
||||
CustomRoles.Tether,
|
||||
CustomRoles.Spy,
|
||||
CustomRoles.Ricochet,
|
||||
CustomRoles.Doormaster,
|
||||
CustomRoles.Mayor,
|
||||
CustomRoles.Paranoia,
|
||||
CustomRoles.Psychic,
|
||||
|
||||
+41
-12
@@ -1,28 +1,29 @@
|
||||
namespace TOHE.Roles.Crewmate
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using static TOHE.Options;
|
||||
using static TOHE.Utils;
|
||||
|
||||
public static class Ricochet
|
||||
{
|
||||
private static readonly int Id = 6400;
|
||||
private static readonly int Id = 640100;
|
||||
private static List<byte> playerIdList = new();
|
||||
public static Dictionary<byte, float> UseLimit = new();
|
||||
public static byte ProtectAgainst = new();
|
||||
public static byte ProtectAgainst = byte.MaxValue;
|
||||
|
||||
public static OptionItem VentCooldown;
|
||||
public static OptionItem UseLimitOpt;
|
||||
public static OptionItem RicochetAbilityUseGainWithEachTaskCompleted;
|
||||
|
||||
public static void SetupCustomOption()
|
||||
{
|
||||
SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Ricochet, 1);
|
||||
VentCooldown = FloatOptionItem.Create(Id + 11, "VentCooldown", new(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Ricochet])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
UseLimitOpt = IntegerOptionItem.Create(Id + 12, "AbilityUseLimit", new(1, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Ricochet])
|
||||
UseLimitOpt = IntegerOptionItem.Create(Id + 10, "AbilityUseLimit", new(1, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Ricochet])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
RicochetAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 13, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 0.2f, TabGroup.CrewmateRoles, false)
|
||||
RicochetAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 11, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 0.5f, TabGroup.CrewmateRoles, false)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Ricochet])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
}
|
||||
@@ -30,7 +31,7 @@ namespace TOHE.Roles.Crewmate
|
||||
{
|
||||
playerIdList = new();
|
||||
UseLimit = new();
|
||||
ProtectAgainst = new();
|
||||
ProtectAgainst = byte.MaxValue;
|
||||
}
|
||||
public static void Add(byte playerId)
|
||||
{
|
||||
@@ -42,7 +43,7 @@ namespace TOHE.Roles.Crewmate
|
||||
{
|
||||
if (killer == null) return false;
|
||||
if (target == null) return false;
|
||||
if (target.Is(CustomRoles.Ricochet)) return true;
|
||||
if (!target.Is(CustomRoles.Ricochet)) return true;
|
||||
|
||||
if (ProtectAgainst == killer.PlayerId)
|
||||
{
|
||||
@@ -56,13 +57,41 @@ namespace TOHE.Roles.Crewmate
|
||||
{
|
||||
if (target == null) return;
|
||||
if (pc == null) return;
|
||||
if (pc.PlayerId == target.PlayerId) return;
|
||||
if (!pc.Is(CustomRoles.Ricochet)) return;
|
||||
|
||||
ProtectAgainst = target.PlayerId;
|
||||
UseLimit[pc.PlayerId] -= 1;
|
||||
if (UseLimit[pc.PlayerId] >= 1)
|
||||
{
|
||||
UseLimit[pc.PlayerId] -= 1;
|
||||
ProtectAgainst = target.PlayerId;
|
||||
}
|
||||
}
|
||||
public static void OnReportDeadBody()
|
||||
{
|
||||
ProtectAgainst = byte.MaxValue;
|
||||
}
|
||||
public static string GetProgressText(byte playerId, bool comms)
|
||||
{
|
||||
return string.Empty;
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var taskState = Main.PlayerStates?[playerId].GetTaskState();
|
||||
Color TextColor;
|
||||
var TaskCompleteColor = Color.green;
|
||||
var NonCompleteColor = Color.yellow;
|
||||
var NormalColor = taskState.IsTaskFinished ? TaskCompleteColor : NonCompleteColor;
|
||||
TextColor = comms ? Color.gray : NormalColor;
|
||||
string Completed = comms ? "?" : $"{taskState.CompletedTasksCount}";
|
||||
|
||||
Color TextColor1;
|
||||
if (UseLimit[playerId] < 1) TextColor1 = Color.red;
|
||||
else TextColor1 = Color.white;
|
||||
|
||||
sb.Append(ColorString(TextColor, $"<color=#777777>-</color> {Completed}/{taskState.AllTasksCount}"));
|
||||
sb.Append(ColorString(TextColor1, $" <color=#777777>-</color> {Math.Round(UseLimit[playerId], 1)}"));
|
||||
|
||||
if (ProtectAgainst != byte.MaxValue) sb.Append($" <color=#777777>-</color> Target: {GetPlayerById(ProtectAgainst).GetRealName()}");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
namespace TOHE.Roles.Crewmate
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using static TOHE.Options;
|
||||
using static TOHE.Utils;
|
||||
|
||||
public static class Spy
|
||||
{
|
||||
private static readonly int Id = 640400;
|
||||
private static List<byte> playerIdList = new();
|
||||
public static Dictionary<byte, float> UseLimit = new();
|
||||
public static Dictionary<byte, long> SpyRedNameList = new();
|
||||
|
||||
public static OptionItem SpyRedNameDur;
|
||||
public static OptionItem UseLimitOpt;
|
||||
public static OptionItem SpyAbilityUseGainWithEachTaskCompleted;
|
||||
|
||||
public static void SetupCustomOption()
|
||||
{
|
||||
SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Spy, 1);
|
||||
UseLimitOpt = IntegerOptionItem.Create(Id + 10, "AbilityUseLimit", new(1, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Spy])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
SpyRedNameDur = FloatOptionItem.Create(Id + 11, "SpyRedNameDur", new(0f, 70f, 1f), 3f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Spy])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
SpyAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 12, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 0.5f, TabGroup.CrewmateRoles, false)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Spy])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
}
|
||||
public static void Init()
|
||||
{
|
||||
playerIdList = new();
|
||||
UseLimit = new();
|
||||
SpyRedNameList = new();
|
||||
}
|
||||
public static void Add(byte playerId)
|
||||
{
|
||||
playerIdList.Add(playerId);
|
||||
UseLimit.Add(playerId, UseLimitOpt.GetInt());
|
||||
}
|
||||
public static bool IsEnable => playerIdList.Any();
|
||||
public static void OnKillAttempt(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
if (killer == null) return;
|
||||
if (target == null) return;
|
||||
if (!target.Is(CustomRoles.Spy)) return;
|
||||
if (killer.PlayerId == target.PlayerId) return;
|
||||
|
||||
if (UseLimit[target.PlayerId] >= 1)
|
||||
{
|
||||
UseLimit[target.PlayerId] -= 1;
|
||||
SpyRedNameList.TryAdd(killer.PlayerId, GetTimeStamp());
|
||||
}
|
||||
}
|
||||
public static void OnFixedUpdate(PlayerControl pc)
|
||||
{
|
||||
if (pc == null) return;
|
||||
if (!pc.Is(CustomRoles.Spy)) return;
|
||||
if (!SpyRedNameList.Any()) return;
|
||||
|
||||
bool change = false;
|
||||
|
||||
foreach (var x in SpyRedNameList)
|
||||
{
|
||||
if (x.Value + SpyRedNameDur.GetInt() < GetTimeStamp() || !GameStates.IsInTask)
|
||||
{
|
||||
SpyRedNameList.Remove(x.Key);
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (change && GameStates.IsInTask) { NotifyRoles(SpecifySeer: pc); }
|
||||
}
|
||||
public static string GetProgressText(byte playerId, bool comms)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var taskState = Main.PlayerStates?[playerId].GetTaskState();
|
||||
Color TextColor;
|
||||
var TaskCompleteColor = Color.green;
|
||||
var NonCompleteColor = Color.yellow;
|
||||
var NormalColor = taskState.IsTaskFinished ? TaskCompleteColor : NonCompleteColor;
|
||||
TextColor = comms ? Color.gray : NormalColor;
|
||||
string Completed = comms ? "?" : $"{taskState.CompletedTasksCount}";
|
||||
|
||||
Color TextColor1;
|
||||
if (UseLimit[playerId] < 1) TextColor1 = Color.red;
|
||||
else TextColor1 = Color.white;
|
||||
|
||||
sb.Append(ColorString(TextColor, $"<color=#777777>-</color> {Completed}/{taskState.AllTasksCount}"));
|
||||
sb.Append(ColorString(TextColor1, $" <color=#777777>-</color> {Math.Round(UseLimit[playerId], 1)}"));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
namespace TOHE.Roles.Crewmate
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using static TOHE.Options;
|
||||
using static TOHE.Utils;
|
||||
|
||||
public static class Tether
|
||||
{
|
||||
private static readonly int Id = 640300;
|
||||
private static List<byte> playerIdList = new();
|
||||
public static Dictionary<byte, float> UseLimit = new();
|
||||
private static byte Target = byte.MaxValue;
|
||||
|
||||
public static OptionItem VentCooldown;
|
||||
public static OptionItem UseLimitOpt;
|
||||
public static OptionItem TetherAbilityUseGainWithEachTaskCompleted;
|
||||
|
||||
public static void SetupCustomOption()
|
||||
{
|
||||
SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Tether, 1);
|
||||
VentCooldown = FloatOptionItem.Create(Id + 10, "VentCooldown", new(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Tether])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
UseLimitOpt = IntegerOptionItem.Create(Id + 11, "AbilityUseLimit", new(1, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Tether])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
TetherAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 12, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 0.4f, TabGroup.CrewmateRoles, false)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Tether])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
}
|
||||
public static void Init()
|
||||
{
|
||||
playerIdList = new();
|
||||
UseLimit = new();
|
||||
Target = byte.MaxValue;
|
||||
}
|
||||
public static void Add(byte playerId)
|
||||
{
|
||||
playerIdList.Add(playerId);
|
||||
UseLimit.Add(playerId, UseLimitOpt.GetInt());
|
||||
}
|
||||
public static bool IsEnable => playerIdList.Any();
|
||||
public static void OnEnterVent(PlayerControl pc, int ventId)
|
||||
{
|
||||
if (pc == null) return;
|
||||
if (!pc.Is(CustomRoles.Tether)) return;
|
||||
|
||||
if (UseLimit[pc.PlayerId] >= 1)
|
||||
{
|
||||
if (Target != byte.MaxValue)
|
||||
{
|
||||
_ = new LateTask(() =>
|
||||
{
|
||||
if (GameStates.IsInTask)
|
||||
{
|
||||
UseLimit[pc.PlayerId] -= 1;
|
||||
TP(pc.NetTransform, GetPlayerById(Target).GetTruePosition());
|
||||
}
|
||||
}, 2f, "Tether TP");
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = new LateTask(() =>
|
||||
{
|
||||
pc.MyPhysics?.RpcBootFromVent(ventId);
|
||||
}, 0.5f, "Tether No Target Boot From Vent");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = new LateTask(() =>
|
||||
{
|
||||
pc.MyPhysics?.RpcBootFromVent(ventId);
|
||||
pc.Notify(Translator.GetString("OutOfAbilityUsesDoMoreTasks"));
|
||||
}, 0.5f, "Tether No Uses Left Boot From Vent");
|
||||
}
|
||||
}
|
||||
public static void OnVote(PlayerControl pc, PlayerControl target)
|
||||
{
|
||||
if (pc == null) return;
|
||||
if (target == null) return;
|
||||
if (!pc.Is(CustomRoles.Tether)) return;
|
||||
if (pc.PlayerId == target.PlayerId) return;
|
||||
|
||||
if (UseLimit[pc.PlayerId] >= 1)
|
||||
{
|
||||
UseLimit[pc.PlayerId] -= 1;
|
||||
Target = target.PlayerId;
|
||||
}
|
||||
}
|
||||
public static void OnReportDeadBody()
|
||||
{
|
||||
Target = byte.MaxValue;
|
||||
}
|
||||
public static string GetProgressText(byte playerId, bool comms)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var taskState = Main.PlayerStates?[playerId].GetTaskState();
|
||||
Color TextColor;
|
||||
var TaskCompleteColor = Color.green;
|
||||
var NonCompleteColor = Color.yellow;
|
||||
var NormalColor = taskState.IsTaskFinished ? TaskCompleteColor : NonCompleteColor;
|
||||
TextColor = comms ? Color.gray : NormalColor;
|
||||
string Completed = comms ? "?" : $"{taskState.CompletedTasksCount}";
|
||||
|
||||
Color TextColor1;
|
||||
if (UseLimit[playerId] < 1) TextColor1 = Color.red;
|
||||
else TextColor1 = Color.white;
|
||||
|
||||
sb.Append(ColorString(TextColor, $"<color=#777777>-</color> {Completed}/{taskState.AllTasksCount}"));
|
||||
sb.Append(ColorString(TextColor1, $" <color=#777777>-</color> {Math.Round(UseLimit[playerId], 1)}"));
|
||||
|
||||
if (Target != byte.MaxValue) sb.Append($" <color=#777777>-</color> Target: {GetPlayerById(Target).GetRealName()}");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
<Description>Town Of Host Edited</Description>
|
||||
<Authors>KARPED1EM</Authors>
|
||||
<langVersion>latest</langVersion>
|
||||
<AmongUs>E:\Program Files\AmongUs</AmongUs>
|
||||
<AmongUs>D:\Epic Games\AmongUs</AmongUs>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ public class Main : BasePlugin
|
||||
public static ConfigEntry<string> DebugKeyInput { get; private set; }
|
||||
public static readonly string MainMenuText = " ";
|
||||
public const string PluginGuid = "com.gurge44.toheplus";
|
||||
public const string PluginVersion = "1.0.3";
|
||||
public const string PluginDisplayVersion = "1.0.3";
|
||||
public const string PluginVersion = "1.0.5";
|
||||
public const string PluginDisplayVersion = "1.0.5";
|
||||
public const int PluginCreate = 3;
|
||||
public const bool Canary = false;
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
Self-notes:
|
||||
- New Fortune Teller hints
|
||||
- Add Ying Yanger?
|
||||
- Controller (PL Mastermind)
|
||||
- Somehow make Crewpostor playable (less OP)
|
||||
- Spy (Crew) => Caly's idea
|
||||
- Background music? (factorio soundtrack)
|
||||
- UI for Inspector
|
||||
- Aid (Crew) => Temporarily shield a player for X seconds via kill button
|
||||
|
||||
!important
|
||||
- Spy: Can see who tried to use the kill button on them a limited times (base: Crewmate)
|
||||
- Aid: Protect someone via kill button temporary + ability use limit (base: Impostor)
|
||||
- Ricochet: Protect yourself against someone specific by voting (base: Crewmate)
|
||||
- Doormaster: Vent to open all closed doors (base: Engineer)
|
||||
- Tether: Mark target by voting, vent to TP to them (base: Engineer)
|
||||
|
||||
Completed:
|
||||
- fix HH KCD going below 0s
|
||||
- fix /kcount
|
||||
- Delete role subcategories
|
||||
- KCD after meetings for Inhibitor and Saboteur
|
||||
- Added Agitater and Bandit
|
||||
- fix fatal error with Mercenary progress text
|
||||
|
||||
Map 5 is coming, motivation is lost - 2023.09.14.
|
||||
|
||||
Strings to add:
|
||||
()
|
||||
Reference in new issue
Block a user