new replay thing
authorhgn <hgodden00@gmail.com>
Mon, 17 Mar 2025 12:45:55 +0000 (12:45 +0000)
committerhgn <hgodden00@gmail.com>
Mon, 17 Mar 2025 12:45:55 +0000 (12:45 +0000)
17 files changed:
src/ent_challenge.c
src/font.h
src/input.h
src/menu.c
src/player.h
src/player_dead.c
src/player_ragdoll.h
src/player_replay.c
src/player_replay.h
src/player_skate.c
src/player_walk.c
src/skaterift.c
src/skaterift.h
src/world.h
src/world_routes.c
src/world_routes_ui.c
src/world_water.c

index f5af322aeb809253a260eef941c1883f64b02e8e..50c27cb9da4afd981376dc67e7f2ed63fd17a297 100644 (file)
@@ -233,6 +233,26 @@ void ent_challenge_update(void)
          _world.challenge_state = k_challenge_state_viewing;
       }
    }
+
+   if( _world.challenge_state >= k_challenge_state_running )
+   {
+      if( button_press( k_srbind_reset ) )
+      {
+         _world.challenge_reset_timer += vg.time_delta;
+
+         if( _world.challenge_reset_timer > 1.0f )
+         {
+            srinput.state = k_input_state_resume;
+            _restart_active_challenge();
+            _world.challenge_reset_timer = 0.0f;
+            gui_helper_reset( k_gui_helper_mode_clear );
+         }
+      }
+      else
+      {
+         _world.challenge_reset_timer = 0.0f;
+      }
+   }
 }
 
 void _ent_challenge_ui( ui_context *ctx )
@@ -279,4 +299,23 @@ void _ent_challenge_ui( ui_context *ctx )
    }
 
    ctx->font = &vgf_default_small;
+
+   if( _world.challenge_reset_timer > 0.0f )
+   {
+      ui_rect box = { vg.window_x/2 - 200, vg.window_y - 200, 400, 100 };
+      ui_fill( ctx, box, ui_opacity( GUI_COL_DARK, 0.35f ) );
+      ui_outline( ctx, box, 1, GUI_COL_NORM, 0 );
+
+      ctx->font = &vgf_default_title;
+      ui_rect title = { box[0], box[1] + 16, box[2], box[3]-16 };
+      ui_text( ctx, box, "Retry?", 1, k_ui_align_center, 0 );
+
+      ui_rect bar = { box[0] + 8, (box[1] + box[3]) - (24+8), box[2] - 16, 24 };
+      ui_fill( ctx, bar, ui_opacity( GUI_COL_DARK, 0.8f ) );
+
+      ui_rect inner = { bar[0]+1, bar[1]+1, (f32)(bar[2]-2)*_world.challenge_reset_timer, bar[3]-2 };
+      ui_fill( ctx, inner, ui_colour( ctx, k_ui_yellow ) );
+
+      ctx->font = &vgf_default_small;
+   }
 }
