Organize scripts and add TWS plugins with HTTP timeouts
Vendor pinned T5 and T6 plugin sources under the new plugins layout. Add native HTTP deadlines, status and timing diagnostics, telemetry integration, and build/test tooling.
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
/* tws_t5_common.gsc — shared config, HUD helpers, connect/spawn/help registries. */
|
||||
|
||||
#include maps\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
if (GetDvar(#"zombiemode") != "1")
|
||||
return;
|
||||
|
||||
common_config();
|
||||
|
||||
register_help_command(".help", "List available commands");
|
||||
level thread help_chat_listener();
|
||||
level thread on_player_connect_dispatch();
|
||||
}
|
||||
|
||||
common_config()
|
||||
{
|
||||
if (isDefined(level.hud_x))
|
||||
return;
|
||||
|
||||
// anchor: move the whole cluster with these two
|
||||
level.hud_x = 10;
|
||||
level.hud_y = 10;
|
||||
|
||||
level.hud_row_match = level.hud_y;
|
||||
level.hud_row_round = level.hud_y + 15;
|
||||
level.hud_row_name = level.hud_y + 32;
|
||||
level.hud_row_count = level.hud_y + 54;
|
||||
level.hud_row_bar = level.hud_y + 84;
|
||||
|
||||
level.hud_font_small = 1.4;
|
||||
level.hud_font_large = 2.0;
|
||||
level.hud_font_mid = 1.6;
|
||||
|
||||
level.hud_bar_width = 120;
|
||||
level.hud_bar_height = 8;
|
||||
|
||||
level.hud_col_count = level.hud_x + 90;
|
||||
level.hud_col_name = level.hud_x + 60;
|
||||
level.hud_col_health = level.hud_x + level.hud_bar_width + 12;
|
||||
|
||||
level.hud_rate = 0.1;
|
||||
|
||||
// green/amber/red ramp is health-only
|
||||
level.hud_c_label = (0.85, 0.85, 0.85);
|
||||
level.hud_c_dim = (0.55, 0.55, 0.55);
|
||||
level.hud_c_count = (1, 1, 1);
|
||||
level.hud_c_name = (0.4, 0.9, 0.5);
|
||||
level.hud_c_high = (0.2, 1, 0.4);
|
||||
level.hud_c_mid = (1, 0.8, 0);
|
||||
level.hud_c_low = (1, 0.2, 0.2);
|
||||
level.hud_c_afk = (1, 0.8, 0.2);
|
||||
|
||||
// numbers fade in below this fraction of max hp
|
||||
level.hud_health_threshold = 1.0;
|
||||
|
||||
if (!isDefined(level.tws_spawn_handlers))
|
||||
level.tws_spawn_handlers = [];
|
||||
}
|
||||
|
||||
ensure_config()
|
||||
{
|
||||
if (!isDefined(level.hud_x))
|
||||
common_config();
|
||||
}
|
||||
|
||||
register_spawn_handler(fn)
|
||||
{
|
||||
if (!isDefined(level.tws_spawn_handlers))
|
||||
level.tws_spawn_handlers = [];
|
||||
|
||||
level.tws_spawn_handlers[level.tws_spawn_handlers.size] = fn;
|
||||
}
|
||||
|
||||
// Connection handlers also serve newcomers still waiting in spectator mode.
|
||||
register_connect_handler(fn)
|
||||
{
|
||||
if (!isDefined(level.tws_connect_handlers))
|
||||
level.tws_connect_handlers = [];
|
||||
|
||||
level.tws_connect_handlers[level.tws_connect_handlers.size] = fn;
|
||||
}
|
||||
|
||||
// Modules register their own entries so help only lists installed commands.
|
||||
register_help_command(command, description)
|
||||
{
|
||||
if (!isDefined(level.tws_help_commands))
|
||||
level.tws_help_commands = [];
|
||||
|
||||
entry = spawnStruct();
|
||||
entry.command = command;
|
||||
entry.description = description;
|
||||
level.tws_help_commands[level.tws_help_commands.size] = entry;
|
||||
}
|
||||
|
||||
// Listen at level scope so newcomers can ask for help before their first spawn.
|
||||
help_chat_listener()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill("say", message, player);
|
||||
|
||||
if (!isDefined(player) || !isDefined(message))
|
||||
continue;
|
||||
|
||||
command = toLower(message);
|
||||
if (command == ".help" || command == ".commands")
|
||||
player show_help();
|
||||
}
|
||||
}
|
||||
|
||||
show_help()
|
||||
{
|
||||
// Cache the text per connection; repeated SetText calls consume config strings.
|
||||
if (!isDefined(self.tws_help_elems))
|
||||
{
|
||||
elems = [];
|
||||
// Use the same anchors as the HUD, with room below the health numbers.
|
||||
y = level.hud_row_bar + level.hud_bar_height + 20;
|
||||
title = make_text_elem(self, level.hud_x, y,
|
||||
"left", level.hud_font_mid, level.hud_c_afk);
|
||||
title SetText("Commands");
|
||||
elems[elems.size] = title;
|
||||
|
||||
for (i = 0; i < level.tws_help_commands.size; i++)
|
||||
{
|
||||
entry = level.tws_help_commands[i];
|
||||
elem = make_text_elem(self, level.hud_x, y + 22 + i * 18,
|
||||
"left", level.hud_font_small, level.hud_c_count);
|
||||
elem SetText("^3" + entry.command + "^7 - " + entry.description);
|
||||
elems[elems.size] = elem;
|
||||
}
|
||||
|
||||
self.tws_help_elems = elems;
|
||||
self thread destroy_on_disconnect(elems);
|
||||
}
|
||||
|
||||
for (i = 0; i < self.tws_help_elems.size; i++)
|
||||
{
|
||||
elem = self.tws_help_elems[i];
|
||||
elem.alpha = 1;
|
||||
}
|
||||
|
||||
// Only the expiry timer is replaced; the say listener and cleanup stay alive.
|
||||
self notify("tws_help_refresh");
|
||||
self thread hide_help_after_delay();
|
||||
}
|
||||
|
||||
hide_help_after_delay()
|
||||
{
|
||||
self endon("disconnect");
|
||||
self endon("tws_help_refresh");
|
||||
|
||||
wait 12;
|
||||
|
||||
for (i = 0; i < self.tws_help_elems.size; i++)
|
||||
{
|
||||
elem = self.tws_help_elems[i];
|
||||
elem.alpha = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// only connect listener in the fleet; a second one crashes the T5 SP handshake
|
||||
on_player_connect_dispatch()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill("connected", player);
|
||||
player thread on_player_spawned_dispatch();
|
||||
player thread on_player_connected_dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
on_player_connected_dispatch()
|
||||
{
|
||||
self endon("disconnect");
|
||||
// Leave the connection handshake before invoking optional modules.
|
||||
wait 0.05;
|
||||
|
||||
if (!isDefined(level.tws_connect_handlers))
|
||||
return;
|
||||
|
||||
for (i = 0; i < level.tws_connect_handlers.size; i++)
|
||||
self thread [[ level.tws_connect_handlers[i] ]]();
|
||||
}
|
||||
|
||||
// handlers own their own self endon("disconnect")
|
||||
on_player_spawned_dispatch()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
self waittill("spawned_player");
|
||||
|
||||
if (!isDefined(level.tws_spawn_handlers))
|
||||
return;
|
||||
|
||||
for (i = 0; i < level.tws_spawn_handlers.size; i++)
|
||||
self thread [[ level.tws_spawn_handlers[i] ]]();
|
||||
}
|
||||
|
||||
make_text_elem(player, x, y, align_x, scale, colour)
|
||||
{
|
||||
elem = NewClientHudElem(player);
|
||||
|
||||
elem.horzAlign = "left";
|
||||
elem.vertAlign = "top";
|
||||
elem.alignX = align_x;
|
||||
elem.alignY = "top";
|
||||
elem.x = x;
|
||||
elem.y = y;
|
||||
elem.foreground = 1;
|
||||
elem.fontScale = scale;
|
||||
elem.alpha = 1;
|
||||
elem.color = colour;
|
||||
|
||||
// black glow reads as an outline against bright geometry
|
||||
elem.glowColor = (0, 0, 0);
|
||||
elem.glowAlpha = 0.6;
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
make_shader_elem(player, x, y)
|
||||
{
|
||||
elem = NewClientHudElem(player);
|
||||
|
||||
elem.horzAlign = "left";
|
||||
elem.vertAlign = "top";
|
||||
elem.alignX = "left";
|
||||
elem.alignY = "top";
|
||||
elem.x = x;
|
||||
elem.y = y;
|
||||
elem.foreground = 1;
|
||||
elem.alpha = 1;
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
destroy_on_disconnect(elems)
|
||||
{
|
||||
self waittill("disconnect");
|
||||
|
||||
for (i = 0; i < elems.size; i++)
|
||||
{
|
||||
if (isDefined(elems[i]))
|
||||
elems[i] Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
int_dvar_or(name, fallback)
|
||||
{
|
||||
raw = GetDvar(name);
|
||||
if (raw == "")
|
||||
return fallback;
|
||||
return int(raw);
|
||||
}
|
||||
|
||||
format_mmss(elapsed_ms)
|
||||
{
|
||||
total_secs = int(elapsed_ms / 1000);
|
||||
|
||||
if (total_secs < 0)
|
||||
total_secs = 0;
|
||||
|
||||
mins = int(total_secs / 60);
|
||||
secs = total_secs - (mins * 60);
|
||||
|
||||
sec_str = "" + secs;
|
||||
if (secs < 10)
|
||||
sec_str = "0" + secs;
|
||||
|
||||
return "" + mins + ":" + sec_str;
|
||||
}
|
||||
Reference in New Issue
Block a user