basic npc
[carveJwlIkooP6JGAAIwe30JlM.git] / world_routes_ui.c
1 #include "skaterift.h"
2 #include "world_routes_ui.h"
3 #include "world_routes.h"
4 #include "player.h"
5
6 static u32 v4_rgba( v4f colour ){
7 u32 r = vg_minf(1.0f,colour[0])*255.0f,
8 g = vg_minf(1.0f,colour[1])*255.0f,
9 b = vg_minf(1.0f,colour[2])*255.0f,
10 a = vg_minf(1.0f,colour[3])*255.0f;
11
12 return r | (g<<8) | (b<<16) | (a<<24);
13 }
14
15 static void ent_route_imgui( world_instance *world, ent_route *route,
16 ui_point inout_cursor ){
17 if( route->flags & k_ent_route_flag_out_of_zone )
18 return;
19
20 u32 last_version=0;
21 f64 last_time = 0.0;
22 ent_checkpoint *last_cp = NULL;
23
24 u32 valid_sections=0;
25
26 struct time_block{
27 f32 length, best;
28 int clean;
29 }
30 blocks[ route->checkpoints_count ];
31
32 for( u32 i=0; i<route->checkpoints_count; i++ ){
33 u32 cpid = i+route->active_checkpoint+1;
34 cpid %= route->checkpoints_count;
35 cpid += route->checkpoints_start;
36
37 ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, cpid );
38 ent_gate *rg = mdl_arritm( &world->ent_gate, cp->gate_index );
39 rg = mdl_arritm( &world->ent_gate, rg->target );
40
41 if( last_version+1 == rg->timing_version ) {
42 struct time_block *block = &blocks[ valid_sections ++ ];
43 block->clean = (rg->flags & k_ent_gate_clean_pass)? 1: 0;
44 block->length = rg->timing_time - last_time;
45 block->best = last_cp? last_cp->best_time: 0.0f;
46 }
47 else valid_sections = 0;
48
49 last_version = rg->timing_version;
50 last_time = rg->timing_time;
51 last_cp = cp;
52 }
53
54 if( last_version+1 == world_static.current_run_version ){
55 struct time_block *block = &blocks[ valid_sections ++ ];
56 block->clean = localplayer.rewinded_since_last_gate? 0: 1;
57 block->length = world_static.time - last_time;
58 block->best = last_cp->best_time;
59 }
60 else
61 valid_sections = 0;
62
63 u32 colour = v4_rgba( route->colour ) | 0xff000000;
64
65 ui_px x = 0,
66 h = route->factive * 16.0f,
67 base = inout_cursor[0];//(f32)vg.window_x*0.5f - route->ui_stopper;
68
69 if( route->ui_residual > 0.0f ){
70 ui_px w = route->ui_residual_block_w,
71 total = w + 4;
72
73 f32 t = vg_smoothstepf(1.0f-route->ui_residual);
74
75 x -= (f32)total * t;
76
77 ui_rect rect = { base+x, inout_cursor[1], w, h };
78
79 v4f fadecolour;
80 v4_copy( route->colour, fadecolour );
81 fadecolour[3] *= route->ui_residual;
82
83 ui_fill( rect, v4_rgba(fadecolour) );
84
85 x += total;
86 }
87
88 int got_first = 0;
89
90 for( u32 i=0; i<valid_sections; i ++ ){
91 struct time_block *block = &blocks[ i ];
92 ui_px w = 20 + (block->length * 6.0f);
93 ui_rect rect = { base+x, inout_cursor[1], w, h };
94 ui_fill( rect, colour );
95
96 if( block->clean )
97 ui_outline( rect, 1, 0xff00ffff, 0 );
98
99 if( block->best != 0.0f ){
100 char buf[32];
101 vg_str str;
102 vg_strnull( &str, buf, 32 );
103
104 f32 diff = block->length - block->best,
105 as = fabsf(diff),
106 s = floorf( as ),
107 ds = floorf( vg_fractf( as ) * 10.0f );
108
109 if( (block->best != 0.0f) && (fabsf(diff) > 0.001f) ){
110 if( diff > 0.0f )
111 vg_strcatch( &str, '+' );
112 else
113 vg_strcatch( &str, '-' );
114
115 vg_strcati32( &str, s );
116 vg_strcatch( &str, '.' );
117 vg_strcati32( &str, ds );
118
119 ui_text( rect, buf, 1, k_ui_align_middle_center, 0 );
120 }
121 }
122
123 x += w + 4;
124
125 if( !got_first ){
126 route->ui_first_block_width = w;
127 got_first = 1;
128 }
129 }
130
131 for( u32 i=0; i<route->checkpoints_count-valid_sections; i++ ){
132 struct time_block *block = &blocks[ i ];
133
134 ui_px w = 20;
135 ui_rect rect = { base+x, inout_cursor[1], w, h };
136 ui_outline( rect, -1, colour, 0 );
137 x += w + 4;
138
139 if( !got_first ){
140 route->ui_first_block_width = w;
141 got_first = 1;
142 }
143 }
144
145 inout_cursor[1] += h + 4;
146
147 vg_slewf( &route->ui_residual, 0.0f, vg.time_frame_delta );
148 route->ui_stopper = vg_lerpf( route->ui_stopper, (f32)x*0.5f,
149 vg.time_frame_delta );
150 }
151
152 void world_routes_imgui( world_instance *world )
153 {
154 ui_point cursor = { 4, 4 };
155 for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
156 ent_route_imgui( world, mdl_arritm( &world->ent_route, i ), cursor );
157 }
158 }