Update spawn map to new UI
[carveJwlIkooP6JGAAIwe30JlM.git] / world_map.c
1 #include "skaterift.h"
2 #include "world_map.h"
3 #include "world.h"
4 #include "input.h"
5 #include "gui.h"
6 #include "menu.h"
7 #include "scene.h"
8
9 struct world_map world_map;
10
11 static void world_map_get_dir( v3f dir )
12 {
13 /* idk */
14 dir[0] = -sqrtf(0.5f);
15 dir[2] = sqrtf(0.5f);
16 dir[1] = 1.0f;
17 v3_normalize(dir);
18 }
19
20 static void world_map_get_plane( v4f plane )
21 {
22 world_instance *world = &world_static.instances[ world_map.world_id ];
23 f32 h = localplayer.rb.co[1];
24 if( world_map.world_id != world_static.active_instance )
25 h = (world->scene_geo.bbx[0][1] + world->scene_geo.bbx[1][1]) * 0.5f;
26
27 v4_copy( (v4f){0.0f,1.0f,0.0f,h}, plane );
28 }
29
30 static void respawn_world_to_plane_pos( v3f pos, v2f plane_pos )
31 {
32 v3f dir;
33 world_map_get_dir( dir );
34 v3_negate(dir,dir);
35 v4f plane;
36 world_map_get_plane( plane );
37
38 v3f co;
39 f32 t = ray_plane( plane, pos, dir );
40 v3_muladds( pos, dir, t, co );
41 plane_pos[0] = co[0];
42 plane_pos[1] = co[2];
43 }
44
45 static void respawn_map_draw_icon( vg_camera *cam,
46 enum gui_icon icon, v3f pos, f32 size )
47 {
48 v4f v;
49 v3_copy( pos, v );
50 v[3] = 1.0f;
51 m4x4_mulv( cam->mtx.pv, v, v );
52 v2_divs( v, v[3], v );
53
54 gui_draw_icon( icon, (v2f){ v[0]*0.5f+0.5f,v[1]*0.5f+0.5f }, size );
55 }
56
57 static void world_map_select_close(void)
58 {
59 world_map.sel_spawn = world_map.close_spawn;
60 gui_helper_clear();
61
62 vg_str text;
63 if( gui_new_helper( input_button_list[k_srbind_maccept], &text ) )
64 vg_strcat( &text, "Spawn Here" );
65 if( gui_new_helper( input_button_list[k_srbind_mback], &text ) )
66 vg_strcat( &text, "Back" );
67 }
68
69 void world_map_click(void)
70 {
71 world_map_select_close();
72 }
73
74 static void world_map_help_normal(void)
75 {
76 gui_helper_clear();
77
78 vg_str text;
79 if( gui_new_helper( input_joy_list[k_srjoystick_steer], &text ) )
80 vg_strcat( &text, "Move" );
81
82 if( gui_new_helper( input_button_list[k_srbind_maccept], &text ) )
83 vg_strcat( &text, "Select" );
84
85 if( gui_new_helper( input_button_list[k_srbind_mback], &text ) )
86 vg_strcat( &text, "Exit" );
87 }
88
89 void world_map_pre_update(void)
90 {
91 if( menu_viewing_map() )
92 {
93 if( !world_map.view_ready )
94 {
95 world_map.world_id = world_static.active_instance;
96
97 world_instance *world = &world_static.instances[ world_map.world_id ];
98 v3f *bbx = world->scene_geo.bbx;
99
100 v3_copy( localplayer.rb.co, world->player_co );
101 respawn_world_to_plane_pos( localplayer.rb.co, world_map.plane_pos );
102 world_map.boom_dist = 400.0f;
103 world_map.home_select = 0;
104 world_map.view_ready = 1;
105 world_map.sel_spawn = NULL;
106 world_map.close_spawn = NULL;
107
108 world_map_help_normal();
109 }
110 }
111 else
112 {
113 if( world_map.view_ready )
114 {
115 gui_helper_clear();
116 world_map.view_ready = 0;
117 }
118
119 return;
120 }
121
122 world_instance *world = &world_static.instances[ world_map.world_id ];
123 v3f *bbx = world->scene_geo.bbx;
124 f32 *pos = world_map.plane_pos;
125
126 v2f steer;
127 joystick_state( k_srjoystick_steer, steer );
128 v2_normalize_clamp( steer );
129
130 if( !world_map.sel_spawn )
131 {
132 f32 *pos = world_map.plane_pos;
133 m2x2f rm;
134 m2x2_create_rotation( rm, -0.25f*VG_PIf );
135 m2x2_mulv( rm, steer, steer );
136 v2_muladds( pos, steer, vg.time_frame_delta * 200.0f, pos );
137 }
138
139 f32 bd_target = 400.0f,
140 interp = vg.time_frame_delta*2.0f;
141
142 if( world_map.sel_spawn )
143 {
144 v2f pp;
145 respawn_world_to_plane_pos( world_map.sel_spawn->transform.co, pp );
146 v2_lerp( pos, pp, interp, pos );
147
148 bd_target = 200.0f;
149 }
150 world_map.boom_dist = vg_lerpf( world_map.boom_dist, bd_target, interp );
151
152 v2_minv( (v2f){ bbx[1][0], bbx[1][2] }, pos, pos );
153 v2_maxv( (v2f){ bbx[0][0], bbx[0][2] }, pos, pos );
154
155 /* update camera */
156 vg_camera *cam = &world_map.cam;
157 v3f dir;
158 world_map_get_dir(dir);
159
160 v4f plane;
161 world_map_get_plane( plane );
162
163 v3f co = { pos[0], plane[3]*plane[1], pos[1] };
164 v3_muladds( co, dir, world_map.boom_dist, cam->pos );
165
166 vg_line_cross( co, VG__RED, 10.0f );
167
168 cam->angles[0] = 0.25f * VG_PIf;
169 cam->angles[1] = 0.25f * VG_PIf;
170 cam->farz = 5000.0f;
171 cam->nearz = 10.0f;
172 cam->fov = 40.0f;
173
174 vg_camera_update_transform( cam );
175 vg_camera_update_view( cam );
176 vg_camera_update_projection( cam );
177 vg_camera_finalize( cam );
178
179 /* pick spawn */
180 f32 closest2 = INFINITY;
181 v2f centroid = { 0, 0 };
182
183 for( u32 i=0; i<mdl_arrcount(&world->ent_spawn); i++ )
184 {
185 ent_spawn *spawn = mdl_arritm(&world->ent_spawn,i);
186
187 v4f v;
188 v3_copy( spawn->transform.co, v );
189 v[3] = 1.0f;
190 m4x4_mulv( cam->mtx.pv, v, v );
191 v2_divs( v, v[3], v );
192
193 f32 d2 = v2_dist2(v, centroid);
194 if( d2 < closest2 )
195 {
196 world_map.close_spawn = spawn;
197 closest2 = d2;
198 }
199 spawn->transform.s[0] = d2;
200 }
201
202 if( button_down( k_srbind_maccept ) )
203 {
204 if( world_map.sel_spawn )
205 {
206 skaterift.activity = k_skaterift_default;
207 world_static.active_instance = world_map.world_id;
208 srinput.state = k_input_state_resume;
209 player__spawn( world_map.sel_spawn );
210 return;
211 }
212 else
213 {
214 world_map_select_close();
215 }
216 }
217
218 if( button_down( k_srbind_mback ) )
219 {
220 if( world_map.sel_spawn )
221 {
222 world_map.sel_spawn = NULL;
223 world_map_help_normal();
224 }
225 else
226 {
227 srinput.state = k_input_state_resume;
228 skaterift.activity = k_skaterift_default;
229 return;
230 }
231 }
232
233 /* icons
234 * ---------------------*/
235 for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ )
236 {
237 ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i );
238
239 enum gui_icon icon = k_gui_icon_exclaim_2d;
240 if( challenge->status )
241 icon = k_gui_icon_tick_2d;
242
243 respawn_map_draw_icon( cam, icon, challenge->transform.co, 1.0f );
244 }
245
246 for( u32 i=0; i<mdl_arrcount(&world->ent_spawn); i ++ )
247 {
248 ent_spawn *spawn = mdl_arritm( &world->ent_spawn, i );
249
250 if( spawn->transform.s[0] > 0.3f )
251 continue;
252
253 f32 s = 1.0f-(spawn->transform.s[0] / 0.3f);
254 respawn_map_draw_icon( cam,
255 spawn==world_map.sel_spawn?
256 k_gui_icon_spawn_select: k_gui_icon_spawn,
257 spawn->transform.co, s );
258 }
259
260 for( u32 i=0; i<mdl_arrcount(&world->ent_skateshop); i++ )
261 {
262 ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, i );
263 if( shop->type == k_skateshop_type_boardshop )
264 {
265 respawn_map_draw_icon( cam, k_gui_icon_board, shop->transform.co, 1 );
266 }
267 else if( shop->type == k_skateshop_type_worldshop )
268 {
269 respawn_map_draw_icon( cam, k_gui_icon_world, shop->transform.co, 1 );
270 }
271 }
272
273 for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ )
274 {
275 ent_gate *gate = mdl_arritm( &world->ent_gate, i );
276 if( gate->flags & k_ent_gate_nonlocal )
277 {
278 respawn_map_draw_icon( cam, k_gui_icon_rift, gate->co[0], 1 );
279 }
280 }
281
282 for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ )
283 {
284 ent_route *route = mdl_arritm( &world->ent_route, i );
285
286 v4f colour;
287 v4_copy( route->colour, colour );
288 v3_muls( colour, 1.6666f, colour );
289 gui_icon_setcolour( colour );
290 respawn_map_draw_icon( cam, k_gui_icon_rift_run_2d,
291 route->board_transform[3], 1 );
292 }
293
294 for( u32 i=0; i<mdl_arrcount(&world->ent_glider); i ++ )
295 {
296 ent_glider *glider = mdl_arritm( &world->ent_glider, i );
297
298 v4f colour = { 1,1,1,1 };
299
300 if( !(glider->flags & 0x1) )
301 v3_muls( colour, 0.5f, colour );
302 gui_icon_setcolour( colour );
303
304 respawn_map_draw_icon( cam, k_gui_icon_glider, glider->transform.co, 1 );
305 }
306 }