Fragile & Curser

This commit is contained in:
Gurge44 committed 2024-11-14 20:54:48 +01:00
1 parent ebc2db6c8f
commit 071c76e32d
20 files changed
+190 -23

No files matched your search

+2
View File
@@ -268,6 +268,7 @@
Chemist,
Cherokious,
Collector,
Curser,
Deathknight,
Gamer, // Demon
Doppelganger,
@@ -427,6 +428,7 @@
EvilSpirit,
Finder,
Flashman,
Fragile,
Fool,
Giant,
Glow,
+2
View File
@@ -456,6 +456,7 @@ namespace EHR
CustomRoles.Hookshot => RoleTypes.Impostor,
CustomRoles.Sprayer => RoleTypes.Impostor,
CustomRoles.PlagueDoctor => RoleTypes.Impostor,
CustomRoles.Curser => RoleTypes.Impostor,
CustomRoles.Postman => RoleTypes.Impostor,
CustomRoles.Shifter => RoleTypes.Impostor,
CustomRoles.Impartial => RoleTypes.Impostor,
@@ -1370,6 +1371,7 @@ namespace EHR
CustomRoles.Tank => RoleOptionType.Neutral_Benign,
CustomRoles.Totocalcio => RoleOptionType.Neutral_Benign,
CustomRoles.Arsonist => RoleOptionType.Neutral_Evil,
CustomRoles.Curser => RoleOptionType.Neutral_Evil,
CustomRoles.Jester => RoleOptionType.Neutral_Evil,
CustomRoles.Gaslighter => RoleOptionType.Neutral_Evil,
CustomRoles.God => RoleOptionType.Neutral_Evil,
+1
View File
@@ -124,6 +124,7 @@ namespace EHR
new("funnytiger#8420", "#ffd4ec", "Registered Bozo", true), // Differntperson
new("raritykey#6021", "#08f638", "DESPAIR", true), // Junko
new("stiltedgap#2406", "#ffff00", "Youtuber", true), // Marcopolo1982
new("spaglad#3866", isUp: true), // spider_191
// Sponsor
new("recentduct#6068", "#FF00FF", "高冷男模法师", false, true),
@@ -269,6 +269,7 @@ namespace EHR.Modules
President.OnAnyoneApplyGameOptions(opt);
Negotiator.OnAnyoneApplyGameOptions(opt, player.PlayerId);
Wizard.OnAnyoneApplyGameOptions(opt, player.PlayerId);
Curser.OnAnyoneApplyGameOptions(opt, player.PlayerId);
if (Sprayer.LowerVisionList.Contains(player.PlayerId))
{
+1 -1
View File
@@ -97,7 +97,7 @@ namespace EHR.Modules
if (AssignedGhostRoles.Count >= GhostRoles.Count) return false;
if (pc.IsAlive() || pc.GetCountTypes() is CountTypes.None or CountTypes.OutOfGame || pc.Is(CustomRoles.EvilSpirit)) return false;
if (pc.IsAlive() || pc.GetCountTypes() is CountTypes.None or CountTypes.OutOfGame || pc.Is(CustomRoles.EvilSpirit) || pc.Is(CustomRoles.Curser)) return false;
switch (pc.GetCustomRole())
{
+2 -2
View File
@@ -14,12 +14,12 @@ using static EHR.Translator;
namespace EHR
{
[HarmonyPatch]
public class ModUpdater
public static class ModUpdater
{
private const string URLGithub = "https://api.github.com/repos/Gurge44/EndlessHostRoles";
public const bool ForceUpdate = false;
public static bool HasUpdate;
private static bool HasOutdate;
public static bool ForceUpdate = false;
public static bool IsBroken;
private static bool IsChecked;
private static Version LatestVersion;
+7 -8
View File
@@ -74,13 +74,9 @@ namespace EHR
// Impostors and Madmates
if (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoleTypes.Impostor)) color = target.Is(CustomRoles.Egoist) && Options.ImpEgoistVisibalToAllies.GetBool() && seer != target ? Main.RoleColors[CustomRoles.Egoist] : Main.ImpostorColor;
if (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoleTypes.Impostor) && Options.MadmateKnowWhosImp.GetBool()) color = Main.ImpostorColor;
if (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoles.Madmate) && Options.ImpKnowWhosMadmate.GetBool()) color = Main.RoleColors[CustomRoles.Madmate];
if (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoles.Madmate) && Options.MadmateKnowWhosMadmate.GetBool()) color = Main.RoleColors[CustomRoles.Madmate];
if (Blackmailer.On && seerRoleClass is Blackmailer { IsEnable: true } bm && bm.BlackmailedPlayerIds.Contains(target.PlayerId)) color = Main.RoleColors[CustomRoles.BloodKnight];
if (Commander.On && seer.Is(Team.Impostor))
@@ -95,13 +91,9 @@ namespace EHR
// Add-ons
if (target.Is(CustomRoles.Glow) && Utils.IsActive(SystemTypes.Electrical)) color = Main.RoleColors[CustomRoles.Glow];
if (target.Is(CustomRoles.Mare) && Utils.IsActive(SystemTypes.Electrical) && !isMeeting) color = Main.RoleColors[CustomRoles.Mare];
if (seer.Is(CustomRoles.Contagious) && target.Is(CustomRoles.Contagious) && Virus.TargetKnowOtherTarget.GetBool()) color = Main.RoleColors[CustomRoles.Virus];
if (seer.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Charmed) && Succubus.TargetKnowOtherTarget.GetBool()) color = Main.RoleColors[CustomRoles.Charmed];
if (seer.Is(CustomRoles.Undead) && target.Is(CustomRoles.Undead)) color = Main.RoleColors[CustomRoles.Undead];
// Ghost roles
@@ -179,6 +171,13 @@ namespace EHR
Team.Neutral => Main.NeutralColor,
_ => color
},
CustomRoles.Curser when ((Curser)seerRoleClass).KnownFactionPlayers.Contains(target.PlayerId) => target.GetTeam() switch
{
Team.Impostor => Main.ImpostorColor,
Team.Crewmate => Main.CrewmateColor,
Team.Neutral => Main.NeutralColor,
_ => color
},
_ => color
};
+3 -4
View File
@@ -2824,6 +2824,9 @@ other: ∟ ⌠ ⌡ ╬ ╨ ▓ ▒ ░ « » █ ▄ ▌▀▐│ ┤ ╡ ╢
switch (target.GetCustomRole())
{
case CustomRoles.Curser:
((Curser)Main.PlayerStates[target.PlayerId].Role).OnDeath();
break;
case CustomRoles.Camouflager when Camouflager.IsActive:
Camouflager.IsDead();
break;
@@ -2885,13 +2888,9 @@ other: ∟ ⌠ ⌡ ╬ ╨ ▓ ▒ ░ « » █ ▄ ▌▀▐│ ┤ ╡ ╢
if (target == null) return;
if (!disconnect) Randomizer.OnAnyoneDeath(target);
if (Executioner.Target.ContainsValue(target.PlayerId)) Executioner.ChangeRoleByTarget(target);
if (Lawyer.Target.ContainsValue(target.PlayerId)) Lawyer.ChangeRoleByTarget(target);
if (!disconnect && target.Is(CustomRoles.Stained)) Stained.OnDeath(target, target.GetRealKiller());
if (!disconnect && target.Is(CustomRoles.Spurt)) Spurt.DeathTask(target);
Postman.CheckAndResetTargets(target, true);
+4
View File
@@ -221,6 +221,10 @@ namespace EHR
case CustomRoles.SchrodingersCat when !pc.IsConverted():
WinnerIds.Remove(pc.PlayerId);
break;
case CustomRoles.Curser when WinnerTeam != CustomWinner.Crewmate:
WinnerIds.Add(pc.PlayerId);
AdditionalWinnerTeams.Add(AdditionalWinners.Curser);
break;
}
}
+1 -1
View File
@@ -1012,7 +1012,7 @@ namespace EHR
return;
}
List<PlayerControl> allPlayers = Main.AllPlayerControls.Where(pc => (!Main.NeverSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary<CustomRoles, List<CustomRoles>> bannedCombos) || bannedCombos.All(x => !pc.Is(x.Key) || !x.Value.Contains(CustomRoles.Lovers))) && !pc.Is(CustomRoles.GM) && (!pc.HasSubRole() || pc.GetCustomSubRoles().Count < Options.NoLimitAddonsNumMax.GetInt()) && !pc.Is(CustomRoles.Dictator) && !pc.Is(CustomRoles.God) && !pc.Is(CustomRoles.FFF) && !pc.Is(CustomRoles.Bomber) && !pc.Is(CustomRoles.Nuker) && !pc.Is(CustomRoles.Provocateur) && !pc.Is(CustomRoles.Altruist) && (!pc.IsCrewmate() || Lovers.CrewCanBeInLove.GetBool()) && (!pc.GetCustomRole().IsNeutral() || Lovers.NeutralCanBeInLove.GetBool()) && (!pc.IsImpostor() || Lovers.ImpCanBeInLove.GetBool())).ToList();
List<PlayerControl> allPlayers = Main.AllPlayerControls.Where(pc => (!Main.NeverSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary<CustomRoles, List<CustomRoles>> bannedCombos) || bannedCombos.All(x => !pc.Is(x.Key) || !x.Value.Contains(CustomRoles.Lovers))) && !pc.Is(CustomRoles.GM) && (!pc.HasSubRole() || pc.GetCustomSubRoles().Count < Options.NoLimitAddonsNumMax.GetInt()) && !pc.Is(CustomRoles.Dictator) && !pc.Is(CustomRoles.God) && !pc.Is(CustomRoles.FFF) && !pc.Is(CustomRoles.Bomber) && !pc.Is(CustomRoles.Nuker) && !pc.Is(CustomRoles.Curser) && !pc.Is(CustomRoles.Provocateur) && !pc.Is(CustomRoles.Altruist) && (!pc.IsCrewmate() || Lovers.CrewCanBeInLove.GetBool()) && (!pc.GetCustomRole().IsNeutral() || Lovers.NeutralCanBeInLove.GetBool()) && (!pc.IsImpostor() || Lovers.ImpCanBeInLove.GetBool())).ToList();
const CustomRoles role = CustomRoles.Lovers;
int count = Math.Clamp(RawCount, 0, allPlayers.Count);
if (RawCount == -1) count = Math.Clamp(role.GetCount(), 0, allPlayers.Count);
+1 -1
View File
@@ -280,7 +280,7 @@ namespace EHR
bool CheckMurder()
{
return Main.PlayerStates[killer.PlayerId].Role.OnCheckMurder(killer, target);
return Main.PlayerStates[killer.PlayerId].Role.OnCheckMurder(killer, target) || target.Is(CustomRoles.Fragile);
}
}
+7
View File
@@ -3981,6 +3981,9 @@
"BackstabberTeam.NK": "a <#ffab1b>Neutral Killer</color>",
"Backstabber.RevealAfterKilling": "Revealed after killing",
"GuessBackstabber": "You cannot guess a revealed Backstabber.",
"Curser": "Curser",
"CurserInfo": "Make Others' Life Worse",
"CurserInfoLong": "(Impostors):\\nAs the Curser, when you use your kill button on someone, they will get one of the following:<size=80%>\\n- -1 ability use\\n- +1 harmful add-on\\n- permanent low vision\\n- permanent low speed</size>\\nYou win if crewmates lose.",
"Postman": "Postman",
"PostmanInfo": "Deliver Mail to Everyone!",
"PostmanInfoLong": "(Neutral):\\nAs the Postman, your job is to deliver mail to everyone. You'll always have a target, and you need to click your kill button on that target to deliver the mail to them. When you've delivered mail to everyone, your win condition is satisfied. You'll win with the winning team, no matter what happens.",
@@ -4644,6 +4647,10 @@
"SpurtModule": "Speed Modulator",
"EnableSpurtCharge": "Display The Charge",
"SpurtSuffix": "\\n« <color=#c9e8f5>Spurt</color>: {0}% »",
"Fragile": "Fragile",
"FragileInfo": "Everything Kills You",
"FragileInfoLong": "(Add-ons):\\nAs the Fragile, even if someone uses their kill button on you with a non-killing intent, they'll kill you anyway.",
"Prefix.Fragile": "Fragile",
"Nimble": "Nimble",
"NimbleInfo": "Grants Vent Access",
"NimbleInfoLong": "(Add-ons):\\nGrants Vent Access for Crewmate Roles.",
+12
View File
@@ -0,0 +1,12 @@
namespace EHR.AddOns.Common
{
public class Fragile : IAddon
{
public AddonTypes Type => AddonTypes.Harmful;
public void SetupCustomOption()
{
Options.SetupAdtRoleOptions(645333, CustomRoles.Fragile, canSetNum: true, teamSpawnOptions: true);
}
}
}
+137
View File
@@ -0,0 +1,137 @@
using System.Collections.Generic;
using System.Linq;
using AmongUs.GameOptions;
namespace EHR.Neutral
{
public class Curser : RoleBase
{
public static bool On;
private static List<Curser> Instances = [];
private static OptionItem AbilityUseLimit;
private static OptionItem AbilityCooldown;
private static OptionItem ImpostorVision;
private static OptionItem CanVent;
private static OptionItem LowerVision;
private static OptionItem LowerSpeed;
public HashSet<byte> KnownFactionPlayers = [];
private HashSet<byte> LowerSpeedPlayers = [];
private HashSet<byte> LowerVisionPlayers = [];
public override bool IsEnable => On;
public override void SetupCustomOption()
{
StartSetup(645450)
.AutoSetupOption(ref AbilityUseLimit, 3, new IntegerValueRule(1, 20, 1), OptionFormat.Times)
.AutoSetupOption(ref AbilityCooldown, 15f, new FloatValueRule(0.5f, 90f, 0.5f), OptionFormat.Seconds)
.AutoSetupOption(ref ImpostorVision, false)
.AutoSetupOption(ref CanVent, false)
.AutoSetupOption(ref LowerVision, 0.3f, new FloatValueRule(0f, 1.5f, 0.05f), OptionFormat.Multiplier)
.AutoSetupOption(ref LowerSpeed, 0.7f, new FloatValueRule(0.05f, 3f, 0.05f), OptionFormat.Multiplier);
}
public override void Init()
{
On = false;
Instances = [];
}
public override void Add(byte playerId)
{
On = true;
Instances.Add(this);
LowerVisionPlayers = [];
LowerSpeedPlayers = [];
KnownFactionPlayers = [];
playerId.SetAbilityUseLimit(AbilityUseLimit.GetInt());
}
public override bool CanUseKillButton(PlayerControl pc)
{
return pc.IsAlive();
}
public override void SetKillCooldown(byte id)
{
Main.AllPlayerKillCooldown[id] = AbilityCooldown.GetFloat();
}
public override bool CanUseImpostorVentButton(PlayerControl pc)
{
return CanVent.GetBool();
}
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
{
opt.SetVision(ImpostorVision.GetBool());
}
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
{
if (killer.CheckDoubleTrigger(target, () =>
{
KnownFactionPlayers.Add(target.PlayerId);
Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target);
}))
{
int random = IRandom.Instance.Next(4);
switch (random)
{
case 0:
target.RpcRemoveAbilityUse();
break;
case 1:
var addons = Options.GroupedAddons[AddonTypes.Harmful].Where(x => !target.Is(x) && CustomRolesHelper.CheckAddonConflict(x, target));
target.RpcSetCustomRole(addons.RandomElement());
break;
case 2:
LowerVisionPlayers.Add(target.PlayerId);
target.MarkDirtySettings();
break;
case 3:
LowerSpeedPlayers.Add(target.PlayerId);
target.MarkDirtySettings();
break;
}
killer.Notify(Translator.GetString($"Curser.Notify.{random}"));
killer.SetKillCooldown();
}
return false;
}
public static void OnAnyoneApplyGameOptions(IGameOptions opt, byte playerId)
{
foreach (Curser instance in Instances)
{
if (instance.LowerVisionPlayers.Contains(playerId))
{
opt.SetVision(false);
float vision = LowerVision.GetFloat();
opt.SetFloat(FloatOptionNames.CrewLightMod, vision);
opt.SetFloat(FloatOptionNames.ImpostorLightMod, vision);
}
if (instance.LowerSpeedPlayers.Contains(playerId))
{
Main.AllPlayerSpeed[playerId] = LowerSpeed.GetFloat();
}
}
}
public void OnDeath()
{
LowerVisionPlayers.UnionWith(LowerSpeedPlayers);
var players = LowerVisionPlayers.ToValidPlayers().ToArray();
LowerVisionPlayers.Clear();
LowerSpeedPlayers.Clear();
players.Do(x => x.MarkDirtySettings());
}
}
}
+1 -1
View File
@@ -184,7 +184,7 @@ namespace EHR.Neutral
if (!CanRecruitMadmates.GetBool() && pc.IsMadmate()) return false;
return pc != null && !pc.Is(CustomRoles.Sidekick) && !pc.Is(CustomRoles.Loyal) && !pc.IsConverted() && pc.GetCustomRole().IsAbleToBeSidekicked();
return pc != null && !pc.Is(CustomRoles.Sidekick) && !pc.Is(CustomRoles.Curser) && !pc.Is(CustomRoles.Loyal) && !pc.IsConverted() && pc.GetCustomRole().IsAbleToBeSidekicked();
}
public override void OnFixedUpdate(PlayerControl pc)
+1 -1
View File
@@ -68,7 +68,7 @@ namespace EHR.Neutral
if (AmongUsClient.Instance.AmHost)
{
List<PlayerControl> targetList = [];
targetList.AddRange(from target in Main.AllPlayerControls where playerId != target.PlayerId where CanTargetImpostor.GetBool() || !target.Is(CustomRoleTypes.Impostor) where CanTargetNeutralKiller.GetBool() || !target.IsNeutralKiller() where CanTargetCrewmate.GetBool() || !target.Is(CustomRoleTypes.Crewmate) where CanTargetJester.GetBool() || !target.Is(CustomRoles.Jester) where !target.Is(CustomRoleTypes.Neutral) || target.IsNeutralKiller() || target.Is(CustomRoles.Jester) where target.GetCustomRole() is not (CustomRoles.GM or CustomRoles.SuperStar) where Main.LoversPlayers.TrueForAll(x => x.PlayerId != playerId) select target);
targetList.AddRange(from target in Main.AllPlayerControls where playerId != target.PlayerId where CanTargetImpostor.GetBool() || !target.Is(CustomRoleTypes.Impostor) where CanTargetNeutralKiller.GetBool() || !target.IsNeutralKiller() where CanTargetCrewmate.GetBool() || !target.Is(CustomRoleTypes.Crewmate) where CanTargetJester.GetBool() || !target.Is(CustomRoles.Jester) where !target.Is(CustomRoleTypes.Neutral) || target.IsNeutralKiller() || target.Is(CustomRoles.Jester) where target.GetCustomRole() is not (CustomRoles.GM or CustomRoles.SuperStar or CustomRoles.Curser) where Main.LoversPlayers.TrueForAll(x => x.PlayerId != playerId) select target);
if (targetList.Count == 0)
{
+2 -2
View File
@@ -88,7 +88,7 @@ namespace EHR.Neutral
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
{
if (Deathknight.DeathknightId == byte.MaxValue && !target.Is(CustomRoles.Loyal) && !target.IsConverted())
if (Deathknight.DeathknightId == byte.MaxValue && !target.Is(CustomRoles.Loyal) && !target.Is(CustomRoles.Curser) && !target.IsConverted())
{
target.RpcChangeRoleBasis(CustomRoles.Deathknight);
target.RpcSetCustomRole(CustomRoles.Deathknight);
@@ -159,7 +159,7 @@ namespace EHR.Neutral
public static bool CanBeUndead(PlayerControl pc)
{
return pc != null && !pc.Is(CustomRoles.Deathknight) && !pc.Is(CustomRoles.Necromancer) && !pc.Is(CustomRoles.Undead) && !pc.Is(CustomRoles.Loyal) && !pc.IsConverted();
return pc != null && !pc.Is(CustomRoles.Deathknight) && !pc.Is(CustomRoles.Necromancer) && !pc.Is(CustomRoles.Undead) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Curser) && !pc.IsConverted();
}
}
+1 -1
View File
@@ -140,7 +140,7 @@ namespace EHR.Neutral
public static bool CanBeCharmed(PlayerControl pc)
{
return pc != null && (pc.IsCrewmate() || pc.IsImpostor() ||
(CanCharmNeutral.GetBool() && (pc.GetCustomRole().IsNeutral() || pc.IsNeutralKiller()))) && !pc.Is(CustomRoles.Charmed) && !pc.Is(CustomRoles.Loyal);
(CanCharmNeutral.GetBool() && (pc.GetCustomRole().IsNeutral() || pc.IsNeutralKiller()))) && !pc.Is(CustomRoles.Charmed) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Curser);
}
public override void OnFixedUpdate(PlayerControl pc)
+1 -1
View File
@@ -196,7 +196,7 @@ namespace EHR.Neutral
private static bool CanBeInfected(PlayerControl pc)
{
return !pc.Is(CustomRoles.Virus) && !pc.Is(CustomRoles.Contagious) && !pc.Is(CustomRoles.Loyal);
return !pc.Is(CustomRoles.Virus) && !pc.Is(CustomRoles.Contagious) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Curser);
}
}
}
+3
View File
@@ -505,6 +505,7 @@ namespace EHR
{ CustomRoles.Hookshot, "#32a852" },
{ CustomRoles.Sprayer, "#ffc038" },
{ CustomRoles.PlagueDoctor, "#ff6633" },
{ CustomRoles.Curser, "#510c91" },
{ CustomRoles.Postman, "#00b893" },
{ CustomRoles.SchrodingersCat, "#616161" },
{ CustomRoles.Shifter, "#777777" },
@@ -567,6 +568,7 @@ namespace EHR
{ CustomRoles.Messenger, "#28b573" },
{ CustomRoles.Dynamo, "#ebe534" },
{ CustomRoles.AntiTP, "#fcba03" },
{ CustomRoles.Fragile, "#debe66" },
{ CustomRoles.Allergic, "#e3bd56" },
{ CustomRoles.Introvert, "#6293e3" },
{ CustomRoles.Deadlined, "#ffa500" },
@@ -893,6 +895,7 @@ namespace EHR
Phantom = CustomRoles.Phantasm,
Sidekick = CustomRoles.Sidekick,
Maverick = CustomRoles.Maverick,
Curser = CustomRoles.Curser,
Postman = CustomRoles.Postman,
Impartial = CustomRoles.Impartial,
Gaslighter = CustomRoles.Gaslighter,