NPC's R us
authorhgn <hgodden00@gmail.com>
Mon, 12 May 2025 00:24:32 +0000 (01:24 +0100)
committerhgn <hgodden00@gmail.com>
Mon, 12 May 2025 00:24:32 +0000 (01:24 +0100)
29 files changed:
content_skaterift/maps/dev_hub/main.mdl
content_skaterift/maps/dev_tutorial/main.mdl
skaterift_blender/sr_main.py
skaterift_blender/sr_mdl.py
src/ent_list.c [new file with mode: 0644]
src/ent_list.h [new file with mode: 0644]
src/ent_npc.c [new file with mode: 0644]
src/ent_npc.h [new file with mode: 0644]
src/entity.c
src/entity.h
src/metascene.c
src/metascene.h
src/npc_gino.c [deleted file]
src/npc_gino.h [deleted file]
src/scripts/blocker_break.c
src/scripts/city.c
src/scripts/generic.c
src/scripts/heaven.c
src/scripts/hub.c
src/scripts/mtzero.c
src/scripts/tutorial_island.c
src/skaterift.c
src/skaterift_script.c
src/skaterift_script.h
src/world.c
src/world.h
src/world_load.c
src/world_render.c
src/world_volumes.c

index 01201377bf97b60e8727b99e0094d0d17b628fac..5dc735a54e5ab4126737aabe6542a1f369e3337d 100644 (file)
Binary files a/content_skaterift/maps/dev_hub/main.mdl and b/content_skaterift/maps/dev_hub/main.mdl differ
index 2765056846aa4afecdb2003348a2f331c94c5cb1..4aeae1ecb1f1c247d342325dcf96b7b10ddc9861 100644 (file)
Binary files a/content_skaterift/maps/dev_tutorial/main.mdl and b/content_skaterift/maps/dev_tutorial/main.mdl differ
index b95a1d83a6da6277188b46db8de13b96fda9c7e6..e6af4271d83015495b2858e9067c6bce7f21e338 100644 (file)
@@ -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))
                #}
             #}
          #}
index c65ffce80fe99d05b5f9e7d0a578c7a3e10bde84..5860d239c2ebad9bbbc10dcb8f564e761fa37a5f 100644 (file)
@@ -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 (file)
index 0000000..2dd69a8
--- /dev/null
@@ -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; i<af_arrcount( &world->ent_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 (file)
index 0000000..3ab9e74
--- /dev/null
@@ -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 (file)
index 0000000..29c9689
--- /dev/null
@@ -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; i<VG_ARRAY_LEN(_gino_contexts); i ++ )
+      _gino_contexts[i].alias_hash = vg_strdjb2( _gino_contexts[i].alias );
+
+   void *alloc = vg_mem.rtmemory;
+   mdl_context *mdl = &_npc.gino.mdl;
+   mdl_open( mdl, "models/gino.mdl", alloc );
+   mdl_load_metadata_block( mdl, alloc );
+   mdl_async_full_load_std( mdl, NULL );
+   _npc.gino.sm_main = mdl_get_submesh_index( mdl, "gino" );
+   _npc.gino.sm_hat = mdl_get_submesh_index( mdl, "gino.hat" );
+   _npc.gino.sm_glow = mdl_get_submesh_index( mdl, "gino.spt" );
+   mdl_close( mdl );
+}
+
+void _ent_npc_reset(void)
+{
+   _npc.gino.state = k_gino_none;
+   _npc.gino.spark_t = 0.0f;
+   _npc.gino.command_t = 0.0;
+   _npc.gino.current_entity_id = 0;
+}
+
+void _ent_npc_speech( enum npc npc_id, const cs_subtitle *subs )
+{
+   srinput.state = k_input_state_resume;
+   if( _npc.subtitles != subs )
+   {
+      _npc.sub_state = k_npc_sub_off;
+      _npc.sub_index = 0;
+      _npc.subtitles = subs;
+   }
+
+   if( _npc.sub_state == k_npc_sub_reading )
+      _npc.sub_index ++;
+
+   const cs_subtitle *sub = &_npc.subtitles[ _npc.sub_index ];
+
+   if( sub->key )
+   {
+      _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; i<VG_ARRAY_LEN(_gino_contexts); i ++ )
+            if( (hash == _gino_contexts[i].alias_hash) && !strcmp(_gino_contexts[i].alias,alias) )
+               _ent_npc_speech( k_npc_gino, _gino_contexts[i].subtitles );
+      }
+      /* proximity */
+      else if( call->function == 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 (file)
index 0000000..94cefd6
--- /dev/null
@@ -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 );
index ee2720a2733743421bbbf6d60da1277a94647791..7a644229228cad90b34006c5b7a72ebf41ffd64b 100644 (file)
@@ -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, 
index d91ad8923f58da6d32aae574e7e35883f3d4d6d0..b781e0d6adcad0df087f8605cb6a92fda4cf7a04 100644 (file)
@@ -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 );
index 437f42f90d601c21298df7237b55606dc2f332ee..910dc304d41575d73c709e457016fe6fb256b091 100644 (file)
@@ -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; j<af_arrcount( &_cutscene.meta.audios ); j++ )
-   {
-      ent_audio *audio = af_arritm( &_cutscene.meta.audios, j );
-      ent_audio_clip *clip = af_arritm( &_cutscene.meta.audio_clips, audio->clip_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; j<skeleton_count; j ++ )
@@ -276,20 +234,15 @@ static void cutscene_load_thread( vg_async_task *task )
       struct cs_instance *ins = &_cutscene.instances[ i ];
       struct model_ref *ref = &_cutscene.refs[ ins->ref_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; j<ref->total_skinning_bones; j ++ )
-      {
          m4x3_identity( ins->skinning_data[ j ] );
-      }
 
       /* load overrides */
       ms_instance *oins = af_arritm( &_cutscene.meta.instances, i );
       for( u32 j=0; j<oins->override_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; l<skele->sk.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; j<af_arrcount( &_cutscene.meta.audios ); j++ )
+      {
+         ent_audio *audio = af_arritm( &_cutscene.meta.audios, j );
+         ent_audio_clip *clip = af_arritm( &_cutscene.meta.audio_clips, audio->clip_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; j<strip->data_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; j<strip->data_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; 
-                        j<samp->curves.track->keyframe_count; j ++ )
+               for( u32 j=samp->curves.keyframe+1; j<samp->curves.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; k<VG_ARRAY_LEN(usage); k ++ )
          {
             if( usage[k] )
-            {
                if( usage[k]->offset + 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 );
 }
index 6988211ae7dee4a08489375d73f8ee904278bd37..7419468f5547bdbf42abb202de76450cdff0b667 100644 (file)
@@ -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 (file)
index b5d44a1..0000000
+++ /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 (file)
index 00bdfed..0000000
+++ /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);
index 37f9a116b9d850ed0a9eb6b12d0b23b44a6a467d..edb1a0650461f17bf56cdc3bb808e17874ac18fd 100644 (file)
@@ -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; i<list->entity_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;
-}
index 378b0f5cbc0c41d50cc4dc34ccc649a3a664a036..8a47073855955fd3738a2e752e28c0d0000eae60 100644 (file)
@@ -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;
 }
index 91ff46287b11b454366f90b1fe31a652d352f9d1..e9bbc90e8ea926512672b4f7df5312cacb9b5bcc 100644 (file)
@@ -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;
          }
       }
index 150dca91750ca6a027654e693915ece526cea97e..d8117690c26df61b551802c23f6adf1c5145a2d2 100644 (file)
@@ -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; i<event->entity_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
index 24afdffdecd21a66cd02ab07985a522d4a32894a..9c58b20d835446090b0136267782f2731b100de5 100644 (file)
@@ -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; i<VG_ARRAY_LEN(blocks); i ++ )
+   {
+      u64 status;
+      if( on_nugget_changed( event, blocks[i].nugget, &status ) )
+      {
+         ent_list *list = _ent_list_get_aliased( blocks[i].list );
+         if( status == 1 )
+         {
+            if( on_nugget_once( event, blocks[i].view_nugget ) )
+            {
+               _cutscene_load_and_play( blocks[i].ms, NULL, 1 );
+               script_hub->break_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;
-}
index 21ea89749f8015af389b27659f5e8fe222462cb0..06208eadda5018941716f5b6dabf617904decb4e 100644 (file)
@@ -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;
 }
index c0b9bcb824727515944bb08881fa9fe5b93b5a3a..91bbdca56ba86706bcd817c699dfe1fcc3bce6e6 100644 (file)
@@ -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;
 }
index 884e23f854950faa502c8e315c0937ab938b5f3d..b78e32302c41cb5846f1c5c5abea12d9b2024bfe 100644 (file)
@@ -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"
index 8cc804a3d6f3287ee1bf1920bd9ff0fd210e29d7..5c37ec5953933b2d86b7d1be5c05c865d9dad21f 100644 (file)
@@ -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; i<list->entity_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
  */
index 5d1d7fd6b5ea7afdce3811a6056803227d84c2d2..8cbad900c0bfa0f0e3f9507f9e43741b399a0579 100644 (file)
@@ -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
index ba492aed3b4a8c88c622ba50c129d11171608694..c94fd56ce40ddddbe845de45969406f097475034 100644 (file)
@@ -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 )
index 776edf91ffe217b9c098287de70062fac4de3957..066309d44254f4173fcb71a019e0f740eaa1cdf6 100644 (file)
@@ -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;
index d2c75b3691f9c19cae1e960c06a69277610cf538..b25e859151931046eab2b125319aecb1c0538f0b 100644 (file)
@@ -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
index 27c499e195131a5a588a7152fd10270bd818ff9d..5986151caa817ba269eb9307750e97382cc8b308 100644 (file)
@@ -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,
index 160c3252b8002cc471f19f124e25999faff4f4cc..6d7d859c8d59b33d1391498add5caab330eb4a35 100644 (file)
@@ -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;