Skip to content

Commit

Permalink
Add Shot4Shot and Mag4Mag (#258)
Browse files Browse the repository at this point in the history
Add Shot 4 Shot and Mag 4 Mag
  • Loading branch information
ShookEagle authored Aug 2, 2024
1 parent c07002a commit d4fdbfb
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 103 deletions.
4 changes: 4 additions & 0 deletions mod/Jailbreak.LastRequest/LastRequestFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ public AbstractLastRequest CreateLastRequest(CCSPlayerController prisoner,
LRType.KNIFE_FIGHT => new KnifeFight(plugin!, manager, prisoner, guard),
LRType.GUN_TOSS => new GunToss(plugin!, manager, prisoner, guard),
LRType.NO_SCOPE => new NoScope(plugin!, manager, prisoner, guard),
LRType.SHOT_FOR_SHOT => new ShotForShot(plugin!, manager, prisoner, guard),
LRType.ROCK_PAPER_SCISSORS => new RockPaperScissors(plugin!, manager,
prisoner, guard),
LRType.COINFLIP => new Coinflip(plugin!, manager, prisoner, guard),
LRType.RACE => new Race(plugin!, manager, prisoner, guard,
services.GetRequiredService<IRaceLRMessages>()),
LRType.MAG_FOR_MAG => new MagForMag(plugin!, manager, prisoner, guard),
_ => throw new ArgumentException("Invalid last request type: " + type,
nameof(type))
};
Expand All @@ -34,9 +36,11 @@ public bool IsValidType(LRType type) {
LRType.KNIFE_FIGHT => true,
LRType.GUN_TOSS => true,
LRType.NO_SCOPE => true,
LRType.SHOT_FOR_SHOT => true,
LRType.ROCK_PAPER_SCISSORS => true,
LRType.COINFLIP => true,
LRType.RACE => true,
LRType.MAG_FOR_MAG => true,
_ => false
};
}
Expand Down
124 changes: 69 additions & 55 deletions mod/Jailbreak.LastRequest/LastRequests/MagForMag.cs
Original file line number Diff line number Diff line change
@@ -1,62 +1,68 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Menu;
using CounterStrikeSharp.API.Modules.Timers;
using Jailbreak.Public.Extensions;
using Jailbreak.Public.Mod.LastRequest;
using Jailbreak.Public.Mod.LastRequest.Enums;

namespace Jailbreak.LastRequest.LastRequests;

