group2 0.1.0
CSE 125 Group 2
Loading...
Searching...
No Matches
systems Namespace Reference

Client-only input sampling system — split into two halves so mouse look can run every iterate() (smooth camera at any FPS) while movement keys run once per physics tick group (server-consistent). More...

Namespaces

namespace  aimassist
namespace  gamepad

Classes

struct  GamepadAimAssistConfig
 Tunable parameters for gamepad aim assist. More...
struct  GamepadAimAssistState
 Per-frame state required to compute the rotational pull as a delta between frames. More...
struct  JoystickAxis
 Gamepad axis mapping configuration for look and move axes, used to support stick swapping in user settings. More...
struct  ReconciliationStats
struct  PendingWeaponDrop
 A weapon drop queued during view iteration, spawned afterward. More...
class  RewindHitboxesGuard
 RAII handle that restores hitbox capsules on scope exit after a rewindHitboxes call swapped them for historical samples. More...
struct  SpawnResolution
 A resolved spawn: safe center position plus the point's facing yaw. More...
struct  BeamLockResult
 Result of an auto-lock cone scan for a Tesla-style beam. More...

Functions

void runGamepadAimAssist (Registry &registry, SDL_Gamepad *gamepad, const GamepadAimAssistConfig &cfg, GamepadAimAssistState &state, float pitchSensitivity, float yawSensitivity, float lookDeadzone, float moveDeadzone, float dt, bool swapSticks=false)
 Apply gamepad aim assist (slowdown + movement-tracking pull) to the local player's InputSnapshot.
JoystickAxis getLookJoystickAxes (bool swapSticks)
 Return the SDL axes used for camera look, honoring the stick-swap setting.
JoystickAxis getMoveJoystickAxes (bool swapSticks)
 Return the SDL axes used for movement, honoring the stick-swap setting.
bool gamepadConnected (SDL_Gamepad *gamepad)
 True when a gamepad handle is non-null and still connected.
bool consumePendingGrenadeThrow ()
 Consume and clear the queued grenade throw request.
bool consumePendingGrenadeCycleNext ()
 Consume and clear the queued "cycle to next grenade" request.
bool consumePendingGrenadeCyclePrev ()
 Consume and clear the queued "cycle to previous grenade" request.
bool consumePendingGamepadWeaponSwap ()
 Consume and clear the latched tap-Y gamepad weapon swap request.
int consumePendingEmote ()
 Consume and clear the latched emote-play request (-1 = none).
void emoteWheelApplyPointing (float dx, float dy, bool accumulate)
 Resolve emoteWheelSelection from a pointing input.
void runEmoteWheelKey (const InputBindings &bindings)
 Track the Emote binding (keyboard/mouse) to open/close the wheel.
void runMouseLook (Registry &registry, float mouseSensitivity, bool gravityFlipped=false)
 Sample mouse delta and accumulate into yaw / pitch.
void runMovementKeys (Registry &registry, const InputBindings &bindings, bool gravityFlipped=false)
 Sample keyboard state into the movement flags.
void runDeadInput (Registry &registry, const InputBindings &bindings)
 Sample skip-respawn input while the local player is dead.
void runWeaponKeys (Registry &registry, const InputBindings &bindings)
 Sample keyboard state into the weapon flags.
void runInputSample (Registry &registry, const InputBindings &bindings, float mouseSensitivity=user_settings::kDefaultMouseSensitivity)
 Legacy combined sampler — calls both runMouseLook and runMovementKeys.
void runGamepadLook (Registry &registry, SDL_Gamepad *gamepad, float pitchSensitivity, float yawSensitivity, float deadzone, float dt, bool gravityFlipped=false, bool swapSticks=false)
 Sample the right stick into yaw / pitch.
void runGamepadEmoteWheel (SDL_Gamepad *gamepad, const InputBindings &bindings, bool swapSticks=false)
 Track the Emote binding (controller) to open/close the wheel and pick a sector from the right stick.
void runGamepadMovement (Registry &registry, SDL_Gamepad *gamepad, const InputBindings &bindings, float deadzone, bool gravityFlipped=false, bool swapSticks=false)
 Sample gamepad buttons / left stick into the movement flags.
void runGamepadWeapon (Registry &registry, SDL_Gamepad *gamepad, const InputBindings &bindings)
 Sample gamepad buttons / right trigger into the weapon flags.
void runGamepadDeadInput (Registry &registry, SDL_Gamepad *gamepad, const InputBindings &bindings)
 Sample controller skip-respawn input while the local player is dead.
void runInputSend (Registry &registry, Client &conn)
 Send the local player's current InputSnapshot over the network.
void runPrediction (Registry &registry, float dt, const physics::WorldGeometry &world)
 Run one tick of client-side prediction for the local player.
ReconciliationStats runReconciliation (Registry &registry, const InputRingBuffer &ring, uint32_t ackedTick, uint32_t currentTick, float dt, const physics::WorldGeometry &world)
 Replay stored inputs from ackedTick + 1 through currentTick on the local player, restoring its predicted state after a snapshot apply rewrote it to the server-authoritative value.
void tickCooldown (float &cooldown, float dt)
void useAbility (entt::entity player, AbilityType type, Registry &registry, AbilityRegistry &abilityRegistry)
bool queueAbilityChoice (AbilityState &state)
void grantAbilityLevel (AbilityState &state)
void grantAbilityProgress (AbilityState &state, float amount)
void handleAbilitySelection (InputSnapshot &snap, AbilityState &state)
void runAbility (Registry &registry, AbilityRegistry &abilityRegistry, float dt)
static void depenetratePlanes (glm::vec3 &pos, glm::vec3 &vel, const glm::vec3 &halfExtents, std::span< const physics::Plane > planes)
 Push the entity out of any infinite planes it currently overlaps.
static void depenetrateBox (glm::vec3 &pos, glm::vec3 &vel, const glm::vec3 &halfExtents, const physics::WorldAABB &box)
 Push the entity out of a static AABB it currently overlaps.
static void depenetrateBrush (glm::vec3 &pos, glm::vec3 &vel, const glm::vec3 &halfExtents, const physics::WorldBrush &brush)
 Push the entity out of a convex brush it currently overlaps.
static void depenetrateCylinder (glm::vec3 &pos, glm::vec3 &vel, const glm::vec3 &halfExtents, const physics::WorldCylinder &cyl)
 Push the entity out of a vertical cylinder it currently overlaps.
static void depenetrateSphere (glm::vec3 &pos, glm::vec3 &vel, const glm::vec3 &halfExtents, const physics::WorldSphere &sph)
 Push the entity out of a world sphere it currently overlaps.
static void depenetrateTriMesh (glm::vec3 &pos, glm::vec3 &vel, const glm::vec3 &halfExtents, const physics::WorldTriMesh &mesh)
 Push the entity out of a triangle mesh it currently overlaps.
static bool overlapsAabb (const physics::WorldAABB &a, const physics::WorldAABB &b)
static void depenetrate (glm::vec3 &pos, glm::vec3 &vel, const glm::vec3 &halfExtents, const physics::WorldGeometry &world)
 Run all depenetration passes for legacy AABB bodies.
void runCollision (Registry &registry, float dt, const physics::WorldGeometry &world)
 Run one tick of swept-AABB collision for all physics entities.
void spawnDroppedWeapon (Registry &registry, glm::vec3 pos, glm::vec3 initialVel, const GunInstance &gun, float pickupDelay)
 Spawn an in-world dropped-weapon pickup carrying a gun's ammo.
bool tryPickup (Registry &registry, Position dropPos, CollisionShape dropShape, const DroppedWeapon &dw, std::vector< PendingWeaponDrop > &pendingDrops)
 Try to grant the dropped weapon to a player.
void runDroppedWeapons (Registry &registry, float dt)
 Tick dropped weapons: handle pickup (overlap-refill or look+F replace) and despawn timer.
void runDynamics (Registry &registry, float dt, const physics::WorldGeometry &world, physics::ContactCache &cache, const physics::SolverConfig &solverCfg, const physics::SleepConfig &sleepCfg)
 One physics tick for rigid-body dynamic entities.
void queueExplosion (Registry &registry, glm::vec3 position, float radius, float maxDamage, entt::entity owner, float falloffExponent=1.0f, float selfDamageMultiplier=1.0f, float maxKnockback=0.0f, float knockbackFalloffExponent=1.0f, entt::entity directKillTarget=entt::null, WeaponType weaponType=WeaponType::Rocket)
 Create an explosion entity at the given position.
void runExplosion (Registry &registry, std::vector< NetParticleEvent > &outParticles, std::vector< NetKillEvent > &killEvents)
 Process all pending explosions: apply radial damage and emit particle events.
void spawnFireField (Registry &registry, glm::vec3 position, float radius, float duration, float dps, entt::entity owner)
 Spawn a FireField at position that lasts duration seconds and deals dps damage to players inside radius.
void runFireField (Registry &registry, float dt, std::vector< NetKillEvent > &killEvents)
 Tick all FireField entities: decrement remaining, apply DoT damage at fixed sub-intervals (4 Hz), and destroy expired fields.
void checkForPlayers (Registry &registry, Position spawnerPos, CollisionShape spawnerShape, HealthPackSpawner &spawner)
 Check if any player overlaps the spawner and transfer the weapon on pickup.
void runHealthPackSpawners (Registry &registry, float dt)
 Tick spawners: check player overlap for pickup, manage cooldowns.
