static void aNG2_set_camera(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    static s8 mov_def_cnt[] = { 3, 0 };
    static f32 obj_look_y_max[] = { 30.0f, 20.0f };
    static f32 obj_look_y_spd[] = { 0.5f, 2.5f };

    xyz_t eye;
    xyz_t pos;
    xyz_t ground;
    s16 move;
    f32 moveX;
    f32 moveY;
    int obj_look_type = guide2->obj_look_type;
    s16 cur_angle;
    f32 inter;
    f32 sin;
    f32 ground_y;
    s16 angle;

    move = guide2->camera_move;
    guide2->camera_move += 0xE20;
    angle = move;
    angle += 0xE20;
    moveX = cos_s(angle) * 0.1f;
    angle = move;
    angle += 0xE20;
    moveY = sin_s(angle) * guide2->camera_move_range;

    if (guide2->camera_move_y <= 0.0f && moveY >= 0.0f) {
        s8 cnt = guide2->camera_move_cnt;

        cnt--;
        if (cnt < 0) {
            s8 set_cnt = guide2->camera_move_set_counter;

            set_cnt--;
            if (set_cnt < 0) {
                set_cnt = ARRAY_COUNT(mov_def_cnt) - 1;
            }

            guide2->camera_move_set_counter = set_cnt;
            cnt = mov_def_cnt[set_cnt];
            guide2->camera_move_range = 0.3f;
        } else {
            guide2->camera_move_range *= 0.35f;
        }

        guide2->camera_move_cnt = cnt;
    }

    guide2->camera_move_y = moveY;
    cur_angle = guide2->camera_tilt_cur_angle;
    chase_angle(&cur_angle, guide2->camera_tilt_goal_angle, guide2->camera_tilt_add);
    guide2->camera_tilt_cur_angle = cur_angle;
    sin = sin_s(cur_angle);

    /* Set camera eye pos */
    eye.x = moveX + sin * 20.0f + 100.0f;
    eye.y = moveY + sin * -5.0f + 80.0f;
    eye.z = 400.0f;

    /* Move NPC head to current target */
    chase_f(&guide2->npc_class.eye_y, obj_look_y_max[obj_look_type], obj_look_y_spd[obj_look_type] * 0.5f);

    /* Set ground pos */
    ground.x = guide2->npc_class.draw.shadow_pos.x;
    ground.z = guide2->npc_class.draw.shadow_pos.z;
    if (obj_look_type == aNG2_OBJ_LOOK_TYPE_TALK) {
        /* Use the guide2's NPC shadow position for Y */
        ground_y = guide2->npc_class.draw.shadow_pos.y;
    } else {
        /* Get the ground position for Y */
        ground_y = mCoBG_GetBgY_OnlyCenter_FromWpos2(ground, 0.0f);
    }

    chase_f(&guide2->obj_dist_ground, ground_y, 0.5f);
    ground.y = guide2->obj_dist_ground;

    /* Set camera center pos */
    if (guide2->lock_camera_flag == TRUE) {
        pos.x = ground.x;
        pos.y = ground.y + guide2->npc_class.eye_y;
        pos.z = ground.z;
    } else if (mDemo_Check(mDemo_TYPE_SPEAK, &guide2->npc_class.actor_class) == TRUE) {
        int morph_counter = guide2->camera_morph_counter;
        f32 r;

        guide2->camera_morph_counter = morph_counter - 1;
        if ((morph_counter - 1) == 0) {
            guide2->lock_camera_flag = TRUE;
        }

        r = (40.0f - (f32)(morph_counter - 1)) / 40.0f;
        inter = cKF_HermitCalc(r, 1.0f, 0.0f, 1.0f, 3.2f, 0.0f);

        pos.x = (ground.x - 90.0f) * inter + 90.0f;
        pos.y = ((ground.y + guide2->npc_class.eye_y) - 80.0f) * inter + 80.0f;
        pos.z = (ground.z - 280.0f) * inter + 280.0f;
    } else {
        /* Default position */
        pos.x = 90.0f;
        pos.y = 80.0f;
        pos.z = 280.0f;
    }

    pos.x += moveX;
    pos.y += moveY;

    Camera2_change_priority(play, 0);
    Camera2_request_main_lock(play, &pos, &eye, 40.0f, 0, 60.0f, 800.0f, 5);
}

