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