X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=ent_npc.c;h=7a4b484b534f22d389e3e3793cc15739a311109f;hb=304647a7672165dd35ffe54884ed9aedcc9bf363;hp=048a1b9b27bd20f6685512fb42b6dc3d7684fa90;hpb=14851c4c820eb07a0db0ec0366a70bdd6518c331;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/ent_npc.c b/ent_npc.c index 048a1b9..7a4b484 100644 --- a/ent_npc.c +++ b/ent_npc.c @@ -1,9 +1,16 @@ #include "vg/vg_mem.h" #include "ent_npc.h" #include "shaders/model_character_view.h" +#include "input.h" +#include "player.h" +#include "gui.h" -struct npc npc_gumpa; +struct npc npc_gumpa, npc_slowmo, npc_volc_flight; static struct skeleton_anim *gumpa_idle; +static struct skeleton_anim *slowmo_momentum, *slowmo_slide, *slowmo_rewind, + *anim_tutorial_cam; +static float slowmo_opacity = 0.0f; +static f64 volc_start_preview = 0.0; void npc_load_model( struct npc *npc, const char *path ) { @@ -20,16 +27,20 @@ void npc_load_model( struct npc *npc, const char *path ) u32 mtx_size = sizeof(m4x3f)*sk->bone_count; npc->final_mtx = vg_linear_alloc( vg_mem.rtmemory, mtx_size ); - if( !mdl_arrcount( &meta->textures ) ) - vg_fatal_error( "No texture in model" ); + if( mdl_arrcount( &meta->textures ) ) + { + mdl_texture *tex0 = mdl_arritm( &meta->textures, 0 ); + void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size ); + mdl_fread_pack_file( meta, &tex0->file, data ); - mdl_texture *tex0 = mdl_arritm( &meta->textures, 0 ); - void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size ); - mdl_fread_pack_file( meta, &tex0->file, data ); - - vg_tex2d_load_qoi_async( data, tex0->file.pack_size, - VG_TEX2D_NEAREST|VG_TEX2D_CLAMP, - &npc->texture ); + vg_tex2d_load_qoi_async( data, tex0->file.pack_size, + VG_TEX2D_NEAREST|VG_TEX2D_CLAMP, + &npc->texture ); + } + else + { + npc->texture = vg.tex_missing; + } mdl_async_load_glmesh( meta, &npc->mesh, NULL ); mdl_close( meta ); @@ -39,16 +50,189 @@ void npc_init(void) { npc_load_model( &npc_gumpa, "models/gumpa.mdl" ); gumpa_idle = skeleton_get_anim( &npc_gumpa.skeleton, "gumpa_idle" ); + + npc_load_model( &npc_slowmo, "models/slowmos.mdl" ); + slowmo_momentum = + skeleton_get_anim( &npc_slowmo.skeleton, "slowmo_momentum" ); + slowmo_slide = skeleton_get_anim( &npc_slowmo.skeleton, "slowmo_slide" ); + slowmo_rewind = skeleton_get_anim( &npc_slowmo.skeleton, "slowmo_rewind" ); + + npc_load_model( &npc_volc_flight, "models/volc_flight.mdl" ); + anim_tutorial_cam = + skeleton_get_anim( &npc_volc_flight.skeleton, "tutorial" ); } static struct npc *npc_resolve( u32 id ) { if( id == 1 ) return &npc_gumpa; + else if( id == 2 ) return &npc_slowmo; + else if( id == 3 ) return &npc_volc_flight; else return NULL; } +static entity_call_result 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" ); + } + return k_entity_call_result_OK; + } + else if( call->function == -1 ) + { + world_entity_clear_focus(); + gui_helper_clear(); + return k_entity_call_result_OK; + } + else + return k_entity_call_result_unhandled; +} + +entity_call_result 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 ) + { + return 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" ); + return k_entity_call_result_OK; + } + else if( call->function == -1 ) + { + world_entity_clear_focus(); + gui_helper_clear(); + return k_entity_call_result_OK; + } + else + return k_entity_call_result_unhandled; + } + else if( npc->id == 4 ) + { + if( call->function == 0 ) + { + gui_helper_clear(); + vg_str text; + if( gui_new_helper( input_button_list[k_srbind_camera], &text )) + vg_strcat( &text, "First/Thirdperson" ); + return k_entity_call_result_OK; + } + else if( call->function == -1 ) + { + gui_helper_clear(); + return k_entity_call_result_OK; + } + else + return k_entity_call_result_unhandled; + } + 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 ???" ); + return k_entity_call_result_OK; + } + else if( call->function == -1 ) + { + world_entity_clear_focus(); + gui_helper_clear(); + return k_entity_call_result_OK; + } + else + return k_entity_call_result_unhandled; + } +} + +void ent_npc_preupdate( ent_focus_context *ctx ) +{ + world_instance *world = ctx->world; + ent_npc *ent = mdl_arritm( &world->ent_npc, ctx->index ); + + if( !ctx->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(); + } +} + void npc_update( ent_npc *ent ) { + if( ent->id == 3 ) return; + if( ent->id == 4 ) return; + struct npc *npc_def = npc_resolve( ent->id ); VG_ASSERT( npc_def ); @@ -57,7 +241,25 @@ void npc_update( ent_npc *ent ) pose.type = k_player_pose_type_ik; pose.board.lean = 0.0f; - skeleton_sample_anim( sk, gumpa_idle, vg.time, pose.keyframes ); + if( ent->id == 1 ) + { + skeleton_sample_anim( sk, gumpa_idle, vg.time, pose.keyframes ); + } + else if( ent->id == 2 ) + { + struct skeleton_anim *anim = NULL; + if( ent->context == 1 ) anim = slowmo_momentum; + else if( ent->context == 2 ) anim = slowmo_slide; + else if( ent->context == 3 ) anim = slowmo_rewind; + + VG_ASSERT( anim ); + + f32 t = vg.time*0.5f, + animtime = fmodf( t*anim->rate, anim->length ), + lt = animtime / (f32)anim->length; + skeleton_sample_anim( sk, anim, t, pose.keyframes ); + slowmo_opacity = vg_clampf(fabsf(lt-0.5f)*9.0f-3.0f,0,1); + } v3_copy( ent->transform.co, pose.root_co ); v4_copy( ent->transform.q, pose.root_q ); @@ -66,6 +268,9 @@ void npc_update( ent_npc *ent ) void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam ) { + if( ent->id == 3 ) return; + if( ent->id == 4 ) return; + struct npc *npc_def = npc_resolve( ent->id ); VG_ASSERT( npc_def ); @@ -76,7 +281,16 @@ void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam ) shader_model_character_view_uTexMain( 0 ); shader_model_character_view_uCamera( cam->transform[3] ); shader_model_character_view_uPv( cam->mtx.pv ); - shader_model_character_view_uDepthCompare( 0 ); + + if( ent->id == 2 ) + { + shader_model_character_view_uDepthMode( 2 ); + shader_model_character_view_uDitherCutoff( slowmo_opacity ); + } + else + { + shader_model_character_view_uDepthMode( 0 ); + } WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_character_view );