mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-19 15:51:58 +00:00
Add Moon Dancer
This commit is contained in:
1 parent
d3146283ad
commit
18ef8d83df
7 files changed
+156
-7
No files matched your search
@@ -416,6 +416,7 @@ public enum CustomRoles
|
||||
Enchanter,
|
||||
Goddess,
|
||||
Illusionist,
|
||||
MoonDancer,
|
||||
Poache,
|
||||
PotionMaster,
|
||||
Reaper,
|
||||
|
||||
@@ -605,6 +605,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Enchanter => RoleTypes.Impostor,
|
||||
CustomRoles.Siren => RoleTypes.Phantom,
|
||||
CustomRoles.Wyrd => RoleTypes.Shapeshifter,
|
||||
CustomRoles.MoonDancer => RoleTypes.Phantom,
|
||||
|
||||
_ => RoleTypes.GuardianAngel
|
||||
};
|
||||
@@ -1116,7 +1117,7 @@ internal static class CustomRolesHelper
|
||||
|
||||
public static bool CheckAddonConflict(CustomRoles role, PlayerControl pc)
|
||||
{
|
||||
return role.IsAdditionRole() && (!Main.NeverSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary<CustomRoles, List<CustomRoles>> neverList) || !neverList.TryGetValue(pc.GetCustomRole(), out List<CustomRoles> bannedAddonList) || !bannedAddonList.Contains(role)) && pc.GetCustomRole() is not CustomRoles.GuardianAngelEHR and not CustomRoles.God && !pc.Is(CustomRoles.Madmate) && !pc.Is(CustomRoles.GM) && role is not CustomRoles.Lovers && !pc.Is(CustomRoles.LazyGuy) && (!pc.HasSubRole() || pc.GetCustomSubRoles().Count < Options.NoLimitAddonsNumMax.GetInt()) && (!Options.AddonCanBeSettings.TryGetValue(role, out (OptionItem Imp, OptionItem Neutral, OptionItem Crew, OptionItem Coven) o) || ((o.Imp.GetBool() || !pc.GetCustomRole().IsImpostor()) && (o.Neutral.GetBool() || !pc.GetCustomRole().IsNeutral()) && (o.Crew.GetBool() || !pc.IsCrewmate()) && (o.Coven.GetBool() || !pc.Is(Team.Coven)))) && (!role.IsImpOnlyAddon() || (pc.IsImpostor() && !pc.Is(CustomRoles.DoubleAgent)) || (pc.Is(CustomRoles.Traitor) && Traitor.CanGetImpostorOnlyAddons.GetBool())) && role switch
|
||||
return role.IsAdditionRole() && !(role.IsGhostRole() && pc.IsAlive()) && (!Main.NeverSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary<CustomRoles, List<CustomRoles>> neverList) || !neverList.TryGetValue(pc.GetCustomRole(), out List<CustomRoles> bannedAddonList) || !bannedAddonList.Contains(role)) && pc.GetCustomRole() is not CustomRoles.GuardianAngelEHR and not CustomRoles.God && !pc.Is(CustomRoles.Madmate) && !pc.Is(CustomRoles.GM) && role is not CustomRoles.Lovers && !pc.Is(CustomRoles.LazyGuy) && (!pc.HasSubRole() || pc.GetCustomSubRoles().Count < Options.NoLimitAddonsNumMax.GetInt()) && (!Options.AddonCanBeSettings.TryGetValue(role, out (OptionItem Imp, OptionItem Neutral, OptionItem Crew, OptionItem Coven) o) || ((o.Imp.GetBool() || !pc.GetCustomRole().IsImpostor()) && (o.Neutral.GetBool() || !pc.GetCustomRole().IsNeutral()) && (o.Crew.GetBool() || !pc.IsCrewmate()) && (o.Coven.GetBool() || !pc.Is(Team.Coven)))) && (!role.IsImpOnlyAddon() || (pc.IsImpostor() && !pc.Is(CustomRoles.DoubleAgent)) || (pc.Is(CustomRoles.Traitor) && Traitor.CanGetImpostorOnlyAddons.GetBool())) && role switch
|
||||
{
|
||||
CustomRoles.Blind when pc.Is(CustomRoles.Sensor) => false,
|
||||
CustomRoles.Composter when float.IsNaN(pc.GetAbilityUseLimit()) => false,
|
||||
@@ -1285,7 +1286,8 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Timelord or
|
||||
CustomRoles.Enchanter or
|
||||
CustomRoles.Siren or
|
||||
CustomRoles.Wyrd;
|
||||
CustomRoles.Wyrd or
|
||||
CustomRoles.MoonDancer;
|
||||
}
|
||||
|
||||
public static bool IncompatibleWithVenom(this CustomRoles role)
|
||||
|
||||
@@ -74,6 +74,7 @@ public class PlayerState(byte playerId)
|
||||
Deafened,
|
||||
Patrolled,
|
||||
Misguess,
|
||||
LossOfBlood,
|
||||
|
||||
// Natural Disasters
|
||||
Meteor,
|
||||
|
||||
@@ -1804,7 +1804,7 @@
|
||||
"TargetKnowsLawyer": "Target knows their <color=#008080>Lawyer</color>",
|
||||
"YourLawyerIsNotify": "Your <color=#008080>Lawyer</color> is {0}. They win if you win.",
|
||||
"ShowLongInfo": "Show Long Role Descriptions instead of Short ones",
|
||||
"InfectiousBiteCooldownIncrese": "Infect Cooldown Increase Per Use",
|
||||
"InfectiousBiteCooldownIncrese": "Infect Cooldown Increase Per Kill",
|
||||
"InfectiousBiteMax": "Maximum Infections",
|
||||
"InfectiousKnowTargetRole": "Know <color=#7B8968>infected</color> player's role",
|
||||
"InfectiousTargetKnowOtherTarget": "<color=#7B8968>Infected</color> players know each other",
|
||||
@@ -1979,6 +1979,7 @@
|
||||
"DeathReason.Deafened": "Deafened",
|
||||
"DeathReason.Patrolled": "Patrolled",
|
||||
"DeathReason.Misguess": "Misguess",
|
||||
"DeathReason.LossOfBlood": "Loss Of Blood",
|
||||
"ND_DRLaughMessage.Meteor": "Meteor.... I hardly knew her!",
|
||||
"ND_DRLaughMessage.Lava": "Lava is not the best place to swim, huh?",
|
||||
"ND_DRLaughMessage.Tornado": "Out for a spin? I hope this tornado didn't make you dizzy!",
|
||||
@@ -9462,6 +9463,7 @@
|
||||
"Bloodmoon.Suffix": "<{1}>You will die in <{2}>{0}s</color></color>",
|
||||
"Bloodmoon.Speed": "<#ff1919>Bloodmoon</color> Speed",
|
||||
"Bloodmoon.DieOnMeetingCall": "Targets Die on Meeting Call",
|
||||
"Bloodmoon.CDCIncreasePerUse": "Cooldown Increase Per Use",
|
||||
"BloodmoonNearYou": "<#ffff00>The {0} is near you! Stay away to avoid death!</color>",
|
||||
"Prefix.Bloodmoon": "Bloodmoon",
|
||||
"GA": "Guardian Angel",
|
||||
@@ -10084,6 +10086,14 @@
|
||||
"Wyrd.Suffix.SuicideWarningOnAction.Report": "Reporting a dead body",
|
||||
"Wyrd.Suffix.SuicideWarningOnAction.Button": "Calling an emergency meeting",
|
||||
"Wyrd.Suffix.SuicideWarnings": "<#ffff00><size=80%>⚠ The following actions will cause you to suicide: ⚠\\n{0}</size></color>",
|
||||
"MoonDancer": "Moon Dancer",
|
||||
"MoonDancerInfo": "Give and Steal Add-ons",
|
||||
"MoonDancerInfoLong": "(Coven):\\nAs the Moon Dancer, you can assign yourself a random add-on. You can also use your kill button on someone,\\n- once to give them an add-on, that is: helpful if they're a coven member, otherwise harmful (assigned after the next meeting)\\n- twice to steal all add-ons from them<sup>*</sup>\\n\\nWith the Necronomicon, double clicks kill the target, while also stealing all add-ons from them<sup>*</sup>.\\n\\n<sup>*</sup>If settings allow",
|
||||
"MoonDancer.SelfAssignAddonCooldown": "Self-Assign Add-on Cooldown",
|
||||
"MoonDancer.OthersAssignAddonCooldown": "Cooldown for Assigning Add-ons to Others",
|
||||
"MoonDancer.StealAddonCooldown": "Add-on Stealing Cooldown",
|
||||
"MoonDancer.CanStealAddonsWithoutNecronomicon": "Can Steal Add-ons Without Necronomicon",
|
||||
"MoonDancer.StealAllAddonsOnKill": "Steal All Add-ons On Kill",
|
||||
"DCNotify.Hacking": "You were <color=#ff1919>banned</color> for hacking.\\n\\nPlease stop.",
|
||||
"DCNotify.Banned": "You were <color=#ff1919>banned</color> from this lobby.\\n\\nContact the host if this was a mistake.",
|
||||
"DCNotify.Kicked": "You were <color=#ffff00>kicked</color> from this lobby.\\n\\nYou may still rejoin.",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Hazel;
|
||||
|
||||
namespace EHR.AddOns.GhostRoles;
|
||||
|
||||
@@ -8,18 +10,22 @@ internal class Bloodmoon : IGhostRole
|
||||
private static OptionItem Duration;
|
||||
private static OptionItem Speed;
|
||||
private static OptionItem DieOnMeetingCall;
|
||||
private static OptionItem CDIncreasePerUse;
|
||||
|
||||
private static readonly Dictionary<byte, long> ScheduledDeaths = [];
|
||||
|
||||
private long LastUpdate;
|
||||
private byte BloodmoonID;
|
||||
|
||||
public Team Team => Team.Impostor | Team.Neutral;
|
||||
public int Cooldown => Duration.GetInt() + CD.GetInt();
|
||||
public int Cooldown => CD.GetInt() + Main.PlayerStates.Values.Count(x => x.GetRealKiller() == BloodmoonID && x.deathReason == PlayerState.DeathReason.LossOfBlood) * CDIncreasePerUse.GetInt();
|
||||
|
||||
public void OnAssign(PlayerControl pc)
|
||||
{
|
||||
Main.AllPlayerSpeed[pc.PlayerId] = Speed.GetFloat();
|
||||
pc.MarkDirtySettings();
|
||||
LastUpdate = Utils.TimeStamp;
|
||||
BloodmoonID = pc.PlayerId;
|
||||
}
|
||||
|
||||
public void OnProtect(PlayerControl pc, PlayerControl target)
|
||||
@@ -46,6 +52,10 @@ internal class Bloodmoon : IGhostRole
|
||||
|
||||
DieOnMeetingCall = new BooleanOptionItem(649405, "Bloodmoon.DieOnMeetingCall", true, TabGroup.OtherRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bloodmoon]);
|
||||
|
||||
CDIncreasePerUse = new IntegerOptionItem(649406, "Bloodmoon.CDCIncreasePerUse", new(0, 60, 1), 15, TabGroup.OtherRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bloodmoon])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
}
|
||||
|
||||
public static void Update(PlayerControl pc, Bloodmoon instance)
|
||||
@@ -67,10 +77,10 @@ internal class Bloodmoon : IGhostRole
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pc.RpcCheckAndMurder(player, true)) player.Suicide(realKiller: pc);
|
||||
if (pc.RpcCheckAndMurder(player, true)) player.Suicide(PlayerState.DeathReason.LossOfBlood, pc);
|
||||
}
|
||||
|
||||
Utils.GetPlayersInRadius(5f, pc.Pos()).DoIf(x => !x.Is(Team.Impostor), x => x.Notify(string.Format(Translator.GetString("BloodmoonNearYou"), CustomRoles.Bloodmoon.ToColoredString())));
|
||||
Utils.GetPlayersInRadius(7f, pc.Pos()).DoIf(x => !x.Is(Team.Impostor), x => x.Notify(string.Format(Translator.GetString("BloodmoonNearYou"), CustomRoles.Bloodmoon.ToColoredString()), sendOption: SendOption.None));
|
||||
}
|
||||
|
||||
public static void OnMeetingStart()
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
|
||||
namespace EHR.Coven;
|
||||
|
||||
public class MoonDancer : Coven
|
||||
{
|
||||
public static bool On;
|
||||
|
||||
public override bool IsEnable => On;
|
||||
|
||||
private static OptionItem SelfAssignAddonCooldown;
|
||||
private static OptionItem OthersAssignAddonCooldown;
|
||||
private static OptionItem StealAddonCooldown;
|
||||
private static OptionItem KillCooldown;
|
||||
private static OptionItem CanStealAddonsWithoutNecronomicon;
|
||||
private static OptionItem StealAllAddonsOnKill;
|
||||
private static OptionItem CanVentBeforeNecronomicon;
|
||||
private static OptionItem CanVentAfterNecronomicon;
|
||||
|
||||
protected override NecronomiconReceivePriorities NecronomiconReceivePriority => NecronomiconReceivePriorities.Random;
|
||||
|
||||
private Dictionary<byte, List<CustomRoles>> ToAssign = [];
|
||||
|
||||
public override void SetupCustomOption()
|
||||
{
|
||||
StartSetup(657300)
|
||||
.AutoSetupOption(ref SelfAssignAddonCooldown, 15f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref OthersAssignAddonCooldown, 15f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref StealAddonCooldown, 15f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref KillCooldown, 30f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds)
|
||||
.AutoSetupOption(ref CanStealAddonsWithoutNecronomicon, true)
|
||||
.AutoSetupOption(ref StealAllAddonsOnKill, true)
|
||||
.AutoSetupOption(ref CanVentBeforeNecronomicon, false)
|
||||
.AutoSetupOption(ref CanVentAfterNecronomicon, true);
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
On = false;
|
||||
}
|
||||
|
||||
public override void Add(byte playerId)
|
||||
{
|
||||
On = true;
|
||||
ToAssign = [];
|
||||
}
|
||||
|
||||
public override bool CanUseImpostorVentButton(PlayerControl pc)
|
||||
{
|
||||
return HasNecronomicon ? CanVentAfterNecronomicon.GetBool() : CanVentBeforeNecronomicon.GetBool();
|
||||
}
|
||||
|
||||
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
|
||||
{
|
||||
AURoleOptions.PhantomCooldown = SelfAssignAddonCooldown.GetFloat();
|
||||
AURoleOptions.PhantomDuration = 0.1f;
|
||||
}
|
||||
|
||||
public override void SetKillCooldown(byte id)
|
||||
{
|
||||
Main.AllPlayerKillCooldown[id] = HasNecronomicon ? KillCooldown.GetFloat() : OthersAssignAddonCooldown.GetFloat();
|
||||
}
|
||||
|
||||
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
if (!HasNecronomicon && !CanStealAddonsWithoutNecronomicon.GetBool())
|
||||
{
|
||||
GiveAddon();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (killer.CheckDoubleTrigger(target, GiveAddon))
|
||||
{
|
||||
if (HasNecronomicon && !StealAllAddonsOnKill.GetBool()) return true;
|
||||
PlayerState state = Main.PlayerStates[target.PlayerId];
|
||||
state.SubRoles.FindAll(x => !killer.Is(x) && !x.IsNotAssignableMidGame() && CustomRolesHelper.CheckAddonConflict(x, killer)).ForEach(x =>
|
||||
{
|
||||
killer.RpcSetCustomRole(x);
|
||||
state.RemoveSubRole(x);
|
||||
});
|
||||
if (!HasNecronomicon) killer.SetKillCooldown(StealAddonCooldown.GetFloat());
|
||||
return HasNecronomicon;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
void GiveAddon()
|
||||
{
|
||||
CustomRoles addon = Options.GroupedAddons[target.Is(Team.Coven) ? AddonTypes.Helpful : AddonTypes.Harmful].Where(x => !target.Is(x) && !x.IsNotAssignableMidGame() && CustomRolesHelper.CheckAddonConflict(x, target)).RandomElement();
|
||||
if (addon == default(CustomRoles))
|
||||
return;
|
||||
|
||||
if (ToAssign.TryGetValue(target.PlayerId, out var list))
|
||||
list.Add(addon);
|
||||
else
|
||||
ToAssign[target.PlayerId] = [addon];
|
||||
|
||||
killer.SetKillCooldown(OthersAssignAddonCooldown.GetFloat());
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnVanish(PlayerControl pc)
|
||||
{
|
||||
CustomRoles addon = Enum.GetValues<CustomRoles>().Where(x => x.IsAdditionRole() && !x.IsGhostRole() && !pc.Is(x) && !x.IsNotAssignableMidGame() && CustomRolesHelper.CheckAddonConflict(x, pc)).RandomElement();
|
||||
if (addon == default(CustomRoles)) return false;
|
||||
pc.RpcSetCustomRole(addon);
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void AfterMeetingTasks()
|
||||
{
|
||||
foreach ((byte id, List<CustomRoles> addons) in ToAssign)
|
||||
{
|
||||
var pc = id.GetPlayer();
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
|
||||
addons.ForEach(x => pc.RpcSetCustomRole(x));
|
||||
}
|
||||
|
||||
ToAssign = [];
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ public class Curser : RoleBase
|
||||
target.RpcRemoveAbilityUse();
|
||||
break;
|
||||
case 1:
|
||||
CustomRoles addon = Options.GroupedAddons[AddonTypes.Harmful].Where(x => x.IsAdditionRole() && !target.Is(x) && !x.IsNotAssignableMidGame() && CustomRolesHelper.CheckAddonConflict(x, target)).RandomElement();
|
||||
CustomRoles addon = Options.GroupedAddons[AddonTypes.Harmful].Where(x => !target.Is(x) && !x.IsNotAssignableMidGame() && CustomRolesHelper.CheckAddonConflict(x, target)).RandomElement();
|
||||
if (addon == default(CustomRoles)) goto Pick;
|
||||
target.RpcSetCustomRole(addon);
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user