static void aNG2_set_camera_eyes(NPC_GUIDE2_ACTOR* guide2) {
    if (guide2->camera_eyes_flag == TRUE) {
        guide2->npc_class.request.head_pos.x = 100.0f;
        guide2->npc_class.request.head_pos.y = guide2->npc_class.actor_class.eye.position.y;
        guide2->npc_class.request.head_pos.z = 400.0f;
        guide2->npc_class.request.head_priority = 3;
        guide2->npc_class.request.head_type = 2;
    }
}

static void aNG2_set_walk_spd(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->npc_class.movement.max_speed = 1.0f;
    guide2->npc_class.movement.acceleration = 0.1f;
    guide2->npc_class.movement.deceleration = 0.2f;
}

static void aNG2_set_walk_spd2(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->npc_class.movement.max_speed = 1.5f;
    guide2->npc_class.movement.acceleration = 0.15f;
    guide2->npc_class.movement.deceleration = 0.3f;
}

static void aNG2_set_stop_spd(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->npc_class.actor_class.speed = 0.0f;
    guide2->npc_class.movement.max_speed = 0.0f;
    guide2->npc_class.movement.acceleration = 0.0f;
    guide2->npc_class.movement.deceleration = 0.0f;
}

static int aNG2_make_keitai(NPC_GUIDE2_ACTOR* guide2, GAME* game) {
    int res = FALSE;

    if (guide2->npc_class.right_hand.item_actor_p == NULL) {
        if (Common_Get(clip).tools_clip != NULL) {
            ACTOR* keitai = Common_Get(clip).tools_clip->aTOL_birth_proc(
                TOOL_KEITAI, aTOL_ACTION_TAKEOUT, &guide2->npc_class.actor_class, game, -1, NULL);

            if (keitai != NULL) {
                guide2->npc_class.right_hand.item_actor_p = keitai;
                res = TRUE;
            }
        }
    } else {
        res = TRUE;
    }

    return res;
}

static int aNG2_chg_cond_keitai(NPC_GUIDE2_ACTOR* guide2, int cond) {
    int res = FALSE;

    if (Common_Get(clip).tools_clip != NULL) {
        if (Common_Get(clip).tools_clip->aTOL_chg_request_mode_proc(
                &guide2->npc_class.actor_class, guide2->npc_class.right_hand.item_actor_p, cond) == TRUE) {
            res = TRUE;
        }
    }

    return res;
}

static void aNG2_talk_demo_proc(ACTOR* actorx) {
    if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
        Common_Get(clip).npc_clip->talk_demo_proc(actorx);
    }
}

static u8* aNG2_getP_other_pl_name(void) {
    Private_c* priv;
    u32 player_no;
    int i;

    player_no = Common_Get(player_no);
    priv = Save_Get(private_data) + player_no;

    /* Search for players before this one's player no */
    for (i = player_no; i != 0; i--) {
        priv--;
        if (mPr_NullCheckPersonalID(&priv->player_ID) != TRUE) {
            return priv->player_ID.player_name;
        }
    }

    priv = Save_Get(private_data) + player_no;
    /* Search for players after this one's player no */
    for (i = (PLAYER_NUM - 1) - player_no; i != 0; i--) {
        priv++;
        if (mPr_NullCheckPersonalID(&priv->player_ID) != TRUE) {
            return priv->player_ID.player_name;
        }
    }

    /* No other players to reference */
    return NULL;
}