index af27a4cdde61d8aaa42b247a525060bb02eeb9f5..43e8537035366c816e5c7cfdc1d8cde84ba98ddf 100644 (file)
@@ -17,6 +17,7 @@ enum efont_SRglyph{
    k_SRglyph_ctrl_baseline = 0x04, /* . */
    k_SRglyph_ctrl_top      = 0x05, /* . */
    k_SRglyph_ctrl_glow     = 0x06, /* glow text */
+   k_SRglyph_ctrl_clear    = 0x07, /* reset all control to default */
    k_SRglyph_mod_circle    = 0x1e, /* surround and center next charater */
    k_SRglyph_mod_square    = 0x1f, /* surround and center next character */
    k_SRglyph_ascii_min     = 0x20, /* standard ascii */
index 2eefc26712bcba9b64a6db093000e0d8c8c5061f..0b3d00218311e9dbee308601845591736822e7d7 100644 (file)
@@ -31,6 +31,7 @@ enum sr_bind
    k_srbind_replay_play,
    k_srbind_replay_freecam,
    k_srbind_replay_resume,
+   k_srbind_replay_hide_ui,
    k_srbind_world_left,
    k_srbind_world_right,
    k_srbind_home,
@@ -103,9 +104,10 @@ static vg_input_op *input_button_list[] = {
    vg_gui_visible, 1,
    vg_joy_button, SDL_CONTROLLER_BUTTON_A, vg_end
 },
-[k_srbind_replay_play]    = INPUT_BASIC( SDLK_g, SDL_CONTROLLER_BUTTON_X ),
-[k_srbind_replay_resume]  = INPUT_BASIC( SDLK_SPACE, SDL_CONTROLLER_BUTTON_A ),
+[k_srbind_replay_play]    = INPUT_BASIC( SDLK_SPACE, SDL_CONTROLLER_BUTTON_A ),
+[k_srbind_replay_resume]  = (vg_input_op[]){vg_end},//INPUT_BASIC( SDLK_SPACE, SDL_CONTROLLER_BUTTON_ ),
 [k_srbind_replay_freecam] = INPUT_BASIC( SDLK_f, SDL_CONTROLLER_BUTTON_Y ),
+[k_srbind_replay_hide_ui] = INPUT_BASIC( SDLK_h, SDL_CONTROLLER_BUTTON_X ),
 [k_srbind_sit]   = INPUT_BASIC( SDLK_z, SDL_CONTROLLER_BUTTON_B ),
 [k_srbind_lobby] = INPUT_BASIC( SDLK_TAB, SDL_CONTROLLER_BUTTON_DPAD_LEFT ),
 [k_srbind_chat ] = (vg_input_op[]){ vg_keyboard, SDLK_y, vg_end },
index 13ecff13460fe7bfe96de5ad6880a5941c8fc365..5def867e18ca67ce2d5ef6bd7ec16ae99bc97930 100644 (file)
@@ -165,8 +165,7 @@ static bool menu_slider( ui_context *ctx,
 
    ui_rect line = { box[0], box[1], t * (f32)box[2], box[3] };
    ui_fill( ctx, line, state&mask_brighter? GUI_COL_ACTIVE: GUI_COL_NORM );
-   ui_fill( ctx, (ui_rect){ box[0]+line[2], box[1], box[2]-line[2], box[3] },
-               GUI_COL_DARK );
+   ui_fill( ctx, (ui_rect){ box[0]+line[2], box[1], box[2]-line[2], box[3] }, GUI_COL_DARK );
 
    ui_outline( ctx, box, 1, state? GUI_COL_HI: GUI_COL_ACTIVE, 0 );
    ui_slider_text( ctx, box, 
@@ -928,9 +927,10 @@ void menu_gui( ui_context *ctx )
 
          ctx->font = &vgf_default_title;
 
-         if( menu_button( ctx, list, R == 2, 1, "Credits" ) )
+         if( menu_button( ctx, list, R == 2, 1, "Replay" ) )
          {
-            menu.page = k_menu_page_credits;
+            //menu.page = k_menu_page_credits;
+            skaterift_open_replay();
          }
 
          ui_rect end = { list[0], list[1]+list[3]-64, list[2], 72 };
index caff55b8a2285de22b46b1bb38768feb4644a2f5..5311e7e34c5964de1c7f3356ae1d65bfe7201605 100644 (file)
@@ -90,7 +90,7 @@ struct localplayer
 
    int immobile;
    bool immunity;
-   int rewinded_since_last_gate;
+   bool fell_since_last_gate;
 
    /* 
     * Network
index f4161211a8e2248942874dbfb6dfd14a71582e5d..a431dfe10b4b56f08d2ca7aeae3042353280ae54 100644 (file)
@@ -43,7 +43,14 @@ void player__dead_post_update(void)
    v3_zero( localplayer.rb.v );
    v3_zero( localplayer.rb.w );
 
-   if( v3_length( d->v_lpf ) < 0.5f )
+   bool only_respawn = 0;
+   if( !((_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running)) )
+   {
+      if( localplayer.drowned )
+         only_respawn = 1;
+   }
+
+   if( (v3_length( d->v_lpf ) < 0.5f) && !only_respawn )
    {
       if( player_dead.helper_getup )
          player_dead.helper_getup->greyed = 0;
@@ -76,6 +83,16 @@ void player__dead_post_update(void)
    {
       if( player_dead.helper_getup )
          player_dead.helper_getup->greyed = 1;
+
+      if( only_respawn )
+      {
+         if( button_down( k_srbind_reset ) )
+         {
+            localplayer_cmd_respawn(0,NULL);
+            srinput.state = k_input_state_resume;
+            gui_helper_reset( k_gui_helper_mode_clear );
+         }
+      }
    }
 }
 
@@ -192,6 +209,8 @@ void player__dead_transition( enum player_die_type type )
    if( localplayer.immunity )
       return;
 
+   localplayer.fell_since_last_gate = 1;
+
    localplayer.subsystem = k_player_subsystem_dead;
    copy_localplayer_to_ragdoll( &localplayer.ragdoll, type );
 
index 08ab5e75d9ff56ce37129ed4b7ed248d7c3d913e..3a67ee6b69e0ce9243b486317c95793dabd032ed 100644 (file)
@@ -54,7 +54,8 @@ struct player_ragdoll{
 enum player_die_type {
    k_player_die_type_generic,
    k_player_die_type_head,
-   k_player_die_type_feet
+   k_player_die_type_feet,
+   k_player_die_type_water
 };
 
 void player_ragdoll_init(void);
index e06ddfe63f2c3497394d4e506dfa135c22da8c1c..00946805ddccb0904cea0752c291e76af2fd1c82 100644 (file)
@@ -13,8 +13,6 @@
 struct replay_globals player_replay = 
 {
    .active_keyframe = -1,
-   .show_ui = 1,
-   .editor_mode = 0
 };
 
 void replay_clear( replay_buffer *replay )
@@ -615,17 +613,14 @@ static void skaterift_replay_resume(void)
       player_replay.resume_begin = player_replay.local.cursor;
       player_replay.resume_transition = 0.0f;
    }
-
-   gui_helper_reset( k_gui_helper_mode_clear );
 }
 
-static void skaterift_replay_update_helpers(void);
-
 void skaterift_replay_pre_update(void)
 {
-   if( skaterift.activity != k_skaterift_replay ) return;
+   if( skaterift.activity != k_skaterift_replay ) 
+      return;
 
-   bool input = player_replay.editor_mode^0x1;
+   bool input = 1;
 
    if( player_replay.replay_control == k_replay_control_resume )
    {
@@ -636,8 +631,7 @@ void skaterift_replay_pre_update(void)
       }
       else 
       {
-         vg_slewf( &player_replay.resume_transition, 1.0f, 
-                   vg.time_frame_delta * (1.0f/1.0f) );
+         vg_slewf( &player_replay.resume_transition, 1.0f, vg.time_frame_delta * (1.0f/1.0f) );
 
          if( player_replay.resume_transition >= 1.0f )
             skaterift_restore_frame( player_replay.resume_target );
@@ -654,26 +648,23 @@ void skaterift_replay_pre_update(void)
    }
    else 
    {
-      if( input && button_down( k_srbind_replay_play ) )
-         player_replay.replay_control = k_replay_control_play;
-      if( input && button_down( k_srbind_replay_freecam ) )
+      if( button_down( k_srbind_replay_play ) )
+         player_replay.replay_control ^= k_replay_control_play;
+
+      if( button_down( k_srbind_replay_freecam ) )
       {
          player_replay.use_freecam ^= 0x1;
 
          if( player_replay.use_freecam )
          {
-            replay_get_camera( &player_replay.local, 
-                               &player_replay.replay_freecam );
+            replay_get_camera( &player_replay.local, &player_replay.replay_freecam );
          }
-         skaterift_replay_update_helpers();
       }
 
-      f32 target_speed = 0.0f;
-      if( input )
-         target_speed = axis_state( k_sraxis_replay_h ) * 5.0;
+      if( button_down( k_srbind_replay_hide_ui ) )
+         player_replay.hide_ui = 1;
 
-      if( input && button_press( k_srbind_reset ) )
-         target_speed += -2.0;
+      f32 target_speed = axis_state( k_sraxis_replay_h ) * 5.0;
 
       if( fabsf(target_speed) > 0.01f )
          player_replay.replay_control = k_replay_control_scrub;
@@ -681,8 +672,7 @@ void skaterift_replay_pre_update(void)
       if( player_replay.replay_control == k_replay_control_play )
          target_speed = 1.0;
 
-      vg_slewf( &player_replay.track_velocity, target_speed, 
-                18.0f*vg.time_frame_delta );
+      vg_slewf( &player_replay.track_velocity, target_speed, 18.0f*vg.time_frame_delta );
 
       if( fabsf( player_replay.track_velocity ) > 0.0001f )
       {
@@ -693,23 +683,29 @@ void skaterift_replay_pre_update(void)
             player_replay.track_velocity = 0.0f;
       }
 
-      if( input && button_down( k_srbind_mback ) )
+      if( button_down( k_srbind_mback ) )
       {
-         if( player_replay.local.statehead )
-            skaterift_restore_frame( player_replay.local.statehead );
+         if( player_replay.hide_ui ) 
+         {
+            player_replay.hide_ui = 0;
+         }
          else
-            skaterift.activity = k_skaterift_default;
+         {
+            if( player_replay.local.statehead )
+               skaterift_restore_frame( player_replay.local.statehead );
+            else
+               skaterift.activity = k_skaterift_default;
+         }
          srinput.state = k_input_state_resume;
-         gui_helper_reset( k_gui_helper_mode_clear );
       }
 
-      if( input )
+      if( player_replay.use_freecam )
       {
-         if( player_replay.use_freecam )
-         {
-            freecam_preupdate();
-         }
-         else 
+         freecam_preupdate();
+      }
+      else 
+      {
+         if( skaterift.allow_replay_resume )
          {
             if( button_down( k_srbind_replay_resume ) )
             {
@@ -720,91 +716,18 @@ void skaterift_replay_pre_update(void)
    }
 }
 
-static void skaterift_replay_update_helpers(void)
-{
-   player_replay.helper_resume->greyed = player_replay.use_freecam;
-
-   vg_str freecam_text;
-   vg_strnull( &freecam_text, player_replay.helper_freecam->text, 
-               GUI_HELPER_TEXT_LENGTH );
-   vg_strcat( &freecam_text, 
-               player_replay.use_freecam? "Exit freecam": "Freecam" );
-}
-
-static void replay_show_helpers(void)
+void skaterift_open_replay(void)
 {
-   gui_helper_reset( k_gui_helper_mode_default );
-   vg_str text;
-
-   if( gui_new_helper( input_axis_list[k_sraxis_replay_h], &text ) )
-      vg_strcat( &text, "Scrub" );
-
-   if( (player_replay.helper_resume = gui_new_helper( 
-               input_button_list[k_srbind_replay_resume], &text )) )
-      vg_strcat( &text, "Resume" );
-   
-   if( gui_new_helper( input_button_list[k_srbind_replay_play], &text ))
-      vg_strcat( &text, "Playback" );
-
-   player_replay.helper_freecam = gui_new_helper(
-         input_button_list[k_srbind_replay_freecam], &text );
-
-   skaterift_replay_update_helpers();
-}
-
-void skaterift_replay_post_render(void)
-{
-#ifndef SR_ALLOW_REWIND_HUB
-   if( _world.active_instance != k_world_purpose_client )
-      return;
-#endif
-
-   if( (_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running) )
-   {
-      if( button_press( k_srbind_reset ) )
-      {
-         player_replay.reset_timer += vg.time_delta;
-
-         if( player_replay.reset_timer > 1.0f )
-         {
-            srinput.state = k_input_state_resume;
-            _restart_active_challenge();
-            player_replay.reset_timer = 0.0f;
-            gui_helper_reset( k_gui_helper_mode_clear );
-         }
-      }
-      else
-      {
-         player_replay.reset_timer = 0.0f;
-      }
-   }
-   else
+   skaterift.activity = k_skaterift_replay;
+   skaterift_record_frame( &player_replay.local, 1 );
+   if( player_replay.local.head )
    {
-      /* capture the current resume frame at the very last point */
-      if( button_down( k_srbind_reset ) )
-      {
-         if( _world.main.info.flags & k_world_flag_no_rewind )
-         {
-            gui_location_print_ccmd( 1, (const char *[]){ KRED "Rewind is not allowed here.." } );
-         }
-         else
-         {
-            if( skaterift.activity == k_skaterift_default )
-            {
-               localplayer.rewinded_since_last_gate = 1;
-               skaterift.activity = k_skaterift_replay;
-               skaterift_record_frame( &player_replay.local, 1 );
-               if( player_replay.local.head )
-               {
-                  player_replay.local.cursor = player_replay.local.head->time;
-                  player_replay.local.cursor_frame = player_replay.local.head;
-               }
-               player_replay.replay_control = k_replay_control_scrub;
-               replay_show_helpers();
-            }
-         }
-      }
+      player_replay.local.cursor = player_replay.local.head->time;
+      player_replay.local.cursor_frame = player_replay.local.head;
    }
+   player_replay.replay_control = k_replay_control_scrub;
+   player_replay.hide_ui = 0;
+   gui_helper_reset( k_gui_helper_mode_clear );
 }
 
 void skaterift_replay_init(void)
@@ -898,72 +821,15 @@ static void replay_fly_edit_keyframe( ui_context *ctx, replay_keyframe *kf )
 
 void skaterift_replay_imgui( ui_context *ctx )
 {
-   if( (_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running) )
-   {
-      if( player_replay.reset_timer > 0.0f )
-      {
-         ui_rect box = { vg.window_x/2 - 200, vg.window_y - 200, 400, 100 };
-         ui_fill( ctx, box, ui_opacity( GUI_COL_DARK, 0.35f ) );
-         ui_outline( ctx, box, 1, GUI_COL_NORM, 0 );
-
-         ctx->font = &vgf_default_title;
-         ui_rect title = { box[0], box[1] + 16, box[2], box[3]-16 };
-         ui_text( ctx, box, "Retry?", 1, k_ui_align_center, 0 );
-
-         ui_rect bar = { box[0] + 8, (box[1] + box[3]) - (24+8), box[2] - 16, 24 };
-         ui_fill( ctx, bar, ui_opacity( GUI_COL_DARK, 0.8f ) );
-
-         ui_rect inner = { bar[0]+1, bar[1]+1, (f32)(bar[2]-2)*player_replay.reset_timer, bar[3]-2 };
-         ui_fill( ctx, inner, ui_colour( ctx, k_ui_yellow ) );
-
-         ctx->font = &vgf_default_small;
-      }
-   }
-
-   if( skaterift.activity != k_skaterift_replay ) return;
-
-   /* extra keys for entering editor */
-   static u8 f1_key = 0;
-   u8 f1_now = vg_getkey(SDLK_F1);
-   if( f1_now && !f1_key && player_replay.show_ui )
-   {
-      player_replay.editor_mode ^= 0x1;
-
-      if( player_replay.editor_mode )
-         gui_helper_reset( k_gui_helper_mode_clear );
-      else
-         replay_show_helpers();
-   }
-   f1_key = f1_now;
-
-   static u8 f2_key = 0;
-   u8 f2_now = vg_getkey(SDLK_F2);
-   if( f2_now && !f2_key )
-   {
-      player_replay.show_ui ^= 0x1;
-   }
-   f2_key = f2_now;
-
-   if( player_replay.editor_mode )
-   {
-      static u8 space_key = 0;
-      u8 space_now = vg_getkey(SDLK_SPACE);
-      if( space_now & !space_key )
-      {
-         player_replay.replay_control ^= k_replay_control_play;
-      }
-      space_key = space_now;
-   }
+   if( skaterift.activity != k_skaterift_replay ) 
+      return;
 
-   if( !player_replay.show_ui ) return;
+   if( player_replay.hide_ui ) 
+      return;
 
-   if( player_replay.editor_mode )
+   if( vg_input.display_input_method != k_input_method_controller )
    {
-      u32 colour = ui_opacity( ui_colour(ctx,k_ui_fg), 0.3333f );
-      ui_rect cx = { vg.window_x/2, 0, 1, vg.window_y },
-              cy = { 0, vg.window_y/2, vg.window_x, 1 };
-      ui_fill( ctx, cx, colour );
-      ui_fill( ctx, cy, colour );
+      ui_capture_mouse( ctx, 1 );
    }
 
    replay_buffer *replay = &player_replay.local;
@@ -977,9 +843,16 @@ void skaterift_replay_imgui( ui_context *ctx )
    char buffer[ 128 ];
 
    /* mainbar */
-   ui_px height = 32,
-         cwidth = 2;
-   ui_rect timeline = { 0, 0, vg.window_x, height };
+   ui_rect timeline = { 8, vg.window_y-(32+8), vg.window_x-16, 32 };
+   ui_rect start_box;
+   ui_split( timeline, k_ui_axis_v, 32, 8, start_box, timeline );
+
+   const char *start_text = (player_replay.replay_control == k_replay_control_play)? "||": ">";
+   if( menu_button_rect( ctx, start_box, 0, 1, start_text ) )
+   {
+      player_replay.replay_control ^= k_replay_control_play;
+   }
+
    ui_fill( ctx, timeline, ui_colour( ctx, k_ui_bg ) );
 
    /* cursor frame block */
@@ -989,56 +862,114 @@ void skaterift_replay_imgui( ui_context *ctx )
       {
          f64 l = (replay->cursor_frame->r->time-replay->cursor_frame->time)/len,
              s = (replay->cursor_frame->time - start) / len;
-         ui_rect box = { s*(f64)vg.window_x, 0
-                         VG_MAX(4,(ui_px)(l*vg.window_x)), timeline[3]+2 };
+         ui_rect box = { timeline[0] + s*(f64)timeline[2], timeline[1]
+                         VG_MAX(4,(ui_px)(l*timeline[2])), timeline[3]+2 };
          ui_fill( ctx, box, ui_colour( ctx, k_ui_bg+4 ) );
       }
    }
 
    /* cursor */
-   ui_rect cusor = { cur * (f64)vg.window_x - (cwidth/2), 0
-                     cwidth, (player_replay.editor_mode? 0: 16) + timeline[3] };
+   ui_rect cusor = { timeline[0] + cur*(f64)timeline[2] - 1, timeline[1]
+                     2, timeline[3] };
    ui_fill( ctx, cusor, ui_colour( ctx, k_ui_bg+7 ) );
 
    /* latest state marker */
-   if( replay->statehead )
+   if( skaterift.allow_replay_resume )
    {
-      f64 t = (replay->statehead->time - start) / len;
-      ui_rect tag = { t*(f64)vg.window_x, 0, 2, timeline[3]+8 };
-      ui_fill( ctx, tag, ui_colour( ctx, k_ui_green+k_ui_brighter ) );
-   }
+      if( replay->statehead )
+      {
+         f64 t = (replay->statehead->time - start) / len;
+         ui_rect tag = { timeline[0] + t*(f64)timeline[2], timeline[1], 
+                         2, timeline[3]+8 };
+         ui_fill( ctx, tag, ui_colour( ctx, k_ui_green+k_ui_brighter ) );
+      }
 
-   /* previous state marker */
-   replay_frame *prev = replay_find_recent_stateframe( replay );
-   if( prev )
-   {
-      f64 t = (prev->time - start) / len;
-      ui_rect tag = { t*(f64)vg.window_x, 0, 2, timeline[3]+8 };
-      ui_fill( ctx, tag, ui_colour( ctx, k_ui_yellow+k_ui_brighter ) );
+      /* previous state marker */
+      replay_frame *prev = replay_find_recent_stateframe( replay );
+      if( prev )
+      {
+         f64 t = (prev->time - start) / len;
+         ui_rect tag = { timeline[0] + t*(f64)timeline[2], timeline[1], 
+                         2, timeline[3]+8 };
+         ui_fill( ctx, tag, ui_colour( ctx, k_ui_yellow+k_ui_brighter ) );
+      }
    }
 
-   snprintf( buffer, 128, "-%.2fs (F1: Edit replay)", (end-replay->cursor) );
+   snprintf( buffer, 128, "-%.2fs", (end-replay->cursor) );
    ui_text( ctx, timeline, buffer, 1, k_ui_align_middle_left, 0 );
    ui_text( ctx, timeline, "0s", 1, k_ui_align_middle_right, 0 );
 
-   if( !player_replay.editor_mode ) return;
-   ui_capture_mouse( ctx, 1 );
 
-   ui_rect panel = { 0, timeline[3] + 20, 200, 400 };
-   ui_fill( ctx, panel, ui_opacity( ui_colour( ctx, k_ui_bg ), 0.5f ) );
-   ui_rect_pad( panel, (ui_px[2]){4,4} );
+   /* helpers */
+   ctx->font = &vgf_default_large;
+
+   ui_rect helper_list_l = { 10, timeline[1] - (ctx->font->sy+8), vg.window_x/2, ctx->font->sy };
+   char buf[256];
+   vg_str str;
+   vg_strnull( &str, buf, sizeof(buf) );
+   vg_input_string( &str, input_axis_list[k_sraxis_replay_h], 1 );
+   vg_strcat( &str, "\x07 Scrub" );
+   ui_text( ctx, helper_list_l, buf, 1, k_ui_align_left, 0 );
+   helper_list_l[1] -= helper_list_l[3]+2;
+
+   vg_strnull( &str, buf, sizeof(buf) );
+   vg_input_string( &str, input_button_list[k_srbind_replay_play], 1 );
+   vg_strcat( &str, (player_replay.replay_control == k_replay_control_play)? "\x07 Pause": "\x07 Play" );
+   ui_text( ctx, helper_list_l, buf, 1, k_ui_align_left, 0 );
+   helper_list_l[1] -= helper_list_l[3]+2;
+
+   vg_strnull( &str, buf, sizeof(buf) );
+   vg_input_string( &str, input_button_list[k_srbind_replay_freecam], 1 );
+   vg_strcat( &str, "\x07 Freecam" );
+   ui_text( ctx, helper_list_l, buf, 1, k_ui_align_left, 0 );
+   helper_list_l[1] -= helper_list_l[3]+2;
+
+   vg_strnull( &str, buf, sizeof(buf) );
+   vg_input_string( &str, input_button_list[k_srbind_replay_hide_ui], 1 );
+   vg_strcat( &str, "\x07 Hide UI" );
+   ui_text( ctx, helper_list_l, buf, 1, k_ui_align_left, 0 );
+   helper_list_l[1] -= helper_list_l[3]+2;
+
+   ui_rect helper_list_r = { vg.window_x/2, timeline[1] - (ctx->font->sy+8), vg.window_x/2-10, ctx->font->sy };
+   vg_strnull( &str, buf, sizeof(buf) );
+   vg_input_string( &str, input_button_list[k_srbind_mback], 1 );
+   vg_strcat( &str, "\x07 Exit Replay" );
+   ui_text( ctx, helper_list_r, buf, 1, k_ui_align_right, 0 );
+   helper_list_l[1] -= helper_list_r[3]+2;
+
+   if( player_replay.use_freecam )
+   {
+      ui_rect box = { vg.window_x/2 - 200, 40, 400, ctx->font->sy };
+      ui_text( ctx, box, KYEL "\x06\x02--- Freecam Enabled ---", 1, k_ui_align_center, 0 );
+   }
+
+   ctx->font = &vgf_default_small;
+
+   /* timeline scrub */
+   bool start_in_timeline = 
+      ui_clicking(ctx, UI_MOUSE_LEFT) && 
+      ui_inside_rect(timeline, ctx->mouse_click);
 
-   if( ui_button( ctx, panel, 
-            (player_replay.replay_control == k_replay_control_play)? 
-               "Pause (space)": "Play (space)" ) == k_ui_button_click )
+   if( (ui_inside_rect( timeline, ctx->mouse )) || start_in_timeline )
    {
-      player_replay.replay_control ^= k_replay_control_play;
+      ui_rect cursor = { ctx->mouse[0], timeline[1], 4, timeline[3] };
+      ui_fill( ctx, cursor, ui_colour( ctx, k_ui_fg ) );
+      ctx->cursor = k_ui_cursor_ibeam;
+
+      if( ui_clicking( ctx, UI_MOUSE_LEFT ) && start_in_timeline )
+      {
+         f64 mouse_t = start + ((f64)(ctx->mouse[0]-timeline[0]) / (f64)timeline[2])*len;
+         replay_seek( &player_replay.local, mouse_t );
+         player_replay.active_keyframe = -1;
+      }
    }
 
+
+   /* This contains the UI for the old removed keyframe editor --------------------------------------- */
+#if 0
    /* script bar */
-   ui_rect script = { 0, height + 2, vg.window_x, 16 };
+   ui_rect script = { timeline[0], timeline[1]+timeline[3] + 2, timeline[2], 16 };
    ui_fill( ctx, script, ui_colour( ctx, k_ui_bg ) );
-   f64 mouse_t = start + ((f64)ctx->mouse[0] / (f64)vg.window_x)*len;
 
    /* keyframe draw and select */
    bool absorb_by_keyframe = 0;
@@ -1048,7 +979,7 @@ void skaterift_replay_imgui( ui_context *ctx )
       replay_keyframe *kf = &player_replay.keyframes[i];
       f64 t = (kf->time-start)/len;
 
-      ui_px x = t*(f64)vg.window_x-8;
+      ui_px x = timeline[0] + t*(f64)timeline[2]-8;
 
       /* draw connections between keyframes */
       if( i )
@@ -1196,24 +1127,9 @@ void skaterift_replay_imgui( ui_context *ctx )
          }
       }
    }
+#endif
 
-   /* timeline scrub */
-   bool start_in_timeline = 
-      ui_clicking(ctx, UI_MOUSE_LEFT) && 
-      ui_inside_rect(timeline, ctx->mouse_click);
-   if( (ui_inside_rect( timeline, ctx->mouse )) || start_in_timeline )
-   {
-      ui_rect cursor = { ctx->mouse[0], timeline[1], 4, timeline[3] };
-      ui_fill( ctx, cursor, ui_colour( ctx, k_ui_fg ) );
-      ctx->cursor = k_ui_cursor_ibeam;
-
-      if( ui_clicking( ctx, UI_MOUSE_LEFT ) && start_in_timeline )
-      {
-         replay_seek( &player_replay.local, mouse_t );
-         player_replay.active_keyframe = -1;
-      }
-   }
-
+#if 0
    if( ui_button( ctx, panel, "Clear keyframes" ) == k_ui_button_click )
    {
       player_replay.keyframe_count = 0;
@@ -1221,7 +1137,7 @@ void skaterift_replay_imgui( ui_context *ctx )
 
    if( (ui_button( ctx, panel, "Hide UI (F2)" ) == k_ui_button_click) )
    {
-      player_replay.show_ui ^= 0x1;
+      player_replay.hide_ui = 1;
    }
 
    if( player_replay.active_keyframe != -1 )
@@ -1246,13 +1162,5 @@ void skaterift_replay_imgui( ui_context *ctx )
       _world.main.time = new_time;
 
    ui_info( ctx, panel, "" );
-   if( ui_button( ctx, panel, "Exit editor (F1)" ) == k_ui_button_click )
-   {
-      player_replay.editor_mode = 0;
-      replay_show_helpers();
-   }
-
-   /* TODO: Add Q/E scrub here too.
-    *       Add replay trimming 
-    */
+#endif
 }
index f84a76757ced21aff1094fea9f3d4a417edaf83e..c1ebf996f07582ab772009828f16e79680bd23f3 100644 (file)
@@ -94,7 +94,7 @@ struct replay_globals
    vg_camera replay_freecam;
 
    bool use_freecam;
-   bool show_ui;
+   bool hide_ui;
    v3f freecam_v, freecam_w;
 
    i32 editor_mode;
@@ -102,8 +102,6 @@ struct replay_globals
    replay_keyframe keyframes[32];
    u32 keyframe_count;
    i32 active_keyframe;
-
-   f32 reset_timer;
 }
 extern player_replay;
 
@@ -114,14 +112,13 @@ void replay_get_camera( replay_buffer *replay, vg_camera *cam );
 void replay_get_frame_camera( replay_frame *frame, vg_camera *cam );
 f32 replay_subframe_time( replay_buffer *replay );
 void replay_clear( replay_buffer *replay );
-void *
-replay_frame_data( replay_frame *frame, enum replay_framedata type );
+void *replay_frame_data( replay_frame *frame, enum replay_framedata type );
 
 void skaterift_replay_pre_update(void);
 void skaterift_replay_imgui( ui_context *ctx );
 void skaterift_replay_debug_info( ui_context *ctx );
-void skaterift_record_frame( replay_buffer *replay, 
-                                    int force_gamestate );
+void skaterift_record_frame( replay_buffer *replay, int force_gamestate );
 void skaterift_replay_post_render(void);
 void skaterift_replay_init(void);
 void skaterift_get_replay_cam( vg_camera *cam );
