chaos pt 1
[carveJwlIkooP6JGAAIwe30JlM.git] / world_load.c
index f1308c151134830e6651509ce8bf731a847423d7..e8f545c56dff8af10b154dcb9e925d77402b87d2 100644 (file)
@@ -45,6 +45,7 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){
    mdl_load_animation_block( meta, world->heap );
    mdl_load_mesh_block( meta, world->heap );
 
+   /* TODO: Make this a table? */
    mdl_load_array( meta, &world->ent_gate,      "ent_gate",       heap );
    mdl_load_array( meta, &world->ent_camera,    "ent_camera",     heap );
    mdl_load_array( meta, &world->ent_spawn,     "ent_spawn",      heap );
@@ -66,6 +67,7 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){
    mdl_load_array( meta, &world->ent_challenge, "ent_challenge",  heap );
    mdl_load_array( meta, &world->ent_relay,     "ent_relay",      heap );
    mdl_load_array( meta, &world->ent_cubemap,   "ent_cubemap",    heap );
+   mdl_load_array( meta, &world->ent_miniworld, "ent_miniworld",  heap );
 
    mdl_array_ptr infos;
    mdl_load_array( meta, &infos, "ent_worldinfo", vg_mem.scratch );
@@ -95,6 +97,16 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){
    world_gen_compute_light_indices( world );
    mdl_close( meta );
 
+   /* init player position.
+    *   - this is overriden by the save state when(if) it loads */
+   v3_zero( world->player_angles );
+   ent_spawn *rp = world_find_spawn_by_name( world, "start" );
+   if( !rp ) rp = world_find_closest_spawn( world, (v3f){0.0f,0.0f,0.0f} );
+
+   /* TODO: fallback to searching for a safe location using raycasts */
+   assert(rp);
+   v3_copy( rp->transform.co, world->player_co );
+
    /* allocate leaderboard buffers */
    u32 bs = mdl_arrcount(&world->ent_route)*sizeof(struct leaderboard_cache);
    world->leaderboard_cache = vg_linear_alloc( heap, bs );
@@ -113,21 +125,27 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){
 
 struct world_load_complete_data{
    savedata_file save;
-   u32 instance_start, instance_count;
+   enum world_purpose purpose;
 };
 
 static void skaterift_world_load_done( void *payload, u32 size ){
    struct world_load_complete_data *data = payload;
 
+   /* TODO(W2): Load player position from this save file */
    vg_msg sav;
    vg_msg_init( &sav, data->save.buf, data->save.len );
 
-   for( u32 i=0; i<data->instance_count; i++ ){
-      world_instance *world = &world_static.instances[ data->instance_start+i ];
-      world_entity_start( world, &sav );
-   }
-
+   world_instance *world = &world_static.instances[ data->purpose ];
+   world_entity_start( world, &sav );
+   world->status = k_world_status_loaded;
    world_static.load_state = k_world_loader_none;
+
+   for( int i=0; i<k_world_max; i ++ ){
+      world_instance *wi = &world_static.instances[i];
+
+      if( wi->status == k_world_status_loaded )
+         world_entity_relink( wi );
+   }
 }
 
 struct world_load_args {
@@ -139,10 +157,15 @@ struct world_load_args {
  * Does a complete world switch using the remaining free slots
  */
 static void skaterift_world_load_thread( void *_args ){
-   struct world_load_args *args = _args;
+   /* FIXME: we need to check all threads that take args. args can dissapear! */
+   struct world_load_args args = *((struct world_load_args *)_args);
+
+   addon_reg *reg = args.reg;
+   world_static.instance_addons[ args.purpose ] = reg;
 
-   addon_reg *reg = args->reg;
-   world_static.instance_addons[ args->purpose ] = reg;
+   char uid[ADDON_UID_MAX];
+   addon_alias_uid( &reg->alias, uid );
+   vg_info( "LOAD WORLD %s @%d\n", uid, args.purpose );
 
    char path_buf[4096];
    vg_str path;
@@ -206,30 +229,15 @@ static void skaterift_world_load_thread( void *_args ){
       }
    }
 
-   u32 instance_start = 0, instance_count = 1;
-   if( args->purpose == k_world_purpose_client ) instance_start = 1;
-
-   world_instance_load_mdl( instance_start, worlds[first_index] );
-
-   /* TODO: Support multiply packed worlds */
-#if 0
-   world_loader.generate_point_cloud = 0;
-   for( u32 j=0; j<i; j++ ){
-      if( j != first_index ){
-         world_loader.world_index = j+1;
-         world_load_mdl( worlds[j] );
-      }
-   }
-#endif
+   world_instance_load_mdl( args.purpose, worlds[first_index] );
 
    vg_async_item *final_call = 
       vg_async_alloc( sizeof(struct world_load_complete_data) );
 
    struct world_load_complete_data *data = final_call->payload;
-   data->instance_start = instance_start;
-   data->instance_count = instance_count;
+   data->purpose = args.purpose;
 
-   skaterift_world_get_save_path( args->purpose, data->save.path );
+   skaterift_world_get_save_path( args.purpose, data->save.path );
    savedata_file_read( &data->save );
 
    vg_async_dispatch( final_call, skaterift_world_load_done );
@@ -287,7 +295,6 @@ static void skaterift_change_world_start( addon_reg *reg ){
 
       vg_linear_clear( vg_mem.scratch ); /* ?? */
       vg_info( "unloading old worlds\n" );
-      world_unlink_nonlocal( &world_static.instances[0] );
       
       for( u32 i=1; i<vg_list_size(world_static.instances); i++ ){
          world_instance *inst = &world_static.instances[i];
@@ -298,6 +305,8 @@ static void skaterift_change_world_start( addon_reg *reg ){
          }
       }
 
+      world_entity_relink( &world_static.instances[k_world_purpose_hub] );
+
       world_static.instance_addons[ k_world_purpose_client ] = reg;
       network_send_item( k_netmsg_playeritem_world1 );
       relink_all_remote_player_worlds();
@@ -305,14 +314,12 @@ static void skaterift_change_world_start( addon_reg *reg ){
 }
 
 /* console command for the above function */
-static int skaterift_change_world_command( int argc, const char *argv[] ){
-   if( !vg_loader_availible() ) return 0;
+static int skaterift_load_world_command( int argc, const char *argv[] ){
+   if( !vg_loader_availible() ) return 0; /* FIXME */
 
    if( argc == 1 ){
       addon_alias q;
-      q.type = k_addon_type_world;
-      q.workshop_id = 0;
-      vg_strncpy( argv[0], q.foldername, 64, k_strncpy_always_add_null );
+      addon_uid_to_alias( argv[0], &q );
 
       u32 reg_id = addon_match( &q );
       if( reg_id != 0xffffffff ){
@@ -320,9 +327,18 @@ static int skaterift_change_world_command( int argc, const char *argv[] ){
          skaterift_change_world_start( reg );
       }
       else {
-         char buf[76];
-         addon_alias_uid( &q, buf );
-         vg_error( "Addon '%s' is not installed or not found.\n", buf );
+         vg_error( "Addon '%s' is not installed or not found.\n", argv[0] );
+      }
+   }
+   else {
+      vg_info( "worlds availible to load:\n" );
+         
+      for( int i=0; i<addon_count(k_addon_type_world); i ++ ){
+         addon_reg *w = get_addon_from_index( k_addon_type_world, i );
+
+         char buf[ADDON_UID_MAX];
+         addon_alias_uid( &w->alias, buf );
+         vg_info( "  %s\n", buf );
       }
    }