diff options
| author | notyourav <65437533+notyourav@users.noreply.github.com> | 2022-03-19 18:21:27 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-19 18:21:27 -0700 |
| commit | 166c87f820929dbfae0ce49c31c60be92507e9bb (patch) | |
| tree | 424b89ee232524f547d05fe04b4556e9eb35716a /src/object | |
| parent | 88330fa5b710346cfffa89935abfa255a1628409 (diff) | |
| parent | d7a794a9d22444b3565ef0827af9579b4fbd25aa (diff) | |
Merge pull request #455 from hatal175/minecart
Diffstat (limited to 'src/object')
| -rw-r--r-- | src/object/minecart.c | 309 |
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; + } +} |
