fixing crap
authorhgn <hgodden00@gmail.com>
Mon, 12 May 2025 10:11:45 +0000 (11:11 +0100)
committerhgn <hgodden00@gmail.com>
Mon, 12 May 2025 10:11:45 +0000 (11:11 +0100)
26 files changed:
content_skaterift/maps/dev_heaven/main.mdl
content_skaterift/maps/dev_tutorial/main.mdl
content_skaterift/maps/mp_mtzero/before.mdl
content_skaterift/maps/mp_mtzero/main.mdl
content_skaterift/metascenes/skater.ms
skaterift_blender/sr_main.py
skaterift_blender/sr_mdl.py
src/ent_challenge.c
src/ent_challenge.h
src/ent_npc.c
src/ent_npc.h
src/ent_objective.c
src/ent_script.h
src/entity.h
src/menu.c
src/metascene.c
src/player_render.c
src/player_render.h
src/scripts/generic.c
src/scripts/mtzero.c
src/scripts/tutorial_island.c
src/skaterift_script.c
src/world_entity.c
src/world_map.c
src/world_render.c
src/world_routes.c

index c1e8027d4028a03d275684dcbceb5890ae1ac76b..90318def519d4934be8e98846e367d28e54fddf4 100644 (file)
Binary files a/content_skaterift/maps/dev_heaven/main.mdl and b/content_skaterift/maps/dev_heaven/main.mdl differ
index 4aeae1ecb1f1c247d342325dcf96b7b10ddc9861..0282cadecbdbcc634c3065304d11222c7df4d9a7 100644 (file)
Binary files a/content_skaterift/maps/dev_tutorial/main.mdl and b/content_skaterift/maps/dev_tutorial/main.mdl differ
index 6321574dfabf3bc7d484e6aa7c4ef59fa1a5f6d8..a7d093739877ce7778c24e58724a531be7169979 100644 (file)
Binary files a/content_skaterift/maps/mp_mtzero/before.mdl and b/content_skaterift/maps/mp_mtzero/before.mdl differ
index 567e19bffc5df2cc9cebc290b918a878d3919e2a..6aeedf0bbc65b09010b498d747e8a37ff9081966 100644 (file)
Binary files a/content_skaterift/maps/mp_mtzero/main.mdl and b/content_skaterift/maps/mp_mtzero/main.mdl differ
index c5d18d8b42ad265437cec200b09c0afef02ed7f5..fab3de868cb4b332f4f7575fb9451dff6b4fa100 100644 (file)
Binary files a/content_skaterift/metascenes/skater.ms and b/content_skaterift/metascenes/skater.ms differ
index e6af4271d83015495b2858e9067c6bce7f21e338..0aca2e13f13c602d87ad33ed5c3a6954eca316d1 100644 (file)
@@ -491,8 +491,8 @@ class ent_objective(Structure):#{
                ("flags",c_uint32),
                ("id_next",c_uint32),
                ("filter",c_uint32),("filter2",c_uint32),
-               ("id_win",c_uint32),
-               ("win_event",c_int32),
+               ("deleted0",c_uint32),
+               ("deleted1",c_int32),
                ("time_limit",c_float),
                ("pstr_description_ui",c_uint32)]
 
@@ -1994,7 +1994,7 @@ class SR_OBJECT_ENT_OBJECTIVE(bpy.types.PropertyGroup):#{
       layout.prop( data[0], 'proxima' )
       layout.prop( data[0], 'time_limit' )
       layout.prop( data[0], 'filtrar' )
-      SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target' )
+      #SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target' )
       layout.prop( data[0], 'description' )
    #}
 #}
index 5860d239c2ebad9bbbc10dcb8f564e761fa37a5f..f7383f2fe8fb83f0fc9a377ce5723a7c72f8d63f 100644 (file)
@@ -871,8 +871,8 @@ def _mdl_compiler_compile_entities():
             objective = ent_objective()
             obj_data = obj.SR_data.ent_objective[0]
             objective.id_next = sr_entity_id( obj_data.proxima )
-            objective.id_win = sr_entity_id( obj_data.target )
-            objective.win_event = obj_data.target_event
+            objective.id_win = sr_entity_id( obj_data.target )
+            objective.win_event = obj_data.target_event
             objective.filter = int(obj_data.filtrar)
             objective.filter2 = 0
             objective.time_limit = obj_data.time_limit
index 773c887b339437275db355f9701a9b17505587bc..b3aa492d2a3258bf30013aeeb041eb6a7000780a 100644 (file)
@@ -3,29 +3,52 @@
 #include "input.h"
 #include "gui.h"
 #include "audio.h"
+#include "ent_region.h"
 
-entity_call_result ent_challenge_call( world_instance *world, ent_call *call )
+void _ent_challenge_complete( ent_challenge *challenge )
 {
-   u32 index = mdl_entity_id_id( call->id );
-   ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
-
-   if( call->function == 0 ) /* win() */
+   world_instance *world = &_world.main;
+   vg_info( "challenge( '%s' )\n", af_str( &world->meta.af, challenge->pstr_alias) );
+   if( challenge->on_complete_id )
    {
-      vg_info( "challenge( '%s' )\n", af_str( &world->meta.af, challenge->pstr_alias) );
+      ent_call call;
+      call.data = NULL;
+      call.function = challenge->on_complete_event;
+      call.id = challenge->on_complete_id;
+      entity_call( world, &call );
+   }
 
-      vg_info( "on complete id: %u\n", challenge->on_complete_id );
-      if( challenge->on_complete_id )
-      {
-         ent_call call;
-         call.data = NULL;
-         call.function = challenge->on_complete_event;
-         call.id = challenge->on_complete_id;
-         entity_call( world, &call );
-      }
+   challenge->status = 1;
+}
 
-      challenge->status = 1;
-      return k_entity_call_result_OK;
+void _ent_challenge_win(void)
+{
+   world_instance *world = &_world.main;
+   ent_challenge *challenge = af_arritm( &world->ent_challenge, mdl_entity_id_id( _world.active_challenge_id ) );
+   _ent_challenge_complete( challenge );
+   ent_region_re_eval( world );
+
+   struct ent_script_event event;
+   struct script_event_completion_changed inf = {
+      .entity_id = _world.active_challenge_id,
+      .completion_flags = k_ent_route_flag_achieve_gold
+   };
+   event.type = k_escript_event_completion_changed;
+   event.info = &inf;
+   ent_script_propogate_event( world, &event );
+
+   if( world_clear_event( k_world_event_challenge ) )
+   {
+      _world.active_challenge_id = 0;
+      _world.challenge_target = NULL;
+      _world.challenge_timer = 0.0f;
    }
+}
+
+entity_call_result ent_challenge_call( world_instance *world, ent_call *call )
+{
+   u32 index = mdl_entity_id_id( call->id );
+   ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
 
    if( (_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running) )
    {
index 36ae1b67e70b08c2e94d73a183cda70e1bda458a..88aef576bbab1163ced999081b5aaed86c311c41 100644 (file)
@@ -4,3 +4,5 @@
 entity_call_result ent_challenge_call( world_instance *world, ent_call *call );
 void _ent_challenge_ui( ui_context *ctx );
 void _restart_active_challenge(void);
+void _ent_challenge_complete( ent_challenge *challenge );
+void _ent_challenge_win(void);
index 29c968950985029eec01820f31fff7076d1d165d..6427496b8071ed3bd667d4748bfbf3656cc17a23 100644 (file)
@@ -21,6 +21,19 @@ struct
    }
    gino;
 
+   struct human_npc
+   {
+      bool alive, in_cutscene;
+      v3f co;
+      v4f q;
+      u16 playermodel_view_slot;
+      struct player_effects_data effect_data;
+      player_pose pose;
+      m4x3f *final_mtx;
+   }
+   jc, mike;
+   struct skeleton_anim anim_idle;
+
    enum npc_sub_state
    {
       k_npc_sub_off,
@@ -34,18 +47,23 @@ struct
 }
 _npc;
 
-struct gino_context
+void _ent_npc_set_in_cutscene( enum npc npc_id, bool yes )
+{
+   if( npc_id == k_npc_jc )
+      _npc.jc.in_cutscene = yes;
+}
+
+struct sub_context
 {
    const char *alias;
    u32 alias_hash;
-
    const cs_subtitle *subtitles;
 }
 static _gino_contexts[] =
 {
    /* HEAVEN world */
    {
-      "heave:introduction", .subtitles = (const cs_subtitle[]) 
+      "heaven:introduction", .subtitles = (const cs_subtitle[]) 
       {
          { "a1", KCOL_JESUS "Hmm.. I'm Gino, hello" },
          { "a2", KCOL_JESUS "Do you remember who you are?" },
@@ -111,6 +129,29 @@ static _gino_contexts[] =
          { NULL, NULL },
       }
    },
+
+   /* MTZERO WORLD */
+   { 
+      "battery:locked", .subtitles = (const cs_subtitle[]) 
+      {
+         { "a1", KCOL_JESUS "See that..?" },
+         { "a2", KCOL_JESUS "Hmm.." },
+         { "a3", KCOL_JESUS "Big ramp over there.." },
+         { NULL, NULL },
+      }
+   },
+},
+_jc_contexts[] =
+{
+   {
+      "jc:demo", .subtitles = (const cs_subtitle[]) 
+      {
+         { "a1", KCOL_JOHN  "HELLO I AM JC" },
+         { "a2", KCOL_JOHN  "JC" },
+         { "a3", KCOL_JOHN  "IS ME" },
+         { NULL, NULL },
+      },
+   },
 };
 
 void _ent_npc_init(void)
@@ -127,6 +168,12 @@ void _ent_npc_init(void)
    _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 );
+
+   struct skeleton *sk = &localplayer.skeleton;
+   u32 mtx_size = sizeof(m4x3f)*sk->bone_count;
+   _npc.jc.final_mtx = vg_linear_alloc( alloc, mtx_size );
+   _npc.mike.final_mtx = vg_linear_alloc( alloc, mtx_size );
+   player_get_anim( &_npc.anim_idle, "idle_lean+y" );
 }
 
 void _ent_npc_reset(void)
@@ -135,6 +182,11 @@ void _ent_npc_reset(void)
    _npc.gino.spark_t = 0.0f;
    _npc.gino.command_t = 0.0;
    _npc.gino.current_entity_id = 0;