void updateHitboxes (Registry &registry, const HitboxRig &hitboxRig, float rigScale, float rigMeshMinY)
 Update world-space hitbox capsules for all entities that have JointMatrices.
void runJumpPads (Registry &registry, float dt)
 Tick jump pads: for each pad, any player whose AABB overlaps the pad's trigger volume on the rising edge has the pad's velocity applied as an impulse.
void runKillzones (Registry &registry, std::vector< NetKillEvent > &killEvents)
 Tick killzones: for each killzone trigger, any player whose AABB overlaps it takes lethal damage.
physics::KccFrameResult runKinematicCharacterController (glm::vec3 &pos, glm::vec3 &vel, const CollisionShape &shape, PlayerVisState &state, float dt, const physics::WorldGeometry &world, entt::entity entity, bool jumpedThisTick, PlayerSimState *simState=nullptr)
 Resolve one fixed-tick capsule character-controller step.
RewindHitboxesGuard rewindHitboxes (Registry &registry, entt::entity shooter, const glm::vec3 *rayOrigin=nullptr, const glm::vec3 *rayDirection=nullptr, float rayMaxDistance=0.0f, float bulletRadius=0.0f)
 Rewind every other player's hitbox capsules to where they were on shooter's screen at fire time.
std::optional< ClientIdhandleWinCondition (Registry &registry, int killsToWin)
 Checks if any player has met win condition and updates their PlayerMatchStats accordingly.
void resetStats (Registry &registry)
 Resets all players' match scores to initial values.
float currentWishSpeed (const PlayerVisState &vis)
 Determine the current ground wish speed based on movement mode and stance.
void reconcileMovementAfterKcc (glm::vec3 &pos, glm::vec3 &vel, const CollisionShape &shape, PlayerVisState &vis, PlayerSimState &sim, const InputSnapshot &input, const physics::WorldGeometry &world, const physics::KccFrameResult &kcc, float dt)
 Consume collision-owned KCC feedback after position integration.
void runMovement (Registry &registry, float dt, const physics::WorldGeometry &world)
 Apply one tick of player movement physics to all eligible entities.
bool overlapsAABB (glm::vec3 aPos, glm::vec3 aHalf, glm::vec3 bPos, glm::vec3 bHalf)
 Test whether two axis-aligned bounding boxes overlap.
glm::vec3 viewForward (float yaw, float pitch)
 Forward direction implied by a player's yaw + pitch.
bool isPlayerLookingAtPickup (glm::vec3 eye, glm::vec3 viewFwd, glm::vec3 pickupPos)
 True if the eye is within range of pickupPos and viewFwd points within the look cone.
void applyHeal (float amount, Health &playerHealth)
float standingHalfHeight (const CollisionShape &shape)
physics::CapsuleShape spawnCapsuleFor (const CollisionShape &shape)
glm::vec3 resolveRespawnPosition (Registry &registry, entt::entity player, glm::vec3 feetPosition)
SpawnResolution chooseRespawnPoint (Registry &registry, entt::entity respawning)
 Choose a respawn point with cooldown-aware, enemy-avoiding selection.
SpawnResolution chooseAndResolveSpawnPosition (Registry &registry, entt::entity player)
 Pick a respawn point and resolve it to a safe spawn center.
void handleRespawn (entt::entity &player, Registry &registry)
 Reset a dead player to a fresh spawn state.
void handleDeath (entt::entity &player, Health &playerHealth, entt::entity &killer, Registry &registry, std::vector< NetKillEvent > &killEvents, BodyRegion hitRegion)
 Transition a player to the dead state if health has reached zero.
void updateAbilityLevel (Registry &registry, entt::entity player, float dmg)
float absorbDamage (float &pool, float damage)
float absorbDamageScaled (float &pool, float damage, float effectiveness)
 Absorb damage through a shield pool with reduced effectiveness.
void applyBulletSlow (entt::entity player, Registry &registry)
 Refresh the bullet-hit movement slow on a player.
float applyDamage (float damage, entt::entity player, entt::entity &killer, Registry &registry, std::vector< NetKillEvent > &killEvents, BodyRegion hitRegion=BodyRegion::UpperTorso, float shieldMultiplier=1.0f)
 Apply damage to a player, splitting across armor then health.
void handleHealing (Health &playerHealth, float dt)
 Tick passive health regeneration after the heal cooldown expires.
void runPlayerStatus (Registry &registry, float dt)
 Run one tick of player status: respawn timers and passive healing.
void runSpawnPointCooldowns (Registry &registry, float dt)
 Tick spawn point cooldowns.
bool hasPowerup (const PowerupState &state, PowerupType type)
void addOrRefreshPowerup (PowerupState &state, PowerupType type, float duration)
void removePowerup (PowerupState &state, PowerupType type)
void applyPowerupSpawnerConfig (Registry &registry, const MatchConfig &matchConfig)
 Clamp pending powerup cooldowns to the current host-managed timing settings.
void resetPowerupSpawnersForMatch (Registry &registry, const MatchConfig &matchConfig)
 Hide all powerups and restart their initial match-start spawn delay.
void checkForPlayers (Registry &registry, Position spawnerPos, CollisionShape spawnerShape, PowerupSpawner &spawner, const MatchConfig &matchConfig, std::vector< NetParticleEvent > &outEvents)
 Check if any player overlaps the spawner and transfer the powerup on collision.
void runPowerupSpawners (Registry &registry, float dt, const MatchConfig &matchConfig, std::vector< NetParticleEvent > &outEvents)
 Tick Powerup spawners: check player overlap for pickup, manage cooldowns.
void runPowerups (Registry &registry, float dt)
 Run one tick of powerup logic for all players.
entt::entity spawnRagdoll (Registry &registry, entt::entity character)
 Build a 15-body humanoid ragdoll for the dead character.
void destroyRagdoll (Registry &registry, entt::entity character)
 Destroy the ragdoll bodies and joints owned by a character.
void runRagdolls (Registry &registry, float dt)
 Per-tick ragdoll bookkeeping: advance age, optionally tick the cleanup timer for old corpses.
void update (Registry &registry, float dt)
 Placeholder system — replace with real logic.
void runTriggers (Registry &registry, bool isPredictedClient=false)
 Test every trigger-volume entity for overlap with non-trigger entities and emit Enter / Stay / Exit events.
void checkForPlayers (Registry &registry, Position spawnerPos, CollisionShape spawnerShape, WeaponSpawner &spawner, std::vector< PendingWeaponDrop > &pendingDrops)
 Check if any player overlaps the spawner and transfer the weapon on pickup.
void runWeaponSpawners (Registry &registry, float dt)
 Tick weapon spawners: check player overlap for pickup, manage cooldowns.
bool combatLogEnabled ()
void handleSwitch (const InputSnapshot &input, WeaponState &weapon)
 Apply weapon slot switch from player input.
void handleCooldown (WeaponState &weapon, float dt)
 Tick fire cooldowns for all weapon slots.
void handleGrenadeCooldown (GrenadeState &grenades, float dt)
void handleReload (GunInstance &gun)
 Reload the gun's magazine from reserve ammo.
bool handleAmmo (GunInstance &gun)
 Consume one round from the magazine; auto-reload if empty.
glm::vec3 muzzleOrigin (glm::vec3 eye, glm::vec3 direction, bool gravityFlipped=false)
 Offset the muzzle origin from the eye position for tracer visuals.
void logShot (Registry &registry, entt::entity shooter, std::uint32_t shotInputTick, const glm::vec3 &origin, const glm::vec3 &direction, const physics::HitboxHit &hit)
void captureShotDebug (Registry &registry, entt::entity shooter, std::uint32_t shotInputTick, const glm::vec3 &origin, const glm::vec3 &direction, float range, const physics::HitboxHit &hit, std::vector< net::shotdebug::ShotDebugCapture > *out)
static void spawnGrenade (Registry &registry, entt::entity shooter, WeaponType type, glm::vec3 muzzle, glm::vec3 eyeDir, glm::vec3 eyeRight, glm::vec3 throwerVel)
 Spawn a grenade projectile from the player's eye position.
int nextGrenadeWithAmmo (const GrenadeState &grenades, int start, int dir)
 Find the next grenade type index (wrapping in direction dir, +1 or -1) that still has ammo, starting the search one step away from start.
void handleGrenadeInput (Registry &registry, entt::entity shooter, InputSnapshot &input, const Position &pos, const CollisionShape &shape, GrenadeState &grenades, bool gravityFlipped)
void handleScope (Registry &registry, entt::entity shooter, const InputSnapshot &input, WeaponState &weapon, float dt)
BeamLockResult findBeamLockTarget (Registry &registry, entt::entity shooter, glm::vec3 eye, glm::vec3 viewDir, const WeaponConfig &config)
 Pick the enemy closest to the crosshair inside the lock-on cone.
void handleFire (Registry &registry, entt::entity shooter, const InputSnapshot &input, const Position &pos, const CollisionShape &shape, WeaponState &weapon, bool gravityFlipped, bool grenadeThrowActive, float dt, std::vector< NetParticleEvent > &outParticles, std::vector< NetKillEvent > &killEvents, std::vector< net::shotdebug::ShotDebugCapture > *outShotDebug)
 Process fire input: hitscan raycasts, beam weapons, charge shots, and projectiles.
void runWeapon (Registry &registry, float dt, std::vector< NetParticleEvent > &outParticles, std::vector< NetKillEvent > &killEvents, std::vector< net::shotdebug::ShotDebugCapture > *outShotDebug=nullptr)
 Run one tick of weapon logic for all armed entities.
void pushHitboxHistory (Registry &registry, uint32_t serverTick)
 Capture this tick's hitbox capsules into each entity's HitboxHistory ring.
Event runInputReceive (const void *data)
 Deserialise a raw InputSnapshot packet into a gameplay Event.

Variables

bool prevKillSelfKey = false
 Tracks previous-frame key state for edge detection.
bool prevGrenadeCycleKey = false
 Previous-frame CycleGrenade (H) / ThrowGrenade (G) key state for edge detection (keyboard/mouse).
bool prevGrenadeThrowKey = false
bool prevGamepadGrenadeCycleKey = false
 Gamepad equivalents: CycleGrenade (D-pad Left) / ThrowGrenade (B).
bool prevGamepadGrenadeThrowKey = false
bool pendingGrenadeThrow = false
 Latched throw request, consumed once per frame by the game loop.
bool pendingGrenadeCycleNext = false
 Latched cycle next/prev requests, consumed once per frame by the game loop.
bool pendingGrenadeCyclePrev = false
bool prevAbilitySelectLeft = false
 Tracks previous-frame Alt+LMB state for ability choice edge detection.
bool prevAbilitySelectRight = false
 Tracks previous-frame Alt+RMB state for ability choice edge detection.
bool prevGamepadAbilitySelectLeft = false
 Tracks previous-frame gamepad left ability-select chord for edge detection.
bool prevGamepadAbilitySelectRight = false
 Tracks previous-frame gamepad right ability-select chord for edge detection.
bool prevGamepadPickupKey = false
 Gamepad Y (Pickup binding) tap-vs-hold state: tap swaps weapon, hold picks up.
Uint64 gamepadPickupDownMs = 0
 SDL_GetTicks at the Y press, for hold-duration timing.
bool gamepadPickupHoldFired = false
 Set once the press crossed the hold threshold (suppresses tap-swap).
bool pendingGamepadWeaponSwap = false
 Latched tap-Y weapon swap, consumed once per frame by the game loop.
float gamepadLookAccel = 0.0f
 COD-style look acceleration progress in [0, 1]; ramps while the look stick is held near full deflection and resets when it eases off.
bool emoteWheelOpen = false
 True while the emote wheel is open (Emote binding held on any device).
int emoteWheelSelection = -1
 Currently highlighted emote sector while the wheel is open, or -1 (none).
float emoteWheelDirX = 0.0f
 Accumulated pointing direction used to resolve the highlighted sector.
float emoteWheelDirY = 0.0f
int pendingEmoteRequest = -1
 Latched emote to play on wheel release; consumed once by the game loop.
bool prevEmoteKey = false
 Previous-frame Emote-binding state for open/close edge detection.
bool prevGamepadEmoteKey = false
constexpr float dmgThreshold = 1000.0f
constexpr int maxLevel = 2
static constexpr float k_pushback = 0.03125f
constexpr float k_droppedWeaponLifetime = 30.0f
 Default lifetime (seconds) for a dropped weapon before it despawns.
constexpr float k_swapDropPickupDelay = 0.8f
 Pickup-immunity applied to a weapon dropped during a swap, so the player can't instantly re-grab the gun they just replaced.
constexpr float healthPackCooldownTime = 15.0f
constexpr float k_pickupRange = 140.0f
 Maximum distance (units) at which a player can press F to pick up.
const glm::vec3 k_weaponPickupHalfExtents {32.0f, 32.0f, 32.0f}
 Shared pickup collision half-extents for weapon spawners and dropped weapons.
constexpr float k_pickupMaxAngleDeg = 12.0f
 Half-angle (degrees) of the look cone for press-F pickup.
const float k_pickupMinDot = std::cos(glm::radians(k_pickupMaxAngleDeg))
 Pre-computed cosine of the look cone half-angle.
constexpr float k_spawnPointCooldown = 5.0f
 Cooldown duration set on a spawn point after a player spawns there.
constexpr float k_spawnPushback = 0.03125f
const float armorMax = 100.0f
 Maximum armor value.
const float healthMax = 100.0f
 Maximum health value.
const float overShieldMax = 200.0f
const float healCooldown = 5.0f
 Seconds after last damage before passive healing starts.
const float healingRate = 20.0f
 Passive healing amount per second.
constexpr float weaponCooldownTime = 10.0f

Detailed Description

Client-only input sampling system — split into two halves so mouse look can run every iterate() (smooth camera at any FPS) while movement keys run once per physics tick group (server-consistent).

Input receive system functions.

Weapon state update system.

Weapon spawner update system.

ECS systems namespace.

Powerup state update system.

Powerup spawner update system.

Player status update system.

Shared movement system — compiled identically on client and server.

Health pack spawner update system.

Shared collision system — compiled identically on client and server.

Client-only system that serialises and sends input to the server.

Any divergence between client and server builds is a bug (breaks prediction).

Any divergence between client and server builds is a bug (breaks prediction).

Implements the Titanfall-inspired movement state machine: OnFoot → Sliding → WallRunning with sprint, double jump, coyote time, jump lurch, air strafing, and speed cap.

Note
Position integration is NOT done here — CollisionSystem owns that via swept AABB.

Each free function (or callable) represents one system. A system receives the shared Registry and any per-frame state it needs, then queries and mutates components.

Concrete system implementations live in individual .hpp/.cpp pairs under this directory.

Function Documentation

◆ absorbDamage()

float systems::absorbDamage ( float & pool,
float damage )
inline
Here is the caller graph for this function:

◆ absorbDamageScaled()

float systems::absorbDamageScaled ( float & pool,
float damage,
float effectiveness )
inline

Absorb damage through a shield pool with reduced effectiveness.

effectiveness scales how fast the pool drains: removing one point of the pool consumes 1 / effectiveness points of the incoming damage budget. With effectiveness == 1 this is identical to absorbDamage; with 0.2 the pool is 5× as tanky (a 100-shield needs 500 damage to break). Returns the leftover damage budget after the pool is exhausted (always full-value, to be applied to the next, less-resistant layer).

Here is the call graph for this function:
Here is the caller graph for this function:

◆ addOrRefreshPowerup()

void systems::addOrRefreshPowerup ( PowerupState & state,
PowerupType type,
float duration )
Here is the caller graph for this function:

◆ applyBulletSlow()

void systems::applyBulletSlow ( entt::entity player,
Registry & registry )

Refresh the bullet-hit movement slow on a player.

Sets the player's PlayerSimState::bulletSlowTimer to tms::k_bulletHitSlowDuration, so the next ground-movement tick clamps the wish speed to k_bulletHitSlowFactor of normal. Hitscan call sites in WeaponSystem invoke this alongside applyDamage so getting shot punishes the target's mobility; explosion / fire / killzone damage paths skip it. No-op if player lacks PlayerSimState (e.g. a hit dummy).

Here is the caller graph for this function:

◆ applyDamage()

float systems::applyDamage ( float damage,
entt::entity player,
entt::entity & killer,
Registry & registry,
std::vector< NetKillEvent > & killEvents,
BodyRegion hitRegion = BodyRegion::UpperTorso,
float shieldMultiplier = 1.0f )

Apply damage to a player, splitting across armor then health.

Resets the heal cooldown timer. If health reaches zero, triggers death handling (respawn timer, kill event, stats update).

Parameters
damageDamage amount being applied.
playerPlayer entity who took damage.
killerEntity who dealt the final blow.
registryThe ECS registry.
killEventsAccumulates kill events for network broadcast.
hitRegionBody region that was hit (for kill feed / headshot tracking).
shieldMultiplierEffectiveness against shield layers (overShield + armor). 1.0 = full; <1.0 makes shields drain slower (energy-vs-energy weapons). Damage spilling into raw health is always applied at full.
Returns
Final damage value after status modifiers such as powerups. Returns 0 if damage was ignored.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ applyHeal()

void systems::applyHeal ( float amount,
Health & playerHealth )

Apply a healing amount, filling health first then armor.

Apply a healing amount, filling health first then armor.

Parameters
amountHealing amount being applied.
playerHealthEntity's health component (modified in place).
amountHealing amount being applied.
playerHealthEntity's health component (modified in place).
Here is the caller graph for this function:

◆ applyPowerupSpawnerConfig()

void systems::applyPowerupSpawnerConfig ( Registry & registry,
const MatchConfig & matchConfig )

Clamp pending powerup cooldowns to the current host-managed timing settings.

Here is the caller graph for this function:

◆ captureShotDebug()

void systems::captureShotDebug ( Registry & registry,
entt::entity shooter,
std::uint32_t shotInputTick,
const glm::vec3 & origin,
const glm::vec3 & direction,
float range,
const physics::HitboxHit & hit,
std::vector< net::shotdebug::ShotDebugCapture > * out )
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ checkForPlayers() [1/3]

void systems::checkForPlayers ( Registry & registry,
Position spawnerPos,
CollisionShape spawnerShape,
HealthPackSpawner & spawner )
inline

Check if any player overlaps the spawner and transfer the weapon on pickup.

Parameters
registryThe ECS registry.
spawnerPosPosition of the spawner entity.
spawnerShapeCollision shape of the spawner.
spawnerSpawner component
Here is the call graph for this function:
Here is the caller graph for this function:

◆ checkForPlayers() [2/3]

void systems::checkForPlayers ( Registry & registry,
Position spawnerPos,
CollisionShape spawnerShape,
PowerupSpawner & spawner,
const MatchConfig & matchConfig,
std::vector< NetParticleEvent > & outEvents )
inline

Check if any player overlaps the spawner and transfer the powerup on collision.

Parameters
registryThe ECS registry.
spawnerPosPosition of the spawner entity.
spawnerShapeCollision shape of the spawner.
spawnerSpawner component.
Here is the call graph for this function:

◆ checkForPlayers() [3/3]

void systems::checkForPlayers ( Registry & registry,
Position spawnerPos,
CollisionShape spawnerShape,
WeaponSpawner & spawner,
std::vector< PendingWeaponDrop > & pendingDrops )
inline

Check if any player overlaps the spawner and transfer the weapon on pickup.

Parameters
registryThe ECS registry.
spawnerPosPosition of the spawner entity.
spawnerShapeCollision shape of the spawner.
spawnerSpawner component (weapon type, availability, cooldown).
Here is the call graph for this function:

◆ chooseAndResolveSpawnPosition()

SpawnResolution systems::chooseAndResolveSpawnPosition ( Registry & registry,
entt::entity player )

Pick a respawn point and resolve it to a safe spawn center.

Uses the same cooldown-aware spawn selection and depenetration logic as on-death respawn, so initial join spawns share the live respawn behavior. Spawn points are biased away from living enemies, and the chosen point's authored facing yaw is returned so the caller can orient the player. The player's CollisionShape should already be attached so the capsule recovery sweep matches the player's actual shape.

Parameters
registryThe ECS registry.
playerThe player entity whose spawn position to resolve.
Returns
The resolved spawn center and facing yaw.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ chooseRespawnPoint()

SpawnResolution systems::chooseRespawnPoint ( Registry & registry,
entt::entity respawning )
inline

Choose a respawn point with cooldown-aware, enemy-avoiding selection.

Prefers available (cooldown = 0) spawn points, biased toward those farthest from living enemies (random tiebreak among the safest few so spawns aren't fully deterministic). If all points are on cooldown, picks the one closest to being ready. Sets a cooldown on the chosen point and returns its feet position plus authored facing yaw.

Here is the caller graph for this function:

◆ combatLogEnabled()

bool systems::combatLogEnabled ( )
inline
Here is the caller graph for this function:

◆ consumePendingEmote()

int systems::consumePendingEmote ( )
inline

Consume and clear the latched emote-play request (-1 = none).

Here is the caller graph for this function:

◆ consumePendingGamepadWeaponSwap()

bool systems::consumePendingGamepadWeaponSwap ( )
inline

Consume and clear the latched tap-Y gamepad weapon swap request.

Here is the caller graph for this function:

◆ consumePendingGrenadeCycleNext()

bool systems::consumePendingGrenadeCycleNext ( )
inline

Consume and clear the queued "cycle to next grenade" request.

Here is the caller graph for this function:

◆ consumePendingGrenadeCyclePrev()

bool systems::consumePendingGrenadeCyclePrev ( )
inline

Consume and clear the queued "cycle to previous grenade" request.

Here is the caller graph for this function:

◆ consumePendingGrenadeThrow()

bool systems::consumePendingGrenadeThrow ( )
inline

Consume and clear the queued grenade throw request.

Here is the caller graph for this function:

◆ currentWishSpeed()

float systems::currentWishSpeed ( const PlayerVisState & vis)

Determine the current ground wish speed based on movement mode and stance.

Returns the speed the player is accelerating toward on the ground this tick: tms::k_adsSpeed (if ADS-ing a precision weapon), else tms::k_crouchSpeed / k_sprintSpeed / k_walkSpeed, or 0 during a slide. For air movement use physics::k_airMaxSpeed directly.

Parameters
visReplicated player vis state (for moveMode + crouching + sprinting + ads).
Returns
Target ground wish speed (u/s).
Here is the caller graph for this function:

◆ depenetrate()

void systems::depenetrate ( glm::vec3 & pos,
glm::vec3 & vel,
const glm::vec3 & halfExtents,
const physics::WorldGeometry & world )
static

Run all depenetration passes for legacy AABB bodies.

Parameters
posEntity position (modified in place).
velEntity velocity (modified in place).
halfExtentsAABB half-extents of the entity.
worldWorld collision geometry.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ depenetrateBox()

void systems::depenetrateBox ( glm::vec3 & pos,
glm::vec3 & vel,
const glm::vec3 & halfExtents,
const physics::WorldAABB & box )
static

Push the entity out of a static AABB it currently overlaps.

Parameters
posEntity position (modified in place).
velEntity velocity (modified in place).
halfExtentsAABB half-extents of the entity.
boxStatic axis-aligned bounding box to test against.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ depenetrateBrush()

void systems::depenetrateBrush ( glm::vec3 & pos,
glm::vec3 & vel,
const glm::vec3 & halfExtents,
const physics::WorldBrush & brush )
static

Push the entity out of a convex brush it currently overlaps.

Only fires if the entity is inside ALL planes simultaneously.

Parameters
posEntity position (modified in place).
velEntity velocity (modified in place).
halfExtentsAABB half-extents of the entity.
brushConvex brush to test against.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ depenetrateCylinder()

void systems::depenetrateCylinder ( glm::vec3 & pos,
glm::vec3 & vel,
const glm::vec3 & halfExtents,
const physics::WorldCylinder & cyl )
static

Push the entity out of a vertical cylinder it currently overlaps.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ depenetratePlanes()

void systems::depenetratePlanes ( glm::vec3 & pos,
glm::vec3 & vel,
const glm::vec3 & halfExtents,
std::span< const physics::Plane > planes )
static

Push the entity out of any infinite planes it currently overlaps.

Parameters
posEntity position (modified in place).
velEntity velocity (modified in place).
halfExtentsAABB half-extents of the entity.
planesInfinite planes to test against.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ depenetrateSphere()

void systems::depenetrateSphere ( glm::vec3 & pos,
glm::vec3 & vel,
const glm::vec3 & halfExtents,
const physics::WorldSphere & sph )
static

Push the entity out of a world sphere it currently overlaps.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ depenetrateTriMesh()

void systems::depenetrateTriMesh ( glm::vec3 & pos,
glm::vec3 & vel,
const glm::vec3 & halfExtents,
const physics::WorldTriMesh & mesh )
static

Push the entity out of a triangle mesh it currently overlaps.

Delegates to physics::depenetrateAABBvsTriMesh, the legacy projectile AABB safety-net path. Player movement uses capsule depenetration in physics::depenetrateCapsuleVsWorld; this remains for small projectile bodies that still use AABB sweeps.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroyRagdoll()

void systems::destroyRagdoll ( Registry & registry,
entt::entity character )

Destroy the ragdoll bodies and joints owned by a character.

Called when the player respawns or disconnects. This removes the transient physics entities immediately instead of letting every death leave orphan registry entries behind.

Here is the caller graph for this function:

◆ emoteWheelApplyPointing()

void systems::emoteWheelApplyPointing ( float dx,
float dy,
bool accumulate )
inline

Resolve emoteWheelSelection from a pointing input.

Parameters
dx,dyPointing delta in screen convention (dx right, dy down).
accumulateTrue for mouse deltas (integrated into a virtual stick), false for an absolute stick direction.

The wheel lays emote 0 at the top and proceeds clockwise. A small deadzone keeps the selection empty until the player points clearly in a direction.

Here is the caller graph for this function:

◆ findBeamLockTarget()

BeamLockResult systems::findBeamLockTarget ( Registry & registry,
entt::entity shooter,
glm::vec3 eye,
glm::vec3 viewDir,
const WeaponConfig & config )
inline

Pick the enemy closest to the crosshair inside the lock-on cone.

Scans every other player's hitbox capsules. A candidate qualifies when its centre of mass is within maxRange, inside the cone of half-angle coneHalfAngleDeg around viewDir, and has clear line-of-sight from eye (no world geometry between the shooter and the target). Among qualifying candidates the one with the smallest angular deviation from the crosshair wins. Must be called while any lag-compensation rewind guard is in scope so the capsules reflect the attacker's screen-time positions.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ gamepadConnected()

bool systems::gamepadConnected ( SDL_Gamepad * gamepad)
inline

True when a gamepad handle is non-null and still connected.

Here is the caller graph for this function:

◆ getLookJoystickAxes()

JoystickAxis systems::getLookJoystickAxes ( bool swapSticks)
inline

Return the SDL axes used for camera look, honoring the stick-swap setting.

Here is the caller graph for this function:

◆ getMoveJoystickAxes()

JoystickAxis systems::getMoveJoystickAxes ( bool swapSticks)
inline

Return the SDL axes used for movement, honoring the stick-swap setting.

Here is the caller graph for this function:

◆ grantAbilityLevel()

void systems::grantAbilityLevel ( AbilityState & state)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ grantAbilityProgress()

void systems::grantAbilityProgress ( AbilityState & state,
float amount )
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleAbilitySelection()

void systems::handleAbilitySelection ( InputSnapshot & snap,
AbilityState & state )
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleAmmo()

bool systems::handleAmmo ( GunInstance & gun)
inline

Consume one round from the magazine; auto-reload if empty.

Parameters
gunGun instance to consume ammo from (modified in place).
Returns
True if a round was consumed, false if the gun is empty.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleCooldown()

void systems::handleCooldown ( WeaponState & weapon,
float dt )
inline

Tick fire cooldowns for all weapon slots.

Parameters
weaponWeapon state (modified in place).
dtFixed physics delta time in seconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleDeath()

void systems::handleDeath ( entt::entity & player,
Health & playerHealth,
entt::entity & killer,
Registry & registry,
std::vector< NetKillEvent > & killEvents,
BodyRegion hitRegion )
inline

Transition a player to the dead state if health has reached zero.

Hides the player, removes hitboxes, starts a 5-second respawn timer, updates death/kill stats, and emits a NetKillEvent for the kill feed.

Parameters
playerEntity that died.
playerHealthHealth component (already at or below zero).
killerEntity that dealt the killing blow.
registryThe ECS registry.
killEventsAccumulates kill events for network broadcast.
hitRegionBody region of the killing blow.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleFire()

void systems::handleFire ( Registry & registry,
entt::entity shooter,
const InputSnapshot & input,
const Position & pos,
const CollisionShape & shape,
WeaponState & weapon,
bool gravityFlipped,
bool grenadeThrowActive,
float dt,
std::vector< NetParticleEvent > & outParticles,
std::vector< NetKillEvent > & killEvents,
std::vector< net::shotdebug::ShotDebugCapture > * outShotDebug )
inline

Process fire input: hitscan raycasts, beam weapons, charge shots, and projectiles.

Handles three weapon archetypes:

  • Beam — continuous DPS drain while held, capsule raycast each tick.
  • Charge — accumulates chargeTime while held, fires on release.
  • Discrete — standard per-click hitscan or projectile spawn.

Emits NetParticleEvent entries for tracer/impact effects and applies damage through applyDamage() which may trigger kill events.

Parameters
registryThe ECS registry.
shooterEntity that is firing.
inputCurrent input snapshot.
posShooter position.
shapeShooter collision shape (for eye height).
weaponShooter weapon state (modified in place).
gravityFlippedTrue when the shooter's gravity is inverted.
dtFixed physics delta time in seconds.
outParticlesAccumulates particle events for network broadcast.
killEventsAccumulates kill events for network broadcast.
outShotDebugPR-20: optional server-side debug capture sink. When non-null, each hitscan-fire path pushes one ShotDebugCapture row while RewindHitboxesGuard is still active, so the captured targets[*]. capsules reflect the historical sample the server actually raycast against.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleGrenadeCooldown()

void systems::handleGrenadeCooldown ( GrenadeState & grenades,
float dt )
inline
Here is the caller graph for this function:

◆ handleGrenadeInput()

void systems::handleGrenadeInput ( Registry & registry,
entt::entity shooter,
InputSnapshot & input,
const Position & pos,
const CollisionShape & shape,
GrenadeState & grenades,
bool gravityFlipped )
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleHealing()

void systems::handleHealing ( Health & playerHealth,
float dt )
inline

Tick passive health regeneration after the heal cooldown expires.

Parameters
playerHealthHealth component (modified in place).
dtFixed physics delta time in seconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleReload()

void systems::handleReload ( GunInstance & gun)
inline

Reload the gun's magazine from reserve ammo.

Parameters
gunGun instance to reload (modified in place).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleRespawn()

void systems::handleRespawn ( entt::entity & player,
Registry & registry )
inline

Reset a dead player to a fresh spawn state.

Clears the respawn timer and death info, restores visibility, resets position/velocity/health/weapons to defaults, and places the player at the spawn point.

Parameters
playerEntity to respawn (modified in place).
registryThe ECS registry.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleScope()

void systems::handleScope ( Registry & registry,
entt::entity shooter,
const InputSnapshot & input,
WeaponState & weapon,
float dt )
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleSwitch()

void systems::handleSwitch ( const InputSnapshot & input,
WeaponState & weapon )

Apply weapon slot switch from player input.

Parameters
inputCurrent input snapshot.
weaponWeapon state (modified in place).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleWinCondition()

std::optional< ClientId > systems::handleWinCondition ( Registry & registry,
int killsToWin )

Checks if any player has met win condition and updates their PlayerMatchStats accordingly.

Here is the caller graph for this function:

◆ hasPowerup()

bool systems::hasPowerup ( const PowerupState & state,
PowerupType type )
Here is the caller graph for this function:

◆ isPlayerLookingAtPickup()

bool systems::isPlayerLookingAtPickup ( glm::vec3 eye,
glm::vec3 viewFwd,
glm::vec3 pickupPos )
inline

True if the eye is within range of pickupPos and viewFwd points within the look cone.

Here is the caller graph for this function:

◆ logShot()

void systems::logShot ( Registry & registry,
entt::entity shooter,
std::uint32_t shotInputTick,
const glm::vec3 & origin,
const glm::vec3 & direction,
const physics::HitboxHit & hit )
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ muzzleOrigin()

glm::vec3 systems::muzzleOrigin ( glm::vec3 eye,
glm::vec3 direction,
bool gravityFlipped = false )
inline

Offset the muzzle origin from the eye position for tracer visuals.

Shifts the origin right and down from eye, slightly forward, so tracers don't originate from the center of the screen.

Parameters
eyeEye position (camera origin).
directionNormalized view direction.
gravityFlippedWhen true, negate the horizontal offset so the tracer originates from the viewmodel side. The viewmodel stays on screen-right, but the 180° camera roll reverses world-left/right — so world-right (the normal offset) appears on the wrong side of the screen.
Returns
Offset muzzle position in world space.
Here is the caller graph for this function:

◆ nextGrenadeWithAmmo()

int systems::nextGrenadeWithAmmo ( const GrenadeState & grenades,
int start,
int dir )
inline

Find the next grenade type index (wrapping in direction dir, +1 or -1) that still has ammo, starting the search one step away from start.

Returns start when no other type has ammo (including when start itself is the only one with ammo, or none do).

Here is the caller graph for this function:

◆ overlapsAABB()

bool systems::overlapsAABB ( glm::vec3 aPos,
glm::vec3 aHalf,
glm::vec3 bPos,
glm::vec3 bHalf )
inline

Test whether two axis-aligned bounding boxes overlap.

Here is the caller graph for this function:

◆ overlapsAabb()

bool systems::overlapsAabb ( const physics::WorldAABB & a,
const physics::WorldAABB & b )
static
Here is the caller graph for this function:

◆ pushHitboxHistory()

void systems::pushHitboxHistory ( Registry & registry,
uint32_t serverTick )

Capture this tick's hitbox capsules into each entity's HitboxHistory ring.

For every entity that has a HitboxInstance, copies its current capsules vector into the next slot of the ring and records the owning server tick. Entities without a HitboxInstance (e.g. dead players whose capsules were dropped by updateHitboxes) are skipped — their existing samples stay in the ring, so a target that died ~200 ms ago can still be hit by a delayed shot once rewind lands.

Parameters
registryThe ECS registry.
serverTickCurrent server tick (monotonic, 128 Hz). Stored alongside the capsules so the rewind guard can pick the closest sample to the attacker's tick.
Here is the caller graph for this function:

◆ queueAbilityChoice()

bool systems::queueAbilityChoice ( AbilityState & state)
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ queueExplosion()

void systems::queueExplosion ( Registry & registry,
glm::vec3 position,
float radius,
float maxDamage,
entt::entity owner,
float falloffExponent = 1.0f,
float selfDamageMultiplier = 1.0f,
float maxKnockback = 0.0f,
float knockbackFalloffExponent = 1.0f,
entt::entity directKillTarget = entt::null,
WeaponType weaponType = WeaponType::Rocket )

Create an explosion entity at the given position.

The explosion is processed on the next call to runExplosion().

Parameters
registryThe ECS registry.
positionWorld-space center of the explosion.
radiusBlast radius (damage falls off to zero at edge).
maxDamageMaximum damage at the epicenter.
ownerEntity that caused the explosion (for self-damage / kill credit).
falloffExponentDamage curve exponent (1 = linear, 3 = cubic/sharp).
selfDamageMultiplierDamage scale when victim == owner (e.g. 0.4 for rocket jumps).
maxKnockbackPeak knockback velocity (u/s) imparted at the epicenter.
knockbackFalloffExponentKnockback curve exponent (same form as damage falloff).
directKillTargetIf valid, this entity takes guaranteed lethal damage regardless of radius/falloff (used by a grenade stuck to a player).
Here is the caller graph for this function:

◆ reconcileMovementAfterKcc()

void systems::reconcileMovementAfterKcc ( glm::vec3 & pos,
glm::vec3 & vel,
const CollisionShape & shape,
PlayerVisState & vis,
PlayerSimState & sim,
const InputSnapshot & input,
const physics::WorldGeometry & world,
const physics::KccFrameResult & kcc,
float dt )

Consume collision-owned KCC feedback after position integration.

MovementSystem owns traversal state. CollisionSystem calls this immediately after KCC so wallrun can respond to blockers, ceilings, and solver stalls before the next movement tick accelerates again.

Here is the caller graph for this function:

◆ removePowerup()

void systems::removePowerup ( PowerupState & state,
PowerupType type )

◆ resetPowerupSpawnersForMatch()

void systems::resetPowerupSpawnersForMatch ( Registry & registry,
const MatchConfig & matchConfig )

Hide all powerups and restart their initial match-start spawn delay.

Here is the caller graph for this function:

◆ resetStats()

void systems::resetStats ( Registry & registry)

Resets all players' match scores to initial values.

Here is the caller graph for this function:

◆ resolveRespawnPosition()

glm::vec3 systems::resolveRespawnPosition ( Registry & registry,
entt::entity player,
glm::vec3 feetPosition )
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rewindHitboxes()

RewindHitboxesGuard systems::rewindHitboxes ( Registry & registry,
entt::entity shooter,
const glm::vec3 * rayOrigin = nullptr,
const glm::vec3 * rayDirection = nullptr,
float rayMaxDistance = 0.0f,
float bulletRadius = 0.0f )
inline

Rewind every other player's hitbox capsules to where they were on shooter's screen at fire time.

Reads LagCompTarget from shooter. If absent or zero, returns a no-op guard immediately (the common case for client-side and for sub-tick-RTT shooters). Otherwise walks every entity with both HitboxInstance and HitboxHistory, finds the most recent history sample whose tick is ≤ targetServerTick, swaps the live capsules for the historical ones, and stashes the originals in the returned guard for restore-on-destruction.

PR-5 (server-perf): two overloads.

  • The unfiltered form (kept for compatibility) rewinds every player. O(N) per shot. Pre-PR-5 measurements at 200 bots during fire bursts: this dominated the weapon scope's 6.29 ms p99 — 25 shots × 200 candidate rewinds × ~1–5 µs each ≈ 5–25 ms / sec.
  • The ray-filtered form rewindHitboxes(registry, shooter, origin, direction, maxDistance) adds a broad-phase ray-vs- AABB test BEFORE rewinding each candidate. Players whose bounding box doesn't intersect the shot ray are skipped — no ring scan, no capsule swap. The AABB test costs ~10 ns and prunes >95 % of candidates for typical shot geometry.

shooter itself is not rewound — resolveHitscanHitbox already excludes the shooter from the player-hitbox raycast.

Parameters
registryThe server ECS registry.
shooterEntity firing the hitscan. Read for LagCompTarget.
Returns
Guard whose destructor restores the original capsules.
Here is the caller graph for this function:

◆ runAbility()

void systems::runAbility ( Registry & registry,
AbilityRegistry & abilityRegistry,
float dt )
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runCollision()

void systems::runCollision ( Registry & registry,
float dt,
const physics::WorldGeometry & world )

Run one tick of swept-AABB collision for all physics entities.

For every entity with [Position, Velocity, CollisionShape, PlayerVisState]:

  1. Clears the grounded flag.
  2. Sweeps the AABB from current position toward pos + vel * dt.
  3. On hit: moves to the contact point, clips velocity, repeats up to 4 times (Quake-style bumping handles corners and multi-surface contacts).
  4. Sets grounded = true if a floor surface (normal.y > 0.7) is hit.
Note
Position integration lives here, not in MovementSystem.
Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
worldWorld collision geometry (planes, boxes, brushes) for this tick.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runDeadInput()

void systems::runDeadInput ( Registry & registry,
const InputBindings & bindings )
inline

Sample skip-respawn input while the local player is dead.

Runs independently of Controllable — dead players can use the Jump binding to skip the remaining respawn timer and respawn immediately.

Parameters
registryThe ECS registry.
bindingsThe configured keyboard/mouse bindings.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runDroppedWeapons()

void systems::runDroppedWeapons ( Registry & registry,
float dt )

Tick dropped weapons: handle pickup (overlap-refill or look+F replace) and despawn timer.

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runDynamics()

void systems::runDynamics ( Registry & registry,
float dt,
const physics::WorldGeometry & world,
physics::ContactCache & cache,
const physics::SolverConfig & solverCfg,
const physics::SleepConfig & sleepCfg )

One physics tick for rigid-body dynamic entities.

Parameters
registryECS registry.
dtTick duration (typically 1/128 s).
worldActive world collision geometry (static).
cachePersistent contact-manifold cache (carried across ticks for warm-starting the solver).
solverCfgSolver tuning parameters (iteration counts, friction).
sleepCfgSleep thresholds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runEmoteWheelKey()

void systems::runEmoteWheelKey ( const InputBindings & bindings)
inline

Track the Emote binding (keyboard/mouse) to open/close the wheel.

Must run every iterate() before runMouseLook so the look sampler can divert mouse motion into the wheel. On release, the highlighted sector is latched as the emote to play.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ runExplosion()

void systems::runExplosion ( Registry & registry,
std::vector< NetParticleEvent > & outParticles,
std::vector< NetKillEvent > & killEvents )

Process all pending explosions: apply radial damage and emit particle events.

For each Explosion component, damages every player within the blast radius (damage = maxDamage * pow(1 - d/r, falloffExponent)), emits a ParticleEffectType::Explosion event, and destroys the explosion entity.

Parameters
registryThe ECS registry.
outParticlesAccumulates particle events for network broadcast.
killEventsAccumulates kill events for network broadcast.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runFireField()

void systems::runFireField ( Registry & registry,
float dt,
std::vector< NetKillEvent > & killEvents )

Tick all FireField entities: decrement remaining, apply DoT damage at fixed sub-intervals (4 Hz), and destroy expired fields.

Self-damage is scaled by 0.4 (matches rocket/grenade self-damage philosophy).

Here is the call graph for this function:
Here is the caller graph for this function:

◆ runGamepadAimAssist()

void systems::runGamepadAimAssist ( Registry & registry,
SDL_Gamepad * gamepad,
const GamepadAimAssistConfig & cfg,
GamepadAimAssistState & state,
float pitchSensitivity,
float yawSensitivity,
float lookDeadzone,
float moveDeadzone,
float dt,
bool swapSticks = false )
inline

Apply gamepad aim assist (slowdown + movement-tracking pull) to the local player's InputSnapshot.

Must run AFTER runGamepadLook so we can refund part of the player input it just integrated.

Parameters
registryECS registry.
gamepadOpen gamepad handle (nullptr → no-op).
cfgTuning parameters.
statePersistent per-frame state (anchor + previous-frame snapshot).
pitchSensitivityPitch radians per second at full stick deflection.
yawSensitivityYaw radians per second at full stick deflection.
lookDeadzoneLook-stick deadzone as a fraction of full deflection.
moveDeadzoneMove-stick deadzone as a fraction of full deflection.
dtFrame delta time (seconds).
swapSticksWhen true, use the swapped stick layout for activation checks.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runGamepadDeadInput()

void systems::runGamepadDeadInput ( Registry & registry,
SDL_Gamepad * gamepad,
const InputBindings & bindings )
inline

Sample controller skip-respawn input while the local player is dead.

Parameters
registryThe ECS registry.
gamepadOpen gamepad, or nullptr to no-op.
bindingsController bindings to sample.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runGamepadEmoteWheel()

void systems::runGamepadEmoteWheel ( SDL_Gamepad * gamepad,
const InputBindings & bindings,
bool swapSticks = false )
inline

Track the Emote binding (controller) to open/close the wheel and pick a sector from the right stick.

Mirrors runEmoteWheelKey; runs every iterate() before runGamepadLook. ORs into the shared wheel state so a player can use either device. On release the highlighted sector is latched as the emote to play.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ runGamepadLook()

void systems::runGamepadLook ( Registry & registry,
SDL_Gamepad * gamepad,
float pitchSensitivity,
float yawSensitivity,
float deadzone,
float dt,
bool gravityFlipped = false,
bool swapSticks = false )
inline

Sample the right stick into yaw / pitch.

Must be called every iterate() call — same cadence as runMouseLook — so camera rotation is smooth at any frame rate. Unlike mouse delta (which is integrated over the time between calls), the stick gives an instantaneous angular velocity, so we multiply by frame delta time.

Adds to existing yaw/pitch (so simultaneous mouse + stick compose).

Parameters
registryThe ECS registry.
gamepadOpen gamepad, or nullptr to no-op.
pitchSensitivityPitch radians per second at full stick deflection.
yawSensitivityYaw radians per second at full stick deflection.
deadzoneStick deadzone as a fraction of full deflection.
dtFrame delta time in seconds.
gravityFlippedWhen true, both axes are inverted for 180° camera roll.
swapSticksWhen true, use the left stick for look instead of the right stick.

< Stick deflection needed to start accelerating.

< Seconds at full deflection to reach the max boost.

< Extra turn-rate multiplier at full ramp (1.0 => up to 2x).

Here is the call graph for this function:
Here is the caller graph for this function:

◆ runGamepadMovement()

void systems::runGamepadMovement ( Registry & registry,
SDL_Gamepad * gamepad,
const InputBindings & bindings,
float deadzone,
bool gravityFlipped = false,
bool swapSticks = false )
inline

Sample gamepad buttons / left stick into the movement flags.

ORs with whatever the keyboard sampler set so kbm + pad coexist. Should run on the same cadence as runMovementKeys (once per physics tick group when synced, otherwise every iterate).

Mapping: Left stick → forward / back / strafe Configured buttons/triggers drive jump, crouch, and abilities.

Parameters
registryThe ECS registry.
gamepadOpen gamepad, or nullptr to no-op.
bindingsController bindings to sample.
deadzoneStick deadzone as a fraction of full deflection.
gravityFlippedWhen true, left/right stick are swapped to match the 180° camera roll.
swapSticksWhen true, use the right stick for movement instead of the left stick.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runGamepadWeapon()

void systems::runGamepadWeapon ( Registry & registry,
SDL_Gamepad * gamepad,
const InputBindings & bindings )
inline

Sample gamepad buttons / right trigger into the weapon flags.

ORs with whatever the keyboard sampler set so kbm + pad coexist.

Mapping: Configured buttons/triggers drive weapon actions.

Parameters
registryThe ECS registry.
gamepadOpen gamepad, or nullptr to no-op.
bindingsController bindings to sample.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runHealthPackSpawners()

void systems::runHealthPackSpawners ( Registry & registry,
float dt )

Tick spawners: check player overlap for pickup, manage cooldowns.

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runInputReceive()

Event systems::runInputReceive ( const void * data)
inline

Deserialise a raw InputSnapshot packet into a gameplay Event.

Parameters
dataPointer to the raw InputSnapshot bytes.
Returns
An Event populated with the decoded movement and action intents.

◆ runInputSample()

void systems::runInputSample ( Registry & registry,
const InputBindings & bindings,
float mouseSensitivity = user_settings::kDefaultMouseSensitivity )
inline

Legacy combined sampler — calls both runMouseLook and runMovementKeys.

Parameters
registryThe ECS registry.
mouseSensitivityRadians per pixel.
Here is the call graph for this function:

◆ runInputSend()

void systems::runInputSend ( Registry & registry,
Client & conn )
inline

Send the local player's current InputSnapshot over the network.

Parameters
registryThe ECS registry.
connNetwork connection to the server.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runJumpPads()

void systems::runJumpPads ( Registry & registry,
float dt )

Tick jump pads: for each pad, any player whose AABB overlaps the pad's trigger volume on the rising edge has the pad's velocity applied as an impulse.

A small per-player cooldown prevents the same player from being relaunched every tick while they're still inside the trigger (the impulse won't have moved them out yet).

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runKillzones()

void systems::runKillzones ( Registry & registry,
std::vector< NetKillEvent > & killEvents )

Tick killzones: for each killzone trigger, any player whose AABB overlaps it takes lethal damage.

Kill events are appended to killEvents so they're broadcast alongside other kills in the tick.

Killer is set to the player themselves so the kill feed shows the kill as a self-elimination (the world has no entity to credit).

Parameters
registryThe ECS registry.
killEventsNetwork kill events to broadcast this tick.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runKinematicCharacterController()

physics::KccFrameResult systems::runKinematicCharacterController ( glm::vec3 & pos,
glm::vec3 & vel,
const CollisionShape & shape,
PlayerVisState & state,
float dt,
const physics::WorldGeometry & world,
entt::entity entity,
bool jumpedThisTick,
PlayerSimState * simState = nullptr )

Resolve one fixed-tick capsule character-controller step.

MovementSystem owns intent and velocity shaping. This module owns the collision-side KCC work: capsule depenetration, walk-capsule horizontal sweep, ground snap, vertical sweep, final grounded state, and diagnostics.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ runMouseLook()

void systems::runMouseLook ( Registry & registry,
float mouseSensitivity,
bool gravityFlipped = false )
inline

Sample mouse delta and accumulate into yaw / pitch.

Must be called every iterate() call regardless of whether a physics tick fires — this keeps camera rotation smooth at the render frame rate. SDL_GetRelativeMouseState returns the accumulated delta since the previous call, so the total rotation over any time window is identical regardless of call frequency.

Parameters
registryThe ECS registry.
mouseSensitivityRadians per pixel of mouse movement.
gravityFlippedWhen true, both mouse axes are inverted so controls feel natural while the camera is rolled 180° for upside-down gravity.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runMovement()

void systems::runMovement ( Registry & registry,
float dt,
const physics::WorldGeometry & world )

Apply one tick of player movement physics to all eligible entities.

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
worldWorld collision geometry (needed for wall detection).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runMovementKeys()

void systems::runMovementKeys ( Registry & registry,
const InputBindings & bindings,
bool gravityFlipped = false )
inline

Sample keyboard state into the movement flags.

Should be called once per physics tick group when input is synced with physics (the default) so movement calculations match the server. Can also be called every iterate() when the sync toggle is off.

Parameters
registryThe ECS registry.
bindingsKeyboard/mouse bindings to sample.
gravityFlippedWhen true, A/D are swapped so strafing feels correct while the camera is rolled 180°.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runPlayerStatus()

void systems::runPlayerStatus ( Registry & registry,
float dt )

Run one tick of player status: respawn timers and passive healing.

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runPowerups()

void systems::runPowerups ( Registry & registry,
float dt )

Run one tick of powerup logic for all players.

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runPowerupSpawners()

void systems::runPowerupSpawners ( Registry & registry,
float dt,
const MatchConfig & matchConfig,
std::vector< NetParticleEvent > & outEvents )

Tick Powerup spawners: check player overlap for pickup, manage cooldowns.

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
matchConfigCurrent host-managed match settings.
outEventsServer-authored replicated events emitted by pickups.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runPrediction()

void systems::runPrediction ( Registry & registry,
float dt,
const physics::WorldGeometry & world )
inline

Run one tick of client-side prediction for the local player.

Just calls the shared runMovement and runCollision against the local registry. The View filter (PlayerSimState) ensures only the local player is processed on the client. Server's runMovement still processes every player in the same single call.

