lotr2_battle_figure — combat unit instance#
Header: lotr2_battle_figure.h
Summary#
Each active soldier stack or siege engine on the battlefield is a battle figure in a fixed array (stride 0x1b0, up to 80 slots). The per-type tick handler table PTR_LAB_004f46a0 dispatches once per frame per live figure.
- Confidence: likely (partial — key combat fields evidenced)
- Stride: 0x1b0 (432 bytes)
- Max index: 0x50 (80 figures; index 0 unused)
Stat tables: lotr2_unit_stats.md. Module: combat MODULE.
Unit type enum#
| ID | Name | Tick handler |
|---|---|---|
| 0 | Peasant | lotr2_combat_tick_peasant @ 0x00493754 |
| 1 | Archer | lotr2_combat_tick_archer @ 0x0049382d |
| 2 | Swordsman | lotr2_combat_tick_swordsman @ 0x00493906 |
| 3 | Maceman | lotr2_combat_tick_maceman @ 0x004939df |
| 4 | Pikesman | lotr2_combat_tick_pikesman @ 0x00493ab8 |
| 5 | Crossbowman | lotr2_combat_tick_crossbowman @ 0x00493b91 |
| 6 | Knight | lotr2_combat_tick_knight @ 0x00493c6a |
| 7 | Catapult | lotr2_combat_tick_catapult @ 0x00493d43 |
| 8 | Battering ram | lotr2_combat_tick_battering_ram @ 0x00493e25 |
| 9 | Siege tower | lotr2_combat_tick_siege_tower @ 0x00493f07 |
| 10 | Moat / ladder | lotr2_combat_tick_moat_diggers @ 0x00493fe9 |
Names for 7–10 are likely pending l2.eng.
Key offset table#
| Offset | Field | Ghidra symbol | Description |
|---|---|---|---|
| +0x0A | unit_type |
lotr2_combat_figure_unit_type |
lotr2_unit_type 0–10 |
| +0x2A | walk_counter |
lotr2_combat_figure_walk_counter |
Tile walk progress (completes at 0x11) |
| +0x192 | damage_acc |
lotr2_combat_figure_damage_acc |
100-point casualty pool per soldier |
| +0x194 | attack_damage |
lotr2_combat_figure_attack_damage |
Melee hit damage (from 0x004f4c18) |
| +0x196 | counter_atk_damage |
lotr2_combat_figure_counter_atk |
Retaliation bonus to attacker |
| +0x198 | head_count |
lotr2_combat_figure_head_count |
Stack size / crew count |
| +0x19B | formation_tier |
lotr2_combat_figure_formation_tier |
0=largest … 3=smallest |
| +0x09 | side |
lotr2_combat_figure_side |
Attacker/defender side byte |
| +0x1C | tile_index |
lotr2_combat_figure_tile_index |
Index into 80×80 battle tile grid |
| +0x31 | state |
lotr2_combat_figure_state |
State-machine byte; indexes PTR_LAB_004f46d0 |
| +0x186 | target_slot |
lotr2_combat_figure_target_slot |
Melee/ranged target figure index |
| +0x19E | projectile_damage |
lotr2_combat_figure_projectile_damage |
Siege / ranged base damage |
Evidence#
| Claim | Source |
|---|---|
| Stride 0x1b0 | param_1 * 0x1b0 on all figure field accesses |
unit_type at +0x0A |
Written at spawn: (&DAT_00549552)[idx * 0x1b0] = param_1 |
| Attack damage table lookup | lotr2_combat_update_attack_damage // was thunk_FUN_00492cb1 |
| Melee hit applies attack_damage to defender damage_acc | lotr2_combat_apply_melee_hit // was thunk_FUN_004a48c6 |
| damage_acc > 99 → head_count-- | Same function @ 0x004a48c6 |
| Current figure index | lotr2_combat_cur_figure // was DAT_0059c32c |
Related globals#
| Symbol | Role |
|---|---|
lotr2_combat_cur_figure |
Loop index 1..0x50 during battle tick |
lotr2_combat_form_tier_thresh_* |
Formation size breakpoints from 0x004f4b28 |
Open questions#
- Full 432-byte layout beyond offsets listed above
- Exact mapping of debug labels (
walking,mov_straff,firing) to offsets