#include "mgm_01.h" #include "hud_element.h" #include "effects.h" void delete_entity(s32 entityIndex); void set_message_images(MessageImageData* images); #define SCOREKEEPER_ENEMY_IDX 0 #define BROKEN_BLOCKS_VAR_IDX 2 #define TOTAL_BLOCKS_VAR_IDX 4 #define JUMP_DATA_VAR_IDX 5 #define PLAY_COST 10 #define NUM_BLOCKS 11 typedef enum JumpGamePanelType { PANEL_1_COIN = 0, PANEL_5_COINS = 1, PANEL_TIMES_5 = 2, PANEL_BOWSER = 3 } JumpGamePanelType; typedef enum JumpGamePanelState { PANEL_STATE_INIT = 0, PANEL_STATE_START_ANIM = 1, PANEL_STATE_EMERGE_INIT = 2, PANEL_STATE_EMERGE_UPDATE = 3, PANEL_STATE_HOLD_INIT = 4, PANEL_STATE_HOLD_UPDATE = 5, PANEL_STATE_TO_TALLY_INIT = 6, PANEL_STATE_TO_TALLY_UPDATE = 7, PANEL_STATE_STOP_ANIM = 8, PANEL_STATE_DONE = 9 } JumpGamePanelState; // the panels found by breaking brick blocks typedef struct JumpGamePanel { /* 0x00 */ JumpGamePanelState state; /* 0x04 */ s32 modelID; /* 0x08 */ JumpGamePanelType type; /* 0x0C */ s32 blockPosIndex; /* 0x10 */ s32 tallyPosIndex; /* 0x14 */ s32 entityIndex; /* 0x18 */ s32 lerpElapsed; /* 0x1C */ s32 lerpDuration; /* 0x20 */ Vec3f curPos; /* 0x2C */ Vec3f startPos; /* 0x38 */ Vec3f endPos; /* 0x44 */ f32 curAngle; /* 0x48 */ f32 startAngle; /* 0x4C */ f32 endAngle; /* 0x50 */ f32 curScale; /* 0x50 */ f32 startScale; /* 0x50 */ f32 endScale; } JumpGamePanel; /* size = 5C */ typedef struct JumpGameData { /* 0x000 */ s32 workerID; /* 0x004 */ s32 hudElemID; /* 0x008 */ s32 unk_08; // unused -- likely hudElemID for an unused/removed hud element /* 0x00C */ s32 currentScore; /* 0x010 */ s32 targetScore; /* 0x014 */ s32 scoreWindowPosX; /* 0x018 */ s32 scoreWindowPosY; // unused -- posY is hard-coded while drawing the box /* 0x01C */ s32 type[NUM_BLOCKS]; /* 0x048 */ s32 breakHistory[NUM_BLOCKS]; /* 0x074 */ JumpGamePanel panels[NUM_BLOCKS]; } JumpGameData; /* size = 0x468 */ extern EntityBlueprint D_802EA0C4; extern s32 MessagePlural; extern s32 MessageSingular; extern MessageImageData N(MsgImgs_Panels); extern s8 N(BlockPosX)[NUM_BLOCKS]; extern s8 N(BlockPosY)[NUM_BLOCKS]; extern s8 N(BlockPosZ)[NUM_BLOCKS]; extern f32 N(TallyPosX)[NUM_BLOCKS]; extern f32 N(TallyPosY)[NUM_BLOCKS]; extern s32 N(PanelModelIDs)[NUM_BLOCKS]; extern JumpGamePanelType N(PanelTypes)[NUM_BLOCKS]; extern JumpGamePanelType N(InitialConfigurations)[4][NUM_BLOCKS]; extern EvtScript* D_802435E8_E15D48[NUM_BLOCKS]; extern EvtScript D_80242310; extern EvtScript D_80242330; extern EvtScript D_80242350; extern EvtScript D_80242370; extern EvtScript D_80242390; extern EvtScript D_802423B0; extern EvtScript D_802423D0; extern EvtScript D_802423F0; extern EvtScript D_80242410; extern EvtScript D_80242430; extern EvtScript D_80242450; void N(draw_score_display) (void* renderData) { Enemy* scorekeeper = get_enemy(SCOREKEEPER_ENEMY_IDX); JumpGameData* data = (JumpGameData*)scorekeeper->varTable[JUMP_DATA_VAR_IDX]; s32 hudElemID; s32 diff; if (scorekeeper->varTable[BROKEN_BLOCKS_VAR_IDX] == -1) { if (data->scoreWindowPosX < SCREEN_WIDTH + 1) { data->scoreWindowPosX += 10; if (data->scoreWindowPosX > SCREEN_WIDTH + 1) { data->scoreWindowPosX = SCREEN_WIDTH + 1; } } } else { if (data->scoreWindowPosX > 220) { data->scoreWindowPosX -= 10; if (data->scoreWindowPosX < 220) { data->scoreWindowPosX = 220; } } } if (data->scoreWindowPosX < SCREEN_WIDTH + 1) { draw_box(0, 9, data->scoreWindowPosX, 28, 0, 72, 20, 255, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, NULL, NULL, NULL, SCREEN_WIDTH, SCREEN_HEIGHT, NULL); hudElemID = data->hudElemID; hud_element_set_render_pos(hudElemID, data->scoreWindowPosX + 15, 39); hud_element_draw_clipped(hudElemID); if (data->currentScore > data->targetScore) { data->currentScore = data->targetScore; } else if (data->currentScore < data->targetScore) { diff = data->targetScore - data->currentScore; if (diff > 100) { data->currentScore += 40; } else if (diff > 75) { data->currentScore += 35; } else if (diff > 50) { data->currentScore += 30; } else if (diff > 30) { data->currentScore += 20; } else if (diff > 20) { data->currentScore += 10; } else if (diff > 10) { data->currentScore += 5; } else if (diff > 5) { data->currentScore += 2; } else { data->currentScore++; } sfx_play_sound_with_params(SOUND_211, 0, 0x40, 0x32); } draw_number(data->currentScore, data->scoreWindowPosX + 63, 32, 1, 0, 255, 3); } } void N(work_draw_score)(void) { RenderTask task; task.renderMode = RENDER_MODE_2D; task.appendGfxArg = 0; task.appendGfx = &mgm_01_draw_score_display; task.distance = 0; queue_render_task(&task); } 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; } // arg0: index ApiStatus N(GetPanelInfo)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); evt_set_variable(script, LW(0), data->panels[index].state); evt_set_variable(script, LW(1), data->panels[index].modelID); evt_set_variable(script, LW(2), data->panels[index].type); evt_set_variable(script, LW(3), data->panels[index].tallyPosIndex); return ApiStatus_DONE2; } // arg0: index, arg1: newState ApiStatus N(SetPanelState)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); s32 value = evt_get_variable(script, *args++); data->panels[index].state = value; return ApiStatus_DONE2; } // arg0: index, arg1: newState ApiStatus N(InitPanelEmergeFromBlock)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); s32 blockPosIndex; data->panels[index].lerpElapsed = 0; data->panels[index].lerpDuration = 5; blockPosIndex = data->panels[index].blockPosIndex; data->panels[index].curPos.x = N(BlockPosX)[blockPosIndex]; data->panels[index].curPos.y = N(BlockPosY)[blockPosIndex] + 15.0; data->panels[index].curPos.z = N(BlockPosZ)[blockPosIndex] + 12; data->panels[index].startPos.x = data->panels[index].curPos.x; data->panels[index].startPos.y = data->panels[index].curPos.y; data->panels[index].startPos.z = data->panels[index].curPos.z; data->panels[index].endPos.x = data->panels[index].curPos.x; data->panels[index].endPos.y = data->panels[index].curPos.y + 35.0; data->panels[index].endPos.z = data->panels[index].curPos.z; data->panels[index].curAngle = 0; data->panels[index].endScale = 2.0; data->panels[index].curScale = 1.0; data->panels[index].startScale = 1.0; return ApiStatus_DONE2; } // arg0: index ApiStatus N(UpdatePanelEmergeFromBlock)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); data->panels[index].curPos.x = update_lerp(EASING_QUADRATIC_OUT, data->panels[index].startPos.x, data->panels[index].endPos.x, data->panels[index].lerpElapsed, data->panels[index].lerpDuration); data->panels[index].curPos.y = update_lerp(EASING_QUADRATIC_OUT, data->panels[index].startPos.y, data->panels[index].endPos.y, data->panels[index].lerpElapsed, data->panels[index].lerpDuration); data->panels[index].curPos.z = update_lerp(EASING_QUADRATIC_OUT, data->panels[index].startPos.z, data->panels[index].endPos.z, data->panels[index].lerpElapsed, data->panels[index].lerpDuration); data->panels[index].curScale = update_lerp(EASING_LINEAR, data->panels[index].startScale, data->panels[index].endScale, data->panels[index].lerpElapsed, data->panels[index].lerpDuration); data->panels[index].lerpElapsed++; if (data->panels[index].lerpElapsed >= data->panels[index].lerpDuration) { evt_set_variable(script, LW(3), TRUE); } else { evt_set_variable(script, LW(3), FALSE); } return ApiStatus_DONE2; } // arg0: index ApiStatus N(InitPanelHoldAboveBlock)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); data->panels[index].lerpElapsed = 0; data->panels[index].lerpDuration = 10; return ApiStatus_DONE2; } // arg0: index ApiStatus N(UpdatetPanelHoldAboveBlock)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); data->panels[index].lerpElapsed++; if (data->panels[index].lerpElapsed >= data->panels[index].lerpDuration) { evt_set_variable(script, LW(3), TRUE); } else { evt_set_variable(script, LW(3), FALSE); } return ApiStatus_DONE2; } // arg0: index, arg1: newState ApiStatus N(InitPanelMoveToTally)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); f32 dist; data->panels[index].lerpElapsed = 0; data->panels[index].curAngle = 0; data->panels[index].startAngle = 0; data->panels[index].startPos.x = data->panels[index].curPos.x; data->panels[index].startPos.y = data->panels[index].curPos.y; data->panels[index].startPos.z = data->panels[index].curPos.z; data->panels[index].startScale = data->panels[index].curScale; if (data->panels[index].type != PANEL_BOWSER) { data->panels[index].endPos.x = N(TallyPosX)[data->panels[index].tallyPosIndex]; data->panels[index].endPos.y = N(TallyPosY)[data->panels[index].tallyPosIndex]; data->panels[index].endPos.z = 110.0f; data->panels[index].endAngle = 360.0f; data->panels[index].endScale = 1.0f; } else { data->panels[index].endPos.x = 0; data->panels[index].endPos.y = 100.0f; data->panels[index].endPos.z = 120.0f; data->panels[index].endAngle = 720.0f; data->panels[index].endScale = 4.0f; } dist = dist3D( data->panels[index].startPos.x, data->panels[index].startPos.y, data->panels[index].startPos.z, data->panels[index].endPos.x, data->panels[index].endPos.y, data->panels[index].endPos.z); if (data->panels[index].type != PANEL_BOWSER) { data->panels[index].lerpDuration = (dist * 0.125) + 0.5; } else { data->panels[index].lerpDuration = (dist / 5.0) + 0.5; } return ApiStatus_DONE2; } // arg0: index ApiStatus N(UpdatePanelMoveToTally)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); data->panels[index].lerpElapsed++; data->panels[index].curPos.x = update_lerp(EASING_QUADRATIC_OUT, data->panels[index].startPos.x, data->panels[index].endPos.x, data->panels[index].lerpElapsed, data->panels[index].lerpDuration); data->panels[index].curPos.y = update_lerp(EASING_QUADRATIC_OUT, data->panels[index].startPos.y, data->panels[index].endPos.y, data->panels[index].lerpElapsed, data->panels[index].lerpDuration); data->panels[index].curPos.z = update_lerp(EASING_LINEAR, data->panels[index].startPos.z, data->panels[index].endPos.z, data->panels[index].lerpElapsed, data->panels[index].lerpDuration); data->panels[index].curAngle = update_lerp(EASING_LINEAR, data->panels[index].startAngle, data->panels[index].endAngle, data->panels[index].lerpElapsed, data->panels[index].lerpDuration); data->panels[index].curScale = update_lerp(EASING_LINEAR, data->panels[index].startScale, data->panels[index].endScale, data->panels[index].lerpElapsed, data->panels[index].lerpDuration); if (data->panels[index].lerpElapsed >= data->panels[index].lerpDuration) { evt_set_variable(script, LW(3), TRUE); } else { evt_set_variable(script, LW(3), FALSE); } return ApiStatus_DONE2; } // arg0: index ApiStatus N(EndPanelAnimation)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); data->panels[index].curAngle = 0; return ApiStatus_DONE2; } ApiStatus N(UpdateRecords)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; PlayerData* player = &gPlayerData; player->jumpGameTotal += data->currentScore; if (player->jumpGameTotal > 99999) { player->jumpGameTotal = 99999; } if (player->jumpGameRecord < data->currentScore) { player->jumpGameRecord = data->currentScore; } set_message_value(data->currentScore, 0); return ApiStatus_DONE2; } ApiStatus N(GiveCoinReward)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_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); data->targetScore = data->currentScore; sfx_play_sound(SOUND_211); if (data->currentScore > 0) { return ApiStatus_BLOCK; } else { return ApiStatus_DONE2; } } ApiStatus N(DoubleScore)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; s32 score = 2 * data->currentScore; data->currentScore = score; data->targetScore = score; return ApiStatus_DONE2; } ApiStatus N(EndBowserPanelAnimation)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; s32 i; for (i = 0; i < ARRAY_COUNT(data->panels); i++) { if (data->panels[i].type == PANEL_BOWSER && data->panels[i].state == PANEL_STATE_DONE) break; } data->panels[i].curPos.x = N(TallyPosX)[data->panels[i].tallyPosIndex]; data->panels[i].curPos.y = N(TallyPosY)[data->panels[i].tallyPosIndex]; data->panels[i].curPos.z = 110.0f; evt_set_variable(script, LW(1), data->panels[i].modelID); evt_set_float_variable(script, LW(5), data->panels[i].curPos.x); evt_set_float_variable(script, LW(6), data->panels[i].curPos.y); evt_set_float_variable(script, LW(7), data->panels[i].curPos.z); return ApiStatus_DONE2; } // arg0: index ApiStatus N(GetPanelPos)(Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); evt_set_float_variable(script, LW(5), data->panels[index].curPos.x); evt_set_float_variable(script, LW(6), data->panels[index].curPos.y); evt_set_float_variable(script, LW(7), data->panels[index].curPos.z); evt_set_float_variable(script, LW(8), data->panels[index].curAngle); evt_set_float_variable(script, LW(9), data->panels[index].curScale); return ApiStatus_DONE2; } ApiStatus N(DestroyBlockEntities) (Evt* script, s32 isInitialCall) { JumpGameData* data = (JumpGameData*)get_enemy(SCOREKEEPER_ENEMY_IDX)->varTable[JUMP_DATA_VAR_IDX]; s32 i; for (i = 0; i < ARRAY_COUNT(data->panels); i++) { if (data->panels[i].entityIndex >= 0) { fx_walking_dust(1, N(BlockPosX)[i], N(BlockPosY)[i] + 13, N(BlockPosZ)[i] + 5, 0, 0); delete_entity(data->panels[i].entityIndex); } } sfx_play_sound_with_params(SOUND_283, 0x50, 0, 0); return ApiStatus_DONE2; } ApiStatus N(OnBreakBlock)(Evt* script, s32 isInitialCall) { Enemy* scorekeeper = get_enemy(SCOREKEEPER_ENEMY_IDX); JumpGameData* data = (JumpGameData*)scorekeeper->varTable[JUMP_DATA_VAR_IDX]; Bytecode* args = script->ptrReadPos; s32 index = evt_get_variable(script, *args++); s32 blockType = data->type[index]; s32 historyPos = scorekeeper->varTable[BROKEN_BLOCKS_VAR_IDX]; s32 coins = 0; s32 i; data->breakHistory[historyPos] = blockType; data->panels[index].entityIndex = -1; for (i = 0; i < historyPos + 1; i++) { switch (data->breakHistory[i]) { case PANEL_1_COIN: coins += 1; break; case PANEL_5_COINS: coins += 5; break; case PANEL_TIMES_5: coins *= 5; break; case PANEL_BOWSER: sfx_play_sound(SOUND_MENU_ERROR); coins = 0; break; } } data->targetScore = coins; for (i = 0; i < ARRAY_COUNT(data->panels); i++) { if (blockType == data->panels[i].type && data->panels[i].state == PANEL_STATE_START_ANIM) { data->panels[i].state = PANEL_STATE_EMERGE_INIT; data->panels[i].blockPosIndex = index; data->panels[i].tallyPosIndex = historyPos; break; } } scorekeeper->varTable[BROKEN_BLOCKS_VAR_IDX]++; return ApiStatus_DONE2; } ApiStatus N(CreateBlockEntities)(Evt* script, s32 isInitialCall) { JumpGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[JUMP_DATA_VAR_IDX]; s32 entityIndex; s32 initialConfiguration; s32 indexA, indexB; s32 curBlockIdx; s32 temp; s32 i; EvtScript* scriptArray[] = { &D_80242310, &D_80242330, &D_80242350, &D_80242370, &D_80242390, &D_802423B0, &D_802423D0, &D_802423F0, &D_80242410, &D_80242430, &D_80242450 }; if (isInitialCall) { // choose one of four initial configurations at random initialConfiguration = rand_int(1000) % ARRAY_COUNT(N(InitialConfigurations)); for (i = 0; i < NUM_BLOCKS; i++) { data->type[i] = N(InitialConfigurations)[initialConfiguration][i]; } // randomly swap 1000 pairs for (i = 0; i < 1000; i++) { indexA = rand_int(10000) % NUM_BLOCKS; indexB = rand_int(10000) % NUM_BLOCKS; if (indexA != indexB) { temp = data->type[indexB]; data->type[indexB] = data->type[indexA]; data->type[indexA] = temp; } } script->functionTemp[0] = 0; script->functionTemp[1] = 0; } script->functionTemp[0]--; if (script->functionTemp[0] <= 0) { curBlockIdx = script->functionTemp[1]; entityIndex = create_entity(&D_802EA0C4, N(BlockPosX)[curBlockIdx], N(BlockPosY)[curBlockIdx], N(BlockPosZ)[curBlockIdx], 0, 0, 0, 0, MAKE_ENTITY_END); data->panels[curBlockIdx].entityIndex = entityIndex; get_entity_by_index(entityIndex)->boundScriptBytecode = scriptArray[curBlockIdx]; fx_sparkles(3, N(BlockPosX)[curBlockIdx], N(BlockPosY)[curBlockIdx] + 13, N(BlockPosZ)[curBlockIdx] + 5, 23.0f); sfx_play_sound(SOUND_213); script->functionTemp[0] = 3; script->functionTemp[1]++; } if (script->functionTemp[1] < NUM_BLOCKS) { return ApiStatus_BLOCK; } else { return ApiStatus_DONE2; } } const char* mgm_01_str = "mgm_00"; ApiStatus N(TakeCoinCost)(Evt* script, s32 isInitialCall) { PlayerData* playerData = &gPlayerData; if (isInitialCall) { playerData->jumpGamePlays++; script->functionTemp[0] = 0; } add_coins(-1); sfx_play_sound(SOUND_211); script->functionTemp[0]++; if (script->functionTemp[0] == PLAY_COST) { return ApiStatus_DONE2; } else { return ApiStatus_BLOCK; } } ApiStatus N(InitializePanels)(Evt* script, s32 isInitialCall) { JumpGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[JUMP_DATA_VAR_IDX]; s32 i; data->currentScore = 0; data->targetScore = 0; for (i = 0; i < ARRAY_COUNT(data->panels); i++) { data->panels[i].state = PANEL_STATE_INIT; data->panels[i].modelID = N(PanelModelIDs)[i]; data->panels[i].type = N(PanelTypes)[i]; data->panels[i].tallyPosIndex = -1; } return ApiStatus_DONE2; } ApiStatus N(CreateMinigame)(Evt* script, s32 isInitialCall) { Enemy* scorekeeper = get_enemy(SCOREKEEPER_ENEMY_IDX); JumpGameData* data = general_heap_malloc(sizeof(*data)); s32 hudElemID; scorekeeper->varTablePtr[JUMP_DATA_VAR_IDX] = data; data->workerID = create_generic_entity_world(NULL, &mgm_01_work_draw_score); hudElemID = hud_element_create(&HudScript_StatusCoin); data->hudElemID = hudElemID; hud_element_set_flags(data->hudElemID, HUD_ELEMENT_FLAGS_80); hud_element_set_tint(data->hudElemID, 255, 255, 255); data->scoreWindowPosX = SCREEN_WIDTH + 1; data->scoreWindowPosY = 28; func_800E9894(); close_status_menu(); return ApiStatus_DONE2; } ApiStatus N(DestroyMinigame) (Evt* script, s32 isInitialCall) { JumpGameData* data = get_enemy(SCOREKEEPER_ENEMY_IDX)->varTablePtr[JUMP_DATA_VAR_IDX]; free_generic_entity(data->workerID); hud_element_free(data->hudElemID); return ApiStatus_DONE2; } ApiStatus N(GetCoinCount)(Evt* script, s32 isInitialCall) { evt_set_variable(script, LW(0xA), gPlayerData.coins); return ApiStatus_DONE2; } ApiStatus N(SetMsgVars_BlocksRemaining)(Evt* script, s32 isInitialCall) { Enemy* scorekeeper = get_enemy(SCOREKEEPER_ENEMY_IDX); s32 remaining = (scorekeeper->varTable[TOTAL_BLOCKS_VAR_IDX] - scorekeeper->varTable[BROKEN_BLOCKS_VAR_IDX]) + 1; set_message_value(remaining, 0); set_message_msg((remaining == 1) ? (s32)&MessageSingular : (s32)&MessagePlural, 1); return ApiStatus_DONE2; } ApiStatus N(HideCoinCounter)(Evt* script, s32 isInitialCall) { hide_coin_counter_immediately(); return ApiStatus_DONE2; } ApiStatus N(SetMsgImgs_Panels)(Evt* script, s32 isInitialCall) { set_message_images(&N(MsgImgs_Panels)); return ApiStatus_DONE2; }