The action hitbox, like all abstract mechanical concepts, is a name given to us by MathOnNapkins in his US disassembly. This hitbox describes the current size and location of Link's sword and hammer attacks.
Hitboxes are very simple shapes. In fact, they're rectangles defined by 4 parameters:
x - The x-position of the top-left corner of the rectangley - The y-position of the top-left corner of the rectanglew - The length in pixels that the rectangle extends towards the right; i.e. its widthh - The length in pixels that the rectangle extends downwards; i.e. its heightFor the action hitbox specifically, x and y will be relative offsets, rather than absolute. That is, all values of x and y will need to be added to Link's x- and y-coordinates to get the actual position of the hitbox.
Hitboxes are simple shapes because this cuts down on calculation time. Even modern 3D games still use basic shapes (spheres or rectangular prisms), because they are much more efficient. These games tend to use a whole lot of them to approximate more complex shapes, but the calculations are so fast and easy that this turns out to be better than a single complicated calculation.
Within the action hitbox routine, there are several branches to determine which hitbox is used, checked in the following order:
| Direction | Parameters | |||
|---|---|---|---|---|
| x | y | w | h | |
| Up | 0 | −8 | 16 | 16 |
| Down | 0 | 16 | 16 | 16 |
| Left | −8 | 8 | 16 | 16 |
| Right | 8 | 8 | 16 | 16 |
The dashing hitbox is used whenever the dashing flag at
The spin hitbox is next, because it's dead simple, and because the next two sets need to be discussed together. This hitbox is used when bit7 of
Link's direction is completely irrelevant for the spin hitbox. This hitbox will always be 14 pixels up, 10 pixels left, and extend 44 pixels right and 45 pixels down.
| $3C | Box? |
|---|---|
| $00 | false |
| $01 | false |
| $02 | false |
| $03 | true |
| $04 | true |
| $05 | true |
| $06 | true |
| $07 | false |
| $08 | false |
| $09 | true |
| $0A | true |
| $0B | false |
| $0C | false |
| $80+ | spin |
The hammer and net hitboxes point to the same branch, which is taken when the hammer is flagged (bit 1 or unused bit 3 of
The sword control address
The parameters of the hitbox are indexed from various tables using the
If direction is irrelevant for the hammer and net, how are their hitboxes actually different?
This is where two more variables come into play. They're pretty much an additional offset to x and y, so we'll call them Ox and Oy.
These offsets are constantly being recalculated, and they depend mostly on Link's current action and the direction he's facing. So I kinda lied. Direction does matter for the hammer and net, but it's done indepedently in an entirely separate part of the code. Furthermore, this means direction matters twice for slash and poke attacks.
As for why the sword can extend the hammer hitbox, that's just because a hitbox calculation is requested after the sword has placed its values, but before the offsets are reset again.
With just that much information, the calculations are super simple:
xhitbox = xLink + xi + Oxyhitbox = yLink + yi + Oywhitbox = wihhitbox = hiWhere vi just indicates the variable came from our tables indexed by our direction and how far we are into the slash animation.
| Hammer/Net | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| I | x | y | w | h | ||||||||||||||||||
| $00 | 0 | 0 | 15 | 15 | ||||||||||||||||||
| Sword slash | ||||||||||||||||||||||
| Up | Down | Left | Right | |||||||||||||||||||
| I | x | y | w | h | I | x | y | w | h | I | x | y | w | h | I | x | y | w | h | |||
| $01 | 2 | 2 | 4 | 4 | $11 | 2 | 2 | 4 | 4 | $21 | 0 | 0 | 8 | 8 | $31 | 0 | 0 | 8 | 8 | |||
| $02 | 0 | 0 | 8 | 8 | $12 | 4 | 0 | 16 | 8 | $22 | 0 | 0 | 8 | 8 | $32 | 0 | 0 | 8 | 8 | |||
| $03 | 0 | 2 | 8 | 2 | $13 | 4 | 2 | 12 | 4 | $23 | 0 | 0 | 8 | 8 | $33 | 0 | 0 | 8 | 8 | |||
| $04 | −8 | 4 | 8 | 12 | $14 | 0 | −4 | 8 | 12 | $24 | 2 | −2 | 10 | 8 | $34 | −4 | −2 | 10 | 8 | |||
| $05 | 0 | 4 | 8 | 8 | $15 | 0 | −3 | 8 | 12 | $25 | 2 | 0 | 14 | 8 | $35 | −4 | 0 | 14 | 8 | |||
| $06 | 2 | 4 | 12 | 12 | $16 | −4 | −8 | 12 | 12 | $26 | 4 | −4 | 15 | 12 | $36 | −10 | −4 | 15 | 12 | |||
| $07 | 0 | 7 | 8 | 8 | $17 | −4 | 0 | 11 | 4 | $27 | 4 | 1 | 4 | 4 | $37 | 0 | 1 | 4 | 4 | |||
| $08 | 2 | 2 | 4 | 4 | $18 | −6 | 0 | 12 | 8 | $28 | 2 | 2 | 4 | 4 | $38 | 2 | 2 | 4 | 4 | |||
| $09 | 2 | 2 | 4 | 4 | $19 | 2 | 2 | 4 | 4 | $29 | 2 | 2 | 4 | 4 | $39 | 2 | 2 | 4 | 4 | |||
| $0A | 1 | 1 | 6 | 6 | $1A | 1 | 1 | 6 | 6 | $2A | 2 | 1 | 6 | 6 | $3A | 0 | 1 | 6 | 6 | |||
| $0B | 1 | 1 | 6 | 6 | $1B | 1 | 1 | 6 | 4 | $2B | 2 | 1 | 6 | 6 | $3B | 0 | 1 | 6 | 6 | |||
| $0C | 0 | 0 | 0 | 0 | $1C | 0 | 0 | 0 | 0 | $2C | 0 | 0 | 0 | 0 | $3C | 0 | 0 | 0 | 0 | |||
| $0D | 0 | 0 | 0 | 0 | $1D | 0 | 0 | 0 | 0 | $2D | 0 | 0 | 0 | 0 | $3D | 0 | 0 | 0 | 0 | |||
| $0E | 0 | 0 | 0 | 0 | $1E | 0 | 0 | 0 | 0 | $2E | 0 | 0 | 0 | 0 | $3E | 0 | 0 | 0 | 0 | |||
| $0F | 0 | 0 | 0 | 0 | $1F | 0 | 0 | 0 | 0 | $2F | 0 | 0 | 0 | 0 | $3F | 0 | 0 | 0 | 0 | |||
| $10 | 0 | 0 | 0 | 0 | $20 | 0 | 0 | 0 | 0 | $30 | 0 | 0 | 0 | 0 | $40 | 0 | 0 | 0 | 0 | |||
Interestingly, I didn't make any mention of how exactly a hitbox is cancelled. That's because, they kind of aren't. In the case where everything else fails the scratch space values are mostly left alone. The only one that isn't is the high byte of the x-coordinate, which will take on the value
What about the offsets for the hammer? Most of the time, these extra offsets are Oy beforehand, skipping the request and subsequent hitbox code if the value is exactly
And as one last thing: ya know that thing where you hit King Helma and then he clinks you and you see the clink at the bottom. What's that about?
At first, I thought it had to do with those offsets, since there's a routine for placing that tink spark, and they're used in the calculation.
It turns out to be even dumber.
When you hit King Helma with the hammer while outmaneuvering him, the game calls a subroutine to calculate the velocity of Link's recoil. In doing so, some leftovers are put into scratch space. And for some got dang reason, right after doing that, those same leftovers are used for the coordinates of the tink.
I think what they were going for is using the leftovers of the action hitbox routine for these coordinates, but, yeah…