+static void npc_slowmo_call( ent_npc *npc, ent_call *call )
+{
+ if( call->function == 0 )
+ {
+ gui_helper_clear();
+ vg_str text;
+
+ if( npc->context == 2 )
+ {
+ if( gui_new_helper( input_axis_list[k_sraxis_grab], &text ))
+ vg_strcat( &text, "Crouch (store energy)" );
+ if( gui_new_helper( input_joy_list[k_srjoystick_steer], &text ))
+ vg_strcat( &text, "Slide" );
+ }
+ else if( npc->context == 1 )
+ {
+ if( gui_new_helper( input_axis_list[k_sraxis_grab], &text ))
+ vg_strcat( &text, "Crouch (store energy)" );
+ }
+ else if( npc->context == 3 )
+ {
+ if( gui_new_helper( input_button_list[k_srbind_reset], &text ))
+ vg_strcat( &text, "Rewind time" );
+ if( gui_new_helper( input_button_list[k_srbind_replay_resume], &text ))
+ vg_strcat( &text, "Resume" );
+ }
+ }
+ else if( call->function == -1 )
+ {
+ world_entity_clear_focus();
+ gui_helper_clear();
+ }
+}
+
+void ent_npc_call( world_instance *world, ent_call *call )
+{
+ u32 index = mdl_entity_id_id( call->id );
+ ent_npc *npc = mdl_arritm( &world->ent_npc, index );
+
+ if( npc->id == 2 )
+ {
+ npc_slowmo_call( npc, call );
+ }
+ else if( npc->id == 3 )
+ {
+ if( call->function == 0 )
+ {
+ world_entity_set_focus( call->id );
+ gui_helper_clear();
+ vg_str text;
+ if( gui_new_helper( input_button_list[k_srbind_maccept], &text ))
+ vg_strcat( &text, "Preview course" );
+ }
+ else if( call->function == -1 )
+ {
+ world_entity_clear_focus();
+ gui_helper_clear();
+ }
+ }
+ else
+ {
+ if( call->function == 0 )
+ {
+ world_entity_set_focus( call->id );
+ gui_helper_clear();
+ vg_str text;
+ if( gui_new_helper( input_button_list[k_srbind_maccept], &text ))
+ vg_strcat( &text, "Talk to ???" );
+ }
+ else if( call->function == -1 )
+ {
+ world_entity_clear_focus();
+ gui_helper_clear();
+ }
+ else
+ {
+ vg_print_backtrace();
+ vg_error( "Unhandled function id: %i\n", call->function );
+ }
+ }
+}
+
+void ent_npc_preupdate( ent_npc *ent, int active )
+{
+ world_instance *world = world_current_instance();
+
+ if( !active )
+ {
+ if( button_down(k_srbind_maccept) )
+ {
+ world_entity_focus_modal();
+ gui_helper_clear();
+ vg_str text;
+ if( gui_new_helper( input_button_list[k_srbind_mback], &text ))
+ vg_strcat( &text, "leave" );
+
+ volc_start_preview = vg.time;
+ }
+
+ return;
+ }
+
+ if( ent->id == 3 )
+ {
+ player_pose pose;
+ struct skeleton *sk = &npc_volc_flight.skeleton;
+
+ f64 t = (vg.time - volc_start_preview) * 0.5;
+ skeleton_sample_anim_clamped( sk, anim_tutorial_cam, t, pose.keyframes );
+
+ ent_camera *cam = mdl_arritm( &world->ent_camera,
+ mdl_entity_id_id(ent->camera) );
+ v3_copy( pose.keyframes[0].co, cam->transform.co );
+
+ v4f qp;
+ q_axis_angle( qp, (v3f){1,0,0}, VG_TAUf*0.25f );
+ q_mul( pose.keyframes[0].q, qp, cam->transform.q );
+ q_normalize( cam->transform.q );
+
+ v3_add( ent->transform.co, cam->transform.co, cam->transform.co );
+ }
+
+ world_entity_focus_camera( world, ent->camera );
+
+ if( button_down( k_srbind_mback ) )
+ {
+ world_entity_exit_modal();
+ world_entity_clear_focus();
+ gui_helper_clear();
+ }
+}
+