|
Download docs/re-notes/weapon-system.md from nmarshall/wormz-a: direct link, hf CLI and curl.
- Browser
- Download file 19.5 kB
-
https://huggingface.co/nmarshall/wormz-a/resolve/main/docs/re-notes/weapon-system.md
- Command line
-
hf download hf://nmarshall/wormz-a/docs/re-notes/weapon-system.md
-
curl -L -o weapon-system.md https://huggingface.co/nmarshall/wormz-a/resolve/main/docs/re-notes/weapon-system.md
19.5 kB
| # Weapon System | |
| Comprehensive reference for the Worms Armageddon 3.8.1 weapon system internals. | |
| ## Overview | |
| The weapon system spans multiple subsystems: a **weapon table** defining all 71 weapons, an **ammo/delay tracker** per team/alliance, a **firing dispatch** that routes weapon activation to type-specific handlers, **CTaskMissile** objects for in-flight projectiles, and an **explosion system** for terrain damage. | |
| ### Object Relationships | |
| ```mermaid | |
| graph TD | |
| DDGame["DDGame (0x98B8 bytes)"] | |
| WT["WeaponTable<br/>DDGame+0x510"] | |
| TAS["TeamArenaState<br/>DDGame+0x4628"] | |
| WP["WeaponPanel<br/>DDGame+0x548"] | |
| CTW["CTaskWorm<br/>(per-live-worm task)"] | |
| CTM["CTaskMissile<br/>(per-projectile task)"] | |
| EXP["CreateExplosion"] | |
| LAND["PCLandscape"] | |
| DDGame --> WT | |
| DDGame --> TAS | |
| DDGame --> WP | |
| CTW -->|"FireWeapon"| CTM | |
| CTW -->|"GetAmmo/SubtractAmmo"| TAS | |
| CTM -->|"impact"| EXP | |
| EXP -->|"terrain damage"| LAND | |
| WP -->|"reads availability"| WT | |
| WP -->|"reads ammo"| TAS | |
| ``` | |
| ### Firing Sequence | |
| ```mermaid | |
| sequenceDiagram | |
| participant P as Player Input | |
| participant W as CTaskWorm | |
| participant FR as WeaponRelease | |
| participant FW as FireWeapon | |
| participant CW as CreateWeaponProjectile | |
| participant M as CTaskMissile | |
| participant E as CreateExplosion | |
| participant L as PCLandscape | |
| P->>W: Fire key pressed | |
| W->>FR: WeaponRelease(0x51C3D0)<br/>position, angle | |
| FR->>FW: FireWeapon(0x51EE60)<br/>weapon type dispatch | |
| FW->>CW: CreateWeaponProjectile(0x51E0F0) | |
| CW->>M: CTaskMissile__Constructor(0x507D10)<br/>allocate 0x40C bytes | |
| loop Every frame | |
| M->>M: PhysicsUpdate(0x508C90)<br/>gravity, wind, collision | |
| end | |
| M->>E: CreateExplosion(0x548080) | |
| E->>L: ApplyExplosion(0x57C820)<br/>terrain bitmap damage | |
| ``` | |
| ## WeaponEntry & WeaponTable | |
| ### WeaponTable (DDGame+0x510) | |
| Allocated by `InitWeaponTable` (0x53CAB0, stdcall(wrapper), RET 0x4). Called once | |
| during `CTaskGameState__vmethod_7` at game start. | |
| ``` | |
| +0x00 [WeaponEntry; 71] entries Standard weapons (0..70) | |
| Total: 71 Γ 0x1D0 = 0x80B0 bytes (no header) | |
| ``` | |
| ### WeaponEntry (0x1D0 = 464 bytes per entry) | |
| Source: `wkJellyWorm/src/CustomWeapons.h` (WeaponStruct) + InitWeaponTable analysis. | |
| ``` | |
| +0x00 *const c_char name1 Primary weapon name string | |
| +0x04 *const c_char name2 Secondary weapon name string | |
| +0x08 i32 panel_state Panel state (init: 0xFFFFFFFF). wkJellyWorm: panelRow | |
| +0x0C i32 unknown_0c Unknown | |
| +0x10 i32 defined Nonzero = weapon exists. Checked by CheckWeaponAvail. | |
| +0x14 [u8; 0x10] unknown_14 Unknown | |
| +0x24 i32 availability Init: 0xFFFFFFFF, then 0 or 1. None/SkipGo/Surrender = 0. | |
| +0x28 i32 enabled Init: 1 | |
| +0x2C [u8; 0x1A4] unknown_2c Remaining fields (opaque) | |
| ``` | |
| **InitWeaponTable per-entry initialization:** | |
| - +0x08 = 0xFFFFFFFF (panel_state) | |
| - +0x24 = 0xFFFFFFFF (availability, then overwritten per-weapon) | |
| - +0x28 = 1 (enabled) | |
| - Weapon 0 (None), 57 (SkipGo), 58 (Surrender): availability forced to 0 | |
| **Rust types:** `WeaponEntry`, `WeaponTable` in `openwa-core/src/game/weapon.rs`. | |
| ### Weapon Enum (71 entries) | |
| Defined in `openwa-core/src/game/weapon.rs`. Key weapon IDs: | |
| | ID | Hex | Name | Category | | |
| |----|-----|------|----------| | |
| | 0 | 0x00 | None | - | | |
| | 1 | 0x01 | Bazooka | Projectile | | |
| | 2 | 0x02 | HomingMissile | Projectile (homing) | | |
| | 6 | 0x06 | Grenade | Thrown | | |
| | 10 | 0x0A | Earthquake | Special (net-disabled) | | |
| | 24 | 0x18 | SuperSheep | Animal (restricted) | | |
| | 25 | 0x19 | AquaSheep | Animal (restricted) | | |
| | 37 | 0x25 | NinjaRope | Rope | | |
| | 40 | 0x28 | Teleport | Utility (immune to sudden death) | | |
| | 54 | 0x36 | Donkey | Special (disable flag) | | |
| | 55 | 0x37 | NuclearTest | Special (net-disabled) | | |
| | 56 | 0x38 | Armageddon | Special (net-disabled) | | |
| | 59 | 0x3B | SelectWorm | Action (needs >1 alive worm) | | |
| | 66 | 0x42 | Invisibility | Power-up (mode flag) | | |
| | 69 | 0x45 | DoubleTurnTime | Power-up (threshold) | | |
| ## Ammunition & Delay System | |
| ### Storage: TeamArenaState (DDGame+0x4628) | |
| Ammo and delay are stored in a flat array indexed by alliance and weapon ID. | |
| ``` | |
| Flat index = alliance_id Γ 142 + weapon_id | |
| Ammo: TeamArenaState + 0x1EB4 + flat_index Γ 4 | |
| Delay: TeamArenaState + 0x1EB4 + (flat_index + 71) Γ 4 | |
| Values: -1 = unlimited, 0 = none, >0 = count | |
| Delay: 0 = available, >0 = turns until available | |
| ``` | |
| 6 alliances Γ 142 entries (71 ammo + 71 delay) = 852 total slots. | |
| Alliance ID is read from the team's sentinel worm field at offset +0x80 | |
| (`sentinel_weapon_alliance`). | |
| ### Functions | |
| | Function | Address | Convention | Parameters | | |
| |----------|---------|------------|------------| | |
| | GetAmmo | 0x5225E0 | usercall | EAX=team_index, ESI=arena_base, EDX=weapon_id β EAX=ammo | | |
| | AddAmmo | 0x522640 | usercall | EAX=team_index, EDX=amount, stack(base, weapon_id), RET 0x8 | | |
| | SubtractAmmo | 0x522680 | usercall | EAX=team_index, ECX=arena_base, stack(weapon_id), RET 0x4 | | |
| | SubtractAmmo_v2 | 0x558E80 | fastcall | ECX=param1, EDX=CTaskTeam* | | |
| | CountAliveWorms | 0x5225A0 | usercall | EAX=team_index, ECX=arena_base β EAX=count | | |
| **GetAmmo special rules:** | |
| - Returns 0 if weapon delay > 0 (weapon on cooldown) | |
| - Sudden death (game_phase β₯ 484): returns 0 for all except Teleport (0x28) | |
| - SelectWorm (0x3B): returns 0 if team has β€1 alive worm | |
| - Game mode flag at TeamArenaState+0x2C0C can override delay checks | |
| **SubtractAmmo call sites (verified):** | |
| - `CTaskWorm__HandleMessage` (0x512C27): subtracts Teleport (0x28) ammo | |
| - `CTaskTeam_vt2__vmethod_2` (0x558443): subtracts the team's selected weapon | |
| - `FUN_0055f8c0` (3 sites): subtracts DamageX2 (0x43), CrateSpy (0x44), and others | |
| Our hook reportedly never triggered β this was because the test replay (bots) | |
| doesn't use Teleport, DamageX2, or CrateSpy. The hook implementation is correct. | |
| The second variant at 0x558E80 (fastcall) has 3 xrefs from `CTaskTeam_vt2__vmethod_2`. | |
| **Port status:** All 4 functions ported in `replacements/weapon.rs`. | |
| ## Weapon Availability | |
| ### DDGame__CheckWeaponAvail (0x53FFC0) | |
| Convention: fastcall(DDGame), ESI=weapon_id. Ported as `check_weapon_avail` | |
| in `openwa-core/src/engine/game_state_init.rs`. | |
| **Per-weapon disable rules:** | |
| | Weapon(s) | Condition | Result | | |
| |-----------|-----------|--------| | |
| | Earthquake (10), NuclearTest (55), Armageddon (56) | `net_config_2 != 0 && net_weapon_exception == 0` | Disabled in network games | | |
| | Donkey (54) | `donkey_disabled != 0` | GameInfo+0xD94C flag | | |
| | Invisibility (66) | `invisibility_mode == 0 && network_ecx == 0` | Needs network or mode flag | | |
| | DoubleTurnTime (69) | `game_version > 0xD1 && threshold > 0x7FFF` | GameInfo+0xD932 threshold | | |
| **General availability path:** | |
| 1. Check weapon table entry: name1 non-null = weapon defined | |
| 2. If `level_width_raw == 0` OR weapon defined: check super weapon rules | |
| 3. `IsSuperWeapon` (0x565960): if super and `super_weapon_allowed == 0`, disable (unless game_version < 0x2A) | |
| 4. `supersheep_restricted` (DDGame+0x7E25): gates SuperSheep/AquaSheep check | |
| 5. `aquasheep_is_supersheep` (GameInfo+0xD956): when set, AquaSheep slot becomes SuperSheep | |
| ### DDGame__IsSuperWeapon (0x565960) | |
| Convention: fastcall(weapon_id). Returns 1 for super weapons: | |
| Super weapon IDs: 16, 19, 29-31, 36, 41-42, 45-46, 49-51, 54-56, 60-61 | |
| ## FireWeapon Dispatch (0x51EE60) | |
| Convention: thiscall. `in_EAX` = weapon context structure where: | |
| - +0x30: weapon type (1-4) | |
| - +0x34: subtype for type 3 and type 4 | |
| - +0x38: subtype for type 1 and type 2 | |
| - +0x3C: parameters base (passed to sub-functions) | |
| `param_2` = DDGameWrapper pointer. Sets `param_2[0xF] = 1` on completion. | |
| ### Type 1: Projectile Weapons | |
| | Subtype | Function | Address | Weapons | | |
| |---------|----------|---------|---------| | |
| | 1 | FireWeapon__PlacedExplosive | 0x51EC80 | Dynamite, Mine, Petrol Bomb | | |
| | 2 | FireWeapon__Projectile | 0x51DFB0 | Bazooka, Mortar, Longbow | | |
| | 3 | CreateWeaponProjectile | 0x51E0F0 | Homing Missile, Homing Pigeon | | |
| | 4 | FireWeapon__Shotgun | 0x51ED90 | Shotgun, Handgun, Uzi, Minigun | | |
| ### Type 2: Rope Weapons | |
| | Subtype | Function | Address | Weapons | | |
| |---------|----------|---------|---------| | |
| | 1 | FireWeapon__RopeType1 | 0x51E1C0 | Ninja Rope (attach) | | |
| | 2 | CreateWeaponProjectile | 0x51E0F0 | Ninja Rope (projectile mode) | | |
| | 3 | FireWeapon__RopeType3 | 0x51E240 | Bungee | | |
| ### Type 3: Thrown Weapons | |
| | Subtype | Function | Address | Weapons | | |
| |---------|----------|---------|---------| | |
| | (all) | FireWeapon__GrenadeMortar | 0x51E2C0 | Grenade, Cluster Bomb, Banana Bomb, Holy Grenade | | |
| ### Type 4: Special Weapons | |
| | Subtype | Function | Address | Description | | |
| |---------|----------|---------|-------------| | |
| | 1 | vtable[0xE](0x6C) | (indirect) | Blowtorch | | |
| | 2 | FireWeapon__Special_Type2 | 0x51E3E0 | Pneumatic Drill | | |
| | 3 | FireWeapon__Special_Type3 | 0x51E350 | Girder | | |
| | 4 | vtable[0xE](0x6D) | (indirect) | Baseball Bat | | |
| | 5 | vtable[0xE](0x75) | (indirect) | Fire Punch | | |
| | 6 | vtable[0xE](0x70) | (indirect) | Dragon Ball | | |
| | 8 | vtable[0xE](0x6E) | (indirect) | Kamikaze | | |
| | 9 | FireWeapon__Special_Type9 | 0x51E480 | Prod | | |
| | 10 | FireWeapon__Special_Type10 | 0x51E710 | Air Strike | | |
| | 11 | vtable[0xE](0x71) | (indirect) | Scales of Justice | | |
| | 13 | FireWeapon__Special_Type13 | 0x51E5C0 | Napalm Strike | | |
| | 14 | FireWeapon__Special_Type14 | 0x51E670 | Mail/Mine/Mole Strike | | |
| | 16 | FUN_0051EB00 (conditional) | 0x51EB00 | Teleport (checks FUN_516930 first) | | |
| | 17 | FireWeapon__Special_Type17 | 0x51E920 | Freeze | | |
| | 18 | vtable[0xE](0x72) | (indirect) | Suicide Bomber | | |
| | 19 | FireWeapon__Special_Type19 | 0x51E8C0 | Skip Go | | |
| | 20 | FireWeapon__Special_Type20 | 0x51E600 | Surrender | | |
| | 21 | FireWeapon__Special_Type21 | 0x51EBE0 | Select Worm | | |
| | 22 | FireWeapon__Special_Type22 | 0x51EC30 | Jet Pack | | |
| | 23 | vtable[0xE](0x78) | (indirect) | Magic Bullet | | |
| | 24 | FireWeapon__Special_Type24 | 0x51EA60 | Low Gravity / Fast Walk | | |
| ## CTaskMissile (0x40C bytes) | |
| Extends CGameTask (0xFC base). Represents an in-flight projectile. | |
| ``` | |
| Constructor: 0x507D10 (stdcall, 4 params) | |
| Vtable: 0x664438 | |
| Class type: 0x0B | |
| Allocation: 0x40C bytes via wa_malloc | |
| ``` | |
| ### Structure Layout | |
| ``` | |
| +0x000 CGameTask base (0xFC bytes) | |
| +0x084 speed_x Fixed16.16 horizontal velocity | |
| +0x088 speed_y Fixed16.16 vertical velocity | |
| +0x090 pos_x Fixed16.16 world X | |
| +0x094 pos_y Fixed16.16 world Y | |
| +0x128 u32 launch_seed Position-derived seed | |
| +0x12C u32 slot_id Object pool slot index | |
| +0x130 spawn_params [11 DWORDs = 44 bytes] | |
| [0] owner_id Team that fired | |
| [2-3] spawn_x/y Fixed16.16 launch position | |
| [4-5] speed_x/y Fixed16.16 initial velocity | |
| [8] pellet_index Cluster volley index | |
| +0x15C weapon_data [94 DWORDs = 376 bytes] | |
| [0x0F] gravity_pct 100 = 1.0Γ gravity | |
| [0x10] bounce_pct Bounce coefficient | |
| [0x12] friction_pct Friction coefficient | |
| [0x1A] missile_type 2=Standard, 3=Homing, 4=Sheep, 5=Cluster | |
| [0x1C] render_timer Fuse countdown | |
| +0x2D4 render_data [42 DWORDs = 168 bytes] | |
| Physics parameters (shifted copy of weapon_data) | |
| +0x3C8 i32 direction -1 (left) or +1 (right) | |
| ``` | |
| ### Missile Type Enum | |
| | Value | Type | Behavior | | |
| |-------|------|----------| | |
| | 2 | Standard | Straight trajectory with gravity | | |
| | 3 | Homing | Tracks target position | | |
| | 4 | Sheep | Walking behavior on terrain | | |
| | 5 | Cluster | Splits into sub-munitions on impact | | |
| ### Key Methods | |
| | Method | Address | Description | | |
| |--------|---------|-------------| | |
| | Constructor | 0x507D10 | Initialize physics, copy weapon data from scheme | | |
| | Init | 0x508640 | Reset physics state | | |
| | PhysicsUpdate | 0x508C90 | Per-frame trajectory, gravity, wind, collision | | |
| | HandleMessage | 0x50B400 | Event processing (detonation triggers, etc.) | | |
| | Free | 0x508330 | Cleanup and pool return | | |
| | vt12 | 0x508C70 | Vtable slot 12 | | |
| | vt18_GetField130 | 0x50BFA0 | Returns spawn_params pointer | | |
| ### Missile Count Limit | |
| DDGame+0x72A4 tracks active missile count. `CreateWeaponProjectile` checks: | |
| - If count + 7 < 0x2BD (701): create missile normally | |
| - If exceeded and game_version < 0x3C: set error code 6 at DDGame+0x4624, load | |
| string resource 0x70F as error message at DDGame+0x7EF4 | |
| - Otherwise: silently fail | |
| ## Projectile Creation (0x51E0F0) | |
| `CreateWeaponProjectile`: thiscall(this=context, param_2=missile_params, param_3=launch_params). | |
| 1. Read DDGame via `this+0x2C` (CTask.ddgame field) | |
| 2. Check missile count limit (DDGame+0x72A4 + 7 < 0x2BD) | |
| 3. Call `FUN_004FDF90(this)` β pool slot allocator | |
| 4. `wa_malloc(0x40C)` + `memset(0, 0x3EC)` | |
| 5. `CTaskMissile__Constructor(slot, missile_params, launch_params)` | |
| 6. Return allocated missile pointer | |
| ## Explosion & Terrain Damage | |
| | Function | Address | Convention | Description | | |
| |----------|---------|------------|-------------| | |
| | CreateExplosion | 0x548080 | usercall(ESI=context) | Spawns explosion task via pool allocator + vtable dispatch | | |
| | PCLandscape_ApplyExplosion | 0x57C820 | (unknown) | Modifies terrain bitmap, creates crater | | |
| CreateExplosion is a thin wrapper: allocates via `FUN_004FDF90`, then calls | |
| `vtable[2]()` on the allocated object. The actual explosion logic (radius, | |
| damage, terrain removal) lives in the explosion task's ProcessFrame. | |
| ## Weapon Panel UI | |
| | Function | Address | Description | | |
| |----------|---------|-------------| | |
| | DDGame__InitWeaponPanel_Maybe | 0x567770 | Initialize panel structures and availability grid | | |
| | PrepareWeaponPanel | 0x568220 | Main panel renderer (~2000 lines). Iterates weapons by row, checks availability, renders tiles | | |
| | WeaponPanelDrawTile | 0x567AA0 | Render individual weapon tile | | |
| | WeaponPanelDescription | 0x567F80 | Show ammo/delay info on hover | | |
| | WeaponPanelCheckClick | 0x5690B0 | Handle weapon selection clicks | | |
| **Panel geometry:** 5 columns Γ 13 rows. Each tile is 29px wide. | |
| Custom weapons (wkJellyWorm): dynamic columns up to 256 weapons. | |
| ## Weapon Crate System | |
| - `CTaskCrate__Constructor` (0x502490): creates a weapon crate in the game world | |
| - Crate probability per weapon defined in scheme (`WeaponSettings.crate_probability`, 0-100%) | |
| - Crate drops award random weapons weighted by probability | |
| ## Scheme Integration | |
| Weapon configuration flows from `.wsc` scheme files into GameInfo, then into the | |
| weapon table and ammo arrays at game start. | |
| ### WeaponSettings (4 bytes per weapon) | |
| ``` | |
| +0x00 u8 ammo 0=none, 1-10=count, 0x80+=infinite | |
| +0x01 u8 power 0-20 (max varies per weapon) | |
| +0x02 u8 delay Turn cooldown before available | |
| +0x03 u8 crate_probability 0-100 percentage | |
| ``` | |
| ### Scheme Formats | |
| | Version | Payload | Weapons | | |
| |---------|---------|---------| | |
| | V1 | 0xD8 bytes | 45 standard weapons | | |
| | V2 | 0x124 bytes | V1 + 19 super weapons | | |
| | V3 | 0x192 bytes | V2 + 110 extended options (physics tweaks) | | |
| **Port status:** Scheme parsing fully ported in `openwa-core/src/game/scheme.rs` | |
| (10 hooks in `replacements/scheme.rs`). | |
| ## Complete Function Address Table | |
| ### Weapon Table & Initialization | |
| | Function | Address | Convention | Port Status | | |
| |----------|---------|------------|-------------| | |
| | InitWeaponTable | 0x53CAB0 | stdcall(wrapper), RET 0x4 | Hooked (passthrough) | | |
| | DDGame__CheckWeaponAvail | 0x53FFC0 | fastcall(DDGame) | **Ported** | | |
| | DDGame__IsSuperWeapon | 0x565960 | fastcall(weapon_id) | **Ported** | | |
| | DDGame__LoadHudAndWeaponSprites | 0x53D0E0 | stdcall(wrapper, ...) | Bridge call | | |
| ### Ammo System | |
| | Function | Address | Convention | Port Status | | |
| |----------|---------|------------|-------------| | |
| | GetAmmo | 0x5225E0 | usercall(EAX,ESI,EDX) | **Ported** | | |
| | AddAmmo | 0x522640 | usercall(EAX,EDX,stack), RET 0x8 | **Ported** | | |
| | SubtractAmmo | 0x522680 | usercall(EAX,ECX,stack), RET 0x4 | **Ported** (may not trigger) | | |
| | SubtractAmmo_v2 | 0x558E80 | fastcall(ECX,EDX) | Unported | | |
| | CountAliveWorms | 0x5225A0 | usercall(EAX,ECX) | **Ported** | | |
| ### Firing & Projectiles | |
| | Function | Address | Convention | Port Status | | |
| |----------|---------|------------|-------------| | |
| | WeaponRelease | 0x51C3D0 | thiscall(CTaskWorm*, ...) | Unported | | |
| | FireWeapon | 0x51EE60 | thiscall, EAX=weapon_ctx | Unported | | |
| | CreateWeaponProjectile | 0x51E0F0 | thiscall(context, params, launch) | Unported | | |
| | CTaskMissile__Constructor | 0x507D10 | stdcall, 4 params | Unported | | |
| | CTaskMissile__PhysicsUpdate | 0x508C90 | (unknown) | Unported | | |
| | CTaskMissile__HandleMessage | 0x50B400 | thiscall | Unported | | |
| | CreateExplosion | 0x548080 | usercall(ESI=context) | Unported | | |
| | PCLandscape_ApplyExplosion | 0x57C820 | (unknown) | Unported | | |
| ### Fire Dispatch Targets | |
| | Function | Address | Weapon Category | | |
| |----------|---------|-----------------| | |
| | FireWeapon__Projectile | 0x51DFB0 | Bazooka-class | | |
| | FireWeapon__PlacedExplosive | 0x51EC80 | Dynamite/Mine/Petrol | | |
| | FireWeapon__Shotgun | 0x51ED90 | Shotgun/Handgun/Uzi | | |
| | FireWeapon__RopeType1 | 0x51E1C0 | Ninja Rope attach | | |
| | FireWeapon__RopeType3 | 0x51E240 | Bungee | | |
| | FireWeapon__GrenadeMortar | 0x51E2C0 | Grenade/Cluster/Banana | | |
| | FireWeapon__Special_Type2 | 0x51E3E0 | Pneumatic Drill | | |
| | FireWeapon__Special_Type3 | 0x51E350 | Girder | | |
| | FireWeapon__Special_Type9 | 0x51E480 | Prod | | |
| | FireWeapon__Special_Type10 | 0x51E710 | Air Strike | | |
| | FireWeapon__Special_Type13 | 0x51E5C0 | Napalm Strike | | |
| | FireWeapon__Special_Type14 | 0x51E670 | Mail/Mine/Mole Strike | | |
| ### Weapon Panel | |
| | Function | Address | Convention | Port Status | | |
| |----------|---------|------------|-------------| | |
| | DDGame__InitWeaponPanel_Maybe | 0x567770 | thiscall | Unported | | |
| | PrepareWeaponPanel | 0x568220 | cdecl | Unported | | |
| | WeaponPanelDrawTile | 0x567AA0 | (unknown) | Unported | | |
| | WeaponPanelDescription | 0x567F80 | (unknown) | Unported | | |
| | WeaponPanelCheckClick | 0x5690B0 | (unknown) | Unported | | |
| ### Scheme | |
| | Function | Address | Convention | Port Status | | |
| |----------|---------|------------|-------------| | |
| | Scheme__CheckWeaponLimits | 0x4D50E0 | stdcall | **Ported** | | |
| | Scheme__ValidateExtendedOptions | 0x4D5110 | stdcall | **Ported** | | |
| | Scheme__ReadFile | 0x4D3890 | stdcall | **Ported** | | |
| ## Port Recommendations | |
| ### Already Done | |
| - Weapon enum and struct types (`WeaponEntry`, `WeaponTable`) | |
| - Ammo system (4 hooks: GetAmmo, AddAmmo, SubtractAmmo, CountAliveWorms) | |
| - Availability checks (2 hooks: CheckWeaponAvail, IsSuperWeapon) | |
| - Scheme parsing (10 hooks covering all scheme I/O) | |
| - Team/worm state queries (8 hooks in replacements/team.rs) | |
| ### Next Priority | |
| 1. **InitWeaponTable internals** β populate WeaponEntry fields from scheme data | |
| 2. **SubtractAmmo investigation** β verify hook triggers, check v2 variant | |
| 3. **Weapon panel init** β DDGame__InitWeaponPanel_Maybe (self-contained) | |
| ### Medium Term | |
| 4. **FireWeapon dispatch** β the type/subtype routing logic | |
| 5. **CreateWeaponProjectile** β missile allocation and pool management | |
| 6. **WeaponRelease** β coordinate transform and launch logic | |
| ### Long Term | |
| 7. **CTaskMissile physics** β gravity, wind, collision, homing AI | |
| 8. **Individual weapon behaviors** β each Fire__* handler | |
| 9. **Explosion system** β terrain damage, damage calculation | |
| 10. **Weapon panel rendering** β PrepareWeaponPanel (~2000 lines) | |