ragdoll quality improvements
[carveJwlIkooP6JGAAIwe30JlM.git] / ent_miniworld.c
1 #include "entity.h"
2 #include "ent_miniworld.h"
3 #include "world_render.h"
4 #include "input.h"
5 #include "gui.h"
6 #include "menu.h"
7
8 static void ent_miniworld_call( world_instance *world, ent_call *call ){
9 ent_miniworld *miniworld = mdl_arritm( &world->ent_miniworld,
10 mdl_entity_id_id(call->id) );
11
12 int world_id = world - world_static.instances;
13
14 if( call->function == 0 ){ /* zone() */
15 const char *uid = mdl_pstr( &world->meta, miniworld->pstr_world );
16 skaterift_load_world_command( 1, (const char *[]){ uid } );
17
18 mdl_transform_m4x3( &miniworld->transform, global_miniworld.mmdl );
19 global_miniworld.active = miniworld;
20
21 gui_helper_clear();
22 vg_str text;
23
24 if( gui_new_helper( input_button_list[k_srbind_miniworld_resume], &text ))
25 vg_strcat( &text, "Enter World" );
26 }
27 else if( call->function == 1 ){
28 global_miniworld.active = NULL;
29 gui_helper_clear();
30
31 if( miniworld->proxy ){
32 ent_prop *prop = mdl_arritm( &world->ent_prop,
33 mdl_entity_id_id(miniworld->proxy) );
34 prop->flags &= ~0x1;
35 }
36 }
37 }
38
39 static void miniworld_icon( camera *cam, enum gui_icon icon, v3f pos, f32 size){
40 m4x3f mmdl;
41 v3_copy( cam->transform[2], mmdl[2] );
42 mmdl[2][1] = 0.0f;
43 v3_normalize( mmdl[2] );
44 v3_copy( (v3f){0,1,0}, mmdl[1] );
45 v3_cross( mmdl[1], mmdl[2], mmdl[0] );
46 m4x3_mulv( global_miniworld.mmdl, pos, mmdl[3] );
47
48 shader_model_font_uMdl( mmdl );
49 shader_model_font_uOffset( (v4f){0,0,0,20.0f*size} );
50
51 m4x4f m4mdl;
52 m4x3_expand( mmdl, m4mdl );
53 m4x4_mul( cam->mtx_prev.pv, m4mdl, m4mdl );
54 shader_model_font_uPvmPrev( m4mdl );
55
56 mdl_submesh *sm = gui.icons[ icon ];
57 if( sm )
58 mdl_draw_submesh( sm );
59 }
60
61 static void ent_miniworld_render( world_instance *host_world, camera *cam ){
62 if( host_world != &world_static.instances[k_world_purpose_hub] )
63 return;
64
65 ent_miniworld *miniworld = global_miniworld.active;
66
67 if( !miniworld )
68 return;
69
70 world_instance *dest_world = &world_static.instances[k_world_purpose_client];
71
72 int rendering = 1;
73 if( dest_world->status != k_world_status_loaded )
74 rendering = 0;
75
76 if( miniworld->proxy ){
77 ent_prop *prop = mdl_arritm( &host_world->ent_prop,
78 mdl_entity_id_id(miniworld->proxy) );
79 if( !rendering )
80 prop->flags &= ~0x1;
81 else
82 prop->flags |= 0x1;
83 }
84
85
86 if( !rendering )
87 return;
88
89 render_world_override( dest_world, host_world, global_miniworld.mmdl, cam,
90 NULL, (v4f){dest_world->tar_min,10000.0f,0.0f,0.0f} );
91 render_world_routes( dest_world, host_world,
92 global_miniworld.mmdl, cam, 0, 1 );
93
94 /* icons
95 * ---------------------*/
96 font3d_bind( &gui.font, k_font_shader_default, 0, NULL, cam );
97 mesh_bind( &gui.icons_mesh );
98
99 glActiveTexture( GL_TEXTURE0 );
100 glBindTexture( GL_TEXTURE_2D, gui.icons_texture );
101 shader_model_font_uTexMain( 0 );
102 shader_model_font_uColour( (v4f){1,1,1,1} );
103
104 miniworld_icon( cam, k_gui_icon_player, dest_world->player_co,
105 1.0f + sinf(vg.time)*0.2f );
106
107 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_challenge); i++ ){
108 ent_challenge *challenge = mdl_arritm( &dest_world->ent_challenge, i );
109
110 enum gui_icon icon = k_gui_icon_exclaim;
111 if( challenge->status )
112 icon = k_gui_icon_tick;
113
114 miniworld_icon( cam, icon, challenge->transform.co, 1.0f );
115 }
116
117 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
118 ent_route *route = mdl_arritm( &dest_world->ent_route, i );
119
120 if( route->flags & k_ent_route_flag_achieve_gold ){
121 miniworld_icon( cam, k_gui_icon_rift_run_gold,
122 route->board_transform[3],1.0f);
123 }
124 else if( route->flags & k_ent_route_flag_achieve_silver ){
125 miniworld_icon( cam, k_gui_icon_rift_run_silver,
126 route->board_transform[3],1.0f);
127 }
128 }
129
130 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
131 ent_route *route = mdl_arritm( &dest_world->ent_route, i );
132
133 v4f colour;
134 v4_copy( route->colour, colour );
135 v3_muls( colour, 1.6666f, colour );
136 shader_model_font_uColour( colour );
137 miniworld_icon( cam, k_gui_icon_rift_run, route->board_transform[3],1.0f);
138 }
139 }
140
141 static void ent_miniworld_preupdate(void){
142 world_instance *hub = world_current_instance(),
143 *dest = &world_static.instances[k_world_purpose_client];
144
145 ent_miniworld *miniworld = global_miniworld.active;
146
147 if( (localplayer.subsystem != k_player_subsystem_walk) ||
148 (global_miniworld.transition) ||
149 (world_static.active_instance != k_world_purpose_hub) ||
150 (!miniworld) ||
151 (dest->status != k_world_status_loaded) ||
152 (skaterift.activity != k_skaterift_default)) {
153 return;
154 }
155
156 if( button_down( k_srbind_miniworld_resume ) ){
157 if( skaterift.demo_mode ){
158 if( world_static.instance_addons[1]->flags & ADDON_REG_PREMIUM ){
159 skaterift.activity = k_skaterift_menu;
160 menu.page = 0xffffffff;
161 menu_open_page( "Premium", k_ent_menuitem_stack_append );
162 return;
163 }
164 }
165
166 global_miniworld.transition = 1;
167 global_miniworld.t = 0.0f;
168 global_miniworld.cam = skaterift.cam;
169
170 world_switch_instance(1);
171 srinput.state = k_input_state_resume;
172 menu.disable_open = 0;
173 gui_helper_clear();
174 audio_lock();
175 audio_oneshot( &audio_ui[2], 1.0f, 0.0f );
176 audio_unlock();
177 }
178 }
179
180 static void ent_miniworld_goback(void){
181 audio_lock();
182 audio_oneshot( &audio_ui[2], 1.0f, 0.0f );
183 audio_unlock();
184
185 global_miniworld.transition = -1;
186 global_miniworld.t = 1.0f;
187
188 global_miniworld.cam = skaterift.cam;
189 m4x3_transform_camera( global_miniworld.mmdl, &global_miniworld.cam );
190 world_switch_instance(0);
191 }