using CounterStrikeSharp.API.Core; using CounterStrikeSharp.API.Modules.UserMessages; namespace Outnumbered.Engine; // CS2 screen fade via the Fade user message. The exact message format is UNVERIFIED (hard to debug blind), so the send is // wrapped: a wrong field name no-ops via onError instead of crashing. The blend/decision logic stays plugin-side. internal static class ScreenFade { public static int Pack(int r, int g, int b, int a) => r | (g << 8) | (b << 16) | (a << 24); public static void Send(CCSPlayerController p, int r, int g, int b, int a, bool clear, Action onError) { try { // CUserMessageFade [106]: duration, hold_time, flags, color — all INT; color is one packed value (not nested clr). var msg = UserMessage.FromPartialName("Fade"); msg.SetInt("duration", (int)(0.3f * 512)); // Q7.9 fixed point (seconds * 512); int, not float msg.SetInt("hold_time", 0); // FFADE_STAYOUT holds it until the next fade // hold a tint: FFADE_OUT|FFADE_STAYOUT. clear it: FFADE_IN|FFADE_PURGE (fades the held colour out + drops stayout). msg.SetInt("flags", clear ? (0x1 | 0x10) : (0x2 | 0x8)); msg.SetInt("color", Pack(r, g, b, a)); // packed color32, R in the low byte msg.Send(p); } catch (Exception ex) { onError(ex); } } }