// lfire-shared.cfg -- shared aliases, binds, and server/network settings
// for the L-Fire CTF crew.
//
// THIS FILE IS YOURS. Edit it, delete what you do not want, keep what you do.
// The comments explain why each setting is the way it is, so you can make an
// informed change rather than guessing.
//
// Lives in baseq2/ so every gamedir (ctf, action, opentdm, ...) picks it up
// through the Quake II search path. Exec'd from each gamedir's autoexec.cfg
// with the line:
//
//     exec lfire-shared.cfg
//
// NOTE: q2pro writes binds and "seta" cvars into q2config.cfg on exit, but it
// never writes aliases. So a bind pointing at an alias will survive into a
// gamedir config while the alias itself silently does not. Define aliases here.

alias +showscore "cmd help"
alias -showscore "cmd help"
bind TAB "+showscore"

// +rendija -- crouch plus the LOWEST physics tick the engine allows, for
// squeezing through tight geometry (q2ctf1 McKinley Revival: down the hatch,
// out to main center through the slot).
//
// This is a low-fps trick, not a high-fps one. At 10 Hz each movement command
// carries 100 ms, so pmove resolves the whole crouch-and-slide in one coarse
// step instead of a dozen fine ones.
//
// Why it must say 10 and not 0: on the 2014 client (r1504) "cl_maxfps 0" hit
//   phys_msec = fps_to_msec(Cvar_ClampInteger(cl_maxfps, 10, 120));
// and Cvar_ClampInteger raises anything below the minimum UP to it, so 0
// became 10 -- 100 ms. The current engine (client/main.c, fps_to_clamped_msec)
// special-cases 0 to mean MAX_PHYS_HZ = 125 instead, i.e. 8 ms: the exact
// opposite. MIN_PHYS_HZ is still 10, so ask for 10 by name and both builds
// behave identically.
//
// 10 and 100 are both exact (1000/10=100 ms, 1000/100=10 ms), so neither
// trips the cl_warn_on_fps_rounding notice. 60 is not -- it rounds to 62.
//
// With cl_async 1 this is the physics/packet tick, not render framerate --
// render is r_maxfps, already uncapped below.
alias +rendija "+movedown;cl_maxfps 10"
alias -rendija "-movedown;cl_maxfps 100"
bind SPACE "+rendija"

alias +zoom "fov 50; sensitivity 1.25"
alias -zoom "fov 120; sensitivity 2.5"
bind SHIFT "+zoom"
bind ALT "+zoom"
bind KP_INS "+zoom"

alias +crapple "use grapple;+attack"
alias -crapple "-attack;weapprev"

// --- server / downloads -----------------------------------------------
// L-Fire CTF ("Misteres Masteres L-Fire CTF"). Old IP 165.22.186.8 was a
// DigitalOcean droplet that got recycled -- its Q2 port is dead but port 80
// still answers, i.e. a stranger owns that address now. Do not fetch from it.
set adr0 "167.172.32.159:27910"
alias lfire "connect 167.172.32.159:27910"

// Empty = only ever use the download URL the server itself advertises.
// Never leave a hardcoded host here; a recycled IP becomes an untrusted
// source for maps/textures written into your game dirs.
set cl_http_default_url ""

// Client download permissions. These live here, not in baseq2/autoexec.cfg,
// because that file is shadowed whenever you launch into another gamedir
// (ctf, action, opentdm) -- the same shadowing that broke the aliases above.
// Setting them here means every gamedir actually gets them.
set allow_download          "1"
set allow_download_maps     "1"
set allow_download_sounds   "1"
set allow_download_models   "1"
set allow_download_textures "1"
set allow_download_pics     "1"
set allow_download_players  "1"
set cl_http_downloads       "1"

// networking
rate 25000            // bandwidth cap
cl_updaterate 30      // matches sv_fps 30 on the Miami servers
cl_maxfps 100         // input/packet rate to server (q2pro, with cl_async 1).
                      // 100 to match -rendija's release value, so a SPACE press
                      // returns you to the baseline instead of drifting it.
                      // Was 60, which is unreachable: 1000/60 = 16 ms = 62 fps,
                      // and the engine warns about the rounding every time.
