From: hgn Date: Sat, 24 Feb 2024 04:38:57 +0000 (+0000) Subject: basic npc X-Git-Url: https://harrygodden.com/git/?p=carveJwlIkooP6JGAAIwe30JlM.git;a=commitdiff_plain;h=14851c4c820eb07a0db0ec0366a70bdd6518c331 basic npc --- diff --git a/blender_export.py b/blender_export.py index 421cf5d..7c8c69f 100644 --- a/blender_export.py +++ b/blender_export.py @@ -45,6 +45,7 @@ sr_entity_list = [ ('ent_list', 'Entity List', '', 24 ), ('ent_region', 'Region', '', 25 ), ('ent_glider', 'Glider', '', 26 ), + ('ent_npc', 'npc', '', 27 ) ] MDL_VERSION_NR = 105 @@ -302,6 +303,12 @@ class ent_glider(Structure):#{ 1: 'equip' } #} +class ent_npc(Structure):#{ + _fields_ = [("transform",mdl_transform), + ("id",c_uint32), + ("context",c_uint32)] +#} + class ent_water(Structure): #{ _fields_ = [("transform",mdl_transform), @@ -2067,6 +2074,14 @@ def sr_compile( collection ): compile_obj_transform( obj, glider.transform ) sr_ent_push( glider ) #} + elif ent_type == 'ent_npc':#{ + obj_data = obj.SR_data.ent_npc[0] + npc = ent_npc() + compile_obj_transform( obj, npc.transform ) + npc.id = obj_data.au + npc.context = obj_data.context + sr_ent_push( npc ) + #} elif ent_type == 'ent_cubemap':#{ cubemap = ent_cubemap() co = obj.matrix_world @ Vector((0,0,0)) @@ -3148,6 +3163,11 @@ class SR_OBJECT_ENT_GLIDER(bpy.types.PropertyGroup):#{ nothing: bpy.props.StringProperty() #} +class SR_OBJECT_ENT_NPC(bpy.types.PropertyGroup):#{ + au: bpy.props.IntProperty() + context: bpy.props.IntProperty() +#} + class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{ subtype: bpy.props.EnumProperty( name="Subtype", @@ -3651,6 +3671,7 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): ent_miniworld: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_MINIWORLD) ent_list: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_LIST) ent_glider: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_GLIDER) + ent_npc: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_NPC) ent_type: bpy.props.EnumProperty( name="Type", @@ -4930,7 +4951,7 @@ classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\ SR_OBJECT_ENT_RELAY,SR_OBJECT_ENT_MINIWORLD,\ SR_OBJECT_ENT_LIST_ENTRY, SR_UL_ENT_LIST, SR_OBJECT_ENT_LIST, \ SR_OT_ENT_LIST_NEW_ITEM, SR_OT_ENT_LIST_DEL_ITEM,\ - SR_OBJECT_ENT_GLIDER, \ + SR_OBJECT_ENT_GLIDER, SR_OBJECT_ENT_NPC, \ \ SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES, SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \ diff --git a/ent_challenge.c b/ent_challenge.c index ce87366..c2ee3b6 100644 --- a/ent_challenge.c +++ b/ent_challenge.c @@ -1,3 +1,4 @@ +#include "vg/vg_engine.h" #include "entity.h" #include "input.h" #include "gui.h" diff --git a/ent_glider.c b/ent_glider.c index d1e2a36..dbea8ea 100644 --- a/ent_glider.c +++ b/ent_glider.c @@ -2,7 +2,8 @@ #include "entity.h" #include "player_glide.h" -static void ent_glider_call( world_instance *world, ent_call *call ){ +void ent_glider_call( world_instance *world, ent_call *call ) +{ u32 index = mdl_entity_id_id( call->id ); ent_glider *glider = mdl_arritm( &world->ent_glider, index ); diff --git a/ent_glider.h b/ent_glider.h index e61bdd0..51857b2 100644 --- a/ent_glider.h +++ b/ent_glider.h @@ -1,4 +1,4 @@ #pragma once #include "entity.h" -static void ent_glider_call( world_instance *world, ent_call *call ); +void ent_glider_call( world_instance *world, ent_call *call ); diff --git a/ent_miniworld.c b/ent_miniworld.c index 4f22df8..fcdba0b 100644 --- a/ent_miniworld.c +++ b/ent_miniworld.c @@ -1,9 +1,11 @@ #include "entity.h" #include "ent_miniworld.h" #include "world_render.h" +#include "world_load.h" #include "input.h" #include "gui.h" #include "menu.h" +#include "audio.h" struct global_miniworld global_miniworld; diff --git a/ent_npc.c b/ent_npc.c new file mode 100644 index 0000000..048a1b9 --- /dev/null +++ b/ent_npc.c @@ -0,0 +1,90 @@ +#include "vg/vg_mem.h" +#include "ent_npc.h" +#include "shaders/model_character_view.h" + +struct npc npc_gumpa; +static struct skeleton_anim *gumpa_idle; + +void npc_load_model( struct npc *npc, const char *path ) +{ + vg_linear_clear( vg_mem.scratch ); + + mdl_context *meta = &npc->meta; + mdl_open( meta, path, vg_mem.rtmemory ); + mdl_load_metadata_block( meta, vg_mem.rtmemory ); + mdl_load_animation_block( meta, vg_mem.rtmemory ); + + struct skeleton *sk = &npc->skeleton; + skeleton_setup( sk, vg_mem.rtmemory, meta ); + + u32 mtx_size = sizeof(m4x3f)*sk->bone_count; + npc->final_mtx = vg_linear_alloc( vg_mem.rtmemory, mtx_size ); + + if( !mdl_arrcount( &meta->textures ) ) + vg_fatal_error( "No texture in model" ); + + mdl_texture *tex0 = mdl_arritm( &meta->textures, 0 ); + void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size ); + mdl_fread_pack_file( meta, &tex0->file, data ); + + vg_tex2d_load_qoi_async( data, tex0->file.pack_size, + VG_TEX2D_NEAREST|VG_TEX2D_CLAMP, + &npc->texture ); + + mdl_async_load_glmesh( meta, &npc->mesh, NULL ); + mdl_close( meta ); +} + +void npc_init(void) +{ + npc_load_model( &npc_gumpa, "models/gumpa.mdl" ); + gumpa_idle = skeleton_get_anim( &npc_gumpa.skeleton, "gumpa_idle" ); +} + +static struct npc *npc_resolve( u32 id ) +{ + if( id == 1 ) return &npc_gumpa; + else return NULL; +} + +void npc_update( ent_npc *ent ) +{ + struct npc *npc_def = npc_resolve( ent->id ); + VG_ASSERT( npc_def ); + + player_pose pose; + struct skeleton *sk = &npc_def->skeleton; + pose.type = k_player_pose_type_ik; + pose.board.lean = 0.0f; + + skeleton_sample_anim( sk, gumpa_idle, vg.time, pose.keyframes ); + + v3_copy( ent->transform.co, pose.root_co ); + v4_copy( ent->transform.q, pose.root_q ); + apply_full_skeleton_pose( &npc_def->skeleton, &pose, npc_def->final_mtx ); +} + +void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam ) +{ + struct npc *npc_def = npc_resolve( ent->id ); + VG_ASSERT( npc_def ); + + shader_model_character_view_use(); + + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, npc_def->texture ); + shader_model_character_view_uTexMain( 0 ); + shader_model_character_view_uCamera( cam->transform[3] ); + shader_model_character_view_uPv( cam->mtx.pv ); + shader_model_character_view_uDepthCompare( 0 ); + + WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_character_view ); + + glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms, + npc_def->skeleton.bone_count, + 0, + (const GLfloat *)npc_def->final_mtx ); + + mesh_bind( &npc_def->mesh ); + mesh_draw( &npc_def->mesh ); +} diff --git a/ent_npc.h b/ent_npc.h new file mode 100644 index 0000000..f474d0d --- /dev/null +++ b/ent_npc.h @@ -0,0 +1,26 @@ +#pragma once +#include "player_render.h" +#include "entity.h" + +struct npc +{ + glmesh mesh; + GLuint texture; + + mdl_context meta; + struct skeleton skeleton; + + m4x3f *final_mtx; +} +extern npc_gumpa; + +enum npc_id +{ + k_npc_id_none = 0, + k_npc_id_gumpa = 1 +}; + +void npc_load_model( struct npc *npc, const char *path ); +void npc_update( ent_npc *ent ); +void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam ); +void npc_init(void); diff --git a/ent_region.h b/ent_region.h index 4b27825..8aed240 100644 --- a/ent_region.h +++ b/ent_region.h @@ -1,5 +1,6 @@ #pragma once #include "world_entity.h" +#include "network_common.h" struct global_ent_region { diff --git a/ent_traffic.c b/ent_traffic.c index 5735d5b..8bb19b9 100644 --- a/ent_traffic.c +++ b/ent_traffic.c @@ -1,6 +1,7 @@ #include "world.h" -static void ent_traffic_update( world_instance *world, v3f pos ){ +void ent_traffic_update( world_instance *world, v3f pos ) +{ for( u32 i=0; ient_traffic ); i++ ){ ent_traffic *traffic = mdl_arritm( &world->ent_traffic, i ); diff --git a/entity.h b/entity.h index a925318..105f449 100644 --- a/entity.h +++ b/entity.h @@ -36,6 +36,7 @@ typedef struct ent_prop ent_prop; typedef struct ent_region ent_region; typedef struct ent_list ent_list; typedef struct ent_glider ent_glider; +typedef struct ent_npc ent_npc; enum entity_alias{ k_ent_none = 0, @@ -64,7 +65,8 @@ enum entity_alias{ k_ent_prop = 23, k_ent_list = 24, k_ent_region = 25, - k_ent_glider = 26 + k_ent_glider = 26, + k_ent_npc = 27 }; static inline u32 mdl_entity_id_type( u32 entity_id ) @@ -557,5 +559,11 @@ struct ent_glider { f32 cooldown; }; +struct ent_npc +{ + mdl_transform transform; + u32 id, context; +}; + #include "world.h" void entity_call( world_instance *world, ent_call *call ); diff --git a/freecam.c b/freecam.c index 246af3c..45713c6 100644 --- a/freecam.c +++ b/freecam.c @@ -1,4 +1,6 @@ #include "skaterift.h" +#include "player.h" +#include "player_render.h" #include "player_replay.h" #include "input.h" diff --git a/maps_src/dev_hub/main.mdl b/maps_src/dev_hub/main.mdl index 5772a92..75298a2 100644 Binary files a/maps_src/dev_hub/main.mdl and b/maps_src/dev_hub/main.mdl differ diff --git a/models_src/gumpa.mdl b/models_src/gumpa.mdl new file mode 100644 index 0000000..d0ccc28 Binary files /dev/null and b/models_src/gumpa.mdl differ diff --git a/player_common.c b/player_common.c index 2551968..e1961b9 100644 --- a/player_common.c +++ b/player_common.c @@ -4,13 +4,15 @@ #include "menu.h" #include "vg/vg_perlin.h" -static float player_get_heading_yaw(void){ +float player_get_heading_yaw(void) +{ v3f xz; q_mulv( localplayer.rb.q, (v3f){ 0.0f,0.0f,1.0f }, xz ); return atan2f( xz[0], xz[2] ); } -static void player_camera_portal_correction(void){ +static void player_camera_portal_correction(void) +{ if( localplayer.gate_waiting ){ /* construct plane equation for reciever gate */ v4f plane; @@ -59,7 +61,8 @@ static void player_camera_portal_correction(void){ } } -static void player__cam_iterate(void){ +void player__cam_iterate(void) +{ struct player_cam_controller *cc = &localplayer.cam_control; if( localplayer.subsystem == k_player_subsystem_walk ){ @@ -252,7 +255,8 @@ static void player__cam_iterate(void){ player_camera_portal_correction(); } -static void player_look( v3f angles, float speed ){ +void player_look( v3f angles, float speed ) +{ if( vg_ui.wants_mouse ) return; angles[2] = 0.0f; diff --git a/player_common.h b/player_common.h index 4510835..b32faee 100644 --- a/player_common.h +++ b/player_common.h @@ -1,6 +1,4 @@ -#ifndef PLAYER_COMMON_H -#define PLAYER_COMMON_H - +#pragma once #include "player_api.h" static float @@ -13,12 +11,6 @@ static float static i32 k_player_debug_info = 0; static ui_rect g_player_debugger; -static void player_look( v3f angles, float speed ); -static void player__cam_iterate(void); -static struct player_board - *player_get_player_board( struct player_instance *player ); -static struct player_model - *player_get_player_model( struct player_instance *player ); -static f32 player_get_heading_yaw(void); - -#endif /* PLAYER_COMMON_H */ +void player_look( v3f angles, float speed ); +void player__cam_iterate(void); +f32 player_get_heading_yaw(void); diff --git a/player_effects.c b/player_effects.c index feca984..981c232 100644 --- a/player_effects.c +++ b/player_effects.c @@ -1,3 +1,4 @@ +#include "player.h" #include "player_effects.h" #include "player_render.h" #include "particle.h" diff --git a/player_effects.h b/player_effects.h index 50caabc..f148dbc 100644 --- a/player_effects.h +++ b/player_effects.h @@ -1,5 +1,6 @@ #pragma once #include "vg/vg_platform.h" +#include "player_render.h" typedef struct effect_blink effect_blink; typedef struct effect_spark effect_spark; diff --git a/player_replay.c b/player_replay.c index 1994eb6..887c6f1 100644 --- a/player_replay.c +++ b/player_replay.c @@ -1,4 +1,5 @@ #include "skaterift.h" +#include "player.h" #include "player_replay.h" #include "input.h" #include "gui.h" diff --git a/player_walk.c b/player_walk.c index 68415dd..b892634 100644 --- a/player_walk.c +++ b/player_walk.c @@ -1,5 +1,3 @@ -#pragma once - #include "vg/vg_rigidbody_collision.h" #include "skaterift.h" diff --git a/save.c b/save.c index db609ca..73eaa49 100644 --- a/save.c +++ b/save.c @@ -5,6 +5,7 @@ #include "vg/vg_log.h" #include "vg/vg_loader.h" #include "world.h" +#include "player.h" static const char *str_skaterift_main_save = "save.bkv"; static f64 last_autosave; diff --git a/skaterift.c b/skaterift.c index 8d79e9e..7d28c0a 100644 --- a/skaterift.c +++ b/skaterift.c @@ -39,6 +39,7 @@ #include "ent_tornado.h" #include "ent_miniworld.h" #include "ent_skateshop.h" +#include "ent_npc.h" #include "world_map.h" #include "gui.h" #include "workshop.h" @@ -222,6 +223,7 @@ void vg_load(void) vg_loader_step( player_init, NULL ); vg_loader_step( player_ragdoll_init, NULL ); + vg_loader_step( npc_init, NULL ); /* content stuff */ vg_loader_step( addon_system_init, NULL ); @@ -775,3 +777,4 @@ void vg_gui(void) #include "world_sfd.c" #include "world_volumes.c" #include "world_water.c" +#include "ent_npc.c" diff --git a/world.h b/world.h index 823b38c..93bc195 100644 --- a/world.h +++ b/world.h @@ -6,6 +6,7 @@ #include "render.h" #include "network_msg.h" #include "addon.h" +#include "scene.h" /* types */ @@ -186,7 +187,8 @@ struct world_instance { ent_miniworld, ent_prop, ent_region, - ent_glider; + ent_glider, + ent_npc; enum skybox { k_skybox_default, diff --git a/world_entity.c b/world_entity.c index 3602530..725c898 100644 --- a/world_entity.c +++ b/world_entity.c @@ -214,7 +214,8 @@ void world_gen_entities_init( world_instance *world ) { k_ent_objective, &world->ent_objective }, { k_ent_volume, &world->ent_volume }, { k_ent_challenge, &world->ent_challenge }, - { k_ent_glider, &world->ent_glider } + { k_ent_glider, &world->ent_glider }, + { k_ent_npc, &world->ent_npc } }; for( u32 i=0; ient_npc, index ); + box_addpt( bound, npc->transform.co ); + } else{ vg_fatal_error( "Programming error\n" ); } @@ -535,15 +541,23 @@ float entity_bh_centroid( void *user, u32 item_index, int axis ) ent_volume *volume = mdl_arritm( &world->ent_volume, index ); return volume->transform.co[axis]; } - else if( type == k_ent_challenge ){ + else if( type == k_ent_challenge ) + { ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index ); return challenge->transform.co[axis]; } - else if( type == k_ent_glider ){ + else if( type == k_ent_glider ) + { ent_glider *glider = mdl_arritm( &world->ent_glider, index ); return glider->transform.co[axis]; } - else { + else if( type == k_ent_npc ) + { + ent_npc *npc = mdl_arritm( &world->ent_npc, index ); + return npc->transform.co[axis]; + } + else + { vg_fatal_error( "Programming error\n" ); return INFINITY; } diff --git a/world_gate.h b/world_gate.h index 03e4568..6339f1d 100644 --- a/world_gate.h +++ b/world_gate.h @@ -7,6 +7,7 @@ #include "vg/vg_camera.h" #include "world.h" #include "shaders/model_gate.h" +#include "entity.h" struct world_gates { diff --git a/world_gen.c b/world_gen.c index 047155e..bc9b222 100644 --- a/world_gen.c +++ b/world_gen.c @@ -206,7 +206,8 @@ void world_unpack_submesh_dynamic( world_instance *world, /* * Create the main meshes for the world */ -static void world_gen_generate_meshes( world_instance *world ){ +void world_gen_generate_meshes( world_instance *world ) +{ /* * Compile meshes into the world scenes */ @@ -395,7 +396,8 @@ static void async_upload_light_indices( void *payload, u32 size ){ /* * Computes light indices for world */ -static void world_gen_compute_light_indices( world_instance *world ){ +void world_gen_compute_light_indices( world_instance *world ) +{ /* light cubes */ v3f cubes_min, cubes_max; v3_muls( world->scene_geo.bbx[0], 1.0f/k_world_light_cube_size, cubes_min ); @@ -555,7 +557,8 @@ static void world_gen_compute_light_indices( world_instance *world ){ /* * Rendering pass needed to complete the world */ -static void async_world_postprocess( void *payload, u32 _size ){ +void async_world_postprocess( void *payload, u32 _size ) +{ /* create scene lighting buffer */ world_instance *world = payload; @@ -709,7 +712,8 @@ static void async_world_postprocess( void *payload, u32 _size ){ } /* Loads textures from the pack file */ -static void world_gen_load_surfaces( world_instance *world ){ +void world_gen_load_surfaces( world_instance *world ) +{ vg_info( "Loading textures\n" ); world->texture_count = 0; diff --git a/world_gen.h b/world_gen.h index ba4adc5..c6ffb92 100644 --- a/world_gen.h +++ b/world_gen.h @@ -5,15 +5,11 @@ * create geometry, apply procedural stuff and save that image to files etc. */ -#ifndef WORLD_GEN_H -#define WORLD_GEN_H - +#pragma once #include "world.h" -static void world_init_blank( world_instance *world ); -static void world_gen_load_surfaces( world_instance *world ); -static void world_gen_generate_meshes( world_instance *world ); -static void world_gen_compute_light_indices( world_instance *world ); -static void async_world_postprocess( void *payload, u32 _size ); - -#endif /* WORLD_GEN_H */ +void world_init_blank( world_instance *world ); +void world_gen_load_surfaces( world_instance *world ); +void world_gen_generate_meshes( world_instance *world ); +void world_gen_compute_light_indices( world_instance *world ); +void async_world_postprocess( void *payload, u32 _size ); diff --git a/world_load.c b/world_load.c index f124e24..b741a31 100644 --- a/world_load.c +++ b/world_load.c @@ -71,6 +71,7 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){ MDL_LOAD_ARRAY( meta, &world->ent_prop, ent_prop, heap ); MDL_LOAD_ARRAY( meta, &world->ent_region, ent_region, heap ); MDL_LOAD_ARRAY( meta, &world->ent_glider, ent_glider, heap ); + MDL_LOAD_ARRAY( meta, &world->ent_npc, ent_npc, heap ); mdl_array_ptr infos; MDL_LOAD_ARRAY( meta, &infos, ent_worldinfo, vg_mem.scratch ); @@ -459,7 +460,8 @@ void world_free( world_instance *world ) * reset the world structure without deallocating persistent buffers * TODO: Make this a memset(0), and have persistent items live in a static loc */ -static void world_init_blank( world_instance *world ){ +void world_init_blank( world_instance *world ) +{ memset( &world->meta, 0, sizeof(mdl_context) ); world->textures = NULL; diff --git a/world_physics.h b/world_physics.h index ce65e5b..06143b9 100644 --- a/world_physics.h +++ b/world_physics.h @@ -2,6 +2,7 @@ #include "world.h" #include "vg/vg_rigidbody.h" #include "vg/vg_rigidbody_collision.h" +#include "vg/vg_bvh.h" void ray_world_get_tri( world_instance *world, ray_hit *hit, v3f tri[3] ); diff --git a/world_render.c b/world_render.c index 029a95f..1b1a9c0 100644 --- a/world_render.c +++ b/world_render.c @@ -10,6 +10,7 @@ #include "ent_miniworld.h" #include "player_remote.h" #include "ent_skateshop.h" +#include "ent_npc.h" #include "shaders/model_entity.h" struct world_render world_render; @@ -886,13 +887,16 @@ void world_prerender( world_instance *world ) sizeof(struct ub_world_lighting), &world->ub_lighting ); } -static void render_other_entities( world_instance *world, vg_camera *cam ){ +static void render_other_entities( world_instance *world, vg_camera *cam ) +{ f32 radius = 40.0f; bh_iter it; bh_iter_init_range( 0, &it, cam->pos, radius+10.0f ); u32 glider_list[4], - glider_count = 0; + glider_count = 0, + npc_list[4], + npc_count = 0; i32 idx; while( bh_next( world->entity_bh, &it, &idx ) ){ @@ -900,20 +904,26 @@ static void render_other_entities( world_instance *world, vg_camera *cam ){ type = mdl_entity_id_type( id ), index = mdl_entity_id_id( id ); - if( type == k_ent_glider ) { + if( type == k_ent_glider ) + { if( glider_count < vg_list_size(glider_list) ) glider_list[ glider_count ++ ] = index; } + else if( type == k_ent_npc ) + { + if( npc_count < vg_list_size(npc_list) ) + npc_list[ npc_count ++ ] = index; + } } shader_model_entity_use(); shader_model_entity_uTexMain( 0 ); shader_model_entity_uCamera( cam->transform[3] ); shader_model_entity_uPv( cam->mtx.pv ); - WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_entity ); - for( u32 j=0; jent_glider, glider_list[j] ); if( !(glider->flags & 0x1) ) @@ -928,6 +938,14 @@ static void render_other_entities( world_instance *world, vg_camera *cam ){ render_glider_model( cam, world, mdl, k_board_shader_entity ); } + + for( u32 j=0; jent_npc, npc_list[j] ); + npc_update( npc ); + npc_render( npc, world, cam ); + } } void render_world( world_instance *world, vg_camera *cam, diff --git a/world_routes.h b/world_routes.h index 6467977..621c28a 100644 --- a/world_routes.h +++ b/world_routes.h @@ -4,6 +4,7 @@ #pragma once #include "vg/vg_camera.h" +#include "vg/vg_msg.h" #include "world.h" #include "network_msg.h" diff --git a/world_routes_ui.c b/world_routes_ui.c index ace8a3d..a4e2f10 100644 --- a/world_routes_ui.c +++ b/world_routes_ui.c @@ -1,6 +1,7 @@ #include "skaterift.h" #include "world_routes_ui.h" #include "world_routes.h" +#include "player.h" static u32 v4_rgba( v4f colour ){ u32 r = vg_minf(1.0f,colour[0])*255.0f,