+
+   _npc.jc.alive = 0;
+   _npc.mike.alive = 0;
+   addon_cache_unwatch( k_addon_type_player, _npc.jc.playermodel_view_slot );
+   addon_cache_unwatch( k_addon_type_player, _npc.mike.playermodel_view_slot );
 }
 
 void _ent_npc_speech( enum npc npc_id, const cs_subtitle *subs )
@@ -233,14 +285,42 @@ void _ent_npc_preupdate(void)
             _npc.gino.spark_t -= vg.time_delta;
       }
    }
+
+   if( _npc.jc.alive && (v3_dist2( localplayer.rb.co, _npc.jc.co ) < 40.0f*40.0f) )
+   {
+      ms_keyframe apose[32], bpose[32];
+      struct skeleton *sk = &localplayer.skeleton;
+      player_pose *pose = &_npc.jc.pose;
+      pose->type = k_player_pose_type_ik;
+      pose->board.lean = 0.0f;
+      v3_copy( _npc.jc.co, pose->root_co );
+      v4_copy( _npc.jc.q, pose->root_q );
+      skeleton_sample_anim( sk, &_npc.anim_idle, vg.time*0.1f+0.4f, apose );
+      skeleton_copy_pose( sk, apose, pose->keyframes );
+      // no for JC.
+      // effect_blink_apply( &_npc.jc.effect_data.blink, pose, vg.time_delta );
+      apply_full_skeleton_pose( sk, pose, _npc.jc.final_mtx );
+   }
 }
 
 void _ent_npc_render( vg_camera *cam )
 {
+   world_instance *world = &_world.main;
+
+   if( _npc.jc.alive && (v3_dist2( localplayer.rb.co, _npc.jc.co ) < 40.0f*40.0f) )
+   {
+      if( !((_cutscene.state == k_cutscene_state_playing) && _npc.jc.in_cutscene) )
+      {
+         m4x3f *final_mtx = _npc.jc.final_mtx;
+         struct player_model *model = addon_cache_item_data( k_addon_type_player, _npc.jc.playermodel_view_slot, 1 );
+         struct skeleton *sk = &localplayer.skeleton;
+         render_playermodel( cam, world, 0, model, sk, final_mtx );
+      }
+   }
+
    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] );
@@ -331,6 +411,25 @@ entity_call_result ent_npc_call( world_instance *world, ent_call *call )
    }
    else if( AF_STR_EQ( &world->meta.af, npc->pstr_id, "JC" ) )
    {
+      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(_jc_contexts); i ++ )
+            if( (hash == _jc_contexts[i].alias_hash) && !strcmp(_jc_contexts[i].alias,alias) )
+               _ent_npc_speech( k_npc_gino, _jc_contexts[i].subtitles );
+      }
+      /* proximity */
+      else if( call->function == 1 )
+      {
+         if( _npc.jc.alive == 0 )
+         {
+            _npc.jc.alive = 1;
+            _npc.jc.playermodel_view_slot = addon_cache_create_viewer_from_uid( k_addon_type_player, "sr003-local-skaterift_john" );
+         }
+         v3_copy( npc->transform.co, _npc.jc.co );
+         q_copy( npc->transform.q, _npc.jc.q );
+      }
       return k_entity_call_result_OK;
    }
 
index 94cefd687122c71df33275e0ebf69f145bdeffb1..21e5e3db5c9b8bec4490f617fdfaf359947fbab1 100644 (file)
@@ -5,6 +5,7 @@ enum npc
    k_npc_none = 0,
    k_npc_gino,
    k_npc_jc,
+   k_npc_max
 };
 
 void _ent_npc_init(void);
@@ -13,4 +14,5 @@ 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);
+void _ent_npc_set_in_cutscene( enum npc npc_id, bool yes );
 entity_call_result ent_npc_call( world_instance *world, ent_call *call );
index 5891d835f79f94e2dfbf150b7c915a5dd7d13197..d33c61a7002e7985182395faf0811dfe967bb937 100644 (file)
@@ -28,28 +28,10 @@ static void ent_objective_pass( world_instance *world, ent_objective *objective
    }
    else 
    {
-      vg_success( "challenge win\n" );
       vg_audio_lock();
       vg_audio_oneshot( &audio_challenge[2], 1.0f, 0.0f, 0, 0 );
       vg_audio_unlock();
-
-      if( objective->id_win )
-      {
-         ent_call call;
-         call.data = NULL;
-         call.function = objective->win_event;
-         call.id = objective->id_win;
-         entity_call( world, &call );
-      }
-
-      ent_region_re_eval( world );
-
-      if( world_clear_event( k_world_event_challenge ) )
-      {
-         _world.active_challenge_id = 0;
-         _world.challenge_target = NULL;
-         _world.challenge_timer = 0.0f;
-      }
+      _ent_challenge_win();
    }
 }
 
index a1f5521a17dbebb814bb5d6c1f77db57ebeb0504..8fc559ad8ad486fc6b7c8d140e2e26cd91a47c02 100644 (file)
@@ -17,9 +17,10 @@ struct script_event_nugget_changed
    u64 value;
 };
 
-struct script_event_region_completion_changed
+struct script_event_completion_changed
 {
-   ent_region *region;
+   u32 entity_id;
+   u32 completion_flags;
 };
 
 typedef struct ent_script_event ent_script_event;
@@ -32,6 +33,7 @@ struct ent_script_event
       k_escript_event_update,
       k_escript_event_world_start,
       k_escript_event_nugget_changed,
+      k_escript_event_completion_changed
    }
    type;
    void *info;
index b781e0d6adcad0df087f8605cb6a92fda4cf7a04..fac8f63e5a97d4a8b42484fd328989dd825c8374 100644 (file)
@@ -651,8 +651,8 @@ struct ent_objective
        flags,
        id_next,
        filter,filter2,
-       id_win;
-   i32 win_event;
+       deleted0;
+   i32 deleted1;
    f32 time_limit;
    u32 pstr_description_ui;
 };
index 7c3a5b60c3973b8eebbaad1a84e376eca1b4f415..7750eb8ebc4e43972ab14c442a10e15dc49ba3f1 100644 (file)
@@ -914,7 +914,7 @@ void menu_gui( ui_context *ctx )
       if( !network_connected() )
       {
          ui_text( ctx, panel, "Offline", 1, k_ui_align_middle_center, 0 );
-         goto menu_draw;
+         goto n1;
       }
 
       i32 R = menu_nav( &menu.spectate_row, mv, netplayers.spectate_count );
@@ -947,6 +947,7 @@ void menu_gui( ui_context *ctx )
          }
       }
 