static int aNG2_check_pname(void) {
    int ok = TRUE;
    int i;

    for (i = 0; i < PLAYER_NUM; i++) {
        Private_c* priv = Save_GetPointer(private_data[i]);

        if (i != Common_Get(player_no)) {
            if (mem_cmp(Now_Private->player_ID.player_name, priv->player_ID.player_name, PLAYER_NAME_LEN) == TRUE) {
                /* Another player has the same name in this town */
                ok = FALSE;
                break;
            }
        }
    }

    return ok;
}

static void aNG2_check_talk_msg_no(NPC_GUIDE2_ACTOR* guide2) {
    if (mDemo_Check(mDemo_TYPE_SPEAK, &guide2->npc_class.actor_class) == TRUE) {
        int msg_no = mMsg_GET_MSG_NUM();
        int flags;

        switch (msg_no) {
            case 0x2AC9:
                flags = (1 << 3);
                break;
            case 0x2ADB:
                flags = (1 << 2);
                break;
            case 0x2ADD:
                flags = (1 << 1);
                break;
            case 0x2AD3:
                flags = (1 << 0);
                break;
            default:
                flags = 0;
                break;
        }

        guide2->answer_flags |= flags;
    }
}

static void aNG2_set_pl_face_type(NPC_GUIDE2_ACTOR* guide2) {
    static int face_type_table[mPr_SEX_NUM][mPr_FACE_TYPE_NUM] = {
        /* Male faces */
        {
            mPr_FACE_TYPE5,
            mPr_FACE_TYPE6,
            mPr_FACE_TYPE1,
            mPr_FACE_TYPE4,
            mPr_FACE_TYPE0,
            mPr_FACE_TYPE2,
            mPr_FACE_TYPE7,
            mPr_FACE_TYPE3,
        },
        /* Female faces */
        {
            mPr_FACE_TYPE0,
            mPr_FACE_TYPE5,
            mPr_FACE_TYPE2,
            mPr_FACE_TYPE6,
            mPr_FACE_TYPE4,
            mPr_FACE_TYPE7,
            mPr_FACE_TYPE3,
            mPr_FACE_TYPE1,
        },
    };

    int answer_flags = guide2->answer_flags;
    int face_type;

    if ((answer_flags & 1) == 0) {
        /* Select a random face for the player */
        face_type = RANDOM(mPr_FACE_TYPE_NUM);
    } else {
        /* Select a face based on choices */
        face_type = face_type_table[Now_Private->gender][answer_flags >> 1];
    }

    Now_Private->face = face_type;
}

static void aNG2_calc_body_angl(NPC_GUIDE2_ACTOR* guide2, f32 pos_x, f32 pos_z) {
    f32 dX = pos_x - guide2->npc_class.actor_class.world.position.x;
    f32 dZ = pos_z - guide2->npc_class.actor_class.world.position.z;
    s16 angl = atans_table(dZ, dX);

    chase_angle(&guide2->npc_class.actor_class.shape_info.rotation.y, angl, DEG2SHORT_ANGLE2(11.25f));
    guide2->npc_class.actor_class.world.angle.y = guide2->npc_class.actor_class.shape_info.rotation.y;
}

static void aNG2_set_default_talk_info(void) {
    mDemo_Set_camera(CAMERA2_PROCESS_NUM);
    mDemo_Set_talk_change_player(FALSE);
    mDemo_Set_use_zoom_sound(TRUE);
}

static void aNG2_enter(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    if (guide2->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
        guide2->camera_eyes_flag = TRUE;
        aNG2_setupAction(guide2, play, aNG2_ACTION_APPROACH);
    } else if (cKF_FrameControl_passCheck_now(&guide2->npc_class.draw.main_animation.keyframe.frame_control, 20.0f) ==
               TRUE) {
        TRAINDOOR_ACTOR* train_door = (TRAINDOOR_ACTOR*)guide2->train_door_actor;

        train_door->open_flag = TRUE;
    }
}

