From 93dc66e068253d7409df4df2f68bc32999afb562 Mon Sep 17 00:00:00 2001 From: MSWS Date: Tue, 27 Aug 2024 23:38:29 -0700 Subject: [PATCH] Add RTD --- Jailbreak.sln | 7 ++ lang/Jailbreak.English/RTD/RTDLocale.cs | 34 ++++++++ mod/Jailbreak.RTD/AutoRTDListener.cs | 22 +++++ mod/Jailbreak.RTD/Jailbreak.RTD.csproj | 14 +++ mod/Jailbreak.RTD/RTDCommand.cs | 68 +++++++++++++++ mod/Jailbreak.RTD/RTDRewarder.cs | 47 ++++++++++ mod/Jailbreak.RTD/RTDServiceExtensions.cs | 15 ++++ mod/Jailbreak.RTD/RTDStatsCommand.cs | 28 ++++++ mod/Jailbreak.RTD/RewardGenerator.cs | 87 +++++++++++++++++++ mod/Jailbreak.RTD/Rewards/AmmoWeaponReward.cs | 24 +++++ mod/Jailbreak.RTD/Rewards/ArmorReward.cs | 16 ++++ mod/Jailbreak.RTD/Rewards/BombReward.cs | 21 +++++ .../Rewards/CannotPickupReward.cs | 57 ++++++++++++ mod/Jailbreak.RTD/Rewards/ColorReward.cs | 43 +++++++++ mod/Jailbreak.RTD/Rewards/CreditReward.cs | 24 +++++ mod/Jailbreak.RTD/Rewards/HPReward.cs | 16 ++++ mod/Jailbreak.RTD/Rewards/NoWeaponReward.cs | 14 +++ mod/Jailbreak.RTD/Rewards/NothingReward.cs | 10 +++ .../Rewards/RandomTeleportReward.cs | 20 +++++ .../Rewards/TransparentReward.cs | 15 ++++ mod/Jailbreak.RTD/Rewards/WeaponReward.cs | 29 +++++++ mod/Jailbreak.Rebel/C4Bomb/C4Behavior.cs | 12 ++- .../SpecialDays/GunGameDay.cs | 6 +- .../SpecialDays/OneInTheChamberDay.cs | 2 +- .../Jailbreak.Formatting/Views/IRTDLocale.cs | 10 +++ .../Extensions/PlayerExtensions.cs | 1 + .../Extensions/WeaponExtensions.cs | 6 +- public/Jailbreak.Public/Mod/RTD/IRTDReward.cs | 22 +++++ .../Jailbreak.Public/Mod/RTD/IRTDRewarder.cs | 39 +++++++++ .../Mod/RTD/IRewardGenerator.cs | 11 +++ .../Jailbreak.Public/Mod/Rebel/IC4Service.cs | 2 + .../Mod/SpecialDay/AbstractSpecialDay.cs | 61 +------------ public/Jailbreak.Public/Utils/MapUtil.cs | 55 ++++++++++++ public/Jailbreak.Tag/WeaponType.cs | 52 +++++++++++ public/Jailbreak.Validator/ItemValidator.cs | 40 +-------- src/Jailbreak/Jailbreak.csproj | 1 + src/Jailbreak/JailbreakServiceCollection.cs | 4 + 37 files changed, 836 insertions(+), 99 deletions(-) create mode 100644 lang/Jailbreak.English/RTD/RTDLocale.cs create mode 100644 mod/Jailbreak.RTD/AutoRTDListener.cs create mode 100644 mod/Jailbreak.RTD/Jailbreak.RTD.csproj create mode 100644 mod/Jailbreak.RTD/RTDCommand.cs create mode 100644 mod/Jailbreak.RTD/RTDRewarder.cs create mode 100644 mod/Jailbreak.RTD/RTDServiceExtensions.cs create mode 100644 mod/Jailbreak.RTD/RTDStatsCommand.cs create mode 100644 mod/Jailbreak.RTD/RewardGenerator.cs create mode 100644 mod/Jailbreak.RTD/Rewards/AmmoWeaponReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/ArmorReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/BombReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/CannotPickupReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/ColorReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/CreditReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/HPReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/NoWeaponReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/NothingReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/RandomTeleportReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/TransparentReward.cs create mode 100644 mod/Jailbreak.RTD/Rewards/WeaponReward.cs create mode 100644 public/Jailbreak.Formatting/Views/IRTDLocale.cs create mode 100644 public/Jailbreak.Public/Mod/RTD/IRTDReward.cs create mode 100644 public/Jailbreak.Public/Mod/RTD/IRTDRewarder.cs create mode 100644 public/Jailbreak.Public/Mod/RTD/IRewardGenerator.cs create mode 100644 public/Jailbreak.Tag/WeaponType.cs diff --git a/Jailbreak.sln b/Jailbreak.sln index 698517b8..a4382dcf 100644 --- a/Jailbreak.sln +++ b/Jailbreak.sln @@ -42,6 +42,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jailbreak.Zones", "mod\Jail EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jailbreak.Trail", "mod\Jailbreak.Trail\Jailbreak.Trail.csproj", "{91F4EC7A-993A-4CA0-84C3-9F1100124A9C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jailbreak.RTD", "mod\Jailbreak.RTD\Jailbreak.RTD.csproj", "{C68D4760-7E1E-4633-995A-5EC1EF40E63B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -116,6 +118,10 @@ Global {91F4EC7A-993A-4CA0-84C3-9F1100124A9C}.Debug|Any CPU.Build.0 = Debug|Any CPU {91F4EC7A-993A-4CA0-84C3-9F1100124A9C}.Release|Any CPU.ActiveCfg = Release|Any CPU {91F4EC7A-993A-4CA0-84C3-9F1100124A9C}.Release|Any CPU.Build.0 = Release|Any CPU + {C68D4760-7E1E-4633-995A-5EC1EF40E63B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C68D4760-7E1E-4633-995A-5EC1EF40E63B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C68D4760-7E1E-4633-995A-5EC1EF40E63B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C68D4760-7E1E-4633-995A-5EC1EF40E63B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {9135CCC9-66C5-4A9C-AE3C-91475B5F0437} = {177DA48D-8306-4102-918D-992569878581} @@ -135,5 +141,6 @@ Global {A6249693-5B7E-4E14-A675-C292914F10F3} = {36BA84C0-291C-4930-A7C6-97CDF8F7F0D7} {C93A626A-BB44-4309-8DAD-4B28B2941870} = {36BA84C0-291C-4930-A7C6-97CDF8F7F0D7} {91F4EC7A-993A-4CA0-84C3-9F1100124A9C} = {36BA84C0-291C-4930-A7C6-97CDF8F7F0D7} + {C68D4760-7E1E-4633-995A-5EC1EF40E63B} = {36BA84C0-291C-4930-A7C6-97CDF8F7F0D7} EndGlobalSection EndGlobal diff --git a/lang/Jailbreak.English/RTD/RTDLocale.cs b/lang/Jailbreak.English/RTD/RTDLocale.cs new file mode 100644 index 00000000..815ad146 --- /dev/null +++ b/lang/Jailbreak.English/RTD/RTDLocale.cs @@ -0,0 +1,34 @@ +using CounterStrikeSharp.API.Modules.Utils; +using Jailbreak.Formatting.Base; +using Jailbreak.Formatting.Logistics; +using Jailbreak.Formatting.Views; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.English.RTD; + +public class RTDLocale : IRTDLocale, ILanguage { + public static readonly string PREFIX = + $" {ChatColors.Purple}[{ChatColors.LightPurple}RTD{ChatColors.Purple}]"; + + public IView RewardSelected(IRTDReward reward) { + return new SimpleView { + { PREFIX, "You rolled ", reward.Name + "." }, + SimpleView.NEWLINE, + { PREFIX, reward.Description } + }; + } + + public IView AlreadyRolled(IRTDReward reward) { + return new SimpleView { + PREFIX, + ChatColors.Red + "You already rolled " + ChatColors.DarkRed + reward.Name + + ChatColors.Red + ".", + }; + } + + public IView CannotRollYet() { + return new SimpleView { + PREFIX, "You can only roll once the round ends or you die." + }; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/AutoRTDListener.cs b/mod/Jailbreak.RTD/AutoRTDListener.cs new file mode 100644 index 00000000..62ef1c64 --- /dev/null +++ b/mod/Jailbreak.RTD/AutoRTDListener.cs @@ -0,0 +1,22 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; +using CounterStrikeSharp.API.Modules.Admin; +using Jailbreak.Public.Behaviors; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD; + +public class AutoRTDListener(IRTDRewarder rewarder) : IPluginBehavior { + [GameEventHandler] + public HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) { + foreach (var player in Utilities.GetPlayers() + .Where(player + => AdminManager.PlayerHasPermissions(player, "@ego/dssilver")) + .Where(player => !rewarder.HasReward(player))) { + player.ExecuteClientCommandFromServer("css_rtd"); + } + + return HookResult.Continue; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Jailbreak.RTD.csproj b/mod/Jailbreak.RTD/Jailbreak.RTD.csproj new file mode 100644 index 00000000..fc87aed4 --- /dev/null +++ b/mod/Jailbreak.RTD/Jailbreak.RTD.csproj @@ -0,0 +1,14 @@ + + + + net8.0 + enable + enable + + + + + + + + diff --git a/mod/Jailbreak.RTD/RTDCommand.cs b/mod/Jailbreak.RTD/RTDCommand.cs new file mode 100644 index 00000000..27ca57f2 --- /dev/null +++ b/mod/Jailbreak.RTD/RTDCommand.cs @@ -0,0 +1,68 @@ +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; +using CounterStrikeSharp.API.Modules.Admin; +using CounterStrikeSharp.API.Modules.Commands; +using Jailbreak.Formatting.Extensions; +using Jailbreak.Formatting.Views; +using Jailbreak.Public.Behaviors; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD; + +public class RTDCommand(IRTDRewarder rewarder, IRewardGenerator generator, + IRTDLocale locale, IGenericCmdLocale generic) : IPluginBehavior { + private bool inBetweenRounds; + + [ConsoleCommand("css_rtd", "Roll the dice!")] + public void Command_RTD(CCSPlayerController? executor, CommandInfo info) { + if (executor == null) return; + var bypass = AdminManager.PlayerHasPermissions(executor, "@css/root") + && info.ArgCount == 2; + + var old = rewarder.GetReward(executor); + if (!bypass && old != null) { + locale.AlreadyRolled(old).ToChat(executor); + return; + } + + if (!bypass && !inBetweenRounds && executor.PawnIsAlive) { + locale.CannotRollYet().ToChat(executor); + return; + } + + var reward = generator.GenerateReward(executor); + if (bypass) { + if (!int.TryParse(info.GetArg(1), out var slot)) { + generic.InvalidParameter(info.GetArg(1), "integer").ToChat(executor); + return; + } + + if (slot != -1) { + var rewards = generator.ToList(); + + if (slot < 0 || slot >= rewards.Count) { + generic.InvalidParameter(info.GetArg(1), "0-" + (rewards.Count - 1)) + .ToChat(executor); + return; + } + + reward = generator.ToList()[slot].Item1; + } + } + + rewarder.SetReward(executor, reward); + locale.RewardSelected(reward).ToChat(executor); + } + + [GameEventHandler] + public HookResult OnEnd(EventRoundEnd @event, GameEventInfo info) { + inBetweenRounds = true; + return HookResult.Continue; + } + + [GameEventHandler] + public HookResult OnStart(EventRoundStart @event, GameEventInfo info) { + inBetweenRounds = false; + return HookResult.Continue; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/RTDRewarder.cs b/mod/Jailbreak.RTD/RTDRewarder.cs new file mode 100644 index 00000000..8ee6211c --- /dev/null +++ b/mod/Jailbreak.RTD/RTDRewarder.cs @@ -0,0 +1,47 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; +using Jailbreak.Formatting.Base; +using Jailbreak.Formatting.Extensions; +using Jailbreak.Formatting.Views; +using Jailbreak.Formatting.Views.Logging; +using Jailbreak.Public.Behaviors; +using Jailbreak.Public.Mod.Logs; +using Jailbreak.Public.Mod.RTD; +using Jailbreak.Public.Utils; +using Microsoft.VisualBasic.CompilerServices; + +namespace Jailbreak.RTD; + +public class RTDRewarder(IRichLogService logs, IRTDLocale locale) + : IRTDRewarder, IPluginBehavior { + private readonly Dictionary rewards = new(); + + public bool HasReward(int id) { return GetReward(id) != null; } + + public IRTDReward? GetReward(int id) { + return rewards.TryGetValue(id, out var reward) ? reward : null; + } + + public bool SetReward(int id, IRTDReward reward) { + if (!reward.PrepareReward(id)) return false; + rewards[id] = reward; + return true; + } + + [GameEventHandler] + public HookResult OnStart(EventRoundStart @event, GameEventInfo info) { + foreach (var player in PlayerUtil.GetAlive()) { + var id = player.UserId ?? -1; + + var reward = GetReward(id); + if (reward == null) continue; + + logs.Append("Granted", reward.Name, "to", logs.Player(player)); + reward.GrantReward(id); + } + + rewards.Clear(); + return HookResult.Continue; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/RTDServiceExtensions.cs b/mod/Jailbreak.RTD/RTDServiceExtensions.cs new file mode 100644 index 00000000..6e811be7 --- /dev/null +++ b/mod/Jailbreak.RTD/RTDServiceExtensions.cs @@ -0,0 +1,15 @@ +using Jailbreak.Public.Extensions; +using Jailbreak.Public.Mod.RTD; +using Microsoft.Extensions.DependencyInjection; + +namespace Jailbreak.RTD; + +public static class RTDServiceExtensions { + public static void AddDiceRoll(this IServiceCollection collection) { + collection.AddPluginBehavior(); + collection.AddPluginBehavior(); + collection.AddPluginBehavior(); + collection.AddPluginBehavior(); + collection.AddPluginBehavior(); + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/RTDStatsCommand.cs b/mod/Jailbreak.RTD/RTDStatsCommand.cs new file mode 100644 index 00000000..618dd184 --- /dev/null +++ b/mod/Jailbreak.RTD/RTDStatsCommand.cs @@ -0,0 +1,28 @@ +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Core.Attributes.Registration; +using CounterStrikeSharp.API.Modules.Commands; +using CounterStrikeSharp.API.Modules.Utils; +using Jailbreak.Public.Behaviors; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD; + +public class RTDStatsCommand(IRewardGenerator generator) : IPluginBehavior { + [ConsoleCommand("css_rtdstats", "View stats and probabilities of the die")] + public void + Command_RTDStats(CCSPlayerController? executor, CommandInfo info) { + if (executor == null) return; + var total = generator.Sum(r => r.Item2); + + var rewards = generator.ToList(); + rewards.Sort((a, b) => a.Item2.CompareTo(b.Item2)); + + var index = 0; + foreach (var (reward, prob) in rewards) { + var name = reward.Name; + var percent = prob / total * 100; + executor.PrintToChat( + $"{ChatColors.Orange}{index++}. {ChatColors.LightBlue}{name}{ChatColors.Grey}: {ChatColors.Yellow}{percent:0.00}%"); + } + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/RewardGenerator.cs b/mod/Jailbreak.RTD/RewardGenerator.cs new file mode 100644 index 00000000..77b20062 --- /dev/null +++ b/mod/Jailbreak.RTD/RewardGenerator.cs @@ -0,0 +1,87 @@ +using System.Collections; +using System.Drawing; +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Behaviors; +using Jailbreak.Public.Mod.Rebel; +using Jailbreak.Public.Mod.RTD; +using Jailbreak.Public.Mod.Zones; +using Jailbreak.RTD.Rewards; + +namespace Jailbreak.RTD; + +public class RewardGenerator(IZoneManager mgr, IC4Service bomb) + : IPluginBehavior, IRewardGenerator { + private static readonly float PROB_LOTTERY = 1 / 5000f; + private static readonly float PROB_EXTREMELY_LOW = 1 / 1000f; + private static readonly float PROB_VERY_LOW = 1 / 100f; + private static readonly float PROB_LOW = 1 / 20f; + private static readonly float PROB_MEDIUM = 1 / 10f; + private static readonly float PROB_OFTEN = 1 / 5f; + private static readonly float PROB_VERY_OFTEN = 1 / 2f; + + private readonly List<(IRTDReward, float)> rewards = [ + (new NothingReward(), PROB_OFTEN), + (new WeaponReward("weapon_healthshot"), PROB_OFTEN), + (new WeaponReward("weapon_decoy"), PROB_OFTEN), + (new CreditReward(1), PROB_MEDIUM), (new CreditReward(2), PROB_MEDIUM), + (new CreditReward(3), PROB_MEDIUM), + (new WeaponReward("weapon_flashbang"), PROB_MEDIUM), + (new WeaponReward("weapon_hegrenade"), PROB_MEDIUM), + (new WeaponReward("weapon_smokegrenade"), PROB_MEDIUM), + (new WeaponReward("weapon_molotov"), PROB_MEDIUM), + (new WeaponReward("weapon_taser"), PROB_MEDIUM), + (new HPReward(150), PROB_MEDIUM), (new HPReward(50), PROB_MEDIUM), + (new ArmorReward(150), PROB_MEDIUM), (new HPReward(1), PROB_LOW), + (new ColorReward(Color.FromArgb(0, 255, 0)), PROB_LOW), + (new ColorReward(Color.FromArgb(255, 0, 0)), PROB_LOW), + (new TransparentReward(), PROB_LOW), + (new AmmoWeaponReward("weapon_glock", 2, 0), PROB_LOW), + (new AmmoWeaponReward("weapon_negev", 0, 5), PROB_LOW), + (new NoWeaponReward(), PROB_VERY_LOW), + (new AmmoWeaponReward("weapon_deagle", 1, 0), PROB_VERY_LOW), + (new RandomTeleportReward(mgr), PROB_VERY_LOW), + (new BombReward(bomb), PROB_VERY_LOW), + (new AmmoWeaponReward("weapon_awp", 1, 0), PROB_EXTREMELY_LOW) + ]; + + public void Start(BasePlugin basePlugin) { + rewards.Add((new CannotPickupReward(basePlugin, WeaponType.GRENADE), + PROB_LOW)); + rewards.Add((new CannotPickupReward(basePlugin, WeaponType.UTILITY), + PROB_LOW)); + rewards.Add(( + new CannotPickupReward(basePlugin, + WeaponType.GRENADE | WeaponType.UTILITY), PROB_LOW)); + rewards.Add((new CannotPickupReward(basePlugin, WeaponType.PISTOLS), + PROB_VERY_LOW)); + rewards.Add((new CannotPickupReward(basePlugin, WeaponType.SNIPERS), + PROB_VERY_LOW)); + rewards.Add((new CannotPickupReward(basePlugin, WeaponType.HEAVY), + PROB_VERY_LOW)); + rewards.Add((new CannotPickupReward(basePlugin, WeaponType.RIFLES), + PROB_EXTREMELY_LOW)); + } + + private readonly Random rng = new(); + + private float totalWeight + => rewards.Where(r => r.Item1.Enabled).Select(s => s.Item2).Sum(); + + public IRTDReward GenerateReward(int slot) { + var roll = rng.NextDouble() * totalWeight; + + foreach (var reward in rewards.Where(reward => reward.Item1.Enabled)) { + roll -= reward.Item2; + if (roll <= 0) return reward.Item1; + } + + throw new InvalidOperationException("No reward was generated."); + } + + public IEnumerator<(IRTDReward, float)> GetEnumerator() { + return rewards.Where(r => r.Item1.Enabled).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } + public int Count => rewards.Count(r => r.Item1.Enabled); +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/AmmoWeaponReward.cs b/mod/Jailbreak.RTD/Rewards/AmmoWeaponReward.cs new file mode 100644 index 00000000..f961b291 --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/AmmoWeaponReward.cs @@ -0,0 +1,24 @@ +using System.Diagnostics; +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Extensions; + +namespace Jailbreak.RTD.Rewards; + +public class AmmoWeaponReward : WeaponReward { + private readonly int primary, secondary; + + public AmmoWeaponReward(string weapon, int primary, int secondary) : + base(weapon) { + Trace.Assert(Tag.GUNS.Contains(weapon)); + this.primary = primary; + this.secondary = secondary; + } + + public override bool GrantReward(CCSPlayerController player) { + var success = base.GrantReward(player); + if (!success) return false; + + player.GetWeaponBase(weapon).SetAmmo(primary, secondary); + return true; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/ArmorReward.cs b/mod/Jailbreak.RTD/Rewards/ArmorReward.cs new file mode 100644 index 00000000..5f65d81f --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/ArmorReward.cs @@ -0,0 +1,16 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Extensions; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD.Rewards; + +public class ArmorReward(int armor) : IRTDReward { + public string Name => armor + " Armor"; + public string Description => "You won " + armor + " Armor next round."; + + public bool GrantReward(CCSPlayerController player) { + player.SetArmor(armor); + return true; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/BombReward.cs b/mod/Jailbreak.RTD/Rewards/BombReward.cs new file mode 100644 index 00000000..aa0c45e2 --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/BombReward.cs @@ -0,0 +1,21 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Mod.Rebel; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD.Rewards; + +public class BombReward(IC4Service bombService) : IRTDReward { + public string Name => "Bomb"; + public string Description => "You won the bomb next round."; + + public bool PrepareReward(int userid) { + bombService.DontGiveC4NextRound(); + return true; + } + + public bool GrantReward(CCSPlayerController player) { + bombService.TryGiveC4ToPlayer(player); + return true; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/CannotPickupReward.cs b/mod/Jailbreak.RTD/Rewards/CannotPickupReward.cs new file mode 100644 index 00000000..28bda9c1 --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/CannotPickupReward.cs @@ -0,0 +1,57 @@ +using System.Collections.Immutable; +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Extensions; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD.Rewards; + +public class CannotPickupReward : IRTDReward { + private readonly BasePlugin plugin; + private readonly ImmutableHashSet blockedWeapons; + + public CannotPickupReward(BasePlugin plugin, WeaponType blocked) : this( + plugin, blocked.GetItems().ToArray()) { + Name = $"Cannot Pickup {blocked}"; + } + + public CannotPickupReward(BasePlugin plugin, params string[] weapons) { + this.plugin = plugin; + this.plugin.RegisterEventHandler(onPickup); + this.plugin.RegisterEventHandler(onRoundEnd); + + blockedWeapons = weapons.ToImmutableHashSet(); + Name = + $"Cannot Pickup {string.Join(", ", blockedWeapons.Select(s => s.GetFriendlyWeaponName()))}"; + } + + public string Name { get; } + + public string Description + => $"You will not be able to pickup {Name} the next round."; + + private readonly HashSet blockedPlayerIDs = []; + + public bool GrantReward(CCSPlayerController player) { + if (player.UserId == null) return false; + blockedPlayerIDs.Add(player.UserId.Value); + return true; + } + + private HookResult onRoundEnd(EventRoundEnd @event, GameEventInfo info) { + blockedPlayerIDs.Clear(); + return HookResult.Continue; + } + + private HookResult onPickup(EventItemPickup @event, GameEventInfo info) { + var player = @event.Userid; + if (player == null || !player.IsValid || player.UserId == null) + return HookResult.Continue; + if (!blockedPlayerIDs.Contains(player.UserId.Value)) + return HookResult.Continue; + var weapon = "weapon_" + @event.Item; + if (!blockedWeapons.Contains(weapon)) return HookResult.Continue; + player.RemoveItemByDesignerName(weapon, true); + return HookResult.Continue; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/ColorReward.cs b/mod/Jailbreak.RTD/Rewards/ColorReward.cs new file mode 100644 index 00000000..59c49cd9 --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/ColorReward.cs @@ -0,0 +1,43 @@ +using System.Drawing; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using Jailbreak.Public.Extensions; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD.Rewards; + +public class ColorReward(Color color) : IRTDReward { + public virtual string Name => "Spawn " + ColorName; + + public virtual string Description + => $"You won spawning {ChatColor}{ColorName}{ChatColors.Grey} next round."; + + public string ColorName + => color.IsNamedColor ? + color.Name : + color.GetHue() switch { + 0 => "Red", + 60 => "Yellow", + 120 => "Green", + 180 => "Cyan", + 240 => "Blue", + 300 => "Magenta", + _ => "#" + color.ToArgb().ToString("X8") + }; + + public char ChatColor + => color.GetHue() switch { + 0 => ChatColors.Red, + 60 => ChatColors.Yellow, + 120 => ChatColors.Green, + 180 => ChatColors.LightBlue, + 240 => ChatColors.Blue, + 300 => ChatColors.Magenta, + _ => ChatColors.White + }; + + public bool GrantReward(CCSPlayerController player) { + player.SetColor(color); + return true; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/CreditReward.cs b/mod/Jailbreak.RTD/Rewards/CreditReward.cs new file mode 100644 index 00000000..327aaa80 --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/CreditReward.cs @@ -0,0 +1,24 @@ +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD.Rewards; + +public class CreditReward(int credits) : IRTDReward { + public string Name => credits + " Credit"; + + public string Description + => "You won " + credits + " credit" + (credits == 1 ? "" : "s") + + (credits > 500 ? "!" : "."); + + public bool Enabled => false; // TODO: Implement + + public bool PrepareReward(int userid) { + // TODO: When we do implement, set their credits here + return true; + } + + public bool GrantReward(CCSPlayerController player) { + // We would have already set their credits in PrepareReward, so do nothing here + return true; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/HPReward.cs b/mod/Jailbreak.RTD/Rewards/HPReward.cs new file mode 100644 index 00000000..d79a544c --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/HPReward.cs @@ -0,0 +1,16 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Extensions; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD.Rewards; + +public class HPReward(int hp) : IRTDReward { + public string Name => hp + " HP"; + public string Description => "You won " + hp + " HP next round."; + + public bool GrantReward(CCSPlayerController player) { + player.SetHealth(hp); + return true; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/NoWeaponReward.cs b/mod/Jailbreak.RTD/Rewards/NoWeaponReward.cs new file mode 100644 index 00000000..b48b2f00 --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/NoWeaponReward.cs @@ -0,0 +1,14 @@ +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD.Rewards; + +public class NoWeaponReward : IRTDReward { + public string Name => "No Weapon"; + public string Description => "You will not spawn with a knife next round."; + + public bool GrantReward(CCSPlayerController player) { + player.RemoveWeapons(); + return true; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/NothingReward.cs b/mod/Jailbreak.RTD/Rewards/NothingReward.cs new file mode 100644 index 00000000..ff1aff1c --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/NothingReward.cs @@ -0,0 +1,10 @@ +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD.Rewards; + +public class NothingReward : IRTDReward { + public string Name => "Nothing"; + public string Description => "You won nothing."; + public bool GrantReward(CCSPlayerController player) { return true; } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/RandomTeleportReward.cs b/mod/Jailbreak.RTD/Rewards/RandomTeleportReward.cs new file mode 100644 index 00000000..8cd38f4b --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/RandomTeleportReward.cs @@ -0,0 +1,20 @@ +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Mod.RTD; +using Jailbreak.Public.Mod.Zones; +using Jailbreak.Public.Utils; + +namespace Jailbreak.RTD.Rewards; + +public class RandomTeleportReward(IZoneManager zones) : IRTDReward { + public string Name => "Random Teleport"; + + public string Description + => "You will be teleported to a random location next round."; + + public bool GrantReward(CCSPlayerController player) { + var zone = MapUtil.GetRandomSpawns(1, zones).FirstOrDefault(); + if (zone == null) return false; + player.Teleport(zone); + return true; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/TransparentReward.cs b/mod/Jailbreak.RTD/Rewards/TransparentReward.cs new file mode 100644 index 00000000..73b143ae --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/TransparentReward.cs @@ -0,0 +1,15 @@ +using System.Drawing; +using CounterStrikeSharp.API.Core; +using CounterStrikeSharp.API.Modules.Utils; +using Jailbreak.Public.Extensions; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD.Rewards; + +public class TransparentReward() + : ColorReward(Color.FromArgb(128, 255, 255, 255)) { + public override string Name => "Spawn Transparent"; + + public override string Description + => "You won spawning transparent next round."; +} \ No newline at end of file diff --git a/mod/Jailbreak.RTD/Rewards/WeaponReward.cs b/mod/Jailbreak.RTD/Rewards/WeaponReward.cs new file mode 100644 index 00000000..50d2ae08 --- /dev/null +++ b/mod/Jailbreak.RTD/Rewards/WeaponReward.cs @@ -0,0 +1,29 @@ +using System.Diagnostics; +using System.Reflection; +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Extensions; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.RTD.Rewards; + +public class WeaponReward : IRTDReward { + protected readonly string weapon; + + public WeaponReward(string weapon) { + this.weapon = weapon; + Trace.Assert(Tag.GUNS.Contains(weapon)); + } + + public string Name => weapon.GetFriendlyWeaponName(); + + public string Description + => "You won a" + + (weapon.GetFriendlyWeaponName()[0].IsVowel() ? "n" : "" + " ") + + weapon.GetFriendlyWeaponName() + " next round."; + + public virtual bool GrantReward(CCSPlayerController player) { + player.GiveNamedItem(weapon); + return true; + } +} \ No newline at end of file diff --git a/mod/Jailbreak.Rebel/C4Bomb/C4Behavior.cs b/mod/Jailbreak.Rebel/C4Bomb/C4Behavior.cs index 19e74d3c..109b2e00 100644 --- a/mod/Jailbreak.Rebel/C4Bomb/C4Behavior.cs +++ b/mod/Jailbreak.Rebel/C4Bomb/C4Behavior.cs @@ -43,6 +43,8 @@ private readonly MemoryFunctionVoid new("css_jb_c4_damage", "Base damage to apply", 340, ConVarFlags.FCVAR_NONE, new RangeValidator(0, 10000)); + private bool giveNextRound = true; + public void ClearActiveC4s() { bombs.Clear(); } public void TryGiveC4ToPlayer(CCSPlayerController player) { @@ -116,11 +118,19 @@ private void playerUseC4ListenerCallback() { } } + public void DontGiveC4NextRound() { giveNextRound = false; } + [GameEventHandler] public HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) { ClearActiveC4s(); - if (CV_GIVE_BOMB.Value) TryGiveC4ToRandomTerrorist(); + if (!CV_GIVE_BOMB.Value) return HookResult.Continue; + if (!giveNextRound) { + giveNextRound = true; + return HookResult.Continue; + } + + TryGiveC4ToRandomTerrorist(); return HookResult.Continue; } diff --git a/mod/Jailbreak.SpecialDay/SpecialDays/GunGameDay.cs b/mod/Jailbreak.SpecialDay/SpecialDays/GunGameDay.cs index f67b22fc..b768194a 100644 --- a/mod/Jailbreak.SpecialDay/SpecialDays/GunGameDay.cs +++ b/mod/Jailbreak.SpecialDay/SpecialDays/GunGameDay.cs @@ -7,7 +7,9 @@ using Jailbreak.Public.Extensions; using Jailbreak.Public.Mod.SpecialDay; using Jailbreak.Public.Mod.SpecialDay.Enums; +using Jailbreak.Public.Mod.Zones; using Jailbreak.Public.Utils; +using Microsoft.Extensions.DependencyInjection; namespace Jailbreak.SpecialDay.SpecialDays; @@ -57,8 +59,10 @@ public override void Setup() { Timers[10] += Execute; base.Setup(); + var mgr = Provider.GetService(); spawns = - new ShuffleBag(getAtLeastRandom(Utilities.GetPlayers().Count)); + new ShuffleBag( + MapUtil.GetRandomSpawns(Utilities.GetPlayers().Count, mgr)); Plugin.RegisterEventHandler(OnDeath, HookMode.Pre); Plugin.RegisterEventHandler(OnRespawn); diff --git a/mod/Jailbreak.SpecialDay/SpecialDays/OneInTheChamberDay.cs b/mod/Jailbreak.SpecialDay/SpecialDays/OneInTheChamberDay.cs index 610a28da..61b4e78d 100644 --- a/mod/Jailbreak.SpecialDay/SpecialDays/OneInTheChamberDay.cs +++ b/mod/Jailbreak.SpecialDay/SpecialDays/OneInTheChamberDay.cs @@ -23,7 +23,7 @@ public override ISDInstanceLocale Locale public static readonly FakeConVar CV_WEAPON = new("jb_sd_oitc_weapon", "Weapon to give to players for the day", "weapon_deagle", - ConVarFlags.FCVAR_NONE, new ItemValidator(ItemValidator.WeaponType.GUNS)); + ConVarFlags.FCVAR_NONE, new ItemValidator(WeaponType.GUNS)); public static readonly FakeConVar CV_ADDITIONAL_WEAPON = new( "jb_sd_oitc_additionalweapon", diff --git a/public/Jailbreak.Formatting/Views/IRTDLocale.cs b/public/Jailbreak.Formatting/Views/IRTDLocale.cs new file mode 100644 index 00000000..0eb25539 --- /dev/null +++ b/public/Jailbreak.Formatting/Views/IRTDLocale.cs @@ -0,0 +1,10 @@ +using Jailbreak.Formatting.Base; +using Jailbreak.Public.Mod.RTD; + +namespace Jailbreak.Formatting.Views; + +public interface IRTDLocale { + public IView RewardSelected(IRTDReward reward); + public IView AlreadyRolled(IRTDReward reward); + public IView CannotRollYet(); +} \ No newline at end of file diff --git a/public/Jailbreak.Public/Extensions/PlayerExtensions.cs b/public/Jailbreak.Public/Extensions/PlayerExtensions.cs index 1fd967f0..4713d6c4 100644 --- a/public/Jailbreak.Public/Extensions/PlayerExtensions.cs +++ b/public/Jailbreak.Public/Extensions/PlayerExtensions.cs @@ -124,6 +124,7 @@ public static void SetColor(this CCSPlayerController player, Color color) { var pawn = player.PlayerPawn.Value; if (!player.IsValid || pawn == null || !pawn.IsValid) return; + // TODO: Don't always override to allow other plugins to show legs. if (color.A == 255) color = Color.FromArgb(254, color.R, color.G, color.B); pawn.RenderMode = RenderMode_t.kRenderTransColor; pawn.Render = color; diff --git a/public/Jailbreak.Public/Extensions/WeaponExtensions.cs b/public/Jailbreak.Public/Extensions/WeaponExtensions.cs index 104e24fa..e85f9484 100644 --- a/public/Jailbreak.Public/Extensions/WeaponExtensions.cs +++ b/public/Jailbreak.Public/Extensions/WeaponExtensions.cs @@ -125,8 +125,10 @@ public static string GetFriendlyWeaponName(this string designerName) { case "weapon_knife_t": case "weapon_knife": return "Knife"; - default: - return designerName.Replace("weapon_", "").ToUpper(); + default: { + var name = designerName.Replace("weapon_", ""); + return char.ToUpper(name[0]) + name[1..]; + } } } diff --git a/public/Jailbreak.Public/Mod/RTD/IRTDReward.cs b/public/Jailbreak.Public/Mod/RTD/IRTDReward.cs new file mode 100644 index 00000000..16031d26 --- /dev/null +++ b/public/Jailbreak.Public/Mod/RTD/IRTDReward.cs @@ -0,0 +1,22 @@ +using CounterStrikeSharp.API; +using CounterStrikeSharp.API.Core; + +namespace Jailbreak.Public.Mod.RTD; + +public interface IRTDReward { + public string Name { get; } + public string Description { get; } + bool Enabled => true; + + bool CanGrantReward(int userid) { return true; } + + bool PrepareReward(int userid) { return true; } + + bool GrantReward(int userid) { + var player = Utilities.GetPlayerFromUserid(userid); + if (player == null || !player.IsValid) return false; + return player.PawnIsAlive && GrantReward(player); + } + + bool GrantReward(CCSPlayerController player); +} \ No newline at end of file diff --git a/public/Jailbreak.Public/Mod/RTD/IRTDRewarder.cs b/public/Jailbreak.Public/Mod/RTD/IRTDRewarder.cs new file mode 100644 index 00000000..a71bf685 --- /dev/null +++ b/public/Jailbreak.Public/Mod/RTD/IRTDRewarder.cs @@ -0,0 +1,39 @@ +using CounterStrikeSharp.API.Core; +using Jailbreak.Public.Behaviors; + +namespace Jailbreak.Public.Mod.RTD; + +/// +/// A rewarder that manages rewards for players. +/// +public interface IRTDRewarder { + /// + /// True if the player currently has a reward. + /// + /// + /// + bool HasReward(int id) { return GetReward(id) != null; } + + bool HasReward(CCSPlayerController player) => HasReward(player.UserId ?? -1); + + /// + /// Gets the reward for the player. + /// + /// + /// + IRTDReward? GetReward(int id); + + IRTDReward? GetReward(CCSPlayerController player) + => GetReward(player.UserId ?? -1); + + /// + /// Attempts to give a reward to the player. + /// + /// + /// + /// + bool SetReward(int id, IRTDReward reward); + + bool SetReward(CCSPlayerController player, IRTDReward reward) + => SetReward(player.UserId ?? -1, reward); +} \ No newline at end of file diff --git a/public/Jailbreak.Public/Mod/RTD/IRewardGenerator.cs b/public/Jailbreak.Public/Mod/RTD/IRewardGenerator.cs new file mode 100644 index 00000000..341b329b --- /dev/null +++ b/public/Jailbreak.Public/Mod/RTD/IRewardGenerator.cs @@ -0,0 +1,11 @@ +using CounterStrikeSharp.API.Core; + +namespace Jailbreak.Public.Mod.RTD; + +public interface IRewardGenerator : IReadOnlyCollection<(IRTDReward, float)> { + IRTDReward GenerateReward(int slot); + + IRTDReward GenerateReward(CCSPlayerController player) { + return GenerateReward(player.UserId ?? -1); + } +} \ No newline at end of file diff --git a/public/Jailbreak.Public/Mod/Rebel/IC4Service.cs b/public/Jailbreak.Public/Mod/Rebel/IC4Service.cs index 56c3b63e..05660163 100644 --- a/public/Jailbreak.Public/Mod/Rebel/IC4Service.cs +++ b/public/Jailbreak.Public/Mod/Rebel/IC4Service.cs @@ -25,5 +25,7 @@ void StartDetonationAttempt(CCSPlayerController player, float delay, /// void TryGiveC4ToRandomTerrorist(); + void DontGiveC4NextRound() { } + void ClearActiveC4s(); } \ No newline at end of file diff --git a/public/Jailbreak.Public/Mod/SpecialDay/AbstractSpecialDay.cs b/public/Jailbreak.Public/Mod/SpecialDay/AbstractSpecialDay.cs index 8597765b..93714843 100644 --- a/public/Jailbreak.Public/Mod/SpecialDay/AbstractSpecialDay.cs +++ b/public/Jailbreak.Public/Mod/SpecialDay/AbstractSpecialDay.cs @@ -147,6 +147,7 @@ private void doTeleports(SpecialDaySettings.TeleportType type, var ctVectors = ctSpawns.ToArray(); ctVectors.Shuffle(); + var mgr = Provider.GetService(); IEnumerable spawnPositions; switch (type) { case SpecialDaySettings.TeleportType.CELL: @@ -162,10 +163,11 @@ private void doTeleports(SpecialDaySettings.TeleportType type, spawnPositions = [ctVectors.First()]; break; case SpecialDaySettings.TeleportType.RANDOM: - spawnPositions = getAtLeastRandom(PlayerUtil.GetAlive().Count()); + spawnPositions = + MapUtil.GetRandomSpawns(PlayerUtil.GetAlive().Count(), mgr); break; case SpecialDaySettings.TeleportType.RANDOM_STACKED: - spawnPositions = [getAtLeastRandom(1).First()]; + spawnPositions = [MapUtil.GetRandomSpawns(1, mgr).First()]; break; default: return; @@ -176,61 +178,6 @@ private void doTeleports(SpecialDaySettings.TeleportType type, player.PlayerPawn.Value?.Teleport(baggedSpawns.GetNext()); } - protected List getAtLeastRandom(int count) { - // Progressively get more lax with our "randomness quality" - var result = getRandomSpawns(false, false, false); - if (result.Count < count) result = getRandomSpawns(false, false); - if (result.Count < count) result = getRandomSpawns(false); - if (result.Count < count) result = getRandomSpawns(); - return result; - } - - protected List getRandomSpawns(bool includeSpawns = true, - bool includeTps = true, bool includeAuto = true) { - var result = new List(); - - if (includeTps) { - var worldTp = Utilities - .FindAllEntitiesByDesignerName( - "info_teleport_destination") - .Where(s => s.AbsOrigin != null) - .Select(s => s.AbsOrigin!); - result.AddRange(worldTp); - } - - if (includeSpawns) { - var tSpawns = Utilities - .FindAllEntitiesByDesignerName("info_player_terrorist") - .Where(s => s.AbsOrigin != null) - .Select(s => s.AbsOrigin!); - var ctSpawns = Utilities - .FindAllEntitiesByDesignerName< - SpawnPoint>("info_player_counterterrorist") - .Where(s => s.AbsOrigin != null) - .Select(s => s.AbsOrigin!); - result.AddRange(tSpawns); - result.AddRange(ctSpawns); - } - - var zoneManager = Provider.GetService(); - if (zoneManager != null) { - if (includeAuto) - result.AddRange(zoneManager - .GetZones(Server.MapName, ZoneType.SPAWN_AUTO) - .GetAwaiter() - .GetResult() - .Select(z => z.GetCenterPoint())); - - var zones = zoneManager.GetZones(Server.MapName, ZoneType.SPAWN) - .GetAwaiter() - .GetResult(); - result.AddRange(zones.Select(z => z.GetCenterPoint())); - } - - result.Shuffle(); - return result; - } - protected object GetConvarValue(ConVar? cvar) { try { if (cvar == null) return ""; diff --git a/public/Jailbreak.Public/Utils/MapUtil.cs b/public/Jailbreak.Public/Utils/MapUtil.cs index 295d6801..baa6d394 100644 --- a/public/Jailbreak.Public/Utils/MapUtil.cs +++ b/public/Jailbreak.Public/Utils/MapUtil.cs @@ -121,6 +121,61 @@ private static bool IsCellButton(CBaseEntity ent, Sensitivity sen) { return false; } + + public static List GetRandomSpawns(int count, IZoneManager? zones) { + // Progressively get more lax with our "randomness quality" + var result = GetRandomSpawns(zones, false, false, false); + if (result.Count < count) result = GetRandomSpawns(zones, false, false); + if (result.Count < count) result = GetRandomSpawns(zones, false); + if (result.Count < count) result = GetRandomSpawns(zones); + return result; + } + + public static List GetRandomSpawns(IZoneManager? zoneManager = null, + bool includeSpawns = true, bool includeTps = true, + bool includeAuto = true) { + var result = new List(); + + if (includeTps) { + var worldTp = Utilities + .FindAllEntitiesByDesignerName( + "info_teleport_destination") + .Where(s => s.AbsOrigin != null) + .Select(s => s.AbsOrigin!); + result.AddRange(worldTp); + } + + if (includeSpawns) { + var tSpawns = Utilities + .FindAllEntitiesByDesignerName("info_player_terrorist") + .Where(s => s.AbsOrigin != null) + .Select(s => s.AbsOrigin!); + var ctSpawns = Utilities + .FindAllEntitiesByDesignerName< + SpawnPoint>("info_player_counterterrorist") + .Where(s => s.AbsOrigin != null) + .Select(s => s.AbsOrigin!); + result.AddRange(tSpawns); + result.AddRange(ctSpawns); + } + + if (zoneManager != null) { + if (includeAuto) + result.AddRange(zoneManager + .GetZones(Server.MapName, ZoneType.SPAWN_AUTO) + .GetAwaiter() + .GetResult() + .Select(z => z.GetCenterPoint())); + + var zones = zoneManager.GetZones(Server.MapName, ZoneType.SPAWN) + .GetAwaiter() + .GetResult(); + result.AddRange(zones.Select(z => z.GetCenterPoint())); + } + + result.Shuffle(); + return result; + } } public enum Sensitivity { diff --git a/public/Jailbreak.Tag/WeaponType.cs b/public/Jailbreak.Tag/WeaponType.cs new file mode 100644 index 00000000..7b9e3886 --- /dev/null +++ b/public/Jailbreak.Tag/WeaponType.cs @@ -0,0 +1,52 @@ +[Flags] +public enum WeaponType { + GRENADE = 1 << 0, // 1 + UTILITY = 1 << 1, // 2 + WEAPON = 1 << 2, // 4 + SNIPERS = 1 << 3, // 8 + RIFLES = 1 << 4, // 16 + PISTOLS = 1 << 5, // 32 + SHOTGUNS = 1 << 6, // 64 + SMGS = 1 << 7, // 128 + HEAVY = 1 << 8, // 256 + GUNS = 1 << 9 // 512 +} + +public static class WeaponTypeExtensions { + public static IReadOnlySet GetItems(this WeaponType type) { + var result = new HashSet(); + + foreach (var t in Enum.GetValues()) + if (type.HasFlag(t)) + result.UnionWith(t.GetItems()); + + switch (type) { + case WeaponType.GUNS: + return Tag.GUNS; + case WeaponType.HEAVY: + return Tag.HEAVY; + case WeaponType.SMGS: + return Tag.SMGS; + case WeaponType.SHOTGUNS: + return Tag.SHOTGUNS; + case WeaponType.PISTOLS: + return Tag.PISTOLS; + case WeaponType.RIFLES: + return Tag.RIFLES; + case WeaponType.SNIPERS: + return Tag.SNIPERS; + case WeaponType.UTILITY: + return Tag.UTILITY; + case WeaponType.GRENADE: + return Tag.GRENADES; + case WeaponType.WEAPON: + return Tag.WEAPONS; + default: + foreach (var t in Enum.GetValues()) { + if (type.HasFlag(t)) result.UnionWith(t.GetItems()); + } + + return result; + } + } +} \ No newline at end of file diff --git a/public/Jailbreak.Validator/ItemValidator.cs b/public/Jailbreak.Validator/ItemValidator.cs index a0506b63..17bd6a5f 100644 --- a/public/Jailbreak.Validator/ItemValidator.cs +++ b/public/Jailbreak.Validator/ItemValidator.cs @@ -3,23 +3,8 @@ namespace Jailbreak.Validator; public class ItemValidator( - ItemValidator.WeaponType type = ItemValidator.WeaponType.WEAPON - | ItemValidator.WeaponType.UTILITY, bool allowEmpty = true, - bool allowMultiple = false) : IValidator { - [Flags] - public enum WeaponType { - GRENADE = 1 << 0, // 1 - UTILITY = 1 << 1, // 2 - WEAPON = 1 << 2, // 4 - SNIPERS = 1 << 3, // 8 - RIFLES = 1 << 4, // 16 - PISTOLS = 1 << 5, // 32 - SHOTGUNS = 1 << 6, // 64 - SMGS = 1 << 7, // 128 - HEAVY = 1 << 8, // 256 - GUNS = 1 << 9 // 512 - } - + WeaponType type = WeaponType.WEAPON | WeaponType.UTILITY, + bool allowEmpty = true, bool allowMultiple = false) : IValidator { public bool Validate(string value, out string? errorMessage) { if (value.Contains(',') && !allowMultiple) { errorMessage = "Value cannot contain multiple values"; @@ -42,29 +27,10 @@ public bool Validate(string value, out string? errorMessage) { } errorMessage = $"invalid {type.ToString()}: {weapon}"; - return Enum.GetValues() - .Where(t => type.HasFlag(t)) - .Any(t => validateType(t, weapon)); + return type.GetItems().Contains(weapon); } errorMessage = null; return true; } - - private bool validateType(WeaponType current, string weapon) { - var result = current switch { - WeaponType.GRENADE => Tag.GRENADES.Contains(weapon), - WeaponType.UTILITY => Tag.UTILITY.Contains(weapon), - WeaponType.WEAPON => Tag.WEAPONS.Contains(weapon), - WeaponType.SNIPERS => Tag.SNIPERS.Contains(weapon), - WeaponType.RIFLES => Tag.RIFLES.Contains(weapon), - WeaponType.PISTOLS => Tag.PISTOLS.Contains(weapon), - WeaponType.SHOTGUNS => Tag.SHOTGUNS.Contains(weapon), - WeaponType.SMGS => Tag.SMGS.Contains(weapon), - WeaponType.HEAVY => Tag.HEAVY.Contains(weapon), - WeaponType.GUNS => Tag.GUNS.Contains(weapon), - _ => throw new ArgumentOutOfRangeException(nameof(weapon)) - }; - return result; - } } \ No newline at end of file diff --git a/src/Jailbreak/Jailbreak.csproj b/src/Jailbreak/Jailbreak.csproj index 155877ae..3ec773c1 100644 --- a/src/Jailbreak/Jailbreak.csproj +++ b/src/Jailbreak/Jailbreak.csproj @@ -61,6 +61,7 @@ + diff --git a/src/Jailbreak/JailbreakServiceCollection.cs b/src/Jailbreak/JailbreakServiceCollection.cs index 90510926..8107ecd2 100644 --- a/src/Jailbreak/JailbreakServiceCollection.cs +++ b/src/Jailbreak/JailbreakServiceCollection.cs @@ -6,6 +6,7 @@ using Jailbreak.English.Logs; using Jailbreak.English.Mute; using Jailbreak.English.Rebel; +using Jailbreak.English.RTD; using Jailbreak.English.SpecialDay; using Jailbreak.English.Warden; using Jailbreak.Formatting.Views; @@ -18,6 +19,7 @@ using Jailbreak.Logs; using Jailbreak.Mute; using Jailbreak.Rebel; +using Jailbreak.RTD; using Jailbreak.SpecialDay; using Jailbreak.Warden; using Jailbreak.Zones; @@ -47,6 +49,7 @@ public void ConfigureServices(IServiceCollection serviceCollection) { serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); // Do we want to make this scoped? // Not sure how this will behave with multiple rounds and whatnot. @@ -60,5 +63,6 @@ public void ConfigureServices(IServiceCollection serviceCollection) { serviceCollection.AddJailbreakLastGuard(); serviceCollection.AddJailbreakSpecialDay(); serviceCollection.AddJailbreakZones(); + serviceCollection.AddDiceRoll(); } } \ No newline at end of file