/* T5-style .afk / .back listener with T6 control and weapon blocking. */ #include maps\mp\_utility; #include common_scripts\utility; // Plutonium probes both entry points; runtime setup belongs in init. main() { } init() { scripts\zm\tws_t6_common::ensure_config(); afk_init(); scripts\zm\tws_t6_common::register_spawn_handler(::afk_spawn); } afk_init() { level.afk_grace_seconds = 2; // invuln tail on .back level thread afk_chat_listener(); } afk_chat_listener() { for (;;) { level waittill("say", message, player); if (!isDefined(player) || !isDefined(message)) continue; cmd = toLower(message); if (cmd == ".afk") player thread afk_enter(); else if (cmd == ".back") player thread afk_exit(); } } afk_spawn() { self endon("disconnect"); self.tws_afk_generation = 0; self.hud_afk_on = false; self.tws_afk_protected = false; self.tws_afk_controls_locked = false; elem = scripts\zm\tws_t6_common::make_text_elem(self, level.hud_x + 42, level.hud_row_match, "left", level.hud_font_small, level.hud_c_afk); elem SetText("[AFK]"); elem.alpha = 0; self.hud_afk_elem = elem; elems = []; elems[0] = elem; self thread scripts\zm\tws_t6_common::destroy_on_disconnect(elems); for (;;) { if (self.tws_afk_protected && !scripts\zm\tws_t6_common::player_active(self)) self afk_release(); if (self.hud_afk_on) self afk_lock_controls(); else if (self.tws_afk_controls_locked) self afk_restore_controls(); wait 0.05; } } afk_enter() { if (!isDefined(self.hud_afk_on) || self.hud_afk_on) return; if (!scripts\zm\tws_t6_common::player_active(self)) return; // Do not take ownership of stock ignoreme (laststand, afterlife, etc.). if (is_true(self.ignoreme) && !self.tws_afk_protected) return; self.tws_afk_generation++; self.hud_afk_on = true; self.tws_afk_protected = true; self.ignoreme = true; self enableInvulnerability(); self afk_lock_controls(); self.hud_afk_elem.alpha = 1; self iPrintLnBold("AFK - type .back to return"); } afk_exit() { self endon("disconnect"); if (!isDefined(self.hud_afk_on) || !self.hud_afk_on) return; self.hud_afk_on = false; self afk_restore_controls(); self.hud_afk_elem.alpha = 0; self.tws_afk_generation++; generation = self.tws_afk_generation; self iPrintLnBold("Back in the fight"); wait level.afk_grace_seconds; if (generation == self.tws_afk_generation && self.tws_afk_protected) self afk_release(); } afk_release() { self.tws_afk_generation++; self.hud_afk_on = false; self.tws_afk_protected = false; self afk_restore_controls(); self.hud_afk_elem.alpha = 0; // Stock scripts own protection during laststand/intermission/death. if (scripts\zm\tws_t6_common::player_active(self)) { self.ignoreme = false; self disableInvulnerability(); } } afk_lock_controls() { // Stock gameplay can clear the freeze flag after AFK entry. Maintain it // while AFK and explicitly block guns and offhand weapons as well. self.tws_afk_controls_locked = true; self freezeControls(true); self disableWeapons(); self disableOffhandWeapons(); } afk_restore_controls() { if (!self.tws_afk_controls_locked) return; // Leave laststand/intermission controls to stock scripts. If the player // respawns, the watcher restores our controls once they are active again. if (!scripts\zm\tws_t6_common::player_active(self)) return; self.tws_afk_controls_locked = false; self freezeControls(false); self enableWeapons(); self enableOffhandWeapons(); }