+ m3x3_setdiagonalv3( mlocal, (v3f){ scale, scale, thickness } );
+ mlocal[3][0] = -font3d_string_width( 0, buftext );
+ mlocal[3][0] *= scale*0.5f;
+ mlocal[3][1] = 0.1f;
+ mlocal[3][2] = 0.0f;
+ m4x3_mul( mtext, mlocal, mtextmdl );
+ font3d_simple_draw( 0, buftext, &skaterift.cam, mtextmdl );
+
+ m3x3_setdiagonalv3( mlocal, (v3f){ scale1, scale1, thickness } );
+ mlocal[3][0] = -font3d_string_width( 0, bufsubtext );
+ mlocal[3][0] *= scale1*0.5f;
+ mlocal[3][1] = -scale1*0.3f;
+ m4x3_mul( mtext, mlocal, mtextmdl );
+ font3d_simple_draw( 0, bufsubtext, &skaterift.cam, mtextmdl );
+}
+
+/*
+ * World: render event
+ */
+static void skateshop_render( ent_skateshop *shop ){
+ if( shop->type == k_skateshop_type_boardshop )
+ skateshop_render_boardshop( shop );
+ else if( shop->type == k_skateshop_type_charshop )
+ skateshop_render_charshop( shop );
+ else if( shop->type == k_skateshop_type_worldshop )
+ skateshop_render_worldshop( shop );
+ else if( shop->type == k_skateshop_type_server ){
+ }
+ else
+ vg_fatal_error( "Unknown store (%u)\n", shop->type );
+}
+
+static void skateshop_render_nonfocused( world_instance *world, camera *cam ){
+ for( u32 j=0; j<mdl_arrcount( &world->ent_skateshop ); j ++ ){
+ ent_skateshop *shop = mdl_arritm(&world->ent_skateshop, j );
+
+ if( shop->type != k_skateshop_type_boardshop ) continue;
+
+ f32 dist2 = v3_dist2( cam->pos, shop->transform.co ),
+ maxdist = 50.0f;
+
+ if( dist2 > maxdist*maxdist ) continue;
+ ent_marker *mark_rack = mdl_arritm( &world->ent_marker,
+ mdl_entity_id_id(shop->boards.id_rack));
+
+ u32 slot_count = vg_list_size(global_skateshop.shop_view_slots);
+ for( u32 i=0; i<slot_count; i++ ){
+ struct player_board *board = &localplayer.fallback_board;
+
+ mdl_transform xform;
+ transform_identity( &xform );
+
+ xform.co[0] = -((float)i - ((float)slot_count)*0.5f)*0.45f;
+ mdl_transform_mul( &mark_rack->transform, &xform, &xform );
+
+ struct player_board_pose pose = {0};
+ m4x3f mmdl;
+ mdl_transform_m4x3( &xform, mmdl );
+ render_board( cam, world, board, mmdl, &pose, k_board_shader_entity );
+ }
+ }
+}
+
+static void ent_skateshop_helpers_pickable( const char *acceptance ){
+ vg_str text;
+
+ if( gui_new_helper( input_button_list[k_srbind_mback], &text ))
+ vg_strcat( &text, "exit" );
+
+ if( (global_skateshop.helper_pick = gui_new_helper(
+ input_button_list[k_srbind_maccept], &text))){
+ vg_strcat( &text, acceptance );
+ }
+
+ if( (global_skateshop.helper_browse = gui_new_helper(
+ input_axis_list[k_sraxis_mbrowse_h], &text ))){
+ vg_strcat( &text, "browse" );
+ }
+}
+
+/*
+ * Entity logic: entrance event
+ */
+static void ent_skateshop_call( world_instance *world, ent_call *call ){
+ u32 index = mdl_entity_id_id( call->id );
+ ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, index );
+ vg_info( "skateshop_call\n" );
+
+ if( skaterift.activity != k_skaterift_default ) return;
+ if( !vg_loader_availible() ) return;