mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-06-22 06:56:33 -04:00
@@ -419,6 +419,10 @@ ac_field_draw.c:
|
||||
.rodata: [0x80643F00, 0x80643F88]
|
||||
.data: [0x806829E0, 0x80682B68]
|
||||
.bss: [0x812F98C0, 0x812F9C28]
|
||||
ac_flag.c:
|
||||
.text: [0x80423E30, 0x80424B88]
|
||||
.rodata: [0x80643F88, 0x80643FC0]
|
||||
.data: [0x80682B90, 0x80682C00]
|
||||
ac_handOverItem.c:
|
||||
.text: [0x80426A50, 0x80427624]
|
||||
.rodata: [0x806440A0, 0x806440B8]
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
#define AC_FLAG_H
|
||||
|
||||
#include "types.h"
|
||||
#include "m_actor.h"
|
||||
#include "ac_structure.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -2725,6 +2725,7 @@ extern int mNT_check_unknown(mActor_name_t item_no);
|
||||
#define DUMMY_LOTUS 0xF11B
|
||||
#define DUMMY_DOUZOU 0xF11D
|
||||
#define DUMMY_NAMEPLATE 0xF11F
|
||||
#define DUMMY_FLAG 0xF122
|
||||
#define DUMMY_TENT 0xF127
|
||||
#define DUMMY_BOAT 0xF128
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ typedef struct original_texture_s {
|
||||
typedef struct original_data_s {
|
||||
/* 0x000 */ u8 name[mNW_ORIGINAL_DESIGN_NAME_LEN];
|
||||
/* 0x010 */ u8 palette;
|
||||
|
||||
/* 0x011 */ u8 flag_design_set;
|
||||
/* 0x020 */ mNW_original_tex_c design; /* this is aligned to 32 bytes for ARAM transfer */
|
||||
} mNW_original_design_c;
|
||||
|
||||
|
||||
+407
@@ -0,0 +1,407 @@
|
||||
#include "ac_flag.h"
|
||||
|
||||
#include "m_name_table.h"
|
||||
#include "sys_matrix.h"
|
||||
#include "m_lib.h"
|
||||
#include "m_rcp.h"
|
||||
#include "m_common_data.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "m_msg.h"
|
||||
#include "m_debug.h"
|
||||
|
||||
enum {
|
||||
aFLAG_ACTION_WAIT,
|
||||
aFLAG_ACTION_TALK,
|
||||
aFLAG_ACTION_TALK_END,
|
||||
aFLAG_ACTION_OPEN_WAIT,
|
||||
aFLAG_ACTION_END_WAIT,
|
||||
aFLAG_ACTION_UP,
|
||||
aFLAG_ACTION_DOWN,
|
||||
|
||||
aFLAG_ACTION_NUM
|
||||
};
|
||||
|
||||
static void aFLAG_actor_ct(ACTOR* actor, GAME* game);
|
||||
static void aFLAG_actor_dt(ACTOR* actor, GAME* game);
|
||||
static void aFLAG_actor_init(ACTOR* actor, GAME* game);
|
||||
static void aFLAG_actor_draw(ACTOR* actor, GAME* game);
|
||||
|
||||
ACTOR_PROFILE Flag_Profile = {
|
||||
mAc_PROFILE_FLAG,
|
||||
ACTOR_PART_ITEM,
|
||||
ACTOR_STATE_TA_SET,
|
||||
FLAG,
|
||||
ACTOR_OBJ_BANK_KEEP,
|
||||
sizeof(STRUCTURE_ACTOR),
|
||||
&aFLAG_actor_ct,
|
||||
&aFLAG_actor_dt,
|
||||
&aFLAG_actor_init,
|
||||
&aFLAG_actor_draw,
|
||||
NULL
|
||||
};
|
||||
|
||||
static u8 aFLAG_shadow_vtx_fix_flg_table[8] = { FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE };
|
||||
|
||||
extern Vtx obj_frag_shadow_v[];
|
||||
extern Gfx obj_frag_shadowT_model[];
|
||||
static bIT_ShadowData_c aFLAG_shadow_data = {
|
||||
8,
|
||||
aFLAG_shadow_vtx_fix_flg_table,
|
||||
60.0f,
|
||||
obj_frag_shadow_v,
|
||||
obj_frag_shadowT_model
|
||||
};
|
||||
|
||||
extern cKF_Skeleton_R_c cKF_bs_r_obj_s_frag;
|
||||
extern cKF_Skeleton_R_c cKF_bs_r_obj_w_frag;
|
||||
extern cKF_Animation_R_c cKF_ba_r_obj_s_frag;
|
||||
extern cKF_Animation_R_c cKF_ba_r_obj_w_frag;
|
||||
|
||||
extern u8 hakushi_tex[];
|
||||
extern u16 hakushi_pal[];
|
||||
|
||||
static void aFLAG_setup_action(STRUCTURE_ACTOR* flag, int action);
|
||||
|
||||
static void aFLAG_actor_ct(ACTOR* actor, GAME* game) {
|
||||
static cKF_Skeleton_R_c* skl[] = { &cKF_bs_r_obj_s_frag, &cKF_bs_r_obj_w_frag };
|
||||
static cKF_Animation_R_c* ani[] = { &cKF_ba_r_obj_s_frag, &cKF_ba_r_obj_w_frag };
|
||||
|
||||
STRUCTURE_ACTOR* flag;
|
||||
int isWinter;
|
||||
|
||||
flag = (STRUCTURE_ACTOR*)actor;
|
||||
isWinter = Common_Get(time.season) == mTM_SEASON_WINTER;
|
||||
flag->action = 32;
|
||||
flag->arg1_f = 132.5f;
|
||||
|
||||
cKF_SkeletonInfo_R_ct(&flag->keyframe, skl[isWinter], ani[isWinter], flag->work_area, flag->morph_area);
|
||||
cKF_SkeletonInfo_R_init_standard_repeat(&flag->keyframe, ani[isWinter], NULL);
|
||||
cKF_SkeletonInfo_R_play(&flag->keyframe);
|
||||
|
||||
aFLAG_setup_action(flag, aFLAG_ACTION_WAIT);
|
||||
}
|
||||
|
||||
static void aFLAG_actor_dt(ACTOR* actor, GAME* game) {
|
||||
STRUCTURE_ACTOR* flag = (STRUCTURE_ACTOR*)actor;
|
||||
cKF_SkeletonInfo_R_dt(&flag->keyframe);
|
||||
}
|
||||
|
||||
static void aFLAG_set_talk_info(ACTOR* actor) {
|
||||
rgba_t window_color;
|
||||
|
||||
mDemo_Set_msg_num(0x3066);
|
||||
mDemo_Set_talk_display_name(FALSE);
|
||||
mDemo_Set_ListenAble();
|
||||
|
||||
window_color.r = 185;
|
||||
window_color.g = 60;
|
||||
window_color.b = 40;
|
||||
window_color.a = 255;
|
||||
|
||||
mDemo_Set_talk_window_color(&window_color);
|
||||
mDemo_Set_camera(TRUE);
|
||||
mDemo_Set_use_zoom_sound(TRUE);
|
||||
}
|
||||
|
||||
static void aFLAG_talk_end(STRUCTURE_ACTOR* flag, GAME_PLAY* game_play) {
|
||||
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
|
||||
|
||||
if (mMsg_Check_main_wait(msg_p) != FALSE) {
|
||||
mMsg_request_main_forceoff();
|
||||
aFLAG_setup_action(flag, aFLAG_ACTION_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aFLAG_talk(STRUCTURE_ACTOR* flag, GAME_PLAY* game_play) {
|
||||
mMsg_Window_c* msg_p;
|
||||
PLAYER_ACTOR* player_actor;
|
||||
s16 target_y;
|
||||
s_xyz target_rot;
|
||||
|
||||
msg_p = mMsg_Get_base_window_p();
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, (ACTOR*)flag) != FALSE) {
|
||||
player_actor = get_player_actor_withoutCheck(game_play);
|
||||
|
||||
target_rot = player_actor->actor_class.shape_info.rotation;
|
||||
target_y = search_position_angleY(&player_actor->actor_class.world.position, &flag->actor_class.world.position);
|
||||
add_calc_short_angle2(&target_rot.y, target_y, 0.3f, 0x1000, 0x100);
|
||||
|
||||
(*get_player_actor_withoutCheck((GAME_PLAY*)gamePT)->Set_force_position_angle_proc)(
|
||||
gamePT, NULL, &target_rot, mPlayer_FORCE_POSITION_ANGLE_ROTY);
|
||||
|
||||
if (mMsg_Check_MainNormalContinue(msg_p) == TRUE) {
|
||||
switch (mChoice_Get_ChoseNum(mChoice_Get_base_window_p())) {
|
||||
case mChoice_CHOICE0:
|
||||
mMsg_request_main_disappear_wait_type1(mMsg_Get_base_window_p());
|
||||
aFLAG_setup_action(flag, aFLAG_ACTION_DOWN);
|
||||
break;
|
||||
|
||||
case mChoice_CHOICE1:
|
||||
mMsg_request_main_disappear_wait_type1(mMsg_Get_base_window_p());
|
||||
aFLAG_setup_action(flag, aFLAG_ACTION_TALK_END);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
aFLAG_setup_action(flag, aFLAG_ACTION_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aFLAG_wait(STRUCTURE_ACTOR* flag, GAME_PLAY* game_play) {
|
||||
PLAYER_ACTOR* player_actor;
|
||||
if (mDemo_Check(mDemo_TYPE_TALK, (ACTOR*)flag) == FALSE) {
|
||||
player_actor = get_player_actor_withoutCheck(game_play);
|
||||
if (player_actor != NULL) {
|
||||
mDemo_Request(mDemo_TYPE_TALK, (ACTOR*)flag, aFLAG_set_talk_info);
|
||||
}
|
||||
} else {
|
||||
aFLAG_setup_action(flag, aFLAG_ACTION_TALK);
|
||||
}
|
||||
}
|
||||
|
||||
static void aFLAG_menu_open_wait(STRUCTURE_ACTOR* flag, GAME_PLAY* game_play) {
|
||||
mSM_open_submenu(&game_play->submenu, mSM_OVL_NEEDLEWORK, 0, common_data.player_no);
|
||||
aFLAG_setup_action(flag, aFLAG_ACTION_END_WAIT);
|
||||
}
|
||||
|
||||
static void aFLAG_menu_end_wait(STRUCTURE_ACTOR* flag, GAME_PLAY* game_play) {
|
||||
Submenu* submenu;
|
||||
Submenu_Item_c* sm_item;
|
||||
u8 design_index;
|
||||
|
||||
submenu = &game_play->submenu;
|
||||
if (submenu->open_flag == FALSE) {
|
||||
sm_item = submenu->item_p;
|
||||
if (sm_item->item == RSV_NO) {
|
||||
design_index = mNW_get_image_no(submenu, sm_item->slot_no) & 7;
|
||||
|
||||
bcopy(Player_Design_Get(design_index), Save_GetPointer(island.flag_design.design),
|
||||
sizeof(mNW_original_tex_c));
|
||||
osWritebackDCache(Save_GetPointer(island.flag_design.design), sizeof(mNW_original_tex_c));
|
||||
|
||||
Save_Get(island.flag_design).flag_design_set = TRUE;
|
||||
Save_Get(island.flag_design).palette = Player_Palette_Get(design_index);
|
||||
|
||||
sAdo_OngenTrgStart(0x461, &flag->actor_class.world.position);
|
||||
|
||||
mISL_SetNowPlayerAction(4);
|
||||
}
|
||||
|
||||
sAdo_OngenTrgStart(0x163, &flag->actor_class.world.position);
|
||||
aFLAG_setup_action(flag, aFLAG_ACTION_UP);
|
||||
}
|
||||
}
|
||||
|
||||
static void aFLAG_up(STRUCTURE_ACTOR* flag, GAME_PLAY* game_play) {
|
||||
f32 starting_x;
|
||||
f32 middle_x;
|
||||
f32 ending_x;
|
||||
f32 ending_frame;
|
||||
f32 third_point_frame;
|
||||
f32 second_point_frame;
|
||||
f32 first_point_frame;
|
||||
f32 normalized_x_length;
|
||||
|
||||
// Flag moves from bottom to top in two distinct "phases" as if the rope was pulled twice
|
||||
starting_x = 72.5f;
|
||||
middle_x = 110.0f;
|
||||
ending_x = 132.5f;
|
||||
ending_frame = 100.0f;
|
||||
third_point_frame = 70.0f;
|
||||
second_point_frame = 55.0f;
|
||||
first_point_frame = 15.0f;
|
||||
|
||||
if (REGADDR(NMREG, 0) != 0) {
|
||||
starting_x = REGADDR(NMREG, 0);
|
||||
}
|
||||
|
||||
if (REGADDR(NMREG, 1) != 0) {
|
||||
ending_x = REGADDR(NMREG, 1);
|
||||
}
|
||||
|
||||
if (REGADDR(NMREG, 2) != 0) {
|
||||
middle_x = REGADDR(NMREG, 2);
|
||||
}
|
||||
|
||||
if (REGADDR(NMREG, 3) != 0) {
|
||||
ending_frame = REGADDR(NMREG, 3);
|
||||
}
|
||||
|
||||
if (REGADDR(NMREG, 4) != 0) {
|
||||
second_point_frame = REGADDR(NMREG, 4);
|
||||
}
|
||||
|
||||
if (REGADDR(NMREG, 5) != 0) {
|
||||
first_point_frame = REGADDR(NMREG, 5);
|
||||
}
|
||||
|
||||
if (REGADDR(NMREG, 6) != 0) {
|
||||
third_point_frame = REGADDR(NMREG, 6);
|
||||
}
|
||||
|
||||
if (flag->arg1 == second_point_frame) {
|
||||
sAdo_OngenTrgStart(0x163U, &flag->actor_class.world.position);
|
||||
}
|
||||
|
||||
if (flag->arg1 <= first_point_frame) {
|
||||
normalized_x_length = (middle_x - starting_x) / (first_point_frame * second_point_frame);
|
||||
flag->arg1_f = starting_x + (normalized_x_length * flag->arg1 * flag->arg1);
|
||||
} else if (flag->arg1 <= second_point_frame) {
|
||||
normalized_x_length = (middle_x - starting_x) / (second_point_frame * (first_point_frame - second_point_frame));
|
||||
flag->arg1_f = middle_x + (normalized_x_length * (flag->arg1 - second_point_frame) * (flag->arg1 - second_point_frame));
|
||||
} else if (flag->arg1 <= third_point_frame) {
|
||||
normalized_x_length = (ending_x - middle_x) / ((third_point_frame - second_point_frame) * (ending_frame - second_point_frame));
|
||||
flag->arg1_f = middle_x + (normalized_x_length * (flag->arg1 - second_point_frame) * (flag->arg1 - second_point_frame));
|
||||
} else {
|
||||
normalized_x_length = (ending_x - middle_x) / ((ending_frame - second_point_frame) * ((third_point_frame - second_point_frame) - (ending_frame - second_point_frame)));
|
||||
flag->arg1_f = ending_x + (normalized_x_length * (flag->arg1 - ending_frame) * (flag->arg1 - ending_frame));
|
||||
}
|
||||
|
||||
flag->arg1 += 1;
|
||||
if (flag->arg1 >= ending_frame) {
|
||||
flag->arg1 = 0;
|
||||
mMsg_request_main_forceoff();
|
||||
aFLAG_setup_action(flag, aFLAG_ACTION_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void aFLAG_down(STRUCTURE_ACTOR* flag, GAME_PLAY* game_play) {
|
||||
f32 normalized_x_length;
|
||||
f32 x_length;
|
||||
f32 starting_x;
|
||||
f32 ending_x;
|
||||
f32 ending_frame;
|
||||
f32 midpoint_frame;
|
||||
|
||||
if (mMsg_Check_main_wait(mMsg_Get_base_window_p()) != FALSE) {
|
||||
// Flag moves down in a smooth motion from top to bottom
|
||||
starting_x = 72.5;
|
||||
ending_x = 132.5;
|
||||
ending_frame = 40.0f;
|
||||
midpoint_frame = 16.0f;
|
||||
|
||||
if (REGADDR(NMREG, 0) != 0) {
|
||||
starting_x = REGADDR(NMREG, 0);
|
||||
}
|
||||
|
||||
if (REGADDR(NMREG, 1) != 0) {
|
||||
ending_x = REGADDR(NMREG, 1);
|
||||
}
|
||||
|
||||
if (REGADDR(NMREG, 7) != 0) {
|
||||
ending_frame = REGADDR(NMREG, 7);
|
||||
}
|
||||
|
||||
if (REGADDR(NMREG, 8) != 0) {
|
||||
midpoint_frame = REGADDR(NMREG, 8);
|
||||
}
|
||||
|
||||
x_length = ending_x - starting_x;
|
||||
if (flag->arg1 == 2) {
|
||||
sAdo_OngenTrgStart(0x164U, &flag->actor_class.world.position);
|
||||
}
|
||||
|
||||
// arg1_f is used to set the joint x position
|
||||
if (flag->arg1 <= midpoint_frame) {
|
||||
normalized_x_length = -(x_length / (midpoint_frame * ending_frame));
|
||||
flag->arg1_f = ending_x + (flag->arg1 * (normalized_x_length * flag->arg1));
|
||||
} else {
|
||||
normalized_x_length = -(x_length / (ending_frame * (midpoint_frame - ending_frame)));
|
||||
flag->arg1_f = starting_x + (normalized_x_length * (flag->arg1 - ending_frame) * (flag->arg1 - ending_frame));
|
||||
}
|
||||
|
||||
flag->arg1 += 1;
|
||||
if (flag->arg1 >= ending_frame) {
|
||||
flag->arg1 = 0;
|
||||
aFLAG_setup_action(flag, aFLAG_ACTION_OPEN_WAIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aFLAG_setup_action(STRUCTURE_ACTOR* flag, int action) {
|
||||
static aSTR_MOVE_PROC process[aFLAG_ACTION_NUM] = {
|
||||
&aFLAG_wait,
|
||||
&aFLAG_talk,
|
||||
&aFLAG_talk_end,
|
||||
&aFLAG_menu_open_wait,
|
||||
&aFLAG_menu_end_wait,
|
||||
&aFLAG_up,
|
||||
&aFLAG_down
|
||||
};
|
||||
|
||||
flag->action_proc = process[action];
|
||||
}
|
||||
|
||||
static void aFLAG_actor_move(ACTOR* actor, GAME* game) {
|
||||
STRUCTURE_ACTOR* flag;
|
||||
f32 wind_power;
|
||||
s16 wind_angle;
|
||||
|
||||
flag = (STRUCTURE_ACTOR*)actor;
|
||||
|
||||
wind_power = mEnv_GetWindPowerF();
|
||||
flag->arg0_f = wind_power;
|
||||
flag->keyframe.frame_control.speed = flag->arg0_f * 0.5f + 0.5f;
|
||||
|
||||
wind_angle = mEnv_GetWindAngleS();
|
||||
flag->arg2_f = wind_angle;
|
||||
|
||||
cKF_SkeletonInfo_R_play(&flag->keyframe);
|
||||
|
||||
(*flag->action_proc)(flag, (GAME_PLAY*)game);
|
||||
}
|
||||
|
||||
static void aFLAG_actor_init(ACTOR* actor, GAME* game) {
|
||||
mFI_SetFG_common(DUMMY_FLAG, actor->home.position, FALSE);
|
||||
aFLAG_actor_move(actor, game);
|
||||
actor->mv_proc = &aFLAG_actor_move;
|
||||
}
|
||||
|
||||
static int aFLAG_before_draw(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape,
|
||||
u8* joint_flags, void* arg, s_xyz* joint_rot, xyz_t* joint_pos) {
|
||||
STRUCTURE_ACTOR* flag = (STRUCTURE_ACTOR*)arg;
|
||||
if (joint_idx == 4) {
|
||||
joint_pos->x = flag->arg1_f * 100.0f;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void aFLAG_actor_draw(ACTOR* actor, GAME* game) {
|
||||
GRAPH* graph;
|
||||
cKF_SkeletonInfo_R_c* keyframe;
|
||||
Gfx* gfx;
|
||||
Mtx* mtx;
|
||||
STRUCTURE_ACTOR* flag;
|
||||
u16* pal;
|
||||
u8* texture;
|
||||
|
||||
flag = (STRUCTURE_ACTOR*)actor;
|
||||
graph = game->graph;
|
||||
keyframe = &flag->keyframe;
|
||||
mtx = GRAPH_ALLOC_TYPE(graph, Mtx, keyframe->skeleton->num_shown_joints);
|
||||
if (mtx != NULL) {
|
||||
_texture_z_light_fog_prim_npc(graph);
|
||||
_texture_z_light_fog_prim_xlu(graph);
|
||||
|
||||
if (Save_Get(island.flag_design).flag_design_set != FALSE) {
|
||||
pal = mNW_PaletteIdx2Palette(Save_Get(island.flag_design).palette);
|
||||
texture = (u8*)Save_GetPointer(island.flag_design.design);
|
||||
} else {
|
||||
pal = hakushi_pal;
|
||||
texture = hakushi_tex;
|
||||
}
|
||||
|
||||
OPEN_DISP(graph);
|
||||
gfx = NOW_POLY_OPA_DISP;
|
||||
|
||||
gSPSegment(gfx++, G_MWO_SEGMENT_8, pal);
|
||||
gSPSegment(gfx++, G_MWO_SEGMENT_9, texture);
|
||||
|
||||
SET_POLY_OPA_DISP(gfx);
|
||||
CLOSE_DISP(graph);
|
||||
|
||||
cKF_Si3_draw_R_SV(game, keyframe, mtx, &aFLAG_before_draw, NULL, actor);
|
||||
(*Common_Get(clip).bg_item_clip->draw_shadow_proc)(game, &aFLAG_shadow_data, FALSE);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user