Parameters
registryThe client ECS registry.
dtFixed physics delta (must match server's dt for prediction parity — typically 1/128 s).
worldActive world geometry. Must match the server's world exactly or prediction diverges.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runRagdolls()

void systems::runRagdolls ( Registry & registry,
float dt )

Per-tick ragdoll bookkeeping: advance age, optionally tick the cleanup timer for old corpses.

Called from the same tick that runs the constraint solver.

Parameters
registryECS registry.
dtTick duration in seconds.
Here is the caller graph for this function:

◆ runReconciliation()

ReconciliationStats systems::runReconciliation ( Registry & registry,
const InputRingBuffer & ring,
uint32_t ackedTick,
uint32_t currentTick,
float dt,
const physics::WorldGeometry & world )
inline

Replay stored inputs from ackedTick + 1 through currentTick on the local player, restoring its predicted state after a snapshot apply rewrote it to the server-authoritative value.

Parameters
registryThe client ECS registry. Local player's Position etc. should be the server's just-applied value.
ringInput history ring; entries from earlier than ackedTick may have been overwritten and are not used.
ackedTickThe client tick the server has acknowledged processing through. The local player's current Position represents state as-of this tick.
currentTickThe client's current clientPredictTick. Replay runs runMovement+runCollision once per tick from ackedTick + 1 through currentTick (inclusive).
dtPhysics delta (match server: 1/128 s).
worldWorld geometry (must match server).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runSpawnPointCooldowns()

void systems::runSpawnPointCooldowns ( Registry & registry,
float dt )

Tick spawn point cooldowns.

Each spawn point's cooldown decrements by dt and becomes available again when it reaches zero.

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
Here is the caller graph for this function:

◆ runTriggers()

void systems::runTriggers ( Registry & registry,
bool isPredictedClient = false )

Test every trigger-volume entity for overlap with non-trigger entities and emit Enter / Stay / Exit events.

Drops trigger volumes' overlap state when the trigger entity is destroyed.

Parameters
registryECS registry.
isPredictedClientTrue when called from the client-side prediction path. Triggers without fireOnPredictedClient do not emit events in this mode (they would double-fire when the server's authoritative state lands).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runWeapon()

void systems::runWeapon ( Registry & registry,
float dt,
std::vector< NetParticleEvent > & outParticles,
std::vector< NetKillEvent > & killEvents,
std::vector< net::shotdebug::ShotDebugCapture > * outShotDebug = nullptr )

Run one tick of weapon logic for all armed entities.

For each entity with [InputSnapshot, Position, CollisionShape, WeaponState]: handles weapon switching, cooldown ticking, fire/beam/charge processing, hitscan raycasting, projectile spawning, damage application, and ammo refill.

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
outParticlesAccumulates particle events for network broadcast.
killEventsAccumulates kill events for network broadcast.
outShotDebugPR-20 (server-side only): if non-null, every hitscan shot pushes a ShotDebugCapture row while the rewind guard is still active so the capsule data reflects the historical sample the server actually raycast against. ServerGame serialises and sends each entry to the shooter via Server::enqueueTo. Client TUs leave this null — clients run WeaponSystem for prediction only and don't generate debug reports.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runWeaponKeys()

void systems::runWeaponKeys ( Registry & registry,
const InputBindings & bindings )
inline

Sample keyboard state into the weapon flags.

Should be called once per physics tick group when input is synced with physics (the default) so movement calculations match the server. Can also be called every iterate() when the sync toggle is off.

Parameters
registryThe ECS registry.
bindingsThe input bindings.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ runWeaponSpawners()

void systems::runWeaponSpawners ( Registry & registry,
float dt )

Tick weapon spawners: check player overlap for pickup, manage cooldowns.

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ spawnCapsuleFor()

physics::CapsuleShape systems::spawnCapsuleFor ( const CollisionShape & shape)
inline
Here is the caller graph for this function:

◆ spawnDroppedWeapon()

void systems::spawnDroppedWeapon ( Registry & registry,
glm::vec3 pos,
glm::vec3 initialVel,
const GunInstance & gun,
float pickupDelay )

Spawn an in-world dropped-weapon pickup carrying a gun's ammo.

Shared by death drops (PlayerStatusSystem) and weapon-swap drops (WeaponSpawnerSystem / DroppedWeaponSystem). The entity gets a compact AABB plus Velocity/RigidBody so it falls under gravity and settles.

Parameters
registryThe ECS registry.
posWorld position to spawn the drop at.
initialVelInitial velocity (e.g. a gentle toss for swap drops).
gunThe gun being dropped; its ammo state is snapshotted.
pickupDelayPickup-immunity window (s) before the drop can be grabbed.
Here is the caller graph for this function:

◆ spawnFireField()

void systems::spawnFireField ( Registry & registry,
glm::vec3 position,
float radius,
float duration,
float dps,
entt::entity owner )

Spawn a FireField at position that lasts duration seconds and deals dps damage to players inside radius.

owner gets kill credit.

◆ spawnGrenade()

void systems::spawnGrenade ( Registry & registry,
entt::entity shooter,
WeaponType type,
glm::vec3 muzzle,
glm::vec3 eyeDir,
glm::vec3 eyeRight,
glm::vec3 throwerVel )
static

Spawn a grenade projectile from the player's eye position.

Computes a throw direction by rotating the eye direction upward by the configured (small) pitch offset, then adds the thrower's velocity so a grenade thrown on the move inherits the player's momentum (Halo-style): moving forward extends the throw, backpedaling shortens it. Copies all flight-relevant fields from the grenade's GrenadeConfig into the new Projectile entity so CollisionSystem can dispatch on them.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ spawnRagdoll()

entt::entity systems::spawnRagdoll ( Registry & registry,
entt::entity character )

Build a 15-body humanoid ragdoll for the dead character.

The character's existing position / velocity become the seed state for the new bodies. Idempotent: calling twice on the same character is a no-op (the second call sees the Ragdoll component is already present).

Returns
The created Ragdoll parent entity (== character).
Here is the caller graph for this function:

◆ standingHalfHeight()

float systems::standingHalfHeight ( const CollisionShape & shape)
inline
Here is the caller graph for this function:

◆ tickCooldown()

void systems::tickCooldown ( float & cooldown,
float dt )
inline
Here is the caller graph for this function:

◆ tryPickup()

bool systems::tryPickup ( Registry & registry,
Position dropPos,
CollisionShape dropShape,
const DroppedWeapon & dw,
std::vector< PendingWeaponDrop > & pendingDrops )
inline

Try to grant the dropped weapon to a player.

Parameters
pendingDropsCollects any swap-out gun to re-drop (spawned after iteration to avoid invalidating the active view).
Returns
True if the entity should be destroyed (pickup happened).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update()

void systems::update ( Registry & registry,
float dt )
inline

Placeholder system — replace with real logic.

Parameters
registryThe ECS registry.
dtFixed physics delta time in seconds.

◆ updateAbilityLevel()

void systems::updateAbilityLevel ( Registry & registry,
entt::entity player,
float dmg )
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateHitboxes()

void systems::updateHitboxes ( Registry & registry,
const HitboxRig & hitboxRig,
float rigScale,
float rigMeshMinY )

Update world-space hitbox capsules for all entities that have JointMatrices.

For each entity with [Position, JointMatrices] this builds the world transform (entity position + yaw rotation + rig scale + vertical offset) and transforms every HitboxDef capsule into a WorldCapsule stored in HitboxInstance.

Parameters
registryThe ECS registry.
hitboxRigShared hitbox definitions (bone-to-capsule mapping).
rigScaleScale factor applied to the rig (model space -> game units).
rigMeshMinYMinimum Y vertex of the bind-pose mesh (model space).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ useAbility()

void systems::useAbility ( entt::entity player,
AbilityType type,
Registry & registry,
AbilityRegistry & abilityRegistry )
inline
Here is the call graph for this function:
Here is the caller graph for this function:

◆ viewForward()

glm::vec3 systems::viewForward ( float yaw,
float pitch )
inline

Forward direction implied by a player's yaw + pitch.

Compute the player's 3D view direction from yaw and pitch angles.

Parameters
yawHorizontal angle (radians).
pitchVertical angle (radians, positive = down).
Returns
Normalized forward direction vector.
Here is the caller graph for this function:

Variable Documentation

◆ armorMax

const float systems::armorMax = 100.0f

Maximum armor value.

◆ dmgThreshold

float systems::dmgThreshold = 1000.0f
constexpr

◆ emoteWheelDirX

float systems::emoteWheelDirX = 0.0f
inline

Accumulated pointing direction used to resolve the highlighted sector.

◆ emoteWheelDirY

float systems::emoteWheelDirY = 0.0f
inline

◆ emoteWheelOpen

bool systems::emoteWheelOpen = false
inline

True while the emote wheel is open (Emote binding held on any device).

◆ emoteWheelSelection

int systems::emoteWheelSelection = -1
inline

Currently highlighted emote sector while the wheel is open, or -1 (none).

◆ gamepadLookAccel

float systems::gamepadLookAccel = 0.0f
inline

COD-style look acceleration progress in [0, 1]; ramps while the look stick is held near full deflection and resets when it eases off.

◆ gamepadPickupDownMs

Uint64 systems::gamepadPickupDownMs = 0
inline

SDL_GetTicks at the Y press, for hold-duration timing.

◆ gamepadPickupHoldFired

bool systems::gamepadPickupHoldFired = false
inline

Set once the press crossed the hold threshold (suppresses tap-swap).

◆ healCooldown

const float systems::healCooldown = 5.0f

Seconds after last damage before passive healing starts.

◆ healingRate

const float systems::healingRate = 20.0f

Passive healing amount per second.

◆ healthMax

const float systems::healthMax = 100.0f

Maximum health value.

◆ healthPackCooldownTime

float systems::healthPackCooldownTime = 15.0f
constexpr

◆ k_droppedWeaponLifetime

float systems::k_droppedWeaponLifetime = 30.0f
constexpr

Default lifetime (seconds) for a dropped weapon before it despawns.

◆ k_pickupMaxAngleDeg

float systems::k_pickupMaxAngleDeg = 12.0f
constexpr

Half-angle (degrees) of the look cone for press-F pickup.

◆ k_pickupMinDot

const float systems::k_pickupMinDot = std::cos(glm::radians(k_pickupMaxAngleDeg))
inline

Pre-computed cosine of the look cone half-angle.

◆ k_pickupRange

float systems::k_pickupRange = 140.0f
constexpr

Maximum distance (units) at which a player can press F to pick up.

◆ k_pushback

float systems::k_pushback = 0.03125f
staticconstexpr

◆ k_spawnPointCooldown

float systems::k_spawnPointCooldown = 5.0f
inlineconstexpr

Cooldown duration set on a spawn point after a player spawns there.

◆ k_spawnPushback

float systems::k_spawnPushback = 0.03125f
inlineconstexpr

◆ k_swapDropPickupDelay

float systems::k_swapDropPickupDelay = 0.8f
constexpr

Pickup-immunity applied to a weapon dropped during a swap, so the player can't instantly re-grab the gun they just replaced.

◆ k_weaponPickupHalfExtents

const glm::vec3 systems::k_weaponPickupHalfExtents {32.0f, 32.0f, 32.0f}
inline

Shared pickup collision half-extents for weapon spawners and dropped weapons.

◆ maxLevel

int systems::maxLevel = 2
constexpr

◆ overShieldMax

const float systems::overShieldMax = 200.0f

◆ pendingEmoteRequest

int systems::pendingEmoteRequest = -1
inline

Latched emote to play on wheel release; consumed once by the game loop.

◆ pendingGamepadWeaponSwap

bool systems::pendingGamepadWeaponSwap = false
inline

Latched tap-Y weapon swap, consumed once per frame by the game loop.

◆ pendingGrenadeCycleNext

bool systems::pendingGrenadeCycleNext = false
inline

Latched cycle next/prev requests, consumed once per frame by the game loop.

◆ pendingGrenadeCyclePrev

bool systems::pendingGrenadeCyclePrev = false
inline

◆ pendingGrenadeThrow

bool systems::pendingGrenadeThrow = false
inline

Latched throw request, consumed once per frame by the game loop.

◆ prevAbilitySelectLeft

bool systems::prevAbilitySelectLeft = false
inline

Tracks previous-frame Alt+LMB state for ability choice edge detection.

◆ prevAbilitySelectRight

bool systems::prevAbilitySelectRight = false
inline

Tracks previous-frame Alt+RMB state for ability choice edge detection.

◆ prevEmoteKey

bool systems::prevEmoteKey = false
inline

Previous-frame Emote-binding state for open/close edge detection.

◆ prevGamepadAbilitySelectLeft

bool systems::prevGamepadAbilitySelectLeft = false
inline

Tracks previous-frame gamepad left ability-select chord for edge detection.

◆ prevGamepadAbilitySelectRight

bool systems::prevGamepadAbilitySelectRight = false
inline

Tracks previous-frame gamepad right ability-select chord for edge detection.

◆ prevGamepadEmoteKey

bool systems::prevGamepadEmoteKey = false
inline

◆ prevGamepadGrenadeCycleKey

bool systems::prevGamepadGrenadeCycleKey = false
inline

Gamepad equivalents: CycleGrenade (D-pad Left) / ThrowGrenade (B).

◆ prevGamepadGrenadeThrowKey

bool systems::prevGamepadGrenadeThrowKey = false
inline

◆ prevGamepadPickupKey

bool systems::prevGamepadPickupKey = false
inline

Gamepad Y (Pickup binding) tap-vs-hold state: tap swaps weapon, hold picks up.

◆ prevGrenadeCycleKey

bool systems::prevGrenadeCycleKey = false
inline

Previous-frame CycleGrenade (H) / ThrowGrenade (G) key state for edge detection (keyboard/mouse).

◆ prevGrenadeThrowKey

bool systems::prevGrenadeThrowKey = false
inline

◆ prevKillSelfKey

bool systems::prevKillSelfKey = false
inline

Tracks previous-frame key state for edge detection.

◆ weaponCooldownTime

float systems::weaponCooldownTime = 10.0f
constexpr