public class MagForMag(BasePlugin plugin, ILastRequestManager manager,
CCSPlayerController prisoner, CCSPlayerController guard)
: WeaponizedRequest(plugin, manager, prisoner, guard) {
private const int BULLET_COUNT = 7;
public class MagForMag : WeaponizedRequest {
private readonly ChatMenu chatMenu;
private string? CHOSEN_PISTOL;
private int MAGAZINE_SIZE;
private CCSPlayerController? whosShot;
public override LRType Type => LRType.GUN_TOSS;

public override void Setup() {
Plugin.RegisterEventHandler<EventPlayerShoot>(OnPlayerShoot);
base.Setup();

whosShot = new Random().Next(2) == 0 ? Prisoner : Guard;
PrintToParticipants(whosShot.PlayerName + " will shoot first.");
Prisoner.GiveNamedItem("weapon_deagle");
Guard.GiveNamedItem("weapon_deagle");

var weapon = findWeapon(Prisoner, "weapon_deagle");
if (weapon != null) setAmmoAmount(weapon, 0, 0);
weapon = findWeapon(Guard, "weapon_deagle");
if (weapon != null) setAmmoAmount(weapon, 0, 0);
public MagForMag(BasePlugin plugin, ILastRequestManager manager,
CCSPlayerController prisoner, CCSPlayerController guard) :
base(plugin, manager, prisoner, guard) {
chatMenu = new ChatMenu("Shot For Shot");
foreach (var pistol in Tag.PISTOLS) {
chatMenu.AddMenuOption(pistol.GetFriendlyWeaponName(), OnSelect);
}
}
public override LRType Type => LRType.SHOT_FOR_SHOT;

private static CBasePlayerWeapon? findWeapon(CCSPlayerController player,
string name) {
if (!player.IsReal()) return null;

var pawn = player.PlayerPawn.Value;
private void OnSelect(CCSPlayerController player, ChatMenuOption option) {
if (player.Slot != Prisoner.Slot) return;
MenuManager.CloseActiveMenu(player);

if (pawn == null) return null;
CHOSEN_PISTOL = Tag.PISTOLS.ElementAt(Array.IndexOf([
"Desert Eagle", "Dualies", "Five Seven", "Glock 18", "HPK2000", "P250",
"USPS", "Tec9", "CZ75", "Revolver"
], option.Text));

var weapons = pawn.WeaponServices?.MyWeapons;
PrintToParticipants(player.PlayerName + " has chosen to use the " +
CHOSEN_PISTOL.GetFriendlyWeaponName());
State = LRState.ACTIVE;

return weapons?.Select(weaponOpt => weaponOpt.Value)
.OfType<CBasePlayerWeapon>()
.FirstOrDefault(weapon => weapon.DesignerName.Contains(name));
Prisoner.GiveNamedItem(CHOSEN_PISTOL);
Prisoner.GetWeaponBase(CHOSEN_PISTOL).SetAmmo(0,0);
Guard.GiveNamedItem(CHOSEN_PISTOL);
Guard.GetWeaponBase(CHOSEN_PISTOL).SetAmmo(0,0);

//steal the VData of the prisoners gun for mag size
MAGAZINE_SIZE = Prisoner.GetWeaponBase(CHOSEN_PISTOL)!.VData!.MaxClip1;

whosShot = new Random().Next(2) == 0 ? Prisoner : Guard;
PrintToParticipants(whosShot.PlayerName + " has been chosen to shoot first");

whosShot.GetWeaponBase(CHOSEN_PISTOL).SetAmmo(MAGAZINE_SIZE, 0);
}

private static void setAmmoAmount(CBasePlayerWeapon weapon, int primary,
int reserve) {
weapon.Clip1 = primary;
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_iClip1");
weapon.Clip2 = reserve;
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_pReserveAmmo");
}
public override void Setup() {
Plugin.RegisterEventHandler<EventPlayerShoot>(OnPlayerShoot);
base.Setup();

CHOSEN_PISTOL = String.Empty;
chatMenu.Title =
$"Shot For Shot - {Prisoner.PlayerName} vs {Guard.PlayerName}";
}
public override void Execute() {
State = LRState.ACTIVE;
var deagle = findWeapon(whosShot!, "weapon_deagle");
if (deagle != null) setAmmoAmount(deagle, BULLET_COUNT, 0);

State = LRState.PENDING;
MenuManager.OpenChatMenu(Prisoner, chatMenu);

Plugin.AddTimer(10, timeout, TimerFlags.STOP_ON_MAPCHANGE);

Plugin.AddTimer(30, () => {
if (State != LRState.ACTIVE) return;
Prisoner.GiveNamedItem("weapon_knife");
Expand All @@ -76,39 +82,47 @@ public override void Execute() {
LRResult.PRISONER_WIN;
} else { PrintToParticipants("Health was the deciding factor. "); }

Manager.EndLastRequest(this, result);
if (result == LRResult.GUARD_WIN)
Prisoner.Pawn.Value?.CommitSuicide(false, true);
else
Guard.Pawn.Value?.CommitSuicide(false, true);
}, TimerFlags.STOP_ON_MAPCHANGE);
}

private void timeout() {
if (CHOSEN_PISTOL == String.Empty)
Manager.EndLastRequest(this, LRResult.TIMED_OUT);
}

public HookResult OnPlayerShoot(EventPlayerShoot @event, GameEventInfo info) {
private HookResult OnPlayerShoot(EventPlayerShoot @event,
GameEventInfo info) {
if (State != LRState.ACTIVE) return HookResult.Continue;

var player = @event.Userid;
if (!player.IsReal()) return HookResult.Continue;

if (player!.Slot != Prisoner.Slot && player.Slot != Guard.Slot)
if (player == null || whosShot == null || !player.IsReal())
return HookResult.Continue;

var shootersDeagle = findWeapon(player, "weapon_deagle");
if (shootersDeagle == null) return HookResult.Continue;
if (player.Slot != Prisoner.Slot && player.Slot != Guard.Slot)
return HookResult.Continue;
if (player.Slot != whosShot.Slot) {
PrintToParticipants(player.PlayerName + " cheated.");
player.Pawn.Value?.CommitSuicide(false, true);
return HookResult.Handled;
}

if (shootersDeagle.Clip1 != 0) return HookResult.Continue;
if (player.GetWeaponBase(CHOSEN_PISTOL).Clip1 != 0)

Check warning on line 113 in mod/Jailbreak.LastRequest/LastRequests/MagForMag.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'designerName' in 'CBasePlayerWeapon? PlayerExtensions.GetWeaponBase(CCSPlayerController player, string designerName)'.

Check warning on line 113 in mod/Jailbreak.LastRequest/LastRequests/MagForMag.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
return HookResult.Continue;

PrintToParticipants(player.PlayerName + " has shot.");
PrintToParticipants(player.PlayerName + " has shot all their bullets.");
var opponent = player.Slot == Prisoner.Slot ? Guard : Prisoner;
opponent.PrintToChat("Your shot");
var deagle = findWeapon(opponent, "weapon_deagle");
if (deagle != null) setAmmoAmount(deagle, 0, BULLET_COUNT);
opponent.GetWeaponBase(CHOSEN_PISTOL).SetAmmo(MAGAZINE_SIZE, 0);
whosShot = opponent;
return HookResult.Continue;
}

public override void OnEnd(LRResult result) {
Plugin.RemoveListener(OnPlayerShoot);
Plugin.DeregisterEventHandler<EventPlayerShoot>(OnPlayerShoot);
State = LRState.COMPLETED;
}
}
100 changes: 53 additions & 47 deletions mod/Jailbreak.LastRequest/LastRequests/ShotForShot.cs
Original file line number Diff line number Diff line change
@@ -1,62 +1,64 @@
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Menu;
using CounterStrikeSharp.API.Modules.Timers;
using Jailbreak.Public.Extensions;
using Jailbreak.Public.Mod.LastRequest;
using Jailbreak.Public.Mod.LastRequest.Enums;

namespace Jailbreak.LastRequest.LastRequests;

public class ShotForShot(BasePlugin plugin, ILastRequestManager manager,
CCSPlayerController prisoner, CCSPlayerController guard)
: WeaponizedRequest(plugin, manager, prisoner, guard) {
public class ShotForShot : WeaponizedRequest {
private readonly ChatMenu chatMenu;
private string? CHOSEN_PISTOL;
private CCSPlayerController? whosShot;
public override LRType Type => LRType.SHOT_FOR_SHOT;

public override void Setup() {
Plugin.RegisterEventHandler<EventPlayerShoot>(OnPlayerShoot);
base.Setup();

whosShot = new Random().Next(2) == 0 ? Prisoner : Guard;
PrintToParticipants(whosShot.PlayerName + " will shoot first.");
Prisoner.GiveNamedItem("weapon_deagle");
Guard.GiveNamedItem("weapon_deagle");

var weapon = findWeapon(Prisoner, "weapon_deagle");
if (weapon != null) setAmmoAmount(weapon, 0, 0);
weapon = findWeapon(Guard, "weapon_deagle");
if (weapon != null) setAmmoAmount(weapon, 0, 0);
public ShotForShot(BasePlugin plugin, ILastRequestManager manager,
CCSPlayerController prisoner, CCSPlayerController guard) :
base(plugin, manager, prisoner, guard) {
chatMenu = new ChatMenu("Shot For Shot");
foreach (var pistol in Tag.PISTOLS) {
chatMenu.AddMenuOption(pistol.GetFriendlyWeaponName(), OnSelect);
}
}
public override LRType Type => LRType.SHOT_FOR_SHOT;

private static CBasePlayerWeapon? findWeapon(CCSPlayerController player,
string name) {
if (!player.IsReal()) return null;

var pawn = player.PlayerPawn.Value;
private void OnSelect(CCSPlayerController player, ChatMenuOption option) {
if (player.Slot != Prisoner.Slot) return;
MenuManager.CloseActiveMenu(player);

if (pawn == null) return null;
CHOSEN_PISTOL = Tag.PISTOLS.ElementAt(Array.IndexOf([
"Desert Eagle", "Dualies", "Five Seven", "Glock 18", "HPK2000", "P250",
"USPS", "Tec9", "CZ75", "Revolver"
], option.Text));

var weapons = pawn.WeaponServices?.MyWeapons;
PrintToParticipants(player.PlayerName + " has chosen to use the " +
CHOSEN_PISTOL.GetFriendlyWeaponName());
State = LRState.ACTIVE;

return weapons?.Select(weaponOpt => weaponOpt.Value)
.OfType<CBasePlayerWeapon>()
.FirstOrDefault(weapon => weapon.DesignerName.Contains(name));
Prisoner.GiveNamedItem(CHOSEN_PISTOL);
Prisoner.GetWeaponBase(CHOSEN_PISTOL).SetAmmo(0,0);
Guard.GiveNamedItem(CHOSEN_PISTOL);
Guard.GetWeaponBase(CHOSEN_PISTOL).SetAmmo(0,0);

whosShot = new Random().Next(2) == 0 ? Prisoner : Guard;
PrintToParticipants(whosShot.PlayerName + " has been chosen to shoot first");

whosShot.GetWeaponBase(CHOSEN_PISTOL).SetAmmo(1, 0);
}

private static void setAmmoAmount(CBasePlayerWeapon weapon, int primary,
int reserve) {
weapon.Clip1 = primary;
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_iClip1");
weapon.Clip2 = reserve;
Utilities.SetStateChanged(weapon, "CBasePlayerWeapon", "m_pReserveAmmo");
}
public override void Setup() {
Plugin.RegisterEventHandler<EventPlayerShoot>(OnPlayerShoot);
base.Setup();

CHOSEN_PISTOL = String.Empty;
chatMenu.Title =
$"Shot For Shot - {Prisoner.PlayerName} vs {Guard.PlayerName}";
}
public override void Execute() {
State = LRState.ACTIVE;
if (whosShot == null) return;
var deagle = findWeapon(whosShot, "weapon_deagle");
if (deagle != null) setAmmoAmount(deagle, 1, 0);

State = LRState.PENDING;
MenuManager.OpenChatMenu(Prisoner, chatMenu);

Plugin.AddTimer(10, timeout, TimerFlags.STOP_ON_MAPCHANGE);
Plugin.AddTimer(30, () => {
if (State != LRState.ACTIVE) return;
Prisoner.GiveNamedItem("weapon_knife");
Expand All @@ -69,7 +71,7 @@ public override void Execute() {
LRResult.GUARD_WIN :
LRResult.PRISONER_WIN;
if (Guard.Health == Prisoner.Health) {
PrintToParticipants("Even health, since " + whosShot.PlayerName
PrintToParticipants("Even health, since " + whosShot!.PlayerName
+ " had the shot last, they lose.");
result = whosShot.Slot == Prisoner.Slot ?
LRResult.GUARD_WIN :
Expand All @@ -82,11 +84,16 @@ public override void Execute() {
Guard.Pawn.Value?.CommitSuicide(false, true);
}, TimerFlags.STOP_ON_MAPCHANGE);
}

private void timeout() {
if (CHOSEN_PISTOL == String.Empty)
Manager.EndLastRequest(this, LRResult.TIMED_OUT);
}

private HookResult OnPlayerShoot(EventPlayerShoot @event,
GameEventInfo info) {
if (State != LRState.ACTIVE) return HookResult.Continue;

var player = @event.Userid;
if (player == null || whosShot == null || !player.IsReal())
return HookResult.Continue;
Expand All @@ -102,14 +109,13 @@ private HookResult OnPlayerShoot(EventPlayerShoot @event,
PrintToParticipants(player.PlayerName + " has shot.");
var opponent = player.Slot == Prisoner.Slot ? Guard : Prisoner;
opponent.PrintToChat("Your shot");
var deagle = findWeapon(opponent, "weapon_deagle");
if (deagle != null) setAmmoAmount(deagle, 1, 0);
opponent.GetWeaponBase(CHOSEN_PISTOL).SetAmmo(1, 0);

Check warning on line 112 in mod/Jailbreak.LastRequest/LastRequests/ShotForShot.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'designerName' in 'CBasePlayerWeapon? PlayerExtensions.GetWeaponBase(CCSPlayerController player, string designerName)'.
whosShot = opponent;
return HookResult.Continue;
}

public override void OnEnd(LRResult result) {
Plugin.RemoveListener(OnPlayerShoot);
Plugin.DeregisterEventHandler<EventPlayerShoot>(OnPlayerShoot);
State = LRState.COMPLETED;
}
}
5 changes: 4 additions & 1 deletion public/Jailbreak.Public/Extensions/WeaponExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ namespace Jailbreak.Public.Extensions;

public static class WeaponExtensions {
public static string ToFriendlyString(this CCSWeaponBase weaponEntity) {
var designerName = weaponEntity.DesignerName;
return weaponEntity.DesignerName.GetFriendlyWeaponName();
}

public static string GetFriendlyWeaponName(this string designerName) {
switch (designerName) {
case "weapon_ak47":
return "AK47";
Expand Down

0 comments on commit d4fdbfb

Please sign in to comment.