cl_async 1            // decouple net/input rate from render framerate
cl_predict 1          // client-side movement prediction (essential)

// rendering latency
r_maxfps 0            // uncap render fps (cl_async makes this safe)
gl_swapinterval 0     // vsync OFF

// input
m_filter 0            // no mouse filtering

cl_particles 0

// --- quad tracker -----------------------------------------------------
// Client-side Quad timer, built into this x64 binary (src/client/quad.c).
// Does what DeathMonitor did: shows who has Quad and how long is left.
//
// It does NOT parse chat or console text -- there is nothing to parse.
// baseq2's Touch_Item() only sets STAT_PICKUP_* in the picking player's own
// playerstate, so item pickups are never announced. The tracker reads three
// things the server actually sends: the "items/damage.wav" sound (svc_sound),
// EF_QUAD on entity states, and the item_quad model on its pedestal.
//
// L-Fire runs dmflags 280340, which includes DF_INSTANT_ITEMS (16) -- items
// are used the instant they're touched, so that sound IS the pickup event.
// It also includes DF_QUAD_DROP (16384), so quads drop on death carrying the
// dead player's remaining time, not a fresh 30 s.
//
// $cl_quad reads:
//   QUAD up             believed sitting on the pedestal
//   QUAD 23 SomeGuy     23 s left, timing measured from an observed EF_QUAD
//   QUAD ~23 SomeGuy    same, but estimated -- see below
//   QUAD in 42          pedestal respawn estimate
//   (blank)             nothing known yet this level
//
// The tilde is not noise, it's the point: sound is PHS-gated and EF_QUAD is
// PVS-gated, so a pickup on the far side of the map is genuinely unknown to
// this client. It marks a guess as a guess instead of inventing certainty.
//
// x is negative, which right-aligns it (SCR_Draw_f: x < 0 sets UI_RIGHT and
// offsets by hud_width). Re-exec'ing this file just moves the existing draw
// object rather than stacking duplicates.
draw cl_quad -8 40 yellow

// Defaults are baseq2 values read out of src/game/g_items.c: Use_Quad grants
// 300 frames (30 s), item_quad has .quantity 60 so SetRespawn gives 60 s.
// If the server you play on uses different numbers, correct them here --
// watch a full quad cycle and compare against the countdown.
set cl_quad_time    30
set cl_quad_respawn 60

// Audible countdown over the last N seconds. 0 = silent.
// 10 = one tick a second for the final ten, so you hear it without having to
// watch the corner of the screen. items/damage2.wav is the game's own "quad
// running out" sample -- the one p_view.c plays at you when yours is ending.
set cl_quad_alert 10
set cl_quad_alert_sound "items/damage2.wav"

// Center-screen text, drawn at hud_height/3 -- one row below where tech and
// other centerprints land, so the two never overlap.
//   cl_quad_banner    seconds to hold "<name> took QUAD" after a pickup and
//                     "QUAD UP" when it returns. 0 = off.
//   cl_quad_countdown seconds of countdown before each event, yellow, turning
//                     red at 3 or less. 0 = off.
set cl_quad_banner 3
set cl_quad_countdown 10

// Which countdowns run, as bits. This is the one that decides *what* the
// 10 seconds are counting down to:
//   1  QUAD 7     the carrier's quad is about to wear off  (30 s after pickup)
//   2  QUAD IN 7  the pedestal quad is about to come back  (60 s after pickup)
//   3  both
// Set to 2: only the respawn countdown, so the center text means "be at the
// spawn" and nothing else. Change to 3 if you want both.
set cl_quad_events 2

// Set to 1 to log every quad sound hit and every EF_QUAD edge to the console.
// Worth doing for one round on a server you do not know: it settles whether
// its game module sets EF_QUAD at all, which decides whether carrier timing
// is measured or only estimated.
set cl_quad_debug 0

// `quad` in the console prints resolved sound/model indices and live state --
// first thing to check if the display stays blank or the carrier reads none.
// eof
