allow replays to pass through rifts
authorhgn <hgodden00@gmail.com>
Tue, 19 Dec 2023 06:05:54 +0000 (06:05 +0000)
committerhgn <hgodden00@gmail.com>
Tue, 19 Dec 2023 06:05:54 +0000 (06:05 +0000)
addon.c
player.c
player.h
player_common.c
player_replay.c
player_replay.h
skaterift.c

diff --git a/addon.c b/addon.c
index 91cb35050491654f72308a205f75ad39c76ac782..6f60311c52980fefdcb9c76f97bc82f8a76ded4f 100644 (file)
--- a/addon.c
+++ b/addon.c
@@ -368,7 +368,7 @@ static addon_reg *addon_mount_local_addon( const char *folder,
       if( (reg->alias.type == type) && (reg->foldername_hash == folder_hash) ){
          if( !strcmp( reg->alias.foldername, folder_name ) ){
             reg->state = k_addon_state_indexed;
-            return NULL;
+            return reg;
          }
       }
    }
index bd929a5f94973c1e9923ef09c437ca58e2242081..498b27e81c8a3561a3b3058cbeb907182d0ca6a7 100644 (file)
--- a/player.c
+++ b/player.c
@@ -128,6 +128,7 @@ static void player__post_update(void){
  */
 static void player__pass_gate( u32 id ){
    world_instance *world = world_current_instance();
+   skaterift_record_frame( &skaterift.replay, 1 );
 
    /* update boundary hash (network animation) */
    u16 index = mdl_entity_id_id(id) & ~NETMSG_BOUNDARY_MASK;
@@ -139,6 +140,7 @@ static void player__pass_gate( u32 id ){
    world_routes_fracture( world, gate, localplayer.rb.co, localplayer.rb.v );
 
    localplayer.gate_waiting = gate;
+   localplayer.deferred_frame_record = 1;
 
    struct player_cam_controller *cc = &localplayer.cam_control;
    m4x3_mulv( gate->transport, cc->tpv_lpf, cc->tpv_lpf );
@@ -157,9 +159,12 @@ static void player__pass_gate( u32 id ){
 
       world_static.active_instance = gate->target;
       player__clean_refs();
+
+      replay_clear( &skaterift.replay );
    }
-   else 
+   else {
       world_routes_activate_entry_gate( world, gate );
+   }
    
    v3f v0;
    v3_angles_vector( localplayer.angles, v0 );
@@ -169,8 +174,6 @@ static void player__pass_gate( u32 id ){
    audio_lock();
    audio_oneshot( &audio_gate_pass, 1.0f, 0.0f );
    audio_unlock();
-
-   replay_clear( &skaterift.replay );
 }
 
 static void player_apply_transport_to_cam( m4x3f transport ){
index 3a3d0f72a7e1b70c5f5105355dbb89cb41cdea7c..8379becbff57e275eee712ae341c61f913ce2e5d 100644 (file)
--- a/player.h
+++ b/player.h
@@ -98,6 +98,8 @@ struct {
 
    v3f cam_land_punch, cam_land_punch_v;
    ent_gate *gate_waiting;
+   int deferred_frame_record;
+
    int immobile;
 
    int rewinded_since_last_gate;
index d1e8fc604aaa067766690eba1d6b5b59abff1bcb..07b1f5ade900678fbcbd8a0fa1f0f71aa86a57c2 100644 (file)
@@ -22,25 +22,41 @@ static void player_camera_portal_correction(void){
 
       f32 pol = v3_dot( localplayer.cam.pos, plane ) - plane[3];
 
-      /* check camera polarity */
-      if( (pol < 0.0f) || (pol > 5.0f) ) {
+      int cleared = (pol < 0.0f) || (pol > 5.0f);
+
+      if( cleared ){
          vg_success( "Plane cleared\n" );
-         player_apply_transport_to_cam( localplayer.gate_waiting->transport );
-         localplayer.gate_waiting = NULL;
       }
-      else{
-         /* de-transform camera and player back */
-         m4x3f inverse;
-         m4x3_invert_affine( localplayer.gate_waiting->transport, inverse );
-         m4x3_mulv( inverse, localplayer.cam.pos, localplayer.cam.pos );
 
-         v3f v0;
-         v3_angles_vector( localplayer.cam.angles, v0 );
-         m3x3_mulv( inverse, v0, v0 );
-         v3_angles( v0, localplayer.cam.angles );
+      m4x3f inverse;
+      m4x3_invert_affine( localplayer.gate_waiting->transport, inverse );
+
+      /* de-transform camera and player back */
+      v3f v0;
+      m4x3_mulv( inverse, localplayer.cam.pos, localplayer.cam.pos );
+      v3_angles_vector( localplayer.cam.angles, v0 );
+      m3x3_mulv( inverse, v0, v0 );
+      v3_angles( v0, localplayer.cam.angles );
 
-         skeleton_apply_transform( &localplayer.skeleton, inverse, 
+      skeleton_apply_transform( &localplayer.skeleton, inverse, 
+                                 localplayer.final_mtx );
+
+      /* record and re-put things again */
+      if( cleared ){
+         skaterift_record_frame( &skaterift.replay, 1 );
+         localplayer.deferred_frame_record = 1;
+
+         skeleton_apply_transform( &localplayer.skeleton, 
+                                    localplayer.gate_waiting->transport,
                                     localplayer.final_mtx );
+
+         m4x3_mulv( localplayer.gate_waiting->transport, 
+                    localplayer.cam.pos, localplayer.cam.pos );
+         v3_angles_vector( localplayer.cam.angles, v0 );
+         m3x3_mulv( localplayer.gate_waiting->transport, v0, v0 );
+         v3_angles( v0, localplayer.cam.angles );
+         player_apply_transport_to_cam( localplayer.gate_waiting->transport );
+         localplayer.gate_waiting = NULL;
       }
    }
 }
index c1bf7b4d785e4a0e00326c9a1e91e16c9716ac41..9fbbfcc6e7dd07c5ae9b2433071dd8b3154e061a 100644 (file)
@@ -176,7 +176,7 @@ static f32 replay_subframe_time( replay_buffer *replay ){
    replay_frame *next = frame->r;
    if( next ){
       f64 l = next->time - frame->time,
-          t = (replay->cursor - frame->time) / l;
+          t = (l <= (1.0/128.0))? 0.0: (replay->cursor - frame->time) / l;
       return vg_clampf( t, 0.0f, 1.0f );
    }
    else 
@@ -218,8 +218,8 @@ struct replay_rb{
    v4f q;
 };
 
-static 
-void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){
+static void skaterift_record_frame( replay_buffer *replay, 
+                                    int force_gamestate ){
    f64 delta      = 9999999.9,
        statedelta = 9999999.9;
 
@@ -302,8 +302,15 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ){
    if( localplayer.gate_waiting ){
       m4x3_mulv( localplayer.gate_waiting->transport, 
                   frame->cam_pos, frame->cam_pos );
+
+      v3f v0;
+      v3_angles_vector( localplayer.cam.angles, v0 );
+      m3x3_mulv( localplayer.gate_waiting->transport, v0, v0 );
+      v3_angles( v0, frame->cam_angles );
    }
-   v3_copy( localplayer.cam.angles, frame->cam_angles );
+   else 
+      v3_copy( localplayer.cam.angles, frame->cam_angles );
+
    frame->cam_fov = localplayer.cam.fov;
 
    /* animator */
index cd9bd849d14c1479166d736198f0bec87b77d0d9..0aa370e63d1407a9d71c3d2830b61f280b95e353 100644 (file)
@@ -41,7 +41,6 @@ struct replay_frame {
 struct replay_gamestate {
    rigidbody rb;
    v3f angles;
-
    struct player_cam_controller cam_control;
 };
 
@@ -66,5 +65,7 @@ replay_frame_data( replay_frame *frame, enum replay_framedata type );
 static void skaterift_replay_pre_update(void);
 static void skaterift_replay_imgui(void);
 static void skaterift_replay_debug_info(void);
+static void skaterift_record_frame( replay_buffer *replay, 
+                                    int force_gamestate );
 
 #endif /* PLAYER_REPLAY_H */
index 5ae3042d4742f6fcf2f30413decb672373b9c0db..ab60a3b3c4c038c8bda40ca7d39d67f3e81cae86 100644 (file)
@@ -164,6 +164,7 @@ static void skaterift_restore_state(void){
 
 static addon_reg *skaterift_mount_world_unloadable( const char *path, u32 ext ){
    addon_reg *reg = addon_mount_local_addon( path, k_addon_type_world, ".mdl" );
+   if( !reg ) vg_fatal_error( "world not found\n" );
    reg->flags |= (ADDON_REG_HIDDEN | ext);
    return reg;
 }
@@ -586,7 +587,9 @@ static void render_main_game(void){
    }
    else{
       player__animate();
-      skaterift_record_frame( &skaterift.replay, 0 );
+      skaterift_record_frame( &skaterift.replay, 
+                              localplayer.deferred_frame_record );
+      localplayer.deferred_frame_record = 0;
    }
    animate_remote_players();
    player__pre_render();