mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
fixes & Summoner settings
This commit is contained in:
1 parent
f212d4676f
commit
94036930e9
10 files changed
+91
-28
No files matched your search
+10
-6
@@ -3991,11 +3991,15 @@ public static class Utils
|
||||
Reaper.OnAnyoneDead(target);
|
||||
Wyrd.OnAnyoneDeath(target);
|
||||
Thanos.OnDeath(targetRealKiller, target, disconnect);
|
||||
CovenMember.OnAnyoneDead();
|
||||
Altruist.OnAnyoneDead();
|
||||
Occultist.OnAnyoneDead();
|
||||
Vulture.OnAnyoneDead();
|
||||
Jackal.OnAnyoneDead();
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
CovenMember.OnAnyoneDead();
|
||||
Altruist.OnAnyoneDead();
|
||||
Occultist.OnAnyoneDead();
|
||||
Vulture.OnAnyoneDead();
|
||||
Jackal.OnAnyoneDead();
|
||||
}, 0.1f);
|
||||
|
||||
if (!onMeeting && !disconnect)
|
||||
{
|
||||
@@ -4017,7 +4021,7 @@ public static class Utils
|
||||
Amogus.OnAnyoneDead(target);
|
||||
Adventurer.OnAnyoneDead(target);
|
||||
Whisperer.OnAnyoneDied(target);
|
||||
Necromancer.OnAnyoneDead();
|
||||
LateTask.New(Necromancer.OnAnyoneDead, 0.1f);
|
||||
}
|
||||
|
||||
if (QuizMaster.On) QuizMaster.Data.NumPlayersDeadThisRound++;
|
||||
|
||||
@@ -524,8 +524,18 @@ internal static class ChatCommands
|
||||
if (!Main.PlayerStates.TryGetValue(player.PlayerId, out PlayerState state) || state.IsDead || state.Role is not Summoner sum || player.GetAbilityUseLimit() < 1) return;
|
||||
if (args.Length < 2 || !byte.TryParse(args[1], out byte targetId) || !Main.PlayerStates.TryGetValue(targetId, out var targetState) || !targetState.IsDead) return;
|
||||
|
||||
bool reSummoned = !Summoner.AlreadySummoned.Add(targetId);
|
||||
|
||||
if (reSummoned && !Summoner.AllowSummoningTheSamePlayerTwice.GetBool())
|
||||
{
|
||||
Utils.SendMessage("\n", player.PlayerId, GetString("Summoner.CantSummonSamePlayerTwice"));
|
||||
return;
|
||||
}
|
||||
|
||||
sum.SummonedPlayerId = targetId;
|
||||
player.RpcRemoveAbilityUse();
|
||||
|
||||
if (!reSummoned || Summoner.ReSummonTakesAbilityUse.GetBool())
|
||||
player.RpcRemoveAbilityUse();
|
||||
|
||||
Utils.SendMessage("\n", player.PlayerId, string.Format(GetString("Summoner.SummonSuccessMessage"), targetId.ColoredPlayerName()));
|
||||
|
||||
|
||||
@@ -653,7 +653,7 @@ internal static class MurderPlayerPatch
|
||||
{
|
||||
Infection.OnAnyMurder();
|
||||
|
||||
Summoner.OnAnyoneMurder(killer);
|
||||
Summoner.OnAnyoneMurder(killer, target);
|
||||
|
||||
// Replacement process when the actual killer and killer are different
|
||||
if (Sniper.TryGetSniper(target.PlayerId, ref killer)) Main.PlayerStates[target.PlayerId].deathReason = PlayerState.DeathReason.Sniped;
|
||||
@@ -1114,6 +1114,11 @@ internal static class ReportDeadBodyPatch
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Summoner.OnAnyoneReport())
|
||||
{
|
||||
Notify("SummonedPlayerAlive");
|
||||
}
|
||||
|
||||
if (!Wyrd.CheckPlayerAction(__instance, Wyrd.Action.Report)) return false; // Player dies, no notify needed
|
||||
|
||||
PlayerControl tpc = target.Object;
|
||||
|
||||
@@ -3404,11 +3404,22 @@
|
||||
"SummonerInfo": "Summon Players to Kill For You",
|
||||
"SummonerInfoLong": "(Coven):\\nUse <b>/cmd summon {player ID}</b> (or the kick menu) to select a dead player to revive (summon) after the meeting. They will have a certain time to kill for you. If they succeed, they can also win alongside you, as well as their original team. Otherwise they die again at the end of the time limit, if they aren't already. With the Necronomicon, you gain a kill button and the ability to kill normally.\\n\\n<size=80%>Type <b>/cmd id</b> to get a list of player IDs, or view them next to the player names on the meeting screen. Example use: <b>/cmd summon 5</b></size>",
|
||||
"Summoner.SummonedTimeToKill": "Time To Kill For Summoned Players",
|
||||
"Summoner.SummonDelayAfterMeeting": "Summon Delay After Meetings",
|
||||
"Summoner.SummonedKillCooldown": "Summoned Player's Kill Cooldown",
|
||||
"Summoner.SummonedKnowsCoven": "Summoned Players Know Coven Members",
|
||||
"Summoner.PlayersSeeSummonedPlayerWarning": "Players See Who The Summoned Player Is",
|
||||
"Summoner.AllowSummoningTheSamePlayerTwice": "Allow Summoning The Same Player Twice",
|
||||
"Summoner.ReSummonTakesAbilityUse": "Re-Summoning Takes Ability Use",
|
||||
"Summoner.SummonedKillsCountForSummoner": "Players who were killed by Summoned Players have the <#7b3fbb>Summoner</color> as their Real Killer",
|
||||
"Summoner.BlockMeetingsWhileSummonedPlayerAlive": "Block Meetings While a Summoned Player Is Alive",
|
||||
"Summoner.SomeoneWillBeRevivedMessage": "Someone from the dead has been chosen to kill for the Coven.",
|
||||
"Summoner.SelfSuffix": "<size=80%>{0} has {1}s to kill</size>",
|
||||
"Summoner.SummonedPlayerSuffix": "<size=120%><#ffff00>{0}, the {1} summoned you to kill for them!\\nYou have</color> {2}s</size>",
|
||||
"Summoner.SummonedWarningSuffix": "Summoned to kill for the Coven",
|
||||
"Summoner.SummonSuccessMessage": "<#00ff00>✓ <#00bb00>{0} will be summoned after the meeting to kill for you",
|
||||
"Summoner.CantSummonSamePlayerTwice": "<#ff5555>X <#bb0000>The same player cannot be summoned twice",
|
||||
"SummonerCantKillCoven": "As a summoned player, you kill for the Coven, meaning you can't kill Coven members",
|
||||
"SummonedPlayerAlive": "Meetings can't be started while a summoned player is alive",
|
||||
"Timelord": "Timelord",
|
||||
"TimelordInfo": "Refresh or reset cooldowns; kill",
|
||||
"TimelordInfoLong": "(Coven):\\nUse your ability on a Coven member to refresh their cooldown (set it to 0). Use your ability on a non-Coven member to reset their cooldown. When enhanced by the Necronomicon, you can kill and also reduce meeting time upon making a kill.",
|
||||
|
||||
@@ -45,7 +45,7 @@ public class CovenMember : CovenBase
|
||||
foreach (CovenMember instance in Instances)
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(instance.CovenMemberId);
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
if (!pc || !pc.IsAlive()) continue;
|
||||
pc.RpcSetCustomRole(CustomRoles.CovenLeader);
|
||||
pc.RpcChangeRoleBasis(CustomRoles.CovenLeader);
|
||||
pc.MarkDirtySettings();
|
||||
|
||||
@@ -12,7 +12,16 @@ public class Summoner : CovenBase
|
||||
public static bool On;
|
||||
public static List<Summoner> Instances = [];
|
||||
public static HashSet<byte> AdditionalWinners = [];
|
||||
public static HashSet<byte> AlreadySummoned = [];
|
||||
|
||||
private static OptionItem SummonDelayAfterMeeting;
|
||||
private static OptionItem SummonedKillCooldown;
|
||||
private static OptionItem SummonedKnowsCoven;
|
||||
private static OptionItem PlayersSeeSummonedPlayerWarning;
|
||||
public static OptionItem AllowSummoningTheSamePlayerTwice;
|
||||
public static OptionItem ReSummonTakesAbilityUse;
|
||||
private static OptionItem SummonedKillsCountForSummoner;
|
||||
private static OptionItem BlockMeetingsWhileSummonedPlayerAlive;
|
||||
private static OptionItem SummonedTimeToKill;
|
||||
private static OptionItem AbilityUseLimit;
|
||||
private static OptionItem AbilityUseGainWithEachKill;
|
||||
@@ -34,6 +43,14 @@ public class Summoner : CovenBase
|
||||
public override void SetupCustomOption()
|
||||
{
|
||||
StartSetup(658000)
|
||||
.AutoSetupOption(ref SummonDelayAfterMeeting, 10f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref SummonedKillCooldown, 15f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref SummonedKnowsCoven, true)
|
||||
.AutoSetupOption(ref PlayersSeeSummonedPlayerWarning, true)
|
||||
.AutoSetupOption(ref AllowSummoningTheSamePlayerTwice, true)
|
||||
.AutoSetupOption(ref ReSummonTakesAbilityUse, true, overrideParent: AllowSummoningTheSamePlayerTwice)
|
||||
.AutoSetupOption(ref SummonedKillsCountForSummoner, true)
|
||||
.AutoSetupOption(ref BlockMeetingsWhileSummonedPlayerAlive, true)
|
||||
.AutoSetupOption(ref SummonedTimeToKill, 30f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref AbilityUseLimit, 1f, new FloatValueRule(0, 20, 0.05f), OptionFormat.Times)
|
||||
.AutoSetupOption(ref AbilityUseGainWithEachKill, 0.3f, new FloatValueRule(0f, 5f, 0.1f), OptionFormat.Times)
|
||||
@@ -49,6 +66,7 @@ public class Summoner : CovenBase
|
||||
On = false;
|
||||
Instances = [];
|
||||
AdditionalWinners = [];
|
||||
AlreadySummoned = [];
|
||||
}
|
||||
|
||||
public override void Add(byte playerId)
|
||||
@@ -91,22 +109,34 @@ public class Summoner : CovenBase
|
||||
return HasNecronomicon && CanVentAfterNecronomicon.GetBool();
|
||||
}
|
||||
|
||||
public static bool OnAnyoneReport()
|
||||
{
|
||||
return !Instances.Exists(x => x.SummonedPlayerId != byte.MaxValue);
|
||||
}
|
||||
|
||||
public override void AfterMeetingTasks()
|
||||
{
|
||||
if (SummonedPlayerId != byte.MaxValue && Main.PlayerStates.TryGetValue(SummonedPlayerId, out var state))
|
||||
LateTask.New(() =>
|
||||
{
|
||||
var summoned = SummonedPlayerId.GetPlayer();
|
||||
if (!GameStates.IsInTask || ExileController.Instance || AntiBlackout.SkipTasks) return;
|
||||
if (SummonedPlayerId == byte.MaxValue || !Main.PlayerStates.TryGetValue(SummonedPlayerId, out var state)) return;
|
||||
|
||||
if (summoned != null && !summoned.IsAlive())
|
||||
PlayerControl summoned = SummonedPlayerId.GetPlayer();
|
||||
|
||||
if (summoned && !summoned.IsAlive())
|
||||
{
|
||||
SummonedPlayerTimer = new(SummonedTimeToKill.GetFloat(), () =>
|
||||
{
|
||||
SummonedPlayerTimer = null;
|
||||
SummonedPlayerId = byte.MaxValue;
|
||||
if (summoned == null || !summoned.IsAlive()) return;
|
||||
if (!summoned || !summoned.IsAlive()) return;
|
||||
state.SetDead();
|
||||
summoned.RpcExileV2();
|
||||
}, onTick: () => Utils.NotifyRoles(SpecifySeer: summoned, SpecifyTarget: summoned), onCanceled: () => SummonedPlayerTimer = null);
|
||||
}, onTick: () => Utils.NotifyRoles(SpecifySeer: summoned, SpecifyTarget: summoned), onCanceled: () =>
|
||||
{
|
||||
SummonedPlayerTimer = null;
|
||||
SummonedPlayerId = byte.MaxValue;
|
||||
});
|
||||
|
||||
RPC.PlaySoundRPC(SummonedPlayerId, Sounds.SpawnSound);
|
||||
GhostRolesManager.RemoveGhostRole(SummonedPlayerId);
|
||||
@@ -116,18 +146,18 @@ public class Summoner : CovenBase
|
||||
summoned.RpcChangeRoleBasis(CustomRoles.SerialKiller);
|
||||
summoned.SyncGeneralOptions();
|
||||
summoned.SyncSettings();
|
||||
summoned.TP(FastVector2.TryGetClosestPlayerTo(summoned, out PlayerControl closest) ? closest : PlayerControl.LocalPlayer);
|
||||
LateTask.New(() => summoned.SetKillCooldown(10f), 0.2f);
|
||||
summoned.TPToRandomVent();
|
||||
LateTask.New(() => summoned.SetKillCooldown(SummonedKillCooldown.GetFloat()), 0.2f);
|
||||
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, SummonerId, 1, SummonedPlayerId);
|
||||
}
|
||||
}
|
||||
}, Math.Max(0, SummonDelayAfterMeeting.GetFloat() - 2f), "Summon Delay");
|
||||
|
||||
|
||||
if (!HasNecronomicon || Changed) return;
|
||||
|
||||
var summoner = SummonerId.GetPlayer();
|
||||
if (summoner == null || !summoner.IsAlive()) return;
|
||||
if (!summoner || !summoner.IsAlive()) return;
|
||||
|
||||
summoner.RpcChangeRoleBasis(CustomRoles.SerialKiller);
|
||||
summoner.ResetKillCooldown();
|
||||
@@ -145,7 +175,7 @@ public class Summoner : CovenBase
|
||||
public override bool KnowRole(PlayerControl seer, PlayerControl target)
|
||||
{
|
||||
if (base.KnowRole(seer, target)) return true;
|
||||
return seer.PlayerId == SummonedPlayerId && target.Is(Team.Coven);
|
||||
return SummonedKnowsCoven.GetBool() && seer.PlayerId == SummonedPlayerId && target.Is(Team.Coven);
|
||||
}
|
||||
|
||||
public static bool OnAnyoneCheckMurder(PlayerControl killer, PlayerControl target)
|
||||
@@ -153,7 +183,7 @@ public class Summoner : CovenBase
|
||||
return !Instances.Exists(x => x.SummonedPlayerId == killer.PlayerId && target.Is(Team.Coven));
|
||||
}
|
||||
|
||||
public static void OnAnyoneMurder(PlayerControl killer)
|
||||
public static void OnAnyoneMurder(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
foreach (Summoner instance in Instances)
|
||||
{
|
||||
@@ -166,6 +196,7 @@ public class Summoner : CovenBase
|
||||
Main.PlayerStates[instance.SummonedPlayerId].SetDead();
|
||||
instance.SummonedPlayerId = byte.MaxValue;
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, instance.SummonerId, 2);
|
||||
if (SummonedKillsCountForSummoner.GetBool()) target.SetRealKiller(instance.SummonerId.GetPlayer());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -199,7 +230,9 @@ public class Summoner : CovenBase
|
||||
|
||||
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
|
||||
{
|
||||
if (seer.PlayerId != target.PlayerId || (seer.IsModdedClient() && !hud) || meeting || SummonedPlayerId == byte.MaxValue || SummonedPlayerTimer == null) return string.Empty;
|
||||
if (meeting || SummonedPlayerId == byte.MaxValue || SummonedPlayerTimer == null) return string.Empty;
|
||||
if (target.PlayerId == SummonedPlayerId && seer.PlayerId != target.PlayerId && PlayersSeeSummonedPlayerWarning.GetBool()) return Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoner), Translator.GetString("Summoner.SummonedWarningSuffix"));
|
||||
if (seer.PlayerId != target.PlayerId || (seer.IsModdedClient() && !hud)) return string.Empty;
|
||||
if (seer.PlayerId == SummonerId) return string.Format(Translator.GetString("Summoner.SelfSuffix"), SummonedPlayerId.ColoredPlayerName(), (int)SummonedPlayerTimer.Remaining.TotalSeconds);
|
||||
return seer.PlayerId == SummonedPlayerId ? string.Format(Translator.GetString("Summoner.SummonedPlayerSuffix"), SummonerId.ColoredPlayerName(), CustomRoles.Summoner.ToColoredString(), (int)SummonedPlayerTimer.Remaining.TotalSeconds) : string.Empty;
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ public class Altruist : RoleBase
|
||||
{
|
||||
PlayerControl revivedPlayer = revived.GetPlayer();
|
||||
|
||||
if (revivedPlayer == null || !revivedPlayer.IsAlive())
|
||||
if (!revivedPlayer || !revivedPlayer.IsAlive())
|
||||
{
|
||||
TargetArrow.Remove(pc.PlayerId, revived);
|
||||
if (GameStates.IsMeeting || ExileController.Instance) continue;
|
||||
|
||||
@@ -198,7 +198,7 @@ public class Vulture : RoleBase
|
||||
if (!Main.PlayerStates.TryGetValue(x, out PlayerState state) || state.Role is not Vulture vulture) return;
|
||||
|
||||
var pc = x.GetPlayer();
|
||||
if (pc == null || !pc.IsAlive()) return;
|
||||
if (!pc || !pc.IsAlive()) return;
|
||||
|
||||
if (ChangeRoleWhenCantWin.GetBool() && Main.AllAlivePlayerControls.Count - 1 <= NumberOfReportsToWin.GetInt() - vulture.TotalEaten)
|
||||
{
|
||||
|
||||
@@ -196,7 +196,7 @@ public class Jackal : RoleBase
|
||||
{
|
||||
if (!CanRecruitImpostors.GetBool() && pc.Is(CustomRoleTypes.Impostor)) return false;
|
||||
if (!CanRecruitMadmates.GetBool() && pc.IsMadmate()) return false;
|
||||
return pc != null && !pc.Is(CustomRoles.Sidekick) && !pc.Is(CustomRoles.Curser) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Bloodlust) && !pc.IsConverted() && pc.GetCustomRole().IsAbleToBeSidekicked();
|
||||
return pc && !pc.Is(CustomRoles.Sidekick) && !pc.Is(CustomRoles.Curser) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Bloodlust) && !pc.IsConverted() && pc.GetCustomRole().IsAbleToBeSidekicked();
|
||||
}
|
||||
|
||||
public void PromoteSidekick()
|
||||
@@ -206,7 +206,7 @@ public class Jackal : RoleBase
|
||||
if (!SKPromotesToJackal.GetBool()) return;
|
||||
|
||||
PlayerControl sk = SidekickId.GetPlayer();
|
||||
if (sk == null || !sk.Is(CustomRoles.Sidekick)) return;
|
||||
if (!sk || !sk.Is(CustomRoles.Sidekick)) return;
|
||||
|
||||
sk.RpcSetCustomRole(CustomRoles.Jackal);
|
||||
if (!PromotedSKCanRecruit.GetBool()) sk.SetAbilityUseLimit(0);
|
||||
@@ -219,7 +219,7 @@ public class Jackal : RoleBase
|
||||
Instances.ForEach(x =>
|
||||
{
|
||||
var pc = x.JackalId.GetPlayer();
|
||||
if (pc == null || pc.IsAlive()) return;
|
||||
if (!pc || pc.IsAlive()) return;
|
||||
|
||||
x.PromoteSidekick();
|
||||
});
|
||||
|
||||
@@ -138,7 +138,7 @@ internal class Necromancer : RoleBase
|
||||
{
|
||||
if (!GameStates.IsInTask || ExileController.Instance) return;
|
||||
|
||||
if ((NecromancerPC == null || !NecromancerPC.IsAlive()) && (Deathknight.DeathknightPC != null && Deathknight.DeathknightPC.IsAlive()))
|
||||
if ((!NecromancerPC || !NecromancerPC.IsAlive()) && (Deathknight.DeathknightPC && Deathknight.DeathknightPC.IsAlive()))
|
||||
{
|
||||
Deathknight.DeathknightPC.RpcSetCustomRole(CustomRoles.Necromancer);
|
||||
Deathknight.DeathknightPC = null;
|
||||
@@ -146,7 +146,7 @@ internal class Necromancer : RoleBase
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CustomRoles.Deathknight.RoleExist() && (Deathknight.DeathknightId != byte.MaxValue || Deathknight.DeathknightPC != null))
|
||||
if (!CustomRoles.Deathknight.RoleExist() && (Deathknight.DeathknightId != byte.MaxValue || Deathknight.DeathknightPC))
|
||||
{
|
||||
Deathknight.DeathknightPC = null;
|
||||
Deathknight.DeathknightId = byte.MaxValue;
|
||||
|
||||
Reference in new issue
Block a user