static void aNG2_approach(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    if (guide2->npc_class.actor_class.world.position.z >= 290.0f) {
        guide2->npc_class.actor_class.world.position.z = 290.0f;
        aNG2_setupAction(guide2, play, aNG2_ACTION_TALK_START_WAIT);
    }
}

static void aNG2_set_talk_info_talk_start_wait(ACTOR* actorx) {
    mMsg_SET_FREE_STR(mMsg_FREE_STR0, aNG2_getP_other_pl_name(), PLAYER_NAME_LEN);
    mDemo_Set_msg_num(0x2AD5);
    aNG2_set_default_talk_info();
    ((NPC_GUIDE2_ACTOR*)actorx)->obj_look_type = aNG2_OBJ_LOOK_TYPE_TALK;
}

static void aNG2_talk_start_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    ACTOR* actorx = (ACTOR*)guide2;

    if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
        if (mDemo_Check_ListenAble() == FALSE &&
            chase_angle(&actorx->shape_info.rotation.y, actorx->player_angle_y, 0x400) == TRUE) {
            guide2->camera_eyes_flag = FALSE;
            aNG2_setupAction(guide2, play, aNG2_ACTION_WAIT_PERMISSION);
            mDemo_Set_ListenAble();
        }
    } else {
        mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNG2_set_talk_info_talk_start_wait);
    }
}

static void aNG2_wait_permission(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
        aNG2_setupAction(guide2, play, aNG2_ACTION_SITDOWN);
    }
}

static void aNG2_sitdown(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->npc_class.actor_class.world.position.x = 100.0f;
    guide2->npc_class.actor_class.world.position.z = 280.0f;
    guide2->npc_class.actor_class.shape_info.rotation.y = 0;

    /* Wait for the sit animation to finish before continuing */
    if (guide2->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
        mMsg_UNSET_LOCKCONTINUE();
        guide2->next_action = aNG2_ACTION_PNAME_MENU_OPEN_WAIT;
        aNG2_setupAction(guide2, play, aNG2_ACTION_SDON_AND_PB_WAIT);
    }
}

static void aNG2_sdon_and_pb_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);

    if (order != 0 && mMsg_CHECK_MAINNORMALCONTINUE()) {
        aNG2_setupAction(guide2, play, guide2->next_action);
        mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
    }
}

static void aNG2_pname_menu_open_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    if (mMsg_CHECK_MAIN_WAIT() == TRUE) {
        aNG2_setupAction(guide2, play, 7);
    }
}

static void aNG2_pname_menu_close_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    if (play->submenu.open_flag == FALSE) {
        aNG2_setupAction(guide2, play, 8);
    }
}

static void aNG2_msg_win_open_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    static int msg_no[] = { 0x2ACA, 0x2AE2 };
    static int next_act_idx[] = { 10, 9 };
    mMsg_Window_c* msg_p = mMsg_Get_base_window_p();

    if (mMsg_Check_not_series_main_wait(msg_p) == TRUE) {
        int idx = 0;

        mMsg_Unset_LockContinue(msg_p);

        /* Check if the player's name already exists in town */
        if (aNG2_check_pname() == FALSE) {
            idx = 1;
        }

        mMsg_Set_continue_msg_num(msg_p, msg_no[idx]);
        mMsg_Set_ForceNext(msg_p);
        aNG2_setupAction(guide2, play, next_act_idx[idx]);
    }
}

static void aNG2_sex_select_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
        switch (mChoice_GET_CHOSENUM()) {
            case mChoice_CHOICE0: // male
            case mChoice_CHOICE1: // female
                aNG2_setupAction(guide2, play, aNG2_ACTION_SEX_SELECT_WAIT2);
                break;
            case mChoice_CHOICE2: // 'That's not right'
                guide2->next_action = aNG2_ACTION_PNAME_MENU_OPEN_WAIT;
                aNG2_setupAction(guide2, play, aNG2_ACTION_SDON_AND_PB_WAIT);
                break;
        }
    }
}

