feat: Panorama skill HUD and menu, CSS 1.0.375
- Skill card and W/S/E target menu drawn as CCSCustomHudLayout panels via PanoramaManager (panorama/ sources), replacing PrintToCenterHtml and WASDMenuAPI; WASDMenuAPI.dll dropped - Custom status lines (cooldowns, charges) overwrite the description on the card; Medic keeps its description with the charge count below - css_setoverride toggles a per-player cooldown bypass - YourSkillChatInfo also gates the round-start skill description in chat - Language: "[css_useSkill]" becomes the configured button name, "Press ... key" wording, welcome message trimmed to its first line - Build against CounterStrikeSharp.API 1.0.375
This commit is contained in:
parent
20dafd2a7c
commit
793370a55f
37 changed files with 1076 additions and 415 deletions
|
|
@ -3,13 +3,13 @@ using CounterStrikeSharp.API.Core;
|
|||
using CounterStrikeSharp.API.Core.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using PanoramaManager;
|
||||
using src.command;
|
||||
using src.player;
|
||||
using src.utils;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using WASDSharedAPI;
|
||||
using static CounterStrikeSharp.API.Core.Listeners;
|
||||
|
||||
namespace src
|
||||
|
|
@ -22,8 +22,21 @@ namespace src
|
|||
public IEnumerable<jSkill_PlayerInfo> SkillPlayer => PlayerManager.GetAllPlayers();
|
||||
public Random Random => Random.Shared;
|
||||
public CCSGameRules? GameRules { get; set; }
|
||||
// The entity backing GameRules above. SetStateChanged needs the entity itself,
|
||||
// not the GameRules subobject, so this is kept alongside it.
|
||||
public CCSGameRulesProxy? GameRulesProxy { get; set; }
|
||||
private ConcurrentBag<string> ManifestResources { get; set; } = ["models/sprays/spray_plane.vmdl"];
|
||||
public IWasdMenuManager? MenuManager;
|
||||
// Stage 1 of the Panorama HUD replacement (see PlayerEvents.cs's UpdateSkillHUD and
|
||||
// CLAUDE.md's "Panorama HUD" section) - drives skill_hud.xml for skills that don't set a
|
||||
// custom PrintHTML override. Own LayoutContract, not LayoutContract.Default: PanoramaManager
|
||||
// warns two layouts sharing a root id silently share dialog variables across plugins.
|
||||
public static readonly LayoutContract SkillHudContract = new()
|
||||
{
|
||||
RootPanelId = "SkillHudRoot",
|
||||
RowCount = 0,
|
||||
CaptureInput = false,
|
||||
};
|
||||
public PanelHandle? SkillHud;
|
||||
// Skills that were enabled at least once this round; used to reset only those on round change (not all 124).
|
||||
public static readonly ConcurrentDictionary<string, byte> ActiveSkillsThisRound = new();
|
||||
public static readonly ConcurrentDictionary<string, byte> SkillsUsedThisMap = new();
|
||||
|
|
@ -44,10 +57,13 @@ namespace src
|
|||
PlayerOnTick.Load();
|
||||
Event.Load();
|
||||
Command.Load();
|
||||
WASDMenuAPI.WASDMenuAPI.LoadPlugin(Instance, hotReload);
|
||||
LoadAllSkills();
|
||||
PlayerManager.SyncWithPlugin(Instance);
|
||||
|
||||
Panorama.Init(this);
|
||||
SkillHud = Panorama.Spawn("panorama/layout/custom_game/skill_hud.vxml_c", SkillHudContract);
|
||||
PanoramaMenu.Load(this);
|
||||
|
||||
Instance.RegisterListener<OnServerPrecacheResources>(LoadManifest);
|
||||
|
||||
Task.Run(async () =>
|
||||
|
|
@ -65,6 +81,10 @@ namespace src
|
|||
Event.Unload();
|
||||
Debug.Unload();
|
||||
|
||||
SkillHud?.Dispose();
|
||||
PanoramaMenu.Unload();
|
||||
Panorama.Shutdown();
|
||||
|
||||
base.Unload(hotReload);
|
||||
}
|
||||
|
||||
|
|
@ -160,6 +180,10 @@ namespace src
|
|||
|
||||
if (method == null) return null;
|
||||
|
||||
if (methodName == "UseSkill" && param?.Length > 0 && param[0] is CCSPlayerController user
|
||||
&& user.IsValid && CooldownOverride.Has(user))
|
||||
CooldownOverride.ResetBeforeUse(method.DeclaringType!, user);
|
||||
|
||||
if (!PerfLog.Enabled)
|
||||
return method.Invoke(null, param);
|
||||
|
||||
|
|
@ -277,7 +301,6 @@ namespace src
|
|||
Console.WriteLine($"\nDependences:");
|
||||
var files = new Dictionary<string, string> {
|
||||
{ "Newtonsoft Json", "./Newtonsoft.Json.dll" },
|
||||
{ "WASDMenuAPI", "./WASDMenuAPI.dll" },
|
||||
{ "MaxMind", "./MaxMind.Db.dll" },
|
||||
{ "GeoLite2", "./packages/GeoLite2-Country.mmdb" },
|
||||
{ "RayTraceApi", "./../../shared/RayTraceApi/RayTraceApi.dll" },
|
||||
|
|
@ -385,6 +408,23 @@ namespace src
|
|||
public string? Content;
|
||||
}
|
||||
|
||||
// Change-detection so SetVariableFor/SetClassFor are only called when something actually
|
||||
// changed, same principle as HudCacheEntry above (its cache.Content re-send is the same idea,
|
||||
// just at a coarser granularity since PrintToCenterHtml takes one blob, not per-field writes).
|
||||
// TouchedThisTick is reset and checked once per HUD frame in PlayerOnTick.cs - it's what closes
|
||||
// the panel for a player who stopped being updated (warmup started, menu opened, HUD
|
||||
// suppressed, ...) instead of it silently showing stale content forever, which a Panorama panel
|
||||
// would otherwise do - PrintToCenterHtml expires on its own after a few seconds; this doesn't.
|
||||
public sealed class PanoramaHudCache
|
||||
{
|
||||
public bool Open;
|
||||
public bool TouchedThisTick;
|
||||
public string? Skill;
|
||||
public string? Extra;
|
||||
public string? RarityClass;
|
||||
public bool? IsInfo;
|
||||
}
|
||||
|
||||
public class jSkill_SkillInfo(Skills skill, string color, bool display)
|
||||
{
|
||||
public Skills Skill { get; } = skill;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue