add medals to miniworld display
authorhgn <hgodden00@gmail.com>
Fri, 24 Nov 2023 12:18:38 +0000 (12:18 +0000)
committerhgn <hgodden00@gmail.com>
Fri, 24 Nov 2023 12:18:38 +0000 (12:18 +0000)
12 files changed:
check_savedata.sh [new file with mode: 0755]
ent_miniworld.c
entity.h
gui.h
model.h
models_src/rs_icons.mdl
player.c
player.h
player_replay.c
save.h
world_entity.c
world_routes.c

diff --git a/check_savedata.sh b/check_savedata.sh
new file mode 100755 (executable)
index 0000000..84d551a
--- /dev/null
@@ -0,0 +1 @@
+vg/bin/msgdump bin/skaterift-clang/savedata/sr002-local-dev_hub.bkv bin/skaterift-clang/savedata/sr002-local-mp_mtzero.bkv bin/skaterift-clang/savedata/sr002-local-mp_spawn.bkv bin/skaterift-clang/savedata/sr002-steam-2986666679.bkv bin/skaterift-clang/savedata/sr002-steam-2987160007.bkv bin/skaterift-clang/savedata/sr002-steam-3006909988.bkv bin/skaterift-clang/savedata/sr002-steam-3015566387.bkv bin/skaterift-clang/savedata/sr002-steam-3017733355.bkv bin/skaterift-clang/savedata/sr002-steam-3081422037.bkv bin/skaterift-clang/save.bkv
index baee0c3cf34af6beaed44e789a871558e7f1c7c3..497e9d04f9da65652edd4e370cc26ad31c95713d 100644 (file)
@@ -114,6 +114,19 @@ static void ent_miniworld_render( world_instance *host_world, camera *cam ){
       miniworld_icon( cam, icon, challenge->transform.co, 1.0f );
    }
 
+   for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
+      ent_route *route = mdl_arritm( &dest_world->ent_route, i );
+
+      if( route->achievment_status & 0x2 ){
+         miniworld_icon( cam, k_gui_icon_rift_run_gold, 
+                         route->board_transform[3],1.0f);
+      }
+      else if( route->achievment_status & 0x1 ){
+         miniworld_icon( cam, k_gui_icon_rift_run_silver, 
+                         route->board_transform[3],1.0f);
+      }
+   }
+
    for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
       ent_route *route = mdl_arritm( &dest_world->ent_route, i );
 
index c39d22400bff0d2c710967f0259f3bef64bd1b20..3fd3508eef3358ff47766b73ef2ad11cc0dddbc0 100644 (file)
--- a/entity.h
+++ b/entity.h
@@ -118,6 +118,8 @@ enum ent_gate_flag{
    k_ent_gate_flip        = 0x4, /* flip direction 180* for exiting portal */
    k_ent_gate_custom_mesh = 0x8, /* use a custom submesh instead of default */
    k_ent_gate_locked      = 0x10,/* has to be unlocked to be useful */
+
+   k_ent_gate_clean_pass  = 0x20,/* player didn't rewind while getting here */
 };
 
 struct ent_gate{
@@ -187,6 +189,10 @@ struct ent_route{
    f64 timing_base;
 
    u32 id_camera; /* v103+ */
+
+   /* v104+, but always accessible */
+   u32 achievment_status;
+   f64 best_laptime;
 };
 
 struct ent_water{
diff --git a/gui.h b/gui.h
index f3da9a406287533432149045a14cb1f71f755a88..2d984f36082b797747a7367a532ea272590ce554 100644 (file)
--- a/gui.h
+++ b/gui.h
@@ -17,6 +17,8 @@ enum gui_icon {
    k_gui_icon_rift_run_2d,
    k_gui_icon_friend,
    k_gui_icon_player,
+   k_gui_icon_rift_run_gold,
+   k_gui_icon_rift_run_silver,
 
    k_gui_icon_count,
 };
@@ -327,6 +329,10 @@ static void gui_init(void){
    gui.icons[ k_gui_icon_rift_run_2d ] = gui_find_icon( "icon_rift_run2d" );
    gui.icons[ k_gui_icon_friend ] = gui_find_icon( "icon_friend" );
    gui.icons[ k_gui_icon_player ] = gui_find_icon( "icon_player" );
+   gui.icons[ k_gui_icon_rift_run_gold ] =
+      gui_find_icon("icon_rift_run_medal_gold");
+   gui.icons[ k_gui_icon_rift_run_silver]=
+      gui_find_icon("icon_rift_run_medal_silver");
 
    vg_linear_clear( vg_mem.scratch );
    if( !mdl_arrcount( &gui.model_icons.textures ) )
diff --git a/model.h b/model.h
index 5608becf70fb90c4621c8d0556cd23a477bffbf0..34963be69e49ef7e5d67c4c20241c24e7ef6baa0 100644 (file)
--- a/model.h
+++ b/model.h
@@ -311,6 +311,8 @@ static void mdl_load_array_file_buffer( mdl_context *mdl, mdl_array *arr,
       }
       else {
          assert( stride >= arr->item_size );
+         vg_warn( "Applying alignment fixup to array @%p [%u -> %u] x %u\n", 
+                  buffer, arr->item_size, stride, arr->item_count );
 
          for( u32 i=0; i<arr->item_count; i++ ){
             u64 l = fread( buffer+i*stride, arr->item_size, 1, mdl->file );
index 8e48c54223358472e50d294a7c25dd3927db125b..e3ee8b5d351052d3637f8ae815721cc0145691d0 100644 (file)
Binary files a/models_src/rs_icons.mdl and b/models_src/rs_icons.mdl differ
index 93cfb10d169fa3c9aef8f9224f32ee6bf3548678..07e5f306ac7f3e6163cf694f9e22bd6190cd8026 100644 (file)
--- a/player.c
+++ b/player.c
@@ -123,7 +123,7 @@ static void player__pass_gate( u32 id ){
    localplayer.boundary_hash ^= NETMSG_GATE_BOUNDARY_BIT;
    localplayer.boundary_hash &= ~NETMSG_BOUNDARY_MASK;
    localplayer.boundary_hash |= index;
-
+   
    ent_gate *gate = mdl_arritm( &world->ent_gate, mdl_entity_id_id(id) );
    world_routes_fracture( world, gate, localplayer.rb.co, localplayer.rb.v );
 
index a5ae8e89ddd55b819adffb39a2e0856e8e89ce4e..fe6d74c59795d6c89934a6f0dd540878768c73ba 100644 (file)
--- a/player.h
+++ b/player.h
@@ -97,6 +97,8 @@ struct {
    ent_gate *gate_waiting;
    int immobile;
 
+   int rewinded_since_last_gate;
+
    /* 
     * Network
     * --------------------------------------------------
index befbf0fd1efc7c873330e751a7341b05dc7d2bc1..1b339474dd593b61f95a46ce56cd2a6e56f4573f 100644 (file)
@@ -511,6 +511,7 @@ static void skaterift_replay_post_render(void){
    /* capture the current resume frame at the very last point */
    if( button_down( k_srbind_reset ) ){
       if( skaterift.activity == k_skaterift_default ){
+         localplayer.rewinded_since_last_gate = 1;
          skaterift.activity = k_skaterift_replay;
          skaterift_record_frame( &skaterift.replay, 1 );
          if( skaterift.replay.head ){
diff --git a/save.h b/save.h
index 941dd12769f659f035748c3accf9e7ff98431bd8..4074b89fd1650613b0580a10ffab14b8df0dd40d 100644 (file)
--- a/save.h
+++ b/save.h
@@ -13,7 +13,7 @@ struct savedata_group {
    u32 file_count;
    struct savedata_file {
       char path[128];
-      u8  buf[1024];
+      u8  buf[2048];
       u32 len;
    }
    files[];
index cbe7432a54aacc1e70b3cc31462d795af348e9c8..0e484ed019b2a21fd0983f23812097ca3280b3ee 100644 (file)
@@ -617,6 +617,28 @@ static void world_entity_start( world_instance *world, vg_msg *sav ){
          entity_call( world, &call );
       }
    }
+
+   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
+      ent_route *route = mdl_arritm( &world->ent_route, i );
+      route->achievment_status = 0;
+      route->best_laptime = 0.0;
+   }
+
+   vg_msg routes_block = *sav;
+   if( vg_msg_seekframe( &routes_block, "routes" ) ){
+      for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
+         ent_route *route = mdl_arritm( &world->ent_route, i );
+
+         vg_msg route_info = routes_block;
+         if( vg_msg_seekframe( &route_info, 
+                               mdl_pstr(&world->meta,route->pstr_name) ) ){
+            route->achievment_status = 
+               vg_msg_getkvu32( &route_info, "achivement_status", 0 );
+            route->best_laptime =
+               vg_msg_getkvf64( &route_info, "best_laptime", 0.0 );
+         }
+      }
+   }
 }
 
 static void world_entity_serialize( world_instance *world, vg_msg *sav ){
@@ -626,6 +648,21 @@ static void world_entity_serialize( world_instance *world, vg_msg *sav ){
       const char *alias = mdl_pstr(&world->meta,challenge->pstr_alias);
       vg_msg_wkvu32( sav, alias, challenge->status );
    }
+   
+   if( mdl_arrcount(&world->ent_route) ){
+      vg_msg_frame( sav, "routes" );
+      for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
+         ent_route *route = mdl_arritm( &world->ent_route, i );
+         
+         vg_msg_frame( sav, mdl_pstr( &world->meta, route->pstr_name ) );
+         {
+            vg_msg_wkvu32( sav, "achivement_status", route->achievment_status );
+            vg_msg_wkvf64( sav, "best_laptime", route->best_laptime );
+         }
+         vg_msg_end_frame( sav );
+      }
+      vg_msg_end_frame( sav );
+   }
 }
 
 #endif /* WORLD_ENTITY_C */
index 33d84db5cb8ff2a80ada0c8e2064634493afa3e5..48df26729b91483e61c0fd4183e4d4a8f25b4e93 100644 (file)
@@ -48,6 +48,7 @@ static void world_routes_time_lap( world_instance *world, ent_route *route )
    u32 last_version=0;
 
    u32 valid_count=0;
+   int clean = 1;
 
    for( u32 i=0; i<route->checkpoints_count; i++ ){
       u32 cpid  = (i+route->active_checkpoint) % route->checkpoints_count;
@@ -69,7 +70,12 @@ static void world_routes_time_lap( world_instance *world, ent_route *route )
       }
 
       last_version = rg->timing_version;
-      vg_info( "%u %f\n", rg->timing_version, rg->timing_time );
+
+      vg_info( "%u %f [%s]\n", rg->timing_version, rg->timing_time,
+               (rg->flags & k_ent_gate_clean_pass)? "CLEAN": "-----");
+
+      if( !(rg->flags & k_ent_gate_clean_pass) )
+         clean = 0;
    }
 
    if( world_static.current_run_version == last_version+1 ){
@@ -85,8 +91,16 @@ static void world_routes_time_lap( world_instance *world, ent_route *route )
 
    if( valid_count==route->checkpoints_count ){
       f64 lap_time = world_static.time - start_time;
-      //world_routes_local_set_record( world, route, lap_time );
 
+      if( (route->best_laptime == 0.0) || (lap_time < route->best_laptime) ){
+         route->best_laptime = lap_time;
+         route->achievment_status |= 0x1;
+
+         if( clean )
+            route->achievment_status |= 0x2;
+      }
+
+      /* for steam achievements. */
       if( route->anon.official_track_id != 0xffffffff ){
          struct track_info *ti = &track_infos[ route->anon.official_track_id ];
          if( ti->achievement_id ){
@@ -120,6 +134,13 @@ static void world_routes_activate_entry_gate( world_instance *world,
    world_static.last_use = world_static.time;
    ent_gate *dest = mdl_arritm( &world->ent_gate, rg->target );
 
+   if( localplayer.rewinded_since_last_gate ){
+      localplayer.rewinded_since_last_gate = 0;
+      dest->flags &= ~k_ent_gate_clean_pass;
+   }
+   else
+      dest->flags |= k_ent_gate_clean_pass;
+
    for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
       ent_route *route = mdl_arritm( &world->ent_route, i );