smooth block ui
[carveJwlIkooP6JGAAIwe30JlM.git] / respawn.c
1 #ifndef RESPAWN_C
2 #define RESPAWN_C
3
4 #if 1
5 #include "respawn.h"
6 #include "skaterift.h"
7 #include "world.h"
8 #include "input.h"
9 #include "gui.h"
10 #include "menu.h"
11 #include "scene.h"
12
13 static void respawn_chooser_get_dir( v3f dir ){
14 /* idk */
15 dir[0] = -sqrtf(0.5f);
16 dir[2] = sqrtf(0.5f);
17 dir[1] = 1.0f;
18 v3_normalize(dir);
19 }
20
21 static void respawn_chooser_get_plane( v4f plane ){
22 world_instance *world = &world_static.instances[ respawn_chooser.world_id ];
23 f32 h = localplayer.rb.co[1];
24 if( respawn_chooser.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 v3f dir;
32 respawn_chooser_get_dir( dir );
33 v3_negate(dir,dir);
34 v4f plane;
35 respawn_chooser_get_plane( plane );
36
37 v3f co;
38 f32 t = ray_plane( plane, pos, dir );
39 v3_muladds( pos, dir, t, co );
40 plane_pos[0] = co[0];
41 plane_pos[1] = co[2];
42 }
43
44 static void respawn_chooser_setworld( u32 next ){
45 world_instance *nw = &world_static.instances[next];
46 if( nw->status == k_world_status_loaded ){
47 respawn_chooser.world_id = next;
48
49 v3f target;
50 if( next == world_static.active_instance )
51 v3_copy( localplayer.rb.co, target );
52 else {
53 scene_context *sc = &nw->scene_geo;
54 v3_lerp( sc->bbx[0], sc->bbx[1], 0.5f, target );
55 }
56 respawn_world_to_plane_pos( target, respawn_chooser.plane_pos );
57 }
58 }
59
60 static void respawn_chooser_gohome(void){
61 respawn_chooser_setworld(0);
62 world_instance *world = &world_static.instances[ respawn_chooser.world_id ];
63
64 const char **alias = respawn_homes[respawn_chooser.home_select];
65 ent_spawn *spawn = world_find_spawn_by_name( world, alias[0] );
66
67 if( spawn ){
68 respawn_world_to_plane_pos( spawn->transform.co,
69 respawn_chooser.plane_pos );
70
71 gui_location_print_ccmd( 1, (const char *[]){ alias[1] } );
72 }
73 else
74 gui_location_print_ccmd( 1, (const char *[]){ "Invalid home ID" } );
75 }
76
77 static void respawn_map_draw_icon( camera *cam,
78 enum gui_icon icon, v3f pos ){
79 v4f v;
80 v3_copy( pos, v );
81 v[3] = 1.0f;
82 m4x4_mulv( cam->mtx.pv, v, v );
83 v2_divs( v, v[3], v );
84
85 gui_draw_icon( icon, (v2f){ v[0]*0.5f+0.5f,v[1]*0.5f+0.5f }, 1.0f );
86 }
87
88 static void respawn_chooser_pre_update(void){
89 if( skaterift.activity != k_skaterift_respawning ) return;
90
91 if( button_down( k_srbind_mback ) ){
92 gui_helper_clear();
93 srinput.state = k_input_state_resume;
94 skaterift.activity = k_skaterift_menu;
95 menu.page = 0xffffffff;
96 menu_open_page( "Main Menu", k_ent_menuitem_stack_append );
97 return;
98 }
99
100 if( button_down( k_srbind_maccept ) ){
101 skaterift.activity = k_skaterift_default;
102 srinput.state = k_input_state_resume;
103
104 if( respawn_chooser.spawn ){
105 world_static.active_instance = respawn_chooser.world_id;
106 player__spawn( respawn_chooser.spawn );
107 }
108 return;
109 }
110
111 world_instance *world = &world_static.instances[ respawn_chooser.world_id ];
112 v3f *bbx = world->scene_geo.bbx;
113 f32 *pos = respawn_chooser.plane_pos;
114
115 v2f steer;
116 joystick_state( k_srjoystick_steer, steer );
117 v2_normalize_clamp( steer );
118
119 m2x2f rm;
120 m2x2_create_rotation( rm, -0.25f*VG_PIf );
121 m2x2_mulv( rm, steer, steer );
122
123 v2_muladds( pos, steer, vg.time_frame_delta * 200.0f, pos );
124 v2_minv( (v2f){ bbx[1][0], bbx[1][2] }, pos, pos );
125 v2_maxv( (v2f){ bbx[0][0], bbx[0][2] }, pos, pos );
126
127 /* update camera */
128 camera *cam = &respawn_chooser.cam;
129 v3f dir;
130 respawn_chooser_get_dir(dir);
131
132 v4f plane;
133 respawn_chooser_get_plane( plane );
134
135 v3f co = { pos[0], plane[3]*plane[1], pos[1] };
136 v3_muladds( co, dir, respawn_chooser.boom_dist, cam->pos );
137
138 vg_line_cross( co, VG__RED, 10.0f );
139
140 cam->angles[0] = 0.25f * VG_PIf;
141 cam->angles[1] = 0.25f * VG_PIf;
142 cam->farz = 5000.0f;
143 cam->nearz = 10.0f;
144 cam->fov = 40.0f;
145
146 camera_update_transform( cam );
147 camera_update_view( cam );
148 camera_update_projection( cam );
149 camera_finalize( cam );
150
151 /* pick spawn */
152 respawn_chooser.spawn = NULL;
153 f32 closest2 = INFINITY;
154
155 for( u32 i=0; i<mdl_arrcount(&world->ent_spawn); i++ ){
156 ent_spawn *spawn = mdl_arritm(&world->ent_spawn,i);
157
158 v4f v;
159 v3_copy( spawn->transform.co, v );
160 v[3] = 1.0f;
161 m4x4_mulv( cam->mtx.pv, v, v );
162 v2_divs( v, v[3], v );
163
164 f32 d2 = v2_length2(v);
165 if( d2 < closest2 ){
166 respawn_chooser.spawn = spawn;
167 closest2 = d2;
168 }
169 }
170
171 /* icons
172 * ---------------------*/
173 for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
174 ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i );
175
176 enum gui_icon icon = k_gui_icon_exclaim_2d;
177 if( challenge->status )
178 icon = k_gui_icon_tick_2d;
179
180 respawn_map_draw_icon( cam, icon, challenge->transform.co );
181 }
182
183 for( u32 i=0; i<mdl_arrcount(&world->ent_skateshop); i++ ){
184 ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, i );
185 if( shop->type == k_skateshop_type_boardshop ){
186 respawn_map_draw_icon( cam, k_gui_icon_board, shop->transform.co );
187 }
188 else if( shop->type == k_skateshop_type_worldshop ){
189 respawn_map_draw_icon( cam, k_gui_icon_world, shop->transform.co );
190 }
191 }
192
193 for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
194 ent_gate *gate = mdl_arritm( &world->ent_gate, i );
195 if( gate->flags & k_ent_gate_nonlocal ){
196 respawn_map_draw_icon( cam, k_gui_icon_rift, gate->co[0] );
197 }
198 }
199
200 for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
201 ent_route *route = mdl_arritm( &world->ent_route, i );
202
203 v4f colour;
204 v4_copy( route->colour, colour );
205 v3_muls( colour, 1.6666f, colour );
206 gui_icon_setcolour( colour );
207 respawn_map_draw_icon( cam, k_gui_icon_rift_run_2d,
208 route->board_transform[3] );
209 }
210 }
211
212 static void respawn_begin_chooser(void){
213 skaterift.activity = k_skaterift_respawning;
214 respawn_chooser.world_id = world_static.active_instance;
215
216 world_instance *world = &world_static.instances[ respawn_chooser.world_id ];
217 v3f *bbx = world->scene_geo.bbx;
218
219 respawn_world_to_plane_pos( localplayer.rb.co, respawn_chooser.plane_pos );
220 respawn_chooser.boom_dist = 400.0f;
221 respawn_chooser.home_select = 0;
222
223 gui_helper_clear();
224
225 vg_str text;
226 if( gui_new_helper( input_joy_list[k_srjoystick_steer], &text ) )
227 vg_strcat( &text, "move" );
228
229 if( gui_new_helper( input_button_list[k_srbind_maccept], &text ) )
230 vg_strcat( &text, "spawn" );
231
232 if( gui_new_helper( input_button_list[k_srbind_mback], &text ) )
233 vg_strcat( &text, "exit" );
234 }
235
236 #if 0
237 static void respawn_chooser_shader_uniforms(void){
238 v4f uPlayerPos, uSpawnPos;
239 v4_zero( uPlayerPos );
240 v4_zero( uSpawnPos );
241
242 v3_copy( localplayer.rb.co, uPlayerPos );
243
244 if( respawn_chooser.spawn )
245 v3_copy( respawn_chooser.spawn->transform.co, uSpawnPos );
246
247 uPlayerPos[3] = v3_dist(uPlayerPos,uSpawnPos);
248 uSpawnPos[3] = 1.0f/uPlayerPos[3];
249
250 shader_scene_override_uPlayerPos( uPlayerPos );
251 shader_scene_override_uSpawnPos( uSpawnPos );
252 }
253 #endif
254 #endif
255
256 #endif /* RESPAWN_C */