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
|
#include "entity.h"
#include "collision.h"
#include "enemy.h"
#include "functions.h"
#include "object.h"
extern void (*const gArrowProjectile[])(Entity*);
extern void (*const gArrowProjectileActions[])(Entity*);
typedef struct {
u8 flipX;
u8 flipY;
u8 animIndex;
u8 unk;
const Hitbox* hitbox;
} struct_081299F8;
extern const struct_081299F8 gUnk_081299F8[];
void sub_080A9488(Entity*);
void sub_080A94C0(Entity*, u32);
void ArrowProjectile(Entity* this) {
gArrowProjectile[GetNextFunction(this)](this);
}
void ArrowProjectile_OnTick(Entity* this) {
gArrowProjectileActions[this->action](this);
}
void sub_080A9334(Entity* this) {
if ((this->contactFlags & 0x80) != 0) {
if ((this->contactFlags & 0x3f) != 0) {
ModHealth(-2);
sub_080A9488(this);
this->knockbackDuration = 0;
this->iframes = 0;
} else {
DeleteThisEntity();
}
}
}
void ArrowProjectile_Init(Entity* this) {
this->action = 1;
this->spriteSettings.draw = 1;
COLLISION_OFF(this);
this->timer = 106;
this->subtimer = 0;
this->zVelocity = Q_16_16(10.0 / 256.0);
sub_080A94C0(this, this->type);
}
void ArrowProjectile_Action1(Entity* this) {
Entity* parent = this->parent;
if ((parent == NULL) || (parent->next == NULL)) {
DeleteThisEntity();
}
if (this->subtimer != 0) {
DeleteThisEntity();
}
if (parent->subtimer != 0) {
this->action = 2;
COLLISION_ON(this);
parent->child = NULL;
SoundReq(SFX_FC);
}
}
void ArrowProjectile_Action2(Entity* this) {
if (this->collisions != COL_NONE) {
this->action = 3;
COLLISION_OFF(this);
this->timer = 32;
InitializeAnimation(this, this->animIndex + 2);
EnqueueSFX(SFX_18A);
LinearMoveUpdate(this);
} else if (--this->timer == 0) {
DeleteThisEntity();
}
ProcessMovement3(this);
}
void ArrowProjectile_Action3(Entity* this) {
if (--this->timer == 0) {
DeleteThisEntity();
}
GetNextFrame(this);
}
void ArrowProjectile_Action4(Entity* this) {
if (GravityUpdate(this, Q_8_8(40.0)) == 0) {
CreateDust(this);
DeleteThisEntity();
} else {
if (--this->timer == 0) {
this->timer = 2;
this->animationState = (this->animationState + 1) & 3;
sub_080A94C0(this, this->animationState);
}
}
}
void sub_080A9488(Entity* this) {
this->action = 4;
COLLISION_OFF(this);
this->timer = 2;
this->zVelocity = Q_16_16(1.5);
this->animationState = (this->knockbackDirection & 0x18) >> 3;
EnqueueSFX(SFX_METAL_CLINK);
sub_080A94C0(this, this->animationState);
}
void sub_080A94C0(Entity* this, u32 animationState) {
const struct_081299F8* entry = &gUnk_081299F8[animationState];
this->spriteSettings.flipX = entry->flipX;
this->spriteSettings.flipY = entry->flipY;
this->animIndex = entry->animIndex;
this->hitbox = (Hitbox*)entry->hitbox;
InitializeAnimation(this, this->animIndex);
}
void (*const gArrowProjectile[])(Entity*) = {
ArrowProjectile_OnTick, sub_080A9334, DeleteEntity, DeleteEntity, DeleteEntity,
};
void (*const gArrowProjectileActions[])(Entity*) = {
ArrowProjectile_Init, ArrowProjectile_Action1, ArrowProjectile_Action2,
ArrowProjectile_Action3, ArrowProjectile_Action4,
};
extern const Hitbox gUnk_08129A18;
extern const Hitbox gUnk_08129A20;
const struct_081299F8 gUnk_081299F8[] = {
{ 0, 0, 1, 0, &gUnk_08129A20 },
{ 1, 0, 0, 0, &gUnk_08129A18 },
{ 0, 1, 1, 0, &gUnk_08129A20 },
{ 0, 0, 0, 0, &gUnk_08129A18 },
};
const Hitbox gUnk_08129A18 = { 0, 0, { 4, 0, 0, 0 }, 6, 4 };
const Hitbox gUnk_08129A20 = { 0, 0, { 0, 0, 0, 4 }, 4, 6 };
|