From: hgn Date: Sun, 16 Mar 2025 15:01:51 +0000 (+0000) Subject: getting up, redoing challenges, spawn directions X-Git-Url: https://skaterift.com/git/?a=commitdiff_plain;h=edac8fb2acb3431d1e17ce5f7ed198d2c8fdcafe;p=carveJwlIkooP6JGAAIwe30JlM.git getting up, redoing challenges, spawn directions --- diff --git a/content_skaterift/maps/dev_tutorial/main.mdl b/content_skaterift/maps/dev_tutorial/main.mdl index 5264be9..e456456 100644 Binary files a/content_skaterift/maps/dev_tutorial/main.mdl and b/content_skaterift/maps/dev_tutorial/main.mdl differ diff --git a/content_skaterift/maps/mp_mtzero/before.mdl b/content_skaterift/maps/mp_mtzero/before.mdl index 117556a..67de6d3 100644 Binary files a/content_skaterift/maps/mp_mtzero/before.mdl and b/content_skaterift/maps/mp_mtzero/before.mdl differ diff --git a/content_skaterift/maps/mp_mtzero/main.mdl b/content_skaterift/maps/mp_mtzero/main.mdl index 85b238f..d7c2658 100644 Binary files a/content_skaterift/maps/mp_mtzero/main.mdl and b/content_skaterift/maps/mp_mtzero/main.mdl differ diff --git a/content_skaterift/maps/mp_spawn/main.mdl b/content_skaterift/maps/mp_spawn/main.mdl index c5a0fdc..5862ad4 100644 Binary files a/content_skaterift/maps/mp_spawn/main.mdl and b/content_skaterift/maps/mp_spawn/main.mdl differ diff --git a/skaterift_blender/sr_main.py b/skaterift_blender/sr_main.py index c5b31b4..c84112c 100644 --- a/skaterift_blender/sr_main.py +++ b/skaterift_blender/sr_main.py @@ -511,7 +511,7 @@ class ent_challenge(Structure):#{ ("first_objective_id",c_uint32), ("camera_id",c_uint32), ("status",c_uint32), - ("visible_when_unlocked_id",c_uint32)] + ("reset_spawn_id",c_uint32)] sr_functions = { 0: 'win', 1: 'view', -1: 'unview' } @@ -1996,15 +1996,20 @@ class SR_OBJECT_ENT_CHALLENGE(bpy.types.PropertyGroup):#{ type=bpy.types.Object, name="Visibile when unlocked", \ poll=lambda self,obj: sr_filter_ent_type(obj,['ent_list'])) + reset_spawn: bpy.props.PointerProperty( \ + type=bpy.types.Object, name="Reset spawn", \ + poll=lambda self,obj: sr_filter_ent_type(obj,['ent_spawn'])) + + @staticmethod def sr_inspector( layout, data ): #{ layout.prop( data[0], 'alias' ) layout.prop( data[0], 'camera', text=("Camera" if not data[0].is_story else "Related Objective") ) layout.prop( data[0], 'first', text=("First Objective") ) - #layout.prop( data[0], 'visible_when_unlocked' ) + layout.prop( data[0], 'reset_spawn' ) layout.prop( data[0], 'time_limit' ) - layout.prop( data[0], 'is_story' ) + # layout.prop( data[0], 'is_story' ) SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', text="On Activate" ) SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'complete', text="On Complete" ) #} @@ -2971,6 +2976,11 @@ def cv_draw():#{ cv_draw_arrow( obj.location, data.complete.location, (0.1,0.9,0) ) if data.first: cv_draw_arrow( obj.location, data.first.location, (1,0.6,0.2) ) + if data.reset_spawn: + #{ + cv_draw_line_dotted( obj.location, data.reset_spawn.location, (0,1,0) ) + cv_draw_arrow( data.reset_spawn.location, data.reset_spawn.matrix_world @ Vector((0,3,0)), (0,1,0) ) + #} cc1 = (0.4,0.3,0.2) info_cu = Vector((1.2,0.01,0.72))*0.5 diff --git a/skaterift_blender/sr_mdl.py b/skaterift_blender/sr_mdl.py index f9ac1e3..4ea8827 100644 --- a/skaterift_blender/sr_mdl.py +++ b/skaterift_blender/sr_mdl.py @@ -898,7 +898,7 @@ def _mdl_compiler_compile_entities(): challenge.first_objective_id = sr_entity_id( obj_data.first ) challenge.camera_id = sr_entity_id( obj_data.camera ) challenge.status = 0 - #challenge.visible_when_unlocked_id = sr_entity_id( obj_data.visible_when_unlocked ) + challenge.reset_spawn_id = sr_entity_id( obj_data.reset_spawn ) sr_ent_push( challenge ) #} elif ent_type == 'ent_list': diff --git a/src/control_overlay.c b/src/control_overlay.c index c7256a9..d6963a2 100644 --- a/src/control_overlay.c +++ b/src/control_overlay.c @@ -71,6 +71,7 @@ void control_overlay_render(void) if( !control_overlay.enabled ) return; if( skaterift.activity != k_skaterift_default ) return; if( _cutscene.state != k_cutscene_state_none ) return; + if( localplayer.subsystem == k_player_subsystem_dead ) return; glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); diff --git a/src/ent_challenge.c b/src/ent_challenge.c index 8edf20d..f5af322 100644 --- a/src/ent_challenge.c +++ b/src/ent_challenge.c @@ -27,7 +27,7 @@ entity_call_result ent_challenge_call( world_instance *world, ent_call *call ) return k_entity_call_result_OK; } - if( (_world.event == k_world_event_challenge) && (_world.challenge_state == k_challenge_state_running) ) + if( (_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running) ) { return k_entity_call_result_OK; } @@ -46,7 +46,7 @@ entity_call_result ent_challenge_call( world_instance *world, ent_call *call ) gui_helper_reset( 1 ); vg_str text; if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) - vg_strcat( &text, (challenge->flags & k_ent_challenge_is_story)? "Play video": "View Challenge" ); + vg_strcat( &text, "View Challenge" ); } } } @@ -55,7 +55,7 @@ entity_call_result ent_challenge_call( world_instance *world, ent_call *call ) } else if( call->function == -1 ) /* unview() */ { - if( _world.challenge_state != k_challenge_state_running ) + if( _world.challenge_state < k_challenge_state_running ) { if( !(challenge->flags & k_ent_challenge_locked) ) { @@ -74,6 +74,66 @@ entity_call_result ent_challenge_call( world_instance *world, ent_call *call ) } } +void _restart_active_challenge(void) +{ + world_instance *world = &_world.main; + + u32 index = mdl_entity_id_id( _world.active_challenge_id ); + ent_challenge *challenge = af_arritm( &world->ent_challenge, index ); + + srinput.state = k_input_state_resume; + + u32 first_objective_index = mdl_entity_id_id( challenge->first_objective_id ); + _world.challenge_state = k_challenge_state_running; + _world.challenge_target = af_arritm( &world->ent_objective, first_objective_index ); + _world.challenge_timer = 0.0f; + + u32 next = challenge->first_objective_id; + while( mdl_entity_id_type(next) == k_ent_objective ) + { + u32 index = mdl_entity_id_id( next ); + ent_objective *objective = af_arritm(&world->ent_objective,index); + objective->flags &= ~(k_ent_objective_passed|k_ent_objective_failed); + next = objective->id_next; + v3_fill( objective->transform.s, 1.0f ); + } + vg_audio_lock(); + vg_audio_oneshot( &audio_challenge[5], 1.0f, 0.0f, 0, 0 ); + vg_audio_unlock(); + + if( challenge->reset_spawn_id ) + { + if( mdl_entity_id_type( challenge->reset_spawn_id ) == k_ent_spawn ) + { + ent_spawn *spawn = af_arritm( &world->ent_spawn, mdl_entity_id_id( challenge->reset_spawn_id ) ); + v3f fwd = {0,0,-1}, angles; + q_mulv( spawn->transform.q, fwd, fwd ); + v3_angles( fwd, angles ); + localplayer.angles[0] = angles[0]; + player__setpos( spawn->transform.co ); + v3_zero( localplayer.rb.v ); + v3_zero( localplayer.rb.w ); + + f32 l = v4_length( localplayer.rb.q ); + if( (l < 0.9f) || (l > 1.1f) ) + q_identity( localplayer.rb.q ); + + rb_update_matrices( &localplayer.rb ); + + localplayer.subsystem = k_player_subsystem_walk; + player__walk_reset(); + + localplayer.immobile = 0; + localplayer.gate_waiting = NULL; + localplayer.have_glider = 0; + localplayer.glider_orphan = 0; + localplayer.drowned = 0; + + v3_copy( localplayer.rb.co, localplayer.cam_control.tpv_lpf ); + } + } +} + void ent_challenge_update(void) { world_instance *world = &_world.main; @@ -99,24 +159,8 @@ void ent_challenge_update(void) _world.challenge_state = k_challenge_state_running; localplayer.immobile = 0; /* TODO: Unify this probably after eating some potats */ menu.disable_open = 0; - srinput.state = k_input_state_resume; - u32 first_objective_index = mdl_entity_id_id( challenge->first_objective_id ); - _world.challenge_target = af_arritm( &world->ent_objective, first_objective_index ); - _world.challenge_timer = 0.0f; - - u32 next = challenge->first_objective_id; - while( mdl_entity_id_type(next) == k_ent_objective ) - { - u32 index = mdl_entity_id_id( next ); - ent_objective *objective = af_arritm(&world->ent_objective,index); - objective->flags &= ~k_ent_objective_passed; - next = objective->id_next; - v3_fill( objective->transform.s, 1.0f ); - } - vg_audio_lock(); - vg_audio_oneshot( &audio_challenge[5], 1.0f, 0.0f, 0, 0 ); - vg_audio_unlock(); + _restart_active_challenge(); if( challenge->on_activate_id ) { @@ -167,51 +211,26 @@ void ent_challenge_update(void) vg_audio_oneshot_3d( &audio_challenge[6], localplayer.rb.co, 30.0f, 1.0f, 0, 0 ); vg_audio_unlock(); vg_info( "Challenge expired due to player being out of range.\n" ); + gui_helper_reset( k_gui_helper_mode_clear ); } } } else if( _world.challenge_state == k_challenge_state_none ) { - if( challenge->flags & k_ent_challenge_is_story ) + if( button_down( k_srbind_maccept ) ) { - if( button_down( k_srbind_maccept ) ) - { - if( challenge->on_activate_id ) - { - srinput.state = k_input_state_resume; - gui_helper_reset( k_gui_helper_mode_clear ); - ent_call call; - call.data = NULL; - call.function = challenge->on_activate_event; - call.id = challenge->on_activate_id; - entity_call( &_world.main, &call ); + srinput.state = k_input_state_resume; + gui_helper_reset( k_gui_helper_mode_clear ); + vg_str text; + if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) + vg_strcat( &text, "Start" ); + if( gui_new_helper( input_button_list[k_srbind_mback], &text )) + vg_strcat( &text, "Exit" ); - if( world_clear_event( k_world_event_challenge ) ) - { - _world.challenge_state = k_challenge_state_none; - _world.active_challenge_id = 0; - gui_helper_reset( k_gui_helper_mode_clear ); - } - } - } - } - else - { - if( button_down( k_srbind_maccept ) ) - { - srinput.state = k_input_state_resume; - gui_helper_reset( k_gui_helper_mode_clear ); - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) - vg_strcat( &text, "Start" ); - if( gui_new_helper( input_button_list[k_srbind_mback], &text )) - vg_strcat( &text, "Exit" ); - - localplayer.immobile = 1; - menu.disable_open = 1; - srinput.state = k_input_state_resume; - _world.challenge_state = k_challenge_state_viewing; - } + localplayer.immobile = 1; + menu.disable_open = 1; + srinput.state = k_input_state_resume; + _world.challenge_state = k_challenge_state_viewing; } } } @@ -230,7 +249,7 @@ void _ent_challenge_ui( ui_context *ctx ) ui_rect description_box = { vg.window_x - (w + 8), 8, w, 32 }; ctx->font = &vgf_default_large; - if( _world.challenge_state != k_challenge_state_running ) + if( !(_world.challenge_state >= k_challenge_state_running) ) description_box[1] += 48; u32 next = challenge->first_objective_id; @@ -242,8 +261,12 @@ void _ent_challenge_ui( ui_context *ctx ) if( objective->pstr_description_ui ) { - bool passed = (objective->flags & k_ent_objective_passed)? 1: 0; - u32 colour = passed? ui_colour(ctx,k_ui_yellow): 0xffcccccc; + u32 colour = 0xffcccccc; + if( objective->flags & k_ent_objective_passed ) + colour = ui_colour(ctx,k_ui_yellow); + + if( objective->flags & k_ent_objective_failed ) + colour = ui_colour(ctx,k_ui_red); ui_fill( ctx, description_box, ui_opacity( GUI_COL_DARK, 0.36f ) ); ui_outline( ctx, description_box, 1, colour, 0 ); diff --git a/src/ent_challenge.h b/src/ent_challenge.h index 4751c11..36ae1b6 100644 --- a/src/ent_challenge.h +++ b/src/ent_challenge.h @@ -3,3 +3,4 @@ entity_call_result ent_challenge_call( world_instance *world, ent_call *call ); void _ent_challenge_ui( ui_context *ctx ); +void _restart_active_challenge(void); diff --git a/src/ent_objective.c b/src/ent_objective.c index c1750c8..5891d83 100644 --- a/src/ent_objective.c +++ b/src/ent_objective.c @@ -96,29 +96,35 @@ entity_call_result ent_objective_call( world_instance *world, ent_call *call ) if( call->function == 0 ) { - if( objective->flags & (k_ent_objective_hidden|k_ent_objective_passed)) + if( (_world.event == k_world_event_challenge) && (_world.challenge_state == k_challenge_state_running) ) { - return k_entity_call_result_OK; - } - - if( _world.challenge_target ) - { - if( (_world.challenge_target == objective) && ent_objective_check_filter( objective )) + if( objective->flags & (k_ent_objective_hidden|k_ent_objective_passed|k_ent_objective_failed)) { - ent_objective_pass( world, objective ); + return k_entity_call_result_OK; } - else - { - vg_audio_lock(); - vg_audio_oneshot_3d( &audio_challenge[6], localplayer.rb.co, 30.0f, 1.0f, 0, 0 ); - vg_audio_unlock(); - vg_error( "challenge failed, filter was not met\n" ); - if( world_clear_event( k_world_event_challenge ) ) + if( _world.challenge_target ) + { + if( (_world.challenge_target == objective) && ent_objective_check_filter( objective )) + { + ent_objective_pass( world, objective ); + } + else { - _world.active_challenge_id = 0; - _world.challenge_target = NULL; - _world.challenge_timer = 0.0f; + vg_audio_lock(); + vg_audio_oneshot_3d( &audio_challenge[6], localplayer.rb.co, 30.0f, 1.0f, 0, 0 ); + vg_audio_unlock(); + vg_error( "challenge failed, filter was not met\n" ); + objective->flags |= k_ent_objective_failed; + _world.challenge_state = k_challenge_state_fail; + + gui_helper_reset( k_gui_helper_mode_black_bars ); + vg_str str; + struct gui_helper *helper; + if( (helper = gui_new_helper(input_button_list[k_srbind_reset], &str)) ) + { + vg_strcat( &str, "Retry" ); + } } } } diff --git a/src/ent_region.c b/src/ent_region.c index 425b101..35df0b1 100644 --- a/src/ent_region.c +++ b/src/ent_region.c @@ -104,9 +104,6 @@ void ent_region_re_eval( world_instance *world ) { ent_challenge *challenge = af_arritm( &world->ent_challenge, index ); - if( challenge->flags & k_ent_challenge_is_story ) - continue; - u32 flags = 0x00; if( challenge->status ) { diff --git a/src/entity.h b/src/entity.h index fbc1c9e..ec43135 100644 --- a/src/entity.h +++ b/src/entity.h @@ -628,7 +628,8 @@ enum ent_objective_filter{ enum ent_objective_flag { k_ent_objective_hidden = 0x1, - k_ent_objective_passed = 0x2 + k_ent_objective_passed = 0x2, + k_ent_objective_failed = 0x4 }; struct ent_objective @@ -648,7 +649,7 @@ struct ent_objective enum ent_challenge_flag { k_ent_challenge_timelimit = 0x1, - k_ent_challenge_is_story = 0x2, + //k_ent_challenge_is_story = 0x2, k_ent_challenge_locked = 0x4, }; @@ -668,6 +669,7 @@ struct ent_challenge u32 camera_id; u32 status; + u32 reset_spawn_id; }; struct ent_relay { diff --git a/src/player.c b/src/player.c index b3c3f47..f4fdc17 100644 --- a/src/player.c +++ b/src/player.c @@ -34,7 +34,8 @@ struct localplayer localplayer = .q = { 0,0,0,1 }, .to_world = M4X3_IDENTITY, .to_local = M4X3_IDENTITY - } + }, + .immunity = 1 /* just for one frame */ }; struct player_subsystem_interface *player_subsystems[] = @@ -361,6 +362,11 @@ void player__reset(void) void player__spawn( ent_spawn *rp ) { + v3f fwd = {0,0,-1}, angles; + q_mulv( rp->transform.q, fwd, fwd ); + v3_angles( fwd, angles ); + localplayer.angles[0] = angles[0]; + player__setpos( rp->transform.co ); player__reset(); } diff --git a/src/player.h b/src/player.h index 6b10f65..caff55b 100644 --- a/src/player.h +++ b/src/player.h @@ -89,6 +89,7 @@ struct localplayer int deferred_frame_record; int immobile; + bool immunity; int rewinded_since_last_gate; /* diff --git a/src/player_dead.c b/src/player_dead.c index dd2b9ae..f416121 100644 --- a/src/player_dead.c +++ b/src/player_dead.c @@ -26,9 +26,9 @@ void player__dead_update(void) world_water_player_safe( world, 0.2f ); } -void player__dead_post_update(void){ - struct ragdoll_part *part = - &localplayer.ragdoll.parts[ localplayer.id_hip-1 ]; +void player__dead_post_update(void) +{ + struct ragdoll_part *part = &localplayer.ragdoll.parts[ localplayer.id_hip-1 ]; struct player_dead *d = &player_dead; v3f ext_co; @@ -43,23 +43,44 @@ void player__dead_post_update(void){ v3_zero( localplayer.rb.v ); v3_zero( localplayer.rb.w ); - if( (skaterift.activity == k_skaterift_default) && - button_down(k_srbind_dead_respawn) ){ - ent_spawn *spawn = world_find_closest_spawn( - &_world.main, localplayer.rb.co ); - - if( spawn ){ - v3_copy( spawn->transform.co, localplayer.rb.co ); - player__reset(); - srinput.state = k_input_state_resume; - } - else { - vg_error( "No spawns!\n" ); + if( v3_length( d->v_lpf ) < 0.5f ) + { + if( player_dead.helper_getup ) + player_dead.helper_getup->greyed = 0; + + if( button_down(k_srbind_skate) ) + { + localplayer.subsystem = k_player_subsystem_walk; + player__walk_transition( 0, 0.0f ); + player__walk_upright(); + + if( (_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running) ) + { + vg_audio_lock(); + vg_audio_oneshot_3d( &audio_challenge[6], localplayer.rb.co, 30.0f, 1.0f, 0, 0 ); + vg_audio_unlock(); + vg_error( "Challenge failed.\n" ); + + if( world_clear_event( k_world_event_challenge ) ) + { + _world.active_challenge_id = 0; + _world.challenge_target = NULL; + _world.challenge_timer = 0.0f; + } + } + + gui_helper_reset( k_gui_helper_mode_clear ); } } + else + { + if( player_dead.helper_getup ) + player_dead.helper_getup->greyed = 1; + } } -void player__dead_animate(void){ +void player__dead_animate(void) +{ struct player_dead *d = &player_dead; struct player_dead_animator *animator = &d->animator; struct player_ragdoll *rd = &localplayer.ragdoll; @@ -75,7 +96,8 @@ void player__dead_animate(void){ v3_copy( localplayer.rb.co, animator->transforms[0].co ); /* colliders with bones transforms */ - for( int i=0; ipart_count; i++ ){ + for( int i=0; ipart_count; i++ ) + { struct ragdoll_part *part = &rd->parts[i]; m4x3f mtx; @@ -95,10 +117,12 @@ void player__dead_animate(void){ } /* bones without colliders transforms */ - for( u32 i=1; ibone_count; i++ ){ + for( u32 i=1; ibone_count; i++ ) + { struct skeleton_bone *sb = &sk->bones[i]; - if( sb->parent && !sb->collider ){ + if( sb->parent && !sb->collider ) + { v3f delta; v3_sub( sk->bones[i].co, sk->bones[sb->parent].co, delta ); @@ -112,7 +136,8 @@ void player__dead_animate(void){ } /* measurements */ - for( u32 i=1; ibone_count; i++ ){ + for( u32 i=1; ibone_count; i++ ) + { struct skeleton_bone *sb = &sk->bones[i]; v3_zero( animator->transforms[i].co ); @@ -126,8 +151,7 @@ void player__dead_animate(void){ v3f _s; m4x3_mul( inverse, transforms[i], local ); - m4x3_decompose( local, animator->transforms[i].co, - animator->transforms[i].q, _s ); + m4x3_decompose( local, animator->transforms[i].co, animator->transforms[i].q, _s ); } } @@ -143,7 +167,8 @@ void player__dead_pose( void *_animator, player_pose *pose ) v3_copy( animator->transforms[0].co, pose->root_co ); v4_copy( animator->transforms[0].q, pose->root_q ); - for( u32 i=1; ibone_count; i++ ){ + for( u32 i=1; ibone_count; i++ ) + { v3_copy( animator->transforms[i].co, pose->keyframes[i-1].co ); v4_copy( animator->transforms[i].q, pose->keyframes[i-1].q ); v3_fill( pose->keyframes[i-1].s, 1.0f ); @@ -164,12 +189,8 @@ void player__dead_transition( enum player_die_type type ) if( localplayer.subsystem == k_player_subsystem_dead ) return; - static bool dont_ask = 1; - if( dont_ask ) - { - dont_ask = 0; + if( localplayer.immunity ) return; - } localplayer.subsystem = k_player_subsystem_dead; copy_localplayer_to_ragdoll( &localplayer.ragdoll, type ); @@ -180,21 +201,36 @@ void player__dead_transition( enum player_die_type type ) v3_copy( part->rb.w, player_dead.w_lpf ); gui_helper_reset( k_gui_helper_mode_black_bars ); + vg_str str; + if( (player_dead.helper_getup = gui_new_helper(input_button_list[k_srbind_skate], &str) )) + { + vg_strcat( &str, "Get Up" ); - struct gui_helper *h; - if( (h = gui_new_helper(input_button_list[k_srbind_reset], &str) )) - vg_strcat( &str, "Rewind" ); + if( (_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running) ) + { + vg_strcat( &str, " (Exit challenge)" ); - if( gui_new_helper(input_button_list[k_srbind_dead_respawn], &str )) - vg_strcat( &str, "Spawn" ); + struct gui_helper *helper; + if( (helper = gui_new_helper(input_button_list[k_srbind_reset], &str)) ) + { + vg_strcat( &str, "Retry" ); + } + } + + player_dead.helper_getup->greyed = 1; + } + + //if( gui_new_helper(input_button_list[k_srbind_dead_respawn], &str )) + // vg_strcat( &str, "Spawn" ); } void player__dead_animator_exchange( bitpack_ctx *ctx, void *data ) { struct player_dead_animator *animator = data; - for( u32 i=0; itransforms[i].co ); bitpack_qquat( ctx, animator->transforms[i].q ); } diff --git a/src/player_dead.h b/src/player_dead.h index b86c586..30d9a72 100644 --- a/src/player_dead.h +++ b/src/player_dead.h @@ -16,6 +16,7 @@ struct player_dead animator; skeleton_anim anim_bail; + struct gui_helper *helper_getup; } extern player_dead; extern struct player_subsystem_interface player_subsystem_dead; diff --git a/src/player_replay.c b/src/player_replay.c index f0ad6d4..e06ddfe 100644 --- a/src/player_replay.c +++ b/src/player_replay.c @@ -759,27 +759,49 @@ void skaterift_replay_post_render(void) return; #endif - /* capture the current resume frame at the very last point */ - if( button_down( k_srbind_reset ) ) + if( (_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running) ) { - if( _world.main.info.flags & k_world_flag_no_rewind ) + if( button_press( k_srbind_reset ) ) { - gui_location_print_ccmd( 1, (const char *[]){ KRED "Rewind is not allowed here.." } ); + 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 { - if( skaterift.activity == k_skaterift_default ) + player_replay.reset_timer = 0.0f; + } + } + else + { + /* 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 { - localplayer.rewinded_since_last_gate = 1; - skaterift.activity = k_skaterift_replay; - skaterift_record_frame( &player_replay.local, 1 ); - if( player_replay.local.head ) + if( skaterift.activity == k_skaterift_default ) { - player_replay.local.cursor = player_replay.local.head->time; - player_replay.local.cursor_frame = player_replay.local.head; + 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.replay_control = k_replay_control_scrub; - replay_show_helpers(); } } } @@ -876,6 +898,28 @@ 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 */ diff --git a/src/player_replay.h b/src/player_replay.h index 313b4d4..f84a767 100644 --- a/src/player_replay.h +++ b/src/player_replay.h @@ -102,6 +102,8 @@ struct replay_globals replay_keyframe keyframes[32]; u32 keyframe_count; i32 active_keyframe; + + f32 reset_timer; } extern player_replay; diff --git a/src/player_skate.c b/src/player_skate.c index fb25787..2eb37fa 100644 --- a/src/player_skate.c +++ b/src/player_skate.c @@ -1277,13 +1277,11 @@ void player__skate_pre_update(void){ v3_add( newpos, (v3f){0.0f,-1.0f,0.0f}, newpos ); v3_sub( localplayer.rb.co, newpos, offset ); v3_copy( newpos, localplayer.rb.co ); - v3_muladds( localplayer.rb.co, localplayer.rb.to_world[1], -0.1f, - localplayer.rb.co ); + v3_muladds( localplayer.rb.co, localplayer.rb.to_world[1], -0.1f, localplayer.rb.co ); player__begin_holdout( offset ); - player__walk_transition( state->activity <= k_skate_activity_air_to_grind? - 0: 1, state->trick_euler[0] ); - + player__walk_transition( state->activity <= k_skate_activity_air_to_grind? 0: 1, state->trick_euler[0] ); + player__walk_upright(); return; } diff --git a/src/player_walk.c b/src/player_walk.c index 03fe56b..fe136bf 100644 --- a/src/player_walk.c +++ b/src/player_walk.c @@ -1223,18 +1223,21 @@ void player__walk_transition( bool grounded, f32 board_yaw ){ rb_update_matrices( &localplayer.rb ); } +void player__walk_upright(void) +{ + v3f fwd = { 0.0f, 0.0f, 1.0f }; + q_mulv( localplayer.rb.q, fwd, fwd ); + q_axis_angle( localplayer.rb.q, (v3f){0.0f,1.0f,0.0f}, atan2f(fwd[0], fwd[2]) ); + rb_update_matrices( &localplayer.rb ); +} + void player__walk_reset(void) { struct player_walk *w = &player_walk; w->state.activity = k_walk_activity_air; w->state.transition_t = 0.0f; - v3f fwd = { 0.0f, 0.0f, 1.0f }; - q_mulv( localplayer.rb.q, fwd, fwd ); - q_axis_angle( localplayer.rb.q, (v3f){0.0f,1.0f,0.0f}, - atan2f(fwd[0], fwd[2]) ); - - rb_update_matrices( &localplayer.rb ); + player__walk_upright(); } void player__walk_animator_exchange( bitpack_ctx *ctx, void *data ){ diff --git a/src/player_walk.h b/src/player_walk.h index b740a8c..50c1a7c 100644 --- a/src/player_walk.h +++ b/src/player_walk.h @@ -112,3 +112,4 @@ void player__walk_restore (void); void player__walk_animator_exchange( bitpack_ctx *ctx, void *data ); void player__walk_transition( bool grounded, f32 board_yaw ); void player__walk_sfx_oneshot( u8 id, v3f pos, f32 volume ); +void player__walk_upright(void); diff --git a/src/skaterift.c b/src/skaterift.c index 7a9f745..3ec7873 100644 --- a/src/skaterift.c +++ b/src/skaterift.c @@ -247,6 +247,8 @@ void vg_post_update(void) vehicle_update_post(); skaterift_autosave_update(); + + localplayer.immunity = 0; } /* diff --git a/src/world.h b/src/world.h index 7b8a288..dad0421 100644 --- a/src/world.h +++ b/src/world.h @@ -274,7 +274,8 @@ struct world_static { k_challenge_state_none = 0, k_challenge_state_viewing, - k_challenge_state_running + k_challenge_state_running, + k_challenge_state_fail } challenge_state; diff --git a/src/world_entity.c b/src/world_entity.c index 0fa08f5..279667a 100644 --- a/src/world_entity.c +++ b/src/world_entity.c @@ -658,22 +658,16 @@ void world_entity_start( world_instance *world, vg_msg *sav ) ent_challenge *challenge = af_arritm( &world->ent_challenge, i ); const char *alias = af_str( &world->meta.af, challenge->pstr_alias ); - if( challenge->flags & k_ent_challenge_is_story ) - { - } - else - { - u32 result; - vg_msg_getkvintg( sav, alias, k_vg_msg_u32, &result, NULL ); + u32 result; + 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 ); - } + if( result ) + { + ent_call call; + call.data = NULL; + call.function = 0; + call.id = mdl_entity_id( k_ent_challenge, i ); + entity_call( world, &call ); } } diff --git a/src/world_map.c b/src/world_map.c index d8ee256..2a89476 100644 --- a/src/world_map.c +++ b/src/world_map.c @@ -638,8 +638,6 @@ void world_map_gui( ui_context *ctx, ui_rect main_area, i32 mh, i32 mv, bool *al else if( type == k_ent_challenge ) { ent_challenge *challenge = af_arritm( &world->ent_challenge, index ); - if( challenge->flags & k_ent_challenge_is_story ) - continue; vg_strnull( &str, buf, sizeof(buf) ); vg_strcat( &str, af_str( &world->meta.af,challenge->pstr_alias)); diff --git a/src/world_render.c b/src/world_render.c index f9d395b..44fa862 100644 --- a/src/world_render.c +++ b/src/world_render.c @@ -506,7 +506,7 @@ static void world_render_challenges( world_instance *world, struct world_pass *p u32 objective_count = 0, challenge_count = 0; - if( (_world.event == k_world_event_challenge) && (_world.challenge_state == k_challenge_state_running) ) + if( (_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running) ) { u32 challenge_index = mdl_entity_id_id( _world.active_challenge_id ); ent_challenge *challenge = af_arritm( &world->ent_challenge, challenge_index ); @@ -563,7 +563,7 @@ static void world_render_challenges( world_instance *world, struct world_pass *p f32 scale = 1.0f; if( (_world.event == k_world_event_challenge) && - (_world.challenge_state == k_challenge_state_running || _world.challenge_state == k_challenge_state_viewing) ) + (_world.challenge_state >= k_challenge_state_running || _world.challenge_state == k_challenge_state_viewing) ) { u32 passed = objective->flags & k_ent_objective_passed; f32 target = passed? 0.0f: 1.0f; @@ -611,12 +611,9 @@ static void world_render_challenges( world_instance *world, struct world_pass *p for( u32 i=0; ient_challenge); i++ ) { ent_challenge *challenge = af_arritm( &world->ent_challenge, i ); - if( !(challenge->flags & k_ent_challenge_is_story) ) - { - if( challenge->status ) - count ++; - total ++; - } + if( challenge->status ) + count ++; + total ++; } char buf[32]; @@ -638,9 +635,6 @@ 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_is_story ) - continue; - m4x3f mmdl; mdl_transform_m4x3( &challenge->transform, mmdl ); m4x3_mul( mmdl, mlocal, mmdl ); diff --git a/src/world_volumes.c b/src/world_volumes.c index d111264..d3dbcf7 100644 --- a/src/world_volumes.c +++ b/src/world_volumes.c @@ -15,7 +15,8 @@ void world_volumes_update( world_instance *world, v3f pos ) m4x3_mulv( volume->to_local, pos, local ); if( (fabsf(local[0]) <= 1.0f) && (fabsf(local[1]) <= 1.0f) && - (fabsf(local[2]) <= 1.0f) ) + (fabsf(local[2]) <= 1.0f) && + (localplayer.subsystem != k_player_subsystem_dead) ) { _world.active_trigger_volumes[ j ++ ] = idx; boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}}; @@ -111,6 +112,9 @@ void world_volumes_update( world_instance *world, v3f pos ) if( _world.active_trigger_volume_count > VG_ARRAY_LEN(_world.active_trigger_volumes) ) continue; + if( localplayer.subsystem == k_player_subsystem_dead ) + continue; + v3f local; m4x3_mulv( volume->to_local, pos, local );