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
|
/**
* @file moblinSpear.c
* @ingroup Projectiles
*
* @brief Moblin Spear Projectile
*/
#include "enemy.h"
#include "sound.h"
#include "projectile.h"
#include "entity.h"
#include "physics.h"
typedef struct {
s8 offsetX;
s8 offsetY;
u8 width;
u8 height;
} HitboxChange;
void MoblinSpear_OnTick(Entity* this);
void MoblinSpear_OnCollision(Entity* this);
void MoblinSpear_Init(Entity* this);
void MoblinSpear_Action1(Entity* this);
void MoblinSpear(Entity* this) {
static void (*const MoblinSpear_Functions[])(Entity*) = {
MoblinSpear_OnTick, MoblinSpear_OnCollision, DeleteEntity, DeleteEntity, DeleteEntity,
};
MoblinSpear_Functions[GetNextFunction(this)](this);
}
void MoblinSpear_OnTick(Entity* this) {
static void (*const MoblinSpear_Actions[])(Entity*) = {
MoblinSpear_Init,
MoblinSpear_Action1,
};
MoblinSpear_Actions[this->action](this);
}
void MoblinSpear_OnCollision(Entity* this) {
u8 tmp;
if (this->contactFlags == CONTACT_NOW) {
this->iframes = 0x10;
this->knockbackDuration = 0xc;
this->knockbackSpeed = 0x180;
this->parent->contactFlags = this->contactFlags;
}
tmp = this->iframes;
if ((tmp & 0x80) != 0) {
this->parent->iframes = tmp;
} else {
this->parent->iframes = -tmp;
}
this->parent->knockbackDuration = this->knockbackDuration;
this->parent->knockbackSpeed = this->knockbackSpeed;
this->parent->knockbackDirection = this->knockbackDirection;
this->knockbackDuration = 0;
}
void MoblinSpear_Init(Entity* this) {
if (AllocMutableHitbox(this) != NULL) {
this->action = 1;
}
}
void MoblinSpear_Action1(Entity* this) {
static const HitboxChange gUnk_0812966C[] = {
{ 6, 11, 2, 4 }, { -12, 2, 3, 3 }, { -13, -15, 1, 2 }, { 5, 12, 1, 3 }, { 7, 10, 1, 2 },
{ 8, 9, 1, 3 }, { 7, 10, 1, 2 }, { -22, 1, 4, 2 }, { -12, 1, 3, 2 }, { -6, 2, 4, 2 },
{ -12, 1, 3, 2 }, { -1, -19, 1, 1 }, { -4, -19, 1, 1 }, { -4, -20, 1, 1 }, { -4, -19, 1, 1 },
{ 6, 9, 1, 2 }, { 6, 10, 1, 2 }, { 6, 9, 1, 2 }, { 6, 10, 1, 2 }, { -29, -11, 3, 2 },
{ -29, -9, 3, 2 }, { -29, -11, 3, 2 }, { -29, -9, 3, 2 }, { -5, -25, 1, 2 }, { -5, -24, 1, 2 },
{ -5, -25, 1, 2 }, { -5, -24, 1, 2 }, { 7, 12, 1, 2 }, { 7, 11, 1, 2 }, { -12, 3, 3, 1 },
{ -12, 2, 3, 1 }, { -13, -16, 1, 2 }, { -13, -15, 1, 2 },
};
u8 frames;
Entity* parent;
u32 tmp;
// const HitboxChange* a;
// TODO: Copying a members using HitboxChange members addresses them directly using [r2, 0x1]
// while the assembly increases the pointer after every copy.
// Not sure how to make this more readable.
const u8* a;
parent = this->parent;
if (parent == NULL) {
DeleteThisEntity();
}
if (parent->next == NULL) {
DeleteThisEntity();
}
frames = parent->frame * 4;
a = (u8*)&gUnk_0812966C[frames / 4];
this->hitbox->offset_x = *a++;
if (parent->frameSpriteSettings == 0x40) {
this->hitbox->offset_x = -this->hitbox->offset_x;
}
this->hitbox->offset_y = *a++;
this->hitbox->width = *a++;
this->hitbox->height = *a++;
if (parent->confusedTime != 0) {
if ((this->flags & ENT_COLLIDE) != 0) {
COLLISION_OFF(this);
}
} else {
if ((this->flags & ENT_COLLIDE) == 0) {
COLLISION_ON(this);
}
}
}
|