72 lines
3.2 KiB
C#
72 lines
3.2 KiB
C#
using CounterStrikeSharp.API;
|
|
using CounterStrikeSharp.API.Core;
|
|
using Microsoft.Extensions.Logging;
|
|
using Outnumbered.Config;
|
|
|
|
namespace Outnumbered;
|
|
|
|
// Entry point. The plugin is a sealed partial class split by concern across files
|
|
// (Persistence.cs, Commands.cs, ...) — cookbook §0.
|
|
public sealed partial class OutnumberedPlugin : BasePlugin, IPluginConfig<OutnumberedConfig>
|
|
{
|
|
public override string ModuleName => "Outnumbered";
|
|
public override string ModuleVersion => "1.0.0-modes";
|
|
public override string ModuleAuthor => "snake";
|
|
public override string ModuleDescription => "Players-vs-bots RPG / perk mod.";
|
|
|
|
public OutnumberedConfig Config { get; set; } = new();
|
|
public void OnConfigParsed(OutnumberedConfig config) => Config = config; // MUST assign (cookbook §0)
|
|
|
|
// True between Load and Unload. Untracked one-shot AddTimer/NextFrame callbacks (SetupMap, the draft auto-pop, the
|
|
// changelevel) check this so a hot-reload/unload landing inside their delay window no-ops instead of firing against a
|
|
// torn-down instance. The REPEAT timers are killed explicitly in their Shutdown_*; this guards the deferred one-shots.
|
|
private bool _live;
|
|
|
|
public override void Load(bool hotReload)
|
|
{
|
|
Initialize_Database(hotReload);
|
|
Initialize_Driver();
|
|
Initialize_Handicap(); // structural guard: HandicapOverride mirrors HandicapConfig (fail-loud at load)
|
|
Initialize_Stats();
|
|
Initialize_Abilities();
|
|
Initialize_Effects(); // survival burn-DoT tick (no-op outside survival)
|
|
Initialize_Hud();
|
|
Initialize_Shop();
|
|
Initialize_Ranks();
|
|
Initialize_Feel();
|
|
Initialize_Api(); // the local UDS status/balance/top API — last: it reads the driver + effective handicap
|
|
RegisterListener<Listeners.OnTick>(OnTick_All); // ONE per-tick roster walk fanning out to the subsystems
|
|
RegisterSkillCommands(); // !s1..!sN direct skill-buy
|
|
RegisterAbilityCommands(); // !ability1..!abilityN bindable casts
|
|
_live = true;
|
|
Logger.LogInformation("Outnumbered loaded (mode driver: {Mode}) — persistence + stats + progression + handicap + abilities + HUD + shop.", _driver.Id);
|
|
}
|
|
|
|
// ONE per-tick roster walk shared by all per-tick subsystems: Utilities.GetPlayers() allocates a List, so materializing
|
|
// it once and fanning out (each subsystem keeps its own Enabled gate + throttle counter) avoids 3 extra full-roster
|
|
// scans + List allocs per tick.
|
|
private void OnTick_All()
|
|
{
|
|
var players = Utilities.GetPlayers();
|
|
OnTick_Abilities(players);
|
|
OnTick_Hud(players);
|
|
OnTick_Shop(players);
|
|
OnTick_Feel(players);
|
|
}
|
|
|
|
public override void Unload(bool hotReload)
|
|
{
|
|
_live = false; // make any in-flight one-shot timer/NextFrame callback a no-op
|
|
RemoveListener<Listeners.OnTick>(OnTick_All);
|
|
Shutdown_Api(); // reverse init order: stop serving (and unlink the socket) before the subsystems it reads tear down
|
|
Shutdown_Feel();
|
|
Shutdown_Ranks();
|
|
Shutdown_Shop();
|
|
Shutdown_Hud();
|
|
Shutdown_Abilities();
|
|
Shutdown_Effects();
|
|
Shutdown_Stats();
|
|
Shutdown_Driver();
|
|
Shutdown_Database();
|
|
}
|
|
}
|