+n1:
       if( button_down( k_srbind_mquick ) || button_down( k_srbind_mback ) )
       {
          vg_audio_lock();
index 910dc304d41575d73c709e457016fe6fb256b091..2867488c6e53983d37a4de8be916cbc0fc30901f 100644 (file)
@@ -288,6 +288,9 @@ void _cutscene_load_and_play( const char *path, const cs_subtitle *subtitles, bo
 {
    VG_ASSERT( _cutscene.state == k_cutscene_state_none );
 
+   for( u32 i=0; i<k_npc_max; i ++ )
+      _ent_npc_set_in_cutscene( i, 0 );
+
    _cutscene.state = k_cutscene_state_loading;
    _cutscene.subtitle_list = subtitles;
    _cutscene.subtitle_index = 0;
index ebcd8bd4605edc2f0d663c010d7c9b034de8015d..4393b12a631f5d87fb8313ecac18b3c33004d99f 100644 (file)
@@ -241,7 +241,6 @@ void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose,
 void player__animate(void)
 {
    struct player_subsystem_interface *sys = player_subsystems[localplayer.subsystem];
-
    struct player_board *board = addon_cache_item_data( k_addon_type_board, localplayer.board_view_slot, 1 );
    if( !board ) 
       board = &localplayer.fallback_board;
@@ -253,21 +252,15 @@ void player__animate(void)
 
    struct skeleton *sk = &localplayer.skeleton;
 
-   if( localplayer.holdout_time > 0.0f ){
-      skeleton_lerp_pose( sk, 
-                          pose->keyframes,localplayer.holdout_pose.keyframes, 
-                          localplayer.holdout_time, pose->keyframes );
-
-      v3_muladds( pose->root_co, localplayer.holdout_pose.root_co, 
-                  localplayer.holdout_time, pose->root_co );
-      q_nlerp( pose->root_q, localplayer.holdout_pose.root_q, 
-               localplayer.holdout_time, pose->root_q );
-
+   if( localplayer.holdout_time > 0.0f )
+   {
+      skeleton_lerp_pose( sk, pose->keyframes,localplayer.holdout_pose.keyframes, localplayer.holdout_time, pose->keyframes );
+      v3_muladds( pose->root_co, localplayer.holdout_pose.root_co, localplayer.holdout_time, pose->root_co );
+      q_nlerp( pose->root_q, localplayer.holdout_pose.root_q, localplayer.holdout_time, pose->root_q );
       localplayer.holdout_time -= vg.time_frame_delta / 0.25f;
    }
 
-   effect_blink_apply( &localplayer.effect_data.blink,
-                       &localplayer.pose, vg.time_delta );
+   effect_blink_apply( &localplayer.effect_data.blink, &localplayer.pose, vg.time_delta );
    apply_full_skeleton_pose( sk, &localplayer.pose, localplayer.final_mtx );
    
    if( sys->effects )
index b2491a708d8794ca8483ac0794c6a05e26ecd6b6..29aa352b86fec5a0034f0aae134bdc202037c71e 100644 (file)
@@ -54,17 +54,13 @@ void render_board( vg_camera *cam, world_instance *world,
                       struct player_board_pose *pose,
                       enum board_shader shader );
 
-void render_playermodel( vg_camera *cam, world_instance *world,
-                            int depth_compare,
+void render_playermodel( vg_camera *cam, world_instance *world, int depth_compare,
                             player_model *model,
                             struct skeleton *skeleton,
                             m4x3f *final_mtx );
-void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose,
-                               m4x3f *final_mtx );
-void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t,
-                       player_pose *posed );
-void player_mirror_pose( ms_keyframe pose[32], 
-                         ms_keyframe mirrored[32] );
+void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose, m4x3f *final_mtx );
+void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t, player_pose *posed );
+void player_mirror_pose( ms_keyframe pose[32], ms_keyframe mirrored[32] );
 void player__observe_system( enum player_subsystem id );
 void player_load_animations( const char *path );
 void player_load_animation_reference( const char *path );
index e9bbc90e8ea926512672b4f7df5312cacb9b5bcc..97c008cca53a2bee1311e39a53b020401cc23b60 100644 (file)
@@ -46,29 +46,17 @@ static bool _skaterift_script_board_maker( ent_script_event *event )
    {
       if( world_set_event( k_world_event_board_maker ) )
       {
-         ent_list *list = event->entity_list;
-         for( u32 i=0; i<list->entity_ref_count; i ++ )
+         struct ent_list_iter iter;
+         _ent_list_iter_start( &iter, event->entity_list, k_ent_marker );
+         while( _ent_list_iter( &iter ) )
          {
-            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 );
+            ent_marker *marker = af_arritm( &event->world->ent_marker, iter.index );
+            const char *alias = af_str( &event->world->meta.af, marker->pstr_alias );
 
-            if( type == k_ent_marker )
-            {
-               ent_marker *marker = af_arritm( &event->world->ent_marker, index );
-
-               const char *alias = af_str( &event->world->meta.af, marker->pstr_alias );
-
-               if( !strcmp( alias, "$board_position" ) )
-               {
-                  v3_copy( marker->transform.co, _board_maker.origin );
-               }
-               else if( !strcmp( alias, "$camera_position" ) )
-               {
-                  v3_copy( marker->transform.co, _board_maker.camera_pos );
-               }
-            }
+            if( !strcmp( alias, "$board_position" ) )
+               v3_copy( marker->transform.co, _board_maker.origin );
+            else if( !strcmp( alias, "$camera_position" ) )
+               v3_copy( marker->transform.co, _board_maker.camera_pos );
          }
          _board_maker_open();
       }
index 06208eadda5018941716f5b6dabf617904decb4e..eef26547ee9db5592dc8140cead7345bf40dbeac 100644 (file)
-static bool _skaterift_script_ch2s1( ent_script_event *event )
+static bool _skaterift_script_mtzero( ent_script_event *event )
 {
-#if 0
-   static const struct cs_subtitle EN[] = 
-   {
-      { "j1", KCOL_JOHN "Eughhh boy" },
-      { "j2", KCOL_JOHN "When we get off this thing I gotta go lay down for a bit" },
-      { "j3", KCOL_JOHN "Oh look" },
-      { "j4", KCOL_JOHN "There's Mike over there" },
-      { "j5", KCOL_JOHN "HELLO MIKE!" },
-      { "j7", KCOL_JOHN "Yeah listen.." },
-      { "j8", KCOL_JOHN "I know things are a bit weird at the moment" },
-      { "j9", KCOL_JOHN "but it'l make sense soon" },
-      { "j10", KCOL_JOHN "I garuntee it" },
-      { "j11", KCOL_JOHN "50%% probably garuntee it" },
-      { "j12", KCOL_JOHN "I need you to go on, keep on setting some time trials here" },
-      { "j13", KCOL_JOHN "We're gonna need your speed later" },
-      { "j14", KCOL_JOHN "Its.. Why I picked you." },
-      { NULL, NULL },
-   };
-   static const struct generic_cutscene cutscene = 
-   {
-      .metascene_path = "metascenes/ch2s1.ms",
-      .freeze_player = 1,
-      .subtitles = EN,
-   };
-   generic_cutscene_wrapper( &cutscene, event );
-
+   /* intro movie */
    if( on_nugget_once( event, "ch2s1_view" ) )
    {
-      play_generic_cutscene( event );
+      static const struct cs_subtitle EN[] = 
+      {
+         { "j1", KCOL_JOHN "Eughhh boy" },
+         { "j2", KCOL_JOHN "When we get off this thing I gotta go lay down for a bit" },
+         { "j3", KCOL_JOHN "Oh look" },
+         { "j4", KCOL_JOHN "There's Mike over there" },
+         { "j5", KCOL_JOHN "HELLO MIKE!" },
+         { "j7", KCOL_JOHN "Yeah listen.." },
+         { "j8", KCOL_JOHN "I know things are a bit weird at the moment" },
+         { "j9", KCOL_JOHN "but it'l make sense soon" },
+         { "j10", KCOL_JOHN "I garuntee it" },
+         { "j11", KCOL_JOHN "50%% probably garuntee it" },
+         { "j12", KCOL_JOHN "I need you to go on, keep on setting some time trials here" },
+         { "j13", KCOL_JOHN "We're gonna need your speed later" },
+         { "j14", KCOL_JOHN "Its.. Why I picked you." },
+         { NULL, NULL },
+      };
+      _cutscene_load_and_play( "metascenes/ch1s2.ms", EN, 1 );
+   }
+
+   /* requirements for battery jump */
+   if( on_completion_changed( event ) )
+   {  
+      bool requirements_met = 1;
+      struct ent_list_iter iter;
+      _ent_list_iter_start( &iter, _ent_list_get_aliased( "battery_requirements" ), k_ent_route );
+      while( _ent_list_iter( &iter ) )
+      {
+         ent_route *route = af_arritm( &_world.main.ent_route, iter.index );
+         if( !(route->flags & (k_ent_route_flag_achieve_gold|k_ent_route_flag_achieve_silver)) )
+         {
+            requirements_met = 0;
+            break;
+         }
+      }
+
+      if( requirements_met )
+         if( _skaterift_script_nugget_status( "ch2s3_view" ) == 0 )
+            _skaterift_script_nugget_set( "ch2s3_view", 2 );
    }
-#endif
+
    return 1;
 }
 
-static bool _skaterift_script_ch2s2( ent_script_event *event )
+static bool _skaterift_script_mtzero_after( ent_script_event *event )
 {
-#if 0
-   static const struct cs_subtitle EN[] = 
-   {
-      { "m1", KCOL_MIKE "Haha!" },
-      { "m2", KCOL_MIKE "Usually you don't put up with JC's nonsense.." },
-      { "m3", KCOL_MIKE "He's been banging on about how we need to set some kind of speed record" },
-      { "m4", KCOL_MIKE "For his.. \"Experiment\"" },
-      { "m5", KCOL_MIKE "To be honest..." },
-      { "m6", KCOL_MIKE "I'm just pretending to go along with it at this point.." },
-      { "m7", KCOL_MIKE "I don't want to loose my internship at the wood place.." },
-      { "m7b", KCOL_MIKE "He is my boss after all" },
-      { "m9", KCOL_MIKE "Anyway uh, speaking of" },
-      { "m10", KCOL_MIKE "I gotta go take care of yet another catastrophe he's created back there." },
-      { "m11", KCOL_MIKE "I won't go into it." },
-      { "m12", KCOL_MIKE "But umm" },
-      { "m13", KCOL_MIKE "Good to see you back again" },
-      { "m14", KCOL_MIKE "Later." },
-
-      { NULL, NULL },
-   };
-   static const struct generic_cutscene cutscene = 
-   {
-      .metascene_path = "metascenes/ch2s2.ms",
-      .freeze_player = 1,
-      .subtitles = EN,
-   };
-   optional_video_wrapper( &cutscene, "ch2s2_view", 0, event );
-#endif
    return 1;
 }
 
-static bool _skaterift_script_first_mtzero( ent_script_event *event )
+static bool _skaterift_script_ch2s2( ent_script_event *event )
 {
-#if 0
-   if( on_function_trigger( event, 6 ) )
+   if( on_function_trigger( event, 0 ) )
    {
-      u64 status = _skaterift_script_nugget_status( "ch2s3_view" );
-      if( status == 0 )
+      if( on_nugget_once( event, "ch2s2_view" ) )
       {
-         _skaterift_script_nugget_set( "ch2s3_view", 2 );
+         static const struct cs_subtitle EN[] = 
+         {
+            { "m1", KCOL_MIKE "Haha!" },
+            { "m2", KCOL_MIKE "Usually you don't put up with JC's nonsense.." },
+            { "m3", KCOL_MIKE "He's been banging on about how we need to set some kind of speed record" },
+            { "m4", KCOL_MIKE "For his.. \"Experiment\"" },
+            { "m5", KCOL_MIKE "To be honest..." },
+            { "m6", KCOL_MIKE "I'm just pretending to go along with it at this point.." },
+            { "m7", KCOL_MIKE "I don't want to loose my internship at the wood place.." },
+            { "m7b", KCOL_MIKE "He is my boss after all" },
+            { "m9", KCOL_MIKE "Anyway uh, speaking of" },
+            { "m10", KCOL_MIKE "I gotta go take care of yet another catastrophe he's created back there." },
+            { "m11", KCOL_MIKE "I won't go into it." },
+            { "m12", KCOL_MIKE "But umm" },
+            { "m13", KCOL_MIKE "Good to see you back again" },
+            { "m14", KCOL_MIKE "Later." },
+            { NULL, NULL },
+         };
+         _cutscene_load_and_play( "metascenes/ch2s2.ms", EN, 1 );
       }
    }
-#endif
+   u64 status;
+   if( on_nugget_changed( event, "ch2s2_view", &status ) )
+      _ent_list_set_visible( event->entity_list, status == 0 );
    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?" },
-      { "m2",  KCOL_MIKE "I mean.." },
-      { "m3",  KCOL_MIKE "JC's gonna be over the moon obviously, but" },
-      { "m4",  KCOL_MIKE "Why?" },
-      { "m5",  KCOL_MIKE "Don't you think its.. pointless?" },
-      { "m6",  KCOL_MIKE "Myeah I'm heading back to the shop" },
-      { "m7",  KCOL_MIKE "Coming?" },
-      { "m8",  KCOL_MIKE "Ohh man.." },
-      { "m9",  KCOL_MIKE "What a **** racket" },
-      { "m10", KCOL_MIKE "It's 8pm even." },
-      { "j1",  KCOL_JOHN "You guys can't be walking in and scaring me like that" },
-      { "m11", KCOL_MIKE "John, " },
-      { "m12", KCOL_MIKE "Whats that?" },
-      { "j2",  KCOL_JOHN "uhhh just uh just uhh" },
-      { "j3",  KCOL_JOHN "just cleaning something up for a client" },
-      { "m13", KCOL_MIKE "A 20ft tall quaterpipe" },
-      { "m14", KCOL_MIKE "for a client.." },
-      { "m15", KCOL_MIKE "on an island full of pensioners?" },
-      { "j4",  KCOL_JOHN "Yeah why not?" },
-      { "j5",  KCOL_JOHN "Skating's taking off right now!" },
-      { "m16", KCOL_MIKE "Come on mate.." },
-      { "j6",  KCOL_JOHN "Aight look.." },
-      { "j7",  KCOL_JOHN "I'm just skimming little bits from the surplus" },
-      { "j8",  KCOL_JOHN "I got this plan right." },
-      { "j9",  KCOL_JOHN "It's gonna be BIG" },
-      { "j10", KCOL_JOHN "People from all over the world are gonna come to see it." },
-      { "j11", KCOL_JOHN "You know how like uh..." },
-      { "j12", KCOL_JOHN "You know how no one visits the west island?" },
-      { "m17", KCOL_MIKE "Well.. yeah?" },
-      { "j13", KCOL_JOHN "Behold!" },
-      { "j14", KCOL_JOHN "Mango mega island!" },
-      { "j15", KCOL_JOHN "A skaters dream.." },
-      { "m18", KCOL_MIKE "Ohhh yeah john" },
-      { "m19", KCOL_MIKE "Looks great!" },
-      { "m20", KCOL_MIKE "And whos gonna build this.." },
-      { "m21", KCOL_MIKE "gigantic skate thing then..?" },
-      { "j16", KCOL_JOHN "Well uhhh" },
-      { "j17", KCOL_JOHN "Thats where I need your guys help." },
-      { "m22", KCOL_MIKE "What are we gonna help with exactly?" },
-      { "m23", KCOL_MIKE "You always do this John." },
-      { "m24", KCOL_MIKE "Have some grand idea and suddenly everyones onboard with it." },
-      { "j18", KCOL_JOHN "Whens the last time I asked you for anything?" },
-      { "m25", KCOL_MIKE "Yesterday.." },
-      { "j19", KCOL_JOHN "Oh..." },
-      { "j20", KCOL_JOHN "Yeah, anyway" },
-      { "j21", KCOL_JOHN "All I need is for you guys to finish the time trials" },
-      { "j22", KCOL_JOHN "Go work on those, and come back when you've got it." },
-      { "m26", KCOL_MIKE "Yeah well I got news for you!" },
-      { "m27", KCOL_MIKE "Bird here has smashed all of them already." },
-      { "j23", KCOL_JOHN "wait what?" },
-      { "j24", KCOL_JOHN "You did!?" },
-      { "j25", KCOL_JOHN "really???" },
-      { "j26", KCOL_JOHN "Holy I knew you were good!" },
-      { "m28", KCOL_MIKE "Yeah but uhh.." },
-      { "m29", KCOL_MIKE "What exactly does this have to do with building a world record size skatepark island?" },
-      { "j27", KCOL_JOHN "You see.." },
-      { "j28", KCOL_JOHN "It was the missing component. It was speed." },
-      { "j29", KCOL_JOHN "It's all we needed, to build a time net" },
-      { "j30", KCOL_JOHN "Large enough to create infinite energy." },
-      { "m30", KCOL_MIKE "Infinite.. energy..?" },
-      { "j31", KCOL_JOHN "Yeah! You know to uh contact Allen and Alvin." },
-      { "j32", KCOL_JOHN "They're the ones who are gonna help us with this whole thing." },
-      { "m31", KCOL_MIKE "Them! Ahhh no man" },
-      { "m32", KCOL_MIKE "not the aliens again.." },
-      { "m33", KCOL_MIKE "the tiny little dudes you saw in a drug induced coma" },
-      { "m34", KCOL_MIKE "are gonna help us build a megapark, on an abandoned island" },
-      { "m35", KCOL_MIKE "I dont even know why I asked.." },
-      { "m36", KCOL_MIKE "I'm clocking out. See you later." },
-      { "j33", KCOL_JOHN "Look..." },
-      { "j34", KCOL_JOHN "I'm not crazy, I promise. Just trust me." },
-      { "j35", KCOL_JOHN "Lemme prove it." },
-      { "j36", KCOL_JOHN "Bring this with you, hold onto it." },
-      { "j37", KCOL_JOHN "Skate those trails as fast as you can with it on you." },
-      { "j38", KCOL_JOHN "You'll understand when it happens," },
-      { "j39", KCOL_JOHN "And you'll see what I mean by that" },
-      { "j40", KCOL_JOHN "You'll just see it.. and" },
-      { "j41", KCOL_JOHN "If anyone asks, you didn't get this from me." },
-      { "j42", KCOL_JOHN "But I'll be there, I'll be watching, just get on with it." },
-      { NULL, NULL },
-   };
-   static const struct generic_cutscene cutscene = 
-   {
-      .metascene_path = "metascenes/ch2s3a.ms",
-      .freeze_player = 1,
-      .subtitles = EN,
-   };
-   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.." },
-      { "j2",  KCOL_JOHN "You **** did it now" },
-      { "j3",  KCOL_JOHN "I told you I am not crazy!" },
-      { "j4",  KCOL_JOHN "You've done me a real solid mate." },
-      { "j5",  KCOL_JOHN "When I switch this thing on" },
-      { "j6",  KCOL_JOHN "It's gonna broadcast our location to them.." },
-      { "j7",  KCOL_JOHN "We have just enough power. Thanks to you my friend" },
-      { "j8",  KCOL_JOHN "Okayyy any second" },
-      { "j9",  KCOL_JOHN "BOSH" },
-      { "j10", KCOL_JOHN "HELLO MY FRIENDS" },
-      { "j11", KCOL_JOHN "WE NEED HELP" },
-      { "j12", KCOL_JOHN "THIS IS CAPTAIN JOHN COCROACH" },
-      { "j13", KCOL_JOHN "PLEASE COME AS SOON AS YOU CAN TO MT.ZERO ISLAND" },
-      { "j14", KCOL_JOHN "Our coordinates are...." },
-      { NULL, NULL },
-   };
-   static const struct generic_cutscene cutscene = 
+   if( on_function_trigger( event, 0 ) )
    {
-      .metascene_path = "metascenes/ch2s4.ms",
-      .freeze_player = 1,
-      .subtitles = EN,
-   };
-   optional_video_wrapper( &cutscene, "ch2s4_view", 2, event );
-#endif
+      if( on_nugget_once( event, "ch2s3_view" ) )
+      {
+         static const struct cs_subtitle EN[] = 
+         {
+            { "m1",  KCOL_MIKE "Holy! You actually bothered to do these?" },
+            { "m2",  KCOL_MIKE "I mean.." },
+            { "m3",  KCOL_MIKE "JC's gonna be over the moon obviously, but" },
+            { "m4",  KCOL_MIKE "Why?" },
+            { "m5",  KCOL_MIKE "Don't you think its.. pointless?" },
+            { "m6",  KCOL_MIKE "Myeah I'm heading back to the shop" },
+            { "m7",  KCOL_MIKE "Coming?" },
+            { "m8",  KCOL_MIKE "Ohh man.." },
+            { "m9",  KCOL_MIKE "What a **** racket" },
+            { "m10", KCOL_MIKE "It's 8pm even." },
+            { "j1",  KCOL_JOHN "You guys can't be walking in and scaring me like that" },
+            { "m11", KCOL_MIKE "John, " },
+            { "m12", KCOL_MIKE "Whats that?" },
+            { "j2",  KCOL_JOHN "uhhh just uh just uhh" },
+            { "j3",  KCOL_JOHN "just cleaning something up for a client" },
+            { "m13", KCOL_MIKE "A 20ft tall quaterpipe" },
+            { "m14", KCOL_MIKE "for a client.." },
+            { "m15", KCOL_MIKE "on an island full of pensioners?" },
+            { "j4",  KCOL_JOHN "Yeah why not?" },
+            { "j5",  KCOL_JOHN "Skating's taking off right now!" },
+            { "m16", KCOL_MIKE "Come on mate.." },
+            { "j6",  KCOL_JOHN "Aight look.." },
+            { "j7",  KCOL_JOHN "I'm just skimming little bits from the surplus" },
+            { "j8",  KCOL_JOHN "I got this plan right." },
+            { "j9",  KCOL_JOHN "It's gonna be BIG" },
+            { "j10", KCOL_JOHN "People from all over the world are gonna come to see it." },
+            { "j11", KCOL_JOHN "You know how like uh..." },
+            { "j12", KCOL_JOHN "You know how no one visits the west island?" },
+            { "m17", KCOL_MIKE "Well.. yeah?" },
+            { "j13", KCOL_JOHN "Behold!" },
+            { "j14", KCOL_JOHN "Mango mega island!" },
+            { "j15", KCOL_JOHN "A skaters dream.." },
+            { "m18", KCOL_MIKE "Ohhh yeah john" },
+            { "m19", KCOL_MIKE "Looks great!" },
+            { "m20", KCOL_MIKE "And whos gonna build this.." },
+            { "m21", KCOL_MIKE "gigantic skate thing then..?" },
+            { "j16", KCOL_JOHN "Well uhhh" },
+            { "j17", KCOL_JOHN "Thats where I need your guys help." },
+            { "m22", KCOL_MIKE "What are we gonna help with exactly?" },
+            { "m23", KCOL_MIKE "You always do this John." },
+            { "m24", KCOL_MIKE "Have some grand idea and suddenly everyones onboard with it." },
+            { "j18", KCOL_JOHN "Whens the last time I asked you for anything?" },
+            { "m25", KCOL_MIKE "Yesterday.." },
+            { "j19", KCOL_JOHN "Oh..." },
+            { "j20", KCOL_JOHN "Yeah, anyway" },
+            { "j21", KCOL_JOHN "All I need is for you guys to finish the time trials" },
+            { "j22", KCOL_JOHN "Go work on those, and come back when you've got it." },
+            { "m26", KCOL_MIKE "Yeah well I got news for you!" },
+            { "m27", KCOL_MIKE "Bird here has smashed all of them already." },
+            { "j23", KCOL_JOHN "wait what?" },
+            { "j24", KCOL_JOHN "You did!?" },
+            { "j25", KCOL_JOHN "really???" },
+            { "j26", KCOL_JOHN "Holy I knew you were good!" },
+            { "m28", KCOL_MIKE "Yeah but uhh.." },
+            { "m29", KCOL_MIKE "What exactly does this have to do with building a world record size skatepark island?" },
+            { "j27", KCOL_JOHN "You see.." },
+            { "j28", KCOL_JOHN "It was the missing component. It was speed." },
+            { "j29", KCOL_JOHN "It's all we needed, to build a time net" },
+            { "j30", KCOL_JOHN "Large enough to create infinite energy." },
+            { "m30", KCOL_MIKE "Infinite.. energy..?" },
+            { "j31", KCOL_JOHN "Yeah! You know to uh contact Allen and Alvin." },
+            { "j32", KCOL_JOHN "They're the ones who are gonna help us with this whole thing." },
+            { "m31", KCOL_MIKE "Them! Ahhh no man" },
+            { "m32", KCOL_MIKE "not the aliens again.." },
+            { "m33", KCOL_MIKE "the tiny little dudes you saw in a drug induced coma" },
+            { "m34", KCOL_MIKE "are gonna help us build a megapark, on an abandoned island" },
+            { "m35", KCOL_MIKE "I dont even know why I asked.." },
+            { "m36", KCOL_MIKE "I'm clocking out. See you later." },
+            { "j33", KCOL_JOHN "Look..." },
+            { "j34", KCOL_JOHN "I'm not crazy, I promise. Just trust me." },
+            { "j35", KCOL_JOHN "Lemme prove it." },
+            { "j36", KCOL_JOHN "Bring this with you, hold onto it." },
+            { "j37", KCOL_JOHN "Skate those trails as fast as you can with it on you." },
+            { "j38", KCOL_JOHN "You'll understand when it happens," },
+            { "j39", KCOL_JOHN "And you'll see what I mean by that" },
+            { "j40", KCOL_JOHN "You'll just see it.. and" },
+            { "j41", KCOL_JOHN "If anyone asks, you didn't get this from me." },
+            { "j42", KCOL_JOHN "But I'll be there, I'll be watching, just get on with it." },
+            { NULL, NULL },
+         };
+         _cutscene_load_and_play( "metascenes/ch2s3a.ms", EN, 1 );
+      }
+   }
+   u64 status;
+   if( on_nugget_changed( event, "ch2s3_view", &status ) )
+      _ent_list_set_visible( event->entity_list, status == 2 );
    return 1;
 }
 
 static bool _skaterift_script_ch2s5_before( ent_script_event *event )
 {
-#if 0
    u64 status;
    if( on_nugget_changed( event, "ch2s5_view", &status ) )
-   {
-      bool visible = 0;
-
-      if( status == 2 )
-         visible = 1;
-
-      ent_list_set_visible( event->world, event->entity_list, visible );
-   }
+      _ent_list_set_visible(  event->entity_list, status == 2 );
 
    if( on_function_trigger( event, 0 ) )
    {
       _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?" },
-      { "m2",  KCOL_MIKE "Yeah yeah.. I get you.. um." },
-      { "m3",  KCOL_MIKE "I genuinely have no idea where he found that cell thing" },
-      { "m4",  KCOL_MIKE "I reckon it came of some kind of secret government tech or whatever" },
-      { "m5",  KCOL_MIKE "but.." },
-      { "m6",  KCOL_MIKE "Now you know what he was doing with all those stupid poles he put up across the island" },
-      { "m7",  KCOL_MIKE "I'm starting to think I might be going crazy but.." },
-      { "m8",  KCOL_MIKE "Did you see the whole west side has actually been taken over?" },
-      { "m9",  KCOL_MIKE "Just like JC was saying.." },
-      { "m10", KCOL_MIKE "Are you telling me the aliens are actually real?" },
-      { NULL, NULL },
-   };
-   static const struct generic_cutscene cutscene = 
-   {
-      .metascene_path = "metascenes/ch2s5.ms",
-      .freeze_player = 1,
-      .subtitles = EN,
-   };
-
-   enum generic_cutscene_event cs_event = generic_cutscene_wrapper( &cutscene, event );
-
    u64 status;
    if( on_nugget_changed( event, "ch2s5_view", &status ) )
    {
       if( status == 3 )
       {
          _skaterift_script_nugget_set( "ch2s5_view", 1 );
-         play_generic_cutscene( event );
+         static const struct cs_subtitle EN[] = 
+         {
+            { "m1",  KCOL_MIKE "Hi mate, hows it goin?" },
+            { "m2",  KCOL_MIKE "Yeah yeah.. I get you.. um." },
+            { "m3",  KCOL_MIKE "I genuinely have no idea where he found that cell thing" },
+            { "m4",  KCOL_MIKE "I reckon it came of some kind of secret government tech or whatever" },
+            { "m5",  KCOL_MIKE "but.." },
+            { "m6",  KCOL_MIKE "Now you know what he was doing with all those stupid poles he put up across the island" },
+            { "m7",  KCOL_MIKE "I'm starting to think I might be going crazy but.." },
+            { "m8",  KCOL_MIKE "Did you see the whole west side has actually been taken over?" },
+            { "m9",  KCOL_MIKE "Just like JC was saying.." },
+            { "m10", KCOL_MIKE "Are you telling me the aliens are actually real?" },
+            { NULL, NULL },
+         };
+         _cutscene_load_and_play( "metascenes/ch2s5.ms", EN, 1 );
       }
    }
-#endif
    return 1;
 }
 
+struct script_ch2s6_waiter
+{
+   bool go;
+};
+
 static bool _skaterift_script_ch2s6( ent_script_event *event )
 {
-#if 0
-   static const struct cs_subtitle EN[] = 
-   {
-      { "j1",  KCOL_JOHN "Ello guys" },
-      { "j2",  KCOL_JOHN "Bout time you showed up" },
-      { "j3",  KCOL_JOHN "Look who I've got here!" },
-      { "m1",  KCOL_MIKE "Uhhhhhhhhhhhhhhhhhhhhhhhhhhh" },
-      { "m2",  KCOL_MIKE "Right then." },
-      { "m3",  KCOL_MIKE "I almost feel bad for these guys" },
-      { "m4",  KCOL_MIKE "Couldve' been any scientist across the planet" },
-      { "m5",  KCOL_MIKE "you know actually smart people" },
-      { "m6",  KCOL_MIKE "but no.." },
-      { "m7",  KCOL_MIKE "JC somehow contacts them first" },
-      { "j4",  KCOL_JOHN "Heyyy man." },
-      { "j5",  KCOL_JOHN "This required a special kind of science" },
-      { "j6",  KCOL_JOHN "The kinda stuff the world isn't quite ready for yet." },
-      { "j7",  KCOL_JOHN "But if you're done insulting me.." },
-      { "j8",  KCOL_JOHN "We're off to the states for a bit." },
-      { "j9",  KCOL_JOHN "Fancy a road trip?" },
-      { NULL, NULL },
-   };
-   static const struct generic_cutscene cutscene = 
+   if( event->type == k_escript_event_allocate )
    {
-      .metascene_path = "metascenes/ch2s6.ms",
-      .freeze_player = 1,
-      .subtitles = EN,
-   };
-   enum generic_cutscene_event cs_event = optional_video_wrapper( &cutscene, "ch2s6_view", 2, event );
+      struct script_event_allocate *event_info = event->info;
+      struct script_ch2s6_waiter *waiter = vg_linear_alloc( event_info->heap, sizeof(struct script_ch2s6_waiter) );
+      waiter->go = 0;
+      event_info->userdata = waiter;
+      return 1;
+   }
+   struct script_ch2s6_waiter *waiter = event->userdata;
+
+   u64 status;
+   if( on_nugget_changed( event, "ch2s6_view", &status ) )
+      _ent_list_set_visible( event->entity_list, status == 2 );
 
-   if( cs_event == k_generic_cutscene_event_end )
+   // TODO: THERE ARE NO UNLOCK CONDITIONS FOR THIS YET!
+
+   if( on_function_trigger( event, 0 ) )
+   {
+      if( on_nugget_once( event, "ch2s6_view" ) )
+      {
+         _skaterift_script_nugget_set( "unlock_city", 1 );
+         _skaterift_script_nugget_set( "ch2s6_view", 1 );
+         static const struct cs_subtitle EN[] = 
+         {
+            { "j1",  KCOL_JOHN "Ello guys" },
+            { "j2",  KCOL_JOHN "Bout time you showed up" },
+            { "j3",  KCOL_JOHN "Look who I've got here!" },
+            { "m1",  KCOL_MIKE "Uhhhhhhhhhhhhhhhhhhhhhhhhhhh" },
+            { "m2",  KCOL_MIKE "Right then." },
+            { "m3",  KCOL_MIKE "I almost feel bad for these guys" },
+            { "m4",  KCOL_MIKE "Couldve' been any scientist across the planet" },
+            { "m5",  KCOL_MIKE "you know actually smart people" },
+            { "m6",  KCOL_MIKE "but no.." },
+            { "m7",  KCOL_MIKE "JC somehow contacts them first" },
+            { "j4",  KCOL_JOHN "Heyyy man." },
+            { "j5",  KCOL_JOHN "This required a special kind of science" },
+            { "j6",  KCOL_JOHN "The kinda stuff the world isn't quite ready for yet." },
+            { "j7",  KCOL_JOHN "But if you're done insulting me.." },
+            { "j8",  KCOL_JOHN "We're off to the states for a bit." },
+            { "j9",  KCOL_JOHN "Fancy a road trip?" },
+            { NULL, NULL },
+         };
+         _cutscene_load_and_play( "metascenes/ch2s6.ms", EN, 1 );
+      }
+   }
+   if( event->type == k_escript_event_update )
    {
-      _skaterift_script_nugget_set( "unlock_city", 1 );
-      skaterift_load_world_command( 1, (const char *[]){ "sr002-local-mp_spawn" } );
+      if( waiter->go )
+      {
+         waiter->go = 0;
+         if( _cutscene.state == k_cutscene_state_none )
+         {
+            skaterift_load_world_command( 1, (const char *[]){ "sr002-local-dev_hub" } );
+         }
+      }
    }
