diff --git a/CustomRoles.cs b/CustomRoles.cs index e25073f26..237948228 100644 --- a/CustomRoles.cs +++ b/CustomRoles.cs @@ -506,6 +506,7 @@ public enum CustomRoles Clumsy, Commited, Compelled, + Composter, Contagious, Damocles, Deadlined, diff --git a/Main.cs b/Main.cs index 106793213..00e305dd5 100644 --- a/Main.cs +++ b/Main.cs @@ -656,6 +656,7 @@ public class Main : BasePlugin { CustomRoles.Listener, "#060270" }, { CustomRoles.Unbound, "#DFC57B" }, { CustomRoles.AntiTP, "#fcba03" }, + { CustomRoles.Composter, "#8D6F64" }, { CustomRoles.TaskMaster, "#00ffa5" }, { CustomRoles.Compelled, "#D2E44C" }, { CustomRoles.Commited, "#f5c542" }, diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs index 88980794c..1d6c58dc9 100644 --- a/Modules/CustomRolesHelper.cs +++ b/Modules/CustomRolesHelper.cs @@ -1098,6 +1098,7 @@ internal static class CustomRolesHelper { return role.IsAdditionRole() && (!Main.NeverSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary> neverList) || !neverList.TryGetValue(pc.GetCustomRole(), out List 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.Needy) && (!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.Composter when float.IsNaN(pc.GetAbilityUseLimit()) => false, CustomRoles.Fragile when pc.Is(CustomRoles.SchrodingersCat) => false, CustomRoles.TaskMaster when !pc.IsCrewmate() || !Utils.HasTasks(pc.Data, forRecompute: false) => false, CustomRoles.Commited when pc.GetRoleTypes() is not (RoleTypes.Impostor or RoleTypes.Phantom or RoleTypes.Shapeshifter or RoleTypes.Viper) => false, diff --git a/Modules/GameState.cs b/Modules/GameState.cs index e5b7e1b6e..ba04eb992 100644 --- a/Modules/GameState.cs +++ b/Modules/GameState.cs @@ -484,7 +484,12 @@ public class TaskState } float add = Utils.GetSettingNameAndValueForRole(player.GetCustomRole(), "AbilityUseGainWithEachTaskCompleted"); - if (Math.Abs(add - float.MaxValue) > 0.5f && add > 0) player.RpcIncreaseAbilityUseLimitBy(add); + + if (Math.Abs(add - float.MaxValue) > 0.5f && add > 0) + { + if (player.Is(CustomRoles.Composter)) add *= Composter.AbilityUseGainMultiplier.GetFloat(); + player.RpcIncreaseAbilityUseLimitBy(add); + } } try { Main.PlayerStates[player.PlayerId].Role.OnTaskComplete(player, CompletedTasksCount, AllTasksCount); } diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 4a3f8574e..404f68f8a 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -721,7 +721,12 @@ public static class Utils if (Main.PlayerStates[killer.PlayerId].Role is Mafioso { IsEnable: true } mo) mo.OnMurder(killer, null); float add = GetSettingNameAndValueForRole(killer.GetCustomRole(), "AbilityUseGainWithEachKill"); - killer.RpcIncreaseAbilityUseLimitBy(add); + + if (Math.Abs(add - float.MaxValue) > 0.5f && add > 0) + { + if (killer.Is(CustomRoles.Composter)) add *= Composter.AbilityUseGainMultiplier.GetFloat(); + killer.RpcIncreaseAbilityUseLimitBy(add); + } } public static void ThrowException(Exception ex, [CallerFilePath] string fileName = "", [CallerLineNumber] int lineNumber = 0, [CallerMemberName] string callerMemberName = "") diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index e76de8d29..13efec580 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -2002,7 +2002,7 @@ internal static class FixedUpdatePatch if (Math.Abs(add - float.MaxValue) > 0.5f && add > 0) { if (player.Is(CustomRoles.Bloodlust)) add *= 5; - + if (player.Is(CustomRoles.Composter)) add *= Composter.AbilityUseGainMultiplier.GetFloat(); player.RpcIncreaseAbilityUseLimitBy(add); } } diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index df30be9d1..510dbc189 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -4390,6 +4390,11 @@ "FabricatorInfoLong": "(Impostors):\\nAs the Fabricator, you can use /fabricate {deathreason} to set the death reason for your next kill. Replace '{deathreason}' with one of the available death reasons in the mod.", "Fabricator.InvalidDeathReason": "<#ff5555>X <#bb0000>Invalid death reason '<#ffffff>{0}'!", "Fabricator.SetDeathReason": "<#00ff00>✓ <#00bb00>Your next kill will have the death reason: <#ffffff>{0}", + "Composter": "Composter", + "ComposterInfo": "You Gain More Ability Uses", + "ComposterInfoLong": "(Add-ons):\\nAs a Composter, you gain more ability uses by a set multiplier per task, kill, or after finishing tasks.", + "Composter.AbilityUseGainMultiplier": "Ability Use Gain Multiplier", + "Prefix.Composter": "Composter", "Slenderman": "Slenderman", "SlendermanInfo": "Everyone Gets Blinded Near You", "SlendermanInfoLong": "(Neutrals):\\nAs the Slenderman, whenever someone gets close to you, they will be blinded until they move away from you.\\n\\nKill everyone to win!", diff --git a/Roles/AddOns/Common/Composter.cs b/Roles/AddOns/Common/Composter.cs new file mode 100644 index 000000000..79bdddd1a --- /dev/null +++ b/Roles/AddOns/Common/Composter.cs @@ -0,0 +1,17 @@ +namespace EHR.AddOns.Common; + +public class Composter : IAddon +{ + public AddonTypes Type => AddonTypes.Helpful; + + public static OptionItem AbilityUseGainMultiplier; + + public void SetupCustomOption() + { + Options.SetupAdtRoleOptions(656000, CustomRoles.Composter, canSetNum: true, teamSpawnOptions: true); + + AbilityUseGainMultiplier = new FloatOptionItem(656010, "Composter.AbilityUseGainMultiplier", new(1.05f, 10f, 0.05f), 1.5f, TabGroup.Addons) + .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Composter]) + .SetValueFormat(OptionFormat.Multiplier); + } +} \ No newline at end of file