#include "m_watch_my_step.h" #include "libultra/libultra.h" #include "m_play.h" #include "m_actor_type.h" #include "m_item_name.h" #include "m_name_table.h" #include "m_player.h" #include "m_player_lib.h" #include "m_event.h" #include "m_field_info.h" #include "m_font.h" #include "m_mail.h" #include "m_common_data.h" #include "sys_matrix.h" #include "m_room_type.h" #include "m_msg.h" #include "audio.h" #include "m_scene_table.h" #include "m_private.h" typedef struct watch_my_step_s { f32 pos_x; f32 pos_y; f32 opacity; f32 trans_x; f32 trans_y; f32 scale; s16 timer; mActor_name_t item_no; u8 mode; u8 item_name[mIN_ITEM_NAME_LEN]; u8 draw_type; } mWt_watch_my_step_c; static mWt_watch_my_step_c S_watch_my_step; typedef struct navigate_s { f32 opacity; s16 timer; u8 mode; u8 draw_type; } mWt_navigate_c; static mWt_navigate_c S_navigate; typedef struct mybell_confirmation_s { f32 opacity; u32 all_money; s16 coin_sfx_timer; u8 mode; u8 draw_type; u8 update_money; u8 play_finish_sfx; } mWt_mybell_confirmation_c; static mWt_mybell_confirmation_c S_mybell_conf; extern void watch_my_step_ct() { bzero(&S_watch_my_step, sizeof(mWt_watch_my_step_c)); S_watch_my_step.item_no = EMPTY_NO; navigate_camera_ct(); mWt_mybell_confirmation_ct(); } extern void watch_my_step_move(GAME_PLAY* play) { mActor_name_t window_item; PLAYER_ACTOR* player_actor = get_player_actor_withoutCheck(play); int can_show = play->camera.now_main_index == CAMERA2_PROCESS_NORMAL && play->camera.main_data.normal.morph_counter > 20; navigate_camera_move(play); mWt_mybell_confirmation_move(play); S_watch_my_step.draw_type = 0; if (mEv_CheckTitleDemo() <= 0) { window_item = mPlib_Get_itemNo_forWindow(); switch (S_watch_my_step.mode) { case 0: { if (window_item != EMPTY_NO && !can_show) { S_watch_my_step.opacity = 0.0f; S_watch_my_step.timer = 2; S_watch_my_step.mode++; } break; } case 1: case 2: { if (S_watch_my_step.timer-- == 0) { S_watch_my_step.timer = 2; S_watch_my_step.mode++; } break; } case 3: { add_calc(&S_watch_my_step.opacity, 1.0f, 1.0f - sqrtf2(0.5), 0.25f, 0.15f); if (window_item == EMPTY_NO || can_show == TRUE) { S_watch_my_step.mode++; } break; } case 4: { add_calc(&S_watch_my_step.opacity, 0.0f, 1.0f - sqrtf2(0.5), 0.1f, 0.05f); add_calc(&S_watch_my_step.opacity, 0.0f, 1.0f - sqrtf2(0.5), 0.005f, 0.005f); if (S_watch_my_step.opacity < 0.01f) { S_watch_my_step.mode = 0; } break; } default: { S_watch_my_step.mode = 0; break; } } if (S_watch_my_step.mode != 0) { xyz_t position = player_actor->actor_class.world.position; xyz_t screen_pos; position.y += 30.0f; /* convert player position plus 75% of a unit up to screen position */ Game_play_Projection_Trans(play, &position, &screen_pos); if (S_watch_my_step.mode < 4) { S_watch_my_step.trans_x = 1.0f; if (screen_pos.x > 200.0f) { S_watch_my_step.trans_x = -1.0f; } else if (screen_pos.x > 120.0f && player_actor->actor_class.shape_info.rotation.y >= 0) { S_watch_my_step.trans_x = -1.0f; } S_watch_my_step.trans_y = 1.0f; if (screen_pos.y < 68.0f) { S_watch_my_step.trans_y = -1.0f; } S_watch_my_step.pos_x = screen_pos.x - (S_watch_my_step.trans_x * -40.0f + 160.0f); S_watch_my_step.pos_y = screen_pos.y - (S_watch_my_step.trans_y * 42.0f + 120.0f); } if (window_item != EMPTY_NO) { f32 size; int len; if (S_watch_my_step.item_no != window_item || S_watch_my_step.item_no == EMPTY_NO) { S_watch_my_step.item_no = window_item; mIN_copy_name_str(S_watch_my_step.item_name, (mActor_name_t)window_item); } len = mMl_strlen(S_watch_my_step.item_name, mIN_ITEM_NAME_LEN, CHAR_SPACE); size = (f32)(mFont_GetStringWidth(S_watch_my_step.item_name, len, TRUE)) * 0.875f - 17.5f; if (size < 0.0f) { size = 0.0f; } S_watch_my_step.scale = size / 122.5f; } else { S_watch_my_step.item_no = EMPTY_NO; } if (S_watch_my_step.mode != 0) { if ((mFI_GET_TYPE(mFI_GetFieldId()) == mFI_TYPE(mFI_FIELDTYPE_FG) && mEv_CheckFirstIntro() != TRUE) || // all items when correct mode outside but not during nook intro (Common_Get(field_type) == mFI_FIELDTYPE2_PLAYER_ROOM && !ITEM_IS_FTR(window_item)) // Non-furniture items when in player house ) { S_watch_my_step.draw_type = 1; } } } } } // TODO: @nonmatching extern void watch_my_step_draw(GAME_PLAY* play) { GAME* game = (GAME*)play; GRAPH* g = play->game.graph; Mtx* font_mtx; OPEN_DISP(g); font_mtx = GRAPH_ALLOC_TYPE(g, Mtx, 1); navigate_camera_draw(play); mWt_mybell_confirmation_draw(play); if (S_watch_my_step.draw_type == 0) { return; } /* load new world-view projection matrix for font */ if (font_mtx != NULL) { mFont_CulcOrthoMatrix(font_mtx); gSPMatrix(NOW_FONT_DISP++, font_mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); } Matrix_scale(16.0f, 16.0f, 16.0f, 0); Matrix_translate(S_watch_my_step.pos_x, -S_watch_my_step.pos_y, 0.0f, 1); { Gfx* font_gfx = NOW_FONT_DISP; gSPMatrix(font_gfx++, _Matrix_to_Mtx_new(g), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(font_gfx++, fki_win_mode); gDPSetRenderMode(font_gfx++, G_RM_CLD_SURF, G_RM_CLD_SURF2); switch (S_watch_my_step.mode) { case 3: { Matrix_push(); Matrix_scale( S_watch_my_step.opacity * (S_watch_my_step.scale * 0.75f + 0.25f), S_watch_my_step.opacity * (S_watch_my_step.scale * 0.23333335f + 0.76666665f), S_watch_my_step.opacity, 1 ); gSPMatrix(font_gfx++, _Matrix_to_Mtx_new(g), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); Matrix_pull(); gSPDisplayList(font_gfx++, fki_win_w3T_model); } /* fallthrough 3 -> 2 */ case 2: { Matrix_push(); Matrix_translate( S_watch_my_step.trans_x * -1.0f, S_watch_my_step.trans_y * -20.0f, 0.0f, 1 ); gSPMatrix(font_gfx++, _Matrix_to_Mtx_new(g), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); Matrix_pull(); gSPDisplayList(font_gfx++, fki_win_w2T_model); } /* fallthrough 2 -> 1 */ case 1: { Matrix_push(); Matrix_translate( S_watch_my_step.trans_x * -13.0f, S_watch_my_step.trans_y * -30.0f, 0.0f, 1 ); gSPMatrix(font_gfx++, _Matrix_to_Mtx_new(g), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); Matrix_pull(); gSPDisplayList(font_gfx++, fki_win_w1T_model); break; } case 4: { int a = S_watch_my_step.opacity * 255.0f; gDPSetPrimColor(font_gfx++, 0, a, 255, 255, 215, a); Matrix_push(); Matrix_scale( S_watch_my_step.scale * 0.75f + 0.25f, S_watch_my_step.scale * 0.23333335f + 0.76666665f, 0.1f, 1 ); gSPMatrix(font_gfx++, _Matrix_to_Mtx_new(g), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); Matrix_pull(); gSPDisplayList(font_gfx++, fki_win_w4_model); break; } } /* Reset font matrix scale */ Matrix_scale(1.0f, 1.0f, 1.0f, 0); gSPMatrix(font_gfx++, _Matrix_to_Mtx_new(g), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); SET_FONT_DISP(font_gfx); } CLOSE_DISP(g); if (S_watch_my_step.mode >= 3) { f32 text_opacity = (S_watch_my_step.opacity - 0.5f) * 2.0f; if (text_opacity > 0.0f) { /* nonmatch starts here */ int a = text_opacity * 255.0f; f32 x = 160.0f + (S_watch_my_step.pos_x - 0.5f * (S_watch_my_step.scale * 120.0f + 40.0f)); f32 y = 120.0f + (S_watch_my_step.pos_y - 0.5f * (S_watch_my_step.scale * 7.0f + 23.0f)); mFont_SetLineStrings( game, S_watch_my_step.item_name, mIN_ITEM_NAME_LEN, (1.0f - S_watch_my_step.scale) + x + 10.0f, S_watch_my_step.scale * 3.0f + y + 5.0f, 45, 45, 35, a, FALSE, TRUE, 0.875f, 0.875f, mFont_MODE_POLY ); } } } static void navigate_camera_ct() { bzero(&S_navigate, sizeof(mWt_navigate_c)); } static void navigate_camera_move(GAME_PLAY* play) { S_navigate.draw_type = 0; switch (S_navigate.mode) { case 0: { if (mPlib_check_able_change_camera_normal_index() != 0 && play->fb_fade_type == 0) { S_navigate.timer = 150; S_navigate.mode++; } break; } case 1: { add_calc(&S_navigate.opacity, 1.0f, 1.0f - sqrtf(0.8), 0.075f, 0.005f); S_navigate.timer--; if (S_navigate.timer == 0 || play->submenu.process_status != mSM_PROCESS_WAIT || mMsg_Check_MainHide(mMsg_Get_base_window_p()) == FALSE) { S_navigate.mode++; } if (mRmTp_PleaseDrawLightSwitch()) { S_navigate.draw_type = 2; } else { S_navigate.draw_type = 1; } break; } case 2: { add_calc(&S_navigate.opacity, 0.0f, 1.0f - sqrtf(0.8), 0.075f, 0.005f); if (S_navigate.opacity < 0.0001f) { S_navigate.mode++; } else if (mRmTp_PleaseDrawLightSwitch()) { S_navigate.draw_type = 2; } else { S_navigate.draw_type = 1; } break; } case 3: { break; } } } static void navigate_camera_draw(GAME_PLAY* play) { GRAPH* g = play->game.graph; Gfx* font_gfx; Mtx* font_mtx; OPEN_DISP(g); font_mtx = GRAPH_ALLOC_TYPE(g, Mtx, 1); if (S_navigate.draw_type != 0) { u8 a = S_navigate.opacity * 255.0f; if (font_mtx != NULL) { mFont_CulcOrthoMatrix(font_mtx); gSPMatrix(NOW_FONT_DISP++, font_mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); } Matrix_scale(16.0f, 16.0f, 16.0f, 0); font_gfx = NOW_FONT_DISP; gSPMatrix(font_gfx++, _Matrix_to_Mtx_new(g), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(font_gfx++, fki_win_mode); /* draw camera movement guide gfx */ gDPSetPrimColor(font_gfx++, 0, 255, 40, 40, 140, a); gSPDisplayList(font_gfx++, cam_win_winT_model); gDPSetPrimColor(font_gfx++, 0, 255, 245, 245, 30, a); gSPDisplayList(font_gfx++, cam_win_cT_model); gDPSetPrimColor(font_gfx++, 0, 255, 255, 255, 255, a); gSPDisplayList(font_gfx++, cam_win_mojiT_model); gDPSetPrimColor(font_gfx++, 0, 255, 30, 165, 30, a); gSPDisplayList(font_gfx++, cam_win_yajirushi_model); if (S_navigate.draw_type == 2) { /* draw light switch guide */ gDPSetPrimColor(font_gfx++, 0, 255, 40, 40, 140, a); gSPDisplayList(font_gfx++, elc_win_winT_model); gDPSetPrimColor(font_gfx++, 0, 255, 30, 0, 50, a); gSPDisplayList(font_gfx++, elc_win_zT_model); gDPSetPrimColor(font_gfx++, 0, 255, 215, 225, 255, a); gSPDisplayList(font_gfx++, elc_win_moji_model); gDPSetPrimColor(font_gfx++, 0, 255, 255, 255, 255, a); gSPDisplayList(font_gfx++, elc_win_moji2T_model); } SET_FONT_DISP(font_gfx); // comenting this out fixes above flow but is wrong } CLOSE_DISP(g); } static void mWt_set_coin_se(int play_flag) { static int S_se_play_flg; if (play_flag == FALSE) { if (S_se_play_flg == TRUE) { sAdo_SysLevStop(NA_SE_COIN); // TODO: enum for sound effects S_mybell_conf.update_money = FALSE; S_mybell_conf.play_finish_sfx = FALSE; S_mybell_conf.coin_sfx_timer = 0; } } else if (S_se_play_flg == FALSE) { sAdo_SysLevStart(NA_SE_COIN); S_mybell_conf.update_money = TRUE; S_mybell_conf.play_finish_sfx = FALSE; S_mybell_conf.coin_sfx_timer = 300; } S_se_play_flg = play_flag; } static u32 get_all_money(); static void mWt_mybell_confirmation_ct() { bzero(&S_mybell_conf, sizeof(S_mybell_conf)); S_mybell_conf.all_money = get_all_money(); mWt_set_coin_se(FALSE); } static void mWt_mybell_confirmation_move(GAME_PLAY* play) { static int place_chk[8] = { SCENE_SHOP0, SCENE_CONVENI, SCENE_SUPER, SCENE_DEPART, SCENE_DEPART_2, SCENE_BROKER_SHOP, SCENE_POST_OFFICE, SCENE_NEEDLEWORK }; int i; S_mybell_conf.draw_type = 0; if (S_mybell_conf.play_finish_sfx == TRUE) { sAdo_SysTrgStart(SE_REGISTER); S_mybell_conf.play_finish_sfx = FALSE; } if (S_mybell_conf.coin_sfx_timer != 0) { if (--S_mybell_conf.coin_sfx_timer <= 0) { mWt_set_coin_se(FALSE); } } for (i = 0; i < 8; i++) { if (Save_Get(scene_no) == place_chk[i]) { break; } } if ((u32)i == 8 || mEv_CheckFirstJob() == TRUE || (i <= 4 && Common_Get(tanuki_shop_status) == mSP_TANUKI_SHOP_STATUS_FUKUBIKI)) { if (S_mybell_conf.update_money == TRUE) { S_mybell_conf.all_money = get_all_money(); mWt_set_coin_se(FALSE); } S_mybell_conf.update_money = FALSE; } else { switch (S_mybell_conf.mode) { case 0: { if (play->submenu.process_status == mSM_PROCESS_WAIT) { S_mybell_conf.mode++; } break; } case 1: { f32 money = S_mybell_conf.all_money; u32 now_money = get_all_money(); if (S_mybell_conf.all_money != now_money) { mWt_set_coin_se(TRUE); } if (play->submenu.process_status != mSM_PROCESS_WAIT) { S_mybell_conf.mode++; } if ((S_mybell_conf.update_money == TRUE) && (S_mybell_conf.all_money == now_money || S_mybell_conf.mode == 2)) { mWt_set_coin_se(FALSE); if (S_mybell_conf.all_money == now_money) { S_mybell_conf.play_finish_sfx = TRUE; } } add_calc(&money, now_money, 0.1f, 10000.0f, 1.0f); S_mybell_conf.all_money = money; add_calc(&S_mybell_conf.opacity, 1.0f, 1.0f - sqrtf(0.8), 0.075f, 0.005f); S_mybell_conf.draw_type = 1; break; } case 2: { add_calc(&S_mybell_conf.opacity, 0.0f, 1.0f - sqrtf(0.8), 0.05f, 0.005f); if (S_mybell_conf.opacity < 0.0001f) { S_mybell_conf.mode = 0; } else { S_mybell_conf.draw_type = 1; } break; } case 3: { break; } } } } static void mWt_mybell_confirmation_draw(GAME_PLAY* play) { GAME* game = (GAME*)play; GRAPH* g = play->game.graph; Mtx* font_mtx; Gfx* font_gfx; font_mtx = GRAPH_ALLOC_TYPE(g, Mtx, 1); if (S_mybell_conf.draw_type != 0) { u8 a = S_mybell_conf.opacity * 255.0f; OPEN_DISP(g); if (font_mtx != NULL) { mFont_CulcOrthoMatrix(font_mtx); gSPMatrix(NOW_FONT_DISP++, font_mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); } Matrix_scale(16.0f, 16.0f, 16.0f, 0); font_gfx = NOW_FONT_DISP; gSPMatrix(font_gfx++, _Matrix_to_Mtx_new(g), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(font_gfx++, fki_win_mode); gDPSetRenderMode(font_gfx++, G_RM_CLD_SURF, G_RM_CLD_SURF2); gDPSetPrimColor(font_gfx++, 0, a, 95, 50, 175, a); gSPDisplayList(font_gfx++, mny_win_ueT_model); gDPSetRenderMode(font_gfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2); gDPSetPrimColor(font_gfx++, 0, a, 255, 245, 255, a); gSPDisplayList(font_gfx++, mny_win_beruT_model); /* Draw "Bells" string (as pre-rendered image) */ gDPSetPrimColor(font_gfx++, 0, a, 255, 245, 255, a); gSPDisplayList(font_gfx++, mny_win_mojiT_model); Matrix_scale(1.0f, 1.0f, 1.0f, 0); gSPMatrix(font_gfx++, _Matrix_to_Mtx_new(g), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); SET_FONT_DISP(font_gfx); CLOSE_DISP(g); /* Draw bell amount */ { u8 bell_str[7]; f32 t; int len; mFont_UnintToString(bell_str, 7, S_mybell_conf.all_money, 6, TRUE, FALSE, TRUE); len = mMl_strlen(bell_str, 7, CHAR_SPACE); mFont_SetLineStrings( game, bell_str, 7, 260.0f - (mFont_GetStringWidth(bell_str, len, TRUE) * 0.75f), 48.0f, 255, 245, 0, a, FALSE, TRUE, 0.75f, 0.75f, mFont_MODE_FONT ); } } } static u32 get_all_money() { static mActor_name_t fg_name[MONEY_NUM] = { ITM_MONEY_1000, ITM_MONEY_10000, ITM_MONEY_30000, ITM_MONEY_100 }; static u32 amount[MONEY_NUM] = { 1000, 10000, 30000, 100 }; u32 money = Common_Get(now_private)->inventory.wallet; int i; for (i = 0; i < MONEY_NUM; i++) { int sum = mPr_GetPossessionItemSumWithCond(Common_Get(now_private), fg_name[i], mPr_ITEM_COND_NORMAL); money += sum * amount[i]; } return money; }