initial commit
All checks were successful
CI / build (push) Successful in 32s
CI / release (push) Successful in 32s
CI / lint (push) Successful in 30s

This commit is contained in:
Kamal Tufekcic 2026-07-05 13:28:35 +03:00
commit d701598350
67 changed files with 9351 additions and 0 deletions

57
Outnumbered/Shop.Draft.cs Normal file
View file

@ -0,0 +1,57 @@
using System.Text;
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Utils;
using Outnumbered.Engine;
namespace Outnumbered;
// The survival between-wave card DRAFT overlay — the 3-card world-text render.
// The draft's input + screen dispatch (ShopScreen.CardDraft, ExecuteOption, the menu-key handling) stays in Shop.cs; this
// partial owns only the panel rendering (create / update / build-text). All state is the shared ShopSession + Config.Shop.
public sealed partial class OutnumberedPlugin
{
// A single survival-draft card panel — centre-justified, chunkier background so each reads as its own "card".
private CPointWorldText? CreateCardPanel()
{
var s = Config.Shop;
return WorldText.Create(s.FontSize, s.WorldUnitsPerPx, s.FontName,
System.Drawing.Color.FromArgb(255, s.ColorR, s.ColorG, s.ColorB), s.DrawBackground, 0.35f,
PointWorldTextJustifyHorizontal_t.POINT_WORLD_TEXT_JUSTIFY_HORIZONTAL_CENTER);
}
// The survival between-wave draft: up to 3 cards side by side (centre card at RightOffset, the others ± CardSpread).
private void UpdateDraftPanels(CCSPlayerController p, ShopSession s, Vector eye, Vector fwd, Vector right, Vector up, QAngle ang)
{
var cfg = Config.Shop;
var draw = Draft is { } sd ? sd.CurrentDraw(p) : new();
int n = Math.Min(draw.Count, s.Cards.Length); // cards actually shown (1..3)
for (int i = 0; i < s.Cards.Length; i++)
{
if (i >= n) // fewer than 3 cards left (pool nearly exhausted) -> drop the spare panel
{
WorldText.Destroy(ref s.Cards[i]); s.CardText[i] = null;
continue;
}
if (s.Cards[i] is null || !s.Cards[i]!.IsValid) { s.Cards[i] = CreateCardPanel(); s.CardText[i] = null; }
var card = s.Cards[i];
if (card is null) continue;
string txt = BuildCardPanel(p, draw[i].key, GrenadeMenuKeys[i]); // grenade keys 6/7/8 (-> [HE]/[Flash]/[Smoke] labels)
if (s.CardText[i] != txt) { WorldText.SetText(card, txt); s.CardText[i] = txt; }
float x = (i - (n - 1) / 2f) * cfg.CardSpread; // centre the row regardless of card count (1/2/3)
WorldText.Place(card, eye + fwd * cfg.ForwardOffset + right * (cfg.RightOffset + x) + up * cfg.UpOffset, ang);
}
}
// One card's text: the key to press, the card name + count, and the current -> next value so you know what you get.
private string BuildCardPanel(CCSPlayerController p, string key, char menuKey)
{
if (Draft is not { } sd || sd.CardInfo(p, key) is not { } v) return " ";
string u = v.Flat ? "" : "%";
var sb = new StringBuilder();
sb.Append($"[ {KeyItemLabel(menuKey)} ]\n");
sb.Append($"{v.Name} [{v.Have}/{v.Cap}]\n");
if (v.Detail is not null) sb.Append(v.Detail); // effect cards: a single descriptive line
else { sb.Append($"Now: +{v.Now:0}{u}\n"); sb.Append($"Next: +{v.Next:0}{u}"); } // stat cards: current -> next
return sb.ToString();
}
}