initial commit
This commit is contained in:
commit
d701598350
67 changed files with 9351 additions and 0 deletions
76
Outnumbered/Feel.cs
Normal file
76
Outnumbered/Feel.cs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Outnumbered.Data;
|
||||
using Outnumbered.Engine;
|
||||
|
||||
namespace Outnumbered;
|
||||
|
||||
// "Ability is active" feedback. Two layers, sharing one blended colour:
|
||||
// 1. HUD recolour (RELIABLE): while any ability is active the whole HUD tints to the blended perk colour.
|
||||
// 2. Screen tint (EXPERIMENTAL): a faint full-screen "movie filter" via the CS2 fade user message — the exact
|
||||
// message format is unverified and hard to debug blind, so it's toggleable (Abilities.ScreenTint) and the
|
||||
// HUD recolour is the guaranteed fallback.
|
||||
// Per-perk colours come from AbilityDef.Tint{R,G,B}; when several are up the colours are averaged.
|
||||
public sealed partial class OutnumberedPlugin
|
||||
{
|
||||
private readonly Dictionary<int, int> _tintState = new(); // slot -> last packed RGBA applied via fade (0 = none)
|
||||
private int _feelTick;
|
||||
private bool _fadeWarned;
|
||||
|
||||
// Per-player sound cue via the client `play` command (built-in CS2 sounds; empty = none).
|
||||
private void PlaySound(CCSPlayerController? p, string path)
|
||||
{
|
||||
if (!Config.Sounds.Enabled || string.IsNullOrEmpty(path) || p is not { IsValid: true } || p.IsBot) return;
|
||||
p.ExecuteClientCommand($"play {path}");
|
||||
}
|
||||
|
||||
private void Initialize_Feel() { /* nothing to initialize — OnTick runs via OnTick_All (shared roster walk); teardown is in Shutdown_Feel */ }
|
||||
|
||||
private void Shutdown_Feel()
|
||||
{
|
||||
foreach (var p in Utilities.GetPlayers()) // don't leave a stuck tint on reload
|
||||
if (p is { IsValid: true } && !p.IsBot) SendFade(p, 0, 0, 0, 0, clear: true);
|
||||
_tintState.Clear();
|
||||
}
|
||||
|
||||
// Averaged colour of the player's currently-active abilities.
|
||||
private (bool any, int r, int g, int b) BlendActiveTint(PlayerData pd)
|
||||
{
|
||||
if (!Config.Abilities.Enabled) return (false, 0, 0, 0);
|
||||
long r = 0, g = 0, b = 0; int n = 0;
|
||||
for (int i = 0; i < AbilityCount; i++)
|
||||
if (AbilityActive(pd, i)) { var d = AbilityCfg(i); r += d.TintR; g += d.TintG; b += d.TintB; n++; }
|
||||
return n == 0 ? (false, 0, 0, 0) : (true, (int)(r / n), (int)(g / n), (int)(b / n));
|
||||
}
|
||||
|
||||
// ---- screen tint (fade) ----
|
||||
private void OnTick_Feel(List<CCSPlayerController> players)
|
||||
{
|
||||
if (!Config.Abilities.Enabled || !Config.Abilities.ScreenTint) return;
|
||||
if (++_feelTick % 8 != 0) return; // ~8 Hz; only sends on change anyway
|
||||
foreach (var p in players)
|
||||
{
|
||||
if (!IsHuman(p)) continue; // inline predicate (no Where-iterator alloc on this per-tick path)
|
||||
var pd = PdOf(p);
|
||||
if (pd is null) continue;
|
||||
|
||||
var (any, r, g, b) = BlendActiveTint(pd);
|
||||
int a = any ? Math.Clamp(Config.Abilities.TintAlpha, 0, 255) : 0;
|
||||
int packed = any ? ScreenFade.Pack(r, g, b, a) : 0;
|
||||
if (!_tintState.TryGetValue(p.Slot, out var last)) last = 0;
|
||||
if (last == packed) continue;
|
||||
_tintState[p.Slot] = packed;
|
||||
|
||||
if (any) SendFade(p, r, g, b, a, clear: false);
|
||||
// clear by fading the PREVIOUS colour back out (FFADE_IN needs a colour to fade from) + purge the stayout
|
||||
else SendFade(p, last & 0xff, (last >> 8) & 0xff, (last >> 16) & 0xff, (last >> 24) & 0xff, clear: true);
|
||||
}
|
||||
}
|
||||
|
||||
// CS2 screen fade via user message (the message format + send live in Engine.ScreenFade); a wrong field name no-ops
|
||||
// via onError instead of crashing. The blend/decision logic stays here in OnTick_Feel.
|
||||
private void SendFade(CCSPlayerController p, int r, int g, int b, int a, bool clear) =>
|
||||
ScreenFade.Send(p, r, g, b, a, clear,
|
||||
ex => { if (!_fadeWarned) { _fadeWarned = true; Logger.LogWarning(ex, "Outnumbered fade send failed"); } });
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue