Skip to main content
This page documents weapon-related data structures: the static weapon table and per-player weapon state.

Weapon Table

Base: 0x004d7a00 (weapon_table)
Entry size: 0x48 bytes (72 bytes)
Count: 54 weapons

Struct Layout

typedef struct {
    i32 ammo;               // +0x00
    float reload_time;      // +0x04
    i32 projectile_count;   // +0x08
    float spread_angle;     // +0x0c
    float base_damage;      // +0x10
    float fire_rate;        // +0x14
    i32 ammo_class;         // +0x18
    float shot_cooldown;    // +0x1c
    i32 projectile_type;    // +0x20
    float speed_scale;      // +0x24
    // ... more fields
} weapon_entry_t;  // 0x48 bytes

Key Fields

OffsetFieldTypeDescription
0x00ammoi32Magazine size
0x04reload_timefloatReload duration (seconds)
0x08projectile_counti32Projectiles per shot (shotguns)
0x0cspread_anglefloatSpread per shot (radians)
0x10base_damagefloatDamage per projectile
0x14fire_ratefloatShots per second
0x18ammo_classi32Ammo type (affects reload/effects)
0x1cshot_cooldownfloatTime between shots
0x20projectile_typei32Projectile pool type ID

Weapon Examples

Pistol (Weapon ID 1)

{
    .ammo = 12,
    .reload_time = 1.5,
    .projectile_count = 1,
    .spread_angle = 0.0,
    .base_damage = 10.0,
    .fire_rate = 8.0,
    .ammo_class = 1,
    .shot_cooldown = 0.125,
    .projectile_type = 0x01
}

Shotgun (Weapon ID 3)

{
    .ammo = 8,
    .reload_time = 2.0,
    .projectile_count = 7,  // 7 pellets
    .spread_angle = 0.15,   // Wide spread
    .base_damage = 5.0,     // Per pellet
    .fire_rate = 3.0,
    .ammo_class = 2,
    .shot_cooldown = 0.333,
    .projectile_type = 0x03
}

Gauss Gun (Weapon ID 6)

{
    .ammo = 30,
    .reload_time = 2.5,
    .projectile_count = 1,
    .spread_angle = 0.0,
    .base_damage = 50.0,    // High damage
    .fire_rate = 2.0,       // Slow
    .ammo_class = 3,
    .shot_cooldown = 0.5,
    .projectile_type = 0x06 // Piercing beam
}

Player Weapon State

Weapon state is embedded in the player struct: Base: player_health + 0x29c (within player pool)

Current Weapon

OffsetFieldTypeDescription
0x29cweapon_idi32Current weapon ID (1-54)
0x2a0clip_sizefloatMagazine capacity (copied from table)
0x2a4reload_activeu81 if currently reloading
0x2a8ammofloatCurrent ammo count
0x2acreload_timerfloatReload countdown
0x2b0shot_cooldownfloatFire rate cooldown
0x2b4reload_timer_maxfloatTotal reload duration

Alt Weapon (Swap State)

OffsetFieldTypeDescription
0x2b8alt_weapon_idi32Swapped-out weapon ID
0x2bcalt_clip_sizefloatSaved magazine size
0x2c0alt_reload_activeu8Saved reload flag
0x2c4alt_ammofloatSaved ammo count
0x2c8alt_reload_timerfloatSaved reload timer
0x2ccalt_shot_cooldownfloatSaved fire cooldown
0x2d0alt_reload_timer_maxfloatSaved reload duration
Usage: When picking up a new weapon, current state is saved to alt_* fields.

Weapon Assignment

The weapon_assign_player function copies table data to player state:
void weapon_assign_player(int player_idx, int weapon_id) {
    weapon_entry_t* entry = &weapon_table[weapon_id];
    player_t* player = &player_pool[player_idx];
    
    // Copy static data
    player->weapon_id = weapon_id;
    player->clip_size = (float)entry->ammo;
    player->ammo = (float)entry->ammo;
    player->reload_timer_max = entry->reload_time;
    player->shot_cooldown = entry->shot_cooldown;
    
    // Reset timers
    player->reload_active = 0;
    player->reload_timer = 0.0;
}

Weapon Fire Logic

Key steps in player_fire_weapon:
  1. Check cooldown: if (shot_cooldown > 0) return;
  2. Check ammo: if (ammo <= 0) start_reload();
  3. Spawn projectiles: Loop projectile_count times with spread
  4. Decrement ammo: ammo -= 1.0;
  5. Set cooldown: shot_cooldown = weapon_table[weapon_id].shot_cooldown;
  6. Trigger effects: Muzzle flash, SFX

Weapon ID Map

  • 0x01: Pistol
  • 0x02: Assault Rifle
  • 0x03: Shotgun
  • 0x04: Sawed-off Shotgun
  • 0x05: Submachine Gun
  • 0x06: Gauss Gun
  • 0x07: Mean Minigun
  • 0x08: Flamethrower
  • 0x09: Plasma Rifle
  • 0x0a: Multi-Plasma
  • 0x0b: Plasma Minigun
  • 0x0e: Plasma Shotgun
  • 0x13: Pulse Gun
  • 0x15: Ion Rifle
  • 0x16: Ion Minigun
  • 0x17: Ion Cannon
  • 0x0c: Rocket Launcher
  • 0x0d: Seeker Rockets
  • 0x11: Mini-Rocket Swarmers
  • 0x12: Rocket Minigun
  • 0x1c: Plasma Cannon
  • 0x18: Shrinkifier 5k
  • 0x19: Blade Gun
  • 0x1d: Splitter Gun
  • 0x1e: Gauss Shotgun
  • 0x1f: Ion Shotgun
  • 0x29: Plague Spreader
  • 0x2a: Bubblegun
  • 0x2b: Rainbow Gun

Weapon Modifiers

Fire Bullets Bonus

When player_fire_bullets_timer > 0, all projectiles are forced to type 0x2d (fire):
// In projectile_spawn:
if (owner_id <= -100 && player_fire_bullets_timer[owner_id] > 0.0) {
    type_id = 0x2d;  // Override to fire type
}

Perk Multipliers

Angry Reloader (perk 50):
  • On reload complete, spawn radial plasma burst
Fast Reloader (perk 46):
  • reload_time *= 0.5
Weapon Recharger (perk 47):
  • shot_cooldown *= 0.75

Entity Structures

Projectile pool layout

Perk Structures

Weapon-modifying perks

Player Struct

Complete player state documentation

Build docs developers (and LLMs) love