File size: 6,629 Bytes
e454eb7 35a783f e454eb7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | # Task Hierarchy - Worms Armageddon 3.8.1
## Overview
WA uses a hierarchical task/entity system. All game objects inherit from `CTask`,
which forms a tree via parent/children pointers. Tasks communicate through a
message passing system (see `TaskMessage` enum).
## Class Hierarchy
```
CTask (base) vtable: 0x669F8C ctor: 0x5625A0
βββ CGameTask vtable: 0x6641F8 ctor: 0x4FED50
β βββ CTaskWorm ctor: 0x50BFB0
β βββ CTaskOldWorm ctor: 0x51FEB0
β βββ CTaskMissile ctor: 0x507D10
β βββ CTaskArrow ctor: 0x4FE130
β βββ CTaskMine ctor: 0x506660
β βββ CTaskCanister ctor: 0x501A80
β βββ CTaskCrate ctor: 0x502490
β βββ CTaskOilDrum ctor: 0x504AF0
β βββ CTaskCross ctor: 0x5045C0
β βββ CTaskLand ctor: 0x505440
βββ CTaskFilter ctor: 0x54F3D0
βββ CTaskTeam ctor: 0x555BB0
βββ CTaskTurnGame ctor: 0x55B280
βββ CTaskAirStrike ctor: 0x5553C0
βββ CTaskDirt ctor: 0x54EDC0
βββ CTaskFlame ctor: 0x54F0F0
βββ CTaskFire ctor: 0x54F4C0
βββ CTaskGirder (was CTaskFireBall) ctor: 0x550890
βββ CTaskGas ctor: 0x554750
βββ CTaskSmoke ctor: 0x5551D0
βββ CTaskCloud ctor: 0x5482E0
βββ CTaskSeaBubble ctor: 0x554FE0
βββ CTaskScoreBubble ctor: 0x554CA0
βββ CTaskCPU ctor: 0x5485D0
βββ CTaskSpriteAnimation ctor: 0x5466C0
```
Note: Not all tasks are confirmed to inherit from CGameTask. The hierarchy
above needs further verification via Ghidra analysis of each constructor.
## CTask vtable (0x669F8C)
| Index | Offset | Address | Name (from wkJellyWorm) |
|-------|--------|------------|-------------------------|
| 0 | 0x00 | 0x562710 | vtable0 (init?) |
| 1 | 0x04 | 0x562620 | Free |
| 2 | 0x08 | 0x562F30 | HandleMessage |
| 3 | 0x0C | 0x5613D0 | unknown |
| 4 | 0x10 | 0x5613D0 | unknown (=vt3) |
| 5 | 0x14 | 0x562FA0 | unknown |
| 6 | 0x18 | 0x563000 | unknown |
| 7 | 0x1C | 0x563210 | ProcessFrame |
Note: wkJellyWorm says 7 methods but we see 8 entries. The 8th may be
the start of CGameTask's extended vtable region, or the count was off by one.
## CGameTask vtable (0x6641F8)
First 3 entries override CTask:
| Index | Offset | Address | Name |
|-------|--------|------------|-------------------------|
| 0 | 0x00 | 0x4FF1C0 | vtable0 override |
| 1 | 0x04 | 0x4FEF10 | Free override |
| 2 | 0x08 | 0x4FF280 | HandleMessage override |
| 3 | 0x0C | 0x5613D0 | (inherited from CTask) |
| 4 | 0x10 | 0x5613D0 | (inherited from CTask) |
| 5 | 0x14 | 0x562FA0 | (inherited from CTask) |
| 6 | 0x18 | 0x563000 | (inherited from CTask) |
| 7 | 0x1C | 0x4FF720 | CGameTask-specific |
| 8 | 0x20 | 0x4FFED0 | CGameTask-specific |
| 9 | 0x24 | 0x500070 | CGameTask-specific |
| 10 | 0x28 | 0x500080 | CGameTask-specific |
| 11 | 0x2C | 0x5000E0 | CGameTask-specific |
| 12 | 0x30 | 0x500380 | CGameTask-specific |
| 13 | 0x34 | 0x500360 | CGameTask-specific |
| 14 | 0x38 | 0x4FE060 | CGameTask-specific |
| 15 | 0x3C | 0x500CC0 | CGameTask-specific |
| 16 | 0x40 | 0x592A50 | CGameTask-specific |
| 17 | 0x44 | 0x500090 | CGameTask-specific |
| 18 | 0x48 | 0x545780 | CGameTask-specific |
| 19 | 0x4C | 0x4AA060 | CGameTask-specific |
CGameTask also has a secondary vtable at object offset 0xE8, pointing to 0x669CF8.
## CTask memory layout (0x30 bytes)
```
Offset Size Field
0x00 4 vtable pointer
0x04 4 parent (CTask*)
0x08 4 unknown (set to 0x10 in ctor)
0x0C 4 children.max_size (init 0)
0x10 4 children.unk4 (init 0)
0x14 4 children.size
0x18 4 children.data_ptr (allocated 0x60 bytes, zeroed 0x40)
0x1C 4 children.hash_list
0x20 4 class_type (ClassType enum)
0x24 12 unknown padding
```
## CGameTask memory layout (0xEC bytes)
Extends CTask at offset 0x00. Key fields discovered from constructor:
```
Offset Size Field
0x00 0x30 CTask base
0x20 4 class_type (set to 3 = GameCollisionTask in ctor)
0x2C 4 param_3 from ctor
0x30 4 param_3 (weapon id?)
0x38 4 param_4
0x3C 4 unknown
...
0x4C 4 = 0x10000 (Fixed 1.0)
0x50 4 = 0x100000 (Fixed 16.0)
0x54 4 = 0xCCCC (Fixed ~0.8)
0x58 4 = 0x10000 (Fixed 1.0)
0x5C 4 = 0
0x60 4 = 0x10000 (Fixed 1.0)
0x64 4 = 0x20000 (Fixed 2.0)
0x68 4 = 0xF333 (Fixed ~0.95)
...
0x84 4 pos_x (Fixed)
0x88 4 pos_y (Fixed)
0x8C 4 = 0x10000 (Fixed 1.0, scale?)
0x90 4 speed_x (Fixed)
0x94 4 speed_y (Fixed)
...
0xCC 4 = 0x10000 (Fixed 1.0)
0xD8 1 byte flag (init 0)
0xD9 1 byte flag (init 0)
0xE0 4 unknown (init 0)
0xE4 4 unknown (init 0)
0xDC 4 unknown (init 0)
0xE8 4 secondary vtable pointer -> 0x669CF8
```
## Physics defaults from CGameTask constructor
Several fixed-point constants are set in the constructor, likely physics defaults:
- `0x10000` = 1.0 (appears at many offsets β scale factors, gravity?)
- `0x100000` = 16.0 (mass? terminal velocity?)
- `0xCCCC` β 0.8 (friction? damping?)
- `0x20000` = 2.0
- `0xF333` β 0.95 (air resistance?)
- `0x3333` β 0.2
- `0x4CCC` β 0.3
- `0xFEB8` β 0.995
- `0x9999` β 0.6
- `0x3AE1` β 0.23
- `0xFC000000` = -67108864 (large negative, possibly a boundary?)
|