From 1dde5a855e1e5aab29d9d3686b5d0aade83c19a1 Mon Sep 17 00:00:00 2001 From: hgn Date: Mon, 17 Mar 2025 12:45:55 +0000 Subject: [PATCH] new replay thing --- src/ent_challenge.c | 39 +++++ src/font.h | 1 + src/input.h | 6 +- src/menu.c | 8 +- src/player.h | 2 +- src/player_dead.c | 21 ++- src/player_ragdoll.h | 3 +- src/player_replay.c | 384 ++++++++++++++++-------------------------- src/player_replay.h | 11 +- src/player_skate.c | 22 +-- src/player_walk.c | 22 ++- src/skaterift.c | 2 +- src/skaterift.h | 1 + src/world.h | 1 + src/world_routes.c | 11 +- src/world_routes_ui.c | 2 +- src/world_water.c | 15 +- 17 files changed, 275 insertions(+), 276 deletions(-) diff --git a/src/ent_challenge.c b/src/ent_challenge.c index f5af322..50c27cb 100644 --- a/src/ent_challenge.c +++ b/src/ent_challenge.c @@ -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; + } } diff --git a/src/font.h b/src/font.h index af27a4c..43e8537 100644 --- a/src/font.h +++ b/src/font.h @@ -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 */ diff --git a/src/input.h b/src/input.h index 2eefc26..0b3d002 100644 --- a/src/input.h +++ b/src/input.h @@ -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 }, diff --git a/src/menu.c b/src/menu.c index 13ecff1..5def867 100644 --- a/src/menu.c +++ b/src/menu.c @@ -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 }; diff --git a/src/player.h b/src/player.h index caff55b..5311e7e 100644 --- a/src/player.h +++ b/src/player.h @@ -90,7 +90,7 @@ struct localplayer int immobile; bool immunity; - int rewinded_since_last_gate; + bool fell_since_last_gate; /* * Network diff --git a/src/player_dead.c b/src/player_dead.c index f416121..a431dfe 100644 --- a/src/player_dead.c +++ b/src/player_dead.c @@ -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 ); diff --git a/src/player_ragdoll.h b/src/player_ragdoll.h index 08ab5e7..3a67ee6 100644 --- a/src/player_ragdoll.h +++ b/src/player_ragdoll.h @@ -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); diff --git a/src/player_replay.c b/src/player_replay.c index e06ddfe..0094680 100644 --- a/src/player_replay.c +++ b/src/player_replay.c @@ -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 } diff --git a/src/player_replay.h b/src/player_replay.h index f84a767..c1ebf99 100644 --- a/src/player_replay.h +++ b/src/player_replay.h @@ -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); diff --git a/src/player_skate.c b/src/player_skate.c index 2eb37fa..84c5c37 100644 --- a/src/player_skate.c +++ b/src/player_skate.c @@ -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; iinfo.surface_prop; } - for( int i=0; inorm_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; } } diff --git a/src/skaterift.c b/src/skaterift.c index 3ec7873..6d419a2 100644 --- a/src/skaterift.c +++ b/src/skaterift.c @@ -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 ) diff --git a/src/skaterift.h b/src/skaterift.h index 2e60d10..e4f7a3c 100644 --- a/src/skaterift.h +++ b/src/skaterift.h @@ -27,6 +27,7 @@ struct skaterift_globals u32 achievements; int demo_mode; + i32 allow_replay_resume; const char *override_load_world; } diff --git a/src/world.h b/src/world.h index dad0421..cc329f8 100644 --- a/src/world.h +++ b/src/world.h @@ -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; diff --git a/src/world_routes.c b/src/world_routes.c index 2cca510..53d911b 100644 --- a/src/world_routes.c +++ b/src/world_routes.c @@ -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; icheckpoints_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 diff --git a/src/world_routes_ui.c b/src/world_routes_ui.c index 0dabcd5..bf4ac29 100644 --- a/src/world_routes_ui.c +++ b/src/world_routes_ui.c @@ -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; } diff --git a/src/world_water.c b/src/world_water.c index 984a370..c936740 100644 --- a/src/world_water.c +++ b/src/world_water.c @@ -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 ) -- 2.25.1