From 74ddef4ba2c604f00317dd77196850f5c7a43bd9 Mon Sep 17 00:00:00 2001
From: MSWS <imodmaker@gmail.com>
Date: Mon, 23 Sep 2024 20:21:40 -0700
Subject: [PATCH 1/5] #JB-120: Fix vowel-based whitespace error

---
 mod/Jailbreak.RTD/Rewards/WeaponReward.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mod/Jailbreak.RTD/Rewards/WeaponReward.cs b/mod/Jailbreak.RTD/Rewards/WeaponReward.cs
index 5b1b6f42..23d459d2 100644
--- a/mod/Jailbreak.RTD/Rewards/WeaponReward.cs
+++ b/mod/Jailbreak.RTD/Rewards/WeaponReward.cs
@@ -21,7 +21,7 @@ public WeaponReward(string weapon, CsTeam? requiredTeam = CsTeam.Terrorist) {
 
   public virtual string Description
     => "You won a"
-      + (weapon.GetFriendlyWeaponName()[0].IsVowel() ? "n" : "" + " ")
+      + (weapon.GetFriendlyWeaponName()[0].IsVowel() ? "n" : "") + " "
       + weapon.GetFriendlyWeaponName() + " next round.";
 
   public bool CanGrantReward(CCSPlayerController player) {

From 1bf53e79da7a876b85ddb13901d0c1bd13d65647 Mon Sep 17 00:00:00 2001
From: MSWS <imodmaker@gmail.com>
Date: Fri, 27 Sep 2024 14:36:59 -0700
Subject: [PATCH 2/5] Resolve JB-123

---
 .../LastRequests/BulletForBullet.cs           | 64 +++++--------------
 mod/Jailbreak.Rebel/RebelManager.cs           |  3 +-
 2 files changed, 19 insertions(+), 48 deletions(-)

diff --git a/mod/Jailbreak.LastRequest/LastRequests/BulletForBullet.cs b/mod/Jailbreak.LastRequest/LastRequests/BulletForBullet.cs
index 06e9b3a7..9e587ca7 100644
--- a/mod/Jailbreak.LastRequest/LastRequests/BulletForBullet.cs
+++ b/mod/Jailbreak.LastRequest/LastRequests/BulletForBullet.cs
@@ -12,11 +12,6 @@
 namespace Jailbreak.LastRequest.LastRequests;
 
 public class BulletForBullet : TeleportingRequest {
-  private static readonly string[] GUNS = [
-    "weapon_deagle", "weapon_usp_silencer", "weapon_tec9", "weapon_ssg08",
-    "weapon_nova"
-  ];
-
   private readonly ChatMenu chatMenu;
   private readonly bool magForMag;
   private readonly ILRB4BLocale msg;
@@ -29,9 +24,6 @@ public BulletForBullet(BasePlugin plugin, IServiceProvider provider,
     provider.GetRequiredService<ILastRequestManager>(), prisoner, guard) {
     this.magForMag = magForMag;
     chatMenu       = new ChatMenu(magForMag ? "Mag for Mag" : "Shot for Shot");
-    foreach (var pistol in GUNS)
-      chatMenu.AddMenuOption(pistol.GetFriendlyWeaponName(),
-        (player, option) => OnSelect(player, option, pistol));
 
     msg = provider.GetRequiredService<ILRB4BLocale>();
   }
@@ -39,36 +31,6 @@ public BulletForBullet(BasePlugin plugin, IServiceProvider provider,
   public override LRType Type
     => magForMag ? LRType.MAG_FOR_MAG : LRType.SHOT_FOR_SHOT;
 
-  private void OnSelect(CCSPlayerController player, ChatMenuOption _,
-    string designer) {
-    if (player.Slot != Prisoner.Slot) return;
-    designerName = designer;
-    MenuManager.CloseActiveMenu(player);
-
-    msg.WeaponSelected(player, designerName.GetFriendlyWeaponName())
-     .ToChat(Prisoner, Guard);
-
-    State = LRState.ACTIVE;
-
-    Prisoner.RemoveWeapons();
-    Guard.RemoveWeapons();
-    Prisoner.GiveNamedItem(designerName);
-    Guard.GiveNamedItem(designerName);
-
-    Plugin.AddTimer(0.5f, () => {
-      magSize = (magForMag ?
-        Prisoner.GetWeaponBase(designerName)!.VData?.MaxClip1 :
-        1) ?? 1;
-      Prisoner.GetWeaponBase(designerName).SetAmmo(0, 0);
-      Guard.GetWeaponBase(designerName).SetAmmo(0, 0);
-      var shooter = new Random().Next(2) == 0 ? Prisoner : Guard;
-      whosShot = shooter.Slot;
-      msg.PlayerGoesFirst(shooter).ToChat(Prisoner, Guard);
-
-      shooter.GetWeaponBase(designer).SetAmmo(magSize.Value, 0);
-    });
-  }
-
   public override void Setup() {
     Plugin.RegisterEventHandler<EventBulletImpact>(OnPlayerShoot);
 
@@ -77,17 +39,30 @@ public override void Setup() {
 
     base.Setup();
     Execute();
-
-    chatMenu.Title =
-      $"{chatMenu.Title} - {Prisoner.PlayerName} vs {Guard.PlayerName}";
   }
 
+  private const string weaponName = "weapon_deagle";
 
   public override void Execute() {
     State = LRState.PENDING;
     MenuManager.OpenChatMenu(Prisoner, chatMenu);
 
-    Plugin.AddTimer(10, timeout, TimerFlags.STOP_ON_MAPCHANGE);
+    Plugin.AddTimer(5, () => {
+      if (State != LRState.PENDING) return;
+      Guard.GiveNamedItem(weaponName);
+      Prisoner.GiveNamedItem(weaponName);
+
+      magSize = (magForMag ?
+        Prisoner.GetWeaponBase(weaponName)!.VData?.MaxClip1 :
+        1) ?? 1;
+      Prisoner.GetWeaponBase(weaponName).SetAmmo(0, 0);
+      Guard.GetWeaponBase(weaponName).SetAmmo(0, 0);
+      var shooter = new Random().Next(2) == 0 ? Prisoner : Guard;
+      whosShot = shooter.Slot;
+      msg.PlayerGoesFirst(shooter).ToChat(Prisoner, Guard);
+      shooter.GetWeaponBase(weaponName).SetAmmo(magSize.Value, 0);
+      State = LRState.ACTIVE;
+    }, TimerFlags.STOP_ON_MAPCHANGE);
 
     Plugin.AddTimer(30, () => {
       if (State != LRState.ACTIVE) return;
@@ -117,11 +92,6 @@ public override void Execute() {
     }, TimerFlags.STOP_ON_MAPCHANGE);
   }
 
-  private void timeout() {
-    if (string.IsNullOrEmpty(designerName))
-      Manager.EndLastRequest(this, LRResult.TIMED_OUT);
-  }
-
   private HookResult OnPlayerShoot(EventBulletImpact @event,
     GameEventInfo info) {
     if (State != LRState.ACTIVE) return HookResult.Continue;
diff --git a/mod/Jailbreak.Rebel/RebelManager.cs b/mod/Jailbreak.Rebel/RebelManager.cs
index b9ccd7af..02b8e4ff 100644
--- a/mod/Jailbreak.Rebel/RebelManager.cs
+++ b/mod/Jailbreak.Rebel/RebelManager.cs
@@ -123,7 +123,8 @@ private float getRebelTimePercentage(CCSPlayerController player) {
   }
 
   private Color getRebelColor(CCSPlayerController player) {
-    var percent             = getRebelTimePercentage(player);
+    var percent = getRebelTimePercentage(player);
+    percent = Math.Clamp(percent, 0, 1);
     var percentRgb          = 255 - (int)Math.Round(percent * 255.0);
     var color               = Color.FromArgb(255, 255, percentRgb, percentRgb);
     if (percent <= 0) color = Color.White;

From 6e7a79904f9baf57c3f021804090390e352fb09a Mon Sep 17 00:00:00 2001
From: MSWS <imodmaker@gmail.com>
Date: Tue, 8 Oct 2024 18:48:12 -0700
Subject: [PATCH 3/5] Add min-player requirements for credts from LR

---
 .../LastRequestManager.cs                     | 39 ++++++++++++-------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/mod/Jailbreak.LastRequest/LastRequestManager.cs b/mod/Jailbreak.LastRequest/LastRequestManager.cs
index 29971e58..a248e9ed 100644
--- a/mod/Jailbreak.LastRequest/LastRequestManager.cs
+++ b/mod/Jailbreak.LastRequest/LastRequestManager.cs
@@ -37,6 +37,10 @@ public class LastRequestManager(ILRLocale messages, IServiceProvider provider)
     new("css_jb_lr_activate_lr_at", "Number of prisoners to activate LR at", 2,
       ConVarFlags.FCVAR_NONE, new RangeValidator<int>(1, 32));
 
+  public static readonly FakeConVar<int> CV_MIN_PLAYERS_FOR_CREDITS =
+    new("css_jb_min_players_for_credits",
+      "Minimum number of players to start" + " giving credits out", 5);
+
   private ILastRequestFactory? factory;
   public bool IsLREnabledForRound { get; set; } = true;
 
@@ -87,6 +91,11 @@ public void DisableLRForRound() {
     IsLREnabledForRound = false;
   }
 
+  private static bool shouldGrantCredits() {
+    if (API.Gangs == null) return false;
+    return Utilities.GetPlayers().Count >= CV_MIN_PLAYERS_FOR_CREDITS.Value;
+  }
+
   public void EnableLR(CCSPlayerController? died = null) {
     messages.LastRequestEnabled().ToAllChat();
     IsLREnabled = true;
@@ -101,25 +110,25 @@ public void EnableLR(CCSPlayerController? died = null) {
 
     RoundUtil.AddTimeRemaining(CV_LR_GUARD_TIME.Value * cts);
 
-    foreach (var player in Utilities.GetPlayers()) {
+    var players = Utilities.GetPlayers();
+    foreach (var player in players) {
       player.ExecuteClientCommand("play sounds/lr");
       if (player.Team != CsTeam.Terrorist || !player.PawnIsAlive) continue;
       if (died != null && player.SteamID == died.SteamID) continue;
       player.ExecuteClientCommandFromServer("css_lr");
     }
 
-    if (API.Gangs != null) {
-      var eco = API.Gangs.Services.GetService<IEcoManager>();
-      if (eco == null) return;
-      var survivors = Utilities.GetPlayers()
-       .Where(p => p is { IsBot: false, PawnIsAlive: true })
-       .Select(p => new PlayerWrapper(p))
-       .ToList();
-      Task.Run(async () => {
-        foreach (var survivor in survivors)
-          await eco.Grant(survivor, 100, reason: "LR Reached");
-      });
-    }
+    if (!shouldGrantCredits()) return;
+    var eco = API.Gangs?.Services.GetService<IEcoManager>();
+    if (eco == null) return;
+    var survivors = Utilities.GetPlayers()
+     .Where(p => p is { IsBot: false, PawnIsAlive: true })
+     .Select(p => new PlayerWrapper(p))
+     .ToList();
+    Task.Run(async () => {
+      foreach (var survivor in survivors)
+        await eco.Grant(survivor, 100, reason: "LR Reached");
+    });
   }
 
   public bool InitiateLastRequest(CCSPlayerController prisoner,
@@ -153,8 +162,8 @@ public bool EndLastRequest(AbstractLastRequest lr, LRResult result) {
       RoundUtil.AddTimeRemaining(CV_LR_BONUS_TIME.Value);
       messages.LastRequestDecided(lr, result).ToAllChat();
 
-      if (API.Gangs != null) {
-        var eco = API.Gangs.Services.GetService<IEcoManager>();
+      if (shouldGrantCredits()) {
+        var eco = API.Gangs?.Services.GetService<IEcoManager>();
         if (eco == null) return false;
         var wrapper =
           new PlayerWrapper(result == LRResult.GUARD_WIN ?

From 85e736ced83eb06c8a033bb4e34cbed2977ae92a Mon Sep 17 00:00:00 2001
From: MSWS <imodmaker@gmail.com>
Date: Tue, 8 Oct 2024 18:49:05 -0700
Subject: [PATCH 4/5] Dont reward 0 credits for 0 killed by C4

---
 mod/Jailbreak.Rebel/C4Bomb/C4Behavior.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mod/Jailbreak.Rebel/C4Bomb/C4Behavior.cs b/mod/Jailbreak.Rebel/C4Bomb/C4Behavior.cs
index bfacd765..25a95d2a 100644
--- a/mod/Jailbreak.Rebel/C4Bomb/C4Behavior.cs
+++ b/mod/Jailbreak.Rebel/C4Bomb/C4Behavior.cs
@@ -268,7 +268,7 @@ private void detonate(CCSPlayerController player, CC4 bomb) {
       }
     }
 
-    if (API.Gangs != null) {
+    if (API.Gangs != null && killed > 0) {
       var eco = API.Gangs.Services.GetService<IEcoManager>();
       if (eco != null) {
         var wrapper = new PlayerWrapper(player);

From d2521b19225109c57a69b190a7fca85438a6ab86 Mon Sep 17 00:00:00 2001
From: MSWS <imodmaker@gmail.com>
Date: Tue, 8 Oct 2024 18:51:03 -0700
Subject: [PATCH 5/5] Bump JSON

---
 public/Jailbreak.Public/Jailbreak.Public.csproj | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/public/Jailbreak.Public/Jailbreak.Public.csproj b/public/Jailbreak.Public/Jailbreak.Public.csproj
index 5595dfab..a766d80e 100644
--- a/public/Jailbreak.Public/Jailbreak.Public.csproj
+++ b/public/Jailbreak.Public/Jailbreak.Public.csproj
@@ -9,7 +9,7 @@
     <ItemGroup>
         <PackageReference Include="CounterStrikeSharp.API" Version="1.0.260"/>
         <PackageReference Include="JetBrains.Annotations" Version="2024.2.0"/>
-        <PackageReference Include="System.Text.Json" Version="8.0.4"/>
+        <PackageReference Include="System.Text.Json" Version="8.0.5"/>
         <ProjectReference Include="..\Jailbreak.Tag\Jailbreak.Tag.csproj"/>
         <Reference Include="GangsAPI">
             <HintPath>Mixin\GangsAPI.dll</HintPath>