diff --git a/CustomRoles.cs b/CustomRoles.cs index 5eefa4172..0d3318380 100644 --- a/CustomRoles.cs +++ b/CustomRoles.cs @@ -161,6 +161,7 @@ public enum CustomRoles Battery, Beacon, Benefactor, + Bestower, Bodyguard, CameraMan, Captain, diff --git a/GameMode/CaptureTheFlag.cs b/GameMode/CaptureTheFlag.cs index b1760a9e7..50547a8ec 100644 --- a/GameMode/CaptureTheFlag.cs +++ b/GameMode/CaptureTheFlag.cs @@ -367,46 +367,51 @@ public static class CaptureTheFlag } yield return new WaitForSeconds(0.2f); - /* + + try + { + foreach (CTFTeamData data in TeamData.Values) + { try { - foreach (CTFTeamData data in TeamData.Values) + foreach (byte id1 in data.Players) { try { - foreach (byte id1 in data.Players) + var pc1 = id1.GetPlayer(); + if (pc1 == null) continue; + + var sender = CustomRpcSender.Create("CTF Set Teams"); + sender.StartMessage(pc1.OwnerId); + + foreach (byte id2 in data.Players) { try { - var pc1 = id1.GetPlayer(); - if (pc1 == null) continue; + if (id1 == id2) continue; - int targetClientId = pc1.OwnerId; + var pc2 = id2.GetPlayer(); + if (pc2 == null) continue; - foreach (byte id2 in data.Players) - { - try - { - if (id1 == id2) continue; - - var pc2 = id2.GetPlayer(); - if (pc2 == null) continue; - - pc2.RpcSetRoleDesync(RoleTypes.Specter, targetClientId, true); - } - catch (Exception e) { Utils.ThrowException(e); } - } + sender.StartRpc(pc2.NetId, RpcCalls.SetRole) + .Write((ushort)RoleTypes.Phantom) + .Write(true) + .EndRpc(); } catch (Exception e) { Utils.ThrowException(e); } } + + sender.SendMessage(); } catch (Exception e) { Utils.ThrowException(e); } } } catch (Exception e) { Utils.ThrowException(e); } + } + } + catch (Exception e) { Utils.ThrowException(e); } yield return new WaitForSeconds(0.2f); - */ ValidTag = true; GameStartTS = Utils.TimeStamp; @@ -423,6 +428,8 @@ public static class CaptureTheFlag data.Flag.TP(flagBase); data.Players.ToValidPlayers().MassTP(flagBase); } + + Main.AllPlayerControls.Do(x => TargetArrow.RemoveAllTarget(x.PlayerId)); } public static void OnCheckMurder(PlayerControl killer, PlayerControl target) @@ -624,6 +631,7 @@ public static class CaptureTheFlag return; } + Restart(); } } diff --git a/Main.cs b/Main.cs index 0981dc5c2..b2008f788 100644 --- a/Main.cs +++ b/Main.cs @@ -502,6 +502,7 @@ public class Main : BasePlugin { CustomRoles.Merchant, "#D27D2D" }, { CustomRoles.Telecommunication, "#7223DA" }, { CustomRoles.Deputy, "#df9026" }, + { CustomRoles.Bestower, "#4C4FE4" }, { CustomRoles.Retributionist, "#cfc999" }, { CustomRoles.Cleanser, "#98FF98" }, { CustomRoles.Swapper, "#922348" }, diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs index 3455fb344..f2601f009 100644 --- a/Modules/CustomRolesHelper.cs +++ b/Modules/CustomRolesHelper.cs @@ -481,6 +481,7 @@ internal static class CustomRolesHelper CustomRoles.Agitator => RoleTypes.Impostor, CustomRoles.Monarch => UsePets && Monarch.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor, CustomRoles.Deputy => UsePets && Deputy.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor, + CustomRoles.Bestower => UsePets && Bestower.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor, CustomRoles.Retributionist => UsePets && Retributionist.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor, CustomRoles.Arsonist => RoleTypes.Impostor, CustomRoles.Jackal => RoleTypes.Impostor, @@ -906,6 +907,7 @@ internal static class CustomRolesHelper CustomRoles.CopyCat when CopyCat.UsePet.GetBool() => true, CustomRoles.Investigator when Investigator.UsePet.GetBool() => true, CustomRoles.Deputy when Deputy.UsePet.GetBool() => true, + CustomRoles.Bestower when Bestower.UsePet.GetBool() => true, CustomRoles.Retributionist when Retributionist.UsePet.GetBool() => true, CustomRoles.Crusader when Crusader.UsePet.GetBool() => true, CustomRoles.Witness when Options.WitnessUsePet.GetBool() => true, @@ -1833,6 +1835,7 @@ internal static class CustomRolesHelper CustomRoles.Battery => RoleOptionType.Crewmate_Support, CustomRoles.Beacon => RoleOptionType.Crewmate_Support, CustomRoles.Benefactor => RoleOptionType.Crewmate_Support, + CustomRoles.Bestower => RoleOptionType.Crewmate_Support, CustomRoles.Bodyguard => RoleOptionType.Crewmate_Support, CustomRoles.Chef => RoleOptionType.Crewmate_Support, CustomRoles.Cleanser => RoleOptionType.Crewmate_Support, diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 12e6708af..91bf04309 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -944,6 +944,7 @@ public static class Utils case CustomRoles.Amnesiac when Amnesiac.RememberMode.GetValue() == 1: case CustomRoles.Monarch when !Options.UsePets.GetBool() || !Monarch.UsePet.GetBool(): case CustomRoles.Deputy when !Options.UsePets.GetBool() || !Deputy.UsePet.GetBool(): + case CustomRoles.Bestower when !Options.UsePets.GetBool() || !Bestower.UsePet.GetBool(): case CustomRoles.Virus: case CustomRoles.Investigator when !Options.UsePets.GetBool() || !Investigator.UsePet.GetBool(): case CustomRoles.Aid when !Options.UsePets.GetBool() || !Aid.UsePet.GetBool(): diff --git a/Patches/HudPatch.cs b/Patches/HudPatch.cs index 09f61fc0b..6b0335072 100644 --- a/Patches/HudPatch.cs +++ b/Patches/HudPatch.cs @@ -647,6 +647,7 @@ internal static class SetHudActivePatch case CustomRoles.Arsonist: case CustomRoles.Vigilante: case CustomRoles.Deputy: + case CustomRoles.Bestower: case CustomRoles.Monarch: case CustomRoles.Pelican: case CustomRoles.Hater: diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index 62cf3cd90..51ef0d760 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -9358,8 +9358,12 @@ "CatalystInfoLong": "(Impostors):\\nAs the Catalyst, with each kill you make, every impostor-teamed player gains a new helpful add-on. Depending on the settings, they may lose these add-ons after you die.", "Catalyst.GiveAddonsToSelf": "<#ff1919>Catalyst also receives helpful add-ons", "Catalyst.GiveOnlyEnabledAddons": "Only give enabled add-ons", - "RemoveGivenAddonsAfterDeath": "Remove all given add-ons after the <#ff1919>Catalyst dies", + "Catalyst.RemoveGivenAddonsAfterDeath": "Remove all given add-ons after the <#ff1919>Catalyst dies", "Catalyst.AddonGivenNotify": "The <#ff1919>Catalyst gave you a new add-on!", + "Bestower": "Bestower", + "BestowerInfo": "Give Ability Uses", + "BestowerInfoLong": "(Crewmates):\\nAs the Bestower, you can use your kill button to give your target more ability uses.", + "Bestower.GivenUses": "Given Uses (to other players)", "Hidden": "Hidden", "HiddenInfo": "Your Body Is Anonymous", "HiddenInfoLong": "(Add-ons):\\nYour body is anonymous.", diff --git a/Roles/Crewmate/Bestower.cs b/Roles/Crewmate/Bestower.cs new file mode 100644 index 000000000..7eff51f2d --- /dev/null +++ b/Roles/Crewmate/Bestower.cs @@ -0,0 +1,66 @@ +using System; +using AmongUs.GameOptions; + +namespace EHR.Crewmate; + +public class Bestower : RoleBase +{ + public static bool On; + + public override bool IsEnable => On; + + private static OptionItem AbilityCooldown; + private static OptionItem AbilityUseLimit; + private static OptionItem GivenUses; + public static OptionItem UsePet; + + public override void SetupCustomOption() + { + StartSetup(657200) + .AutoSetupOption(ref AbilityCooldown, 30f, new FloatValueRule(0.5f, 120f, 0.5f), OptionFormat.Seconds) + .AutoSetupOption(ref AbilityUseLimit, 3, new IntegerValueRule(1, 20, 1), OptionFormat.Times) + .AutoSetupOption(ref GivenUses, 1f, new FloatValueRule(0.05f, 20f, 0.05f), OptionFormat.Times) + .CreatePetUseSetting(ref UsePet); + } + + public override void Init() + { + On = false; + } + + public override void Add(byte playerId) + { + On = true; + playerId.SetAbilityUseLimit(AbilityUseLimit.GetInt()); + } + + public override void SetKillCooldown(byte id) + { + Main.AllPlayerKillCooldown[id] = AbilityCooldown.GetFloat(); + } + + public override bool CanUseKillButton(PlayerControl player) + { + return player.GetAbilityUseLimit() > 0; + } + + public override bool CanUseImpostorVentButton(PlayerControl pc) + { + return false; + } + + public override void ApplyGameOptions(IGameOptions opt, byte playerId) + { + opt.SetVision(false); + } + + public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) + { + float give = GivenUses.GetFloat(); + target.RpcIncreaseAbilityUseLimitBy(give); + killer.Notify(string.Format(Translator.GetString("Bestower.GaveNotify"), Math.Round(give, 2))); + killer.RpcRemoveAbilityUse(); + killer.SetKillCooldown(); + return false; + } +} \ No newline at end of file