From: hgn Date: Thu, 8 Feb 2024 02:12:09 +0000 (+0000) Subject: completed all glider stuff X-Git-Url: https://harrygodden.com/git/?p=carveJwlIkooP6JGAAIwe30JlM.git;a=commitdiff_plain;h=888e62fcd8f9777cee774fbb8fab2e52660303a7 completed all glider stuff --- diff --git a/blender_export.py b/blender_export.py index 695fff0..421cf5d 100644 --- a/blender_export.py +++ b/blender_export.py @@ -43,13 +43,14 @@ sr_entity_list = [ ('ent_miniworld', 'Mini World', '', 22 ), ('ent_prop', 'Prop', '', 23 ), ('ent_list', 'Entity List', '', 24 ), - ('ent_region', 'Region', '', 25 ) + ('ent_region', 'Region', '', 25 ), + ('ent_glider', 'Glider', '', 26 ), ] -MDL_VERSION_NR = 104 +MDL_VERSION_NR = 105 SR_TRIGGERABLE = [ 'ent_audio', 'ent_ccmd', 'ent_gate', 'ent_challenge', \ 'ent_relay', 'ent_skateshop', 'ent_objective', 'ent_route',\ - 'ent_miniworld', 'ent_region' ] + 'ent_miniworld', 'ent_region', 'ent_glider', 'ent_list' ] def get_entity_enum_id( alias ): #{ @@ -244,12 +245,26 @@ class union_file_audio_clip(Union): ("reserved",vg_audio_clip)] #} +# NOTE: not really an entity. no reason for ent_ -- makes more sense as file_, +# but then again, too late to change because compat. class ent_audio_clip(Structure): #{ _fields_ = [("_anon",union_file_audio_clip), ("probability",c_float)] #} +class ent_list(Structure): +#{ + _fields_ = [("entity_ref_start",c_uint32), + ("entity_ref_count",c_uint32)] +#} + +# used in ent_list +class file_entity_ref(Structure): +#{ + _fields_ = [("index",c_uint32)] +#} + class ent_checkpoint(Structure): #{ _fields_ = [("gate_index",c_uint16), @@ -279,6 +294,14 @@ class ent_list(Structure):#{ _fields_ = [("start",c_uint16),("count",c_uint16)] #} +class ent_glider(Structure):#{ + _fields_ = [("transform",mdl_transform), + ("flags",c_uint32), + ("cooldown",c_float)] + sr_functions = { 0: 'unlock', + 1: 'equip' } +#} + class ent_water(Structure): #{ _fields_ = [("transform",mdl_transform), @@ -528,7 +551,9 @@ class ent_region(Structure):#{ ("submesh_start",c_uint32), ("submesh_count",c_uint32), ("pstr_title",c_uint32), ("flags",c_uint32), - ("zone_volume",c_uint32)] + ("zone_volume",c_uint32), + #105+ + ("target0",c_uint32*2)] sr_functions = { 0: 'enter', 1: 'leave' } #} @@ -1729,6 +1754,7 @@ def sr_compile( collection ): #} audio_clip_count = 0 + entity_file_ref_count = 0 for ent_type, arr in sr_compile.entities.items():#{ print(F"[SR] Compiling {len(arr)} {ent_type}{'s' if len(arr)>1 else ''}") @@ -2003,6 +2029,8 @@ def sr_compile( collection ): sr_compile_mesh_internal( obj ) region.pstr_title = sr_compile_string( obj_data.title ) region.zone_volume = sr_entity_id( obj_data.zone_volume ) + region.target0[0] = sr_entity_id( obj_data.target0 ) + region.target0[1] = obj_data.target0_event sr_ent_push( region ) #} elif ent_type == 'ent_relay':#{ @@ -2018,6 +2046,27 @@ def sr_compile( collection ): relay.targets[3][1] = obj_data.target3_event sr_ent_push( relay ) #} + # elif ent_type == 'ent_list':#{ + # lista = ent_list() + # obj_data = obj.SR_data.ent_list[0] + + # lista.entity_ref_start = entity_file_ref_count + # lista.entity_ref_count = len( obj_data.entities ) + # entity_file_ref_count += lista.entity_ref_count + + # for child in obj_data.entities:#{ + # reference_struct = file_entity_ref() + # reference_struct.index = sr_entity_id( child.target ) + # sr_ent_push( reference_struct ) + # #} + + # sr_ent_push( lista ) + # #} + elif ent_type == 'ent_glider':#{ + glider = ent_glider() + compile_obj_transform( obj, glider.transform ) + sr_ent_push( glider ) + #} elif ent_type == 'ent_cubemap':#{ cubemap = ent_cubemap() co = obj.matrix_world @ Vector((0,0,0)) @@ -3095,6 +3144,9 @@ class SR_OBJECT_ENT_LIST(bpy.types.PropertyGroup):#{ #} #} +class SR_OBJECT_ENT_GLIDER(bpy.types.PropertyGroup):#{ + nothing: bpy.props.StringProperty() +#} class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{ subtype: bpy.props.EnumProperty( @@ -3532,6 +3584,18 @@ class SR_OBJECT_ENT_REGION(bpy.types.PropertyGroup):#{ zone_volume: bpy.props.PointerProperty( type=bpy.types.Object, name="Zone Volume", \ poll=lambda self,obj: sr_filter_ent_type(obj,['ent_volume'])) + + target0: bpy.props.PointerProperty( \ + type=bpy.types.Object, name="Triger on unlock", \ + poll=lambda self,obj: sr_filter_ent_type(obj,SR_TRIGGERABLE)) + target0_event: bpy.props.IntProperty( name="Event/Method" ) + + @staticmethod + def sr_inspector( layout, data ):#{ + layout.prop( data[0], 'title' ) + layout.prop( data[0], 'zone_volume' ) + SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target0' ) + #} #} class SR_OBJECT_ENT_RELAY(bpy.types.PropertyGroup):#{ @@ -3586,6 +3650,7 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): ent_relay: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_RELAY) 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_type: bpy.props.EnumProperty( name="Type", @@ -4210,6 +4275,14 @@ def draw_skeleton_helpers( obj ): #} #} +def cv_draw_wireframe( mdl, points, colour ):#{ + for i in range(len(points)//2):#{ + p0 = mdl@points[i*2+0] + p1 = mdl@points[i*2+1] + cv_draw_line( p0, p1, colour ) + #} +#} + def cv_ent_gate( obj ): #{ global cv_view_verts, cv_view_colours @@ -4624,6 +4697,20 @@ def cv_draw():#{ #} #} #} + elif ent_type == 'ent_glider':#{ + mesh = [Vector((-1.13982, 0.137084, -0.026358)), \ + Vector(( 1.13982, 0.137084, -0.026358)), \ + Vector(( 0.0, 1.6, 1.0)), \ + Vector(( 0.0, -3.0, 1.0)), \ + Vector(( -3.45, -1.78, 0.9)), \ + Vector(( 0.0, 1.6, 1.0)), \ + Vector(( 3.45, -1.78, 0.9)), \ + Vector(( 0.0, 1.6, 1.0)), \ + Vector(( 3.45, -1.78, 0.9)), \ + Vector(( -3.45, -1.78, 0.9))] + + cv_draw_wireframe( obj.matrix_world, mesh, (1,1,1) ) + #} elif ent_type == 'ent_skateshop':#{ data = obj.SR_data.ent_skateshop[0] display = data.mark_display @@ -4691,6 +4778,22 @@ def cv_draw():#{ if display1: cv_draw_ucube(display1.matrix_world, cc1, display_cu, display_co) #} + # elif ent_type == 'ent_list':#{ + # data = obj.SR_data.ent_list[0] + # for child in data.entities:#{ + # if child.target:#{ + # cv_draw_arrow( obj.location, child.target.location, \ + # (.5,.5,.5), 0.1 ) + # #} + # #} + # #} + elif ent_type == 'ent_region':#{ + data = obj.SR_data.ent_region[0] + if data.target0:#{ + cv_draw_arrow( obj.location, data.target0.location, \ + (.5,.5,.5), 0.1 ) + #} + #} elif ent_type == 'ent_menuitem':#{ for i,col in enumerate(obj.users_collection):#{ colour32 = hash_djb2( col.name ) @@ -4827,6 +4930,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_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES, SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \ diff --git a/ent_glider.c b/ent_glider.c new file mode 100644 index 0000000..d1e2a36 --- /dev/null +++ b/ent_glider.c @@ -0,0 +1,21 @@ +#pragma once +#include "entity.h" +#include "player_glide.h" + +static 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 ); + + if( call->function == 0 ){ + glider->flags |= 0x1; + } + else if( call->function == 1 ){ + if( glider->flags & 0x1 ){ + player_glide_equip_glider(); + } + } + else { + vg_print_backtrace(); + vg_error( "Unhandled function id: %i\n", call->function ); + } +} diff --git a/ent_glider.h b/ent_glider.h new file mode 100644 index 0000000..e61bdd0 --- /dev/null +++ b/ent_glider.h @@ -0,0 +1,4 @@ +#pragma once +#include "entity.h" + +static void ent_glider_call( world_instance *world, ent_call *call ); diff --git a/ent_region.c b/ent_region.c index fd24f4e..44d49a0 100644 --- a/ent_region.c +++ b/ent_region.c @@ -113,6 +113,20 @@ static void ent_region_re_eval( world_instance *world ){ region->flags = combined; world_total &= combined; + + /* run unlock triggers. v105+ */ + if( world->meta.info.version >= 105 ){ + if( region->flags & (k_ent_route_flag_achieve_gold| + k_ent_route_flag_achieve_silver) ){ + if( region->target0[0] ){ + ent_call call; + call.data = NULL; + call.id = region->target0[0]; + call.function = region->target0[1]; + entity_call( world, &call ); + } + } + } } u32 instance_id = world - world_static.instances; diff --git a/entity.c b/entity.c index 2ff0cab..ce6d98e 100644 --- a/entity.c +++ b/entity.c @@ -13,6 +13,7 @@ #include "ent_miniworld.c" #include "ent_region.c" #include "ent_traffic.c" +#include "ent_glider.c" typedef void (*fn_entity_call_handler)( world_instance *, ent_call *); @@ -30,7 +31,8 @@ static void entity_call( world_instance *world, ent_call *call ){ [k_ent_challenge] = ent_challenge_call, [k_ent_route] = ent_route_call, [k_ent_miniworld] = ent_miniworld_call, - [k_ent_region] = ent_region_call + [k_ent_region] = ent_region_call, + [k_ent_glider] = ent_glider_call }; if( type >= vg_list_size(table) ){ diff --git a/entity.h b/entity.h index 1c11f38..1adeb7e 100644 --- a/entity.h +++ b/entity.h @@ -33,6 +33,8 @@ typedef struct ent_cubemap ent_cubemap; typedef struct ent_miniworld ent_miniworld; typedef struct ent_prop ent_prop; typedef struct ent_region ent_region; +typedef struct ent_list ent_list; +typedef struct ent_glider ent_glider; enum entity_alias{ k_ent_none = 0, @@ -60,7 +62,8 @@ enum entity_alias{ k_ent_miniworld = 22, k_ent_prop = 23, k_ent_list = 24, - k_ent_region = 25 + k_ent_region = 25, + k_ent_glider = 26 }; static u32 mdl_entity_id_type( u32 entity_id ){ @@ -548,7 +551,16 @@ struct ent_prop { struct ent_region { mdl_transform transform; - u32 submesh_start, submesh_count, pstr_title, flags, zone_volume; + u32 submesh_start, submesh_count, pstr_title, flags, zone_volume, + + /* 105+ */ + target0[2]; +}; + +struct ent_glider { + mdl_transform transform; + u32 flags; + f32 cooldown; }; #include "world.h" diff --git a/gui.h b/gui.h index 1414bd5..67f78b5 100644 --- a/gui.h +++ b/gui.h @@ -19,6 +19,7 @@ enum gui_icon { k_gui_icon_player, k_gui_icon_rift_run_gold, k_gui_icon_rift_run_silver, + k_gui_icon_glider, k_gui_icon_count, }; @@ -329,6 +330,7 @@ static void gui_init(void){ gui.icons[ k_gui_icon_rift_run_2d ] = gui_find_icon( "icon_rift_run2d" ); gui.icons[ k_gui_icon_friend ] = gui_find_icon( "icon_friend" ); gui.icons[ k_gui_icon_player ] = gui_find_icon( "icon_player" ); + gui.icons[ k_gui_icon_glider ] = gui_find_icon( "icon_glider" ); gui.icons[ k_gui_icon_rift_run_gold ] = gui_find_icon("icon_rift_run_medal_gold"); gui.icons[ k_gui_icon_rift_run_silver]= diff --git a/maps_src/mp_mtzero/main.mdl b/maps_src/mp_mtzero/main.mdl index 76139c8..b743ebe 100644 Binary files a/maps_src/mp_mtzero/main.mdl and b/maps_src/mp_mtzero/main.mdl differ diff --git a/model.h b/model.h index 62438dc..ba1c3f2 100644 --- a/model.h +++ b/model.h @@ -8,7 +8,7 @@ #include "skaterift.h" #define MDL_VERSION_MIN 101 -#define MDL_VERSION_NR 104 +#define MDL_VERSION_NR 105 enum mdl_shader{ k_shader_standard = 0, diff --git a/models_src/rs_icons.mdl b/models_src/rs_icons.mdl index e3ee8b5..7dec122 100644 Binary files a/models_src/rs_icons.mdl and b/models_src/rs_icons.mdl differ diff --git a/player_glide.c b/player_glide.c index 331565c..af44ea6 100644 --- a/player_glide.c +++ b/player_glide.c @@ -289,10 +289,21 @@ static void player_glide_im_gui(void){ player_glide.info_drag[2] ); } +static void player_glide_equip_glider(void){ + if( !localplayer.have_glider ){ + localplayer.have_glider = 1; + localplayer.glider_orphan = 0; + player_glide.t = -1.0f; + } +} + static int ccmd_player_glider_spawn( int argc, const char *argv[] ){ - localplayer.have_glider = 1; - localplayer.glider_orphan = 0; - player_glide.t = -1.0f; + if( vg_console.cheats ){ + player_glide_equip_glider(); + } + else { + vg_error( "Can't spawn without cheats enabled.\n" ); + } return 0; } diff --git a/player_glide.h b/player_glide.h index fdf34bc..f8f6dd9 100644 --- a/player_glide.h +++ b/player_glide.h @@ -122,6 +122,7 @@ static void render_glider_model( camera *cam, world_instance *world, m4x3f mmdl, enum board_shader shader ); static void player_glide_remote_animator_exchange( bitpack_ctx *ctx, void *data ); +static void player_glide_equip_glider(void); struct player_subsystem_interface static player_subsystem_glide = { .pre_update = player_glide_pre_update, diff --git a/player_replay.c b/player_replay.c index a013f7c..f5a2ab9 100644 --- a/player_replay.c +++ b/player_replay.c @@ -427,10 +427,10 @@ void skaterift_restore_frame( replay_frame *frame ){ rb_update_matrices( rb ); } + localplayer.subsystem = frame->system; + /* restore the seperated glider data if we have it */ if( frame->data_table[ k_replay_framedata_glider ][1] ){ - localplayer.subsystem = frame->system; - struct replay_glider_data *inf = replay_frame_data( frame, k_replay_framedata_glider ); diff --git a/world.h b/world.h index 9e9387b..6ff3afb 100644 --- a/world.h +++ b/world.h @@ -188,7 +188,8 @@ struct world_instance { ent_cubemap, ent_miniworld, ent_prop, - ent_region; + ent_region, + ent_glider; enum skybox { k_skybox_default, diff --git a/world_entity.c b/world_entity.c index 4402291..831e7eb 100644 --- a/world_entity.c +++ b/world_entity.c @@ -12,6 +12,7 @@ #include "ent_skateshop.h" #include "ent_route.h" #include "ent_traffic.h" +#include "ent_glider.h" static void world_entity_focus( u32 entity_id ){ localplayer.immobile = 1; @@ -194,7 +195,8 @@ static void world_gen_entities_init( world_instance *world ){ { k_ent_gate, &world->ent_gate }, { k_ent_objective, &world->ent_objective }, { k_ent_volume, &world->ent_volume }, - { k_ent_challenge, &world->ent_challenge } + { k_ent_challenge, &world->ent_challenge }, + { k_ent_glider, &world->ent_glider } }; for( u32 i=0; itransform, transform ); m4x3_expand_aabb_aabb( transform, bound, box ); } + else if( type == k_ent_glider ){ + ent_glider *glider = mdl_arritm( &world->ent_glider, index ); + m4x3f transform; + mdl_transform_m4x3( &glider->transform, transform ); + m4x3_expand_aabb_aabb( transform, bound, + (boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}} ); + } else{ vg_fatal_error( "Programming error\n" ); } @@ -510,6 +519,10 @@ static float entity_bh_centroid( void *user, u32 item_index, int axis ){ ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index ); return challenge->transform.co[axis]; } + else if( type == k_ent_glider ){ + ent_glider *glider = mdl_arritm( &world->ent_glider, index ); + return glider->transform.co[axis]; + } else { vg_fatal_error( "Programming error\n" ); return INFINITY; diff --git a/world_load.c b/world_load.c index 6055d88..ece9297 100644 --- a/world_load.c +++ b/world_load.c @@ -69,6 +69,7 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){ MDL_LOAD_ARRAY( meta, &world->ent_miniworld, ent_miniworld, heap ); 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_array_ptr infos; MDL_LOAD_ARRAY( meta, &infos, ent_worldinfo, vg_mem.scratch ); diff --git a/world_map.c b/world_map.c index e2fbe7a..c7f6ec8 100644 --- a/world_map.c +++ b/world_map.c @@ -173,6 +173,18 @@ static void world_map_pre_update(void){ respawn_map_draw_icon( cam, k_gui_icon_rift_run_2d, route->board_transform[3] ); } + + for( u32 i=0; ient_glider); i ++ ){ + ent_glider *glider = mdl_arritm( &world->ent_glider, i ); + + v4f colour = { 1,1,1,1 }; + + if( !(glider->flags & 0x1) ) + v3_muls( colour, 0.5f, colour ); + gui_icon_setcolour( colour ); + + respawn_map_draw_icon( cam, k_gui_icon_glider, glider->transform.co ); + } } static void world_map_enter(void){ diff --git a/world_render.c b/world_render.c index 1033041..2355e20 100644 --- a/world_render.c +++ b/world_render.c @@ -13,6 +13,7 @@ #include "ent_miniworld.h" #include "player_remote.h" #include "ent_skateshop.h" +#include "shaders/model_entity.h" static int ccmd_set_time( int argc, const char *argv[] ){ world_instance *world = world_current_instance(); @@ -891,6 +892,50 @@ static void world_prerender( world_instance *world ){ sizeof(struct ub_world_lighting), &world->ub_lighting ); } +static void render_other_entities( world_instance *world, 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; + + i32 idx; + while( bh_next( world->entity_bh, &it, &idx ) ){ + u32 id = world->entity_list[ idx ], + type = mdl_entity_id_type( id ), + index = mdl_entity_id_id( id ); + + if( type == k_ent_glider ) { + if( glider_count < vg_list_size(glider_list) ) + glider_list[ glider_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) ) + continue; + + m4x3f mdl; + mdl_transform_m4x3( &glider->transform, mdl ); + + f32 dist = v3_dist( glider->transform.co, cam->pos ) * (1.0f/radius), + scale = vg_smoothstepf( vg_clampf( 5.0f-dist*5.0f, 0.0f,1.0f ) ); + m3x3_scalef( mdl, scale ); + + render_glider_model( cam, world, mdl, k_board_shader_entity ); + } +} + static void render_world( world_instance *world, camera *cam, int stenciled, int viewing_from_gate, int with_water, int with_cubemaps ){ @@ -987,6 +1032,7 @@ static void render_world( world_instance *world, camera *cam, } render_remote_players( world, cam ); + render_other_entities( world, cam ); ent_miniworld_render( world, cam ); if( stenciled ){