mirror of
https://github.com/zeldaret/tmc
synced 2026-05-26 23:47:47 -04:00
149 lines
4.2 KiB
C
149 lines
4.2 KiB
C
/**
|
|
* @file pushableLever.c
|
|
* @ingroup Objects
|
|
*
|
|
* @brief Pushable Lever 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 tilePosition;
|
|
/*0x72*/ u16 tileIndex;
|
|
/*0x74*/ u16 timer;
|
|
/*0x76*/ u8 unk_76[16];
|
|
/*0x86*/ u16 pushedFlag;
|
|
} PushableLeverEntity;
|
|
|
|
enum PushableLeverAction {
|
|
INIT,
|
|
IDLE,
|
|
PUSHING,
|
|
};
|
|
|
|
extern void (*const PushableLever_Actions[])(PushableLeverEntity*);
|
|
extern const u16 PushableLever_Tiles[];
|
|
extern const u8 PushableLever_InitialOffsets[];
|
|
extern const u8 PushableLever_PushedOffsets[];
|
|
|
|
void PushableLever_SetIdle(PushableLeverEntity*);
|
|
bool32 PushableLever_ShouldStartPushing(PushableLeverEntity* this);
|
|
void PushableLever_SetTiles(PushableLeverEntity*);
|
|
void PushableLever_CalculateSpriteOffsets(PushableLeverEntity*);
|
|
|
|
#define TILE_INITIAL 0x4053
|
|
#define TILE_PUSHED 0x4052
|
|
|
|
void PushableLever(PushableLeverEntity* this) {
|
|
PushableLever_Actions[super->action](this);
|
|
}
|
|
|
|
void PushableLever_Init(PushableLeverEntity* this) {
|
|
super->spritePriority.b0 = 5;
|
|
PushableLever_SetIdle(this);
|
|
}
|
|
|
|
void PushableLever_Idle(PushableLeverEntity* this) {
|
|
if (PushableLever_ShouldStartPushing(this)) {
|
|
super->action = PUSHING;
|
|
super->spriteOffsetX = 0;
|
|
super->spriteOffsetY = 0;
|
|
SetTile(this->tileIndex, this->tilePosition, super->collisionLayer);
|
|
EnqueueSFX(SFX_16A);
|
|
RequestPriorityDuration(super, 0x1e);
|
|
if (sub_08079F8C()) {
|
|
gPlayerState.pushedObject = 0x90;
|
|
gPlayerState.queued_action = 5;
|
|
gPlayerState.flags |= 1;
|
|
gPlayerEntity.x.HALF.LO = 0;
|
|
gPlayerEntity.y.HALF.LO = 0;
|
|
gPlayerEntity.direction = gPlayerEntity.animationState << 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
void PushableLever_Pushing(PushableLeverEntity* this) {
|
|
GetNextFrame(super);
|
|
if ((super->frame & 0x80) != 0) {
|
|
if (super->type2 == 0) {
|
|
SetFlag(this->pushedFlag);
|
|
} else {
|
|
ClearFlag(this->pushedFlag);
|
|
}
|
|
PushableLever_SetIdle(this);
|
|
}
|
|
}
|
|
|
|
void PushableLever_SetIdle(PushableLeverEntity* this) {
|
|
super->action = IDLE;
|
|
this->timer = 0x3c;
|
|
PushableLever_SetTiles(this);
|
|
}
|
|
|
|
void PushableLever_SetTiles(PushableLeverEntity* this) {
|
|
if (CheckFlags(this->pushedFlag) == FALSE) {
|
|
super->type2 = 0;
|
|
this->tilePosition = COORD_TO_TILE_OFFSET(super, 0, 0x10);
|
|
this->tileIndex = GetTileIndex(this->tilePosition, super->collisionLayer);
|
|
SetTile(TILE_INITIAL, this->tilePosition, super->collisionLayer);
|
|
InitializeAnimation(super, 1);
|
|
} else {
|
|
super->type2 = 1;
|
|
this->tilePosition = COORD_TO_TILE_OFFSET(super, 0x10, 0);
|
|
this->tileIndex = GetTileIndex(this->tilePosition, super->collisionLayer);
|
|
SetTile(TILE_PUSHED, this->tilePosition, super->collisionLayer);
|
|
InitializeAnimation(super, 0);
|
|
}
|
|
}
|
|
|
|
bool32 PushableLever_ShouldStartPushing(PushableLeverEntity* this) {
|
|
if (GetTileIndex(this->tilePosition, super->collisionLayer) == 0x4054) {
|
|
if (--this->timer == 0) {
|
|
return TRUE;
|
|
}
|
|
PushableLever_CalculateSpriteOffsets(this);
|
|
SetTile(PushableLever_Tiles[super->type2], this->tilePosition, super->collisionLayer);
|
|
} else {
|
|
this->timer = 0x3c;
|
|
super->spriteOffsetX = 0;
|
|
super->spriteOffsetY = 0;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void PushableLever_CalculateSpriteOffsets(PushableLeverEntity* this) {
|
|
const u8* offsets;
|
|
if (super->type2 == 0) {
|
|
offsets = PushableLever_InitialOffsets;
|
|
} else {
|
|
offsets = PushableLever_PushedOffsets;
|
|
}
|
|
offsets = &offsets[(this->timer / 4) & 6];
|
|
super->spriteOffsetX = offsets[0];
|
|
super->spriteOffsetY = offsets[1];
|
|
if ((this->timer & 3) == 0) {
|
|
EnqueueSFX(SFX_104);
|
|
}
|
|
}
|
|
|
|
void (*const PushableLever_Actions[])(PushableLeverEntity*) = {
|
|
PushableLever_Init,
|
|
PushableLever_Idle,
|
|
PushableLever_Pushing,
|
|
};
|
|
const u16 PushableLever_Tiles[] = {
|
|
TILE_INITIAL,
|
|
TILE_PUSHED,
|
|
};
|
|
const u8 PushableLever_InitialOffsets[] = {
|
|
0, 0, 0, 0, 255, 0, 0, 0,
|
|
};
|
|
const u8 PushableLever_PushedOffsets[] = {
|
|
0, 0, 0, 0, 0, 255, 0, 0,
|
|
};
|