-
Notifications
You must be signed in to change notification settings - Fork 1
/
PlayerFreezeManager.cs
116 lines (90 loc) · 3.63 KB
/
PlayerFreezeManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using System.Drawing;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using ChaseMod.Utils;
using Timer = CounterStrikeSharp.API.Modules.Timers.Timer;
using Microsoft.Extensions.Logging;
namespace ChaseMod;
public record FrozenPlayer(
float Time,
float StartTime,
System.Numerics.Vector3 StoredVelocity,
Timer Timer
);
internal class PlayerFreezeManager
{
private readonly ChaseMod _plugin;
private readonly Dictionary<CCSPlayerController, FrozenPlayer> _frozenPlayers = new();
public PlayerFreezeManager(ChaseMod chaseMod)
{
_plugin = chaseMod;
}
public void Freeze(CCSPlayerController controller, float time, bool showEffect, bool sendMessage, bool resetVelocity)
{
if (!ChaseModUtils.IsRealPlayer(controller)) return;
var pawn = controller.PlayerPawn.Value!;
ChaseMod.Logger.LogInformation($"Freeze player {pawn.Index}");
var origVelocity = pawn.AbsVelocity.ToManaged();
pawn.AbsVelocity.Set(0, 0, 0);
if (_frozenPlayers.TryGetValue(controller, out var freezeState))
{
if (!resetVelocity) origVelocity = freezeState.StoredVelocity;
freezeState.Timer.Kill();
}
pawn.FreezePlayer();
var playerAlpha = pawn.Render.A;
pawn.Render = Color.FromArgb(playerAlpha, 4, 58, 140);
Utilities.SetStateChanged(pawn, "CBaseModelEntity", "m_clrRender");
if (showEffect)
{
pawn.HealthShotBoostExpirationTime = Server.CurrentTime + time;
Utilities.SetStateChanged(pawn, "CCSPlayerPawn", "m_flHealthShotBoostExpirationTime");
}
if (pawn.WeaponServices != null)
{
var activeWeaponHandle = pawn.WeaponServices.ActiveWeapon;
if (activeWeaponHandle.IsValid)
activeWeaponHandle.Value!.DisableUntil(Server.TickCount + (int)(0.5f + (time / Server.TickInterval)));
}
var timer = _plugin.AddTimer(
time, () => Unfreeze(controller, sendMessage));
_frozenPlayers[controller] = new FrozenPlayer(time, Server.CurrentTime, origVelocity, timer);
if (sendMessage)
{
ChaseModUtils.ChatPrefixed(
controller,
$"{ChatColors.DarkRed}⚠{ChatColors.Grey} You have been {ChatColors.DarkRed}frozen{ChatColors.Grey}.");
}
}
private void Unfreeze(CCSPlayerController controller, bool sendMessage)
{
if (!ChaseModUtils.IsRealPlayer(controller)) return;
var pawn = controller.PlayerPawn.Value!;
ChaseMod.Logger.LogInformation($"Unfreeze player {pawn.Index}");
pawn.UnfreezePlayer();
if (_frozenPlayers.TryGetValue(controller, out var frozenState))
{
pawn.AbsVelocity.Set(frozenState.StoredVelocity);
}
pawn.Render = Color.FromArgb(pawn.Render.A, 255, 255, 255);
Utilities.SetStateChanged(pawn, "CBaseModelEntity", "m_clrRender");
_frozenPlayers.Remove(controller);
if (sendMessage)
{
ChaseModUtils.ChatPrefixed(
controller,
$"{ChatColors.Green}⚠{ChatColors.Grey} You are now {ChatColors.Green}unfrozen{ChatColors.Grey}.");
}
}
public float? GetPlayerFreezeRemaining(CCSPlayerController controller)
{
if (_frozenPlayers.TryGetValue(controller, out var freezeState))
{
var freezeTime = Server.CurrentTime - freezeState.StartTime;
var timeRemaining = freezeState.Time - freezeTime;
return timeRemaining;
}
return null;
}
}