Files
ac-decomp/src/m_watch_my_step.c
T
2024-01-13 22:51:39 +01:00

643 lines
17 KiB
C

#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;
}