diff options
| author | notyourav <65437533+notyourav@users.noreply.github.com> | 2022-02-23 18:44:27 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-23 18:44:27 -0800 |
| commit | abe6053a4f3dcaa511035baba764609464eadc46 (patch) | |
| tree | 86ac2d159d2fc79038f0ca852f1088529afaec5f /src | |
| parent | b7126576132acd50c1a02899f223deb67d80bbcd (diff) | |
| parent | 4df984bcf707a0855cf5cbecabf9c3630e60c450 (diff) | |
Merge pull request #405 from octorock/crenelBeanSprout
Diffstat (limited to 'src')
| -rw-r--r-- | src/object.c | 2 | ||||
| -rw-r--r-- | src/object/crenelBeanSprout.c | 339 |
2 files changed, 340 insertions, 1 deletions
diff --git a/src/object.c b/src/object.c index 420783e2..a2ffb4b8 100644 --- a/src/object.c +++ b/src/object.c @@ -109,7 +109,7 @@ void (*const gObjectFunctions[])(Entity*) = { [OBJECT_68] = Object68, [OBJECT_69] = Object69, [OBJECT_6A] = Object6A, - [CRENAL_BEAN_SPROUT] = CrenalBeanSprout, + [CRENEL_BEAN_SPROUT] = CrenelBeanSprout, [MINECART_DOOR] = MinecartDoor, [OBJECT_ON_PILLAR] = ObjectOnPillar, [MINERAL_WATER_SOURCE] = MineralWaterSource, diff --git a/src/object/crenelBeanSprout.c b/src/object/crenelBeanSprout.c new file mode 100644 index 00000000..5fa2ec7a --- /dev/null +++ b/src/object/crenelBeanSprout.c @@ -0,0 +1,339 @@ +/** + * @file crenelBeanSprout.c + * @ingroup Objects + * + * @brief Crenel Bean Sprout object + */ + +#define NENT_DEPRECATED +#include "global.h" +#include "object.h" +#include "functions.h" + +typedef struct { + /*0x00*/ Entity base; + /*0x68*/ u8 unk_68[8]; + /*0x70*/ u16 unk_70; + /*0x72*/ u16 unk_72; +} CrenelBeanSproutEntity; + +extern u32 sub_080002BC(s32, s32, u32); + +extern Hitbox gUnk_080FD2A8; + +void sub_080969A4(CrenelBeanSproutEntity*); +void sub_08096A78(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Init(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action1(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action2(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action3(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action4(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action5(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action6(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action2SubAction0(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action2SubAction1(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action2SubAction2(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action2SubAction3(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action6SubAction0(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action6SubAction1(CrenelBeanSproutEntity*); +void CrenelBeanSprout_Action6SubAction2(CrenelBeanSproutEntity*); + +void CrenelBeanSprout(CrenelBeanSproutEntity* this) { + static void (*const CrenelBeanSprout_Actions[])(CrenelBeanSproutEntity*) = { + CrenelBeanSprout_Init, CrenelBeanSprout_Action1, CrenelBeanSprout_Action2, CrenelBeanSprout_Action3, + CrenelBeanSprout_Action4, CrenelBeanSprout_Action5, CrenelBeanSprout_Action6, + }; + CrenelBeanSprout_Actions[super->action](this); +} + +void CrenelBeanSprout_Init(CrenelBeanSproutEntity* this) { + Entity* obj; + u32 tmp; + + super->action = 1; + tmp = super->speed = 0x80; + super->hitbox = (Hitbox*)&gUnk_080FD2A8; + switch (super->type) { + case 0: + if (CheckGlobalFlag(WATERBEAN_OUT)) { + if (CheckGlobalFlag(WATERBEAN_PUT) == 0) { + PositionRelative(&gPlayerEntity, super, 0, 0x10000); + SetTile(0x4022, 0xdc, super->collisionLayer); + } else { + if (CheckLocalFlag(super->type2) == 0) { + InitializeAnimation(super, 10); + super->y.HALF.HI += 4; + super->action = 4; + SetTile(0x403b, COORD_TO_TILE(super), super->collisionLayer); + return; + } + super->type2 = 0; + super->field_0xf = 2; + sub_080969A4(this); + DeleteThisEntity(); + } + } else { + super->x.HALF.HI = gRoomControls.origin_x + 0xd0; + super->y.HALF.HI = gRoomControls.origin_y + 0x44; + super->action = 4; + InitializeAnimation(super, super->type + 3); + return; + } + break; + case 3: + if (CheckGlobalFlag(WATERBEAN_OUT)) { + if (CheckGlobalFlag(WATERBEAN_PUT) == 0) { + super->spritePriority.b0 = gPlayerEntity.spritePriority.b0 - 1; + *(((u8*)&gPlayerEntity) + 0x79) = tmp; + PositionRelative(&gPlayerEntity, super, 0, -0x180000); + } else { + DeleteThisEntity(); + } + } + obj = CreateObjectWithParent(super, CRENEL_BEAN_SPROUT, 1, 0); + super->child = obj; + if (obj != NULL) { + PositionRelative(super, obj, -0x1c0000, -0x280000); + } + super->field_0x16 = 0x10; + super->spriteRendering.b0 = 3; + InitializeAnimation(super, 0xc); + CrenelBeanSprout_Action1(this); + return; + break; + case 1: + super->spriteRendering.b0 = 3; + SetDefaultPriority(super, 6); + break; + case 2: + if (CheckLocalFlag((u32)super->type2) == 0) { + + InitializeAnimation(super, 0xb); + super->y.HALF.HI += 4; + super->action = 4; + SetTile(0x4032, COORD_TO_TILE(super), super->collisionLayer); + return; + } else { + super->type2 = 0; + super->field_0xf = 3; + sub_080969A4(this); + DeleteThisEntity(); + return; + } + break; + } + InitializeAnimation(super, super->type + 3); + CrenelBeanSprout_Action1(this); +} + +void CrenelBeanSprout_Action1(CrenelBeanSproutEntity* this) { + static const u8 gUnk_08123184[] = { + 0, 240, 16, 0, 0, 16, 240, 0, + }; + Entity* parent; + u32 tmp; + if ((super->type & 1) != 0) { + if (super->type == 3) { + sub_08078930(super); + sub_0800445C(super); + } else { + PositionRelative(super->parent, super, -0x1c0000, -0x280000); + if (super->parent->action == 2) { + switch (super->parent->subAction) { + case 1: + if ((gPlayerState.field_0xd & 0x80) != 0) { + InitializeAnimation(super, 4); + } else { + GetNextFrame(super); + } + break; + case 2: + GetNextFrame(super); + break; + default: + InitializeAnimation(super, 4); + break; + } + } + super->spritePriority.b0 = super->parent->spritePriority.b0 - 1; + parent = super->parent; + super->spriteRendering.b3 = parent->spriteRendering.b3; + super->spriteOrientation.flipY = parent->spriteOrientation.flipY; + } + sub_0805EC9C(super, 0xcc, 0xcc, 0); + } else { + gPlayerState.mobility |= 0x80; + gPlayerState.heldObject = 5; + if ((gPlayerState.field_0xd & 0x80) != 0) { + InitializeAnimation(super, (super->type >> 1) + 3); + } else { + GetNextFrame(super); + } + tmp = gPlayerEntity.animationState & 6; + this->unk_70 = ((super->x.HALF.HI + (s8)gUnk_08123184[tmp]) & -0x10) | 8; + this->unk_72 = ((super->y.HALF.HI + (s8)gUnk_08123184[(tmp) + 1]) & -0x10) | 8; + if (sub_080002BC(this->unk_70, this->unk_72, super->collisionLayer) == 0x19) { + gUnk_0200AF00.filler25[10] = 3; + } else { + gUnk_0200AF00.filler25[10] = 0; + } + PositionRelative(&gPlayerEntity, super, 0, 0x10000); + if (sub_080002B8(super) == 0x19) { + sub_0807BA8C(0xdc, super->collisionLayer); + sub_08096A78(this); + } + if ((gPlayerState.field_0x92 & 0xc0) == 0) { + return; + } + if (gUnk_0200AF00.filler25[10] != 3) { + return; + } + gPlayerState.heldObject = 0; + super->action = 5; + super->speed = 0x100; + super->zVelocity = 0x20000; + super->spritePriority.b1 = 1; + super->spriteSettings.shadow = 1; + sub_0807BA8C(0xdc, super->collisionLayer); + SoundReq(SFX_PLY_VO5); + } +} + +void CrenelBeanSprout_Action2(CrenelBeanSproutEntity* this) { + static void (*const CrenelBeanSprout_Action2SubActions[])(CrenelBeanSproutEntity*) = { + CrenelBeanSprout_Action2SubAction0, + CrenelBeanSprout_Action2SubAction1, + CrenelBeanSprout_Action2SubAction2, + CrenelBeanSprout_Action2SubAction3, + }; + CrenelBeanSprout_Action2SubActions[super->subAction](this); +} + +void CrenelBeanSprout_Action2SubAction0(CrenelBeanSproutEntity* this) { + SetGlobalFlag(WATERBEAN_OUT); + super->subAction++; +} + +void CrenelBeanSprout_Action2SubAction1(CrenelBeanSproutEntity* this) { +} + +void CrenelBeanSprout_Action2SubAction2(CrenelBeanSproutEntity* this) { + ClearGlobalFlag(WATERBEAN_OUT); +} + +void CrenelBeanSprout_Action2SubAction3(CrenelBeanSproutEntity* this) { + InitScreenShake(0x10, 0); + super->action = 1; + super->subAction = 0; +} + +void CrenelBeanSprout_Action3(CrenelBeanSproutEntity* this) { + UpdateAnimationSingleFrame(super); + if ((super->frame & 0x80) != 0) { + super->action++; + InitializeAnimation(super, 10); + } +} + +void CrenelBeanSprout_Action4(CrenelBeanSproutEntity* this) { + static const u16 gUnk_0812319C[] = { 0x403c, 0x4033 }; + if (gUnk_0812319C[super->type >> 1] == GetTileTypeByEntity(super)) { + GetNextFrame(super); + gPlayerState.keepFacing |= 0x80; + gPlayerState.field_0xa |= 0x80; + gPlayerState.field_0x7 |= 0x80; + if (--super->actionDelay == 0) { + super->action = 6; + super->subAction = 0; + CreateDust(super); + } + } else { + super->actionDelay = 0xc0; + } +} + +void CrenelBeanSprout_Action5(CrenelBeanSproutEntity* this) { + if ((this->unk_70 != super->x.HALF.HI) || (this->unk_72 != super->y.HALF.HI)) { + super->direction = CalculateDirectionTo(super->x.HALF.HI, super->y.HALF.HI, this->unk_70, this->unk_72); + LinearMoveUpdate(super); + } + if (GravityUpdate(super, 0x4000) == 0) { + sub_08096A78(this); + } +} + +void CrenelBeanSprout_Action6(CrenelBeanSproutEntity* this) { + static void (*const CrenelBeanSprout_Action6SubActions[])(CrenelBeanSproutEntity*) = { + CrenelBeanSprout_Action6SubAction0, + CrenelBeanSprout_Action6SubAction1, + CrenelBeanSprout_Action6SubAction2, + }; + if (super->subAction != 2) { + sub_08078B48(); + } + CrenelBeanSprout_Action6SubActions[super->subAction](this); +} + +void CrenelBeanSprout_Action6SubAction0(CrenelBeanSproutEntity* this) { + static const u8 gUnk_081231AC[] = { + 2, + 3, + }; + SetLocalFlag(super->type2); + super->actionDelay = 0x0f; + super->field_0xf = gUnk_081231AC[super->type >> 1]; + super->type2 = 0; + super->spriteSettings.draw = 0; + super->subAction++; + if (super->type == 0) { + sub_0807B7D8(0x1ce, COORD_TO_TILE(super), super->collisionLayer); + } else { + sub_0807B7D8(0x1cd, COORD_TO_TILE(super), super->collisionLayer); + } + SoundReq(SFX_1DB); +} + +void CrenelBeanSprout_Action6SubAction1(CrenelBeanSproutEntity* this) { + static const u16 gUnk_081231AE[] = { 0x1cc, 0x1cb, 0x1c9 }; + if (--super->actionDelay == 0) { + super->y.HALF.HI += -0x10; + sub_0807B7D8(gUnk_081231AE[super->type2], COORD_TO_TILE(super), super->collisionLayer); + super->type2++; + if (super->type2 == super->field_0xf) { + gPlayerState.keepFacing &= 0x7f; + super->subAction++; + super->actionDelay = 0x3c; + } else { + super->actionDelay = 0x0f; + } + } +} + +void CrenelBeanSprout_Action6SubAction2(CrenelBeanSproutEntity* this) { + if ((super->actionDelay != 0) && (--super->actionDelay == 0)) { + SoundReq(SFX_SECRET); + } +} + +void sub_080969A4(CrenelBeanSproutEntity* this) { + static const u16 gUnk_081231B4[] = { 0x1cc, 0x1cb, 0x1c9 }; + if (super->type == 0) { + sub_0807B7D8(0x1ce, COORD_TO_TILE(super), super->collisionLayer); + } else { + sub_0807B7D8(0x1cd, COORD_TO_TILE(super), super->collisionLayer); + } + while (super->type2 != super->field_0xf) { + super->y.HALF.HI -= 0x10; + sub_0807B7D8(gUnk_081231B4[super->type2], COORD_TO_TILE(super), super->collisionLayer); + super->type2++; + } +} + +void sub_08096A78(CrenelBeanSproutEntity* this) { + SetGlobalFlag(WATERBEAN_PUT); + InitAnimationForceUpdate(super, (super->type >> 1) + 8); + sub_08004168(super); + super->y.HALF.HI += 4; + super->action = 3; + SetTile(0x403b, COORD_TO_TILE(super), super->collisionLayer); +} |