-#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." },
-      { "j2",  KCOL_JOHN "If you wanna give me a graphic," },
-      { "j3",  KCOL_JOHN "I'll print it onto this plywood and press it" },
-      { "j4",  KCOL_JOHN "Mike'l griptape it and seal it" },
-      { "j5",  KCOL_JOHN "Ready to sell and skate!" },
-      { NULL, NULL },
-   };
-   static const struct generic_cutscene cutscene = 
+   if( on_function_trigger( event, 0 ) )
    {
-      .metascene_path = "metascenes/ch2e1.ms",
-      .freeze_player = 1,
-      .subtitles = EN,
-   };
-   enum generic_cutscene_event cs_event = optional_video_wrapper( &cutscene, "ch2e1_view", 2, event );
-
-   if( cs_event == k_generic_cutscene_event_start )
-      _skaterift_script_nugget_set( "board_maker_unlock", 1 );
-#endif
+      if( on_nugget_once( event, "ch2e1_view" ) )
+      {
+         _skaterift_script_nugget_set( "board_maker_unlock", 1 );
+         static const struct cs_subtitle EN[] = 
+         {
+            { "j1",  KCOL_JOHN "Hey bird I'm just working on some boards here." },
+            { "j2",  KCOL_JOHN "If you wanna give me a graphic," },
+            { "j3",  KCOL_JOHN "I'll print it onto this plywood and press it" },
+            { "j4",  KCOL_JOHN "Mike'l griptape it and seal it" },
+            { "j5",  KCOL_JOHN "Ready to sell and skate!" },
+            { NULL, NULL },
+         };
+         _cutscene_load_and_play( "metascenes/ch2e1.ms", EN, 1 );
+      }
+   }
+   u64 status;
+   if( on_nugget_changed( event, "ch2e1_view", &status ) )
+      _ent_list_set_visible( event->entity_list, status == 2 );
    return 1;
 }
 
+struct script_ch2s4_waiter
+{
+   bool go;
+   f32 timer;
+   ent_list *break_list;
+};
+
 static bool _skaterift_script_battery_jump( ent_script_event *event )
 {
-#if 0
-   static const struct cs_subtitle EN[] = {
-   { NULL, NULL },
-   };
-   static const struct generic_cutscene cutscene = 
+   if( event->type == k_escript_event_allocate )
    {
-      .metascene_path = "metascenes/battery_intro.ms",
-      .freeze_player = 1,
-      .subtitles = EN,
-   };
-   challenge_video_wrapper( &cutscene, "battery_jump_view", event );
+      struct script_event_allocate *event_info = event->info;
+      struct script_ch2s4_waiter *waiter = vg_linear_alloc( event_info->heap, sizeof(struct script_ch2s4_waiter) );
+      waiter->go = 0;
+      waiter->timer = 0.0f;
+      waiter->break_list = NULL;
+      event_info->userdata = waiter;
+      return 1;
+   }
+   struct script_ch2s4_waiter *waiter = event->userdata;
+   if( on_cutscene_marker( event, "$break" ) )
+      _explode_template_boom( waiter->break_list );
 
-   if( on_function_trigger( event, 7 ) )
+   if( on_function_trigger( event, 2 ) )
    {
-      // TODO
-      vg_error( "WHY????????????\n" );
+      if( on_nugget_once( event, "ch2s4_view" ) )
+      {
+         _skaterift_script_nugget_set( "ch2s5_view", 2 );
+         waiter->go = 1;
+      }
    }
 
-   if( on_cutscene_marker( event, "$break" ) )
+   /* viewed ch2s3 means we allowing this challenge now */
+   u64 status;
+   if( on_nugget_changed( event, "ch2s3_view", &status ) )
+      _ent_list_set_visible( event->entity_list, status == 1 );
+
+   if( event->type == k_escript_event_update )
    {
-      _explode_template_boom( event );
+      if( waiter->go )
+      {
+         waiter->timer += vg.time_frame_delta;
+         if( waiter->timer > 2.0f )
+         {
+            waiter->go = 0;
+            static const struct cs_subtitle EN[] = 
+            {
+               { "j1",  KCOL_JOHN "Oh my god.." },
+               { "j2",  KCOL_JOHN "You **** did it now" },
+               { "j3",  KCOL_JOHN "I told you I am not crazy!" },
+               { "j4",  KCOL_JOHN "You've done me a real solid mate." },
+               { "j5",  KCOL_JOHN "When I switch this thing on" },
+               { "j6",  KCOL_JOHN "It's gonna broadcast our location to them.." },
+               { "j7",  KCOL_JOHN "We have just enough power. Thanks to you my friend" },
+               { "j8",  KCOL_JOHN "Okayyy any second" },
+               { "j9",  KCOL_JOHN "BOSH" },
+               { "j10", KCOL_JOHN "HELLO MY FRIENDS" },
+               { "j11", KCOL_JOHN "WE NEED HELP" },
+               { "j12", KCOL_JOHN "THIS IS CAPTAIN JOHN COCROACH" },
+               { "j13", KCOL_JOHN "PLEASE COME AS SOON AS YOU CAN TO MT.ZERO ISLAND" },
+               { "j14", KCOL_JOHN "Our coordinates are...." },
+               { NULL, NULL },
+            };
+            _cutscene_load_and_play( "metascenes/ch2s4.ms", EN, 1 );
+         }
+      }
    }
 
-   if( event->type == k_escript_event_world_start )
+   if( on_function_trigger( event, 0 ) )
    {
-      u32 status = _skaterift_script_nugget_status( "battery_jump_view" );
+      if( on_nugget_once( event, "battery_jump_view" ) )
+      {
+         _cutscene_load_and_play( "metascenes/battery_intro.ms", NULL, 1 );
+         waiter->break_list = _ent_list_get_aliased( "battery:locked" );
+      }
+   }
 
-      if( status == 1 )
-         ent_list_set_visible( event->world, event->entity_list, 0 );
+   if( event->type == k_escript_event_world_start )
+   {
+      _ent_list_set_visible( _ent_list_get_aliased( "battery:locked" ), 
+                             _skaterift_script_nugget_status( "battery_jump_view" ) == 0 );
    }
-#endif
+
    return 1;
 }
index 91bbdca56ba86706bcd817c699dfe1fcc3bce6e6..c8945f3e579bdf25b712bc8f45193fbe0998ffa4 100644 (file)
@@ -89,6 +89,7 @@ static bool _skaterift_script_ch1s3( ent_script_event *event )
          { NULL, NULL },
          };
          _cutscene_load_and_play( "metascenes/ch1s3.ms", EN, 1 );
+         _ent_npc_set_in_cutscene( k_npc_jc, 1 );
       }
    }
 
@@ -102,11 +103,12 @@ static bool _skaterift_script_ch1s3( ent_script_event *event )
          { NULL, NULL },
          };
          _cutscene_load_and_play( "metascenes/ch1s3b.ms", EN, 1 );
+         _ent_npc_set_in_cutscene( k_npc_jc, 1 );
       }
    }
 
    u64 viewed;
-   if( on_nugget_changed( event, "ch1s3b_view", &viewed ) )
+   if( on_nugget_changed( event, "ch1s3_view", &viewed ) )
       _ent_list_set_visible( event->entity_list, !viewed );
 
    return 1;
@@ -240,6 +242,7 @@ static bool _skaterift_script_ch1s6a( ent_script_event *event )
       {
          if( _cutscene.state == k_cutscene_state_none )
          {
+            waiter->go = 0;
             skaterift_load_world_command( 1, (const char *[]){ "sr002-local-dev_hub" } );
          }
       }
index 5c37ec5953933b2d86b7d1be5c05c865d9dad21f..73d49d704b2d9eea282b7be20864cd67580f8ad6 100644 (file)
@@ -577,6 +577,13 @@ bool on_nugget_once( ent_script_event *event, const char *nugget_alias )
    return 0;
 }
 
