mirror of
https://github.com/zeldaret/tmc
synced 2026-07-08 06:30:33 -04:00
323 lines
8.3 KiB
C
323 lines
8.3 KiB
C
#define NENT_DEPRECATED
|
|
#include "entity.h"
|
|
#include "enemy.h"
|
|
#include "hitbox.h"
|
|
#include "player.h"
|
|
#include "physics.h"
|
|
#include "room.h"
|
|
#include "asm.h"
|
|
#include "object.h"
|
|
|
|
typedef struct {
|
|
Entity base;
|
|
u8 filler[0xc];
|
|
u8 unk_74;
|
|
u8 unk_75;
|
|
u16 unk_76;
|
|
} DustEntity;
|
|
|
|
typedef struct {
|
|
s8 unk_0;
|
|
s8 unk_1;
|
|
u8 unk_2;
|
|
u8 unk_3;
|
|
u8 unk_4;
|
|
} PACKED DustHeapItem;
|
|
|
|
typedef struct {
|
|
u8 unk_0;
|
|
DustHeapItem items[0];
|
|
} PACKED DustHeap;
|
|
|
|
#define HEAP ((DustHeap*)super->myHeap)
|
|
|
|
#ifdef EU
|
|
#define DUST_SPRITE_INDEX 0x1ea
|
|
#else
|
|
#define DUST_SPRITE_INDEX 0x1eb
|
|
#endif
|
|
|
|
void Dust_OnTick(DustEntity*);
|
|
void Dust_OnCollision(DustEntity*);
|
|
void Dust_OnGrabbed(DustEntity*);
|
|
void sub_080441E0(DustEntity*);
|
|
void sub_080442A0(DustEntity*);
|
|
void sub_080441CC(DustEntity*);
|
|
void sub_080441C4(DustEntity*);
|
|
void sub_080441BC(DustEntity*);
|
|
void sub_08044310(DustEntity*);
|
|
void sub_080445C0(DustEntity*);
|
|
void sub_080442BC(DustEntity*);
|
|
void sub_08044498(DustEntity*);
|
|
void sub_08044550(DustEntity*);
|
|
|
|
extern void* sub_080AD8F0(u32, u32);
|
|
|
|
extern const s8 gUnk_08126EE4[];
|
|
|
|
void (*const Dust_Functions[])(Entity*) = {
|
|
(EntityActionPtr)Dust_OnTick, (EntityActionPtr)Dust_OnCollision, GenericKnockback, GenericDeath, GenericConfused,
|
|
(EntityActionPtr)Dust_OnGrabbed,
|
|
};
|
|
|
|
void Dust(Entity* this) {
|
|
Dust_Functions[GetNextFunction(this)](this);
|
|
}
|
|
|
|
void Dust_OnTick(DustEntity* this) {
|
|
static void (*const Dust_Actions[])(DustEntity*) = {
|
|
sub_080441E0,
|
|
sub_080442A0,
|
|
};
|
|
Dust_Actions[super->action](this);
|
|
}
|
|
|
|
void Dust_OnCollision(DustEntity* this) {
|
|
EnemyFunctionHandlerAfterCollision(super, Dust_Functions);
|
|
}
|
|
|
|
void Dust_OnGrabbed(DustEntity* this) {
|
|
static void (*const Dust_SubActions[])(DustEntity*) = {
|
|
sub_080441BC,
|
|
sub_080441C4,
|
|
sub_080441CC,
|
|
};
|
|
|
|
if (super->type == 0) {
|
|
if (sub_0806F520(super)) {
|
|
if (--super->timer == 0) {
|
|
super->timer = 8;
|
|
sub_08044310(this);
|
|
}
|
|
} else {
|
|
super->timer = 8;
|
|
}
|
|
} else {
|
|
if (sub_0806F520(super)) {
|
|
Dust_SubActions[super->subAction](this);
|
|
} else {
|
|
sub_080445C0(this);
|
|
DeleteThisEntity();
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_080441BC(DustEntity* this) {
|
|
super->subAction = 2;
|
|
}
|
|
|
|
void sub_080441C4(DustEntity* this) {
|
|
sub_0806F4E8(super);
|
|
}
|
|
|
|
void sub_080441CC(DustEntity* this) {
|
|
if (sub_0806F3E4(super)) {
|
|
GenericDeath(super);
|
|
}
|
|
}
|
|
|
|
void sub_080441E0(DustEntity* this) {
|
|
int iVar1;
|
|
u8* pbVar2;
|
|
u32* puVar3;
|
|
Hitbox* pHVar4;
|
|
|
|
if (CheckGlobalFlag(MACHI_MACHIHOKORI)) {
|
|
DeleteThisEntity();
|
|
}
|
|
if (super->type == 0) {
|
|
pbVar2 = (u8*)sub_080AD8F0(DUST_SPRITE_INDEX, 1);
|
|
iVar1 = (u32)*pbVar2 * sizeof(DustHeapItem) + 1;
|
|
puVar3 = (u32*)zMalloc(iVar1);
|
|
super->myHeap = puVar3;
|
|
if (puVar3 == NULL) {
|
|
return;
|
|
}
|
|
MemCopy(pbVar2, puVar3, iVar1);
|
|
super->spriteAnimation[2] = 0xff;
|
|
pHVar4 = (Hitbox*)zMalloc(HEAP->unk_0 * 8 + 0xc);
|
|
if (pHVar4 == NULL) {
|
|
zFree(super->myHeap);
|
|
return;
|
|
}
|
|
super->hitbox = pHVar4;
|
|
*pHVar4 = gHitbox_4;
|
|
sub_080442BC(this);
|
|
super->frameIndex = 1;
|
|
super->spritePriority.b0 = 7;
|
|
this->unk_75 = 0;
|
|
this->unk_76 = -1;
|
|
} else {
|
|
super->frameIndex = 0;
|
|
super->speed = 0;
|
|
super->hitbox = (Hitbox*)&gHitbox_1;
|
|
super->gustJarFlags = 1;
|
|
}
|
|
super->action = 1;
|
|
super->timer = 8;
|
|
}
|
|
|
|
void sub_080442A0(DustEntity* this) {
|
|
if (super->type == 0) {
|
|
sub_08044498(this);
|
|
} else {
|
|
sub_08044550(this);
|
|
}
|
|
}
|
|
|
|
extern const u8 gUnk_080D15B4[];
|
|
|
|
void sub_080442BC(DustEntity* this) {
|
|
u32 hitboxCount;
|
|
u32 i;
|
|
const u8* ptr = gUnk_080D15B4;
|
|
hitboxCount = HEAP->unk_0;
|
|
|
|
for (i = 0; i < hitboxCount; i++) {
|
|
((Hitbox3D*)&super->hitbox[i])[1].offset_x = ptr[0];
|
|
((Hitbox3D*)&super->hitbox[i])[1].offset_y = ptr[1];
|
|
((Hitbox3D*)&super->hitbox[i])[1].unknown[0] = ptr[2];
|
|
((Hitbox3D*)&super->hitbox[i])[1].unknown[1] = ptr[3];
|
|
((Hitbox3D*)&super->hitbox[i])[1].unknown[2] = 0;
|
|
((Hitbox3D*)&super->hitbox[i])[1].unknown[3] = i;
|
|
}
|
|
this->unk_74 = hitboxCount;
|
|
}
|
|
|
|
// heap and hitbox struct
|
|
void sub_08044310(DustEntity* this) {
|
|
Entity* iVar1;
|
|
u32 bVar2;
|
|
u32 i;
|
|
u32 uVar7;
|
|
u8* pbVar9;
|
|
u32 tmp;
|
|
DustHeap* reg7;
|
|
|
|
uVar7 = 0xff;
|
|
tmp = 0xff;
|
|
|
|
switch (gPlayerEntity.animationState / 2 & 3) {
|
|
case 0:
|
|
for (i = 0; i < this->unk_74; i++) {
|
|
if ((((Hitbox3D*)&super->hitbox[i])[1].unknown[2] == 0) &&
|
|
(tmp > (u8)((Hitbox3D*)&super->hitbox[i])[1].offset_y)) {
|
|
uVar7 = i;
|
|
}
|
|
}
|
|
break;
|
|
case 1:
|
|
for (i = 0; i < this->unk_74; i++) {
|
|
if ((((Hitbox3D*)&super->hitbox[i])[1].unknown[2] == 0) &&
|
|
(tmp > ((Hitbox3D*)&super->hitbox[i])[1].unknown[0])) {
|
|
uVar7 = i;
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
for (i = 0; i < this->unk_74; i++) {
|
|
if ((((Hitbox3D*)&super->hitbox[i])[1].unknown[2] == 0) &&
|
|
(tmp > (u8)((Hitbox3D*)&super->hitbox[i])[1].offset_x)) {
|
|
uVar7 = i;
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
for (i = 0; i < this->unk_74; i++) {
|
|
if ((((Hitbox3D*)&super->hitbox[i])[1].unknown[2] == 0) &&
|
|
(tmp > ((Hitbox3D*)&super->hitbox[i])[1].unknown[1])) {
|
|
uVar7 = i;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (uVar7 != 0xff) {
|
|
super->hitbox[uVar7 + 2].offset_x = 1;
|
|
HEAP->unk_0--;
|
|
reg7 = HEAP + 1 + HEAP->unk_0 * 5;
|
|
bVar2 = HEAP->unk_0;
|
|
pbVar9 = &HEAP->items[(u32)(u8)super->hitbox[uVar7 + 2].offset_y].unk_0;
|
|
iVar1 = CreateEnemy(DUST, 1);
|
|
if (iVar1 != 0) {
|
|
PositionRelative(super, iVar1, ((s8)*pbVar9 + 8) * 0x10000, ((s8)pbVar9[1] + 8) * 0x10000);
|
|
}
|
|
|
|
if (HEAP->unk_0 == 0) {
|
|
SetGlobalFlag(MACHI_MACHIHOKORI);
|
|
SoundReq(SFX_SECRET);
|
|
DeleteThisEntity();
|
|
}
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
pbVar9[i] = reg7[i].unk_0;
|
|
}
|
|
|
|
for (i = 0; i < this->unk_74; i++) {
|
|
if (((Hitbox3D*)&super->hitbox[i])[1].unknown[3] == HEAP->unk_0) {
|
|
((Hitbox3D*)&super->hitbox[i])[1].unknown[3] = super->hitbox[uVar7 + 2].offset_y;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_08044498(DustEntity* this) {
|
|
Entity* pEVar1;
|
|
DustHeapItem* pbVar2;
|
|
u32 i;
|
|
u32 tileIndex;
|
|
u32 uVar4;
|
|
u32 tmp;
|
|
u32 xdiff, ydiff;
|
|
|
|
uVar4 = COORD_TO_TILE(&gPlayerEntity);
|
|
tmp = (gPlayerState.playerInput.newInput & 0xf00);
|
|
if (tmp != this->unk_75 || uVar4 != this->unk_76) {
|
|
this->unk_75 = tmp;
|
|
this->unk_76 = uVar4;
|
|
pbVar2 = HEAP->items;
|
|
uVar4 = HEAP->unk_0;
|
|
xdiff = gPlayerEntity.x.HALF.HI - super->x.HALF.HI;
|
|
ydiff = gPlayerEntity.y.HALF.HI - super->y.HALF.HI;
|
|
|
|
for (i = 0; i < uVar4; i++) {
|
|
if (xdiff - pbVar2[i].unk_0 < 0x10 && ydiff - pbVar2[i].unk_1 < 0x10) {
|
|
pEVar1 = CreateObject(SPECIAL_FX, FX_DASH, 0);
|
|
if (pEVar1 == NULL) {
|
|
return;
|
|
}
|
|
CopyPosition(&gPlayerEntity, pEVar1);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_08044550(DustEntity* this) {
|
|
u8 uVar1;
|
|
const s8* ptr;
|
|
|
|
if ((gPlayerState.field_0x1c & 0xf) == 1) {
|
|
if (super->speed < 0x100) {
|
|
super->speed += 0x10;
|
|
}
|
|
ptr = &gUnk_08126EE4[gPlayerEntity.animationState & 0xe];
|
|
super->direction = CalculateDirectionTo(super->x.HALF.HI, super->y.HALF.HI, gPlayerEntity.x.HALF.HI + ptr[0],
|
|
gPlayerEntity.y.HALF.HI + ptr[1]);
|
|
LinearMoveUpdate(super);
|
|
} else {
|
|
sub_080445C0(this);
|
|
DeleteThisEntity();
|
|
}
|
|
}
|
|
|
|
void sub_080445C0(DustEntity* this) {
|
|
Entity* pEVar1;
|
|
|
|
pEVar1 = CreateObject(DIRT_PARTICLE, 1, 1);
|
|
if (pEVar1 != NULL) {
|
|
CopyPosition(super, pEVar1);
|
|
}
|
|
}
|