world save position
[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 miniworld_helper_default(void){
9 gui_helper_clear();
10 vg_str text;
11 if( gui_new_helper( input_button_list[k_srbind_miniworld_resume], &text ))
12 vg_strcat( &text, "Enter World" );
13
14 if( gui_new_helper( input_button_list[k_srbind_miniworld_teleport],&text))
15 vg_strcat( &text, "Teleport" );
16 }
17
18 static void miniworld_helper_tele(void){
19 gui_helper_clear();
20 vg_str text;
21 if( gui_new_helper( input_button_list[k_srbind_miniworld_resume], &text ))
22 vg_strcat( &text, "Confirm" );
23
24 if( gui_new_helper( input_button_list[k_srbind_mback],&text))
25 vg_strcat( &text, "Cancel" );
26 }
27
28 static void ent_miniworld_call( world_instance *world, ent_call *call ){
29 ent_miniworld *miniworld = mdl_arritm( &world->ent_miniworld,
30 mdl_entity_id_id(call->id) );
31
32 int world_id = world - world_static.instances;
33
34 if( call->function == 0 ){ /* zone() */
35 const char *uid = mdl_pstr( &world->meta, miniworld->pstr_world );
36 skaterift_load_world_command( 1, (const char *[]){ uid } );
37
38 mdl_transform_m4x3( &miniworld->transform, global_miniworld.mmdl );
39 global_miniworld.active = miniworld;
40 miniworld_helper_default();
41 }
42 else if( call->function == 1 ){
43 global_miniworld.active = NULL;
44 gui_helper_clear();
45
46 if( miniworld->proxy ){
47 ent_prop *prop = mdl_arritm( &world->ent_prop,
48 mdl_entity_id_id(miniworld->proxy) );
49 prop->flags &= ~0x1;
50 }
51 }
52 }
53
54 static void miniworld_icon( camera *cam, enum gui_icon icon, v3f pos, f32 size){
55 m4x3f mmdl;
56 v3_copy( cam->transform[2], mmdl[2] );
57 mmdl[2][1] = 0.0f;
58 v3_normalize( mmdl[2] );
59 v3_copy( (v3f){0,1,0}, mmdl[1] );
60 v3_cross( mmdl[1], mmdl[2], mmdl[0] );
61 m4x3_mulv( global_miniworld.mmdl, pos, mmdl[3] );
62
63 shader_model_font_uMdl( mmdl );
64 shader_model_font_uOffset( (v4f){0,0,0,20.0f*size} );
65
66 m4x4f m4mdl;
67 m4x3_expand( mmdl, m4mdl );
68 m4x4_mul( cam->mtx_prev.pv, m4mdl, m4mdl );
69 shader_model_font_uPvmPrev( m4mdl );
70
71 mdl_submesh *sm = gui.icons[ icon ];
72 if( sm )
73 mdl_draw_submesh( sm );
74 }
75
76 static void ent_miniworld_render( world_instance *host_world, camera *cam ){
77 if( host_world != &world_static.instances[k_world_purpose_hub] )
78 return;
79
80 ent_miniworld *miniworld = global_miniworld.active;
81
82 if( !miniworld )
83 return;
84
85 world_instance *dest_world = &world_static.instances[k_world_purpose_client];
86
87 int rendering = 1;
88 if( dest_world->status != k_world_status_loaded )
89 rendering = 0;
90
91 if( miniworld->proxy ){
92 ent_prop *prop = mdl_arritm( &host_world->ent_prop,
93 mdl_entity_id_id(miniworld->proxy) );
94 if( !rendering )
95 prop->flags &= ~0x1;
96 else
97 prop->flags |= 0x1;
98 }
99
100
101 if( !rendering )
102 return;
103
104 render_world_override( dest_world, host_world, global_miniworld.mmdl, cam,
105 global_miniworld.dest_spawn );
106 render_world_routes( dest_world, host_world,
107 global_miniworld.mmdl, cam, 0, 1 );
108
109 /* icons
110 * ---------------------*/
111 font3d_bind( &gui.font, k_font_shader_default, 0, NULL, cam );
112 mesh_bind( &gui.icons_mesh );
113
114 glActiveTexture( GL_TEXTURE0 );
115 glBindTexture( GL_TEXTURE_2D, gui.icons_texture );
116 shader_model_font_uTexMain( 0 );
117 shader_model_font_uColour( (v4f){1,1,1,1} );
118
119 miniworld_icon( cam, k_gui_icon_player, dest_world->player_co,
120 1.0f + sinf(vg.time)*0.2f );
121
122 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_challenge); i++ ){
123 ent_challenge *challenge = mdl_arritm( &dest_world->ent_challenge, i );
124
125 enum gui_icon icon = k_gui_icon_exclaim;
126 if( challenge->status )
127 icon = k_gui_icon_tick;
128
129 miniworld_icon( cam, icon, challenge->transform.co, 1.0f );
130 }
131
132 #if 0
133 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_skateshop); i++ ){
134 ent_skateshop *shop = mdl_arritm( &dest_world->ent_skateshop, i );
135 if( shop->type == k_skateshop_type_boardshop ){
136 miniworld_icon( cam, k_gui_icon_board, shop->transform.co, 1.0f );
137 }
138 else if( shop->type == k_skateshop_type_worldshop ){
139 miniworld_icon( cam, k_gui_icon_world, shop->transform.co, 1.0f );
140 }
141 }
142 #endif
143
144 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
145 ent_route *route = mdl_arritm( &dest_world->ent_route, i );
146
147 v4f colour;
148 v4_copy( route->colour, colour );
149 v3_muls( colour, 1.6666f, colour );
150 shader_model_font_uColour( colour );
151 miniworld_icon( cam, k_gui_icon_rift_run, route->board_transform[3],1.0f);
152 }
153 }
154
155 static void ent_miniworld_preupdate(void){
156 world_instance *hub = world_current_instance(),
157 *dest = &world_static.instances[k_world_purpose_client];
158
159 ent_miniworld *miniworld = global_miniworld.active;
160
161 if( (localplayer.subsystem != k_player_subsystem_walk) ||
162 (global_miniworld.transition) ||
163 (world_static.active_instance != k_world_purpose_hub) ||
164 (!miniworld) ||
165 (dest->status != k_world_status_loaded) ){
166
167 if( global_miniworld.mode ){
168 global_miniworld.mode = 0;
169 menu.disable_open = 0;
170 srinput.state = k_input_state_resume;
171 gui_helper_clear();
172 }
173 return;
174 }
175
176 if( button_down( k_srbind_miniworld_resume ) ){
177 global_miniworld.mode = 0;
178 global_miniworld.transition = 1;
179 global_miniworld.t = 0.0f;
180 global_miniworld.cam = skaterift.cam;
181
182 if( global_miniworld.dest_spawn ){
183 v3_copy( global_miniworld.dest_spawn->transform.co,
184 dest->player_co );
185 }
186
187 world_switch_instance(1);
188 global_miniworld.dest_spawn = NULL;
189 srinput.state = k_input_state_resume;
190 menu.disable_open = 0;
191 gui_helper_clear();
192 audio_lock();
193 audio_oneshot( &audio_ui[2], 1.0f, 0.0f );
194 audio_unlock();
195 }
196 else {
197 if( global_miniworld.mode == 1 ){
198 if( button_down(k_srbind_mback) ){
199 global_miniworld.mode = 0;
200 global_miniworld.dest_spawn = NULL;
201 menu.disable_open = 0;
202 srinput.state = k_input_state_resume;
203 miniworld_helper_default();
204 }
205 else {
206 m4x3f mmdl_inv;
207 m4x3_invert_full( global_miniworld.mmdl, mmdl_inv );
208 v3f lco;
209 m4x3_mulv( mmdl_inv, localplayer.rb.co, lco );
210 global_miniworld.dest_spawn = world_find_closest_spawn( dest, lco );
211 }
212 }
213 else {
214 if( button_down( k_srbind_miniworld_teleport ) ){
215 global_miniworld.mode = 1;
216 menu.disable_open = 1;
217 miniworld_helper_tele();
218 }
219 }
220 }
221 }
222
223 static void ent_miniworld_goback(void){
224 audio_lock();
225 audio_oneshot( &audio_ui[2], 1.0f, 0.0f );
226 audio_unlock();
227
228 global_miniworld.transition = -1;
229 global_miniworld.t = 1.0f;
230
231 global_miniworld.cam = skaterift.cam;
232 m4x3_transform_camera( global_miniworld.mmdl, &global_miniworld.cam );
233 world_switch_instance(0);
234 }