static void aNG2_sex_select_wait2(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    static int next_act_idx[] = { aNG2_ACTION_STANDUP_START_WAIT, aNG2_ACTION_SEX_SELECT_AFTER };
    int order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);

    if (order != 0) {
        mMsg_Window_c* msg_p = mMsg_Get_base_window_p();

        if (mMsg_Check_MainNormalContinue(msg_p) == TRUE) {
            int idx = -1;

            switch (mChoice_GET_CHOSENUM()) {
                case mChoice_CHOICE0: // male
                    switch (order) {
                        case 1: // That's right
                            Now_Private->gender = mPr_SEX_MALE;
                            break;
                        case 2: // I'm not a boy
                            Now_Private->gender = mPr_SEX_FEMALE;
                            break;
                    }

                    idx = 0;
                    mMsg_Set_continue_msg_num(msg_p, 0x2AD9);
                    mMsg_Set_ForceNext(msg_p);
                    break;
                case mChoice_CHOICE1: // female
                    switch (order) {
                        case 1: // That's right
                            Now_Private->gender = mPr_SEX_FEMALE;
                            break;
                        case 2: // I'm not a girl
                            Now_Private->gender = mPr_SEX_MALE;
                            break;
                    }
                    idx = 1;
                    break;
            }

            if (idx != -1) {
                aNG2_setupAction(guide2, play, next_act_idx[idx]);
                mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
            }
        }
    }
}

static void aNG2_sex_select_after(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
    u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);

    if (order != 0 && mMsg_Check_MainNormalContinue(msg_p)) {
        aNG2_setupAction(guide2, play, aNG2_ACTION_STANDUP_START_WAIT);
        mMsg_Set_continue_msg_num(msg_p, 0x2AD9);
        mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
    }
}

static void aNG2_standup_start_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    /* Wait for guide2 to stop speaking to us */
    if (mDemo_Check(mDemo_TYPE_SPEAK, &guide2->npc_class.actor_class) == FALSE) {
        guide2->obj_look_type = aNG2_OBJ_LOOK_TYPE_NORMAL;
        aNG2_setupAction(guide2, play, aNG2_ACTION_STANDUP);
    }
}

static void aNG2_standup(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    /* Wait for animation to finish */
    if (guide2->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
        aNG2_setupAction(guide2, play, guide2->next_action);
    }
}

static void aNG2_move_ready(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->npc_class.actor_class.world.position.x = 100.0f;
    guide2->npc_class.actor_class.world.position.z = 300.0f;
    aNG2_setupAction(guide2, play, aNG2_ACTION_MOVE_TO_AISLE);
}

static void aNG2_move_to_aisle(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    aNG2_calc_body_angl(guide2, 140.0f, 290.0f);
    if (guide2->npc_class.actor_class.world.position.x > 140.0f) {
        aNG2_setupAction(guide2, play, aNG2_ACTION_MOVE_TO_DOOR);
    }
}

static void aNG2_move_to_door(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    aNG2_calc_body_angl(guide2, 140.0f, 130.0f);
    /* Check if we reached the door */
    if (guide2->npc_class.actor_class.world.position.z < 130.0f) {
        aNG2_setupAction(guide2, play, aNG2_ACTION_MOVE_TO_DECK);
    }

    /* Check if we should start rotating */
    if (guide2->npc_class.draw.shadow_pos.z < 140.0f) {
        guide2->camera_tilt_goal_angle = DEG2SHORT_ANGLE2(90.0f);
        guide2->camera_tilt_add = DEG2SHORT_ANGLE2(2.8125f);
    }
}

static void aNG2_move_to_deck(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    if (cKF_FrameControl_passCheck_now(&guide2->npc_class.draw.main_animation.keyframe.frame_control, 9.0f) == TRUE) {
        TRAINDOOR_ACTOR* train_door = (TRAINDOOR_ACTOR*)guide2->train_door_actor;

        train_door->open_flag = TRUE;
    }

    /* Reuse standup state to wait for animation to finish */
    aNG2_standup(guide2, play);
}

static void aNG2_set_talk_info_keitai_on(ACTOR* actorx) {
    mDemo_Set_msg_num(0x2ADE);
    aNG2_set_default_talk_info();
}

static void aNG2_keitai_on(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    static f32 anmSpd[] = { 0.0f, 0.5f };
    int idx = aNG2_make_keitai(guide2, &play->game);

    guide2->npc_class.draw.main_animation.keyframe.frame_control.speed = anmSpd[idx];
    if (idx != 0) {
        if (mDemo_Check(mDemo_TYPE_SPEAK, (ACTOR*)guide2) == TRUE) {
            if (mDemo_Check_ListenAble() == FALSE) {
                mDemo_Set_ListenAble();
            }
        } else {
            /* Request to start speaking */
            mDemo_Request(mDemo_TYPE_SPEAK, (ACTOR*)guide2, &aNG2_set_talk_info_keitai_on);
        }
    }

    /* Wait for animation to finish */
    if (guide2->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
        aNG2_setupAction(guide2, play, aNG2_ACTION_KEITAI_TALK);
    }
}

static void aNG2_keitai_talk(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    if (mDemo_Check(mDemo_TYPE_SPEAK, &guide2->npc_class.actor_class) == FALSE) {
        aNG2_setupAction(guide2, play, aNG2_ACTION_KEITAI_OFF);
    } else if (guide2->npc_class.draw.main_animation_state == cKF_STATE_STOPPED) {
        Common_Get(clip).npc_clip->animation_init_proc(&guide2->npc_class.actor_class, aNPC_ANIM_KEITAI_TALK2, TRUE);
    }
}

static void aNG2_open_door(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    chase_angle(&guide2->npc_class.actor_class.shape_info.rotation.y, DEG2SHORT_ANGLE2(-180.0f),
                DEG2SHORT_ANGLE2(0.703125f));
    if (cKF_FrameControl_passCheck_now(&guide2->npc_class.draw.main_animation.keyframe.frame_control, 22.0f) == TRUE) {
        TRAINDOOR_ACTOR* train_door = (TRAINDOOR_ACTOR*)guide2->train_door_actor;

        train_door->open_flag = TRUE;
        if (guide2->npc_class.draw.shadow_pos.z < 140.0f) {
            guide2->camera_tilt_goal_angle = 0;
            guide2->camera_tilt_add = 0x600;
        }
    }

    /* Reuse standup state to wait for animation to finish */
    aNG2_standup(guide2, play);
}

static void aNG2_return_approach(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->npc_class.actor_class.world.position.x = 140.0f;
    guide2->npc_class.actor_class.world.angle.y = 0;
    guide2->npc_class.actor_class.shape_info.rotation.y = 0;
    if (guide2->npc_class.actor_class.world.position.z > 290.0f) {
        aNG2_setupAction(guide2, play, aNG2_ACTION_LAST_TALK_START_WAIT);
    }
}

static void aNG2_set_talk_info_last_talk_start_wait(ACTOR* actorx) {
    mDemo_Set_msg_num(0x2AD1);
    aNG2_set_default_talk_info();
    ((NPC_GUIDE2_ACTOR*)actorx)->obj_look_type = aNG2_OBJ_LOOK_TYPE_TALK;
}

static void aNG2_last_talk_start_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    ACTOR* actorx = (ACTOR*)guide2;

    if (mDemo_Check(mDemo_TYPE_SPEAK, actorx) == TRUE) {
        if (mDemo_Check_ListenAble() == FALSE &&
            chase_angle(&actorx->shape_info.rotation.y, actorx->player_angle_y, 0x400) == TRUE) {
            guide2->camera_eyes_flag = FALSE;
            aNG2_setupAction(guide2, play, aNG2_ACTION_SITDOWN2_START_WAIT);
            mDemo_Set_ListenAble();
        }
    } else {
        mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNG2_set_talk_info_last_talk_start_wait);
    }
}

static void aNG2_sitdown2_start_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    u16 order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);

    if (order != 0) {
        aNG2_setupAction(guide2, play, aNG2_ACTION_SITDOWN2);
        mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
    }
}

static void aNG2_sitdown2(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->npc_class.actor_class.world.position.x = 100.0f;
    guide2->npc_class.actor_class.world.position.z = 280.0f;
    guide2->npc_class.actor_class.shape_info.rotation.y = 0;

    /* Wait for animation to finish */
    aNG2_standup(guide2, play);
}

static void aNG2_last_talk_end_wait(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    if (mDemo_Check(mDemo_TYPE_SPEAK, &guide2->npc_class.actor_class) == FALSE) {
        aNG2_setupAction(guide2, play, aNG2_ACTION_SCENE_CHANGE_WAIT);
    }
}

/* Init procs */

static void aNG2_sitdown_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    mMsg_SET_LOCKCONTINUE();
}

static void aNG2_pname_menu_open_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    mMsg_Window_c* msg_p = mMsg_Get_base_window_p();

    mMsg_Set_LockContinue(msg_p);
    mMsg_request_main_disappear_wait_type1(msg_p);
}

static void aNG2_pname_menu_close_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    Submenu* submenu = &play->submenu;

    mSM_open_submenu(submenu, mSM_OVL_LEDIT, mLE_TYPE_PLAYER_NAME, 0);
}

static void aNG2_msg_win_open_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    mMsg_REQUEST_MAIN_APPEAR_WAIT_TYPE1();
}

static void aNG2_pname_ng_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->next_action = 6;
}

static void aNG2_standup_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->next_action = aNG2_ACTION_MOVE_READY;
}

static void aNG2_move_ready_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f;
}

static void aNG2_move_to_aisle_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    aNG2_set_walk_spd2(guide2, play);
}

static void aNG2_move_to_deck_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    aNG2_set_stop_spd(guide2, play);
    guide2->npc_class.actor_class.world.position.x = 140.0f;
    guide2->npc_class.actor_class.world.position.z = 130.0f;
    guide2->next_action = aNG2_ACTION_KEITAI_ON;
}

static void aNG2_keitai_off_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    aNG2_chg_cond_keitai(guide2, aTOL_ACTION_PUTAWAY);
    guide2->next_action = aNG2_ACTION_OPEN_DOOR;
}

static void aNG2_open_door_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->next_action = aNG2_ACTION_RETURN_APPROACH;
}

static void aNG2_return_approach_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->camera_eyes_flag = TRUE;
    aNG2_set_walk_spd2(guide2, play);
    guide2->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f;
}

static void aNG2_sitdown2_start_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
}

static void aNG2_sitdown2_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    guide2->npc_class.draw.main_animation.keyframe.morph_counter = 0.0f;
    guide2->next_action = aNG2_ACTION_LAST_TALK_END_WAIT;
}

static void aNG2_last_talk_end_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    aNG2_chg_cond_keitai(guide2, aTOL_ACTION_DESTRUCT);
    guide2->npc_class.right_hand.item_actor_p = NULL;
}

static void aNG2_scene_change_wait_init(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play) {
    /* Init next scene transition */
    goto_next_scene(play, 0, 1);
    play->fb_wipe_type = 3;
    Common_Get(transition).wipe_type = 4;

    mEv_SetFirstJob();
    mEv_SetFirstIntro();
    mEnv_DecideWeather_NormalGameStart();
    aNG2_set_pl_face_type(guide2);
    mPr_SetNowPrivateCloth();
    Common_Set(submenu_disabled, TRUE);
    mBGMPsComp_make_ps_wipe(0x41C2);
    mBGMPsComp_scene_mode(18);
}

