basic npc
[carveJwlIkooP6JGAAIwe30JlM.git] / ent_miniworld.c
index cd79b4552626ca5dda89aac1bbcd0b7d1ef63419..fcdba0b12c20cf62967d84c6037cda3ab9d97fe1 100644 (file)
@@ -1,9 +1,16 @@
 #include "entity.h"
 #include "ent_miniworld.h"
 #include "world_render.h"
+#include "world_load.h"
 #include "input.h"
+#include "gui.h"
+#include "menu.h"
+#include "audio.h"
 
-static void ent_miniworld_call( world_instance *world, ent_call *call ){
+struct global_miniworld global_miniworld;
+
+void ent_miniworld_call( world_instance *world, ent_call *call )
+{
    ent_miniworld *miniworld = mdl_arritm( &world->ent_miniworld, 
                                           mdl_entity_id_id(call->id) );
 
@@ -13,14 +20,18 @@ static void ent_miniworld_call( world_instance *world, ent_call *call ){
       const char *uid = mdl_pstr( &world->meta, miniworld->pstr_world );
       skaterift_load_world_command( 1, (const char *[]){ uid } );
 
-      global_miniworld.active_id = call->id;
+      mdl_transform_m4x3( &miniworld->transform, global_miniworld.mmdl );
+      global_miniworld.active = miniworld;
+
+      gui_helper_clear();
+      vg_str text;
+
+      if( gui_new_helper( input_button_list[k_srbind_miniworld_resume], &text ))
+         vg_strcat( &text, "Enter World" );
    }
    else if( call->function == 1 ){
-
-      if( global_miniworld.active_id == call->id )
-         global_miniworld.active_id = 0;
-      else 
-         vg_warn( "bad call\n" );
+      global_miniworld.active = NULL;
+      gui_helper_clear();
 
       if( miniworld->proxy ){
          ent_prop *prop = mdl_arritm( &world->ent_prop, 
@@ -30,17 +41,44 @@ static void ent_miniworld_call( world_instance *world, ent_call *call ){
    }
 }
 
-static void ent_miniworld_render( world_instance *host_world ){
-   u32 entity_id = global_miniworld.active_id;
+static void miniworld_icon( vg_camera *cam, enum gui_icon icon, 
+                            v3f pos, f32 size)
+{
+   m4x3f mmdl;
+   v3_copy( cam->transform[2], mmdl[2] );
+   mmdl[2][1] = 0.0f;
+   v3_normalize( mmdl[2] );
+   v3_copy( (v3f){0,1,0}, mmdl[1] );
+   v3_cross( mmdl[1], mmdl[2], mmdl[0] );
+   m4x3_mulv( global_miniworld.mmdl, pos, mmdl[3] );
+
+   shader_model_font_uMdl( mmdl );
+   shader_model_font_uOffset( (v4f){0,0,0,20.0f*size} );
+
+   m4x4f m4mdl;
+   m4x3_expand( mmdl, m4mdl );
+   m4x4_mul( cam->mtx_prev.pv, m4mdl, m4mdl );
+   shader_model_font_uPvmPrev( m4mdl );
+
+   mdl_submesh *sm = gui.icons[ icon ];
+   if( sm )
+      mdl_draw_submesh( sm );
+}
+
+void ent_miniworld_render( world_instance *host_world, vg_camera *cam )
+{
+   if( host_world != &world_static.instances[k_world_purpose_hub] )
+      return;
+
+   ent_miniworld *miniworld = global_miniworld.active;
 
-   if( !entity_id )
+   if( !miniworld )
       return;
-   
-   ent_miniworld *miniworld = mdl_arritm( &host_world->ent_miniworld, 
-                                          mdl_entity_id_id(entity_id) );
+
+   world_instance *dest_world = &world_static.instances[k_world_purpose_client];
 
    int rendering = 1;
-   if( miniworld->purpose == k_world_purpose_invalid )
+   if( dest_world->status != k_world_status_loaded )
       rendering = 0;
 
    if( miniworld->proxy ){
@@ -52,24 +90,112 @@ static void ent_miniworld_render( world_instance *host_world ){
          prop->flags |= 0x1;
    }
 
+
    if( !rendering )
       return;
 
-   world_instance *dest_world = &world_static.instances[miniworld->purpose];
+   render_world_override( dest_world, host_world, global_miniworld.mmdl, cam,
+                          NULL, (v4f){dest_world->tar_min,10000.0f,0.0f,0.0f} );
+   render_world_routes( dest_world, host_world, 
+                        global_miniworld.mmdl, cam, 0, 1 );
 
+   /* icons
+    * ---------------------*/
+   font3d_bind( &gui.font, k_font_shader_default, 0, NULL, cam );
+   mesh_bind( &gui.icons_mesh );
 
-   m4x3f mmdl;
-   mdl_transform_m4x3( &miniworld->transform, mmdl );
-   render_world_override( dest_world, host_world, mmdl );
+   glActiveTexture( GL_TEXTURE0 );
+   glBindTexture( GL_TEXTURE_2D, gui.icons_texture );
+   shader_model_font_uTexMain( 0 );
+   shader_model_font_uColour( (v4f){1,1,1,1} );
+
+   miniworld_icon( cam, k_gui_icon_player, dest_world->player_co, 
+                  1.0f + sinf(vg.time)*0.2f );
+
+   for( u32 i=0; i<mdl_arrcount(&dest_world->ent_challenge); i++ ){
+      ent_challenge *challenge = mdl_arritm( &dest_world->ent_challenge, i );
+
+      enum gui_icon icon = k_gui_icon_exclaim;
+      if( challenge->status )
+         icon = k_gui_icon_tick;
+
+      miniworld_icon( cam, icon, challenge->transform.co, 1.0f );
+   }
 
-   //render_world_routes( , &skaterift.cam, 1 );
+   for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
+      ent_route *route = mdl_arritm( &dest_world->ent_route, i );
+
+      if( route->flags & k_ent_route_flag_achieve_gold ){
+         miniworld_icon( cam, k_gui_icon_rift_run_gold, 
+                         route->board_transform[3],1.0f);
+      }
+      else if( route->flags & k_ent_route_flag_achieve_silver ){
+         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 );
+
+      v4f colour;
+      v4_copy( route->colour, colour );
+      v3_muls( colour, 1.6666f, colour );
+      shader_model_font_uColour( colour );
+      miniworld_icon( cam, k_gui_icon_rift_run, route->board_transform[3],1.0f);
+   }
 }
 
-static void ent_miniworld_preupdate(void){
-   if( !global_miniworld.active_id )
+void ent_miniworld_preupdate(void)
+{
+   world_instance *hub = world_current_instance(),
+                  *dest = &world_static.instances[k_world_purpose_client];
+
+   ent_miniworld *miniworld = global_miniworld.active;
+
+   if( (localplayer.subsystem != k_player_subsystem_walk) ||
+       (global_miniworld.transition) ||
+       (world_static.active_instance != k_world_purpose_hub) ||
+       (!miniworld) ||
+       (dest->status != k_world_status_loaded) ||
+       (skaterift.activity != k_skaterift_default)) {
       return;
+   }
+
+   if( button_down( k_srbind_miniworld_resume ) ){
+      if( skaterift.demo_mode ){
+         if( world_static.instance_addons[1]->flags & ADDON_REG_PREMIUM ){
+            skaterift.activity = k_skaterift_menu;
+            menu.page = 0xffffffff;
+            menu_open_page( "Premium", k_ent_menuitem_stack_append );
+            return;
+         }
+      }
 
-   if( button_down( k_srbind_use ) ){
-      
+      global_miniworld.transition = 1;
+      global_miniworld.t = 0.0f;
+      global_miniworld.cam = skaterift.cam;
+
+      world_switch_instance(1);
+      srinput.state = k_input_state_resume;
+      menu.disable_open = 0;
+      gui_helper_clear();
+      audio_lock();
+      audio_oneshot( &audio_ui[2], 1.0f, 0.0f );
+      audio_unlock();
    }
 }
+
+void ent_miniworld_goback(void)
+{
+   audio_lock();
+   audio_oneshot( &audio_ui[2], 1.0f, 0.0f );
+   audio_unlock();
+
+   global_miniworld.transition = -1;
+   global_miniworld.t = 1.0f;
+
+   global_miniworld.cam = skaterift.cam;
+   vg_m4x3_transform_camera( global_miniworld.mmdl, &global_miniworld.cam );
+   world_switch_instance(0);
+}