chaos pt 3
[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 else if( call->function == 1 ){
22 global_miniworld.active = NULL;
23
24 if( miniworld->proxy ){
25 ent_prop *prop = mdl_arritm( &world->ent_prop,
26 mdl_entity_id_id(miniworld->proxy) );
27 prop->flags &= ~0x1;
28 }
29 }
30 }
31
32 static void miniworld_icon( camera *cam, enum gui_icon icon, v3f pos ){
33 m4x3f mmdl;
34 v3_copy( cam->transform[2], mmdl[2] );
35 mmdl[2][1] = 0.0f;
36 v3_normalize( mmdl[2] );
37 v3_copy( (v3f){0,1,0}, mmdl[1] );
38 v3_cross( mmdl[1], mmdl[2], mmdl[0] );
39 m4x3_mulv( global_miniworld.mmdl, pos, mmdl[3] );
40
41 shader_model_font_uMdl( mmdl );
42 shader_model_font_uOffset( (v4f){0,0,0,20} );
43
44 m4x4f m4mdl;
45 m4x3_expand( mmdl, m4mdl );
46 m4x4_mul( cam->mtx_prev.pv, m4mdl, m4mdl );
47 shader_model_font_uPvmPrev( m4mdl );
48
49 mdl_submesh *sm = gui.icons[ icon ];
50 if( sm )
51 mdl_draw_submesh( sm );
52 }
53
54 static void ent_miniworld_render( world_instance *host_world, camera *cam ){
55 if( host_world != &world_static.instances[k_world_purpose_hub] )
56 return;
57
58 ent_miniworld *miniworld = global_miniworld.active;
59
60 if( !miniworld )
61 return;
62
63 world_instance *dest_world = &world_static.instances[k_world_purpose_client];
64
65 int rendering = 1;
66 if( dest_world->status != k_world_status_loaded )
67 rendering = 0;
68
69 if( miniworld->proxy ){
70 ent_prop *prop = mdl_arritm( &host_world->ent_prop,
71 mdl_entity_id_id(miniworld->proxy) );
72 if( !rendering )
73 prop->flags &= ~0x1;
74 else
75 prop->flags |= 0x1;
76 }
77
78
79 if( !rendering )
80 return;
81
82 render_world_override( dest_world, host_world, global_miniworld.mmdl, cam,
83 global_miniworld.dest_spawn );
84 render_world_routes( dest_world, host_world,
85 global_miniworld.mmdl, cam, 0, 1 );
86
87 /* icons
88 * ---------------------*/
89 font3d_bind( &gui.font, k_font_shader_default, 0, NULL, cam );
90 mesh_bind( &gui.icons_mesh );
91
92 glActiveTexture( GL_TEXTURE0 );
93 glBindTexture( GL_TEXTURE_2D, gui.icons_texture );
94 shader_model_font_uTexMain( 0 );
95 shader_model_font_uColour( (v4f){1,1,1,1} );
96
97 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_challenge); i++ ){
98 ent_challenge *challenge = mdl_arritm( &dest_world->ent_challenge, i );
99
100 enum gui_icon icon = k_gui_icon_exclaim;
101 if( challenge->status )
102 icon = k_gui_icon_tick;
103
104 miniworld_icon( cam, icon, challenge->transform.co );
105 }
106
107 for( u32 i=0; i<mdl_arrcount(&dest_world->ent_skateshop); i++ ){
108 ent_skateshop *shop = mdl_arritm( &dest_world->ent_skateshop, i );
109 if( shop->type == k_skateshop_type_boardshop ){
110 miniworld_icon( cam, k_gui_icon_board, shop->transform.co );
111 }
112 else if( shop->type == k_skateshop_type_worldshop ){
113 miniworld_icon( cam, k_gui_icon_world, shop->transform.co );
114 }
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 v4f colour;
121 v4_copy( route->colour, colour );
122 v3_muls( colour, 1.6666f, colour );
123 shader_model_font_uColour( colour );
124 miniworld_icon( cam, k_gui_icon_rift_run, route->board_transform[3] );
125 }
126 }
127
128 static void ent_miniworld_preupdate(void){
129 world_instance *hub = world_current_instance(),
130 *dest = &world_static.instances[k_world_purpose_client];
131
132 ent_miniworld *miniworld = global_miniworld.active;
133
134 if( (localplayer.subsystem != k_player_subsystem_walk) ||
135 (global_miniworld.transition) ||
136 (world_static.active_instance != k_world_purpose_hub) ||
137 (!miniworld) ||
138 (dest->status != k_world_status_loaded) ){
139
140 if( global_miniworld.mode ){
141 global_miniworld.mode = 0;
142 menu.disable_open = 0;
143 srinput.state = k_input_state_resume;
144 }
145 return;
146 }
147
148 if( button_down( k_srbind_miniworld_resume ) ){
149 global_miniworld.mode = 0;
150 global_miniworld.transition = 1;
151 global_miniworld.t = 0.0f;
152 global_miniworld.cam = skaterift.cam;
153
154 if( global_miniworld.dest_spawn ){
155 v3_copy( global_miniworld.dest_spawn->transform.co,
156 dest->player_co );
157 }
158
159 world_switch_instance(1);
160 global_miniworld.dest_spawn = NULL;
161 srinput.state = k_input_state_resume;
162 menu.disable_open = 0;
163 }
164 else {
165 if( global_miniworld.mode == 1 ){
166 if( button_down(k_srbind_mback) ){
167 global_miniworld.mode = 0;
168 global_miniworld.dest_spawn = NULL;
169 menu.disable_open = 0;
170 srinput.state = k_input_state_resume;
171 }
172 else {
173 m4x3f mmdl_inv;
174 m4x3_invert_full( global_miniworld.mmdl, mmdl_inv );
175 v3f lco;
176 m4x3_mulv( mmdl_inv, localplayer.rb.co, lco );
177 global_miniworld.dest_spawn = world_find_closest_spawn( dest, lco );
178 }
179 }
180 else {
181 if( button_down( k_srbind_miniworld_teleport ) ){
182 global_miniworld.mode = 1;
183 menu.disable_open = 1;
184 }
185 }
186 }
187 }
188
189 static void ent_miniworld_goback(void){
190 global_miniworld.transition = -1;
191 global_miniworld.t = 1.0f;
192
193 global_miniworld.cam = skaterift.cam;
194 m4x3_transform_camera( global_miniworld.mmdl, &global_miniworld.cam );
195 world_switch_instance(0);
196 }