12 VG_STATIC
void respawn_chooser_get_dir( v3f dir
){
14 dir
[0] = -sqrtf(0.5f
);
20 VG_STATIC
void respawn_chooser_get_plane( v4f plane
){
21 world_instance
*world
= &world_static
.instances
[ respawn_chooser
.world_id
];
22 f32 h
= localplayer
.rb
.co
[1];
23 if( respawn_chooser
.world_id
!= world_static
.active_instance
)
24 h
= (world
->scene_geo
.bbx
[0][1] + world
->scene_geo
.bbx
[1][1]) * 0.5f
;
26 v4_copy( (v4f
){0.0f
,1.0f
,0.0f
,h
}, plane
);
29 VG_STATIC
void respawn_world_to_plane_pos( v3f pos
, v2f plane_pos
){
31 respawn_chooser_get_dir( dir
);
34 respawn_chooser_get_plane( plane
);
37 f32 t
= ray_plane( plane
, pos
, dir
);
38 v3_muladds( pos
, dir
, t
, co
);
43 VG_STATIC
void respawn_chooser_setworld( u32 next
){
44 world_instance
*nw
= &world_static
.instances
[next
];
45 if( nw
->status
== k_world_status_loaded
){
46 respawn_chooser
.world_id
= next
;
49 if( next
== world_static
.active_instance
)
50 v3_copy( localplayer
.rb
.co
, target
);
52 scene_context
*sc
= &nw
->scene_geo
;
53 v3_lerp( sc
->bbx
[0], sc
->bbx
[1], 0.5f
, target
);
55 respawn_world_to_plane_pos( target
, respawn_chooser
.plane_pos
);
59 VG_STATIC
void respawn_chooser_gohome(void){
60 respawn_chooser_setworld(0);
61 world_instance
*world
= &world_static
.instances
[ respawn_chooser
.world_id
];
63 const char **alias
= respawn_homes
[respawn_chooser
.home_select
];
64 ent_spawn
*spawn
= world_find_spawn_by_name( world
, alias
[0] );
67 respawn_world_to_plane_pos( spawn
->transform
.co
,
68 respawn_chooser
.plane_pos
);
70 gui_location_print_ccmd( 1, (const char *[]){ alias
[1] } );
73 gui_location_print_ccmd( 1, (const char *[]){ "Invalid home ID" } );
77 VG_STATIC
void respawn_chooser_pre_update(void){
78 if( skaterift
.activity
!= k_skaterift_respawning
) return;
80 gui_helper_action( joystick_display_string(k_srjoystick_steer
,2), "move" );
81 if( world_static
.instances
[0].status
== k_world_status_loaded
)
82 gui_helper_action( axis_display_string(k_sraxis_mworld_h
), "world" );
83 gui_helper_action( button_display_string(k_srbind_maccept
), "spawn" );
84 gui_helper_action( button_display_string(k_srbind_home
), "home" );
86 if( button_down( k_srbind_mback
) ){
88 skaterift
.activity
= k_skaterift_menu
;
89 menu
.page
= 0xffffffff;
90 menu_open_page( "Main Menu", k_ent_menuitem_stack_append
);
94 if( button_down( k_srbind_maccept
) ){
95 skaterift
.activity
= k_skaterift_default
;
98 if( respawn_chooser
.spawn
){
99 world_static
.active_instance
= respawn_chooser
.world_id
;
100 localplayer
.viewable_world
=
101 &world_static
.instances
[ respawn_chooser
.world_id
];
102 player__spawn( &localplayer
, respawn_chooser
.spawn
);
107 if( button_down( k_srbind_world_left
) ){
108 if( respawn_chooser
.world_id
> 0 )
109 respawn_chooser_setworld( respawn_chooser
.world_id
-1 );
112 if( button_down( k_srbind_world_right
) ){
113 u32 next
= respawn_chooser
.world_id
+1;
114 if( next
< vg_list_size(world_static
.instances
) )
115 respawn_chooser_setworld( next
);
118 if( button_down(k_srbind_home
) ){
119 respawn_chooser
.home_select
++;
120 if( respawn_chooser
.home_select
>= vg_list_size(respawn_homes
) )
121 respawn_chooser
.home_select
= 0;
122 respawn_chooser_gohome();
125 world_instance
*world
= &world_static
.instances
[ respawn_chooser
.world_id
];
126 v3f
*bbx
= world
->scene_geo
.bbx
;
127 f32
*pos
= respawn_chooser
.plane_pos
;
130 joystick_state( k_srjoystick_steer
, steer
);
131 v2_normalize_clamp( steer
);
134 m2x2_create_rotation( rm
, -0.25f
*VG_PIf
);
135 m2x2_mulv( rm
, steer
, steer
);
137 v2_muladds( pos
, steer
, vg
.time_frame_delta
* 200.0f
, pos
);
138 v2_minv( (v2f
){ bbx
[1][0], bbx
[1][2] }, pos
, pos
);
139 v2_maxv( (v2f
){ bbx
[0][0], bbx
[0][2] }, pos
, pos
);
142 camera
*cam
= &respawn_chooser
.cam
;
144 respawn_chooser_get_dir(dir
);
147 respawn_chooser_get_plane( plane
);
149 v3f co
= { pos
[0], plane
[3]*plane
[1], pos
[1] };
150 v3_muladds( co
, dir
, respawn_chooser
.boom_dist
, cam
->pos
);
152 vg_line_cross( co
, VG__RED
, 10.0f
);
154 cam
->angles
[0] = 0.25f
* VG_PIf
;
155 cam
->angles
[1] = 0.25f
* VG_PIf
;
160 camera_update_transform( cam
);
161 camera_update_view( cam
);
162 camera_update_projection( cam
);
163 camera_finalize( cam
);
166 respawn_chooser
.spawn
= NULL
;
167 f32 closest2
= INFINITY
;
169 for( u32 i
=0; i
<mdl_arrcount(&world
->ent_spawn
); i
++ ){
170 ent_spawn
*spawn
= mdl_arritm(&world
->ent_spawn
,i
);
173 v3_copy( spawn
->transform
.co
, v
);
175 m4x4_mulv( cam
->mtx
.pv
, v
, v
);
177 f32 d2
= v2_length2(v
);
179 respawn_chooser
.spawn
= spawn
;
184 if( respawn_chooser
.spawn
){
185 vg_line_cross( respawn_chooser
.spawn
->transform
.co
, VG__GREEN
, 5.0f
);
189 VG_STATIC
void respawn_begin_chooser(void){
190 skaterift
.activity
= k_skaterift_respawning
;
191 respawn_chooser
.world_id
= world_static
.active_instance
;
193 world_instance
*world
= &world_static
.instances
[ respawn_chooser
.world_id
];
194 v3f
*bbx
= world
->scene_geo
.bbx
;
196 respawn_world_to_plane_pos( localplayer
.rb
.co
, respawn_chooser
.plane_pos
);
197 respawn_chooser
.boom_dist
= 400.0f
;
198 respawn_chooser
.home_select
= 0;
201 VG_STATIC
void respawn_chooser_shader_uniforms(void){
202 v4f uPlayerPos
, uSpawnPos
;
203 v4_zero( uPlayerPos
);
204 v4_zero( uSpawnPos
);
206 v3_copy( localplayer
.rb
.co
, uPlayerPos
);
208 if( respawn_chooser
.spawn
)
209 v3_copy( respawn_chooser
.spawn
->transform
.co
, uSpawnPos
);
211 uPlayerPos
[3] = v3_dist(uPlayerPos
,uSpawnPos
);
212 uSpawnPos
[3] = 1.0f
/uPlayerPos
[3];
214 shader_scene_override_uPlayerPos( uPlayerPos
);
215 shader_scene_override_uSpawnPos( uSpawnPos
);
218 #endif /* RESPAWN_C */