+void skaterift_open_replay(void);
index 2eb37fab08e866d7fd8f964cb0d23a78ac0b8500..84c5c3756a425fa4a481a0fea72e3321b8b18ec5 100644 (file)
@@ -2760,8 +2760,10 @@ begin_collision:;
     */
 
    f32 nforce = v3_length(normal_total);
-   if( nforce > 4.0f ){
-      if( nforce > 17.6f ){
+   if( nforce > 4.0f )
+   {
+      if( nforce > 17.6f )
+      {
          vg_info( "player fell off due to hitting ground too hard\n" );
          v3_muladds( localplayer.rb.v, normal_total, -1.0f, localplayer.rb.v );
          player__dead_transition( k_player_die_type_feet );
@@ -2769,17 +2771,16 @@ begin_collision:;
       }
 
       f32 amt = k_cam_punch;
-      if( localplayer.cam_control.camera_mode == k_cam_firstperson ){
+      if( localplayer.cam_control.camera_mode == k_cam_firstperson )
          amt *= 0.25f;
-      }
 
-      v3_muladds( localplayer.cam_land_punch_v, normal_total, amt,
-                  localplayer.cam_land_punch_v );
+      v3_muladds( localplayer.cam_land_punch_v, normal_total, amt, localplayer.cam_land_punch_v );
    }
 
    player_skate.surface = k_surface_prop_concrete;
 
-   for( int i=0; i<manifold_len; i++ ){
+   for( int i=0; i<manifold_len; i++ )
+   {
       rb_ct *ct = &manifold[i];
       struct world_surface *surf = world_contact_surface( world, ct );
 
@@ -2787,13 +2788,12 @@ begin_collision:;
          player_skate.surface = surf->info.surface_prop;
    }
 
-   for( int i=0; i<k_wheel_count; i++ ){
+   for( int i=0; i<k_wheel_count; i++ )
+   {
       m4x3f mtx;
       m3x3_copy( localplayer.rb.to_world, mtx );
       m4x3_mulv( localplayer.rb.to_world, wheels[i].pos, mtx[3] );
-      vg_line_sphere( mtx, wheels[i].radius,
-                      (u32[]){ VG__WHITE, VG__BLACK, 
-                            wheels[i].colour }[ wheels[i].state ]);
+      vg_line_sphere( mtx, wheels[i].radius, (u32[]){ VG__WHITE, VG__BLACK, wheels[i].colour }[ wheels[i].state ]);
    }
 
    skate_integrate();
index fe136bfe981d3a6b1de6bf5f4f3c439a17006f5d..eefacfe238cef4a8fbd8309411a215b6de2f1548 100644 (file)
@@ -630,8 +630,13 @@ static void player_walk_update_generic(void){
    /*
     * Resolve velocity constraints
     */
-   for( int j=0; j<5; j++ ){
-      for( int i=0; i<len; i++ ){
+   v3f normal_total;
+   v3_zero( normal_total );
+
+   for( int j=0; j<5; j++ )
+   {
+      for( int i=0; i<len; i++ )
+      {
          rb_ct *ct = &manifold[i];
          
          /*normal */
@@ -642,6 +647,19 @@ static void player_walk_update_generic(void){
          vn = ct->norm_impulse - temp;
 
          v3_muladds( localplayer.rb.v, ct->n, vn, localplayer.rb.v );
+         v3_muladds( normal_total, ct->n, vn, normal_total );
+      }
+   }
+
+   f32 nforce = v3_length(normal_total);
+   if( nforce > 4.0f )
+   {
+      if( nforce > 17.6f )
+      {
+         vg_info( "player fell off due to hitting ground too hard\n" );
+         v3_muladds( localplayer.rb.v, normal_total, -1.0f, localplayer.rb.v );
+         player__dead_transition( k_player_die_type_feet );
+         return;
       }
    }
 
index 3ec7873b64b145532e000f035f492ebe61aa661d..6d419a26696f52a0addb16b8b298e7fe0a67d8c4 100644 (file)
@@ -86,6 +86,7 @@ void game_load(void)
 
    vg_console_reg_cmd( "load_world", skaterift_load_world_command, NULL );
    vg_console_reg_var( "immobile", &localplayer.immobile, k_var_dtype_i32, 0 );
+   vg_console_reg_var( "allow_resume", &skaterift.allow_replay_resume, k_var_dtype_i32, VG_VAR_CHEAT );
    vg_loader_step( menu_init, NULL );
    vg_loader_step( control_overlay_init, NULL );
    vg_loader_step( world_init, NULL );
@@ -478,7 +479,6 @@ static void render_main_game(void)
       v2_zero( g_render.blur_override );
 
    postprocess_to_screen( g_render.fb_main );
-   skaterift_replay_post_render();
    cutscene_render_fadeout();
 
    if( gui.helper_count == 0 )
index 2e60d10cd440329e165d02d03c33241895d5c0c6..e4f7a3c0f3a4ad464045156efc2910ac9321d07c 100644 (file)
@@ -27,6 +27,7 @@ struct skaterift_globals
 
    u32 achievements;
    int demo_mode;
+   i32 allow_replay_resume;
 
    const char *override_load_world;
 }
index dad0421a0bc4f08c1f66a2cb8eaa1724b55be51f..cc329f885cebf6c476de622556f153fc868bd0b4 100644 (file)
@@ -281,6 +281,7 @@ struct world_static
 
    ent_objective *challenge_target;
    f32 challenge_timer; /* unused */
+   f32 challenge_reset_timer;
 
    vg_camera entity_driven_camera;
    bool entity_set_camera;
index 2cca51063ac4a43c5854abc2ffe9af0aa2fb44a2..53d911bd97952c9a40fecc008dd64e41dc95b11c 100644 (file)
@@ -56,7 +56,7 @@ static void world_routes_time_lap( world_instance *world, ent_route *route )
    ent_checkpoint *last_cp = NULL;
 
    u32 valid_sections=0;
-   int clean = !localplayer.rewinded_since_last_gate;
+   int clean = !localplayer.fell_since_last_gate;
 
    for( u32 i=0; i<route->checkpoints_count; i++ )
    {
@@ -104,9 +104,8 @@ static void world_routes_time_lap( world_instance *world, ent_route *route )
    }
    else valid_sections = 0;
 
-   vg_info( "%u %f [%s]\n", 
-            _world.current_run_version, _world.time,
-           !localplayer.rewinded_since_last_gate? "CLEAN": "     " );
+   vg_info( "%u %f [%s]\n", _world.current_run_version, _world.time, 
+                            !localplayer.fell_since_last_gate? "CLEAN": "     " );
 
    if( valid_sections==route->checkpoints_count )
    {
@@ -193,9 +192,9 @@ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg )
    recording_gate->timing_version = _world.current_run_version;
    recording_gate->timing_time = _world.time;
 
-   if( localplayer.rewinded_since_last_gate )
+   if( localplayer.fell_since_last_gate )
    {
-      localplayer.rewinded_since_last_gate = 0;
+      localplayer.fell_since_last_gate = 0;
       recording_gate->flags &= ~k_ent_gate_clean_pass;
    }
    else
index 0dabcd53f0b265466344e4b3af232cdd52cc1fcf..bf4ac296116c74de4609ec2b4e78e6ee796b6c92 100644 (file)
@@ -59,7 +59,7 @@ static void ent_route_imgui( ui_context *ctx, world_instance *world, ent_route *
    if( last_version+1 == _world.current_run_version )
    {
       struct time_block *block = &blocks[ valid_sections ++ ];
-      block->clean = localplayer.rewinded_since_last_gate? 0: 1;
+      block->clean = localplayer.fell_since_last_gate? 0: 1;
       block->length = _world.time - last_time;
       block->best = last_cp->best_time;
    }
index 984a370b8762aebc533f29cce3c51c76986a6d1f..c936740f2d24e87cf6d12936966d0ab93d4e0faf 100644 (file)
@@ -228,13 +228,26 @@ void render_water_surface( world_instance *world, vg_camera *cam )
 
 static void world_water_drown(void)
 {
+   if( localplayer.immunity )
+      return;
+
    if( localplayer.drowned ) 
       return;
 
    player__networked_sfx( k_player_subsystem_walk, 32, k_player_walk_soundeffect_splash, localplayer.rb.co, 1.0f );
    vg_info( "player fell of due to walking into walker\n" );
    localplayer.drowned = 1;
-   player__dead_transition( k_player_die_type_generic );
+   player__dead_transition( k_player_die_type_water );
+
+   if( !((_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running)) )
+   {
+      vg_str str;
+      struct gui_helper *helper;
+      if( (helper = gui_new_helper(input_button_list[k_srbind_reset], &str)) )
+      {
+         vg_strcat( &str, "Respawn" );
+      }
+   }
 }
 
 bool world_water_player_safe( world_instance *world, f32 allowance )