mirror of
https://github.com/edgegamers/Jailbreak.git
synced 2025-12-05 20:40:29 -08:00
refactor: Refactor damage and event handling logic for LRs
- Remove obsolete method overload in `IDamageBlocker.cs` to simplify the interface. - Simplify logic in `GunToss.cs` by removing initialization and cleanup operations, locale injection, and timer setup for guard status. - Refactor `LastRequestManager.cs` by: - Adding `JetBrains.Annotations` and replacing game event handler attributes for better annotation usage. - Streamlining last request event handling by removing redundant tasks and encapsulating utility functions. - Suppressing extra damage event broadcasts and improving message clarity. - Adjusting round time management logic for last requests.
This commit is contained in:
@@ -28,6 +28,7 @@ using Jailbreak.Public.Mod.Rainbow;
|
||||
using Jailbreak.Public.Mod.Rebel;
|
||||
using Jailbreak.Public.Mod.Weapon;
|
||||
using Jailbreak.Public.Utils;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using MStatsShared;
|
||||
@@ -112,14 +113,9 @@ public class LastRequestManager(ILRLocale messages, IServiceProvider provider)
|
||||
basePlugin.RegisterListener<Listeners.OnEntityParentChanged>(OnDrop);
|
||||
VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Hook(OnTakeDamage,
|
||||
HookMode.Pre);
|
||||
VirtualFunctions.CCSPlayer_ItemServices_CanAcquireFunc.Hook(OnCanAcquire,
|
||||
HookMode.Pre);
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
VirtualFunctions.CCSPlayer_ItemServices_CanAcquireFunc.Unhook(OnCanAcquire,
|
||||
HookMode.Pre);
|
||||
|
||||
VirtualFunctions.CBaseEntity_TakeDamageOldFunc.Unhook(OnTakeDamage,
|
||||
HookMode.Pre);
|
||||
}
|
||||
@@ -135,8 +131,6 @@ public class LastRequestManager(ILRLocale messages, IServiceProvider provider)
|
||||
messages.LastRequestEnabled().ToAllChat();
|
||||
IsLREnabled = true;
|
||||
|
||||
API.Stats?.PushStat(new ServerStat("JB_LASTREQUEST_ACTIVATED"));
|
||||
|
||||
var cts = Utilities.GetPlayers()
|
||||
.Count(p => p is { Team: CsTeam.CounterTerrorist, PawnIsAlive: true });
|
||||
|
||||
@@ -188,7 +182,6 @@ public class LastRequestManager(ILRLocale messages, IServiceProvider provider)
|
||||
foreach (var survivor in survivors) {
|
||||
await eco.Grant(survivor, survivor.Team == CsTeam.Terrorist ? 65 : 60,
|
||||
reason: "LR Reached");
|
||||
await incrementLRReached(survivor);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -207,16 +200,6 @@ public class LastRequestManager(ILRLocale messages, IServiceProvider provider)
|
||||
prisoner.SetArmor(0);
|
||||
guard.SetArmor(0);
|
||||
|
||||
var prisonerWrapper = new PlayerWrapper(prisoner);
|
||||
var guardWrapper = new PlayerWrapper(guard);
|
||||
|
||||
Task.Run(async () => {
|
||||
await incrementLRStart(prisonerWrapper);
|
||||
await incrementLRStart(guardWrapper);
|
||||
|
||||
await colorForLR(prisonerWrapper, guardWrapper);
|
||||
});
|
||||
|
||||
messages.InformLastRequest(lr).ToAllChat();
|
||||
return true;
|
||||
}
|
||||
@@ -225,7 +208,6 @@ public class LastRequestManager(ILRLocale messages, IServiceProvider provider)
|
||||
rainbowColorizer.StopRainbow(lr.Prisoner);
|
||||
rainbowColorizer.StopRainbow(lr.Guard);
|
||||
if (result is LRResult.GUARD_WIN or LRResult.PRISONER_WIN) {
|
||||
// RoundUtil.AddTimeRemaining(CV_LR_BONUS_TIME.Value);
|
||||
addRoundTimeCapped(CV_LR_BONUS_TIME.Value, CV_MAX_TIME_FOR_LR.Value);
|
||||
messages.LastRequestDecided(lr, result).ToAllChat();
|
||||
|
||||
@@ -239,9 +221,6 @@ public class LastRequestManager(ILRLocale messages, IServiceProvider provider)
|
||||
Task.Run(async () => await eco.Grant(wrapper,
|
||||
wrapper.Team == CsTeam.CounterTerrorist ? 35 : 20, reason: "LR Win"));
|
||||
}
|
||||
|
||||
if (API.Gangs != null)
|
||||
Task.Run(async () => await incrementLRWin(wrapper));
|
||||
}
|
||||
|
||||
API.Stats?.PushStat(new ServerStat("JB_LASTREQUEST_RESULT",
|
||||
@@ -275,168 +254,6 @@ public class LastRequestManager(ILRLocale messages, IServiceProvider provider)
|
||||
listener.OnWeaponDrop(owner, weapon);
|
||||
}
|
||||
|
||||
private HookResult OnCanAcquire(DynamicHook hook) {
|
||||
if (ActiveLRs.Count == 0) return HookResult.Continue;
|
||||
var player = hook.GetParam<CCSPlayer_ItemServices>(0)
|
||||
.Pawn.Value.Controller.Value?.As<CCSPlayerController>();
|
||||
var data = VirtualFunctions.GetCSWeaponDataFromKey.Invoke(-1,
|
||||
hook.GetParam<CEconItemView>(1).ItemDefinitionIndex.ToString());
|
||||
|
||||
if (player == null || !player.IsValid) return HookResult.Continue;
|
||||
|
||||
var method = hook.GetParam<AcquireMethod>(2);
|
||||
if (method != AcquireMethod.PickUp) return HookResult.Continue;
|
||||
|
||||
if (ActiveLRs.Any(lr => lr.PreventEquip(player, data))) {
|
||||
hook.SetReturn(AcquireResult.NotAllowedByMode);
|
||||
return HookResult.Handled;
|
||||
}
|
||||
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
private async Task colorForLR(PlayerWrapper a, PlayerWrapper b) {
|
||||
var playerStats = API.Gangs?.Services.GetService<IPlayerStatManager>();
|
||||
var gangStats = API.Gangs?.Services.GetService<IGangStatManager>();
|
||||
var gangs = API.Gangs?.Services.GetService<IGangManager>();
|
||||
var localizer = API.Gangs?.Services.GetService<IStringLocalizer>();
|
||||
if (playerStats == null || localizer == null || gangs == null
|
||||
|| gangStats == null)
|
||||
return;
|
||||
var aData = await playerStats.GetForPlayer<LRColor>(a, LRColorPerk.STAT_ID);
|
||||
var bData = await playerStats.GetForPlayer<LRColor>(b, LRColorPerk.STAT_ID);
|
||||
|
||||
LRColor? toApply = null;
|
||||
PlayerWrapper? higher = null;
|
||||
higher = await getHigherPlayer(a, b);
|
||||
if (toApply == null) return;
|
||||
if (a.Player == null || b.Player == null) return;
|
||||
|
||||
var higherGang = await gangs.GetGang(higher.Steam);
|
||||
if (higherGang == null) return;
|
||||
|
||||
var gData =
|
||||
await gangStats.GetForGang<LRColor>(higherGang, LRColorPerk.STAT_ID);
|
||||
|
||||
if ((gData & toApply.Value) == 0) return;
|
||||
|
||||
var color = toApply.Value.GetColor();
|
||||
|
||||
if (color == null) { // Player picked random, but we need to pick
|
||||
// the random from their GANG's colors
|
||||
var gangData =
|
||||
await playerStats.GetForPlayer<LRColor>(higher, LRColorPerk.STAT_ID);
|
||||
color = gangData.PickRandomColor();
|
||||
}
|
||||
|
||||
if (color == null) return;
|
||||
|
||||
await Server.NextFrameAsync(() => {
|
||||
if (toApply == LRColor.RAINBOW) {
|
||||
rainbowColorizer.StartRainbow(a.Player);
|
||||
rainbowColorizer.StartRainbow(b.Player);
|
||||
var rmsg = localizer.Get(MSG.PREFIX)
|
||||
+ $"Your LR will be {IRainbowColorizer.RAINBOW}.";
|
||||
|
||||
a.Player.PrintToChat(rmsg);
|
||||
b.Player.PrintToChat(rmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
a.Player.SetColor(color.Value);
|
||||
b.Player.SetColor(color.Value);
|
||||
|
||||
var msg = localizer.Get(MSG.PREFIX)
|
||||
+ $"Your LR will be {color.GetChatColor()}{color.Value.Name}{ChatColors.Grey}.";
|
||||
|
||||
a.Player.PrintToChat(msg);
|
||||
b.Player.PrintToChat(msg);
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<PlayerWrapper> getHigherPlayer(PlayerWrapper a,
|
||||
PlayerWrapper b) {
|
||||
var leaderboard = API.Gangs?.Services.GetService<ILeaderboard>();
|
||||
var players = API.Gangs?.Services.GetService<IPlayerManager>();
|
||||
if (leaderboard == null || players == null) return a;
|
||||
var aGangPlayer = await players.GetPlayer(a.Steam);
|
||||
var bGangPlayer = await players.GetPlayer(b.Steam);
|
||||
|
||||
if (aGangPlayer == null && bGangPlayer != null) return b;
|
||||
if (aGangPlayer != null && bGangPlayer == null) return a;
|
||||
|
||||
if (aGangPlayer == null || bGangPlayer == null) return a;
|
||||
|
||||
var aGang = aGangPlayer.GangId;
|
||||
var bGang = bGangPlayer.GangId;
|
||||
|
||||
if (aGang == null && bGang != null) return b;
|
||||
if (aGang != null && bGang == null) return a;
|
||||
|
||||
if (aGang == null || bGang == null) return a;
|
||||
if (aGang == bGang) return a;
|
||||
|
||||
var aRank = await leaderboard.GetPosition(aGang.Value);
|
||||
var bRank = await leaderboard.GetPosition(bGang.Value);
|
||||
|
||||
if (aRank == null && bRank != null) return b;
|
||||
if (aRank != null && bRank == null) return a;
|
||||
|
||||
if (aRank == null || bRank == null) return a;
|
||||
|
||||
return aRank < bRank ? a : b;
|
||||
}
|
||||
|
||||
private async Task incrementLRReached(PlayerWrapper player) {
|
||||
var stats = API.Gangs?.Services.GetService<IPlayerStatManager>();
|
||||
if (stats == null) return;
|
||||
var stat = await getStat(player);
|
||||
if (stat == null) return;
|
||||
|
||||
if (player.Team == CsTeam.Terrorist)
|
||||
stat.LRsReachedAsT++;
|
||||
else
|
||||
stat.LRsReachedAsCt++;
|
||||
|
||||
await stats.SetForPlayer(player, LRStat.STAT_ID, stat);
|
||||
}
|
||||
|
||||
private async Task incrementLRStart(PlayerWrapper player) {
|
||||
var stats = API.Gangs?.Services.GetService<IPlayerStatManager>();
|
||||
if (stats == null) return;
|
||||
var stat = await getStat(player);
|
||||
if (stat == null) return;
|
||||
|
||||
if (player.Team == CsTeam.Terrorist)
|
||||
stat.TLrs++;
|
||||
else
|
||||
stat.CtLrs++;
|
||||
|
||||
await stats.SetForPlayer(player, LRStat.STAT_ID, stat);
|
||||
}
|
||||
|
||||
private async Task incrementLRWin(PlayerWrapper player) {
|
||||
var stats = API.Gangs?.Services.GetService<IPlayerStatManager>();
|
||||
if (stats == null) return;
|
||||
var stat = await getStat(player);
|
||||
if (stat == null) return;
|
||||
|
||||
if (player.Team == CsTeam.Terrorist)
|
||||
stat.TLrsWon++;
|
||||
else
|
||||
stat.CTLrsWon++;
|
||||
|
||||
await stats.SetForPlayer(player, LRStat.STAT_ID, stat);
|
||||
}
|
||||
|
||||
private async Task<LRData?> getStat(PlayerWrapper player) {
|
||||
var stats = API.Gangs?.Services.GetService<IPlayerStatManager>();
|
||||
if (stats == null) return null;
|
||||
var data = await stats.GetForPlayer<LRData>(player, LRStat.STAT_ID)
|
||||
?? new LRData();
|
||||
return data;
|
||||
}
|
||||
|
||||
public static bool shouldGrantCredits() {
|
||||
if (API.Gangs == null) return false;
|
||||
return Utilities.GetPlayers().Count >= CV_MIN_PLAYERS_FOR_CREDITS.Value;
|
||||
@@ -459,39 +276,43 @@ public class LastRequestManager(ILRLocale messages, IServiceProvider provider)
|
||||
HookResult.Continue;
|
||||
}
|
||||
|
||||
[GameEventHandler]
|
||||
[UsedImplicitly]
|
||||
[GameEventHandler(HookMode.Pre)]
|
||||
public HookResult OnTakeDamage(EventPlayerHurt ev, GameEventInfo info) {
|
||||
var player = ev.Userid;
|
||||
var attacker = ev.Attacker;
|
||||
if (player == null || !player.IsReal()) return HookResult.Continue;
|
||||
if (player == null || player.Pawn.Value == null) return HookResult.Continue;
|
||||
if (!ShouldBlockDamage(player, attacker)) return HookResult.Continue;
|
||||
if (player.PlayerPawn.IsValid) {
|
||||
var playerPawn = player.PlayerPawn.Value!;
|
||||
playerPawn.Health = playerPawn.LastHealth;
|
||||
}
|
||||
|
||||
info.DontBroadcast = false;
|
||||
ev.DmgArmor = ev.DmgHealth = 0;
|
||||
return HookResult.Handled;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
[GameEventHandler]
|
||||
public HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) {
|
||||
foreach (var lr in ActiveLRs.ToList())
|
||||
EndLastRequest(lr, LRResult.TIMED_OUT);
|
||||
|
||||
IsLREnabled = false;
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
[GameEventHandler]
|
||||
public HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info) {
|
||||
IsLREnabledForRound = true;
|
||||
IsLREnabled = false;
|
||||
foreach (var player in Utilities.GetPlayers())
|
||||
MenuManager.CloseActiveMenu(player);
|
||||
|
||||
foreach (var lr in ActiveLRs.ToList())
|
||||
EndLastRequest(lr, LRResult.TIMED_OUT);
|
||||
ActiveLRs.Clear();
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
[GameEventHandler]
|
||||
public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info) {
|
||||
var player = @event.Userid;
|
||||
@@ -515,6 +336,7 @@ public class LastRequestManager(ILRLocale messages, IServiceProvider provider)
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
[GameEventHandler]
|
||||
public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event,
|
||||
GameEventInfo info) {
|
||||
|
||||
@@ -20,11 +20,6 @@ public class GunToss(BasePlugin plugin, ILastRequestManager manager,
|
||||
IServiceProvider provider, CCSPlayerController prisoner,
|
||||
CCSPlayerController guard)
|
||||
: TeleportingRequest(plugin, manager, prisoner, guard), IDropListener {
|
||||
private readonly List<BeamLine> guardLines = [], prisonerLines = [];
|
||||
|
||||
private readonly ILRGunTossLocale locale =
|
||||
provider.GetRequiredService<ILRGunTossLocale>();
|
||||
|
||||
/// <summary>
|
||||
/// Null if no one has thrown a gun yet, negative if only one has thrown a gun,
|
||||
/// Positive if both have thrown a gun.
|
||||
@@ -56,13 +51,6 @@ public class GunToss(BasePlugin plugin, ILastRequestManager manager,
|
||||
}
|
||||
|
||||
if (prisonerTossed && guardTossed) bothThrewTick = Server.TickCount;
|
||||
|
||||
if (bothThrewTick > 0)
|
||||
Plugin.AddTimer(5, () => {
|
||||
if (State != LRState.ACTIVE) return;
|
||||
Guard.SetHealth(Math.Min(Guard.PlayerPawn.Value!.Health, 100));
|
||||
Guard.SetArmor(Math.Min(Guard.PawnArmor, 100));
|
||||
});
|
||||
}
|
||||
|
||||
public override void Setup() {
|
||||
@@ -71,13 +59,6 @@ public class GunToss(BasePlugin plugin, ILastRequestManager manager,
|
||||
Prisoner.RemoveWeapons();
|
||||
Guard.RemoveWeapons();
|
||||
|
||||
Server.NextFrame(() => {
|
||||
if (!Guard.IsValid) return;
|
||||
|
||||
Guard.SetHealth(500);
|
||||
Guard.SetArmor(500);
|
||||
});
|
||||
|
||||
Plugin.AddTimer(3, Execute);
|
||||
}
|
||||
|
||||
@@ -91,14 +72,7 @@ public class GunToss(BasePlugin plugin, ILastRequestManager manager,
|
||||
Server.RunOnTick(Server.TickCount + 16, () => State = LRState.ACTIVE);
|
||||
}
|
||||
|
||||
public override void OnEnd(LRResult result) {
|
||||
State = LRState.COMPLETED;
|
||||
|
||||
guardLines.ForEach(l => l.Remove());
|
||||
guardLines.Clear();
|
||||
prisonerLines.ForEach(l => l.Remove());
|
||||
prisonerLines.Clear();
|
||||
}
|
||||
public override void OnEnd(LRResult result) { State = LRState.COMPLETED; }
|
||||
|
||||
public override bool PreventEquip(CCSPlayerController player,
|
||||
CCSWeaponBaseVData weapon) {
|
||||
|
||||
@@ -7,12 +7,6 @@ namespace Jailbreak.Public.Mod.Damage;
|
||||
/// taking damage.
|
||||
/// </summary>
|
||||
public interface IDamageBlocker {
|
||||
[Obsolete("Do not use the EventPlayerHurt overload.")]
|
||||
bool ShouldBlockDamage(CCSPlayerController victim,
|
||||
CCSPlayerController? attacker, EventPlayerHurt @event) {
|
||||
return ShouldBlockDamage(victim, attacker);
|
||||
}
|
||||
|
||||
bool ShouldBlockDamage(CCSPlayerController victim,
|
||||
CCSPlayerController? attacker);
|
||||
}
|
||||
Reference in New Issue
Block a user