mirror of https://github.com/pmret/papermario.git
1004 lines
40 KiB
C
1004 lines
40 KiB
C
#include "mgm_02.h"
|
|
#include "hud_element.h"
|
|
#include "effects.h"
|
|
#include "model.h"
|
|
#include "sprite/npc/bob_omb.h"
|
|
#include "sprite/npc/fuzzy.h"
|
|
|
|
void startup_draw_prim_rect_COPY(s16 left, s16 top, s16 right, s16 bottom, u16 r, u16 g, u16 b, u16 a);
|
|
void delete_entity(s32);
|
|
void partner_enable_input(void);
|
|
|
|
#define SCOREKEEPER_ENEMY_IDX 0
|
|
#define SMASH_DATA_VAR_IDX 0
|
|
|
|
#define PLAY_COST 10
|
|
#define PLAY_TIME 900
|
|
#define NUM_BOXES 35
|
|
#define NUM_PANELS 10
|
|
|
|
#define SMASH_DATA_VAR_IDX 0
|
|
#define SMASH_DATA_VAR_IDX 0
|
|
|
|
#define FUZZY_NPC_ID_BASE 0x0A
|
|
#define BOBOMB_NPC_ID_BASE 0x1E
|
|
#define LUIGI_NPC_ID_BASE 0x64
|
|
|
|
extern HudScript HudScript_BlueMeter;
|
|
extern HudScript HudScript_AButton;
|
|
extern HudScript HudScript_MashAButton;
|
|
|
|
extern s32 mgm_02_InitialConfigurations[3][NUM_BOXES];
|
|
extern s32 mgm_02_BoxModelIDs[NUM_BOXES];
|
|
extern s32 mgm_02_BoxColliderIDs[NUM_BOXES];
|
|
extern s32 mgm_02_PanelModelIDs[NUM_PANELS];
|
|
extern s32 D_80248600[NUM_PANELS]; //TODO set name: mgm_02_PanelModelsAssigned
|
|
|
|
extern s32 mgm_02_PeachPanelImg;
|
|
extern s32 mgm_02_PeachPanelPal;
|
|
|
|
extern EntityBlueprint D_802EAFDC; // SIGNPOST
|
|
extern EvtScript D_80242A3C_E187BC; // EVT_ReadSign
|
|
|
|
typedef enum SmashGameBoxCotent {
|
|
BOX_CONTENT_FUZZY = 0,
|
|
BOX_CONTENT_BOMB = 1,
|
|
BOX_CONTENT_PEACH = 2,
|
|
BOX_CONTENT_EMPTY = 3
|
|
} SmashGameBoxCotent;
|
|
|
|
typedef enum SmashGameStunFlags {
|
|
STUN_FLAGS_STUNNED = 1,
|
|
STUN_FLAGS_CHANGED = 2,
|
|
STUN_FLAGS_GRABBED = 4
|
|
} SmashGameStunFlags;
|
|
|
|
typedef enum SmashGameBoxState {
|
|
BOX_STATE_FUZZY_INIT = 10,
|
|
BOX_STATE_FUZZY_IDLE = 11,
|
|
BOX_STATE_FUZZY_POPUP = 12,
|
|
BOX_STATE_FUZZY_HIT = 13,
|
|
BOX_STATE_FUZZY_ATTACH = 14,
|
|
BOX_STATE_FUZZY_GRAB = 15,
|
|
BOX_STATE_FUZZY_DETACH = 16,
|
|
BOX_STATE_FUZZY_DONE = 17,
|
|
BOX_STATE_FUZZY_END = 18,
|
|
|
|
BOX_STATE_BOMB_INIT = 30,
|
|
BOX_STATE_BOMB_IDLE = 31,
|
|
BOX_STATE_BOMB_POPUP = 32,
|
|
BOX_STATE_BOMB_HIT = 33,
|
|
BOX_STATE_BOMB_ATTACK = 34,
|
|
BOX_STATE_BOMB_STUN = 35,
|
|
BOX_STATE_BOMB_DONE = 36,
|
|
BOX_STATE_BOMB_END = 37,
|
|
|
|
BOX_STATE_EMPTY_INIT = 50,
|
|
BOX_STATE_EMPTY_IDLE = 51,
|
|
BOX_STATE_EMPTY_HIT = 52,
|
|
|
|
BOX_STATE_PEACH_INIT = 70,
|
|
BOX_STATE_PEACH_IDLE = 71,
|
|
BOX_STATE_PEACH_POPUP = 72,
|
|
BOX_STATE_PEACH_HIT = 73,
|
|
BOX_STATE_PEACH_EMERGE = 74,
|
|
BOX_STATE_PEACH_DONE = 75
|
|
} SmashGameBoxState;
|
|
|
|
typedef struct SmashGameBoxData {
|
|
/* 0x00 */ SmashGameBoxState state;
|
|
/* 0x04 */ s32 stateTimer;
|
|
/* 0x08 */ s32 content;
|
|
/* 0x0C */ s32 modelID;
|
|
/* 0x10 */ s32 colliderID;
|
|
/* 0x14 */ s32 npcID;
|
|
/* 0x18 */ s32 peachPanelModelID;
|
|
} SmashGameBoxData; /* size = 0x1C */
|
|
|
|
typedef struct SmashGameData {
|
|
/* 0x000 */ s32 workerID;
|
|
/* 0x004 */ s32 found;
|
|
/* 0x008 */ s32 timeLeft; // num frames at 30fps
|
|
/* 0x00C */ s32 hudElemID_AButton;
|
|
/* 0x010 */ s32 hudElemID_Meter;
|
|
/* 0x014 */ s32 windowA_posX;
|
|
/* 0x018 */ s32 windowB_posX;
|
|
/* 0x01C */ s32 signpostEntity;
|
|
/* 0x020 */ s32 currentScore;
|
|
/* 0x024 */ s32 mashProgress;
|
|
/* 0x028 */ SmashGameStunFlags stunFlags;
|
|
/* 0x02C */ SmashGameBoxData box[NUM_BOXES];
|
|
} SmashGameData; /* size = 0x400 */
|
|
|
|
void N(draw_score_display)(void* renderData) {
|
|
Enemy* scorekeeper = get_enemy(SCOREKEEPER_ENEMY_IDX);
|
|
SmashGameData* data = scorekeeper->varTablePtr[SMASH_DATA_VAR_IDX];
|
|
s32 hudElemA;
|
|
s32 hudElemMeter;
|
|
s32 timeLeft;
|
|
s32 seconds;
|
|
s32 deciseconds;
|
|
|
|
// show mash meter while grabbed by a fuzzy
|
|
if (data->stunFlags & STUN_FLAGS_GRABBED) {
|
|
hudElemA = data->hudElemID_AButton;
|
|
hud_element_set_render_pos(hudElemA, 90, 90);
|
|
hud_element_draw_clipped(hudElemA);
|
|
hudElemMeter = data->hudElemID_Meter;
|
|
hud_element_set_render_pos(hudElemMeter, 90, 120);
|
|
hud_element_draw_clipped(hudElemMeter);
|
|
startup_draw_prim_rect_COPY(62, 116, 62 + (s32)(((f32)data->mashProgress / 12.0) * 59.0), 116 + 5, 0, 228, 134, 255);
|
|
}
|
|
|
|
if (scorekeeper->varTable[3] == 0 || scorekeeper->varTable[3] >= 4) {
|
|
if (data->windowA_posX > -80) {
|
|
data->windowA_posX -= 10;
|
|
if (data->windowA_posX < -80) {
|
|
data->windowA_posX = -80;
|
|
}
|
|
}
|
|
} else {
|
|
if (data->windowA_posX < 23) {
|
|
data->windowA_posX += 10;
|
|
if (data->windowA_posX > 23) {
|
|
data->windowA_posX = 23;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (scorekeeper->varTable[3] == 0) {
|
|
if (data->windowB_posX < SCREEN_WIDTH) {
|
|
data->windowB_posX += 10;
|
|
if (data->windowB_posX > SCREEN_WIDTH) {
|
|
data->windowB_posX = SCREEN_WIDTH;
|
|
}
|
|
}
|
|
} else {
|
|
if (data->windowB_posX > 225) {
|
|
data->windowB_posX -= 10;
|
|
if (data->windowB_posX < 225) {
|
|
data->windowB_posX = 225;
|
|
}
|
|
}
|
|
}
|
|
|
|
draw_box(0, 9, data->windowA_posX, 23, 0, 80, 38, 180, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, NULL, NULL, NULL, SCREEN_WIDTH, SCREEN_HEIGHT, NULL);
|
|
draw_msg(MESSAGE_ID(0x8,0x47), data->windowA_posX + 42, 28, 255, MSG_PAL_WHITE, 0);
|
|
draw_number(NUM_PANELS - data->found, data->windowA_posX + 65, 43, TRUE, MSG_PAL_WHITE, 255, 3);
|
|
draw_ci_image_with_clipping(&mgm_02_PeachPanelImg, 32, 32, G_IM_FMT_CI, G_IM_SIZ_4b, &mgm_02_PeachPanelPal,
|
|
data->windowA_posX + 5, 26, 10, 20, 300, 200, 255);
|
|
|
|
timeLeft = MIN(data->timeLeft, PLAY_TIME);
|
|
deciseconds = ((f32)(timeLeft % 30) * 10.0) / 30;
|
|
seconds = timeLeft / 30;
|
|
|
|
draw_box(0, 0xB, data->windowB_posX, 27, 0, 60, 20, 180, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, NULL, NULL, NULL, SCREEN_WIDTH, SCREEN_HEIGHT, NULL);
|
|
// draw whole seconds
|
|
draw_number(seconds, data->windowB_posX + 29, 31, TRUE, MSG_PAL_WHITE, 255, 3);
|
|
// draw tenths of seconds
|
|
draw_number(deciseconds, data->windowB_posX + 40, 31, TRUE, MSG_PAL_WHITE, 255, 0);
|
|
// draw dot
|
|
draw_msg(MESSAGE_ID(0x8,0x24), data->windowB_posX + 30, 29, 255, MSG_PAL_WHITE, 0);
|
|
}
|
|
|
|
void N(work_draw_score)(void) {
|
|
RenderTask task;
|
|
|
|
task.renderMode = RENDER_MODE_2D;
|
|
task.appendGfxArg = 0;
|
|
task.appendGfx = &mgm_02_draw_score_display;
|
|
task.distance = 0;
|
|
|
|
queue_render_task(&task);
|
|
}
|
|
|
|
ApiStatus N(CreateScoreDisplay)(Evt* script, s32 isInitialCall) {
|
|
SmashGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[SMASH_DATA_VAR_IDX];
|
|
s32 hudElemA, hudElemMeter;
|
|
|
|
if (isInitialCall) {
|
|
data->workerID = create_generic_entity_world(NULL, &mgm_02_work_draw_score);
|
|
|
|
hudElemA = hud_element_create(&HudScript_AButton);
|
|
data->hudElemID_AButton = hudElemA;
|
|
hud_element_set_render_depth(hudElemA, 0);
|
|
hud_element_set_flags(hudElemA, HUD_ELEMENT_FLAGS_80);
|
|
hud_element_set_tint(hudElemA, 255, 255, 255);
|
|
hud_element_set_script(hudElemA, &HudScript_AButton);
|
|
|
|
hudElemMeter = hud_element_create(&HudScript_BlueMeter);
|
|
data->hudElemID_Meter = hudElemMeter;
|
|
hud_element_set_render_depth(hudElemMeter, 0);
|
|
hud_element_set_flags(hudElemMeter, HUD_ELEMENT_FLAGS_80);
|
|
}
|
|
|
|
return ApiStatus_BLOCK;
|
|
}
|
|
|
|
ApiStatus N(DisableMenus)(Evt* script, s32 isInitialCall) {
|
|
gOverrideFlags |= GLOBAL_OVERRIDES_DISABLE_MENUS;
|
|
func_800E9894();
|
|
close_status_menu();
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(EnableMenus)(Evt* script, s32 isInitialCall) {
|
|
gOverrideFlags &= ~GLOBAL_OVERRIDES_DISABLE_MENUS;
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(DestroySignpost)(Evt* script, s32 isInitialCall) {
|
|
SmashGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[SMASH_DATA_VAR_IDX];
|
|
delete_entity(data->signpostEntity);
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(CreateSignpost)(void) {
|
|
SmashGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[SMASH_DATA_VAR_IDX];
|
|
s32 entityIndex = create_entity(&D_802EAFDC, 355, 20, -180, 0, 0, 0, 0, MAKE_ENTITY_END);
|
|
data->signpostEntity = entityIndex;
|
|
get_entity_by_index(entityIndex)->boundScriptBytecode = &D_80242A3C_E187BC;
|
|
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(OnHitBox)(Evt* script, s32 isInitialCall0) {
|
|
SmashGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[SMASH_DATA_VAR_IDX];
|
|
s32 hitModelID = evt_get_variable(script, LW(0xA));
|
|
s32 hitColliderID = evt_get_variable(script, LW(0xB)); // unused
|
|
s32 i;
|
|
|
|
for (i = 0; i < NUM_BOXES; i++) {
|
|
if (hitModelID == data->box[i].modelID) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
evt_set_variable(script, LW(0xC), data->box[i].content);
|
|
|
|
switch (data->box[i].content) {
|
|
case BOX_CONTENT_FUZZY:
|
|
evt_set_variable(script, LW(0xD), data->box[i].npcID);
|
|
data->box[i].state = BOX_STATE_FUZZY_HIT;
|
|
break;
|
|
case BOX_CONTENT_BOMB:
|
|
evt_set_variable(script, LW(0xD), data->box[i].npcID);
|
|
data->box[i].state = BOX_STATE_BOMB_HIT;
|
|
break;
|
|
case BOX_CONTENT_EMPTY:
|
|
evt_set_variable(script, LW(0xD), data->box[i].npcID);
|
|
data->box[i].state = BOX_STATE_EMPTY_HIT;
|
|
break;
|
|
case BOX_CONTENT_PEACH:
|
|
data->found++;
|
|
data->box[i].state = BOX_STATE_PEACH_HIT;
|
|
break;
|
|
}
|
|
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(SetBoxContents)(Evt* script, s32 isInitialCall) {
|
|
s32 initialConfiguration;
|
|
s32 configuration[NUM_BOXES];
|
|
s32 indexA, indexB, temp;
|
|
s32 i, j;
|
|
|
|
Enemy* enemy;
|
|
Npc* npc;
|
|
|
|
SmashGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[SMASH_DATA_VAR_IDX];
|
|
data->found = 0;
|
|
data->timeLeft = PLAY_TIME + 10;
|
|
data->currentScore = 0;
|
|
data->mashProgress = 0;
|
|
data->stunFlags = 0;
|
|
|
|
// choose one of three initial configurations at random
|
|
initialConfiguration = rand_int(1000) % ARRAY_COUNT(mgm_02_InitialConfigurations);
|
|
for (i = 0; i < NUM_BOXES; i++) {
|
|
configuration[i] = mgm_02_InitialConfigurations[initialConfiguration][i];
|
|
}
|
|
|
|
// randomly swap 10000 pairs
|
|
for (i = 0; i < 10000; i++) {
|
|
indexA = rand_int(1000) % NUM_BOXES;
|
|
indexB = rand_int(1000) % NUM_BOXES;
|
|
|
|
if (indexA != indexB) {
|
|
temp = configuration[indexB];
|
|
configuration[indexB] = configuration[indexA];
|
|
configuration[indexA] = temp;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < NUM_BOXES; i++) {
|
|
data->box[i].state = -1;
|
|
data->box[i].stateTimer = 0;
|
|
data->box[i].content = configuration[i];
|
|
data->box[i].modelID = mgm_02_BoxModelIDs[i];
|
|
data->box[i].colliderID = mgm_02_BoxColliderIDs[i];
|
|
data->box[i].npcID = -1;
|
|
data->box[i].peachPanelModelID = -1;
|
|
}
|
|
|
|
for (i = FUZZY_NPC_ID_BASE; i < FUZZY_NPC_ID_BASE + 5; i++) {
|
|
enemy = get_enemy(i);
|
|
enemy->varTable[0] = 0;
|
|
}
|
|
|
|
for (i = BOBOMB_NPC_ID_BASE; i < BOBOMB_NPC_ID_BASE + 5; i++) {
|
|
enemy = get_enemy(i);
|
|
enemy->varTable[0] = 0;
|
|
}
|
|
|
|
for (i = LUIGI_NPC_ID_BASE; i < LUIGI_NPC_ID_BASE + 10; i++) {
|
|
enemy = get_enemy(i);
|
|
enemy->varTable[0] = 0;
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_COUNT(D_80248600); i++) {
|
|
D_80248600[i] = FALSE;
|
|
}
|
|
|
|
for (i = 0; i < NUM_BOXES; i++) {
|
|
switch (data->box[i].content) {
|
|
case BOX_CONTENT_FUZZY:
|
|
data->box[i].state = BOX_STATE_FUZZY_INIT;
|
|
for (j = FUZZY_NPC_ID_BASE; j < FUZZY_NPC_ID_BASE + 5; j++) {
|
|
enemy = get_enemy(j);
|
|
if (enemy->varTable[0] == 0) {
|
|
npc = get_npc_unsafe(enemy->npcID);
|
|
enemy->varTable[0] = 1;
|
|
data->box[i].npcID = j;
|
|
disable_npc_shadow(npc);
|
|
npc->flags |= NPC_FLAG_2;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case BOX_CONTENT_BOMB:
|
|
data->box[i].state = BOX_STATE_BOMB_INIT;
|
|
for (j = BOBOMB_NPC_ID_BASE; j < BOBOMB_NPC_ID_BASE + 5; j++) {
|
|
enemy = get_enemy(j);
|
|
if (enemy->varTable[0] == 0) {
|
|
npc = get_npc_unsafe(enemy->npcID);
|
|
enemy->varTable[0] = 1;
|
|
data->box[i].npcID = j;
|
|
disable_npc_shadow(npc);
|
|
npc->flags |= NPC_FLAG_2;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case BOX_CONTENT_PEACH:
|
|
data->box[i].state = BOX_STATE_PEACH_INIT;
|
|
for (j = LUIGI_NPC_ID_BASE; j < LUIGI_NPC_ID_BASE + 10; j++) {
|
|
enemy = get_enemy(j);
|
|
if (enemy->varTable[0] == 0) {
|
|
npc = get_npc_unsafe(enemy->npcID);
|
|
enemy->varTable[0] = 1;
|
|
data->box[i].npcID = j;
|
|
disable_npc_shadow(npc);
|
|
npc->flags |= NPC_FLAG_2;
|
|
break;
|
|
}
|
|
}
|
|
// ARRAY BOUNDS ERROR IN ORIGINAL CODE!
|
|
for (j = 0; j <= ARRAY_COUNT(D_80248600); j++) {
|
|
if (!D_80248600[j]) {
|
|
D_80248600[j] = TRUE;
|
|
data->box[i].peachPanelModelID = mgm_02_PanelModelIDs[j];
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
data->box[i].state = BOX_STATE_EMPTY_INIT;
|
|
break;
|
|
}
|
|
}
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(RunMinigame)(Evt* script, s32 isInitialCall) {
|
|
SmashGameData* data;
|
|
Enemy* enemy;
|
|
|
|
Npc* npc;
|
|
s32 writeback;
|
|
|
|
Model* model;
|
|
Matrix4f mtx;
|
|
f32 centerX, centerY, centerZ;
|
|
f32 sizeX, sizeY, sizeZ;
|
|
s32 i;
|
|
|
|
s32 gameFinished;
|
|
s32 hittingPeachBlock;
|
|
|
|
gameFinished = FALSE;
|
|
hittingPeachBlock = FALSE;
|
|
data = get_enemy(0)->varTablePtr[0];
|
|
|
|
for (i = 0; i < NUM_BOXES; i++) {
|
|
if (data->box[i].npcID != -1) {
|
|
enemy = get_enemy(data->box[i].npcID);
|
|
npc = get_npc_unsafe(enemy->npcID);
|
|
switch (data->box[i].state) {
|
|
case BOX_STATE_FUZZY_INIT:
|
|
data->box[i].state = BOX_STATE_FUZZY_IDLE;
|
|
data->box[i].stateTimer = rand_int(210);
|
|
npc->pos.y = -1000.0f;
|
|
npc->flags &= -(NPC_FLAG_PASSIVE | NPC_FLAG_2);
|
|
disable_npc_shadow(npc);
|
|
// fallthrough
|
|
case BOX_STATE_FUZZY_IDLE:
|
|
data->box[i].stateTimer--;
|
|
if (data->box[i].stateTimer <= 0) {
|
|
npc->currentAnim.w = NPC_ANIM_fuzzy_Palette_00_Anim_2;
|
|
data->box[i].state = BOX_STATE_FUZZY_POPUP;
|
|
sfx_play_sound_at_position(enemy->varTable[8], 0x100000, npc->pos.x, npc->pos.y, npc->pos.z);
|
|
get_model_center_and_size(data->box[i].modelID, ¢erX, ¢erY, ¢erZ, &sizeX, &sizeY, &sizeZ);
|
|
npc->jumpVelocity = 10.5f;
|
|
npc->pos.x = centerX;
|
|
npc->jumpScale = 1.5f;
|
|
npc->pos.y = centerY - 12.5;
|
|
npc->moveToPos.y = npc->pos.y;
|
|
npc->pos.z = centerZ + 2.0;
|
|
data->box[i].stateTimer = 0;
|
|
}
|
|
break;
|
|
case BOX_STATE_FUZZY_POPUP:
|
|
data->box[i].stateTimer++;
|
|
npc->pos.y += npc->jumpVelocity;
|
|
npc->jumpVelocity -= npc->jumpScale;
|
|
if ((npc->moveToPos.y + 20.0f) < npc->pos.y) {
|
|
enable_npc_shadow(npc);
|
|
} else {
|
|
disable_npc_shadow(npc);
|
|
}
|
|
if ((npc->jumpVelocity < 0.0) && (npc->pos.y <= npc->moveToPos.y)) {
|
|
data->box[i].state = BOX_STATE_FUZZY_IDLE;
|
|
data->box[i].stateTimer = rand_int(330) + 90;
|
|
npc->pos.y = -1000.0f;
|
|
if (rand_int(100) < 50) {
|
|
npc->yaw = 270.0f;
|
|
} else {
|
|
npc->yaw = 90.0f;
|
|
}
|
|
disable_npc_shadow(npc);
|
|
}
|
|
break;
|
|
case BOX_STATE_FUZZY_HIT:
|
|
hud_element_set_script(data->hudElemID_AButton, &HudScript_AButton);
|
|
hud_element_set_alpha(data->hudElemID_AButton, 160);
|
|
hud_element_set_alpha(data->hudElemID_Meter, 160);
|
|
data->mashProgress = 0;
|
|
data->stunFlags |= STUN_FLAGS_GRABBED;
|
|
enable_npc_shadow(npc);
|
|
data->stunFlags |= (STUN_FLAGS_STUNNED | STUN_FLAGS_CHANGED);
|
|
npc->duration = 8;
|
|
sfx_play_sound(enemy->varTable[8]);
|
|
data->box[i].state = BOX_STATE_FUZZY_ATTACH;
|
|
gPlayerStatusPtr->anim = ANIM_CROUCH_STILL;
|
|
npc->currentAnim.w = NPC_ANIM_fuzzy_Palette_00_Anim_3;
|
|
get_model_center_and_size(data->box[i].modelID, ¢erX, ¢erY, ¢erZ, &sizeX, &sizeY, &sizeZ);
|
|
npc->pos.x = centerX;
|
|
npc->pos.y = centerY;
|
|
npc->pos.z = centerZ + 2.0;
|
|
npc->moveToPos.y = gPlayerStatusPtr->position.y + 35.0f;
|
|
npc->jumpVelocity = 10.5f;
|
|
npc->jumpScale = 1.5f;
|
|
|
|
data->box[i].stateTimer = 0;
|
|
fx_emote(EMOTE_EXCLAMATION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, 0.0f, 10, &writeback);
|
|
enemy->varTable[1] = npc->pos.x * 10.0f;
|
|
enemy->varTable[2] = npc->pos.y * 10.0f;
|
|
enemy->varTable[3] = npc->pos.z * 10.0f;
|
|
enemy->varTable[4] = gPlayerStatusPtr->position.x * 10.0f;
|
|
enemy->varTable[5] = (gPlayerStatusPtr->position.y + 28.0f) * 10.0f;
|
|
enemy->varTable[6] = (gPlayerStatusPtr->position.z + 2.0f) * 10.0f;
|
|
enemy->varTable[7] = 0;
|
|
break;
|
|
case BOX_STATE_FUZZY_ATTACH:
|
|
enemy->varTable[7]++;
|
|
npc->pos.x = update_lerp(EASING_LINEAR, (f32)enemy->varTable[1] / 10.0, (f32)enemy->varTable[4] / 10.0, enemy->varTable[7], 8);
|
|
npc->pos.y = update_lerp(EASING_LINEAR, (f32)enemy->varTable[2] / 10.0, (f32)enemy->varTable[5] / 10.0, enemy->varTable[7], 8);
|
|
npc->pos.z = update_lerp(EASING_LINEAR, (f32)enemy->varTable[3] / 10.0, (f32)enemy->varTable[6] / 10.0, enemy->varTable[7], 8);
|
|
gPlayerStatusPtr->anim = ANIM_CROUCH_STILL;
|
|
npc->duration--;
|
|
if (npc->duration <= 0) {
|
|
npc->currentAnim.w = NPC_ANIM_fuzzy_Palette_00_Anim_F;
|
|
gPlayerStatusPtr->anim = ANIM_RUN_PANIC;
|
|
data->mashProgress = 0;
|
|
npc->pos.x = gPlayerStatusPtr->position.x;
|
|
npc->pos.y = gPlayerStatusPtr->position.y + 28.0;
|
|
npc->pos.z = gPlayerStatusPtr->position.z + 2.0;
|
|
hud_element_set_script(data->hudElemID_AButton, &HudScript_MashAButton);
|
|
hud_element_set_alpha(data->hudElemID_AButton, 255);
|
|
hud_element_set_alpha(data->hudElemID_Meter, 255);
|
|
data->box[i].state = BOX_STATE_FUZZY_GRAB;
|
|
}
|
|
break;
|
|
case BOX_STATE_FUZZY_GRAB:
|
|
gPlayerStatusPtr->anim = ANIM_RUN_PANIC;
|
|
if (gGameStatusPtr->pressedButtons & BUTTON_A) {
|
|
data->mashProgress++;
|
|
}
|
|
if (data->mashProgress >= 12) {
|
|
gPlayerStatusPtr->anim = ANIM_10002;
|
|
data->stunFlags &= ~STUN_FLAGS_STUNNED;
|
|
data->stunFlags |= STUN_FLAGS_CHANGED;
|
|
data->box[i].state = BOX_STATE_FUZZY_DETACH;
|
|
npc->duration = 10;
|
|
hud_element_set_script(data->hudElemID_AButton, &HudScript_AButton);
|
|
hud_element_set_alpha(data->hudElemID_AButton, 160);
|
|
hud_element_set_alpha(data->hudElemID_Meter, 160);
|
|
npc->currentAnim.w = NPC_ANIM_fuzzy_Palette_00_Anim_8;
|
|
npc->pos.y += 3.0;
|
|
}
|
|
break;
|
|
case BOX_STATE_FUZZY_DETACH:
|
|
npc->duration--;
|
|
if (npc->duration == 8) {
|
|
data->stunFlags &= ~STUN_FLAGS_GRABBED;
|
|
}
|
|
if (npc->duration <= 0) {
|
|
data->box[i].state = BOX_STATE_FUZZY_DONE;
|
|
disable_npc_shadow(npc);
|
|
npc->flags |= NPC_FLAG_2;
|
|
fx_walking_dust(1, npc->pos.x, npc->pos.y + 10.0f, npc->pos.z + 1.0f, 0, 0);
|
|
}
|
|
break;
|
|
case BOX_STATE_FUZZY_DONE:
|
|
break;
|
|
|
|
case BOX_STATE_BOMB_INIT:
|
|
data->box[i].state = BOX_STATE_BOMB_IDLE;
|
|
data->box[i].stateTimer = rand_int(210);
|
|
npc->pos.y = -1000.0f;
|
|
disable_npc_shadow(npc);
|
|
npc->flags &= -(NPC_FLAG_PASSIVE | NPC_FLAG_2);
|
|
// fallthrough
|
|
case BOX_STATE_BOMB_IDLE:
|
|
data->box[i].stateTimer--;
|
|
if (data->box[i].stateTimer <= 0) {
|
|
data->box[i].state = BOX_STATE_BOMB_POPUP;
|
|
sfx_play_sound_at_position(enemy->varTable[8], 0x100000, npc->pos.x, npc->pos.y, npc->pos.z);
|
|
get_model_center_and_size(data->box[i].modelID, ¢erX, ¢erY, ¢erZ, &sizeX, &sizeY, &sizeZ);
|
|
npc->jumpVelocity = 10.5f;
|
|
npc->pos.x = centerX;
|
|
npc->jumpScale = 1.5f;
|
|
npc->pos.y = centerY - 12.5;
|
|
npc->moveToPos.y = npc->pos.y;
|
|
npc->pos.z = centerZ + 2.0;
|
|
data->box[i].stateTimer = 0;
|
|
}
|
|
break;
|
|
case BOX_STATE_BOMB_POPUP:
|
|
data->box[i].stateTimer++;
|
|
npc->pos.y += npc->jumpVelocity;
|
|
npc->jumpVelocity -= npc->jumpScale;
|
|
if ((npc->moveToPos.y + 20.0f) < npc->pos.y) {
|
|
enable_npc_shadow(npc);
|
|
} else {
|
|
disable_npc_shadow(npc);
|
|
}
|
|
if ((npc->jumpVelocity < 0.0) && (npc->pos.y <= npc->moveToPos.y)) {
|
|
data->box[i].state = BOX_STATE_BOMB_IDLE;
|
|
data->box[i].stateTimer = rand_int(330) + 90;
|
|
npc->pos.y = -1000.0f;
|
|
if (rand_int(100) < 50) {
|
|
npc->yaw = 270.0f;
|
|
} else {
|
|
npc->yaw = 90.0f;
|
|
}
|
|
disable_npc_shadow(npc);
|
|
}
|
|
break;
|
|
case BOX_STATE_BOMB_HIT:
|
|
enable_npc_shadow(npc);
|
|
npc->duration = 15;
|
|
npc->currentAnim.w = NPC_ANIM_bob_omb_Palette_00_Anim_5;
|
|
data->stunFlags |= (STUN_FLAGS_STUNNED | STUN_FLAGS_CHANGED);
|
|
data->box[i].state = BOX_STATE_BOMB_ATTACK;
|
|
get_model_center_and_size(data->box[i].modelID, ¢erX, ¢erY, ¢erZ, &sizeX, &sizeY, &sizeZ);
|
|
npc->pos.x = centerX;
|
|
npc->pos.y = centerY - 10.0f;
|
|
npc->pos.z = centerZ + 8.0;
|
|
fx_emote(EMOTE_EXCLAMATION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, 0.0f, 10, &writeback);
|
|
if (npc->pos.x > gPlayerStatusPtr->position.x) {
|
|
npc->yaw = 270.0f;
|
|
gPlayerStatusPtr->targetYaw = 95.0f;
|
|
} else {
|
|
npc->yaw = 90.0f;
|
|
gPlayerStatusPtr->targetYaw = 265.0f;
|
|
}
|
|
// rest of case could simply use fallthough, but wouldnt match
|
|
gPlayerStatusPtr->anim = ANIM_CROUCH_STILL;
|
|
npc->duration--;
|
|
if (npc->duration <= 0) {
|
|
fx_explosion(0, npc->pos.x, npc->pos.y, npc->pos.z + 1.0f);
|
|
npc->duration = 30;
|
|
npc->pos.y = -1000.0f;
|
|
data->box[i].state = BOX_STATE_BOMB_STUN;
|
|
sfx_play_sound(SOUND_BOMB_BLAST);
|
|
}
|
|
break;
|
|
case BOX_STATE_BOMB_ATTACK:
|
|
gPlayerStatusPtr->anim = ANIM_CROUCH_STILL;
|
|
npc->duration--;
|
|
if (npc->duration <= 0) {
|
|
fx_explosion(0, npc->pos.x, npc->pos.y, npc->pos.z + 1.0f);
|
|
npc->duration = 30;
|
|
npc->pos.y = -1000.0f;
|
|
data->box[i].state = BOX_STATE_BOMB_STUN;
|
|
sfx_play_sound(SOUND_BOMB_BLAST);
|
|
}
|
|
break;
|
|
case BOX_STATE_BOMB_STUN:
|
|
npc->duration--;
|
|
if (npc->duration == 25) {
|
|
gPlayerStatusPtr->anim = ANIM_CHARRED;
|
|
}
|
|
if (npc->duration <= 0) {
|
|
gPlayerStatusPtr->anim = ANIM_10002;
|
|
data->stunFlags &= ~STUN_FLAGS_STUNNED;
|
|
data->stunFlags |= STUN_FLAGS_CHANGED;
|
|
data->box[i].state = BOX_STATE_BOMB_DONE;
|
|
disable_npc_shadow(npc);
|
|
npc->flags |= NPC_FLAG_2;
|
|
}
|
|
break;
|
|
case BOX_STATE_BOMB_DONE:
|
|
break;
|
|
|
|
case BOX_STATE_PEACH_INIT:
|
|
get_model_center_and_size(data->box[i].modelID, ¢erX, ¢erY, ¢erZ, &sizeX, &sizeY, &sizeZ);
|
|
data->box[i].state = BOX_STATE_PEACH_IDLE;
|
|
data->box[i].stateTimer = rand_int(210);
|
|
npc->pos.x = centerX;
|
|
npc->pos.y = centerY;
|
|
npc->moveToPos.y = npc->pos.y;
|
|
npc->pos.z = centerZ + 2.0;
|
|
disable_npc_shadow(npc);
|
|
// fallthrough
|
|
case BOX_STATE_PEACH_IDLE:
|
|
data->box[i].stateTimer--;
|
|
if (data->box[i].stateTimer <= 0) {
|
|
get_model_center_and_size(data->box[i].modelID, ¢erX, ¢erY, ¢erZ, &sizeX, &sizeY, &sizeZ);
|
|
data->box[i].state = BOX_STATE_PEACH_POPUP;
|
|
sfx_play_sound_at_position(SOUND_214, 0x200000, npc->pos.x, npc->pos.y, npc->pos.z);
|
|
get_model_center_and_size(data->box[i].modelID, ¢erX, ¢erY, ¢erZ, &sizeX, &sizeY, &sizeZ);
|
|
npc->jumpVelocity = 10.0f;
|
|
npc->pos.y = npc->moveToPos.y;
|
|
npc->jumpScale = 1.1f;
|
|
data->box[i].stateTimer = 0;
|
|
model = get_model_from_list_index(get_model_list_index_from_tree_index(data->box[i].peachPanelModelID));
|
|
model->flags &= -(MODEL_FLAGS_FLAG_1 | MODEL_FLAGS_ENABLED);
|
|
if (!(model->flags & MODEL_FLAGS_HAS_TRANSFORM_APPLIED)) {
|
|
guTranslateF(model->transformMatrix, npc->pos.x, npc->pos.y, npc->pos.z);
|
|
model->flags |= (MODEL_FLAGS_USES_TRANSFORM_MATRIX | MODEL_FLAGS_HAS_TRANSFORM_APPLIED);
|
|
}
|
|
else {
|
|
guTranslateF(mtx, npc->pos.x, npc->pos.y, npc->pos.z);
|
|
guMtxCatF(mtx, model->transformMatrix, model->transformMatrix);
|
|
}
|
|
}
|
|
break;
|
|
case BOX_STATE_PEACH_POPUP:
|
|
data->box[i].stateTimer++;
|
|
npc->pos.y += npc->jumpVelocity;
|
|
npc->jumpVelocity -= npc->jumpScale;
|
|
model = get_model_from_list_index(get_model_list_index_from_tree_index(data->box[i].peachPanelModelID));
|
|
if (!(model->flags & MODEL_FLAGS_HAS_TRANSFORM_APPLIED)) {
|
|
guTranslateF(model->transformMatrix, npc->pos.x, npc->pos.y, npc->pos.z);
|
|
model->flags |= (MODEL_FLAGS_USES_TRANSFORM_MATRIX | MODEL_FLAGS_HAS_TRANSFORM_APPLIED);
|
|
} else {
|
|
guTranslateF(mtx, npc->pos.x, npc->pos.y, npc->pos.z);
|
|
guMtxCatF(mtx, model->transformMatrix, model->transformMatrix);
|
|
}
|
|
if ((npc->moveToPos.y + 20.0f) < npc->pos.y) {
|
|
enable_npc_shadow(npc);
|
|
} else {
|
|
disable_npc_shadow(npc);
|
|
}
|
|
if ((npc->jumpVelocity < 0.0) && (npc->pos.y <= npc->moveToPos.y)) {
|
|
data->box[i].state = BOX_STATE_PEACH_IDLE;
|
|
data->box[i].stateTimer = rand_int(330) + 90;
|
|
disable_npc_shadow(npc);
|
|
model->flags |= MODEL_FLAGS_ENABLED;
|
|
}
|
|
break;
|
|
case BOX_STATE_PEACH_HIT:
|
|
sfx_play_sound(SOUND_21C);
|
|
model = get_model_from_list_index(get_model_list_index_from_tree_index(data->box[i].peachPanelModelID));
|
|
enable_npc_shadow(npc);
|
|
npc->duration = 0;
|
|
data->box[i].state = BOX_STATE_PEACH_EMERGE;
|
|
model->flags &= -(MODEL_FLAGS_FLAG_1 | MODEL_FLAGS_ENABLED);
|
|
// fallthrough
|
|
case BOX_STATE_PEACH_EMERGE:
|
|
hittingPeachBlock = TRUE;
|
|
model = get_model_from_list_index(get_model_list_index_from_tree_index(data->box[i].peachPanelModelID));
|
|
centerY = update_lerp(EASING_QUADRATIC_OUT, npc->moveToPos.y, npc->moveToPos.y + 30.0, npc->duration, 30);
|
|
if (!(model->flags & MODEL_FLAGS_HAS_TRANSFORM_APPLIED)) {
|
|
guTranslateF(model->transformMatrix, npc->pos.x, centerY, npc->pos.z);
|
|
model->flags |= (MODEL_FLAGS_USES_TRANSFORM_MATRIX | MODEL_FLAGS_HAS_TRANSFORM_APPLIED);
|
|
} else {
|
|
guTranslateF(mtx, npc->pos.x, centerY, npc->pos.z);
|
|
guMtxCatF(mtx, model->transformMatrix, model->transformMatrix);
|
|
}
|
|
npc->duration++;
|
|
if (npc->duration >= 30) {
|
|
data->box[i].state = BOX_STATE_PEACH_DONE;
|
|
disable_npc_shadow(npc);
|
|
model->flags |= MODEL_FLAGS_ENABLED;
|
|
}
|
|
break;
|
|
case BOX_STATE_PEACH_DONE:
|
|
break;
|
|
}
|
|
} else {
|
|
if (data->box[i].state == BOX_STATE_EMPTY_INIT) {
|
|
data->box[i].state = BOX_STATE_EMPTY_IDLE;
|
|
data->box[i].stateTimer = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (data->timeLeft > 0) {
|
|
if (data->found < NUM_PANELS) {
|
|
data->timeLeft--;
|
|
if (data->timeLeft == 750) {
|
|
sfx_play_sound(SOUND_1A5);
|
|
} else if (data->timeLeft == 600) {
|
|
sfx_play_sound(SOUND_1A5);
|
|
} else if (data->timeLeft == 450) {
|
|
sfx_play_sound(SOUND_1A5);
|
|
} else if (data->timeLeft == 300) {
|
|
sfx_play_sound(SOUND_1A6);
|
|
} else if (data->timeLeft == 270) {
|
|
sfx_play_sound(SOUND_1A6);
|
|
} else if (data->timeLeft == 240) {
|
|
sfx_play_sound(SOUND_1A6);
|
|
} else if (data->timeLeft == 210) {
|
|
sfx_play_sound(SOUND_1A6);
|
|
} else if (data->timeLeft == 180) {
|
|
sfx_play_sound(SOUND_1A6);
|
|
} else if (data->timeLeft == 150) {
|
|
sfx_play_sound(SOUND_1A7);
|
|
} else if (data->timeLeft == 120) {
|
|
sfx_play_sound(SOUND_1A7);
|
|
} else if (data->timeLeft == 90) {
|
|
sfx_play_sound(SOUND_1A7);
|
|
} else if (data->timeLeft == 60) {
|
|
sfx_play_sound(SOUND_1A7);
|
|
} else if (data->timeLeft == 30) {
|
|
sfx_play_sound(SOUND_1A7);
|
|
}
|
|
}
|
|
if ((data->timeLeft > 0) && (data->found == NUM_PANELS)) {
|
|
if (!(data->stunFlags & STUN_FLAGS_STUNNED)) {
|
|
data->stunFlags |= (STUN_FLAGS_STUNNED | STUN_FLAGS_CHANGED);
|
|
}
|
|
}
|
|
}
|
|
if ((data->timeLeft == 0) && hittingPeachBlock) {
|
|
if (!(data->stunFlags & STUN_FLAGS_STUNNED)) {
|
|
data->stunFlags |= (STUN_FLAGS_STUNNED | STUN_FLAGS_CHANGED);
|
|
}
|
|
}
|
|
if (data->stunFlags & STUN_FLAGS_CHANGED) {
|
|
data->stunFlags &= ~STUN_FLAGS_CHANGED;
|
|
if (data->stunFlags & STUN_FLAGS_STUNNED) {
|
|
disable_player_input();
|
|
partner_disable_input();
|
|
} else {
|
|
enable_player_input();
|
|
partner_enable_input();
|
|
}
|
|
}
|
|
if (!hittingPeachBlock && ((data->found == 10) || ((data->timeLeft == 0)
|
|
&& (gPlayerStatusPtr->actionState != ACTION_STATE_HAMMER)))) {
|
|
gameFinished = TRUE;
|
|
}
|
|
if (gameFinished) {
|
|
if (data->stunFlags & STUN_FLAGS_STUNNED) {
|
|
enable_player_input();
|
|
partner_enable_input();
|
|
}
|
|
data->stunFlags = 0;
|
|
|
|
gPlayerStatusPtr->targetYaw = 180.0;
|
|
if (data->timeLeft == 0) {
|
|
sfx_play_sound(SOUND_MENU_ERROR);
|
|
gPlayerStatusPtr->anim = ANIM_10002;
|
|
} else {
|
|
sfx_play_sound(SOUND_D4);
|
|
gPlayerStatusPtr->anim = ANIM_10002;
|
|
}
|
|
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
return ApiStatus_BLOCK;
|
|
}
|
|
|
|
|
|
static char* N(exit_str_0) = "mgm_00";
|
|
|
|
ApiStatus N(UpdateRecords)(Evt* script, s32 isInitialCall) {
|
|
PlayerData* playerData = &gPlayerData;
|
|
SmashGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[SMASH_DATA_VAR_IDX];
|
|
s32 seconds, deciseconds;
|
|
s32 outScore;
|
|
|
|
seconds = data->timeLeft / 30;
|
|
deciseconds = ((f32)(data->timeLeft % 30) * 10.0) / 30;
|
|
|
|
data->currentScore = (seconds * 10) + deciseconds;
|
|
playerData->smashGameTotal += data->currentScore;
|
|
|
|
if (playerData->smashGameTotal > 99999) {
|
|
playerData->smashGameTotal = 99999;
|
|
}
|
|
if (playerData->smashGameRecord < data->currentScore) {
|
|
playerData->smashGameRecord = data->currentScore;
|
|
}
|
|
|
|
set_message_value(seconds, 0);
|
|
set_message_value(deciseconds, 1);
|
|
set_message_value(data->currentScore, 2);
|
|
|
|
outScore = data->currentScore;
|
|
if (data->currentScore == 0 && data->found == NUM_PANELS) {
|
|
outScore = -1;
|
|
}
|
|
evt_set_variable(script, LW(0), outScore);
|
|
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(GiveCoinReward)(Evt* script, s32 isInitialCall) {
|
|
SmashGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[SMASH_DATA_VAR_IDX];
|
|
s32 coinsLeft = data->currentScore;
|
|
s32 increment;
|
|
|
|
if (coinsLeft > 100) {
|
|
increment = 40;
|
|
} else if (coinsLeft > 75) {
|
|
increment = 35;
|
|
} else if (coinsLeft > 50) {
|
|
increment = 30;
|
|
} else if (coinsLeft > 30) {
|
|
increment = 10;
|
|
} else if (coinsLeft > 20) {
|
|
increment = 5;
|
|
} else if (coinsLeft > 10) {
|
|
increment = 2;
|
|
} else {
|
|
increment = 1;
|
|
}
|
|
|
|
data->currentScore -= increment;
|
|
add_coins(increment);
|
|
sfx_play_sound(SOUND_211);
|
|
|
|
return (data->currentScore > 0) ? ApiStatus_BLOCK : ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(CleanupGame)(Evt* script, s32 isInitialCall) {
|
|
Enemy* enemy = get_enemy(SCOREKEEPER_ENEMY_IDX);
|
|
SmashGameData* data = enemy->varTablePtr[SMASH_DATA_VAR_IDX];
|
|
Npc* npc;
|
|
u32 screenX, screenY,screenZ;
|
|
s32 writeback;
|
|
s32 i;
|
|
|
|
if (enemy->varTable[3] == 4) {
|
|
for (i = 0; i < NUM_BOXES; i++) {
|
|
if (data->box[i].npcID == -1) {
|
|
continue;
|
|
}
|
|
enemy = get_enemy(data->box[i].npcID);
|
|
npc = get_npc_unsafe(enemy->npcID);
|
|
if ((npc->flags & NPC_FLAG_2)) {
|
|
continue;
|
|
}
|
|
|
|
get_screen_coords(0, npc->pos.x, npc->pos.y, npc->pos.z, &screenX, &screenY, &screenZ);
|
|
if (screenX - 1 < SCREEN_WIDTH - 1) {
|
|
fx_walking_dust(1, npc->pos.x, npc->pos.y, npc->pos.z, 0, 0);
|
|
sfx_play_sound(SOUND_283);
|
|
}
|
|
npc->flags |= NPC_FLAG_2;
|
|
disable_npc_shadow(npc);
|
|
enemy->varTable[0] = 0;
|
|
}
|
|
return ApiStatus_DONE2;
|
|
} else {
|
|
for (i = 0; i < NUM_BOXES; i++) {
|
|
if (data->box[i].npcID == -1) {
|
|
continue;
|
|
}
|
|
enemy = get_enemy(data->box[i].npcID);
|
|
npc = get_npc_unsafe(enemy->npcID);
|
|
if ((npc->flags & NPC_FLAG_2)) {
|
|
continue;
|
|
}
|
|
|
|
switch (data->box[i].content) {
|
|
case BOX_CONTENT_FUZZY:
|
|
if (data->box[i].state != BOX_STATE_FUZZY_END) {
|
|
data->box[i].state = BOX_STATE_FUZZY_END;
|
|
fx_emote(EMOTE_QUESTION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, 0.0f, 30, &writeback);
|
|
npc->currentAnim.w = NPC_ANIM_fuzzy_Palette_00_Anim_E;
|
|
enable_npc_shadow(npc);
|
|
}
|
|
break;
|
|
|
|
case BOX_CONTENT_BOMB:
|
|
if (data->box[i].state != BOX_STATE_BOMB_END) {
|
|
data->box[i].state = BOX_STATE_BOMB_END;
|
|
fx_emote(EMOTE_QUESTION, npc, 0.0f, npc->collisionHeight, 1.0f, 2.0f, 0.0f, 30, &writeback);
|
|
npc->currentAnim.w = NPC_ANIM_bob_omb_Palette_00_Anim_1C;
|
|
enable_npc_shadow(npc);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return ApiStatus_BLOCK;
|
|
}
|
|
}
|
|
|
|
ApiStatus N(CreateMinigame)(Evt* script, s32 isInitialCall) {
|
|
Enemy* scorekeeper = get_enemy(SCOREKEEPER_ENEMY_IDX);
|
|
SmashGameData* data = heap_malloc(sizeof(*data));
|
|
scorekeeper->varTablePtr[SMASH_DATA_VAR_IDX] = data;
|
|
|
|
data->windowA_posX = -80;
|
|
data->windowB_posX = SCREEN_WIDTH;
|
|
data->timeLeft = PLAY_TIME;
|
|
|
|
func_800E9894();
|
|
close_status_menu();
|
|
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(DestroyMinigame)(Evt* script, s32 isInitialCall) {
|
|
SmashGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[SMASH_DATA_VAR_IDX];
|
|
|
|
free_generic_entity(data->workerID);
|
|
hud_element_free(data->hudElemID_AButton);
|
|
hud_element_free(data->hudElemID_Meter);
|
|
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(GetCoinCount)(Evt* script, s32 isInitialCall) {
|
|
evt_set_variable(script, LW(0xA), gPlayerData.coins);
|
|
return ApiStatus_DONE2;
|
|
}
|
|
|
|
ApiStatus N(TakeCoinCost)(Evt* script, s32 isInitialCall) {
|
|
PlayerData* playerData = &gPlayerData;
|
|
|
|
if (isInitialCall) {
|
|
playerData->smashGamePlays++;
|
|
script->functionTemp[0] = 0;
|
|
}
|
|
add_coins(-1);
|
|
sfx_play_sound(SOUND_211);
|
|
|
|
script->functionTemp[0]++;
|
|
return (script->functionTemp[0] == PLAY_COST) ? ApiStatus_DONE2 : ApiStatus_BLOCK;
|
|
}
|
|
|
|
ApiStatus N(HideCoinCounter)(Evt* script, s32 isInitialCall) {
|
|
hide_coin_counter_immediately();
|
|
return ApiStatus_DONE2;
|
|
}
|