summaryrefslogtreecommitdiff
path: root/src/object
diff options
context:
space:
mode:
authornotyourav <65437533+notyourav@users.noreply.github.com>2022-03-19 18:21:27 -0700
committerGitHub <noreply@github.com>2022-03-19 18:21:27 -0700
commit166c87f820929dbfae0ce49c31c60be92507e9bb (patch)
tree424b89ee232524f547d05fe04b4556e9eb35716a /src/object
parent88330fa5b710346cfffa89935abfa255a1628409 (diff)
parentd7a794a9d22444b3565ef0827af9579b4fbd25aa (diff)
Merge pull request #455 from hatal175/minecart
Diffstat (limited to 'src/object')
-rw-r--r--src/object/minecart.c309
1 files changed, 220 insertions, 89 deletions
diff --git a/src/object/minecart.c b/src/object/minecart.c
index 7370c28b..97b0adbb 100644
--- a/src/object/minecart.c
+++ b/src/object/minecart.c
@@ -1,67 +1,82 @@
+#define NENT_DEPRECATED
#include "object.h"
#include "functions.h"
#include "hitbox.h"
-extern u32 sub_08091DDC(Entity*);
+typedef struct {
+ Entity base;
+ u8 filler[0x1C];
+ struct_030010EC* minecartData;
+} MinecartEntity;
+
extern u32 sub_08007DD6(u32, u32);
extern void sub_08017744(Entity*);
-extern void sub_08091C0C(Entity*);
-extern void (*const gUnk_081223A8[])(Entity*);
+u32 sub_08091DDC(MinecartEntity*);
+void sub_080916EC(MinecartEntity*);
+void sub_080917DC(MinecartEntity*);
+void sub_080918A4(MinecartEntity*);
+void sub_080919AC(MinecartEntity*);
+void sub_08091C0C(MinecartEntity*);
+void sub_08091C98(MinecartEntity*);
+void sub_08091CC8(MinecartEntity*);
+void sub_08091D90(MinecartEntity*);
-extern const s8 gUnk_081223C8[];
extern const u32 gUnk_081223D8[];
void Minecart(Entity* this) {
- gUnk_081223A8[this->action](this);
+ static void (*const actionFuncs[])(MinecartEntity*) = {
+ sub_080916EC, sub_080917DC, sub_080918A4, sub_080919AC, sub_08091C0C, sub_08091C98, sub_08091CC8, sub_08091D90,
+ };
+ actionFuncs[this->action]((MinecartEntity*)this);
this->bitfield = 0;
}
-void sub_080916EC(Entity* this) {
- struct_030010EC* unk = &gRoomTransition.minecart_data[this->actionDelay];
+void sub_080916EC(MinecartEntity* this) {
+ struct_030010EC* unk = &gRoomTransition.minecart_data[super->actionDelay];
- *(struct_030010EC**)&this->cutsceneBeh.HWORD = unk;
- if ((gRoomControls.room != unk->field_0x4) || (gPlayerState.flags & PL_IN_MINECART) != 0) {
+ this->minecartData = unk;
+ if ((gRoomControls.room != unk->room) || (gPlayerState.flags & PL_IN_MINECART) != 0) {
DeleteThisEntity();
}
- this->x.HALF.HI = gRoomControls.origin_x + ((unk->field_0x0 & 0x3f) << 4) + 8;
- this->y.HALF.HI = gRoomControls.origin_y + ((unk->field_0x0 & 0xfc << 4) >> 2) + 8;
- this->animationState = unk->field_0x5;
- this->type2 = unk->field_0x6;
- this->action = 1;
- this->hitbox = (Hitbox*)&gUnk_080FD310;
- COLLISION_ON(this);
- this->hitType = 1;
- this->field_0x3c = 0x47;
- this->hurtType = 0x44;
- this->flags2 = 0x80;
- this->direction = DirectionFromAnimationState(this->animationState);
- this->speed = 0x700;
- this->spritePriority.b1 = 3;
- InitAnimationForceUpdate(this, this->type2 + 4 + this->animationState);
- SetTile(0x4022, COORD_TO_TILE(this), this->collisionLayer);
+ super->x.HALF.HI = gRoomControls.origin_x + ((unk->tilePos & 0x3f) << 4) + 8;
+ super->y.HALF.HI = gRoomControls.origin_y + ((unk->tilePos & 0xfc << 4) >> 2) + 8;
+ super->animationState = unk->animationState;
+ super->type2 = unk->field_0x6;
+ super->action = 1;
+ super->hitbox = (Hitbox*)&gUnk_080FD310;
+ COLLISION_ON(super);
+ super->hitType = 1;
+ super->field_0x3c = 0x47;
+ super->hurtType = 0x44;
+ super->flags2 = 0x80;
+ super->direction = DirectionFromAnimationState(super->animationState);
+ super->speed = 0x700;
+ super->spritePriority.b1 = 3;
+ InitAnimationForceUpdate(super, super->type2 + 4 + super->animationState);
+ SetTile(0x4022, COORD_TO_TILE(super), super->collisionLayer);
}
-void sub_080917DC(Entity* this) {
- if ((this->bitfield & 0x7f) == 0x1d) {
- this->zVelocity = Q_16_16(2.625);
- this->action = 7;
- InitAnimationForceUpdate(this, this->type2 + 4 + this->animationState);
+void sub_080917DC(MinecartEntity* this) {
+ if ((super->bitfield & 0x7f) == 0x1d) {
+ super->zVelocity = Q_16_16(2.625);
+ super->action = 7;
+ InitAnimationForceUpdate(super, super->type2 + 4 + super->animationState);
SoundReq(SFX_13B);
} else {
- if (sub_0800445C(this) != 0) {
+ if (sub_0800445C(super) != 0) {
if (!((gPlayerState.flags & (PL_MINISH | PL_ROLLING)) || gPlayerState.field_0x1c ||
gPlayerState.heldObject || gPlayerState.jump_status)) {
- this->actionDelay++;
+ super->actionDelay++;
} else {
- this->actionDelay = 0;
+ super->actionDelay = 0;
}
} else {
- this->actionDelay = 0;
+ super->actionDelay = 0;
}
- if (this->type2 == 0) {
- if (this->actionDelay > 8) {
- this->action++;
+ if (super->type2 == 0) {
+ if (super->actionDelay > 8) {
+ super->action++;
gPlayerState.jump_status = 0x81;
gPlayerState.flags |= PL_ENTER_MINECART;
gPlayerEntity.zVelocity = Q_16_16(2.0);
@@ -72,100 +87,102 @@ void sub_080917DC(Entity* this) {
SoundReq(SFX_PLY_JUMP);
}
} else {
- this->actionDelay = 0;
+ super->actionDelay = 0;
}
}
}
-void sub_080918A4(Entity* this) {
- if (EntityInRectRadius(this, &gPlayerEntity, 2, 2) != 0) {
- gPlayerEntity.x.HALF.HI = this->x.HALF.HI;
- gPlayerEntity.y.HALF.HI = this->y.HALF.HI;
+void sub_080918A4(MinecartEntity* this) {
+ if (EntityInRectRadius(super, &gPlayerEntity, 2, 2) != 0) {
+ gPlayerEntity.x.HALF.HI = super->x.HALF.HI;
+ gPlayerEntity.y.HALF.HI = super->y.HALF.HI;
if (gPlayerEntity.z.HALF.HI > -0x10) {
if (gPlayerEntity.zVelocity >= 0) {
return;
}
- gPlayerEntity.animationState = this->animationState << 1;
+ gPlayerEntity.animationState = super->animationState << 1;
gPlayerState.flags = (gPlayerState.flags ^ PL_ENTER_MINECART) | PL_IN_MINECART;
- this->action++;
- this->field_0xf = 1;
- this->flags |= ENT_PERSIST;
- this->hitType = 0x97;
- this->field_0x3c = (gPlayerEntity.field_0x3c + 1) | 0x20;
- this->flags2 = gPlayerEntity.flags2;
- this->hurtType = 0x18;
- this->damage = 8;
- sub_0801766C(this);
- sub_0807BA8C(COORD_TO_TILE(this), this->collisionLayer);
+ super->action++;
+ super->field_0xf = 1;
+ super->flags |= ENT_PERSIST;
+ super->hitType = 0x97;
+ super->field_0x3c = (gPlayerEntity.field_0x3c + 1) | 0x20;
+ super->flags2 = gPlayerEntity.flags2;
+ super->hurtType = 0x18;
+ super->damage = 8;
+ sub_0801766C(super);
+ sub_0807BA8C(COORD_TO_TILE(super), super->collisionLayer);
SoundReq(SFX_137);
}
} else {
- gPlayerEntity.direction = GetFacingDirection(&gPlayerEntity, this);
+ gPlayerEntity.direction = GetFacingDirection(&gPlayerEntity, super);
}
if (gPlayerEntity.zVelocity < 0) {
- gPlayerEntity.spritePriority.b0 = this->spritePriority.b0 - 1;
+ gPlayerEntity.spritePriority.b0 = super->spritePriority.b0 - 1;
}
}
-void sub_080919AC(Entity* this) {
+void sub_080919AC(MinecartEntity* this) {
+ static const s8 gUnk_081223C8[] = { 0, -7, 7, 0, 0, 7, -7, 0 };
+
u32 iVar2;
u32 uVar3;
gRoomControls.unk5 = 7;
if ((gPlayerState.flags & PL_IN_MINECART) == 0) {
- this->action = 1;
+ super->action = 1;
return;
}
if ((gPlayerEntity.frame & 0xf) == 0) {
- COLLISION_OFF(this);
- CopyPosition(this, &gPlayerEntity);
+ COLLISION_OFF(super);
+ CopyPosition(super, &gPlayerEntity);
if ((gPlayerEntity.frame & 0xf0) == 0x10) {
- this->spriteOffsetY = 1;
+ super->spriteOffsetY = 1;
} else {
- this->spriteOffsetY = 0;
+ super->spriteOffsetY = 0;
}
} else {
- COLLISION_ON(this);
+ COLLISION_ON(super);
gPlayerEntity.speed = 0;
- LinearMoveUpdate(this);
- CopyPosition(this, &gPlayerEntity);
- gPlayerEntity.spritePriority.b0 = this->spritePriority.b0 - 1;
+ LinearMoveUpdate(super);
+ CopyPosition(super, &gPlayerEntity);
+ gPlayerEntity.spritePriority.b0 = super->spritePriority.b0 - 1;
if (!sub_08091DDC(this)) {
if ((gRoomTransition.frameCount & 0xf) == 0) {
SoundReq(SFX_138);
}
- if (--this->field_0xf == 0xff) {
+ if (--super->field_0xf == 0xff) {
SoundReq(SFX_PLY_VO7);
- this->field_0xf = 0x3c;
+ super->field_0xf = 0x3c;
}
- uVar3 = sub_080B1A8C(this, gUnk_081223C8[this->animationState * 2],
- gUnk_081223C8[this->animationState * 2 + 1]);
- iVar2 = sub_08007DD6(uVar3, gUnk_081223D8[this->animationState]);
+ uVar3 = sub_080B1A8C(super, gUnk_081223C8[super->animationState * 2],
+ gUnk_081223C8[super->animationState * 2 + 1]);
+ iVar2 = sub_08007DD6(uVar3, gUnk_081223D8[super->animationState]);
if (iVar2 == 0) {
- this->direction = DirectionTurnAround(this->direction);
- this->animationState = AnimationStateFlip90(this->animationState);
+ super->direction = DirectionTurnAround(super->direction);
+ super->animationState = AnimationStateFlip90(super->animationState);
} else {
switch (uVar3) {
case 0x64:
- this->flags &= ~ENT_PERSIST;
- this->hitType = 1;
- this->field_0x3c = 0x47;
- this->hurtType = 0x44;
- this->flags2 = 0x80;
- this->action = 6;
- sub_08017744(this);
+ super->flags &= ~ENT_PERSIST;
+ super->hitType = 1;
+ super->field_0x3c = 0x47;
+ super->hurtType = 0x44;
+ super->flags2 = 0x80;
+ super->action = 6;
+ sub_08017744(super);
gPlayerState.jump_status = 0x41;
gPlayerState.flags = (gPlayerState.flags ^ PL_IN_MINECART) | PL_ENTER_MINECART;
gPlayerEntity.zVelocity = Q_16_16(2.0);
gPlayerEntity.speed = 0x200;
- gPlayerEntity.animationState = this->animationState << 1;
- gPlayerEntity.direction = this->direction;
+ gPlayerEntity.animationState = super->animationState << 1;
+ gPlayerEntity.direction = super->direction;
gPlayerEntity.flags |= PL_MINISH;
- sub_08004168(this);
- InitAnimationForceUpdate(this, this->animationState + 0xc);
+ sub_08004168(super);
+ InitAnimationForceUpdate(super, super->animationState + 0xc);
SoundReq(SFX_PLY_VO4);
SoundReq(SFX_139);
return;
@@ -177,21 +194,135 @@ void sub_080919AC(Entity* this) {
case 0x6d:
case 0x6e:
case 0x6f:
- if (uVar3 == GetTileUnderEntity(this)) {
+ if (uVar3 == GetTileUnderEntity(super)) {
sub_08091C0C(this);
- gPlayerEntity.animationState = this->animationState << 1;
+ gPlayerEntity.animationState = super->animationState << 1;
return;
}
break;
}
}
- gPlayerEntity.animationState = this->animationState << 1;
- if (this->animIndex == this->animationState) {
- UpdateAnimationSingleFrame(this);
+ gPlayerEntity.animationState = super->animationState << 1;
+ if (super->animIndex == super->animationState) {
+ UpdateAnimationSingleFrame(super);
} else {
- InitAnimationForceUpdate(this, this->animationState);
+ InitAnimationForceUpdate(super, super->animationState);
}
}
}
}
+
+void sub_08091C0C(MinecartEntity* this) {
+ sub_08004168(super);
+ CopyPosition(super, &gPlayerEntity);
+ switch (GetTileUnderEntity(super)) {
+ case 0x67:
+ if (super->direction == DirectionWest) {
+ super->direction = DirectionNorth;
+ super->animationState = 0;
+ } else {
+ super->direction = DirectionEast;
+ super->animationState = 1;
+ }
+ break;
+ case 0x68:
+ if (super->direction == DirectionEast) {
+ super->direction = DirectionSouth;
+ super->animationState = 2;
+ } else {
+ super->direction = DirectionWest;
+ super->animationState = 3;
+ }
+ break;
+ case 0x69:
+ if (super->direction == DirectionEast) {
+ super->direction = DirectionNorth;
+ super->animationState = 0;
+ } else {
+ super->direction = DirectionWest;
+ super->animationState = 3;
+ }
+ break;
+ case 0x6a:
+ if (super->direction == DirectionWest) {
+ super->direction = DirectionSouth;
+ super->animationState = 2;
+ } else {
+ super->direction = DirectionEast;
+ super->animationState = 1;
+ }
+ break;
+ default:
+ super->action = 3;
+ return;
+ }
+
+ super->action = 3;
+ gPlayerEntity.animationState = super->animationState << 1;
+}
+
+void sub_08091C98(MinecartEntity* this) {
+ LinearMoveUpdate(super);
+ CopyPosition(super, &gPlayerEntity);
+ if (gRoomControls.reload_flags == 0) {
+ super->action = 3;
+ super->speed = 0x700;
+ gRoomControls.camera_target = &gPlayerEntity;
+ }
+}
+
+void sub_08091CC8(MinecartEntity* this) {
+ struct_030010EC* minecartData;
+
+ if (gPlayerState.jump_status == 0) {
+ super->action = 1;
+ super->direction = DirectionTurnAround(super->direction);
+ super->animationState ^= 2;
+ gPlayerState.flags ^= PL_ENTER_MINECART;
+ minecartData = this->minecartData;
+ minecartData->tilePos = COORD_TO_TILE(super);
+ minecartData->room = gRoomControls.room;
+ minecartData->animationState = super->animationState;
+ InitAnimationForceUpdate(super, super->animationState + 0x10);
+ SetTile(0x4022, COORD_TO_TILE(super), super->collisionLayer);
+ } else {
+ UpdateAnimationSingleFrame(super);
+ gPlayerEntity.spritePriority.b0 = super->spritePriority.b0 - 1;
+ }
+}
+
+void sub_08091D90(MinecartEntity* this) {
+ if (super->zVelocity < 0) {
+ UpdateAnimationSingleFrame(super);
+ }
+ if (((super->frame & 0x7f) == 0) && GravityUpdate(super, 0x2000) == 0) {
+ super->type2 ^= 4;
+ super->action = 1;
+ this->minecartData->field_0x6 = super->type2;
+ SoundReq(SFX_13C);
+ }
+}
+
+bool32 sub_08091DDC(MinecartEntity* this) {
+ static const s8 gUnk_081223D0[] = { 0, -8, 8, 0, 0, 8, -8, 0 };
+ if ((sub_080B1AF0(super, gUnk_081223D0[super->animationState * 2], gUnk_081223D0[super->animationState * 2 + 1]) ==
+ 0xff) &&
+ (sub_0807BD14(&gPlayerEntity, super->animationState))) {
+ super->updatePriority = 6;
+ super->action = 5;
+ switch (super->direction) {
+ case 0:
+ case 8:
+ case 0x10:
+ case 0x18:
+ super->speed = 0xa0;
+ break;
+ }
+ gPlayerEntity.direction = super->direction;
+ gRoomControls.camera_target = super;
+ return 1;
+ } else {
+ return 0;
+ }
+}