remote items test
[carveJwlIkooP6JGAAIwe30JlM.git] / ent_skateshop.c
1 #ifndef ENT_SKATESHOP_C
2 #define ENT_SKATESHOP_C
3
4 #define VG_GAME
5 #include "vg/vg.h"
6 #include "vg/vg_steam_ugc.h"
7 #include "vg/vg_msg.h"
8 #include "ent_skateshop.h"
9 #include "world.h"
10 #include "player.h"
11 #include "gui.h"
12 #include "menu.h"
13 #include "pointcloud.h"
14 #include "highscores.h"
15 #include "steam.h"
16 #include "addon.h"
17 #include "save.h"
18 #include "network.h"
19
20 /*
21 * Checks string equality but does a hash check first
22 */
23 static inline int const_str_eq( u32 hash, const char *str, const char *cmp )
24 {
25 if( hash == vg_strdjb2(cmp) )
26 if( !strcmp( str, cmp ) )
27 return 1;
28 return 0;
29 }
30
31 static void skateshop_update_viewpage(void){
32 u32 page = global_skateshop.selected_board_id/SKATESHOP_VIEW_SLOT_MAX;
33
34 for( u32 i=0; i<SKATESHOP_VIEW_SLOT_MAX; i++ ){
35 u32 j = SKATESHOP_VIEW_SLOT_MAX-1-i;
36 struct shop_view_slot *slot = &global_skateshop.shop_view_slots[j];
37 addon_cache_unwatch( k_addon_type_board, slot->cache_id );
38 }
39
40 for( u32 i=0; i<SKATESHOP_VIEW_SLOT_MAX; i++ ){
41 struct shop_view_slot *slot = &global_skateshop.shop_view_slots[i];
42 u32 request_id = page*SKATESHOP_VIEW_SLOT_MAX + i;
43 slot->cache_id = addon_cache_create_viewer( k_addon_type_board,
44 request_id );
45 }
46 }
47
48 /*
49 * op/subroutine: k_workshop_op_item_load
50 * -----------------------------------------------------------------------------
51 */
52
53 static void world_scan_thread( void *_args ){
54 addon_mount_content_folder( k_addon_type_world, "maps", ".mdl" );
55 addon_mount_workshop_items();
56 vg_async_call( async_addon_reg_update, NULL, 0 );
57 }
58
59 /*
60 * Asynchronous scan of local disk for worlds
61 */
62 static void skateshop_op_world_scan(void){
63 vg_loader_start( world_scan_thread, NULL );
64 }
65
66 static void board_processview_thread( void *_args ){
67 addon_cache_load_loop();
68 }
69
70 static void board_scan_thread( void *_args ){
71 addon_mount_content_folder( k_addon_type_board, "boards", ".mdl" );
72 addon_mount_workshop_items();
73 vg_async_call( async_addon_reg_update, NULL, 0 );
74 vg_async_stall();
75 board_processview_thread(NULL);
76 }
77
78 /* TODO: migrate to addon.c */
79 static void skateshop_op_board_scan(void){
80 vg_loader_start( board_scan_thread, NULL );
81 }
82
83 /* TODO: migrate to addon.c */
84 static void skateshop_autostart_loading(void){
85 if( !vg_loader_availible() ) return;
86
87 SDL_AtomicLock( &addon_system.sl_cache_using_resources );
88 for( u32 type=0; type<k_addon_type_max; type++ ){
89 struct addon_cache *cache = &addon_system.cache[type];
90
91 for( u32 id=1; id<=cache->pool.count; id++ ){
92 addon_cache_entry *entry = vg_pool_item( &cache->pool, id );
93 if( entry->state == k_addon_cache_state_load_request ){
94 SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
95 goto launch;
96 }
97 }
98 }
99 SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
100 return;
101 launch:
102 vg_loader_start( board_processview_thread, NULL );
103 }
104
105 /*
106 * Regular stuff
107 * -----------------------------------------------------------------------------
108 */
109
110 /*
111 * VG event init
112 */
113 static void skateshop_init(void){
114 }
115
116 static u16 skateshop_selected_cache_id(void){
117 if( addon_count(k_addon_type_board) ){
118 addon_reg *reg = get_addon_from_index(k_addon_type_board,
119 global_skateshop.selected_board_id);
120 return reg->cache_id;
121 }
122 else return 0;
123 }
124
125 static void pointcloud_async_end(void *_, u32 __)
126 {
127 pointcloud_animate( k_pointcloud_anim_opening );
128 }
129
130 static void pointcloud_clear_async(void *_, u32 __)
131 {
132 pointcloud.count = 0;
133 pointcloud_animate( k_pointcloud_anim_opening );
134 }
135
136 static void skateshop_world_preview_loader_thread( void *_data )
137 {
138 addon_reg *reg = _data;
139
140 char path_buf[4096];
141 vg_str path;
142 vg_strnull( &path, path_buf, 4096 );
143 addon_get_content_folder( reg, &path );
144 vg_strcat( &path, "/preview.bin" );
145
146 vg_linear_clear(vg_mem.scratch);
147 u32 size;
148
149 void *data = vg_file_read( vg_mem.scratch, path_buf, &size );
150 if( data ){
151 if( size < sizeof(pointcloud_buffer) ){
152 vg_async_call( pointcloud_clear_async, NULL, 0 );
153 return;
154 }
155
156 vg_async_item *call = vg_async_alloc(size);
157 pointcloud_buffer *pcbuf = call->payload;
158 memcpy( pcbuf, data, size );
159
160 u32 point_count = (size-sizeof(pointcloud_buffer)) /
161 sizeof(struct pointcloud_vert);
162 pcbuf->max = point_count;
163 pcbuf->count = point_count;
164 pcbuf->op = k_pointcloud_op_clear;
165
166 vg_async_dispatch( call, async_pointcloud_sub );
167 vg_async_call( pointcloud_async_end, NULL, 0 );
168 }
169 else{
170 vg_async_call( pointcloud_clear_async, NULL, 0 );
171 }
172 }
173
174 static void skateshop_world_preview_loader_thread_and_end( void *_data ){
175 skateshop_world_preview_loader_thread( _data );
176 }
177
178 static void skateshop_load_world_preview( addon_reg *reg ){
179 vg_loader_start( skateshop_world_preview_loader_thread_and_end, reg );
180 }
181
182 /*
183 * VG event preupdate
184 */
185 void temp_update_playermodel(void);
186 static void ent_skateshop_preupdate( ent_skateshop *shop, int active ){
187 if( !active ) return;
188
189 /* input filter */
190 world_instance *world = world_current_instance();
191
192 /* camera positioning */
193 ent_camera *ref = mdl_arritm( &world->ent_camera,
194 mdl_entity_id_id(shop->id_camera) );
195
196 v3f dir = {0.0f,-1.0f,0.0f};
197 mdl_transform_vector( &ref->transform, dir, dir );
198 m3x3_mulv( localplayer.invbasis, dir, dir );
199 player_vector_angles( world_static.focus_cam.angles, dir, 1.0f, 0.0f );
200
201 v3f lookat;
202 if( shop->type == k_skateshop_type_boardshop ||
203 shop->type == k_skateshop_type_worldshop ){
204 ent_marker *display = mdl_arritm( &world->ent_marker,
205 mdl_entity_id_id(shop->boards.id_display) );
206 v3_sub( display->transform.co, localplayer.rb.co, lookat );
207 }
208 else if( shop->type == k_skateshop_type_charshop )
209 v3_sub( ref->transform.co, localplayer.rb.co, lookat );
210 else
211 vg_fatal_error( "Unknown store (%u)\n", shop->type );
212
213 q_axis_angle( localplayer.rb.q, (v3f){0.0f,1.0f,0.0f},
214 atan2f(lookat[0],lookat[2]) );
215
216 v3_copy( ref->transform.co, world_static.focus_cam.pos );
217 world_static.focus_cam.fov = ref->fov;
218
219 /* input */
220 if( shop->type == k_skateshop_type_boardshop ){
221 if( !vg_loader_availible() ) return;
222
223 gui_helper_action( axis_display_string( k_sraxis_mbrowse_h ), "browse" );
224 gui_helper_action( button_display_string( k_srbind_mback ), "exit" );
225
226 u16 cache_id = skateshop_selected_cache_id();
227 if( cache_id ){
228 gui_helper_action( button_display_string( k_srbind_maccept ), "pick" );
229 }
230
231 /*
232 * Controls
233 * ----------------------
234 */
235 u32 opage = global_skateshop.selected_board_id/SKATESHOP_VIEW_SLOT_MAX;
236
237 if( button_down( k_srbind_mleft ) ){
238 if( global_skateshop.selected_board_id > 0 ){
239 global_skateshop.selected_board_id --;
240 }
241 }
242
243 if( button_down( k_srbind_mright ) ){
244 if( global_skateshop.selected_board_id+1 <
245 addon_count(k_addon_type_board) )
246 {
247 global_skateshop.selected_board_id ++;
248 }
249 }
250
251 u32 npage = global_skateshop.selected_board_id/SKATESHOP_VIEW_SLOT_MAX;
252
253 if( opage != npage ){
254 skateshop_update_viewpage();
255 //skateshop_op_processview();
256 }
257 else if( cache_id && button_down( k_srbind_maccept )){
258 vg_info( "chose board from skateshop (%u)\n",
259 global_skateshop.selected_board_id );
260
261 addon_cache_unwatch( k_addon_type_board, localplayer.board_view_slot );
262 addon_cache_watch( k_addon_type_board, cache_id );
263 localplayer.board_view_slot = cache_id;
264 network_send_item( k_addon_type_board );
265
266 world_entity_unfocus();
267 skaterift_autosave(1);
268 return;
269 }
270 }
271 else if( shop->type == k_skateshop_type_charshop ){
272 if( !vg_loader_availible() ) return;
273
274 gui_helper_action( axis_display_string( k_sraxis_mbrowse_h ), "browse" );
275 gui_helper_action( button_display_string( k_srbind_mback ), "exit" );
276 gui_helper_action( button_display_string( k_srbind_maccept ), "pick" );
277
278 int changed = 0;
279
280 if( button_down( k_srbind_mleft ) ){
281 if( global_skateshop.selected_player_id > 0 ){
282 global_skateshop.selected_player_id --;
283 }
284 else{
285 global_skateshop.selected_player_id =
286 addon_count(k_addon_type_player) -1;
287 }
288
289 changed = 1;
290 }
291
292 if( button_down( k_srbind_mright ) ){
293 if( global_skateshop.selected_player_id+1 <
294 addon_count(k_addon_type_player) ){
295 global_skateshop.selected_player_id ++;
296 }
297 else{
298 global_skateshop.selected_player_id = 0;
299 }
300
301 changed = 1;
302 }
303
304 if( changed ){
305 player__use_model( global_skateshop.selected_player_id );
306 //skateshop_op_processview();
307 }
308
309 if( button_down( k_srbind_maccept ) ){
310 network_send_item( k_addon_type_player );
311 world_entity_unfocus();
312 }
313 }
314 else if( shop->type == k_skateshop_type_worldshop ){
315 int browseable = 0,
316 loadable = 0;
317
318 if( addon_count(k_addon_type_world) && vg_loader_availible() ){
319 gui_helper_action( axis_display_string(k_sraxis_mbrowse_h), "browse" );
320 browseable = 1;
321 }
322
323 if( vg_loader_availible() && global_skateshop.selected_world_id > 0 ){
324 gui_helper_action( button_display_string(k_srbind_maccept),
325 "open rift" );
326 loadable = 1;
327 }
328
329 int change = 0;
330
331 if( browseable ){
332 if( button_down( k_srbind_mleft ) ){
333 if( global_skateshop.selected_world_id > 0 ){
334 global_skateshop.selected_world_id --;
335 change = 1;
336 }
337 }
338
339 if( button_down( k_srbind_mright ) ){
340 if( global_skateshop.selected_world_id+1 <
341 addon_count(k_addon_type_world) )
342 {
343 global_skateshop.selected_world_id ++;
344 change = 1;
345 }
346 }
347 }
348
349 if( change && pointcloud_idle() ){
350 pointcloud_animate( k_pointcloud_anim_hiding );
351 }
352
353 if( vg_loader_availible() ){
354 addon_reg *reg = get_addon_from_index( k_addon_type_world,
355 global_skateshop.selected_world_id );
356
357 /* automatically load in clouds */
358 if( loadable && button_down( k_srbind_maccept ) ){
359 vg_info( "Select rift (%u)\n",
360 global_skateshop.selected_world_id );
361 skaterift_change_world_start( reg );
362 return;
363 }
364 else{
365 if( pointcloud.anim == k_pointcloud_anim_idle_closed ){
366 if( global_skateshop.pointcloud_world_id !=
367 global_skateshop.selected_world_id )
368 {
369 global_skateshop.pointcloud_world_id =
370 global_skateshop.selected_world_id;
371 skateshop_load_world_preview( reg );
372 }
373 else{
374 pointcloud_animate( k_pointcloud_anim_opening );
375 }
376 }
377 else if( pointcloud.anim == k_pointcloud_anim_idle_open ){
378 if( global_skateshop.pointcloud_world_id !=
379 global_skateshop.selected_world_id )
380 {
381 pointcloud_animate( k_pointcloud_anim_hiding );
382 }
383 }
384 }
385 }
386 }
387 else{
388 vg_fatal_error( "Unknown store (%u)\n", shop->type );
389 }
390
391 if( button_down( k_srbind_mback ) ){
392 if( shop->type == k_skateshop_type_charshop )
393 network_send_item( k_addon_type_player );
394
395 world_entity_unfocus();
396 return;
397 }
398 }
399
400 static void skateshop_render_boardshop( ent_skateshop *shop ){
401 world_instance *world = world_current_instance();
402 u32 slot_count = vg_list_size(global_skateshop.shop_view_slots);
403
404 ent_marker *mark_rack = mdl_arritm( &world->ent_marker,
405 mdl_entity_id_id(shop->boards.id_rack)),
406 *mark_display = mdl_arritm( &world->ent_marker,
407 mdl_entity_id_id(shop->boards.id_display));
408
409 SDL_AtomicLock( &addon_system.sl_cache_using_resources );
410 struct addon_cache *cache = &addon_system.cache[k_addon_type_board];
411
412 /* Render loaded boards in the view slots */
413 for( u32 i=0; i<slot_count; i++ ){
414 struct shop_view_slot *slot = &global_skateshop.shop_view_slots[i];
415 float selected = 0.0f;
416
417 if( !slot->cache_id )
418 goto fade_out;
419
420 addon_cache_entry *entry = vg_pool_item( &cache->pool, slot->cache_id );
421
422 if( entry->state != k_addon_cache_state_loaded )
423 goto fade_out;
424
425 struct player_board *board =
426 addon_cache_item( k_addon_type_board, slot->cache_id );
427
428 mdl_transform xform;
429 transform_identity( &xform );
430
431 xform.co[0] = -((float)i - ((float)slot_count)*0.5f)*0.45f;
432 mdl_transform_mul( &mark_rack->transform, &xform, &xform );
433
434
435 if( entry->reg_index == global_skateshop.selected_board_id ){
436 selected = 1.0f;
437 }
438
439 float t = slot->view_blend;
440 v3_lerp( xform.co, mark_display->transform.co, t, xform.co );
441 q_nlerp( xform.q, mark_display->transform.q, t, xform.q );
442 v3_lerp( xform.s, mark_display->transform.s, t, xform.s );
443
444 struct player_board_pose pose = {0};
445 m4x3f mmdl;
446 mdl_transform_m4x3( &xform, mmdl );
447 render_board( &skaterift.cam, world, board, mmdl,
448 &pose, k_board_shader_entity );
449
450 fade_out:;
451 float rate = 5.0f*vg.time_delta;
452 slot->view_blend = vg_lerpf( slot->view_blend, selected, rate );
453 }
454
455 ent_marker *mark_info = mdl_arritm( &world->ent_marker,
456 mdl_entity_id_id(shop->boards.id_info));
457 m4x3f mtext, mrack;
458 mdl_transform_m4x3( &mark_info->transform, mtext );
459 mdl_transform_m4x3( &mark_rack->transform, mrack );
460
461 #if 0
462 const char *text_title = "Fish - Title";
463 const char *text_author = "by Shaniqua";
464 #endif
465
466 m4x3f mlocal, mmdl;
467 m4x3_identity( mlocal );
468
469 float scale = 0.2f,
470 thickness = 0.03f;
471
472 font3d_bind( &gui.font, &skaterift.cam );
473 shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
474
475 /* Selection counter
476 * ------------------------------------------------------------------ */
477 m3x3_zero( mlocal );
478 v3_zero( mlocal[3] );
479 mlocal[0][0] = -scale*2.0f;
480 mlocal[1][2] = -scale*2.0f;
481 mlocal[2][1] = -thickness;
482 mlocal[3][2] = -0.7f;
483 m4x3_mul( mrack, mlocal, mmdl );
484
485 if( addon_count(k_addon_type_board) ){
486 char buf[16];
487 int i=0;
488 i+=highscore_intl( buf+i, global_skateshop.selected_board_id+1, 3 );
489 buf[i++] = '/';
490 i+=highscore_intl( buf+i, addon_count(k_addon_type_board), 3 );
491 buf[i++] = '\0';
492
493 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
494 buf, &skaterift.cam, mmdl );
495 }
496 else{
497 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
498 "Nothing installed", &skaterift.cam, mmdl );
499 }
500
501 u16 cache_id = skateshop_selected_cache_id();
502 struct addon_cache_entry *entry = vg_pool_item( &cache->pool, cache_id );
503 addon_reg *reg = NULL;
504
505 if( entry ) reg = entry->reg_ptr;
506
507 if( !reg ){
508 SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
509 global_skateshop.render.item_title = "";
510 global_skateshop.render.item_desc = "";
511 return;
512 }
513
514 if( global_skateshop.render.reg_id != global_skateshop.selected_board_id ){
515 global_skateshop.render.item_title = "";
516 global_skateshop.render.item_desc = "";
517 vg_msg root = {0};
518 root.buf = reg->metadata;
519 root.len = reg->metadata_len;
520 root.max = sizeof(reg->metadata);
521
522 vg_msg workshop = root;
523 if( vg_msg_seekframe( &workshop, "workshop", 0 ) ){
524 const char *title = vg_msg_seekkvstr( &workshop, "title", 0 );
525 if( title ) global_skateshop.render.item_title = title;
526
527 const char *dsc = vg_msg_seekkvstr( &workshop, "author", 0 );
528 if( dsc ) global_skateshop.render.item_desc = dsc;
529 }
530
531 global_skateshop.render.reg_id = global_skateshop.selected_board_id;
532 }
533
534 /* Skin title
535 * ----------------------------------------------------------------- */
536 m3x3_zero( mlocal );
537 m3x3_setdiagonalv3( mlocal, (v3f){ scale, scale, thickness } );
538 mlocal[3][0] = -font3d_string_width( &gui.font, 0,
539 global_skateshop.render.item_title );
540 mlocal[3][0] *= scale*0.5f;
541 mlocal[3][1] = 0.1f;
542 mlocal[3][2] = 0.0f;
543 m4x3_mul( mtext, mlocal, mmdl );
544 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
545 global_skateshop.render.item_title,
546 &skaterift.cam, mmdl );
547
548 /* Author name
549 * ----------------------------------------------------------------- */
550 scale *= 0.4f;
551 m3x3_setdiagonalv3( mlocal, (v3f){ scale, scale, thickness } );
552 mlocal[3][0] = -font3d_string_width( &gui.font, 0,
553 global_skateshop.render.item_desc );
554 mlocal[3][0] *= scale*0.5f;
555 mlocal[3][1] = 0.0f;
556 mlocal[3][2] = 0.0f;
557 m4x3_mul( mtext, mlocal, mmdl );
558 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
559 global_skateshop.render.item_desc,
560 &skaterift.cam, mmdl );
561
562 SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
563 }
564
565 static void skateshop_render_charshop( ent_skateshop *shop ){
566 }
567
568 static void skateshop_render_worldshop( ent_skateshop *shop ){
569 world_instance *world = world_current_instance();
570
571 ent_marker *mark_display = mdl_arritm( &world->ent_marker,
572 mdl_entity_id_id(shop->worlds.id_display)),
573 *mark_info = mdl_arritm( &world->ent_marker,
574 mdl_entity_id_id(shop->boards.id_info));
575
576 if( global_skateshop.render.world_reg != global_skateshop.selected_world_id){
577 global_skateshop.render.world_title = "";
578
579 addon_reg *reg = get_addon_from_index( k_addon_type_world,
580 global_skateshop.selected_world_id );
581 vg_msg root = {0};
582 root.buf = reg->metadata;
583 root.len = reg->metadata_len;
584 root.max = sizeof(reg->metadata);
585 vg_msg workshop = root;
586 if( vg_msg_seekframe( &workshop, "workshop", 0 ) ){
587 global_skateshop.render.world_title = vg_msg_seekkvstr( &workshop,
588 "title", 0 );
589 }
590 global_skateshop.render.world_loc = vg_msg_seekkvstr(&root,"location",0);
591 global_skateshop.render.world_reg = global_skateshop.selected_world_id;
592 }
593
594 /* Text */
595 char buftext[128], bufsubtext[128];
596 vg_str info, subtext;
597 vg_strnull( &info, buftext, 128 );
598 vg_strnull( &subtext, bufsubtext, 128 );
599
600 if( addon_count(k_addon_type_world) ){
601 addon_reg *reg = get_addon_from_index( k_addon_type_world,
602 global_skateshop.selected_world_id );
603
604 info.i+=highscore_intl( info.buffer+info.i,
605 global_skateshop.selected_world_id+1, 3 );
606 info.buffer[info.i++] = '/';
607 info.i+=highscore_intl( info.buffer+info.i,
608 addon_count(k_addon_type_world), 3 );
609 info.buffer[info.i++] = ' ';
610 info.buffer[info.i] = '\0';
611
612 vg_strcat( &info, global_skateshop.render.world_title );
613 if( !vg_loader_availible() ){
614 vg_strcat( &subtext, "Loading..." );
615 }
616 else{
617 addon_reg *reg = get_addon_from_index( k_addon_type_world,
618 global_skateshop.selected_world_id );
619
620 if( reg->alias.workshop_id )
621 vg_strcat( &subtext, "(Workshop) " );
622
623 vg_strcat( &subtext, global_skateshop.render.world_loc );
624 }
625 }
626 else{
627 vg_strcat( &info, "No worlds installed" );
628 }
629
630
631 m4x3f mtext,mlocal,mtextmdl;
632 mdl_transform_m4x3( &mark_info->transform, mtext );
633
634 font3d_bind( &gui.font, &skaterift.cam );
635 shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
636
637 float scale = 0.2f, thickness = 0.015f, scale1 = 0.08f;
638 m3x3_zero( mlocal );
639 m3x3_setdiagonalv3( mlocal, (v3f){ scale, scale, thickness } );
640 mlocal[3][0] = -font3d_string_width( &gui.font, 0, buftext );
641 mlocal[3][0] *= scale*0.5f;
642 mlocal[3][1] = 0.1f;
643 mlocal[3][2] = 0.0f;
644 m4x3_mul( mtext, mlocal, mtextmdl );
645 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
646 buftext, &skaterift.cam, mtextmdl );
647
648 m3x3_setdiagonalv3( mlocal, (v3f){ scale1, scale1, thickness } );
649 mlocal[3][0] = -font3d_string_width( &gui.font, 0, bufsubtext );
650 mlocal[3][0] *= scale1*0.5f;
651 mlocal[3][1] = -scale1*0.3f;
652 m4x3_mul( mtext, mlocal, mtextmdl );
653 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
654 bufsubtext, &skaterift.cam, mtextmdl );
655
656 /* pointcloud */
657 m4x3f mmdl;
658 mdl_transform_m4x3( &mark_display->transform, mmdl );
659 m4x3_rotate_y( mmdl, vg.time * 0.2 );
660
661 glEnable(GL_BLEND);
662 glBlendFunc(GL_ONE, GL_ONE);
663 glDisable(GL_DEPTH_TEST);
664 pointcloud_render( world, &skaterift.cam, mmdl );
665 glDisable(GL_BLEND);
666 glEnable(GL_DEPTH_TEST);
667 }
668
669 /*
670 * World: render event
671 */
672 static void skateshop_render( ent_skateshop *shop ){
673 if( shop->type == k_skateshop_type_boardshop )
674 skateshop_render_boardshop( shop );
675 else if( shop->type == k_skateshop_type_charshop )
676 skateshop_render_charshop( shop );
677 else if( shop->type == k_skateshop_type_worldshop )
678 skateshop_render_worldshop( shop );
679 else
680 vg_fatal_error( "Unknown store (%u)\n", shop->type );
681 }
682
683 /*
684 * Entity logic: entrance event
685 */
686 static void ent_skateshop_call( world_instance *world, ent_call *call ){
687 u32 index = mdl_entity_id_id( call->id );
688 ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, index );
689 vg_info( "skateshop_call\n" );
690
691 if( skaterift.activity != k_skaterift_default ) return;
692 if( !vg_loader_availible() ) return;
693
694 if( call->function == k_ent_function_trigger ){
695 if( localplayer.subsystem != k_player_subsystem_walk ) return;
696
697 vg_info( "Entering skateshop\n" );
698
699 world_entity_focus( call->id );
700 #if 0
701 localplayer.immobile = 1;
702 menu.disable_open = 1;
703 skaterift.activity = k_skaterift_skateshop;
704
705 v3_zero( localplayer.rb.v );
706 v3_zero( localplayer.rb.w );
707 localplayer._walk.move_speed = 0.0f;
708 global_skateshop.ptr_ent = shop;
709 #endif
710
711 if( shop->type == k_skateshop_type_boardshop ){
712 skateshop_update_viewpage();
713 skateshop_op_board_scan();
714 }
715 else if( shop->type == k_skateshop_type_charshop ){
716
717 }
718 else if( shop->type == k_skateshop_type_worldshop ){
719 pointcloud_animate( k_pointcloud_anim_opening );
720 skateshop_op_world_scan();
721 }
722 }
723 }
724
725 #endif /* ENT_SKATESHOP_C */