typedef void (*aNG2_INIT_PROC)(NPC_GUIDE2_ACTOR*, GAME_PLAY*);

static void aNG2_init_proc(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play, int action) {
    static aNG2_INIT_PROC init_proc[] = {
        (aNG2_INIT_PROC)&none_proc1,
        &aNG2_set_walk_spd,
        &aNG2_set_stop_spd,
        (aNG2_INIT_PROC)&none_proc1,
        &aNG2_sitdown_init,
        (aNG2_INIT_PROC)&none_proc1,
        &aNG2_pname_menu_open_wait_init,
        &aNG2_pname_menu_close_wait_init,
        &aNG2_msg_win_open_wait_init,
        &aNG2_pname_ng_init,
        (aNG2_INIT_PROC)&none_proc1,
        (aNG2_INIT_PROC)&none_proc1,
        (aNG2_INIT_PROC)&none_proc1,
        (aNG2_INIT_PROC)&none_proc1,
        &aNG2_standup_init,
        &aNG2_move_ready_init,
        &aNG2_move_to_aisle_init,
        (aNG2_INIT_PROC)&none_proc1,
        &aNG2_move_to_deck_init,
        (aNG2_INIT_PROC)&none_proc1,
        (aNG2_INIT_PROC)&none_proc1,
        &aNG2_keitai_off_init,
        &aNG2_open_door_init,
        &aNG2_return_approach_init,
        &aNG2_set_stop_spd,
        &aNG2_sitdown2_start_wait_init,
        &aNG2_sitdown2_init,
        &aNG2_last_talk_end_wait_init,
        &aNG2_scene_change_wait_init,
    };

    (*init_proc[action])(guide2, play);
}

static void aNG2_setupAction(NPC_GUIDE2_ACTOR* guide2, GAME_PLAY* play, int action) {
    static aNG2_PROC process[] = {
        &aNG2_enter,
        &aNG2_approach,
        &aNG2_talk_start_wait,
        &aNG2_wait_permission,
        &aNG2_sitdown,
        &aNG2_sdon_and_pb_wait,
        &aNG2_pname_menu_open_wait,
        &aNG2_pname_menu_close_wait,
        &aNG2_msg_win_open_wait,
        &aNG2_sdon_and_pb_wait,
        &aNG2_sex_select_wait,
        &aNG2_sex_select_wait2,
        &aNG2_sex_select_after,
        &aNG2_standup_start_wait,
        &aNG2_standup,
        &aNG2_move_ready,
        &aNG2_move_to_aisle,
        &aNG2_move_to_door,
        &aNG2_move_to_deck,
        &aNG2_keitai_on,
        &aNG2_keitai_talk,
        &aNG2_standup,
        &aNG2_open_door,
        &aNG2_return_approach,
        &aNG2_last_talk_start_wait,
        &aNG2_sitdown2_start_wait,
        &aNG2_sitdown2,
        &aNG2_last_talk_end_wait,
        (aNG2_PROC)&none_proc1,
    };

    guide2->action = action;
    guide2->proc = process[action];
    aNG2_set_animation(guide2, action);
    aNG2_init_proc(guide2, play, action);
}

static void aNG2_actor_move(ACTOR* actorx, GAME* game) {
    NPC_GUIDE2_ACTOR* guide2 = (NPC_GUIDE2_ACTOR*)actorx;
    GAME_PLAY* play = (GAME_PLAY*)game;

    Common_Get(clip).npc_clip->move_before_proc(actorx, game);
    aNG2_talk_demo_proc(actorx);
    aNG2_check_talk_msg_no(guide2);
    (*guide2->proc)(guide2, play);
    Common_Get(clip).npc_clip->move_after_proc(actorx, game);
    aNG2_set_camera(guide2, play);
    aNG2_set_camera_eyes(guide2);
    mSC_change_player_freeze(play);
}