+bool on_completion_changed( ent_script_event *event )
+{
+   if( event->type == k_escript_event_completion_changed )
+      return 1;
+   return 0;
+}
+
 #if 0
 enum generic_cutscene_event optional_video_wrapper( const struct generic_cutscene *cutscene_template, 
                                                     const char *nugget_alias,
@@ -647,11 +654,10 @@ struct ent_script_table_entry _ent_script_table[] =
    { "ch1s5", _skaterift_script_ch1s5 },
    { "ch1s6a", _skaterift_script_ch1s6a },
 
-   { "ch2s1", _skaterift_script_ch2s1 },
+   { "mtzero", _skaterift_script_mtzero },
+   { "mtzero_after", _skaterift_script_mtzero_after },
    { "ch2s2", _skaterift_script_ch2s2 },
-   { "first_mtzero", _skaterift_script_first_mtzero },
    { "ch2s3", _skaterift_script_ch2s3 },
-   { "ch2s4", _skaterift_script_ch2s4 },
    { "battery_jump", _skaterift_script_battery_jump },
    { "ch2s5_before", _skaterift_script_ch2s5_before },
    { "ch2s5_after", _skaterift_script_ch2s5_after },
index dbc7a48bda385a95ff6b223dce34b382cbd237b8..33651d272a576bfbf7fcb8aa20d447cd57552e30 100644 (file)
@@ -106,11 +106,9 @@ void world_gen_entities_init( world_instance *world )
    for( u32 j=0; j<af_arrcount(&world->ent_audio); j++ )
    {
       ent_audio *audio = af_arritm( &world->ent_audio, j );
-
       for( u32 k=0; k<audio->clip_count; k++ )
       {
          ent_audio_clip *clip = af_arritm( &world->ent_audio_clip, audio->clip_start+k );
-
          if( clip->_.file.pack_size )
          {
             u32 size = clip->_.file.pack_size,
@@ -148,7 +146,8 @@ void world_gen_entities_init( world_instance *world )
       u32 type;
       array_file_ptr *array;
    }
-   indexables[] = {
+   indexables[] = 
+   {
       { k_ent_gate, &world->ent_gate },
       { k_ent_objective, &world->ent_objective },
       { k_ent_volume, &world->ent_volume },
@@ -160,15 +159,13 @@ void world_gen_entities_init( world_instance *world )
       indexed_count += af_arrcount( indexables[i].array );
    vg_info( "indexing %u entities\n", indexed_count );
 
-   world->entity_list = vg_linear_alloc( world->heap, 
-                                         vg_align8(indexed_count*sizeof(u32)));
+   world->entity_list = vg_linear_alloc( world->heap, vg_align8(indexed_count*sizeof(u32)));
 
    u32 index=0;
    for( u32 i=0; i<VG_ARRAY_LEN(indexables); i++ )
    {
       u32 type  = indexables[i].type,
           count = af_arrcount( indexables[i].array );
-      
       for( u32 j=0; j<count; j ++ )
          world->entity_list[index ++] = mdl_entity_id( type, j );
    }
@@ -182,7 +179,6 @@ void world_gen_entities_init( world_instance *world )
    for( u32 i=0; i<af_arrcount(&world->ent_marker); i++ )
    {
       ent_marker *marker = af_arritm( &world->ent_marker, i );
-
       if( AF_STR_EQ( &world->meta.af, marker->pstr_alias, "tar_min" ) )
          world->tar_min = marker->transform.co[1];
 
@@ -199,26 +195,27 @@ ent_spawn *world_find_closest_spawn( world_instance *world, v3f position )
    for( u32 i=0; i<af_arrcount(&world->ent_spawn); i++ )
    {
       r = af_arritm( &world->ent_spawn, i );
-
       if( r->flags & k_ent_spawn_flag_locked )
          continue;
 
       float d = v3_dist2( r->transform.co, position );
       
-      if( d < min_dist ){
+      if( d < min_dist )
+      {
          min_dist = d;
          rp = r;
       }
    }
 
-   if( !rp ){
-      if( af_arrcount(&world->ent_spawn) ){
+   if( !rp )
+   {
+      if( af_arrcount(&world->ent_spawn) )
+      {
          vg_warn( "Invalid distances to spawns.. defaulting to first one.\n" );
          return af_arritm( &world->ent_spawn, 0 );
       }
-      else{
+      else
          vg_error( "There are no spawns in the level!\n" );
-      }
    }
 
    return rp;
@@ -232,7 +229,6 @@ ent_spawn *world_find_spawn_by_name( world_instance *world, const char *name )
    for( u32 i=0; i<af_arrcount(&world->ent_spawn); i++ )
    {
       r = af_arritm( &world->ent_spawn, i );
-
       if( af_str_eq( &world->meta.af, r->pstr_name, name, hash ) )
       {
          rp = r;
@@ -296,9 +292,7 @@ entity_call_result ent_volume_call( world_instance *world, ent_call *call )
       call->id = volume->target;
 
       if( volume->flags & k_ent_volume_flag_particles )
-      {
          vg_warn( "Invalid condition; calling leave on particle volume.\n" );
-      }
       else
       {
          call->function = volume->trigger.event_leave;
@@ -319,13 +313,9 @@ entity_call_result ent_audio_call( world_instance *world, ent_call *call )
    v3f sound_co;
 
    if( call->function == k_ent_function_particle_spawn )
-   {
       v3_copy( call->data, sound_co );
-   }
    else if( call->function == k_ent_function_trigger )
-   {
       v3_copy( audio->transform.co, sound_co );
-   }
    else
       return k_entity_call_result_unhandled;
 
@@ -443,14 +433,15 @@ void entity_bh_expand_bound( void *user, boxf bound, u32 item_index )
        type  = mdl_entity_id_type( id ),
        index = mdl_entity_id_id( id );
 
-   if( type == k_ent_gate ){
+   if( type == k_ent_gate )
+   {
       ent_gate *gate = af_arritm( &world->ent_gate, index );
       boxf box = {{ -gate->dimensions[0], -gate->dimensions[1], -0.1f },
                   {  gate->dimensions[0],  gate->dimensions[1],  0.1f }};
-
       m4x3_expand_aabb_aabb( gate->to_world, bound, box );
    }
-   else if( type == k_ent_objective ){
+   else if( type == k_ent_objective )
+   {
       ent_objective *objective = af_arritm( &world->ent_objective, index );
       
       /* TODO: This might be more work than necessary. could maybe just get
@@ -469,30 +460,29 @@ void entity_bh_expand_bound( void *user, boxf bound, u32 item_index )
       mdl_transform_m4x3( &objective->transform, transform );
       m4x3_expand_aabb_aabb( transform, bound, box );
    }
-   else if( type == k_ent_volume ){
+   else if( type == k_ent_volume )
+   {
       ent_volume *volume = af_arritm( &world->ent_volume, index );
-      m4x3_expand_aabb_aabb( volume->to_world, bound,
-                              (boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}} );
+      m4x3_expand_aabb_aabb( volume->to_world, bound, (boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}} );
    }
-   else if( type == k_ent_challenge ){
+   else if( type == k_ent_challenge )
+   {
       ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
-
       boxf box = {{-1.2f*0.5f,-0.72f*0.5f,-0.01f*0.5f},
                   { 1.2f*0.5f, 0.72f*0.5f, 0.01f*0.5f}};
       m4x3f transform;
       mdl_transform_m4x3( &challenge->transform, transform );
       m4x3_expand_aabb_aabb( transform, bound, box );
    }
-   else if( type == k_ent_glider ){
+   else if( type == k_ent_glider )
+   {
       ent_glider *glider = af_arritm( &world->ent_glider, index );
       m4x3f transform;
       mdl_transform_m4x3( &glider->transform, transform );
-      m4x3_expand_aabb_aabb( transform, bound,
-                            (boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}} );
+      m4x3_expand_aabb_aabb( transform, bound, (boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}} );
    }
-   else{
+   else
       vg_fatal_error( "Programming error\n" );
-   }
 }
 
 float entity_bh_centroid( void *user, u32 item_index, int axis )
@@ -503,15 +493,18 @@ float entity_bh_centroid( void *user, u32 item_index, int axis )
        type  = mdl_entity_id_type( id ),
        index = mdl_entity_id_id( id );
 
-   if( type == k_ent_gate ){
+   if( type == k_ent_gate )
+   {
       ent_gate *gate = af_arritm( &world->ent_gate, index );
       return gate->to_world[3][axis];
    }
-   else if( type == k_ent_objective ){
+   else if( type == k_ent_objective )
+   {
       ent_objective *objective = af_arritm( &world->ent_objective, index );
       return objective->transform.co[axis];
    }
-   else if( type == k_ent_volume ){
+   else if( type == k_ent_volume )
+   {
       ent_volume *volume = af_arritm( &world->ent_volume, index );
       return volume->transform.co[axis];
    }
@@ -535,7 +528,6 @@ float entity_bh_centroid( void *user, u32 item_index, int axis )
 void entity_bh_swap( void *user, u32 ia, u32 ib )
 {
    world_instance *world = user;
-
    u32 a = world->entity_list[ ia ],
        b = world->entity_list[ ib ];
 
@@ -543,20 +535,22 @@ void entity_bh_swap( void *user, u32 ia, u32 ib )
    world->entity_list[ ib ] = a;
 }
 
-void entity_bh_debug( void *user, u32 item_index ){
+void entity_bh_debug( void *user, u32 item_index )
+{
    world_instance *world = user;
-
    u32 id    = world->entity_list[ item_index ],
        type  = mdl_entity_id_type( id ),
        index = mdl_entity_id_id( id );
 
-   if( type == k_ent_gate ){
+   if( type == k_ent_gate )
+   {
       ent_gate *gate = af_arritm( &world->ent_gate, index );
       boxf box = {{ -gate->dimensions[0], -gate->dimensions[1], -0.1f },
                   {  gate->dimensions[0],  gate->dimensions[1],  0.1f }};
       vg_line_boxf_transformed( gate->to_world, box, 0xf000ff00 );
    }
-   else if( type == k_ent_objective ){
+   else if( type == k_ent_objective )
+   {
       ent_objective *objective = af_arritm( &world->ent_objective, index );
       boxf box;
       box_init_inf( box );
@@ -571,24 +565,22 @@ void entity_bh_debug( void *user, u32 item_index ){
       mdl_transform_m4x3( &objective->transform, transform );
       vg_line_boxf_transformed( transform, box, 0xf000ff00 );
    }
-   else if( type == k_ent_volume ){
+   else if( type == k_ent_volume )
+   {
       ent_volume *volume = af_arritm( &world->ent_volume, index );
-      vg_line_boxf_transformed( volume->to_world,
-                                (boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}},
-                                0xf000ff00 );
+      vg_line_boxf_transformed( volume->to_world, (boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}}, 0xf000ff00 );
    }
-   else if( type == k_ent_challenge ){
+   else if( type == k_ent_challenge )
+   {
       ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
-
       boxf box = {{-1.2f*0.5f,-0.72f*0.5f,-0.01f*0.5f},
                   { 1.2f*0.5f, 0.72f*0.5f, 0.01f*0.5f}};
       m4x3f transform;
       mdl_transform_m4x3( &challenge->transform, transform );
       vg_line_boxf_transformed( transform, box, 0xf0ff0000 );
    }
-   else{
+   else
       vg_fatal_error( "Programming error\n" );
-   }
 }
 
 void update_ach_models(void)
@@ -607,25 +599,28 @@ void entity_bh_closest( void *user, u32 item_index, v3f point, v3f closest )
        type  = mdl_entity_id_type( id ),
        index = mdl_entity_id_id( id );
 
-   if( type == k_ent_gate ){
+   if( type == k_ent_gate )
+   {
       ent_gate *gate = af_arritm( &world->ent_gate, index );
       v3_copy( gate->to_world[3], closest );
    }
-   else if( type == k_ent_objective ){
+   else if( type == k_ent_objective )
+   {
       ent_objective *challenge = af_arritm( &world->ent_objective, index );
       v3_copy( challenge->transform.co, closest );
    }
-   else if( type == k_ent_volume ){
+   else if( type == k_ent_volume )
+   {
       ent_volume *volume = af_arritm( &world->ent_volume, index );
       v3_copy( volume->to_world[3], closest );
    }
-   else if( type == k_ent_challenge ){
+   else if( type == k_ent_challenge )
+   {
       ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
       v3_copy( challenge->transform.co, closest );
    }
-   else{
+   else
       vg_fatal_error( "Programming error\n" );
-   }
 }
 
 void world_entity_start( world_instance *world, vg_msg *sav )
@@ -658,67 +653,55 @@ void world_entity_start( world_instance *world, vg_msg *sav )
       vg_msg_getkvintg( sav, alias, k_vg_msg_u32, &result, NULL );
 
       if( result )
-      {
-         ent_call call;
-         call.data = NULL;
-         call.function = 0;
-         call.id = mdl_entity_id( k_ent_challenge, i );
-         entity_call( world, &call );
-      }
+         _ent_challenge_complete( challenge );
    }
 
    vg_msg routes_block = *sav;
-   if( vg_msg_seekframe( &routes_block, "routes" ) ){
-      for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+   if( vg_msg_seekframe( &routes_block, "routes" ) )
+   {
+      for( u32 i=0; i<af_arrcount(&world->ent_route); i++ )
+      {
          ent_route *route = af_arritm( &world->ent_route, i );
-
          vg_msg route_info = routes_block;
-         if( vg_msg_seekframe( &route_info, 
-                               af_str(&world->meta.af,route->pstr_name) ) )
+         if( vg_msg_seekframe( &route_info, af_str(&world->meta.af,route->pstr_name) ) )
          {
-
             u32 flags;
-            vg_msg_getkvintg( &route_info, "flags", k_vg_msg_u32,    
-                              &flags, NULL );
+            vg_msg_getkvintg( &route_info, "flags", k_vg_msg_u32, &flags, NULL );
             route->flags |= flags;
 
-            vg_msg_getkvintg( &route_info, "best_laptime", k_vg_msg_f64,
-                              &route->best_laptime, NULL );
+            vg_msg_getkvintg( &route_info, "best_laptime", k_vg_msg_f64, &route->best_laptime, NULL );
 
             f32 sections[ route->checkpoints_count ];
             vg_msg_cmd cmd;
-            if( vg_msg_getkvcmd( &route_info, "sections", &cmd ) ){
-               vg_msg_cast( cmd.value, cmd.code, sections,
-                            k_vg_msg_f32 |
-                            vg_msg_count_bits(route->checkpoints_count) );
+            if( vg_msg_getkvcmd( &route_info, "sections", &cmd ) )
+            {
+               vg_msg_cast( cmd.value, cmd.code, sections, k_vg_msg_f32 | vg_msg_count_bits(route->checkpoints_count) );
             }
-            else{
+            else
+            {
                for( u32 j=0; j<route->checkpoints_count; j ++ )
                   sections[j] = 0.0f;
             }
 
-            for( u32 j=0; j<route->checkpoints_count; j ++ ){
-               ent_checkpoint *cp = af_arritm( &world->ent_checkpoint,
-                     route->checkpoints_start + j );
-
+            for( u32 j=0; j<route->checkpoints_count; j ++ )
+            {
+               ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, route->checkpoints_start + j );
                cp->best_time = sections[j];
             }
 
             /* LEGACY: check if steam achievements can give us a medal */
-            if( steam_ready && steam_stats_ready ){
-               for( u32 j=0; j<VG_ARRAY_LEN(track_infos); j ++ ){
+            if( steam_ready && steam_stats_ready )
+            {
+               for( u32 j=0; j<VG_ARRAY_LEN(track_infos); j ++ )
+               {
                   struct track_info *inf = &track_infos[j];
-                  if( !strcmp(inf->name,
-                              af_str(&world->meta.af,route->pstr_name)))
+                  if( !strcmp( inf->name, af_str(&world->meta.af,route->pstr_name)))
                   {
-                     
                      steamapi_bool set = 0;
-                     if( SteamAPI_ISteamUserStats_GetAchievement( 
-                              hSteamUserStats, inf->achievement_id, &set ) )
+                     if( SteamAPI_ISteamUserStats_GetAchievement( hSteamUserStats, inf->achievement_id, &set ) )
                      {
-                        if( set ){
+                        if( set )
                            route->flags |= k_ent_route_flag_achieve_silver;
-                        }
                      }
                   }
                }
@@ -733,9 +716,9 @@ void world_entity_start( world_instance *world, vg_msg *sav )
 
 void world_entity_serialize( world_instance *world, vg_msg *sav )
 {
-   for( u32 i=0; i<af_arrcount(&world->ent_challenge); i++ ){
+   for( u32 i=0; i<af_arrcount(&world->ent_challenge); i++ )
+   {
       ent_challenge *challenge = af_arritm(&world->ent_challenge,i);
-
       const char *alias = af_str( &world->meta.af, challenge->pstr_alias );
       vg_msg_wkvnum( sav, alias, k_vg_msg_u32, 1, &challenge->status );
    }
@@ -743,9 +726,9 @@ void world_entity_serialize( world_instance *world, vg_msg *sav )
    if( af_arrcount(&world->ent_route) )
    {
       vg_msg_frame( sav, "routes" );
-      for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+      for( u32 i=0; i<af_arrcount(&world->ent_route); i++ )
+      {
          ent_route *route = af_arritm( &world->ent_route, i );
-         
          vg_msg_frame( sav, af_str( &world->meta.af, route->pstr_name ) );
          {
             vg_msg_wkvnum( sav, "flags", k_vg_msg_u32, 1, &route->flags );
@@ -753,10 +736,9 @@ void world_entity_serialize( world_instance *world, vg_msg *sav )
 
             f32 sections[ route->checkpoints_count ];
 
-            for( u32 j=0; j<route->checkpoints_count; j ++ ){
-               ent_checkpoint *cp = af_arritm( &world->ent_checkpoint,
-                     route->checkpoints_start + j );
-
+            for( u32 j=0; j<route->checkpoints_count; j ++ )
+            {
+               ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, route->checkpoints_start + j );
                sections[j] = cp->best_time;
             }
 
index 300816ff4153ad1ea8c7304058226e8c634ee556..b94f9f51f68c5a4de6c30146523fb2ad309960fe 100644 (file)
@@ -748,19 +748,24 @@ void world_map_gui( ui_context *ctx, ui_rect main_area, i32 mh, i32 mv, bool *al
                   {
                      ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
 
-                     vg_strnull( &str, buf, sizeof(buf) );
-                     vg_strcat( &str, af_str( &world->meta.af,challenge->pstr_alias));
-
-                     u32 flags = 0x00;
-                     if( challenge->status )
+                     if( challenge->flags & k_ent_challenge_locked ) 
+                        ui_text( ctx, r, "locked...", 1, k_ui_align_middle_left, ui_colour( ctx, k_ui_gray ) );
+                     else
                      {
-                        flags |= k_ent_route_flag_achieve_gold;
-                        flags |= k_ent_route_flag_achieve_silver;
-                        vg_strcat( &str, " \xb3\xb3" );
+                        vg_strnull( &str, buf, sizeof(buf) );
+                        vg_strcat( &str, af_str( &world->meta.af,challenge->pstr_alias));
+
+                        u32 flags = 0x00;
+                        if( challenge->status )
+                        {
+                           flags |= k_ent_route_flag_achieve_gold;
+                           flags |= k_ent_route_flag_achieve_silver;
+                           vg_strcat( &str, " \xb3\xb3" );
+                        }
+
+                        combined &= flags;
+                        ui_text( ctx, r, buf, 1, k_ui_align_middle_left, medal_colour( ctx, flags ) );
                      }
-
-                     combined &= flags;
-                     ui_text( ctx, r, buf, 1, k_ui_align_middle_left, medal_colour( ctx, flags ) );
                   }
                }
 
index 5986151caa817ba269eb9307750e97382cc8b308..a406bea3592bb80a4f7831a8811b7d8b98a3c4a8 100644 (file)
@@ -629,6 +629,9 @@ static void world_render_challenges( world_instance *world, struct world_pass *p
       u32 index = challenge_list[ i ];
       ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
 
+      if( challenge->flags & k_ent_challenge_locked )
+         continue;
+
       m4x3f mmdl;
       mdl_transform_m4x3( &challenge->transform, mmdl );
       m4x3_mul( mmdl, mlocal, mmdl );
index b9adcad01faa5e0c65a96e9bc2bb4c1fd7788c92..0abcfef83970f3d8fd3f4e5f26634bfba040376d 100644 (file)
@@ -46,8 +46,11 @@ void world_routes_clear( world_instance *world )
    _world.last_gate_hit_time = -9999.9;
 }
 
-static void world_routes_time_lap( world_instance *world, ent_route *route )
+static void world_routes_time_lap( u32 route_index )
 {
+   world_instance *world = &_world.main;
+   ent_route *route = af_arritm( &world->ent_route, route_index );
+
    const char *route_name = af_str( &world->meta.af, route->pstr_name);
    vg_info( "------- time lap %s -------\n", route_name );
 
@@ -119,6 +122,15 @@ static void world_routes_time_lap( world_instance *world, ent_route *route )
       if( clean ) route->flags |= k_ent_route_flag_achieve_gold;
       ent_region_re_eval( world );
 
+      struct ent_script_event event;
+      struct script_event_completion_changed inf = {
+         .entity_id = mdl_entity_id( k_ent_route, route_index ),
+         .completion_flags = route->flags
+      };
+      event.type = k_escript_event_completion_changed;
+      event.info = &inf;
+      ent_script_propogate_event( world, &event );
+
       /* for steam achievements. */
       if( route->anon.official_track_id != 0xffffffff )
       {
@@ -158,7 +170,6 @@ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg )
    for( u32 i=0; i<af_arrcount(&world->ent_route); i++ )
    {
       ent_route *route = af_arritm( &world->ent_route, i );
-
       u32 active_prev = route->active_checkpoint;
       route->active_checkpoint = 0xffff;
 
@@ -169,7 +180,6 @@ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg )
             for( u32 k=0; k<route->checkpoints_count; k++ )
             {
                ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, route->checkpoints_start+k );
-
                ent_gate *gk = af_arritm( &world->ent_gate, cp->gate_index );
 
                if( !(gk->flags & k_ent_gate_passive) )
@@ -178,7 +188,7 @@ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg )
                if( gk == recording_gate )
                {
                   route->active_checkpoint = k;
-                  world_routes_time_lap( world, route );
+                  world_routes_time_lap( i );
                   break;
                }
             }