scene font rendering
[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 global_skateshop_preupdate(void){
167 float rate = vg_minf( 1.0f, vg.time_frame_delta * 2.0f );
168 int active = 0;
169 if( skaterift.activity == k_skaterift_skateshop )
170 active = 1;
171
172 vg_slewf( &global_skateshop.factive, active,
173 vg.time_frame_delta * (1.0f/0.5f) );
174
175 if( !active ) return;
176
177 /* input filter */
178 world_instance *world = world_current_instance();
179 ent_skateshop *shop = global_skateshop.ptr_ent;
180
181 /* camera positioning */
182 ent_camera *ref = mdl_arritm( &world->ent_camera,
183 mdl_entity_id_id(shop->id_camera) );
184
185 v3f dir = {0.0f,-1.0f,0.0f};
186 mdl_transform_vector( &ref->transform, dir, dir );
187 m3x3_mulv( localplayer.invbasis, dir, dir );
188 player_vector_angles( global_skateshop.cam.angles, dir, 1.0f, 0.0f );
189
190 v3f lookat;
191 if( shop->type == k_skateshop_type_boardshop ||
192 shop->type == k_skateshop_type_worldshop ){
193 ent_marker *display = mdl_arritm( &world->ent_marker,
194 mdl_entity_id_id(shop->boards.id_display) );
195 v3_sub( display->transform.co, localplayer.rb.co, lookat );
196 }
197 else if( shop->type == k_skateshop_type_charshop )
198 v3_sub( ref->transform.co, localplayer.rb.co, lookat );
199 else
200 vg_fatal_error( "Unknown store (%u)\n", shop->type );
201
202 q_axis_angle( localplayer.rb.q, (v3f){0.0f,1.0f,0.0f},
203 atan2f(lookat[0],lookat[2]) );
204
205 v3_copy( ref->transform.co, global_skateshop.cam.pos );
206 global_skateshop.cam.fov = ref->fov;
207
208 /* input */
209 if( shop->type == k_skateshop_type_boardshop ){
210 if( !vg_loader_availible() ) return;
211
212 gui_helper_action( axis_display_string( k_sraxis_mbrowse_h ), "browse" );
213 gui_helper_action( button_display_string( k_srbind_mback ), "exit" );
214
215 u16 cache_id = skateshop_selected_cache_id();
216 if( cache_id ){
217 gui_helper_action( button_display_string( k_srbind_maccept ), "pick" );
218 }
219
220 /*
221 * Controls
222 * ----------------------
223 */
224 u32 opage = global_skateshop.selected_board_id/SKATESHOP_VIEW_SLOT_MAX;
225
226 if( button_down( k_srbind_mleft ) ){
227 if( global_skateshop.selected_board_id > 0 ){
228 global_skateshop.selected_board_id --;
229 }
230 }
231
232 if( button_down( k_srbind_mright ) ){
233 if( global_skateshop.selected_board_id+1 <
234 addon_count(k_addon_type_board) )
235 {
236 global_skateshop.selected_board_id ++;
237 }
238 }
239
240 u32 npage = global_skateshop.selected_board_id/SKATESHOP_VIEW_SLOT_MAX;
241
242 if( opage != npage ){
243 skateshop_update_viewpage();
244 skateshop_op_processview();
245 }
246 else if( cache_id && button_down( k_srbind_maccept )){
247 vg_info( "chose board from skateshop (%u)\n",
248 global_skateshop.selected_board_id );
249
250 addon_cache_unwatch( k_addon_type_board, localplayer.board_view_slot );
251 addon_cache_watch( k_addon_type_board, cache_id );
252 localplayer.board_view_slot = cache_id;
253
254 global_skateshop_exit();
255 skaterift_autosave(1);
256 return;
257 }
258 }
259 else if( shop->type == k_skateshop_type_charshop ){
260 if( !vg_loader_availible() ) return;
261
262 gui_helper_action( axis_display_string( k_sraxis_mbrowse_h ), "browse" );
263 gui_helper_action( button_display_string( k_srbind_mback ), "exit" );
264 gui_helper_action( button_display_string( k_srbind_maccept ), "pick" );
265
266 int changed = 0;
267
268 if( button_down( k_srbind_mleft ) ){
269 if( global_skateshop.selected_player_id > 0 ){
270 global_skateshop.selected_player_id --;
271 }
272 else{
273 global_skateshop.selected_player_id =
274 addon_count(k_addon_type_player) -1;
275 }
276
277 changed = 1;
278 }
279
280 if( button_down( k_srbind_mright ) ){
281 if( global_skateshop.selected_player_id+1 <
282 addon_count(k_addon_type_player) ){
283 global_skateshop.selected_player_id ++;
284 }
285 else{
286 global_skateshop.selected_player_id = 0;
287 }
288
289 changed = 1;
290 }
291
292 if( changed ){
293 player__use_model( &localplayer, global_skateshop.selected_player_id );
294 skateshop_op_processview();
295 }
296
297 if( button_down( k_srbind_maccept ) ){
298 global_skateshop_exit();
299 }
300 }
301 else if( shop->type == k_skateshop_type_worldshop ){
302 int browseable = 0,
303 loadable = 0;
304
305 if( addon_count(k_addon_type_world) && vg_loader_availible() ){
306 gui_helper_action( axis_display_string(k_sraxis_mbrowse_h), "browse" );
307 browseable = 1;
308 }
309
310 if( vg_loader_availible() && global_skateshop.selected_world_id > 0 ){
311 gui_helper_action( button_display_string(k_srbind_maccept),
312 "open rift" );
313 loadable = 1;
314 }
315
316 int change = 0;
317
318 if( browseable ){
319 if( button_down( k_srbind_mleft ) ){
320 if( global_skateshop.selected_world_id > 0 )
321 {
322 global_skateshop.selected_world_id --;
323 change = 1;
324 }
325 }
326
327 if( button_down( k_srbind_mright ) ){
328 if( global_skateshop.selected_world_id+1 <
329 addon_count(k_addon_type_world) )
330 {
331 global_skateshop.selected_world_id ++;
332 change = 1;
333 }
334 }
335 }
336
337 if( change && pointcloud_idle() ){
338 pointcloud_animate( k_pointcloud_anim_hiding );
339 }
340
341 if( vg_loader_availible() ){
342 addon_reg *reg = get_addon_from_index( k_addon_type_world,
343 global_skateshop.selected_world_id );
344
345 /* automatically load in clouds */
346 if( loadable && button_down( k_srbind_maccept ) ){
347 vg_info( "Select rift (%u)\n",
348 global_skateshop.selected_world_id );
349 skaterift_change_world_start( reg );
350 return;
351 }
352 else{
353 if( pointcloud.anim == k_pointcloud_anim_idle_closed ){
354 if( global_skateshop.pointcloud_world_id !=
355 global_skateshop.selected_world_id )
356 {
357 global_skateshop.pointcloud_world_id =
358 global_skateshop.selected_world_id;
359 skateshop_load_world_preview( reg );
360 }
361 else{
362 pointcloud_animate( k_pointcloud_anim_opening );
363 }
364 }
365 else if( pointcloud.anim == k_pointcloud_anim_idle_open ){
366 if( global_skateshop.pointcloud_world_id !=
367 global_skateshop.selected_world_id )
368 {
369 pointcloud_animate( k_pointcloud_anim_hiding );
370 }
371 }
372 }
373 }
374 }
375 else{
376 vg_fatal_error( "Unknown store (%u)\n", shop->type );
377 }
378
379 if( button_down( k_srbind_mback ) ){
380 global_skateshop_exit();
381 return;
382 }
383 }
384
385 VG_STATIC void skateshop_render_boardshop(void){
386 world_instance *world = world_current_instance();
387 ent_skateshop *shop = global_skateshop.ptr_ent;
388
389 u32 slot_count = vg_list_size(global_skateshop.shop_view_slots);
390
391 ent_marker *mark_rack = mdl_arritm( &world->ent_marker,
392 mdl_entity_id_id(shop->boards.id_rack)),
393 *mark_display = mdl_arritm( &world->ent_marker,
394 mdl_entity_id_id(shop->boards.id_display));
395
396 SDL_AtomicLock( &addon_system.sl_cache_using_resources );
397 struct addon_cache *cache = &addon_system.cache[k_addon_type_board];
398
399 /* Render loaded boards in the view slots */
400 for( u32 i=0; i<slot_count; i++ ){
401 struct shop_view_slot *slot = &global_skateshop.shop_view_slots[i];
402 float selected = 0.0f;
403
404 if( !slot->cache_id )
405 goto fade_out;
406
407 addon_cache_entry *entry = vg_pool_item( &cache->pool, slot->cache_id );
408
409 if( entry->state != k_addon_cache_state_loaded )
410 goto fade_out;
411
412 struct player_board *board =
413 addon_cache_item( k_addon_type_board, slot->cache_id );
414
415 mdl_transform xform;
416 transform_identity( &xform );
417
418 xform.co[0] = -((float)i - ((float)slot_count)*0.5f)*0.45f;
419 mdl_transform_mul( &mark_rack->transform, &xform, &xform );
420
421
422 if( entry->reg_index == global_skateshop.selected_board_id ){
423 selected = 1.0f;
424 }
425
426 float t = slot->view_blend;
427 v3_lerp( xform.co, mark_display->transform.co, t, xform.co );
428 q_nlerp( xform.q, mark_display->transform.q, t, xform.q );
429 v3_lerp( xform.s, mark_display->transform.s, t, xform.s );
430
431 struct player_board_pose pose = {0};
432 m4x3f mmdl;
433 mdl_transform_m4x3( &xform, mmdl );
434 render_board( &skaterift.cam, world, board, mmdl,
435 &pose, k_board_shader_entity );
436
437 fade_out:;
438 float rate = 5.0f*vg.time_delta;
439 slot->view_blend = vg_lerpf( slot->view_blend, selected, rate );
440 }
441
442 ent_marker *mark_info = mdl_arritm( &world->ent_marker,
443 mdl_entity_id_id(shop->boards.id_info));
444 m4x3f mtext, mrack;
445 mdl_transform_m4x3( &mark_info->transform, mtext );
446 mdl_transform_m4x3( &mark_rack->transform, mrack );
447
448 #if 0
449 const char *text_title = "Fish - Title";
450 const char *text_author = "by Shaniqua";
451 #endif
452
453 m4x3f mlocal, mmdl;
454 m4x3_identity( mlocal );
455
456 float scale = 0.2f,
457 thickness = 0.03f;
458
459 font3d_bind( &gui.font, &skaterift.cam );
460 shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
461
462 /* Selection counter
463 * ------------------------------------------------------------------ */
464 m3x3_zero( mlocal );
465 v3_zero( mlocal[3] );
466 mlocal[0][0] = -scale*2.0f;
467 mlocal[1][2] = -scale*2.0f;
468 mlocal[2][1] = -thickness;
469 mlocal[3][2] = -0.7f;
470 m4x3_mul( mrack, mlocal, mmdl );
471
472 if( addon_count(k_addon_type_board) ){
473 char buf[16];
474 int i=0;
475 i+=highscore_intl( buf+i, global_skateshop.selected_board_id+1, 3 );
476 buf[i++] = '/';
477 i+=highscore_intl( buf+i, addon_count(k_addon_type_board), 3 );
478 buf[i++] = '\0';
479
480 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
481 buf, &skaterift.cam, mmdl );
482 }
483 else{
484 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
485 "Nothing installed", &skaterift.cam, mmdl );
486 }
487
488 u16 cache_id = skateshop_selected_cache_id();
489 struct addon_cache_entry *entry = vg_pool_item( &cache->pool, cache_id );
490 addon_reg *reg = NULL;
491
492 if( entry ) reg = entry->reg_ptr;
493
494 if( !reg ){
495 SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
496 global_skateshop.render.item_title = "";
497 global_skateshop.render.item_desc = "";
498 return;
499 }
500
501 if( global_skateshop.render.reg_id != global_skateshop.selected_board_id ){
502 global_skateshop.render.item_title = "";
503 global_skateshop.render.item_desc = "";
504 vg_msg root = {0};
505 root.buf = reg->metadata;
506 root.len = reg->metadata_len;
507 root.max = sizeof(reg->metadata);
508
509 vg_msg workshop = root;
510 if( vg_msg_seekframe( &workshop, "workshop", 0 ) ){
511 const char *title = vg_msg_seekkvstr( &workshop, "title", 0 );
512 if( title ) global_skateshop.render.item_title = title;
513
514 const char *dsc = vg_msg_seekkvstr( &workshop, "author", 0 );
515 if( dsc ) global_skateshop.render.item_desc = dsc;
516 }
517
518 global_skateshop.render.reg_id = global_skateshop.selected_board_id;
519 }
520
521 /* Skin title
522 * ----------------------------------------------------------------- */
523 m3x3_zero( mlocal );
524 m3x3_setdiagonalv3( mlocal, (v3f){ scale, scale, thickness } );
525 mlocal[3][0] = -font3d_string_width( &gui.font, 0,
526 global_skateshop.render.item_title );
527 mlocal[3][0] *= scale*0.5f;
528 mlocal[3][1] = 0.1f;
529 mlocal[3][2] = 0.0f;
530 m4x3_mul( mtext, mlocal, mmdl );
531 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
532 global_skateshop.render.item_title,
533 &skaterift.cam, mmdl );
534
535 /* Author name
536 * ----------------------------------------------------------------- */
537 scale *= 0.4f;
538 m3x3_setdiagonalv3( mlocal, (v3f){ scale, scale, thickness } );
539 mlocal[3][0] = -font3d_string_width( &gui.font, 0,
540 global_skateshop.render.item_desc );
541 mlocal[3][0] *= scale*0.5f;
542 mlocal[3][1] = 0.0f;
543 mlocal[3][2] = 0.0f;
544 m4x3_mul( mtext, mlocal, mmdl );
545 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
546 global_skateshop.render.item_desc,
547 &skaterift.cam, mmdl );
548
549 SDL_AtomicUnlock( &addon_system.sl_cache_using_resources );
550 }
551
552 VG_STATIC void skateshop_render_charshop(void)
553 {
554 }
555
556 VG_STATIC void skateshop_render_worldshop(void)
557 {
558 world_instance *world = world_current_instance();
559
560 ent_skateshop *shop = global_skateshop.ptr_ent;
561 ent_marker *mark_display = mdl_arritm( &world->ent_marker,
562 mdl_entity_id_id(shop->worlds.id_display)),
563 *mark_info = mdl_arritm( &world->ent_marker,
564 mdl_entity_id_id(shop->boards.id_info));
565
566 if( global_skateshop.render.world_reg != global_skateshop.selected_world_id){
567 global_skateshop.render.world_title = "";
568
569 addon_reg *reg = get_addon_from_index( k_addon_type_world,
570 global_skateshop.selected_world_id );
571 vg_msg root = {0};
572 root.buf = reg->metadata;
573 root.len = reg->metadata_len;
574 root.max = sizeof(reg->metadata);
575 vg_msg workshop = root;
576 if( vg_msg_seekframe( &workshop, "workshop", 0 ) ){
577 global_skateshop.render.world_title = vg_msg_seekkvstr( &workshop,
578 "title", 0 );
579 }
580 global_skateshop.render.world_loc = vg_msg_seekkvstr(&root,"location",0);
581 global_skateshop.render.world_reg = global_skateshop.selected_world_id;
582 }
583
584 /* Text */
585 char buftext[128], bufsubtext[128];
586 vg_str info, subtext;
587 vg_strnull( &info, buftext, 128 );
588 vg_strnull( &subtext, bufsubtext, 128 );
589
590 if( addon_count(k_addon_type_world) ){
591 addon_reg *reg = get_addon_from_index( k_addon_type_world,
592 global_skateshop.selected_world_id );
593
594 info.i+=highscore_intl( info.buffer+info.i,
595 global_skateshop.selected_world_id+1, 3 );
596 info.buffer[info.i++] = '/';
597 info.i+=highscore_intl( info.buffer+info.i,
598 addon_count(k_addon_type_world), 3 );
599 info.buffer[info.i++] = ' ';
600 info.buffer[info.i] = '\0';
601
602 vg_strcat( &info, global_skateshop.render.world_title );
603 if( !vg_loader_availible() ){
604 vg_strcat( &subtext, "Loading..." );
605 }
606 else{
607 addon_reg *reg = get_addon_from_index( k_addon_type_world,
608 global_skateshop.selected_world_id );
609
610 if( reg->alias.workshop_id )
611 vg_strcat( &subtext, "(Workshop) " );
612
613 vg_strcat( &subtext, global_skateshop.render.world_loc );
614 }
615 }
616 else{
617 vg_strcat( &info, "No worlds installed" );
618 }
619
620
621 m4x3f mtext,mlocal,mtextmdl;
622 mdl_transform_m4x3( &mark_info->transform, mtext );
623
624 font3d_bind( &gui.font, &skaterift.cam );
625 shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
626
627 float scale = 0.2f, thickness = 0.015f, scale1 = 0.08f;
628 m3x3_zero( mlocal );
629 m3x3_setdiagonalv3( mlocal, (v3f){ scale, scale, thickness } );
630 mlocal[3][0] = -font3d_string_width( &gui.font, 0, buftext );
631 mlocal[3][0] *= scale*0.5f;
632 mlocal[3][1] = 0.1f;
633 mlocal[3][2] = 0.0f;
634 m4x3_mul( mtext, mlocal, mtextmdl );
635 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
636 buftext, &skaterift.cam, mtextmdl );
637
638 m3x3_setdiagonalv3( mlocal, (v3f){ scale1, scale1, thickness } );
639 mlocal[3][0] = -font3d_string_width( &gui.font, 0, bufsubtext );
640 mlocal[3][0] *= scale1*0.5f;
641 mlocal[3][1] = -scale1*0.3f;
642 m4x3_mul( mtext, mlocal, mtextmdl );
643 font3d_simple_draw( &gui.font, 0, k_font_shader_default,
644 bufsubtext, &skaterift.cam, mtextmdl );
645
646 /* pointcloud */
647 m4x3f mmdl;
648 mdl_transform_m4x3( &mark_display->transform, mmdl );
649 m4x3_rotate_y( mmdl, vg.time * 0.2 );
650
651 glEnable(GL_BLEND);
652 glBlendFunc(GL_ONE, GL_ONE);
653 glDisable(GL_DEPTH_TEST);
654 pointcloud_render( world, &skaterift.cam, mmdl );
655 glDisable(GL_BLEND);
656 glEnable(GL_DEPTH_TEST);
657 }
658
659 /*
660 * World: render event
661 */
662 VG_STATIC void skateshop_render(void){
663 if( skaterift.activity != k_skaterift_skateshop ) return;
664
665 ent_skateshop *shop = global_skateshop.ptr_ent;
666
667 if( shop->type == k_skateshop_type_boardshop ){
668 skateshop_render_boardshop();
669 }
670 else if( shop->type == k_skateshop_type_charshop ){
671 skateshop_render_charshop();
672 }
673 else if( shop->type == k_skateshop_type_worldshop ){
674 skateshop_render_worldshop();
675 }
676 else{
677 vg_fatal_error( "Unknown store (%u)\n", shop->type );
678 }
679 }
680
681 /*
682 * Entity logic: entrance event
683 */
684 VG_STATIC void ent_skateshop_call( world_instance *world, ent_call *call )
685 {
686 u32 index = mdl_entity_id_id( call->id );
687 ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, index );
688 vg_info( "skateshop_call\n" );
689
690 if( skaterift.activity != k_skaterift_default ) return;
691 if( !vg_loader_availible() ) return;
692
693 if( call->function == k_ent_function_trigger ){
694 if( localplayer.subsystem != k_player_subsystem_walk ) return;
695
696 vg_info( "Entering skateshop\n" );
697
698 localplayer.immobile = 1;
699 menu.disable_open = 1;
700 skaterift.activity = k_skaterift_skateshop;
701
702 v3_zero( localplayer.rb.v );
703 v3_zero( localplayer.rb.w );
704 localplayer._walk.move_speed = 0.0f;
705 global_skateshop.ptr_ent = shop;
706
707 if( shop->type == k_skateshop_type_boardshop ){
708 skateshop_update_viewpage();
709 skateshop_op_board_scan();
710 }
711 else if( shop->type == k_skateshop_type_charshop ){
712
713 }
714 else if( shop->type == k_skateshop_type_worldshop ){
715 pointcloud_animate( k_pointcloud_anim_opening );
716 skateshop_op_world_scan();
717 }
718 }
719 }
720
721 /*
722 * Entity logic: exit event
723 */
724 VG_STATIC void global_skateshop_exit(void){
725 vg_info( "exit skateshop\n" );
726 localplayer.immobile = 0;
727 skaterift.activity = k_skaterift_default;
728 menu.disable_open = 0;
729 srinput.enabled = 0;
730 }
731
732 #endif /* ENT_SKATESHOP_C */