From: hgn Date: Mon, 12 May 2025 00:24:32 +0000 (+0100) Subject: NPC's R us X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=3cda5f09226f64d8fb548d843e63ce1c55a53cee;p=carveJwlIkooP6JGAAIwe30JlM.git NPC's R us --- diff --git a/content_skaterift/maps/dev_hub/main.mdl b/content_skaterift/maps/dev_hub/main.mdl index 0120137..5dc735a 100644 Binary files a/content_skaterift/maps/dev_hub/main.mdl and b/content_skaterift/maps/dev_hub/main.mdl differ diff --git a/content_skaterift/maps/dev_tutorial/main.mdl b/content_skaterift/maps/dev_tutorial/main.mdl index 2765056..4aeae1e 100644 Binary files a/content_skaterift/maps/dev_tutorial/main.mdl and b/content_skaterift/maps/dev_tutorial/main.mdl differ diff --git a/skaterift_blender/sr_main.py b/skaterift_blender/sr_main.py index b95a1d8..e6af427 100644 --- a/skaterift_blender/sr_main.py +++ b/skaterift_blender/sr_main.py @@ -258,7 +258,9 @@ class ent_audio_clip(Structure): class ent_list(Structure): #{ - _fields_ = [("entity_ref_start",c_uint16),("entity_ref_count",c_uint16)] + _fields_ = [("entity_ref_start",c_uint16),("entity_ref_count",c_uint16), + ("alias_type",c_uint8),("none0",c_uint8),("none1",c_uint8),("none2",c_uint8), + ("pstr_alias",c_uint32) ] #} # used in ent_list @@ -302,10 +304,9 @@ class ent_glider(Structure):#{ class ent_npc(Structure):#{ _fields_ = [("transform",mdl_transform), - ("id",c_uint32), - ("context",c_uint32), - ("camera",c_uint32)] - sr_functions = { 0: 'proximity', -1: 'leave' } + ("pstr_id",c_uint32), + ("pstr_context_id",c_uint32)] + sr_functions = { 1: 'proximity', 0: 'interact', -1: 'unproximity' } #} class ent_water(Structure): @@ -1632,12 +1633,20 @@ class SR_UL_ENT_LIST(bpy.types.UIList):#{ #} #} -class SR_OBJECT_ENT_LIST(bpy.types.PropertyGroup):#{ +class SR_OBJECT_ENT_LIST(bpy.types.PropertyGroup): +#{ entities: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_LIST_ENTRY) entities_index: bpy.props.IntProperty() + alias_type: bpy.props.EnumProperty( + name="Subtype", + items=[('0','No Alias',''), + ('1','String Alias','')] + ) + alias_string: bpy.props.StringProperty() @staticmethod - def sr_inspector( layout, data ):#{ + def sr_inspector( layout, data ): + #{ layout.label( text='Entities' ) layout.template_list('SR_UL_ENT_LIST', 'Entities', \ data[0], 'entities', data[0], \ @@ -1646,6 +1655,15 @@ class SR_OBJECT_ENT_LIST(bpy.types.PropertyGroup):#{ row = layout.row() row.operator( 'skaterift.ent_list_new_entry', text='Add' ) row.operator( 'skaterift.ent_list_del_entry', text='Remove' ) + + data = data[0] + box = layout.box() + box.prop( data, 'alias_type' ) + + if data.alias_type == '1': + #{ + box.prop( data, 'alias_string' ) + #} #} #} @@ -1654,11 +1672,15 @@ class SR_OBJECT_ENT_GLIDER(bpy.types.PropertyGroup):#{ #} class SR_OBJECT_ENT_NPC(bpy.types.PropertyGroup):#{ - au: bpy.props.IntProperty() - context: bpy.props.IntProperty() - cam: bpy.props.PointerProperty( \ - type=bpy.types.Object, name="Viewpoint", \ - poll=lambda self,obj: sr_filter_ent_type(obj,['ent_camera'])) + id: bpy.props.StringProperty() + context_id: bpy.props.StringProperty() + + # old, unused. + # au: bpy.props.IntProperty() + # context: bpy.props.IntProperty() + # cam: bpy.props.PointerProperty( \ + # type=bpy.types.Object, name="Viewpoint", \ + # poll=lambda self,obj: sr_filter_ent_type(obj,['ent_camera'])) #} class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{ @@ -1675,6 +1697,7 @@ class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{ target_event: bpy.props.IntProperty( name="Enter Ev" ) target_event_leave: bpy.props.IntProperty( name="Leave Ev", default=-1 ) + repeatable: bpy.props.BoolProperty( name="Repeatable" ) auto_run: bpy.props.BoolProperty( name="Auto Run" ) water_volume: bpy.props.BoolProperty( name="Water Volume" ) text: bpy.props.StringProperty() @@ -1715,7 +1738,10 @@ class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{ layout.prop( data[0], 'subtype' ) SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', ['_event','_event_leave'] ) if data[0].subtype == '2': + #{ layout.prop( data[0], 'text' ) + layout.prop( data[0], 'repeatable' ) + #} layout.prop( data[0], 'water_volume' ) #} #} @@ -2949,13 +2975,13 @@ def cv_draw():#{ #} elif ent_type == 'ent_list': #{ - if obj.select_get(): + if True or obj.select_get(): #{ data = obj.SR_data.ent_list[0] for subj in data.entities: #{ if subj.target: - cv_draw_line_dotted( obj.location, subj.target.location, (0.9,0.0,0.7)) + cv_draw_line( obj.location, subj.target.location, (0.9,0.0,0.7)) #} #} #} diff --git a/skaterift_blender/sr_mdl.py b/skaterift_blender/sr_mdl.py index c65ffce..5860d23 100644 --- a/skaterift_blender/sr_mdl.py +++ b/skaterift_blender/sr_mdl.py @@ -752,6 +752,9 @@ def _mdl_compiler_compile_entities(): if obj_data.water_volume: volume.flags |= 0x10 + if obj_data.repeatable: + volume.flags |= 0x20 + #if obj_data.auto_run: # volume.flags |= 0x4 compile_obj_transform( obj, volume.transform ) @@ -909,6 +912,11 @@ def _mdl_compiler_compile_entities(): lista = ent_list() lista.entity_ref_start = _mdl_compiler_ent_count( 'file_entity_ref' ) lista.entity_ref_count = 0 + lista.alias_type = int( obj_data.alias_type ) + + if obj_data.alias_type == '1': + lista.pstr_alias = _af_pack_string( obj_data.alias_string ) + for k in range(len(obj_data.entities)): #{ if obj_data.entities[k]: @@ -957,9 +965,8 @@ def _mdl_compiler_compile_entities(): obj_data = obj.SR_data.ent_npc[0] npc = ent_npc() compile_obj_transform( obj, npc.transform ) - npc.id = obj_data.au - npc.context = obj_data.context - npc.camera = sr_entity_id( obj_data.cam ) + npc.pstr_id = _af_pack_string( obj_data.id ) + npc.pstr_context_id = _af_pack_string( obj_data.context_id ) sr_ent_push( npc ) #} elif ent_type == 'ent_cubemap': diff --git a/src/ent_list.c b/src/ent_list.c new file mode 100644 index 0000000..2dd69a8 --- /dev/null +++ b/src/ent_list.c @@ -0,0 +1,89 @@ +#include "ent_list.h" + +ent_list *_ent_list_get_aliased( const char *alias ) +{ + world_instance *world = &_world.main; + u32 hash = vg_strdjb2( alias ); + for( u32 i=0; ient_list ); i ++ ) + { + ent_list *list = af_arritm( &world->ent_list, i ); + if( list->alias_type == k_list_alias_string ) + if( af_str_eq( &world->meta.af, list->pstr_alias, alias, hash ) ) + return list; + } + return NULL; +} + +void _ent_list_iter_start( struct ent_list_iter *iter, ent_list *list, enum entity_alias filter_type ) +{ + iter->list = list; + iter->i = 0; + iter->specific_type = filter_type; +} + +bool _ent_list_iter( struct ent_list_iter *iter ) +{ + if( !iter->list ) + return 0; + + world_instance *world = &_world.main; +AGAIN: + if( iter->i < iter->list->entity_ref_count ) + { + u32 ref_index = iter->list->entity_ref_start + iter->i; + file_entity_ref *ref = af_arritm( &world->file_entity_ref, ref_index ); + iter->type = mdl_entity_id_type( ref->entity_id ); + iter->index = mdl_entity_id_id( ref->entity_id ); + iter->i ++; + + if( iter->specific_type != k_ent_none ) + { + if( iter->specific_type == iter->type ) return 1; + else goto AGAIN; + } + else return 1; + } + else return 0; +} + +void _ent_list_set_visible( ent_list *list, bool visible ) +{ + world_instance *world = &_world.main; + struct ent_list_iter iter; + _ent_list_iter_start( &iter, list, 0 ); + + while( _ent_list_iter( &iter ) ) + { + if( iter.type == k_ent_objective ) + { + ent_objective *objective = af_arritm( &world->ent_objective, iter.index ); + if( visible ) objective->flags &= ~((u32)k_ent_objective_hidden); + else objective->flags |= k_ent_objective_hidden; + } + else if( iter.type == k_ent_prop ) + { + ent_prop *prop = af_arritm( &world->ent_prop, iter.index ); + if( visible ) prop->flags &= ~((u32)k_prop_flag_hidden); + else prop->flags |= k_prop_flag_hidden; + } + else if( iter.type == k_ent_challenge ) + { + ent_challenge *challenge = af_arritm( &world->ent_challenge, iter.index ); + if( visible ) challenge->flags &= ~((u32)k_ent_challenge_locked); + else challenge->flags |= (u32)k_ent_challenge_locked; + } + else if( iter.type == k_ent_volume ) + { + ent_volume *volume = af_arritm( &world->ent_volume, iter.index ); + if( visible ) volume->flags &= ~((u32)k_ent_volume_flag_disabled); + else volume->flags |= (u32)k_ent_volume_flag_disabled; + } + else if( iter.type == k_ent_marker ) + { + ent_marker *marker = af_arritm( &world->ent_marker, iter.index ); + if( visible ) marker->flags &= ~((u32)k_ent_marker_flag_hidden); + else marker->flags |= (u32)k_ent_marker_flag_hidden; + } + } +} + diff --git a/src/ent_list.h b/src/ent_list.h new file mode 100644 index 0000000..3ab9e74 --- /dev/null +++ b/src/ent_list.h @@ -0,0 +1,14 @@ +#pragma once + +struct ent_list_iter +{ + ent_list *list; + u32 i; + u32 type, index; + enum entity_alias specific_type; +}; + +ent_list *_ent_list_get_aliased( const char *alias ); +void _ent_list_iter_start( struct ent_list_iter *iter, ent_list *list, enum entity_alias filter_type ); +bool _ent_list_iter( struct ent_list_iter *iter ); +void _ent_list_set_visible( ent_list *list, bool visible ); diff --git a/src/ent_npc.c b/src/ent_npc.c new file mode 100644 index 0000000..29c9689 --- /dev/null +++ b/src/ent_npc.c @@ -0,0 +1,338 @@ +#include "ent_npc.h" + +struct +{ + struct + { + enum gino_state + { + k_gino_none, + k_gino_intro, + k_gino_normal, + } + state; + + mdl_context mdl; + i32 sm_main, sm_hat, sm_glow; + v3f co, p0, p1; + f64 command_t; + u32 current_entity_id; + f32 spark_t; + } + gino; + + enum npc_sub_state + { + k_npc_sub_off, + k_npc_sub_reading, + } + sub_state; + + const cs_subtitle *subtitles; + i32 sub_index; + v3f sub_position; +} +_npc; + +struct gino_context +{ + const char *alias; + u32 alias_hash; + + const cs_subtitle *subtitles; +} +static _gino_contexts[] = +{ + /* HEAVEN world */ + { + "heave:introduction", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Hmm.. I'm Gino, hello" }, + { "a2", KCOL_JESUS "Do you remember who you are?" }, + { "a3", KCOL_JESUS "Pick here.." }, + { NULL, NULL }, + }, + }, + { + "heaven:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Welcome to almost Heaven.." }, + { "a2", KCOL_JESUS "The entrance is blocked.." }, + { "a3", KCOL_JESUS "You'll go back to earth for now.." }, + { "a4", KCOL_JESUS "There are people waiting for you.." }, + { "a5", KCOL_JESUS "I think.." }, + { NULL, NULL }, + } + }, + { + "heaven:shop", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Might want to pick up one of these.." }, + { "a2", KCOL_JESUS "See you at the center Island.." }, + { NULL, NULL }, + } + }, + + /* HUB world */ + { + "mtzero:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Someone put boxes here.." }, + { "a2", KCOL_JESUS "Hmm.." }, + { NULL, NULL }, + } + }, + { + "city:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Again with the boxes!" }, + { "a2", KCOL_JESUS "Who is doing that?" }, + { NULL, NULL }, + } + }, + { + "valley:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS ".." }, + { "a2", KCOL_JESUS "You know what to do.." }, + { NULL, NULL }, + } + }, + + /* VOLCANO world */ + { + "docks:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "To get to the docks.." }, + { "a2", KCOL_JESUS "Hmm.." }, + { "a3", KCOL_JESUS "JC demands you do all the tasks here.." }, + { "a4", KCOL_JESUS "Before going home.." }, + { "a5", KCOL_JESUS "Take a look at the map.." }, + { NULL, NULL }, + } + }, +}; + +void _ent_npc_init(void) +{ + for( u32 i=0; ikey ) + { + _npc.sub_state = k_npc_sub_reading; + _cutscene.subtitle = sub->value; + + gui_helper_reset( k_gui_helper_mode_black_bars ); + vg_str text; + if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) + vg_strcat( &text, "Next" ); + v3_copy( localplayer.rb.co, _npc.sub_position ); + } + else + { + _npc.sub_index = 0; + _npc.sub_state = k_npc_sub_off; + _npc.subtitles = NULL; + _cutscene.subtitle = NULL; + gui_helper_reset( k_gui_helper_mode_clear ); + } +} + +void _ent_npc_preupdate(void) +{ + if( _npc.sub_state == k_npc_sub_reading ) + { + f32 dist2 = v3_dist2( _npc.sub_position, localplayer.rb.co ); + if( dist2 > 5.0f*5.0f ) + { + _npc.sub_state = k_npc_sub_off; + _cutscene.subtitle = NULL; + gui_helper_reset( k_gui_helper_mode_clear ); + } + } + + /* gino */ + if( _npc.gino.state == k_gino_intro ) + { + f32 t = (vg.time - _npc.gino.command_t) / 2.0; + bool end = 0; + + if( t >= 1.0f ) + { + end = 1; + t = 1.0f; + } + + if( end ) + _npc.gino.state = k_gino_normal; + + f32 ts = vg_smoothstepf( t ); + v3_lerp( _npc.gino.p0, _npc.gino.p1, ts, _npc.gino.co ); + _npc.gino.co[1] += vg_smoothstepf(1.0f-(fabsf(t-0.5f)*2.0f)) * 8.0f; + } + else + v3_copy( _npc.gino.p1, _npc.gino.co ); + + if( _npc.gino.state != k_gino_none ) + { + f32 dist2 = v3_dist2( _npc.gino.co, localplayer.rb.co ); + _npc.gino.co[0] += cos( vg.time * 1.23 + 0.3 ) * 0.07f; + _npc.gino.co[1] += sin( vg.time ) * 0.1f; + _npc.gino.co[2] += cos( vg.time * 1.1 + 0.3 ) * 0.04f; + + if( dist2 < 40.0f*40.0f ) + { + if( _npc.gino.spark_t < 0.0f ) + { + _npc.gino.spark_t += 0.05f+vg_randf64(&vg.rand)*0.1f; + + v3f pos; + v3_add( _npc.gino.co, (v3f){0,0.16f,0}, pos ); + f32 a = vg_randf64(&vg.rand) * VG_TAUf, + r = 0.43f; + pos[0] += sinf( a ) * r; + pos[2] += cosf( a ) * r; + particle_spawn_cone( &particles_grind, pos, (v3f){0,-1,0}, VG_PIf/2.0f, 2, 4.0f, 0xffffffff ); + } + else + _npc.gino.spark_t -= vg.time_delta; + } + } +} + +void _ent_npc_render( vg_camera *cam ) +{ + if( _npc.gino.state == k_gino_none ) + return; + + world_instance *world = &_world.main; + shader_model_entity_use(); + shader_model_entity_uTexMain( 0 ); + shader_model_entity_uCamera( cam->transform[3] ); + shader_model_entity_uPv( cam->mtx.pv ); + WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_entity ); + + mesh_bind( &_npc.gino.mdl.mesh ); + glActiveTexture( GL_TEXTURE0 ); + + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + glBlendEquation(GL_FUNC_ADD); + glBindTexture( GL_TEXTURE_2D, _npc.gino.mdl.textures[1].glname ); + + m4x3f mmdl; + m3x3_copy( cam->transform, mmdl ); + v3_copy( _npc.gino.co, mmdl[3] ); + shader_model_entity_uMdl( mmdl ); + glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); + mdl_draw_submesh( &_npc.gino.mdl.submeshes[ _npc.gino.sm_glow ] ); + glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 } ); + + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + glBindTexture( GL_TEXTURE_2D, _npc.gino.mdl.textures[0].glname ); + + v3f v0 = { localplayer.rb.co[0] - _npc.gino.co[0], 0.0f, localplayer.rb.co[2] - _npc.gino.co[2] }; + v3_normalize( v0 ); + v3_copy( v0, mmdl[0] ); + v3_copy( (v3f){0,1,0}, mmdl[1] ); + v3_cross( mmdl[0], mmdl[1], mmdl[2] ); + v3_copy( _npc.gino.co, mmdl[3] ); + + m4x4f m4mmdl; + m4x3_expand( mmdl, m4mmdl ); + m4x4_mul( cam->mtx_prev.pv, m4mmdl, m4mmdl ); + shader_model_entity_uMdl( mmdl ); + shader_model_entity_uPvmPrev( m4mmdl ); + mdl_draw_submesh( &_npc.gino.mdl.submeshes[ _npc.gino.sm_main ] ); + + m3x3f mspin; + v4f qspin; + q_axis_angle( qspin, (v3f){0,1,0}, vg_fractf(vg.time)*VG_TAUf*16.0f ); + q_m3x3( qspin, mspin ); + m3x3_mul( mspin, mmdl, mmdl ); + m4x3_expand( mmdl, m4mmdl ); + m4x4_mul( cam->mtx_prev.pv, m4mmdl, m4mmdl ); + shader_model_entity_uMdl( mmdl ); + shader_model_entity_uPvmPrev( m4mmdl ); + mdl_draw_submesh( &_npc.gino.mdl.submeshes[ _npc.gino.sm_hat ] ); +} + +entity_call_result ent_npc_call( world_instance *world, ent_call *call ) +{ + u32 index = mdl_entity_id_id( call->id ); + ent_npc *npc = af_arritm( &world->ent_npc, index ); + + if( AF_STR_EQ( &world->meta.af, npc->pstr_id, "gino" ) ) + { + /* interact */ + if( call->function == 0 ) + { + const char *alias = af_str( &world->meta.af, npc->pstr_context_id ); + u32 hash = vg_strdjb2( alias ); + for( u32 i=0; ifunction == 1 ) + { + if( _npc.gino.current_entity_id != call->id ) + { + _npc.gino.current_entity_id = call->id; + v3_copy( npc->transform.co, _npc.gino.p1 ); + if( _npc.gino.state == k_gino_none ) + v3_add( npc->transform.co, (v3f){0,30,0}, _npc.gino.p0 ); + else + v3_copy( _npc.gino.co, _npc.gino.p0 ); + + _npc.gino.state = k_gino_intro; + _npc.gino.command_t = vg.time; + } + } + + return k_entity_call_result_OK; + } + else if( AF_STR_EQ( &world->meta.af, npc->pstr_id, "JC" ) ) + { + return k_entity_call_result_OK; + } + + return k_entity_call_result_unhandled; +} diff --git a/src/ent_npc.h b/src/ent_npc.h new file mode 100644 index 0000000..94cefd6 --- /dev/null +++ b/src/ent_npc.h @@ -0,0 +1,16 @@ +#pragma once + +enum npc +{ + k_npc_none = 0, + k_npc_gino, + k_npc_jc, +}; + +void _ent_npc_init(void); +void _ent_npc_render( vg_camera *cam ); +void _ent_npc_goto( v3f pos, i32 uid ); +void _ent_npc_preupdate(void); +void _ent_npc_speech( enum npc npc_id, const cs_subtitle *subs ); +void _ent_npc_reset(void); +entity_call_result ent_npc_call( world_instance *world, ent_call *call ); diff --git a/src/entity.c b/src/entity.c index ee2720a..7a64422 100644 --- a/src/entity.c +++ b/src/entity.c @@ -36,6 +36,7 @@ void entity_call( world_instance *world, ent_call *call ) [k_ent_glider] = ent_glider_call, [k_ent_water] = ent_water_call, [k_ent_script] = ent_script_call, + [k_ent_npc] = ent_npc_call, }; if( type >= VG_ARRAY_LEN(table) ){ @@ -47,17 +48,13 @@ void entity_call( world_instance *world, ent_call *call ) if( !fn ) { - vg_error( "Entity type %u does not have a call handler, " - "but was called anyway\n", type ); + vg_error( "Entity type %u does not have a call handler, but was called anyway\n", type ); return; } enum entity_call_result res = fn( world, call ); - if( res == k_entity_call_result_unhandled ) - { vg_warn( "Call to entity %u#%u was unhandled.\n", type, index ); - } } ent_marker *ent_find_marker( mdl_context *mdl, array_file_ptr *arr, diff --git a/src/entity.h b/src/entity.h index d91ad89..b781e0d 100644 --- a/src/entity.h +++ b/src/entity.h @@ -182,9 +182,17 @@ enum gate_type{ }; #endif +enum list_alias_type +{ + k_list_alias_none = 0, + k_list_alias_string = 1 +}; + struct ent_list { u16 entity_ref_start, entity_ref_count; + u8 alias_type, none0, none1, none2; + u32 pstr_alias; }; struct file_entity_ref @@ -334,7 +342,8 @@ enum ent_volume_flag { k_ent_volume_flag_disabled = 0x2, k_ent_volume_flag_removed0 = 0x4, k_ent_volume_flag_interact = 0x8, - k_ent_volume_flag_water = 0x10 + k_ent_volume_flag_water = 0x10, + k_ent_volume_flag_repeatable= 0x20 }; struct ent_volume @@ -728,7 +737,7 @@ struct ent_glider { struct ent_npc { mdl_transform transform; - u32 id, context, camera; + u32 pstr_id, pstr_context_id; }; #include "world.h" @@ -739,7 +748,5 @@ struct ent_call{ void *data; }; -typedef enum entity_call_result - (*fn_entity_call_handler)( world_instance *, ent_call *); - +typedef enum entity_call_result (*fn_entity_call_handler)( world_instance *, ent_call *); void entity_call( world_instance *world, ent_call *call ); diff --git a/src/metascene.c b/src/metascene.c index 437f42f..910dc30 100644 --- a/src/metascene.c +++ b/src/metascene.c @@ -15,8 +15,7 @@ void metascene_load( ms_context *ms, const char *path, void *alloc ) AF_LOAD_ARRAY_STRUCT( &ms->af, &ms->cameras, ent_camera, alloc ); AF_LOAD_ARRAY_STRUCT( &ms->af, &ms->audios, ent_audio, alloc ); AF_LOAD_ARRAY_STRUCT( &ms->af, &ms->audio_clips, ent_audio_clip, alloc ); - af_load_array( &ms->af, &ms->curves, "ms_curves", - alloc, sizeof(ms_curve_keyframe) ); + af_load_array( &ms->af, &ms->curves, "ms_curves", alloc, sizeof(ms_curve_keyframe) ); af_close( &ms->af ); if( af_arrcount( &ms->infos ) ) @@ -25,9 +24,7 @@ void metascene_load( ms_context *ms, const char *path, void *alloc ) ms->info = *src_inf; } else - { vg_fatal_error( "No scene info in metascene.\n" ); - } } struct cs_instance *_cutscene_get_first_model_instance( const char *mdl_name ) @@ -38,44 +35,12 @@ struct cs_instance *_cutscene_get_first_model_instance( const char *mdl_name ) struct model_ref *mref = &_cutscene.refs[ inst->ref_id ]; if( vg_str_eq( mdl_name, mref->name ) ) - { return inst; - } } return NULL; } -void _cutscene_play(void) -{ - _cutscene.state = k_cutscene_state_playing; - - vg_audio_lock(); - for( u32 j=0; jclip_start ); - - if( audio->flags & AUDIO_FLAG_AUTO_START ) - { - const u16 group = 0xfff1; - const u32 flags = AUDIO_FLAG_CUTSCENE; - - if( audio->flags & AUDIO_FLAG_SPACIAL_3D ) - vg_audio_oneshot_3d( &clip->_.clip, audio->transform.co, audio->transform.s[0], audio->volume, group,flags); - else - vg_audio_oneshot( &clip->_.clip, 1.0f, 0.0f, group, flags ); - } - } - vg_audio_unlock(); -} - -void _cutscene_set_subtitle_list( const cs_subtitle *subtitles ) -{ - _cutscene.subtitle_list = subtitles; - _cutscene.subtitle_index = 0; -} - void _cutscene_unload(void) { vg_info( "Unloading cutscene\n" ); @@ -116,9 +81,7 @@ static void _cutscene_override_asoc( u32 instance_id, u32 override_index, struct mdl_context *mdl = &_cutscene.refs[ instance->ref_id ].mdl; ms_instance *oins = af_arritm( &_cutscene.meta.instances, instance_id ); - ms_override *override = - af_arritm( &_cutscene.meta.overrides, - oins->override_start + override_index ); + ms_override *override = af_arritm( &_cutscene.meta.overrides, oins->override_start + override_index ); out_asoc->orig_data = mdl; out_asoc->entity_type = override->entity_type; @@ -159,9 +122,7 @@ static void _cutscene_get_strip_asoc( ms_strip *strip, out_asoc->override = NULL; } else - { _cutscene_override_asoc( strip->instance_id, strip->object_id, out_asoc ); - } } static void sync_cutscene_loaded( void *userdata ) @@ -204,8 +165,7 @@ static void cutscene_load_thread( vg_async_task *task ) { struct model_ref *ref_j = &_cutscene.refs[ j ]; - if( af_str_eq( &_cutscene.meta.af, instance->pstr_name, - ref_j->name, ref_j->name_hash ) ) + if( af_str_eq( &_cutscene.meta.af, instance->pstr_name, ref_j->name, ref_j->name_hash ) ) { ref = ref_j; ref_id = j; @@ -226,7 +186,6 @@ static void cutscene_load_thread( vg_async_task *task ) } ref->reference_count ++; - _cutscene.instances[ i ].ref_id = ref_id; _cutscene.instances[ i ].skinning_data = NULL; _cutscene.instances[ i ].disable_render = 0; @@ -251,8 +210,7 @@ static void cutscene_load_thread( vg_async_task *task ) u32 skeleton_count = ref->mdl.armature_count; if( skeleton_count ) { - ref->skeletons = vg_linear_alloc( _cutscene.arena, - sizeof(struct cs_skeleton) * skeleton_count ); + ref->skeletons = vg_linear_alloc( _cutscene.arena, sizeof(struct cs_skeleton) * skeleton_count ); ref->total_skinning_bones = 0; for( u32 j=0; jref_id ]; - ins->skinning_data = vg_linear_alloc( _cutscene.arena, - sizeof(m4x3f) * ref->total_skinning_bones ); - + ins->skinning_data = vg_linear_alloc( _cutscene.arena, sizeof(m4x3f) * ref->total_skinning_bones ); for( u32 j=0; jtotal_skinning_bones; j ++ ) - { m4x3_identity( ins->skinning_data[ j ] ); - } /* load overrides */ ms_instance *oins = af_arritm( &_cutscene.meta.instances, i ); for( u32 j=0; joverride_count; j ++ ) { - ms_override *override = - af_arritm( &_cutscene.meta.overrides, oins->override_start + j ); + ms_override *override = af_arritm( &_cutscene.meta.overrides, oins->override_start + j ); struct cs_asoc asoc; _cutscene_override_asoc( i, j, &asoc ); @@ -297,14 +250,11 @@ static void cutscene_load_thread( vg_async_task *task ) VG_ASSERT( asoc.entity_type == 28 ); struct cs_skeleton *skele = &ref->skeletons[ asoc.entity_index ]; - m4x3f mmdl; mdl_transform_m4x3( &override->transform, mmdl ); for( u32 l=0; lsk.bone_count; l ++ ) - { m4x3_copy( mmdl, ins->skinning_data[skele->skinning_offset+l] ); - } } } @@ -318,9 +268,7 @@ static void cutscene_load_thread( vg_async_task *task ) ent_audio_clip *clip = af_arritm( &_cutscene.meta.audio_clips, audio->clip_start+k ); if( clip->_.file.pack_size ) - { vg_error( "Currently not support packed audio in metascene..." ); - } else { clip->_.clip.path = af_str( &_cutscene.meta.af, clip->_.file.pstr_path ); @@ -336,40 +284,29 @@ static void cutscene_load_thread( vg_async_task *task ) vg_async_call( &vg.main_tasks, sync_cutscene_loaded, NULL ); } -static int cmd_cutscene_load( int argc, const char *argv[] ) +void _cutscene_load_and_play( const char *path, const cs_subtitle *subtitles, bool freeze_player ) { - if( argc == 1 ) - { - if( _cutscene.state != k_cutscene_state_none ) - { - vg_error( "Cutscene already in use..\n" ); - return 0; - } + VG_ASSERT( _cutscene.state == k_cutscene_state_none ); - _cutscene.state = k_cutscene_state_loading; - _cutscene.time = 0.0f; - _cutscene.strip = 0; - _cutscene.active_samplers = 0; - - u32 len = strlen( argv[0] ) +1; - vg_async_task *task = vg_allocate_async_task( &vg.loader_tasks, sizeof(struct cutscene_load_info) + len, 1 ); - struct cutscene_load_info *info = (void *)task->data; - strcpy( info->path, argv[0] ); - vg_async_task_dispatch( task, cutscene_load_thread ); - return 1; - } - else - { - vg_error( "Usage: cutscene path/to/cutscene.ms\n" ); - return 0; - } + _cutscene.state = k_cutscene_state_loading; + _cutscene.subtitle_list = subtitles; + _cutscene.subtitle_index = 0; + _cutscene.time = 0.0f; + _cutscene.strip = 0; + _cutscene.active_samplers = 0; + _cutscene.freeze_player = freeze_player; + + u32 len = strlen( path ) +1; + vg_async_task *task = vg_allocate_async_task( &vg.loader_tasks, sizeof(struct cutscene_load_info) + len, 1 ); + struct cutscene_load_info *info = (void *)task->data; + strcpy( info->path, path ); + vg_async_task_dispatch( task, cutscene_load_thread ); } /* * Currently draws everything as skinned meshes. */ -void cutscene_render_instance( struct cs_instance *ins, - world_instance *world, vg_camera *cam ) +void cutscene_render_instance( struct cs_instance *ins, world_instance *world, vg_camera *cam ) { if( ins->disable_render ) return; @@ -471,15 +408,12 @@ static bool link_internal_datapath( struct cs_asoc *asoc, const char *datapath, out_link->target = reference[i].arr + offset; out_link->semantic_type = reference[i].semantic + offset; - vg_info( "Linked %d#%d:'%s'\n", - asoc->entity_type, asoc->entity_index, datapath ); + vg_info( "Linked %d#%d:'%s'\n", asoc->entity_type, asoc->entity_index, datapath ); return 1; } } - vg_warn( "Failed link %d#%d:'%s'\n", - asoc->entity_type, asoc->entity_index, datapath ); - + vg_warn( "Failed link %d#%d:'%s'\n", asoc->entity_type, asoc->entity_index, datapath ); return 0; } @@ -490,6 +424,37 @@ ent_camera *_cutscene_active_camera(void) void cutscene_update( f32 delta ) { + if( _cutscene.state == k_cutscene_state_ready ) + { + _cutscene.player_binding = _cutscene_get_first_model_instance( "models/ch_none" ); + if( _cutscene.player_binding ) + _cutscene.player_binding->disable_render = 1; + + /* start playing */ + if( _cutscene.freeze_player ) + localplayer.immobile = 1; + + _cutscene.state = k_cutscene_state_playing; + vg_audio_lock(); + for( u32 j=0; jclip_start ); + + if( audio->flags & AUDIO_FLAG_AUTO_START ) + { + const u16 group = 0xfff1; + const u32 flags = AUDIO_FLAG_CUTSCENE; + + if( audio->flags & AUDIO_FLAG_SPACIAL_3D ) + vg_audio_oneshot_3d( &clip->_.clip, audio->transform.co, audio->transform.s[0], audio->volume, group,flags); + else + vg_audio_oneshot( &clip->_.clip, 1.0f, 0.0f, group, flags ); + } + } + vg_audio_unlock(); + } + if( _cutscene.state == k_cutscene_state_unloading ) { if( !vg_audio_flagged_stopped( AUDIO_FLAG_CUTSCENE ) ) @@ -519,9 +484,7 @@ void cutscene_update( f32 delta ) struct cs_sampler *si = &_cutscene.samplers[i]; if( frame > (si->strip->offset + si->strip->length) ) - { move = 1; - } else { if( move ) @@ -541,9 +504,7 @@ void cutscene_update( f32 delta ) ms_strip *strip = af_arritm(&_cutscene.meta.strips, i); if( frame < strip->offset ) - { break; - } if( frame > strip->offset + strip->length ) { @@ -560,8 +521,7 @@ void cutscene_update( f32 delta ) _cutscene_get_strip_asoc( strip, &asoc ); VG_ASSERT( asoc.entity_type == k_ent_camera ); - ent_camera *cam = - af_arritm( &_cutscene.meta.cameras, asoc.entity_index ); + ent_camera *cam = af_arritm( &_cutscene.meta.cameras, asoc.entity_index ); _cutscene.active_camera = cam; } @@ -606,78 +566,66 @@ void cutscene_update( f32 delta ) } else { - if( strip->instance_id == 0xffffffff ) - { - vg_info( "+ Strip: '%s' entity: %u\n", - af_str( &_cutscene.meta.af, strip->pstr_name ), - strip->object_id ); - /* internal link */ - struct cs_asoc asoc; - _cutscene_get_strip_asoc( strip, &asoc ); - - if( strip->data_mode == 1 ) + if( strip->instance_id == 0xffffffff ) { - for( u32 j=0; jdata_count; j ++ ) - { - ms_track *track = af_arritm( &_cutscene.meta.tracks, - strip->data_start + j ); - - const char *datapath = - af_str( &_cutscene.meta.af, track->pstr_datapath ); - - struct cs_link_info link; - if( !link_internal_datapath( &asoc, datapath, &link ) ) - continue; - - VG_ASSERT( _cutscene.active_samplers < - VG_ARRAY_LEN(_cutscene.samplers) ); - - struct cs_sampler *samp = - &_cutscene.samplers[ _cutscene.active_samplers ++ ]; - samp->strip = strip; - samp->curves.track = track; + vg_info( "+ Strip: '%s' entity: %u\n", af_str( &_cutscene.meta.af, strip->pstr_name ), strip->object_id ); + /* internal link */ + struct cs_asoc asoc; + _cutscene_get_strip_asoc( strip, &asoc ); - samp->curves.target = link.target; - samp->curves.semantic = link.semantic_type; - samp->curves.keyframe = 0; - samp->override = asoc.override; - VG_ASSERT( samp->curves.target ); + if( strip->data_mode == 1 ) + { + for( u32 j=0; jdata_count; j ++ ) + { + ms_track *track = af_arritm( &_cutscene.meta.tracks, strip->data_start + j ); + const char *datapath = af_str( &_cutscene.meta.af, track->pstr_datapath ); + + struct cs_link_info link; + if( !link_internal_datapath( &asoc, datapath, &link ) ) + continue; + + VG_ASSERT( _cutscene.active_samplers < VG_ARRAY_LEN(_cutscene.samplers) ); + struct cs_sampler *samp = &_cutscene.samplers[ _cutscene.active_samplers ++ ]; + samp->strip = strip; + samp->curves.track = track; + + samp->curves.target = link.target; + samp->curves.semantic = link.semantic_type; + samp->curves.keyframe = 0; + samp->override = asoc.override; + VG_ASSERT( samp->curves.target ); + } } - } - else VG_ASSERT(0); - } - else - { - /* external link */ - struct cs_instance *ins = &_cutscene.instances[ strip->instance_id ]; - - struct cs_asoc asoc; - _cutscene_get_strip_asoc( strip, &asoc ); - VG_ASSERT( asoc.entity_type == 28 ); - - if( strip->data_mode == 1 ) - { - VG_ASSERT(0); + else VG_ASSERT(0); } else { - VG_ASSERT( _cutscene.active_samplers < - VG_ARRAY_LEN(_cutscene.samplers) ); + /* external link */ + struct cs_instance *ins = &_cutscene.instances[ strip->instance_id ]; + + struct cs_asoc asoc; + _cutscene_get_strip_asoc( strip, &asoc ); + VG_ASSERT( asoc.entity_type == 28 ); - struct cs_sampler *samp = - &_cutscene.samplers[ _cutscene.active_samplers ++ ]; + if( strip->data_mode == 1 ) + { + VG_ASSERT(0); + } + else + { + VG_ASSERT( _cutscene.active_samplers < VG_ARRAY_LEN(_cutscene.samplers) ); - struct model_ref *ref = &_cutscene.refs[ ins->ref_id ]; - struct cs_skeleton *skele = &ref->skeletons[ asoc.entity_index ]; + struct cs_sampler *samp = &_cutscene.samplers[ _cutscene.active_samplers ++ ]; + struct model_ref *ref = &_cutscene.refs[ ins->ref_id ]; + struct cs_skeleton *skele = &ref->skeletons[ asoc.entity_index ]; - samp->strip = strip; - samp->skeleton.skinning_data = - &ins->skinning_data[ skele->skinning_offset ]; - samp->skeleton.ref_sk = &skele->sk; - samp->override = asoc.override; + samp->strip = strip; + samp->skeleton.skinning_data = &ins->skinning_data[ skele->skinning_offset ]; + samp->skeleton.ref_sk = &skele->sk; + samp->override = asoc.override; + } } } - } _cutscene.strip ++; } @@ -693,8 +641,7 @@ void cutscene_update( f32 delta ) { .strip = samp->strip, .framerate = _cutscene.meta.info.framerate, - .keyframes_base = af_arritm( &_cutscene.meta.keyframes, - samp->strip->data_start ) + .keyframes_base = af_arritm( &_cutscene.meta.keyframes, samp->strip->data_start ) }; f32 t = _cutscene.time; @@ -706,11 +653,9 @@ void cutscene_update( f32 delta ) ms_keyframe pose[32]; skeleton_sample_anim_clamped( ref_sk, &temp_anim, t, pose ); - skeleton_apply_pose( ref_sk, pose, - k_anim_apply_defer_ik, final_mtx ); + skeleton_apply_pose( ref_sk, pose, k_anim_apply_defer_ik, final_mtx ); skeleton_apply_ik_pass( ref_sk, final_mtx ); - skeleton_apply_pose( ref_sk, pose, - k_anim_apply_deffered_only, final_mtx ); + skeleton_apply_pose( ref_sk, pose, k_anim_apply_deffered_only, final_mtx ); skeleton_apply_inverses( ref_sk, final_mtx ); if( samp->override ) @@ -735,12 +680,9 @@ void cutscene_update( f32 delta ) { if( samp->curves.track->keyframe_count > 1 ) { - for( u32 j=samp->curves.keyframe+1; - jcurves.track->keyframe_count; j ++ ) + for( u32 j=samp->curves.keyframe+1; jcurves.track->keyframe_count; j ++ ) { - kr = af_arritm( &_cutscene.meta.curves, - samp->curves.track->keyframe_start + j ); - + kr = af_arritm( &_cutscene.meta.curves, samp->curves.track->keyframe_start + j ); if( kr->co[0] <= t ) { kl = kr; @@ -753,14 +695,9 @@ void cutscene_update( f32 delta ) } if( kl && kr ) - { - *samp->curves.target = - explicit_bezier( kl->co, kl->r, kr->l, kr->co, t ); - } + *samp->curves.target = explicit_bezier( kl->co, kl->r, kr->l, kr->co, t ); else - { *samp->curves.target = kl->co[1]; - } if( samp->curves.semantic == CS_FOV ) { @@ -777,19 +714,16 @@ void cutscene_update( f32 delta ) vg_line_cross( cam->co, VG__RED, 0.2f ); } -#if 0 - if( (_cutscene.strip == af_arrcount(&_cutscene.meta.strips)) && - (_cutscene.active_samplers == 0 ) ) - { - _cutscene.state = k_cutscene_state_done; - } -#endif - f32 scene_t = _cutscene.time * _cutscene.meta.info.framerate, end_t = _cutscene.meta.info.end_frame; if( scene_t >= end_t ) - _cutscene.state = k_cutscene_state_done; + { + if( _cutscene.freeze_player ) + localplayer.immobile = 0; + + _cutscene_unload(); + } } void cutscene_render_fadeout(void) @@ -836,9 +770,7 @@ void cutscene_render( world_instance *world, vg_camera *cam ) if( _cutscene.state >= k_cutscene_state_ready ) { for( u32 i=0; i<_cutscene.instance_count; i ++ ) - { cutscene_render_instance( &_cutscene.instances[i], world, cam ); - } } } @@ -950,9 +882,7 @@ static void cb_cutscene_view( ui_context *ctx, ui_rect rect, struct vg_magi_pane struct model_ref *mref = &_cutscene.refs[i]; char inf[128]; - snprintf( inf, sizeof(inf), "%s (%u references)", - mref->name, mref->reference_count ); - + snprintf( inf, sizeof(inf), "%s (%u references)", mref->name, mref->reference_count ); ui_text( ctx, box, inf, 1, k_ui_align_middle_left, 0 ); box[1] += 16; } @@ -976,10 +906,7 @@ static void cb_cutscene_view( ui_context *ctx, ui_rect rect, struct vg_magi_pane box[3] = 16; if( ui_clip( panel_r, box, box ) ) - { - ui_text( ctx, box, af_str( &_cutscene.meta.af, strip->pstr_name ), - 1, k_ui_align_middle_left, 0 ); - } + ui_text( ctx, box, af_str( &_cutscene.meta.af, strip->pstr_name ), 1, k_ui_align_middle_left, 0 ); continue; } @@ -987,12 +914,8 @@ static void cb_cutscene_view( ui_context *ctx, ui_rect rect, struct vg_magi_pane for( u32 k=0; koffset + usage[k]->length < strip->offset ) - { usage[k] = NULL; - } - } if( !usage[k] ) { @@ -1011,13 +934,11 @@ static void cb_cutscene_view( ui_context *ctx, ui_rect rect, struct vg_magi_pane u32 colour = af_str_hash( &_cutscene.meta.af, strip->pstr_name ); ui_fill( ctx, box, colour | 0xff000000 ); - ui_text( ctx, box, af_str( &_cutscene.meta.af, strip->pstr_name ), 1, - k_ui_align_middle_center, 0 ); + ui_text( ctx, box, af_str( &_cutscene.meta.af, strip->pstr_name ), 1, k_ui_align_middle_center, 0 ); } } - ui_rect cursor = { (f32)_cutscene.time*_cutscene.meta.info.framerate, - 0, 1, VG_ARRAY_LEN(usage)*32 }; + ui_rect cursor = { (f32)_cutscene.time*_cutscene.meta.info.framerate, 0, 1, VG_ARRAY_LEN(usage)*32 }; cursor[0] += root[0]; cursor[1] += root[1]; if( ui_clip( panel_r, cursor, cursor ) ) @@ -1038,6 +959,6 @@ static int cmd_cutscene_inspector( int argc, const char *argv[] ) void cutscene_init(void) { - vg_console_reg_cmd( "cutscene", cmd_cutscene_load, NULL ); + //vg_console_reg_cmd( "cutscene", cmd_cutscene_load, NULL ); vg_console_reg_cmd( "cutscene_inspector", cmd_cutscene_inspector, NULL ); } diff --git a/src/metascene.h b/src/metascene.h index 6988211..7419468 100644 --- a/src/metascene.h +++ b/src/metascene.h @@ -170,6 +170,8 @@ struct _cutscene const *subtitle_list; u32 subtitle_index; bool subtitle_length_warning; + + bool freeze_player; } extern _cutscene; @@ -177,7 +179,7 @@ void metascene_load( ms_context *ms, const char *path, void *alloc ); void cutscene_init(void); void cutscene_render( world_instance *world, vg_camera *cam ); void cutscene_render_fadeout(void); -void _cutscene_play(void); +void _cutscene_load_and_play( const char *path, const cs_subtitle *subtitles, bool freeze_player ); void _cutscene_unload(void); void cutscene_update( f32 delta ); ent_camera *_cutscene_active_camera(void); diff --git a/src/npc_gino.c b/src/npc_gino.c deleted file mode 100644 index b5d44a1..0000000 --- a/src/npc_gino.c +++ /dev/null @@ -1,258 +0,0 @@ -#include "npc_gino.h" - -struct -{ - enum gino_state - { - k_gino_none, - k_gino_intro, - k_gino_normal, - } - state; - - mdl_context mdl; - i32 sm_main, sm_hat, sm_glow; - - f64 command_t; - v3f co, p0, p1; - - i32 uid; - - enum gino_sub_state - { - k_gino_sub_off, - k_gino_sub_reading, - k_gino_sub_read - } - sub_state; - - const cs_subtitle *subtitles; - i32 sub_index; - - f32 spark_t; -} -_gino; - -void _npc_gino_reset(void) -{ - _gino.state = k_gino_none; - _gino.sub_state = k_gino_sub_off; - _gino.spark_t = 0.0f; - _gino.sub_index = 0; - _gino.subtitles = NULL; - _gino.uid = 0; - _gino.command_t = 0.0; -} - -void _npc_gino_speech( const cs_subtitle *subs ) -{ - _gino.subtitles = subs; -} - -void _npc_gino_goto( v3f pos, i32 uid ) -{ - if( _gino.uid == uid ) - return; - - v3_copy( pos, _gino.p1 ); - - if( _gino.state == k_gino_none ) - v3_add( pos, (v3f){0,30,0}, _gino.p0 ); - else - v3_copy( _gino.co, _gino.p0 ); - - _gino.uid = uid; - _gino.state = k_gino_intro; - _gino.command_t = vg.time; -} - -void _npc_gino_init(void) -{ - void *alloc = vg_mem.rtmemory; - mdl_context *mdl = &_gino.mdl; - mdl_open( mdl, "models/gino.mdl", alloc ); - mdl_load_metadata_block( mdl, alloc ); - mdl_async_full_load_std( mdl, NULL ); - _gino.sm_main = mdl_get_submesh_index( mdl, "gino" ); - _gino.sm_hat = mdl_get_submesh_index( mdl, "gino.hat" ); - _gino.sm_glow = mdl_get_submesh_index( mdl, "gino.spt" ); - mdl_close( mdl ); -} - -void _npc_gino_preupdate(void) -{ - if( _gino.state == k_gino_none ) - return; - - f32 dist2 = v3_dist2( _gino.p1, localplayer.rb.co ); - if( _world.event == k_world_event_gino ) - { - if( dist2 > 4.0f*4.0f ) - { - if( world_clear_event( k_world_event_gino ) ) - { - _gino.sub_state = k_gino_sub_off; - _cutscene.subtitle = NULL; - gui_helper_reset( k_gui_helper_mode_clear ); - } - } - else - { - if( (_gino.sub_state != k_gino_sub_read) && button_down( k_srbind_maccept ) && _gino.subtitles ) - { - srinput.state = k_input_state_resume; - if( _gino.sub_state == k_gino_sub_reading ) - _gino.sub_index ++; - - const cs_subtitle *sub = &_gino.subtitles[ _gino.sub_index ]; - - if( sub->key ) - { - _gino.sub_state = k_gino_sub_reading; - _cutscene.subtitle = sub->value; - - gui_helper_reset( k_gui_helper_mode_black_bars ); - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) - vg_strcat( &text, "Next" ); - } - else - { - _gino.sub_index = 0; - _gino.sub_state = k_gino_sub_read; - _cutscene.subtitle = NULL; - gui_helper_reset( k_gui_helper_mode_clear ); - } - } - } - } - - v3f co; - - if( _gino.state == k_gino_normal ) - { - v3_copy( _gino.p1, co ); - - if( _world.event == k_world_event_none ) - { - if( dist2 < 3.0f*3.0f ) - { - if( localplayer.subsystem == k_player_subsystem_walk ) - { - if( world_set_event( k_world_event_gino ) ) - { - gui_helper_reset( k_gui_helper_mode_black_bars ); - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) - vg_strcat( &text, "Talk to Gino" ); - } - } - } - } - } - else - { - f32 t = (vg.time - _gino.command_t) / 2.0; - bool end = 0; - - if( t >= 1.0f ) - { - end = 1; - t = 1.0f; - } - - if( end ) - _gino.state = k_gino_normal; - - f32 ts = vg_smoothstepf( t ); - v3_lerp( _gino.p0, _gino.p1, ts, co ); - co[1] += vg_smoothstepf(1.0f-(fabsf(t-0.5f)*2.0f)) * 8.0f; - } - - co[0] += cos( vg.time * 1.23 + 0.3 ) * 0.07f; - co[1] += sin( vg.time ) * 0.1f; - co[2] += cos( vg.time * 1.1 + 0.3 ) * 0.04f; - v3_copy( co, _gino.co ); - - if( dist2 < 40.0f*40.0f ) - { - if( _gino.spark_t < 0.0f ) - { - _gino.spark_t += 0.05f+vg_randf64(&vg.rand)*0.1f; - - v3f pos; - v3_add( co, (v3f){0,0.16f,0}, pos ); - f32 a = vg_randf64(&vg.rand) * VG_TAUf, - r = 0.43f; - pos[0] += sinf( a ) * r; - pos[2] += cosf( a ) * r; - particle_spawn_cone( &particles_grind, pos, (v3f){0,-1,0}, VG_PIf/2.0f, 2, 4.0f, 0xffffffff ); - } - else - _gino.spark_t -= vg.time_delta; - } -} - -void _npc_gino_render( vg_camera *cam ) -{ - if( _gino.state == k_gino_none ) - return; - - world_instance *world = &_world.main; - shader_model_entity_use(); - shader_model_entity_uTexMain( 0 ); - shader_model_entity_uCamera( cam->transform[3] ); - shader_model_entity_uPv( cam->mtx.pv ); - WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_entity ); - - mesh_bind( &_gino.mdl.mesh ); - glActiveTexture( GL_TEXTURE0 ); - - glDepthMask(GL_FALSE); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); - glBlendEquation(GL_FUNC_ADD); - glBindTexture( GL_TEXTURE_2D, _gino.mdl.textures[1].glname ); - - m4x3f mmdl; - m3x3_copy( cam->transform, mmdl ); - v3_copy( _gino.co, mmdl[3] ); - shader_model_entity_uMdl( mmdl ); - glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); - mdl_draw_submesh( &_gino.mdl.submeshes[ _gino.sm_glow ] ); - glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 } ); - - glDepthMask(GL_TRUE); - glDisable(GL_BLEND); - glBindTexture( GL_TEXTURE_2D, _gino.mdl.textures[0].glname ); - - v3f v0 = { localplayer.rb.co[0] - _gino.co[0], 0.0f, localplayer.rb.co[2] - _gino.co[2] }; - v3_normalize( v0 ); - v3_copy( v0, mmdl[0] ); - v3_copy( (v3f){0,1,0}, mmdl[1] ); - v3_cross( mmdl[0], mmdl[1], mmdl[2] ); - v3_copy( _gino.co, mmdl[3] ); - - m4x4f m4mmdl; - m4x3_expand( mmdl, m4mmdl ); - m4x4_mul( cam->mtx_prev.pv, m4mmdl, m4mmdl ); - shader_model_entity_uMdl( mmdl ); - shader_model_entity_uPvmPrev( m4mmdl ); - mdl_draw_submesh( &_gino.mdl.submeshes[ _gino.sm_main ] ); - - m3x3f mspin; - v4f qspin; - q_axis_angle( qspin, (v3f){0,1,0}, vg_fractf(vg.time)*VG_TAUf*16.0f ); - q_m3x3( qspin, mspin ); - m3x3_mul( mspin, mmdl, mmdl ); - m4x3_expand( mmdl, m4mmdl ); - m4x4_mul( cam->mtx_prev.pv, m4mmdl, m4mmdl ); - shader_model_entity_uMdl( mmdl ); - shader_model_entity_uPvmPrev( m4mmdl ); - mdl_draw_submesh( &_gino.mdl.submeshes[ _gino.sm_hat ] ); -} - -void _npc_gino_imgui( ui_context *ctx ) -{ - vg_camera *cam = &g_render.cam; -} diff --git a/src/npc_gino.h b/src/npc_gino.h deleted file mode 100644 index 00bdfed..0000000 --- a/src/npc_gino.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -void _npc_gino_init(void); -void _npc_gino_render( vg_camera *cam ); -void _npc_gino_goto( v3f pos, i32 uid ); -void _npc_gino_preupdate(void); -void _npc_gino_imgui( ui_context *ctx ); -void _npc_gino_speech( const cs_subtitle *subs ); -void _npc_gino_reset(void); diff --git a/src/scripts/blocker_break.c b/src/scripts/blocker_break.c index 37f9a11..edb1a06 100644 --- a/src/scripts/blocker_break.c +++ b/src/scripts/blocker_break.c @@ -1,20 +1,17 @@ -void _explode_template_boom( ent_script_event *event ) +void _explode_template_boom( ent_list *list ) { - ent_list_set_visible( event->world, event->entity_list, 0 ); - + world_instance *world = &_world.main; + _ent_list_set_visible( list, 0 ); v3f where = {0,0,0}; - ent_list *list = event->entity_list; - for( u32 i=0; ientity_ref_count; i ++ ) - { - file_entity_ref *ref = af_arritm( &event->world->file_entity_ref, list->entity_ref_start + i ); - - u32 type = mdl_entity_id_type( ref->entity_id ), - index = mdl_entity_id_id( ref->entity_id ); + struct ent_list_iter iter; + _ent_list_iter_start( &iter, list, 0 ); - if( type == k_ent_marker ) + while( _ent_list_iter( &iter ) ) + { + if( iter.type == k_ent_marker ) { - ent_marker *marker = af_arritm( &event->world->ent_marker, index ); + ent_marker *marker = af_arritm( &world->ent_marker, iter.index ); for( u32 j=0; j<80; j ++ ) { particle_spawn_cone( &particles_env, marker->transform.co, @@ -27,38 +24,3 @@ void _explode_template_boom( ent_script_event *event ) vg_audio_oneshot_3d( &audio_wood_break, where, 100.0f, 1.0f, 0, 0 ); vg_audio_unlock(); } - -static bool _skaterift_script_blocker_break_template( ent_script_event *event, - const struct generic_cutscene *cutscene_template, - const char *once_nugget_trigger ) -{ - static const struct generic_cutscene cutscene = - { - .metascene_path = "metascenes/unlock_docks.ms", - .freeze_player = 1, - }; - generic_cutscene_wrapper( &cutscene, event ); - - if( on_function_trigger( event, 1 ) ) - { - vg_error( "Show required objectives here\n" ); - } - - if( on_function_trigger( event, 2 ) ) - { - if( on_nugget_once( event, "unlock_docks_view" ) ) - { - play_generic_cutscene( event ); - } - else - { - ent_list_set_visible( event->world, event->entity_list, 0 ); - } - } - - if( on_cutscene_marker( event, "$break" ) ) - { - } - - return 1; -} diff --git a/src/scripts/city.c b/src/scripts/city.c index 378b0f5..8a47073 100644 --- a/src/scripts/city.c +++ b/src/scripts/city.c @@ -1,5 +1,6 @@ static bool _skaterift_script_ch3s1( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { "j1", KCOL_JOHN "Ohh this is it guys." }, @@ -22,12 +23,13 @@ static bool _skaterift_script_ch3s1( ent_script_event *event ) { play_generic_cutscene( event ); } - +#endif return 1; } static bool _skaterift_script_ch3s2( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { "m1", KCOL_MIKE "Is that the FBI??" }, @@ -44,11 +46,13 @@ static bool _skaterift_script_ch3s2( ent_script_event *event ) .subtitles = EN, }; optional_video_wrapper( &cutscene, "ch3s2_view", 0, event ); +#endif return 1; } static bool _skaterift_script_ch3s3( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { "p1", KCOL_PRES "Yall have some explaining to do here.." }, @@ -94,5 +98,6 @@ static bool _skaterift_script_ch3s3( ent_script_event *event ) .subtitles = EN, }; optional_video_wrapper( &cutscene, "ch3s3_view", 0, event ); +#endif return 1; } diff --git a/src/scripts/generic.c b/src/scripts/generic.c index 91ff462..e9bbc90 100644 --- a/src/scripts/generic.c +++ b/src/scripts/generic.c @@ -1,3 +1,4 @@ + struct board_maker_unlock_waiter { bool changed; @@ -30,7 +31,7 @@ static bool _skaterift_script_board_maker_unlock( ent_script_event *event ) struct board_maker_unlock_waiter *waiter = event->userdata; if( waiter->changed ) { - ent_list_set_visible( event->world, event->entity_list, waiter->unlocked ); + _ent_list_set_visible( event->entity_list, waiter->unlocked ); waiter->changed = 0; } } diff --git a/src/scripts/heaven.c b/src/scripts/heaven.c index 150dca9..d811769 100644 --- a/src/scripts/heaven.c +++ b/src/scripts/heaven.c @@ -1,3 +1,4 @@ +#if 0 static bool _skaterift_script_intro( ent_script_event *event ) { static const cs_subtitle EN[] = { @@ -24,82 +25,6 @@ static bool _skaterift_script_intro( ent_script_event *event ) if( viewed ) gate->flags &= ~((u32)k_ent_gate_locked); else gate->flags |= (u32)k_ent_gate_locked; } - - return 1; -} - -static void _skaterift_script_gino_send( ent_script_event *event, i32 which ) -{ - i32 count = 0; - for( u32 i=0; ientity_list->entity_ref_count; i ++ ) - { - u32 ref_index = event->entity_list->entity_ref_start + i; - file_entity_ref *ref = af_arritm( &event->world->file_entity_ref, ref_index ); - u32 type = mdl_entity_id_type( ref->entity_id ), - index = mdl_entity_id_id( ref->entity_id ); - - if( type == k_ent_marker ) - { - if( count == which ) - { - ent_marker *marker = af_arritm( &event->world->ent_marker, index ); - _npc_gino_goto( marker->transform.co, which+1 ); - break; - } - - count ++; - } - } -} - -static bool _skaterift_script_gino_intro( ent_script_event *event ) -{ - static const cs_subtitle EN0[] = - { - { "a1", KCOL_JESUS "Hello, I'm Gino!" }, - { "a2", KCOL_JESUS "Do you remember who you are?" }, - { "a3", KCOL_JESUS "Pick here." }, - { NULL, NULL }, - }, - EN1[] = - { - { "a1", KCOL_JESUS "Welcome to almost Heaven.." }, - { "a2", KCOL_JESUS "For some reason the entrance is blocked" }, - { "a3", KCOL_JESUS "You'll have to go back home for now" }, - { "a4", KCOL_JESUS "There are people waiting for you after all." }, - { NULL, NULL }, - }, - EN2[] = - { - { "a1", KCOL_JESUS "Might want to pick up one of these" }, - { "a2", KCOL_JESUS "See you at the center Island." }, - { NULL, NULL }, - }; - - if( event->type == k_escript_event_world_start ) - { - _npc_gino_speech( EN0 ); - _skaterift_script_gino_send( event, 0 ); - return 1; - } - - if( on_function_trigger( event, 0 ) ) - { - _npc_gino_speech( EN0 ); - _skaterift_script_gino_send( event, 0 ); - } - - if( on_function_trigger( event, 1 ) ) - { - _npc_gino_speech( EN1 ); - _skaterift_script_gino_send( event, 1 ); - } - - if( on_function_trigger( event, 2 ) ) - { - _npc_gino_speech( EN2 ); - _skaterift_script_gino_send( event, 2 ); - } - return 1; } +#endif diff --git a/src/scripts/hub.c b/src/scripts/hub.c index 24afdff..9c58b20 100644 --- a/src/scripts/hub.c +++ b/src/scripts/hub.c @@ -1,13 +1,62 @@ +struct script_hub +{ + ent_list *break_list; +}; + static bool _skaterift_script_hub( ent_script_event *event ) { + if( event->type == k_escript_event_allocate ) + { + struct script_event_allocate *event_info = event->info; + struct script_hub *script_hub = vg_linear_alloc( event_info->heap, sizeof(struct script_hub) ); + script_hub->break_list = NULL; + event_info->userdata = script_hub; + return 1; + } + + struct script_hub *script_hub = event->userdata; + + /* small text box pop up, the welcome thing. */ if( on_function_trigger( event, 0 ) ) { if( on_nugget_once( event, "hub_info_view" ) ) - { menu_open( k_menu_page_impromptu_guide ); + } + + struct + { + const char *ms, *nugget, *view_nugget, *list; + } + blocks[] = + { + { "metascenes/unlock_mtzero.ms", "unlock_mtzero", "unlock_mtzero_view", "mtzero:locked" }, + { "metascenes/unlock_city.ms", "unlock_city", "unlock_city_view", "city:locked" }, + { "metascenes/unlock_valley.ms", "unlock_valley", "unlock_valley_view", "valley:locked" }, + }; + + for( u32 i=0; ibreak_list = list; + } + else + _ent_list_set_visible( list, 0 ); + } } } - else if( event->type == k_escript_event_nugget_changed ) + + if( on_cutscene_marker( event, "$break" ) ) + _explode_template_boom( script_hub->break_list ); + + if( event->type == k_escript_event_nugget_changed ) { world_instance *world = &_world.main; @@ -34,24 +83,6 @@ static bool _skaterift_script_hub( ent_script_event *event ) if( AF_STR_EQ( &world->meta.af, prop->pstr_alias, "BERNADETTA" ) ) if( skaterift.achievements & 0x8 ) prop->flags &= ~0x1; - -#if 0 - if( AF_STR_EQ( &world->meta.af, prop->pstr_alias, "main_island_block" ) ) - if( unlock_mtzero ) - prop->flags |= k_prop_flag_hidden; - - if( AF_STR_EQ( &world->meta.af, prop->pstr_alias, "mtzero_block" ) ) - if( unlock_mtzero ) - prop->flags |= k_prop_flag_hidden; - - if( AF_STR_EQ( &world->meta.af, prop->pstr_alias, "city_block" ) ) - if( unlock_city ) - prop->flags |= k_prop_flag_hidden; - - if( AF_STR_EQ( &world->meta.af, prop->pstr_alias, "valley_block" ) ) - if( unlock_valley ) - prop->flags |= k_prop_flag_hidden; -#endif } u32 spawns_allowed = 0; @@ -77,141 +108,3 @@ static bool _skaterift_script_hub( ent_script_event *event ) return 0; } - -static void _hub_blocker_template( ent_script_event *event, const char *unlock, const char *guard ) -{ - u64 status; - if( on_nugget_changed( event, unlock, &status ) ) - { - if( status ) - { - if( on_nugget_once( event, guard ) ) - { - play_generic_cutscene( event ); - } - else - { - ent_list_set_visible( event->world, event->entity_list, 0 ); - } - } - } - - if( on_cutscene_marker( event, "$break" ) ) - { - _explode_template_boom( event ); - } - -} - -static bool _skaterift_script_unlock_mtzero( ent_script_event *event ) -{ - static const struct generic_cutscene cutscene = - { - .metascene_path = "metascenes/unlock_mtzero.ms", - .freeze_player = 1, - }; - generic_cutscene_wrapper( &cutscene, event ); - _hub_blocker_template( event, "unlock_mtzero", "unlock_mtzero_view" ); - return 1; -} - -static bool _skaterift_script_unlock_city( ent_script_event *event ) -{ - static const struct generic_cutscene cutscene = - { - .metascene_path = "metascenes/unlock_city.ms", - .freeze_player = 1, - }; - generic_cutscene_wrapper( &cutscene, event ); - _hub_blocker_template( event, "unlock_city", "unlock_city_view" ); - return 1; -} - -static bool _skaterift_script_unlock_valley( ent_script_event *event ) -{ - static const struct generic_cutscene cutscene = - { - .metascene_path = "metascenes/unlock_valley.ms", - .freeze_player = 1, - }; - generic_cutscene_wrapper( &cutscene, event ); - _hub_blocker_template( event, "unlock_valley", "unlock_valley_view" ); - return 1; -} - -static bool _skaterift_script_gino_hub( ent_script_event *event ) -{ - if( on_function_trigger( event, 0 ) ) - { - if( _skaterift_script_nugget_status( "unlock_mtzero" ) ) - { - static const cs_subtitle EN[] = - { - { "a1", KCOL_JESUS "It's clear now" }, - { NULL, NULL }, - }; - _npc_gino_speech( EN ); - _skaterift_script_gino_send( event, 0 ); - } - else - { - static const cs_subtitle EN[] = - { - { "a1", KCOL_JESUS "Someone put boxes here.." }, - { "a2", KCOL_JESUS "Stuff to do at the volcano.." }, - { NULL, NULL }, - }; - - _npc_gino_speech( EN ); - _skaterift_script_gino_send( event, 0 ); - } - } - - if( on_function_trigger( event, 1 ) ) - { - if( _skaterift_script_nugget_status( "unlock_city" ) ) - { - static const cs_subtitle EN[] = - { - { "a1", KCOL_JESUS "Cool" }, - { NULL, NULL }, - }; - _npc_gino_speech( EN ); - _skaterift_script_gino_send( event, 1 ); - } - else - { - static const cs_subtitle EN[] = - { - { "a1", KCOL_JESUS "Again with the boxes!" }, - { "a2", KCOL_JESUS "Who is doing that?" }, - { NULL, NULL }, - }; - - _npc_gino_speech( EN ); - _skaterift_script_gino_send( event, 1 ); - } - } - - if( on_function_trigger( event, 2 ) ) - { - if( _skaterift_script_nugget_status( "unlock_valley" ) ) - { - _npc_gino_speech( NULL ); - _skaterift_script_gino_send( event, 2 ); - } - else - { - static const cs_subtitle EN[] = - { - { "a1", KCOL_JESUS "..." }, - { "a2", KCOL_JESUS "You know what to do..." }, - { NULL, NULL }, - }; - - _npc_gino_speech( EN ); - _skaterift_script_gino_send( event, 2 ); - } - } - return 1; -} diff --git a/src/scripts/mtzero.c b/src/scripts/mtzero.c index 21ea897..06208ea 100644 --- a/src/scripts/mtzero.c +++ b/src/scripts/mtzero.c @@ -1,5 +1,6 @@ static bool _skaterift_script_ch2s1( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { "j1", KCOL_JOHN "Eughhh boy" }, @@ -29,12 +30,13 @@ static bool _skaterift_script_ch2s1( ent_script_event *event ) { play_generic_cutscene( event ); } - +#endif return 1; } static bool _skaterift_script_ch2s2( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { "m1", KCOL_MIKE "Haha!" }, @@ -61,11 +63,13 @@ static bool _skaterift_script_ch2s2( ent_script_event *event ) .subtitles = EN, }; optional_video_wrapper( &cutscene, "ch2s2_view", 0, event ); +#endif return 1; } static bool _skaterift_script_first_mtzero( ent_script_event *event ) { +#if 0 if( on_function_trigger( event, 6 ) ) { u64 status = _skaterift_script_nugget_status( "ch2s3_view" ); @@ -74,12 +78,13 @@ static bool _skaterift_script_first_mtzero( ent_script_event *event ) _skaterift_script_nugget_set( "ch2s3_view", 2 ); } } - +#endif return 1; } static bool _skaterift_script_ch2s3( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { "m1", KCOL_MIKE "Holy! You actually bothered to do these?" }, @@ -171,12 +176,13 @@ static bool _skaterift_script_ch2s3( ent_script_event *event ) optional_video_wrapper( &cutscene, "ch2s3_view", 2, event ); /* TODO: Unlocking the blocker thing here, for the final challenge */ - +#endif return 1; } static bool _skaterift_script_ch2s4( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { "j1", KCOL_JOHN "Oh my god.." }, @@ -202,11 +208,13 @@ static bool _skaterift_script_ch2s4( ent_script_event *event ) .subtitles = EN, }; optional_video_wrapper( &cutscene, "ch2s4_view", 2, event ); +#endif return 1; } static bool _skaterift_script_ch2s5_before( ent_script_event *event ) { +#if 0 u64 status; if( on_nugget_changed( event, "ch2s5_view", &status ) ) { @@ -223,12 +231,13 @@ static bool _skaterift_script_ch2s5_before( ent_script_event *event ) _skaterift_script_nugget_set( "ch2s5_view", 3 ); skaterift_load_world_command( 1, (const char *[]){ "reload" } ); } - +#endif return 1; } static bool _skaterift_script_ch2s5_after( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { "m1", KCOL_MIKE "Hi mate, hows it goin?" }, @@ -261,12 +270,13 @@ static bool _skaterift_script_ch2s5_after( ent_script_event *event ) play_generic_cutscene( event ); } } - +#endif return 1; } static bool _skaterift_script_ch2s6( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { "j1", KCOL_JOHN "Ello guys" }, @@ -300,11 +310,13 @@ static bool _skaterift_script_ch2s6( ent_script_event *event ) _skaterift_script_nugget_set( "unlock_city", 1 ); skaterift_load_world_command( 1, (const char *[]){ "sr002-local-mp_spawn" } ); } +#endif return 1; } static bool _skaterift_script_ch2e1( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { "j1", KCOL_JOHN "Hey bird I'm just working on some boards here." }, @@ -324,12 +336,13 @@ static bool _skaterift_script_ch2e1( ent_script_event *event ) if( cs_event == k_generic_cutscene_event_start ) _skaterift_script_nugget_set( "board_maker_unlock", 1 ); - +#endif return 1; } static bool _skaterift_script_battery_jump( ent_script_event *event ) { +#if 0 static const struct cs_subtitle EN[] = { { NULL, NULL }, }; @@ -359,6 +372,6 @@ static bool _skaterift_script_battery_jump( ent_script_event *event ) if( status == 1 ) ent_list_set_visible( event->world, event->entity_list, 0 ); } - +#endif return 1; } diff --git a/src/scripts/tutorial_island.c b/src/scripts/tutorial_island.c index c0b9bcb..91bbdca 100644 --- a/src/scripts/tutorial_island.c +++ b/src/scripts/tutorial_island.c @@ -1,53 +1,75 @@ -static bool _skaterift_script_tutorial_island( ent_script_event *event ) +struct script_volcano { - static const struct cs_subtitle EN[] = { - { "john_1", KCOL_JOHN "Well, here we are. Home." }, - { "john_2", KCOL_JOHN "I mean, halfway home." }, - { "john_3", KCOL_JOHN "Obviously you've forgotten quite a bit, so we'll stop off here" }, - { "john_4", KCOL_JOHN "and I'll teach you some stuff again" }, - { NULL, NULL }, - }; - static const struct generic_cutscene cutscene = - { - .metascene_path = "metascenes/ch1s2.ms", - .freeze_player = 1, - .subtitles = EN, - }; - generic_cutscene_wrapper( &cutscene, event ); + ent_list *break_list; + bool docks_wait; + f32 stopped_timer; +}; - if( on_nugget_once( event, "ch1s2_view" ) ) +static bool _skaterift_script_tutorial_island( ent_script_event *event ) +{ + if( event->type == k_escript_event_allocate ) { - play_generic_cutscene( event ); + struct script_event_allocate *event_info = event->info; + struct script_volcano *script_volcano = vg_linear_alloc( event_info->heap, sizeof(struct script_volcano) ); + script_volcano->break_list = NULL; + script_volcano->docks_wait = 0; + script_volcano->stopped_timer = 0.0f; + event_info->userdata = script_volcano; + return 1; } - return 1; -} + struct script_volcano *script_volcano = event->userdata; -static bool _skaterift_script_unlock_docks( ent_script_event *event ) -{ - static const struct generic_cutscene cutscene = + if( on_cutscene_marker( event, "$break" ) ) + _explode_template_boom( script_volcano->break_list ); + + /* intro movie */ + if( on_nugget_once( event, "ch1s2_view" ) ) { - .metascene_path = "metascenes/unlock_docks.ms", - .freeze_player = 1, - }; - generic_cutscene_wrapper( &cutscene, event ); + static const struct cs_subtitle EN[] = { + { "john_1", KCOL_JOHN "Well, here we are. Home." }, + { "john_2", KCOL_JOHN "I mean, halfway home." }, + { "john_3", KCOL_JOHN "Obviously you've forgotten quite a bit, so we'll stop off here" }, + { "john_4", KCOL_JOHN "and I'll teach you some stuff again" }, + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch1s2.ms", EN, 1 ); + } + /* all tasks completed (called from the region entity) */ if( on_function_trigger( event, 2 ) ) { - _skaterift_script_nugget_set( "ch1s6a_view", 2 ); + ent_list *list = _ent_list_get_aliased( "docks:locked" ); if( on_nugget_once( event, "unlock_docks_view" ) ) { - play_generic_cutscene( event ); + vg_low( "waiting for stopped...\n" ); + _skaterift_script_nugget_set( "ch1s6a_view", 2 ); + script_volcano->docks_wait = 1; } else - { - ent_list_set_visible( event->world, event->entity_list, 0 ); - } + _ent_list_set_visible( list, 0 ); } - if( on_cutscene_marker( event, "$break" ) ) + if( event->type == k_escript_event_update ) { - _explode_template_boom( event ); + if( script_volcano->docks_wait ) + { + if( localplayer.subsystem == k_player_subsystem_walk ) + { + if( v3_length2( localplayer.rb.v ) < 1.0f ) + { + script_volcano->stopped_timer += vg.time_frame_delta; + if( script_volcano->stopped_timer > 3.0f ) + { + script_volcano->docks_wait = 0; + _cutscene_load_and_play( "metascenes/unlock_docks.ms", NULL, 1 ); + script_volcano->break_list = _ent_list_get_aliased( "docks:locked" ); + } + } + else + script_volcano->stopped_timer = 0.0f; + } + } } return 1; @@ -55,182 +77,172 @@ static bool _skaterift_script_unlock_docks( ent_script_event *event ) static bool _skaterift_script_ch1s3( ent_script_event *event ) { - static const struct cs_subtitle EN[] = { - { "john_1", KCOL_JOHN "Alright so, fliptricks." }, - { "john_2", KCOL_JOHN "We spent ages practicing these before" }, - { "john_3", KCOL_JOHN "Shouldn't take you long to get it again" }, - { "john_4", KCOL_JOHN "see if you can get a tre-flip down there" }, - { NULL, NULL }, - }; - static const struct generic_cutscene cutscene = + if( on_function_trigger( event, 1 ) ) { - .metascene_path = "metascenes/ch1s3.ms", - .freeze_player = 1, - .subtitles = EN, - }; - challenge_video_wrapper( &cutscene, "ch1s3_view", event ); - return 1; -} + if( on_nugget_once( event, "ch1s3_view" ) ) + { + static const struct cs_subtitle EN[] = { + { "john_1", KCOL_JOHN "Alright so, fliptricks." }, + { "john_2", KCOL_JOHN "We spent ages practicing these before" }, + { "john_3", KCOL_JOHN "Shouldn't take you long to get it again" }, + { "john_4", KCOL_JOHN "see if you can get a tre-flip down there" }, + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch1s3.ms", EN, 1 ); + } + } -static bool _skaterift_script_ch1s3b( ent_script_event *event ) -{ - static const struct cs_subtitle EN[] = { - { "john_1", KCOL_JOHN "That is it mate!" }, - { "john_2", KCOL_JOHN "You have still got it!" }, - { NULL, NULL }, - }; - static const struct generic_cutscene cutscene = + if( on_function_trigger( event, 2 ) ) { - .metascene_path = "metascenes/ch1s3b.ms", - .freeze_player = 0, - .subtitles = EN, - }; - challenge_video_wrapper( &cutscene, "ch1s3b_view", event ); + if( on_nugget_once( event, "ch1s3b_view" ) ) + { + static const struct cs_subtitle EN[] = { + { "john_1", KCOL_JOHN "That is it mate!" }, + { "john_2", KCOL_JOHN "You have still got it!" }, + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch1s3b.ms", EN, 1 ); + } + } u64 viewed; if( on_nugget_changed( event, "ch1s3b_view", &viewed ) ) - ent_list_set_visible( event->world, event->entity_list, !viewed ); + _ent_list_set_visible( event->entity_list, !viewed ); return 1; } static bool _skaterift_script_ch1s4( ent_script_event *event ) { - static const struct cs_subtitle EN[] = { - { "john_1", KCOL_JOHN "Remember these courses we were setting up?" }, - { "john_2", KCOL_JOHN "Nah?" }, - { "john_3", KCOL_JOHN "Alright well uh, to jog your memory.." }, - { "john_4", KCOL_JOHN "Get yourself down through the gates as quick as possible" }, - { "john_5", KCOL_JOHN "Thats it." }, - { "john_6", KCOL_JOHN "Give it a shot mate" }, - { NULL, NULL }, - }; - static const struct generic_cutscene cutscene = + if( on_function_trigger( event, 0 ) ) { - .metascene_path = "metascenes/ch1s4.ms", - .freeze_player = 1, - .subtitles = EN, - }; - optional_video_wrapper( &cutscene, "ch1s4_view", 0, event ); + if( on_nugget_once( event, "ch1s4_view" ) ) + { + static const struct cs_subtitle EN[] = { + { "john_1", KCOL_JOHN "Remember these courses we were setting up?" }, + { "john_2", KCOL_JOHN "Nah?" }, + { "john_3", KCOL_JOHN "Alright well uh, to jog your memory.." }, + { "john_4", KCOL_JOHN "Get yourself down through the gates as quick as possible" }, + { "john_5", KCOL_JOHN "Thats it." }, + { "john_6", KCOL_JOHN "Give it a shot mate" }, + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch1s4.ms", EN, 1 ); + } + } + + u64 status; + if( on_nugget_changed( event, "ch1s4_view", &status ) ) + _ent_list_set_visible( event->entity_list, status == 0 ); + return 1; } static bool _skaterift_script_ch1s5( ent_script_event *event ) { - static const struct cs_subtitle EN[] = { - -/* 50ch| set cc=70 |################################################| */ -{ "j1", KCOL_JOHN "Alright, well then" }, -{ "j2", KCOL_JOHN "You're gonna need to play close attention to\n" - "this part" }, - -{ "j3", KCOL_JOHN "because its difficult.." }, -{ "j4", KCOL_JOHN "It's gonna take some practice until it clicks" }, -{ "j5", KCOL_JOHN "Right as you like, go across the transition \n" - "of the ramp," }, - -{ "j6", KCOL_JOHN "Right here," }, -{ "j7", KCOL_JOHN "you need to pump to gain some momentum." }, -{ "j8", KCOL_JOHN "What I mean right, watch" }, -{ "j9", KCOL_JOHN "just as I'm going into the base of the ramp" }, -{ "j10",KCOL_JOHN "I'm storing up some energy here by crouching down" }, -{ "j11",KCOL_JOHN "Right as I go across this point" }, -{ "j12",KCOL_JOHN "I'm almost jumping back up, adding some uwpwards\n" - "momentum" }, - -{ "j13",KCOL_JOHN "Then as the board comes up to this angle.." }, -{ "j14",KCOL_JOHN "that upwards momentum is transferred \n" - "into my speed" }, - -{ "j15",KCOL_JOHN "Same principle works, same way in the \n" - "other direction" }, - -{ "j16",KCOL_JOHN "Now, like I'm saying" }, -{ "j17",KCOL_JOHN "this might take you a little bit until it clicks" }, - -{ "j18",KCOL_JOHN "But once it does you'll feel it. You'll know!" }, - -{ "j19",KCOL_JOHN "And I uhh, set a target for you" }, -{ "j20",KCOL_JOHN "right up there.." }, -{ "j21",KCOL_JOHN "Thats how we'll know you're back on form." }, - -{ "j22",KCOL_JOHN "Come see me at the docks once you've got it." }, - -{ NULL, NULL }, - }; - - static const struct generic_cutscene cutscene = + if( on_function_trigger( event, 0 ) ) { - .metascene_path = "metascenes/ch1s5.ms", - .freeze_player = 1, - .subtitles = EN, - }; - challenge_video_wrapper( &cutscene, "ch1s5_view", event ); + if( on_nugget_once( event, "ch1s5_view" ) ) + { + static const struct cs_subtitle EN[] = { + /* 50ch| set cc=70 |################################################| */ + { "j1", KCOL_JOHN "Alright, well then" }, + { "j2", KCOL_JOHN "You're gonna need to play close attention to\n" + "this part" }, + + { "j3", KCOL_JOHN "because its difficult.." }, + { "j4", KCOL_JOHN "It's gonna take some practice until it clicks" }, + { "j5", KCOL_JOHN "Right as you like, go across the transition \n" + "of the ramp," }, + + { "j6", KCOL_JOHN "Right here," }, + { "j7", KCOL_JOHN "you need to pump to gain some momentum." }, + { "j8", KCOL_JOHN "What I mean right, watch" }, + { "j9", KCOL_JOHN "just as I'm going into the base of the ramp" }, + { "j10",KCOL_JOHN "I'm storing up some energy here by crouching down" }, + { "j11",KCOL_JOHN "Right as I go across this point" }, + { "j12",KCOL_JOHN "I'm almost jumping back up, adding some uwpwards\n" + "momentum" }, + + { "j13",KCOL_JOHN "Then as the board comes up to this angle.." }, + { "j14",KCOL_JOHN "that upwards momentum is transferred \n" + "into my speed" }, + + { "j15",KCOL_JOHN "Same principle works, same way in the \n" + "other direction" }, + + { "j16",KCOL_JOHN "Now, like I'm saying" }, + { "j17",KCOL_JOHN "this might take you a little bit until it clicks" }, + + { "j18",KCOL_JOHN "But once it does you'll feel it. You'll know!" }, + + { "j19",KCOL_JOHN "And I uhh, set a target for you" }, + { "j20",KCOL_JOHN "right up there.." }, + { "j21",KCOL_JOHN "Thats how we'll know you're back on form." }, + + { "j22",KCOL_JOHN "Come see me at the docks once you've got it." }, + + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch1s5.ms", EN, 1 ); + } + } return 1; } -static bool _skaterift_script_ch1s6a( ent_script_event *event ) +struct script_ch1s6a_waiter { - static const struct cs_subtitle EN[] = { - { "j1", KCOL_JOHN "Eyyy! Looks like you're ready again.." }, - { "j2", KCOL_JOHN "Didn't take long" }, - { "j3", KCOL_JOHN "Just a short ferry ride back over to Mt.Zero now." }, - { "j4", KCOL_JOHN "Oh right, Mt.Zero.. You really don't remember anything do you?" }, - { "j5", KCOL_JOHN "Its where we live." }, - { "j7", KCOL_JOHN "Yknow it's where the woodshop is," }, - { "j8", KCOL_JOHN "It's where we skate, where Mike is," }, - { "j9", KCOL_JOHN "yknow, its our home!" }, - - { NULL, NULL }, - }; - static const struct generic_cutscene cutscene = - { - .metascene_path = "metascenes/ch1s6a.ms", - .freeze_player = 1, - .subtitles = EN, - }; - enum generic_cutscene_event cs_event = optional_video_wrapper( &cutscene, "ch1s6a_view", 2, event ); + bool go; +}; - if( cs_event == k_generic_cutscene_event_start ) - { - _skaterift_script_nugget_set( "unlock_mtzero", 1 ); - } - - if( cs_event == k_generic_cutscene_event_end ) +static bool _skaterift_script_ch1s6a( ent_script_event *event ) +{ + if( event->type == k_escript_event_allocate ) { - skaterift_load_world_command( 1, (const char *[]){ "sr002-local-dev_hub" } ); + struct script_event_allocate *event_info = event->info; + struct script_ch1s6a_waiter *waiter = vg_linear_alloc( event_info->heap, sizeof(struct script_ch1s6a_waiter) ); + waiter->go = 0; + event_info->userdata = waiter; + return 1; } - return 1; -} + struct script_ch1s6a_waiter *waiter = event->userdata; + u64 status; + if( on_nugget_changed( event, "ch1s6a_view", &status ) ) + _ent_list_set_visible( event->entity_list, status == 2 ); -static bool _skaterift_script_gino_volc( ent_script_event *event ) -{ if( on_function_trigger( event, 0 ) ) { - if( _skaterift_script_nugget_status( "unlock_docks_view" ) ) + if( on_nugget_once( event, "ch1s6a_view" ) ) { - static const cs_subtitle EN[] = - { - { "a1", KCOL_JESUS "Off to mt.zero at last!" }, - { NULL, NULL }, + _skaterift_script_nugget_set( "unlock_mtzero", 1 ); + + static const struct cs_subtitle EN[] = { + { "j1", KCOL_JOHN "Eyyy! Looks like you're ready again.." }, + { "j2", KCOL_JOHN "Didn't take long" }, + { "j3", KCOL_JOHN "Just a short ferry ride back over to Mt.Zero now." }, + { "j4", KCOL_JOHN "Oh right, Mt.Zero.. You really don't remember anything do you?" }, + { "j5", KCOL_JOHN "Its where we live." }, + { "j7", KCOL_JOHN "Yknow it's where the woodshop is," }, + { "j8", KCOL_JOHN "It's where we skate, where Mike is," }, + { "j9", KCOL_JOHN "yknow, its our home!" }, + + { NULL, NULL }, }; - _npc_gino_speech( EN ); - _skaterift_script_gino_send( event, 0 ); + _cutscene_load_and_play( "metascenes/ch1s6a.ms", EN, 1 ); + waiter->go = 1; } - else + } + + if( event->type == k_escript_event_update ) + { + if( waiter->go ) { - static const cs_subtitle EN[] = + if( _cutscene.state == k_cutscene_state_none ) { - { "a1", KCOL_JESUS "This leads down to the docks" }, - { "a2", KCOL_JESUS "JC won't let us leave until we did his tasks" }, - { NULL, NULL }, - }; - - _npc_gino_speech( EN ); - _skaterift_script_gino_send( event, 0 ); + skaterift_load_world_command( 1, (const char *[]){ "sr002-local-dev_hub" } ); + } } } - return 1; } diff --git a/src/skaterift.c b/src/skaterift.c index 884e23f..b78e323 100644 --- a/src/skaterift.c +++ b/src/skaterift.c @@ -57,7 +57,8 @@ #include "replay2.h" #include "user_profile.h" #include "ent_route.h" -#include "npc_gino.h" +#include "ent_npc.h" +#include "ent_list.h" struct skaterift_globals skaterift = { @@ -129,7 +130,7 @@ static void game_load_co( vg_coroutine *co ) vg_loader_step( ent_tornado_init, NULL ); vg_loader_step( skaterift_load_player_content, NULL ); vg_loader_step( _replay2_init, NULL ); - vg_loader_step( _npc_gino_init, NULL ); + vg_loader_step( _ent_npc_init, NULL ); vg_loader_set_user_information( "Compiling shaders" ); vg_bake_shaders(); @@ -658,7 +659,8 @@ void vg_framebuffer_resize( int w, int h ) #include "compass.c" #include "replay2.c" #include "user_profile.c" -#include "npc_gino.c" +#include "ent_npc.c" +#include "ent_list.c" //TODO //#include "vg/submodules/hashmap.c/hashmap.c" diff --git a/src/skaterift_script.c b/src/skaterift_script.c index 8cc804a..5c37ec5 100644 --- a/src/skaterift_script.c +++ b/src/skaterift_script.c @@ -435,68 +435,7 @@ static bool _skaterift_script_test( enum escript_event ev, const char *inf ) extern m4x3f *_TEMP_VAR; -static bool _skaterift_script_bind_player(void) -{ - _cutscene.player_binding = _cutscene_get_first_model_instance( "models/ch_none" ); - - if( !_cutscene.player_binding ) - { - vg_error( "Failed to find models/ch_none in scene!" ); - return 0; - } - - _cutscene.player_binding->disable_render = 1; - return 1; -} - -static void ent_list_set_visible( world_instance *world, ent_list *list, bool visible ) -{ - for( u32 i=0; ientity_ref_count; i ++ ) - { - u32 ref_index = list->entity_ref_start + i; - - file_entity_ref *ref = af_arritm( &world->file_entity_ref, ref_index ); - - u32 type = mdl_entity_id_type( ref->entity_id ), - index = mdl_entity_id_id( ref->entity_id ); - - if( type == k_ent_objective ) - { - ent_objective *objective = af_arritm( &world->ent_objective, index ); - - if( visible ) objective->flags &= ~((u32)k_ent_objective_hidden); - else objective->flags |= k_ent_objective_hidden; - } - else if( type == k_ent_prop ) - { - ent_prop *prop = af_arritm( &world->ent_prop, index ); - - if( visible ) prop->flags &= ~((u32)k_prop_flag_hidden); - else prop->flags |= k_prop_flag_hidden; - } - else if( type == k_ent_challenge ) - { - ent_challenge *challenge = af_arritm( &world->ent_challenge, index ); - - if( visible ) challenge->flags &= ~((u32)k_ent_challenge_locked); - else challenge->flags |= (u32)k_ent_challenge_locked; - } - else if( type == k_ent_volume ) - { - ent_volume *volume = af_arritm( &world->ent_volume, index ); - - if( visible ) volume->flags &= ~((u32)k_ent_volume_flag_disabled); - else volume->flags |= (u32)k_ent_volume_flag_disabled; - } - else if( type == k_ent_marker ) - { - ent_marker *marker = af_arritm( &world->ent_marker, index ); - if( visible ) marker->flags &= ~((u32)k_ent_marker_flag_hidden); - else marker->flags |= (u32)k_ent_marker_flag_hidden; - } - } -} - +#if 0 enum generic_cutscene_event generic_cutscene_wrapper( const struct generic_cutscene *cutscene_template, ent_script_event *event ) { @@ -522,9 +461,6 @@ enum generic_cutscene_event generic_cutscene_wrapper( const struct generic_cutsc { generic->state = k_generic_cutscene_state_init; vg_info( "generic_cutscene:state = initializing\n" ); - - if( generic->freeze_player ) - localplayer.immobile = 1; } } @@ -563,8 +499,6 @@ enum generic_cutscene_event generic_cutscene_wrapper( const struct generic_cutsc vg_info( "generic_template:state = end\n" ); _cutscene_unload(); - if( generic->freeze_player ) - localplayer.immobile = 0; return k_generic_cutscene_event_end; } @@ -582,22 +516,15 @@ void play_generic_cutscene( ent_script_event *event ) struct generic_cutscene *generic = event->userdata; generic->state = k_generic_cutscene_state_wake; } +#endif bool on_cutscene_marker( ent_script_event *event, const char *marker ) { if( event->type != k_escript_event_allocate ) - { - struct generic_cutscene *generic = event->userdata; - - if( generic->state == k_generic_cutscene_state_playing ) - { + if( _cutscene.state == k_cutscene_state_playing ) if( _cutscene.marker_this_frame ) - { if( vg_str_eq( marker, _cutscene.marker_this_frame ) ) return 1; - } - } - } return 0; } @@ -650,6 +577,7 @@ bool on_nugget_once( ent_script_event *event, const char *nugget_alias ) return 0; } +#if 0 enum generic_cutscene_event optional_video_wrapper( const struct generic_cutscene *cutscene_template, const char *nugget_alias, u64 nugget_visible_value, @@ -690,6 +618,7 @@ enum generic_cutscene_event challenge_video_wrapper( const struct generic_cutsce return cs_event; } +#endif #include "scripts/generic.c" #include "scripts/blocker_break.c" @@ -709,21 +638,15 @@ struct ent_script_table_entry _ent_script_table[] = { "board_maker_unlock", _skaterift_script_board_maker_unlock }, { "board_maker", _skaterift_script_board_maker }, - { "intro", _skaterift_script_intro }, - { "gino.intro", _skaterift_script_gino_intro }, - { "gino.hub", _skaterift_script_gino_hub }, - { "gino.volc", _skaterift_script_gino_volc }, + //{ "intro", _skaterift_script_intro }, { "hub", _skaterift_script_hub }, { "tutorial_island", _skaterift_script_tutorial_island }, { "ch1s3", _skaterift_script_ch1s3 }, - { "ch1s3b", _skaterift_script_ch1s3b }, { "ch1s4", _skaterift_script_ch1s4 }, { "ch1s5", _skaterift_script_ch1s5 }, { "ch1s6a", _skaterift_script_ch1s6a }, - { "unlock_docks", _skaterift_script_unlock_docks }, - { "unlock_mtzero", _skaterift_script_unlock_mtzero }, { "ch2s1", _skaterift_script_ch2s1 }, { "ch2s2", _skaterift_script_ch2s2 }, { "first_mtzero", _skaterift_script_first_mtzero }, @@ -735,17 +658,13 @@ struct ent_script_table_entry _ent_script_table[] = { "ch2s6", _skaterift_script_ch2s6 }, { "ch2e1", _skaterift_script_ch2e1 }, - { "unlock_city", _skaterift_script_unlock_city }, { "ch3s1", _skaterift_script_ch3s1 }, { "ch3s2", _skaterift_script_ch3s2 }, { "ch3s3", _skaterift_script_ch3s3 }, - { "unlock_valley", _skaterift_script_unlock_valley }, - { NULL } }; - /* -------------------------------------------------------------------------------------------------------------------- * save data */ diff --git a/src/skaterift_script.h b/src/skaterift_script.h index 5d1d7fd..8cbad90 100644 --- a/src/skaterift_script.h +++ b/src/skaterift_script.h @@ -8,6 +8,7 @@ void _skaterift_script_load_savedata( vg_msg *sav ); u64 _skaterift_script_nugget_status( const char *nugget_alias ); void _skaterift_script_nugget_set( const char *nugget_alias, u64 value ); +#if 0 struct generic_cutscene { enum generic_cutscene_state @@ -35,3 +36,4 @@ enum generic_cutscene_event enum generic_cutscene_event generic_cutscene_wrapper( const struct generic_cutscene *cutscene_template, ent_script_event *event ); void play_generic_cutscene( ent_script_event *event ); +#endif diff --git a/src/world.c b/src/world.c index ba492ae..c94fd56 100644 --- a/src/world.c +++ b/src/world.c @@ -40,7 +40,7 @@ void world_update( world_instance *world, v3f pos ) { ent_script_update( world ); ent_route_preupdate(); - _npc_gino_preupdate(); + _ent_npc_preupdate(); world_routes_update_timer_texts( world ); world_routes_update( world ); ent_traffic_update( world, pos ); @@ -55,7 +55,6 @@ void world_gui( ui_context *ctx, world_instance *world ) { ent_skateshop_gui( ctx ); _ent_challenge_ui( ctx ); - _npc_gino_imgui( ctx ); } bool world_set_event( enum world_event event ) diff --git a/src/world.h b/src/world.h index 776edf9..066309d 100644 --- a/src/world.h +++ b/src/world.h @@ -177,6 +177,7 @@ struct world_instance ent_region, ent_glider, ent_list, + ent_npc, file_entity_ref, ent_script; @@ -269,7 +270,6 @@ struct world_static k_world_event_route_leaderboard, k_world_event_interact, k_world_event_board_maker, - k_world_event_gino, k_world_event_max } event; diff --git a/src/world_load.c b/src/world_load.c index d2c75b3..b25e859 100644 --- a/src/world_load.c +++ b/src/world_load.c @@ -115,6 +115,7 @@ static void world_instance_load_mdl( world_instance *world, const char *path, vo AF_LOAD_ARRAY_STRUCT( af, &world->ent_list, ent_list, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->file_entity_ref, file_entity_ref, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->ent_script, ent_script, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_npc, ent_npc, heap ); } array_file_ptr infos; @@ -486,7 +487,7 @@ void skaterift_load_world_start( addon_id addon_id, bool preview ) _world.event = k_world_event_none; player__clear_world_dependent_variables(); relink_all_remote_player_worlds(); - _npc_gino_reset(); + _ent_npc_reset(); vg_loader_set_user_information( "Saving current world" ); } else diff --git a/src/world_render.c b/src/world_render.c index 27c499e..5986151 100644 --- a/src/world_render.c +++ b/src/world_render.c @@ -1060,7 +1060,7 @@ static void render_other_entities( world_instance *world, vg_camera *cam ) } cutscene_render( world, cam ); - _npc_gino_render( cam ); + _ent_npc_render( cam ); } void render_world( world_instance *world, vg_camera *cam, diff --git a/src/world_volumes.c b/src/world_volumes.c index 160c325..6d7d859 100644 --- a/src/world_volumes.c +++ b/src/world_volumes.c @@ -160,17 +160,28 @@ next_volume:; if( _world.event == k_world_event_interact ) { - if( button_down( k_srbind_maccept ) ) + ent_volume *volume = _world_volumes.active_volume_interact; + if( volume->flags & k_ent_volume_flag_disabled ) + { + /* might get turned off by another system eg scripts */ + if( world_clear_event( k_world_event_interact ) ) + { + _world_volumes.active_volume_interact = NULL; + gui_helper_reset( k_gui_helper_mode_clear ); + } + } + else if( button_down( k_srbind_maccept ) ) { - ent_volume *volume = _world_volumes.active_volume_interact; if( volume->target ) { srinput.state = k_input_state_resume; - - if( world_clear_event( k_world_event_interact ) ) + if( !(volume->flags & k_ent_volume_flag_repeatable) ) { - _world_volumes.active_volume_interact = NULL; - gui_helper_reset( k_gui_helper_mode_clear ); + if( world_clear_event( k_world_event_interact ) ) + { + _world_volumes.active_volume_interact = NULL; + gui_helper_reset( k_gui_helper_mode_clear ); + } } ent_call call;