From: hgn Date: Fri, 7 Mar 2025 21:39:10 +0000 (+0000) Subject: linking some cutscenes up, various entity shuffles, aaaaand passive gates X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=858099dc7f62bc2776fde5cb324a159a582cb128;p=carveJwlIkooP6JGAAIwe30JlM.git linking some cutscenes up, various entity shuffles, aaaaand passive gates --- diff --git a/content_skaterift/maps/dev_hub/main.mdl b/content_skaterift/maps/dev_hub/main.mdl index 8119612..54de7f3 100644 Binary files a/content_skaterift/maps/dev_hub/main.mdl and b/content_skaterift/maps/dev_hub/main.mdl differ diff --git a/content_skaterift/maps/dev_tutorial/main.mdl b/content_skaterift/maps/dev_tutorial/main.mdl index 9a24db8..454775a 100644 Binary files a/content_skaterift/maps/dev_tutorial/main.mdl and b/content_skaterift/maps/dev_tutorial/main.mdl differ diff --git a/content_skaterift/maps/mp_line1/main.mdl b/content_skaterift/maps/mp_line1/main.mdl index 047f8a8..af8ec30 100644 Binary files a/content_skaterift/maps/mp_line1/main.mdl and b/content_skaterift/maps/mp_line1/main.mdl differ diff --git a/content_skaterift/maps/mp_mtzero/main.mdl b/content_skaterift/maps/mp_mtzero/main.mdl index 2551173..ed318b4 100644 Binary files a/content_skaterift/maps/mp_mtzero/main.mdl and b/content_skaterift/maps/mp_mtzero/main.mdl differ diff --git a/content_skaterift/maps/mp_spawn/main.mdl b/content_skaterift/maps/mp_spawn/main.mdl index 12e63c5..6ab54b5 100644 Binary files a/content_skaterift/maps/mp_spawn/main.mdl and b/content_skaterift/maps/mp_spawn/main.mdl differ diff --git a/content_skaterift/maps/sr002-local-dev_hub-cm-hub-line1.qoi b/content_skaterift/maps/sr002-local-dev_hub-cm-hub-line1.qoi new file mode 100644 index 0000000..c017888 Binary files /dev/null and b/content_skaterift/maps/sr002-local-dev_hub-cm-hub-line1.qoi differ diff --git a/content_skaterift/maps/sr002-local-dev_hub-cm-hub-mtzero.qoi b/content_skaterift/maps/sr002-local-dev_hub-cm-hub-mtzero.qoi new file mode 100644 index 0000000..8b3c473 Binary files /dev/null and b/content_skaterift/maps/sr002-local-dev_hub-cm-hub-mtzero.qoi differ diff --git a/content_skaterift/maps/sr002-local-dev_hub-cm-hub-spawn.qoi b/content_skaterift/maps/sr002-local-dev_hub-cm-hub-spawn.qoi new file mode 100644 index 0000000..39fc040 Binary files /dev/null and b/content_skaterift/maps/sr002-local-dev_hub-cm-hub-spawn.qoi differ diff --git a/content_skaterift/maps/sr002-local-dev_hub-cm-hub-tutorial.qoi b/content_skaterift/maps/sr002-local-dev_hub-cm-hub-tutorial.qoi new file mode 100644 index 0000000..7690cb8 Binary files /dev/null and b/content_skaterift/maps/sr002-local-dev_hub-cm-hub-tutorial.qoi differ diff --git a/content_skaterift/maps/sr002-local-dev_hub-cm-straw.qoi b/content_skaterift/maps/sr002-local-dev_hub-cm-straw.qoi index c441340..3929af0 100644 Binary files a/content_skaterift/maps/sr002-local-dev_hub-cm-straw.qoi and b/content_skaterift/maps/sr002-local-dev_hub-cm-straw.qoi differ diff --git a/content_skaterift/maps/sr002-local-dev_tutorial-cm-hub-tutorial.qoi b/content_skaterift/maps/sr002-local-dev_tutorial-cm-hub-tutorial.qoi new file mode 100644 index 0000000..4dc48f1 Binary files /dev/null and b/content_skaterift/maps/sr002-local-dev_tutorial-cm-hub-tutorial.qoi differ diff --git a/content_skaterift/maps/sr002-local-mp_line1-cm-hub-line1.qoi b/content_skaterift/maps/sr002-local-mp_line1-cm-hub-line1.qoi new file mode 100644 index 0000000..57d74cc Binary files /dev/null and b/content_skaterift/maps/sr002-local-mp_line1-cm-hub-line1.qoi differ diff --git a/content_skaterift/maps/sr002-local-mp_mtzero-cm-hub-mtzero.qoi b/content_skaterift/maps/sr002-local-mp_mtzero-cm-hub-mtzero.qoi new file mode 100644 index 0000000..e18912c Binary files /dev/null and b/content_skaterift/maps/sr002-local-mp_mtzero-cm-hub-mtzero.qoi differ diff --git a/content_skaterift/maps/sr002-local-mp_mtzero-cm-straw.qoi b/content_skaterift/maps/sr002-local-mp_mtzero-cm-straw.qoi index 2274a14..7bca803 100644 Binary files a/content_skaterift/maps/sr002-local-mp_mtzero-cm-straw.qoi and b/content_skaterift/maps/sr002-local-mp_mtzero-cm-straw.qoi differ diff --git a/content_skaterift/maps/sr002-local-mp_spawn-cm-hub-spawn.qoi b/content_skaterift/maps/sr002-local-mp_spawn-cm-hub-spawn.qoi new file mode 100644 index 0000000..f8a707a Binary files /dev/null and b/content_skaterift/maps/sr002-local-mp_spawn-cm-hub-spawn.qoi differ diff --git a/skaterift_blender/sr_main.py b/skaterift_blender/sr_main.py index 3370d20..ca1771a 100644 --- a/skaterift_blender/sr_main.py +++ b/skaterift_blender/sr_main.py @@ -339,7 +339,7 @@ class ent_volume(Structure): _fields_ = [("transform",mdl_transform), ("to_world",(c_float*3)*4), ("to_local",(c_float*3)*4), - ("type",c_uint32), + ("flags",c_uint32), ("target",c_uint32), ("_anon",volume_union)] #} @@ -488,13 +488,13 @@ class ent_challenge(Structure):#{ ("flags",c_uint32), ("on_activate_id",c_uint32), ("on_activate_event",c_int32), - ("reset",c_uint32), - ("reset_event",c_int32), + ("on_complete_id",c_uint32), + ("on_complete_event",c_int32), ("first_objective_id",c_uint32), ("camera_id",c_uint32), ("status",c_uint32), ("visible_when_unlocked_id",c_uint32)] - sr_functions = { 0: 'unlock', + sr_functions = { 0: 'win', 1: 'view', -1: 'unview' } #} @@ -1175,7 +1175,8 @@ class SR_OBJECT_ENT_GATE(bpy.types.PropertyGroup): nonlocal_world: bpy.props.StringProperty() key: bpy.props.StringProperty() tipo: bpy.props.EnumProperty(items=(('default', 'Default', ""), - ('nonlocal', 'Non-Local', ""))) + ('nonlocal', 'Non-Local', ""), + ('passive', 'Passive (Non-teleporting)', ""))) flip: bpy.props.BoolProperty( name="Flip exit", default=False ) custom: bpy.props.BoolProperty( name="Mesh is surface", default=False ) @@ -1652,6 +1653,8 @@ class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{ target_event: bpy.props.IntProperty( name="Enter Ev" ) target_event_leave: bpy.props.IntProperty( name="Leave Ev", default=-1 ) + auto_run: bpy.props.BoolProperty( name="Auto Run" ) + @staticmethod def inspect_target( layout, data, propname, evs = ['_event'], text='' ):#{ box = layout.box() @@ -1685,8 +1688,8 @@ class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{ @staticmethod def sr_inspector( layout, data ):#{ layout.prop( data[0], 'subtype' ) - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', \ - ['_event','_event_leave'] ) + SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', ['_event','_event_leave'] ) + layout.prop( data[0], 'auto_run' ) #} #} @@ -1945,13 +1948,14 @@ class SR_OBJECT_ENT_CHALLENGE(bpy.types.PropertyGroup):#{ alias: bpy.props.StringProperty( name="Alias" ) target: bpy.props.PointerProperty( \ - type=bpy.types.Object, name="On Complete", \ + type=bpy.types.Object, name="On Activate", \ poll=lambda self,obj: sr_filter_ent_type(obj,SR_TRIGGERABLE)) target_event: bpy.props.IntProperty( name="Event/Method" ) - reset: bpy.props.PointerProperty( \ + + complete: bpy.props.PointerProperty( \ type=bpy.types.Object, name="On Reset", \ poll=lambda self,obj: sr_filter_ent_type(obj,SR_TRIGGERABLE)) - reset_event: bpy.props.IntProperty( name="Event/Method" ) + complete_event: bpy.props.IntProperty( name="Event/Method" ) time_limit: bpy.props.BoolProperty( name="Time Limit" ) is_story: bpy.props.BoolProperty( name="Is story event" ) @@ -1977,8 +1981,8 @@ class SR_OBJECT_ENT_CHALLENGE(bpy.types.PropertyGroup):#{ layout.prop( data[0], 'visible_when_unlocked' ) layout.prop( data[0], 'time_limit' ) layout.prop( data[0], 'is_story' ) - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', text=("On Activate" if data[0].is_story else "On Complete") ) - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'reset', text="On Reset" ) + SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', text="On Activate" ) + SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'complete', text="On Complete" ) #} #} @@ -2802,11 +2806,15 @@ def cv_draw_route( route, dij ): gi = checkpoints[i].target gj = checkpoints[(i+1)%len(checkpoints)].target - if gi:#{ - dest = gi.SR_data.ent_gate[0].target - if dest: - cv_draw_line_dotted( gi.location, dest.location, cc ) - gi = dest + if gi: + #{ + if gi.SR_data.ent_gate[0].tipo != 'passive': + #{ + dest = gi.SR_data.ent_gate[0].target + if dest: + cv_draw_line_dotted( gi.location, dest.location, cc ) + gi = dest + #} #} if gi==gj: continue # error? @@ -2880,7 +2888,7 @@ def cv_draw():#{ cv_draw_arrow( obj.location, data.proxima.location, (1,0.6,0.2) ) #} if data.target: - cv_draw_arrow( obj.location, data.target.location, (1,1,1) ) + cv_draw_arrow( obj.location, data.target.location, (0,1,0) ) #} elif ent_type == 'ent_relay':#{ data = obj.SR_data.ent_relay[0] @@ -2904,9 +2912,9 @@ def cv_draw():#{ elif ent_type == 'ent_challenge':#{ data = obj.SR_data.ent_challenge[0] if data.target: - cv_draw_arrow( obj.location, data.target.location, (1,1,1) ) - if data.reset: - cv_draw_arrow( obj.location, data.reset.location, (0.9,0,0) ) + cv_draw_arrow( obj.location, data.target.location, (0,0.4,0.8) ) + if data.complete: + cv_draw_arrow( obj.location, data.complete.location, (0.1,0.9,0) ) if data.first: cv_draw_arrow( obj.location, data.first.location, (1,0.6,0.2) ) diff --git a/skaterift_blender/sr_mdl.py b/skaterift_blender/sr_mdl.py index c352c86..32da8a5 100644 --- a/skaterift_blender/sr_mdl.py +++ b/skaterift_blender/sr_mdl.py @@ -637,6 +637,10 @@ def _mdl_compiler_compile_entities(): gate.key = _af_pack_string(obj_data.key) flags |= 0x0002 #} + elif obj_data.tipo == 'passive': + #{ + flags |= 0x80 + #} if obj_data.flip: flags |= 0x0004 if obj_data.custom:#{ @@ -740,7 +744,9 @@ def _mdl_compiler_compile_entities(): elif ent_type == 'ent_volume':#{ obj_data = obj.SR_data.ent_volume[0] volume = ent_volume() - volume.type = int(obj_data.subtype) + volume.flags = int(obj_data.subtype) + if obj_data.auto_run: + volume.flags |= 0x4 compile_obj_transform( obj, volume.transform ) if obj_data.target:#{ @@ -856,8 +862,8 @@ def _mdl_compiler_compile_entities(): if obj_data.is_story: challenge.flags |= 0x02 challenge.on_activate_id = sr_entity_id( obj_data.target ) challenge.on_activate_event = obj_data.target_event - challenge.reset = sr_entity_id( obj_data.reset ) - challenge.reset_event = obj_data.reset_event + challenge.on_complete_id = sr_entity_id( obj_data.complete ) + challenge.on_complete_event = obj_data.complete_event challenge.first_objective_id = sr_entity_id( obj_data.first ) challenge.camera_id = sr_entity_id( obj_data.camera ) challenge.status = 0 @@ -987,8 +993,11 @@ def _mdl_compiler_compile_entities(): if gi: #{ - dest = gi.SR_data.ent_gate[0].target - gi = dest + if gi.SR_data.ent_gate[0].tipo != 'passive': + #{ + dest = gi.SR_data.ent_gate[0].target + gi = dest + #} #} if gi==gj: continue # error? diff --git a/skaterift_blender/sr_route_graph.py b/skaterift_blender/sr_route_graph.py index 3e3ffc6..b36290c 100644 --- a/skaterift_blender/sr_route_graph.py +++ b/skaterift_blender/sr_route_graph.py @@ -165,23 +165,27 @@ def create_node_graph( curves, gates ): #} # add and link gates( by name ) - for gate in gates:#{ + for gate in gates: + #{ v1 = gate.matrix_world.to_3x3() @ Vector((0,1,0)) if gate.SR_data.ent_gate[0].target: v1 = v1 * -1.0 graph[ gate.name ] = {} - for i in range(len(graph_keys)):#{ + for i in range(len(graph_keys)): + #{ ni = graph_keys[i] pi = route_points[ni] v0 = pi-gate.location - if v0.dot(v1) < 0.0: continue + #if v0.dot(v1) < 0.0: + # continue dist = round(v0.magnitude,2) - if dist < 10.0:#{ + if dist < 10.0: + #{ graph[ gate.name ][ ni ] = dist graph[ ni ][ gate.name ] = dist #} diff --git a/src/ent_challenge.c b/src/ent_challenge.c index bc5a953..09bb5f5 100644 --- a/src/ent_challenge.c +++ b/src/ent_challenge.c @@ -25,17 +25,20 @@ entity_call_result ent_challenge_call( world_instance *world, ent_call *call ) u32 index = mdl_entity_id_id( call->id ); ent_challenge *challenge = af_arritm( &world->ent_challenge, index ); - if( call->function == 0 ) /* unlock() */ + if( call->function == 0 ) /* win() */ { - if( !challenge->status ) + vg_info( "challenge( '%s' )\n", af_str( &world->meta.af, challenge->pstr_alias) ); + + vg_info( "on complete id: %u\n", challenge->on_complete_id ); + if( challenge->on_complete_id ) { - vg_info( "challenge( '%s' )\n", af_str( &world->meta.af, challenge->pstr_alias) ); ent_call call; call.data = NULL; call.function = challenge->on_complete_event; call.id = challenge->on_complete_id; entity_call( world, &call ); } + challenge->status = 1; return k_entity_call_result_OK; } @@ -156,6 +159,15 @@ void ent_challenge_update(void) vg_audio_lock(); vg_audio_oneshot( &audio_challenge[5], 1.0f, 0.0f, 0, 0 ); vg_audio_unlock(); + + if( challenge->on_activate_id ) + { + ent_call call; + call.data = NULL; + call.function = challenge->on_activate_event; + call.id = challenge->on_activate_id; + entity_call( &_world.main, &call ); + } } else if( button_down( k_srbind_mback ) ) { @@ -206,18 +218,21 @@ void ent_challenge_update(void) { if( button_down( k_srbind_maccept ) ) { - gui_helper_reset( k_gui_helper_mode_clear ); - ent_call call; - call.data = NULL; - call.function = challenge->on_activate_event; - call.id = challenge->on_activate_id; - entity_call( &_world.main, &call ); - - if( world_clear_event( k_world_event_challenge ) ) + if( challenge->on_activate_id ) { - _world.challenge_state = k_challenge_state_none; - _world.active_challenge_id = 0; gui_helper_reset( k_gui_helper_mode_clear ); + ent_call call; + call.data = NULL; + call.function = challenge->on_activate_event; + call.id = challenge->on_activate_id; + entity_call( &_world.main, &call ); + + if( world_clear_event( k_world_event_challenge ) ) + { + _world.challenge_state = k_challenge_state_none; + _world.active_challenge_id = 0; + gui_helper_reset( k_gui_helper_mode_clear ); + } } } } diff --git a/src/entity.h b/src/entity.h index dc1a81c..28c0441 100644 --- a/src/entity.h +++ b/src/entity.h @@ -200,6 +200,7 @@ enum ent_gate_flag k_ent_gate_clean_pass = 0x20,/* player didn't rewind while getting here */ k_ent_gate_no_linkback = 0x40,/* NONLOCAL Recievers are not allowed to linkback through this gate */ + k_ent_gate_passive = 0x80 }; struct ent_gate{ @@ -320,7 +321,8 @@ struct volume_trigger{ enum ent_volume_flag { k_ent_volume_flag_particles = 0x1, - k_ent_volume_flag_disabled = 0x2 + k_ent_volume_flag_disabled = 0x2, + k_ent_volume_flag_autorun = 0x4 }; struct ent_volume{ @@ -609,24 +611,17 @@ enum ent_challenge_flag k_ent_challenge_locked = 0x4, }; -struct ent_challenge{ +struct ent_challenge +{ mdl_transform transform; u32 pstr_alias, flags; - union - { - u32 on_complete_id, - on_activate_id; - }; - union - { - i32 on_complete_event, - on_activate_event; - }; + u32 on_activate_id; + u32 on_activate_event; - u32 reset; - i32 reset_event; + u32 on_complete_id; + i32 on_complete_event; u32 first_objective_id; u32 camera_id; diff --git a/src/menu.c b/src/menu.c index e1e2ee4..94deb16 100644 --- a/src/menu.c +++ b/src/menu.c @@ -725,19 +725,52 @@ void menu_gui( ui_context *ctx ) goto menu_draw; } -#if 0 - else if( menu.page == k_menu_page_world_select ) + else if( menu.page == k_menu_page_impromptu_guide ) { + ui_rect panel = { 0,0, 600, 400+240 }, + screen = { 0,0, vg.window_x,vg.window_y }; + + ui_rect_center( screen, panel ); + ui_fill( ctx, panel, ui_opacity( GUI_COL_DARK, 0.35f ) ); + ui_outline( ctx, panel, 1, GUI_COL_NORM, 0 ); + ui_rect_pad( panel, (ui_px[]){8,8} ); + + ui_rect title; + ui_split( panel, k_ui_axis_h, 28*2, 0, title, panel ); + ctx->font = &vgf_default_title; + ui_text( ctx, title, "Welcome to Center Island", 1, k_ui_align_middle_center, 0 ); + + ui_split( panel, k_ui_axis_h, 28, 0, title, panel ); + ctx->font = &vgf_default_large; + + ui_rect content; + ui_split( panel, k_ui_axis_h, 456, 0, content, panel ); + ui_text( ctx, content, + /*|------------------------------------------------| */ + "Here you can visit different locations and keep\n" + "track of your progress.\n" + "\n" + "Walk through the rifts to visit the worlds. Our\n" + "story begins at the training volcano where you\n" + "will learn to skate again!\n" + "\n" + "Come back here at any time using the world menu,\n" + "if you want to change your character or boards\n" + "too.\n" + , 1, k_ui_align_left, 0 ); - if( /*menu_button( ctx, end, 1, 1, "Back" ) ||*/ button_down( k_srbind_mback ) ) + ui_rect end = { panel[0], panel[1] + panel[3] - 48, panel[2], 48 }; + if( menu_button( ctx, end, 1, 1, "OK" ) || button_down( k_srbind_mback ) ) { - menu.page = k_menu_page_main; + vg_audio_lock(); + vg_audio_oneshot( &audio_ui[3], 1.0f, 0.0f, 0, 0 ); + vg_audio_unlock(); + menu_close(); + return; } - menu.bg_blur = 0; goto menu_draw; } -#endif /* TOP BAR * -------------------------------------------------------------------*/ diff --git a/src/menu.h b/src/menu.h index f8a96a0..85cbe7b 100644 --- a/src/menu.h +++ b/src/menu.h @@ -15,6 +15,7 @@ enum menu_page k_menu_page_main, k_menu_page_credits, k_menu_page_help, + k_menu_page_impromptu_guide }; enum menu_main_subpage diff --git a/src/player.c b/src/player.c index 057c8cf..b3c3f47 100644 --- a/src/player.c +++ b/src/player.c @@ -204,6 +204,13 @@ void player__pass_gate( u32 id ) world_instance *world = &_world.main; ent_gate *gate = af_arritm( &world->ent_gate, mdl_entity_id_id(id) ); + if( gate->flags & k_ent_gate_passive ) + { + world_routes_fracture( world, gate, localplayer.rb.co, localplayer.rb.v ); + world_routes_activate_entry_gate( world, gate ); + return; + } + if( gate->flags & k_ent_gate_nonlocal ) { _world.travelled_through_nonlocal_gate = 1; @@ -217,6 +224,8 @@ void player__pass_gate( u32 id ) _world.nonlocal_destination_key, 32, k_strncpy_overflow_fatal ); + player__clean_refs(); + addon_reg *reg = get_addon_from_index( k_addon_type_world, gate->addon_reg, 0,0 ); skaterift_load_world_start( reg, 0 ); return; diff --git a/src/player_walk.c b/src/player_walk.c index 7fc7922..2947386 100644 --- a/src/player_walk.c +++ b/src/player_walk.c @@ -728,9 +728,7 @@ static void player_walk_update_generic(void){ w->state.activity = prev_state; } - w->move_speed = vg_minf( v2_length( (v2f){ localplayer.rb.v[0], - localplayer.rb.v[2] } ), - k_runspeed ); + w->move_speed = vg_minf( v2_length( (v2f){ localplayer.rb.v[0], localplayer.rb.v[2] } ), k_runspeed ); } void player__walk_transport( m4x3f transport ) diff --git a/src/skaterift_script.c b/src/skaterift_script.c index efa1b40..920989d 100644 --- a/src/skaterift_script.c +++ b/src/skaterift_script.c @@ -46,8 +46,7 @@ struct sr_subtitle const char *k, *v; }; -static void _skaterift_dialogue( struct sr_subtitle *subtitles, u32 *index, - const char *inf ) +static void _skaterift_dialogue( struct sr_subtitle *subtitles, u32 *index, const char *inf ) { u32 i = *index; @@ -145,258 +144,68 @@ static bool _skaterift_script_intro( enum escript_event ev, const char *inf ) static bool _skaterift_script_ch1s2( enum escript_event ev, const char *inf ) { - static u32 state, subtitle_id; - static struct cs_instance *override_inst; - if( ev == k_escript_event_call ) { - state = k_escript_state_loading; - override_inst = NULL; - subtitle_id = 0; - vg_info( "test:state = loading\n" ); - } - - if( ev == k_escript_event_cutscene_marker ) - { - struct sr_subtitle EN[] = { - { "john_1", KCOL_JOHN "Well, here we are. Home." }, - { "john_2", KCOL_JOHN "I mean, halfway home." }, - { "john_3", KCOL_JOHN "Obviously you've forgotten quite a bit, so we'll stop off here" }, - { "john_4", KCOL_JOHN "and I'll teach you some stuff again" }, - { NULL, NULL }, - }; - _skaterift_dialogue( EN, &subtitle_id, inf ); - - return 0; - } - - /* scene - * --------------------------------------------------------------- */ - - if( state == k_escript_state_loading ) - { - if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/ch1s2.ms" } ) ) - { - state = k_escript_state_initializing; - vg_info( "test:state = initializing\n" ); - } - } - - if( state == k_escript_state_initializing ) - { - if( _cutscene.state == k_cutscene_state_ready ) - { - _skaterift_script_bind_player(); - state = k_escript_state_playing; - vg_info( "test:state = playing\n" ); - _cutscene_play(); - } - } - - if( state == k_escript_state_playing ) - { - if( _cutscene.state == k_cutscene_state_done ) - { - state = k_escript_state_end; - vg_info( "test:state = end\n" ); - _cutscene_unload(); + if( _skaterift_script_already_viewed( k_escript_script_id_ch1s2 ) ) return 1; - } } - return 0; + struct sr_subtitle EN[] = { + { "john_1", KCOL_JOHN "Well, here we are. Home." }, + { "john_2", KCOL_JOHN "I mean, halfway home." }, + { "john_3", KCOL_JOHN "Obviously you've forgotten quite a bit, so we'll stop off here" }, + { "john_4", KCOL_JOHN "and I'll teach you some stuff again" }, + { NULL, NULL }, + }; + return _skaterift_generic_script_template( ev, inf, "metascenes/ch1s2.ms", EN, 1 ); } static bool _skaterift_script_ch1s3( enum escript_event ev, const char *inf ) { - static u32 state, subtitle_id; - static struct cs_instance *override_inst; - if( ev == k_escript_event_call ) - { - state = k_escript_state_loading; - override_inst = NULL; - subtitle_id = 0; - vg_info( "test:state = loading\n" ); - } - - if( ev == k_escript_event_cutscene_marker ) - { - struct sr_subtitle EN[] = { - { "john_1", KCOL_JOHN "Alright so, fliptricks." }, - { "john_2", KCOL_JOHN "We spent ages practicing these before" }, - { "john_3", KCOL_JOHN "Shouldn't take you long to get it again" }, - { "john_4", KCOL_JOHN "see if you can get a tre-flip down there" }, - { NULL, NULL }, - }; - _skaterift_dialogue( EN, &subtitle_id, inf ); - - return 0; - } - - /* scene - * --------------------------------------------------------------- */ - - if( state == k_escript_state_loading ) - { - if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/ch1s3.ms" } ) ) - { - state = k_escript_state_initializing; - vg_info( "test:state = initializing\n" ); - } - } - - if( state == k_escript_state_initializing ) - { - if( _cutscene.state == k_cutscene_state_ready ) - { - _skaterift_script_bind_player(); - state = k_escript_state_playing; - vg_info( "test:state = playing\n" ); - _cutscene_play(); - } - } - - if( state == k_escript_state_playing ) - { - if( _cutscene.state == k_cutscene_state_done ) - { - state = k_escript_state_end; - vg_info( "test:state = end\n" ); - _cutscene_unload(); + if( _skaterift_script_already_viewed( k_escript_script_id_ch1s3 ) ) return 1; - } - } - return 0; + struct sr_subtitle EN[] = { + { "john_1", KCOL_JOHN "Alright so, fliptricks." }, + { "john_2", KCOL_JOHN "We spent ages practicing these before" }, + { "john_3", KCOL_JOHN "Shouldn't take you long to get it again" }, + { "john_4", KCOL_JOHN "see if you can get a tre-flip down there" }, + { NULL, NULL }, + }; + return _skaterift_generic_script_template( ev, inf, "metascenes/ch1s3.ms", EN, 1 ); } static bool _skaterift_script_ch1s3b( enum escript_event ev, const char *inf ) { - static u32 state, subtitle_id; - static struct cs_instance *override_inst; - if( ev == k_escript_event_call ) - { - state = k_escript_state_loading; - override_inst = NULL; - subtitle_id = 0; - vg_info( "test:state = loading\n" ); - } - - if( ev == k_escript_event_cutscene_marker ) - { - struct sr_subtitle EN[] = { - { "john_1", KCOL_JOHN "That is it mate!" }, - { "john_2", KCOL_JOHN "You have still got it!" }, - { NULL, NULL }, - }; - _skaterift_dialogue( EN, &subtitle_id, inf ); - - return 0; - } - - /* scene - * --------------------------------------------------------------- */ - - if( state == k_escript_state_loading ) - { - if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/ch1s3b.ms" } ) ) - { - state = k_escript_state_initializing; - vg_info( "test:state = initializing\n" ); - } - } - - if( state == k_escript_state_initializing ) - { - if( _cutscene.state == k_cutscene_state_ready ) - { - _skaterift_script_bind_player(); - state = k_escript_state_playing; - vg_info( "test:state = playing\n" ); - _cutscene_play(); - } - } - - if( state == k_escript_state_playing ) - { - if( _cutscene.state == k_cutscene_state_done ) - { - state = k_escript_state_end; - vg_info( "test:state = end\n" ); - _cutscene_unload(); + if( _skaterift_script_already_viewed( k_escript_script_id_ch1s3b ) ) return 1; - } - } - return 0; + struct sr_subtitle EN[] = { + { "john_1", KCOL_JOHN "That is it mate!" }, + { "john_2", KCOL_JOHN "You have still got it!" }, + { NULL, NULL }, + }; + return _skaterift_generic_script_template( ev, inf, "metascenes/ch1s3b.ms", EN, 0 ); } static bool _skaterift_script_ch1s4( enum escript_event ev, const char *inf ) { - static u32 state, subtitle_id; - static struct cs_instance *override_inst; - if( ev == k_escript_event_call ) - { - state = k_escript_state_loading; - override_inst = NULL; - subtitle_id = 0; - vg_info( "test:state = loading\n" ); - } - - if( ev == k_escript_event_cutscene_marker ) - { - struct sr_subtitle EN[] = { - { "john_1", KCOL_JOHN "Remember these courses we were setting up?" }, - { "john_2", KCOL_JOHN "Nah?" }, - { "john_3", KCOL_JOHN "Alright well uh, to jog your memory.." }, - { "john_4", KCOL_JOHN "Get yourself down through the gates as quick as possible" }, - { "john_5", KCOL_JOHN "Thats it." }, - { "john_6", KCOL_JOHN "Give it a shot mate" }, - { NULL, NULL }, - }; - _skaterift_dialogue( EN, &subtitle_id, inf ); - - return 0; - } - - /* scene - * --------------------------------------------------------------- */ - - if( state == k_escript_state_loading ) - { - if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/ch1s4.ms" } ) ) - { - state = k_escript_state_initializing; - vg_info( "test:state = initializing\n" ); - } - } - - if( state == k_escript_state_initializing ) - { - if( _cutscene.state == k_cutscene_state_ready ) - { - _skaterift_script_bind_player(); - state = k_escript_state_playing; - vg_info( "test:state = playing\n" ); - _cutscene_play(); - } - } - - if( state == k_escript_state_playing ) - { - if( _cutscene.state == k_cutscene_state_done ) - { - state = k_escript_state_end; - vg_info( "test:state = end\n" ); - _cutscene_unload(); + if( _skaterift_script_already_viewed( k_escript_script_id_ch1s4 ) ) return 1; - } - } - return 0; + struct sr_subtitle EN[] = { + { "john_1", KCOL_JOHN "Remember these courses we were setting up?" }, + { "john_2", KCOL_JOHN "Nah?" }, + { "john_3", KCOL_JOHN "Alright well uh, to jog your memory.." }, + { "john_4", KCOL_JOHN "Get yourself down through the gates as quick as possible" }, + { "john_5", KCOL_JOHN "Thats it." }, + { "john_6", KCOL_JOHN "Give it a shot mate" }, + { NULL, NULL }, + }; + return _skaterift_generic_script_template( ev, inf, "metascenes/ch1s4.ms", EN, 1 ); } static bool _skaterift_script_ch1s5( enum escript_event ev, const char *inf ) @@ -1818,6 +1627,20 @@ static bool _skaterift_script_hub_setup( enum escript_event ev, const char *inf return 0; } +static bool _skaterift_script_hub_guide( enum escript_event ev, const char *inf ) +{ + if( ev == k_escript_event_call ) + { + if( _skaterift_script_already_viewed( k_escript_script_id_hub_guide ) ) + return 1; + + menu_open( k_menu_page_impromptu_guide ); + return 1; + } + + return 0; +} + struct { enum escript_script_id script_id; @@ -1848,6 +1671,7 @@ static struct script_info _script_infos[] = [k_escript_script_id_ch4s2] = { "ch4s2", _skaterift_script_ch4s2, SCRIPT_FLAG_STORY_EVENT }, [k_escript_script_id_ch4s3] = { "ch4s3", _skaterift_script_ch4s3, SCRIPT_FLAG_STORY_EVENT }, [k_escript_script_id_hub_setup] = { "hub_setup", _skaterift_script_hub_setup }, + [k_escript_script_id_hub_guide] = { "hub_guide", _skaterift_script_hub_guide, SCRIPT_FLAG_STORY_EVENT }, }; bool _skaterift_script_check_unlocked( enum escript_script_id id ) @@ -1856,6 +1680,12 @@ bool _skaterift_script_check_unlocked( enum escript_script_id id ) return info->availible; } +bool _skaterift_script_already_viewed( enum escript_script_id id ) +{ + struct script_info *info = &_script_infos[ id ]; + return info->viewed_time? 1: 0; +} + struct script_info *skaterift_script_get_info( const char *alias ) { for( u32 i=0; iid ); ent_ccmd *ccmd = af_arritm( &world->ent_ccmd, index ); const char *cmd_text = af_str( &world->meta.af, ccmd->pstr_command ); + vg_info( "ccmd: %s\n", cmd_text ); vg_execute_console_input( cmd_text, 0 ); return k_entity_call_result_OK; } @@ -900,6 +901,7 @@ void world_entity_start( world_instance *world, vg_msg *sav ) } ent_region_re_eval( world ); + world_volumes_start( world ); } void world_entity_serialize( world_instance *world, vg_msg *sav ) diff --git a/src/world_gate.c b/src/world_gate.c index d7faf6f..525661c 100644 --- a/src/world_gate.c +++ b/src/world_gate.c @@ -290,7 +290,7 @@ u32 world_intersect_gates( world_instance *world, v3f pos, v3f last ) { ent_gate *gate = af_arritm( &world->ent_gate, i ); - if( !(gate->flags & k_ent_gate_linked) ) + if( !(gate->flags & k_ent_gate_linked) && !(gate->flags & k_ent_gate_passive) ) continue; if( gate->flags & k_ent_gate_locked ) @@ -349,6 +349,9 @@ void world_link_gates_async( void *payload, u32 size ) ent_gate *gate = af_arritm( &world->ent_gate, j ); gate_transform_update( gate ); + if( gate->flags & k_ent_gate_passive ) + continue; + if( gate->flags & k_ent_gate_nonlocal ) { if( gate->target ) @@ -369,56 +372,54 @@ void world_link_gates_async( void *payload, u32 size ) vg_error( "Reference in non-local gate to other world '%s' was not found.\n", dest_world ); } } - else + + if( _world.travelled_through_nonlocal_gate ) { - if( _world.travelled_through_nonlocal_gate ) + const char *key = af_str( &world->meta.af, gate->key ); + if( vg_str_eq( key, _world.nonlocal_destination_key ) ) { - const char *key = af_str( &world->meta.af, gate->key ); - if( vg_str_eq( key, _world.nonlocal_destination_key ) ) + if( found_nonlocal_reciever ) + vg_warn( "There are multiple nonlocal gates that share the same key in this world (%s)\n", key ); + else { - if( found_nonlocal_reciever ) - vg_warn( "There are multiple nonlocal gates that share the same key in this world (%s)\n", key ); - else - { - found_nonlocal_reciever = 1; + found_nonlocal_reciever = 1; + + ent_gate *gate2 = &_world.copy_of_nonlocal_sender; - ent_gate *gate2 = &_world.copy_of_nonlocal_sender; + v3_copy( gate->co[0], gate2->co[1] ); + v3_copy( gate2->co[0], gate->co[1] ); + v4_copy( gate->q[0], gate2->q[1] ); + v4_copy( gate2->q[0], gate->q[1] ); - v3_copy( gate->co[0], gate2->co[1] ); - v3_copy( gate2->co[0], gate->co[1] ); - v4_copy( gate->q[0], gate2->q[1] ); - v4_copy( gate2->q[0], gate->q[1] ); + if( world->meta.version < 102 ) + { + /* LEGACY BEHAVIOUR: v101 + * this would flip both the client worlds portal's entrance and + * exit. effectively the clients portal would be the opposite + * to the hub worlds one. new behaviour is to just flip the + * destinations so the rules are consistent in each world. + */ + v4f qflip; + q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf ); + q_mul( gate->q[0], qflip, gate->q[0] ); + q_mul( gate->q[1], qflip, gate->q[1] ); + } - if( world->meta.version < 102 ) + gate_transform_update( gate ); + gate_transform_update( gate2 ); + + if( !(_world.copy_of_nonlocal_sender.flags & k_ent_gate_no_linkback) ) + { + gate->addon_reg = get_index_from_addon( k_addon_type_world, _world.previous_world_addon,0,0 ); + + if( gate->addon_reg != 0xffffffff ) { - /* LEGACY BEHAVIOUR: v101 - * this would flip both the client worlds portal's entrance and - * exit. effectively the clients portal would be the opposite - * to the hub worlds one. new behaviour is to just flip the - * destinations so the rules are consistent in each world. - */ - v4f qflip; - q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf ); - q_mul( gate->q[0], qflip, gate->q[0] ); - q_mul( gate->q[1], qflip, gate->q[1] ); + gate->flags |= k_ent_gate_linked; + vg_info( "Linked non-local gate to addon #%u\n", gate->addon_reg ); } - - gate_transform_update( gate ); - gate_transform_update( gate2 ); - - if( !(_world.copy_of_nonlocal_sender.flags & k_ent_gate_no_linkback) ) + else { - gate->addon_reg = get_index_from_addon( k_addon_type_world, _world.previous_world_addon,0,0 ); - - if( gate->addon_reg != 0xffffffff ) - { - gate->flags |= k_ent_gate_linked; - vg_info( "Linked non-local gate to addon #%u\n", gate->addon_reg ); - } - else - { - vg_error( "Error while linking to previous world.\n" ); - } + vg_error( "Error while linking to previous world.\n" ); } } } diff --git a/src/world_render.c b/src/world_render.c index f9f47e9..f9d395b 100644 --- a/src/world_render.c +++ b/src/world_render.c @@ -892,6 +892,9 @@ void render_world_gates( world_instance *world, vg_camera *cam ) if( !(gi->flags & k_ent_gate_linked) ) continue; + if( gi->flags & k_ent_gate_passive ) + continue; + float dist = v3_dist2( gi->co[0], cam->transform[3] ); vg_line_point( gi->co[0], 0.25f, VG__BLUE ); diff --git a/src/world_routes.c b/src/world_routes.c index 68686b3..2cca510 100644 --- a/src/world_routes.c +++ b/src/world_routes.c @@ -58,28 +58,30 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ) u32 valid_sections=0; int clean = !localplayer.rewinded_since_last_gate; - for( u32 i=0; icheckpoints_count; i++ ){ + for( u32 i=0; icheckpoints_count; i++ ) + { u32 cpid = (i+route->active_checkpoint) % route->checkpoints_count; cpid += route->checkpoints_start; ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, cpid ); ent_gate *rg = af_arritm( &world->ent_gate, cp->gate_index ); - rg = af_arritm( &world->ent_gate, rg->target ); - if( i == 1 ){ + if( !(rg->flags & k_ent_gate_passive) ) + rg = af_arritm( &world->ent_gate, rg->target ); + + if( i == 1 ) route->timing_base = rg->timing_time; - } if( i == 0 ) start_time = rg->timing_time; - else{ + else + { if( last_version+1 == rg->timing_version ) valid_sections ++; else valid_sections = 0; } - vg_info( "%u %f [%s]\n", rg->timing_version, rg->timing_time, - i? ((rg->flags & k_ent_gate_clean_pass)? "CLEAN": " "): - " N/A "); + vg_info( "%u %f [%s]\n", rg->timing_version, rg->timing_time, + i? ((rg->flags & k_ent_gate_clean_pass)? "CLEAN": " "): " N/A "); if( !(rg->flags & k_ent_gate_clean_pass) ) clean = 0; @@ -89,17 +91,16 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ) last_cp = cp; } - if( _world.current_run_version == last_version+1 ){ + if( _world.current_run_version == last_version+1 ) + { valid_sections ++; - if( route->checkpoints_count == 1 ){ + if( route->checkpoints_count == 1 ) route->timing_base = _world.time; - } f32 section = _world.time - last_time; - if( (section < last_cp->best_time) || (last_cp->best_time == 0.0f) ){ + if( (section < last_cp->best_time) || (last_cp->best_time == 0.0f) ) last_cp->best_time = section; - } } else valid_sections = 0; @@ -107,21 +108,23 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ) _world.current_run_version, _world.time, !localplayer.rewinded_since_last_gate? "CLEAN": " " ); - if( valid_sections==route->checkpoints_count ){ + if( valid_sections==route->checkpoints_count ) + { f64 lap_time = _world.time - start_time; - if( (route->best_laptime == 0.0) || (lap_time < route->best_laptime) ){ + if( (route->best_laptime == 0.0) || (lap_time < route->best_laptime) ) route->best_laptime = lap_time; - } route->flags |= k_ent_route_flag_achieve_silver; if( clean ) route->flags |= k_ent_route_flag_achieve_gold; ent_region_re_eval( world ); /* for steam achievements. */ - if( route->anon.official_track_id != 0xffffffff ){ + if( route->anon.official_track_id != 0xffffffff ) + { struct track_info *ti = &track_infos[ route->anon.official_track_id ]; - if( ti->achievement_id ){ + if( ti->achievement_id ) + { steam_set_achievement( ti->achievement_id ); steam_store_achievements(); } @@ -131,9 +134,7 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ) char mod_uid[ ADDON_UID_MAX ]; addon_alias_uid( alias, mod_uid ); - network_publish_laptime( mod_uid, - af_str( &world->meta.af, route->pstr_name ), - lap_time ); + network_publish_laptime( mod_uid, af_str( &world->meta.af, route->pstr_name ), lap_time ); } route->valid_checkpoints = valid_sections+1; @@ -150,23 +151,35 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ) */ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg ) { - ent_gate *dest = af_arritm( &world->ent_gate, rg->target ); + ent_gate *recording_gate; - for( u32 i=0; ient_route); i++ ){ + if( rg->flags & k_ent_gate_passive ) + recording_gate = rg; + else + recording_gate = af_arritm( &world->ent_gate, rg->target ); + + for( u32 i=0; ient_route); i++ ) + { ent_route *route = af_arritm( &world->ent_route, i ); u32 active_prev = route->active_checkpoint; route->active_checkpoint = 0xffff; - for( u32 j=0; j<4; j++ ){ - if( dest->routes[j] == i ){ - for( u32 k=0; kcheckpoints_count; k++ ){ - ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, - route->checkpoints_start+k ); + for( u32 j=0; j<4; j++ ) + { + if( recording_gate->routes[j] == i ) + { + for( u32 k=0; kcheckpoints_count; k++ ) + { + ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, route->checkpoints_start+k ); ent_gate *gk = af_arritm( &world->ent_gate, cp->gate_index ); - gk = af_arritm( &world->ent_gate, gk->target ); - if( gk == dest ){ + + if( !(gk->flags & k_ent_gate_passive) ) + gk = af_arritm( &world->ent_gate, gk->target ); + + if( gk == recording_gate ) + { route->active_checkpoint = k; world_routes_time_lap( world, route ); break; @@ -177,15 +190,16 @@ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg ) } } - dest->timing_version = _world.current_run_version; - dest->timing_time = _world.time; + recording_gate->timing_version = _world.current_run_version; + recording_gate->timing_time = _world.time; - if( localplayer.rewinded_since_last_gate ){ + if( localplayer.rewinded_since_last_gate ) + { localplayer.rewinded_since_last_gate = 0; - dest->flags &= ~k_ent_gate_clean_pass; + recording_gate->flags &= ~k_ent_gate_clean_pass; } else - dest->flags |= k_ent_gate_clean_pass; + recording_gate->flags |= k_ent_gate_clean_pass; _world.current_run_version ++; } @@ -357,8 +371,7 @@ void world_routes_place_curve( world_instance *world, ent_route *route, } } -static void world_routes_gen_meshes( world_instance *world, u32 route_id, - scene_context *sc ) +static void world_routes_gen_meshes( world_instance *world, u32 route_id, scene_context *sc ) { ent_route *route = af_arritm( &world->ent_route, route_id ); u8 colour[4]; @@ -369,7 +382,8 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id, u32 last_valid = 0; - for( int i=0; icheckpoints_count; i++ ){ + for( int i=0; icheckpoints_count; i++ ) + { int i0 = route->checkpoints_start+i, i1 = route->checkpoints_start+((i+1)%route->checkpoints_count); @@ -377,10 +391,16 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id, *c1 = af_arritm(&world->ent_checkpoint, i1); ent_gate *start_gate = af_arritm( &world->ent_gate, c0->gate_index ); - start_gate = af_arritm( &world->ent_gate, start_gate->target ); + if( !(start_gate->flags & k_ent_gate_passive) ) + start_gate = af_arritm( &world->ent_gate, start_gate->target ); - ent_gate *end_gate = af_arritm( &world->ent_gate, c1->gate_index ), - *collector = af_arritm( &world->ent_gate, end_gate->target ); + ent_gate *end_gate = af_arritm( &world->ent_gate, c1->gate_index ); + + ent_gate *collector; + if( end_gate->flags & k_ent_gate_passive ) + collector = end_gate; + else + collector = af_arritm( &world->ent_gate, end_gate->target ); v4f p[3]; @@ -396,7 +416,8 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id, v3f temp_alignments[2]; ent_gate *both[] = { start_gate, end_gate }; - for( int j=0; j<2; j++ ){ + for( int j=0; j<2; j++ ) + { int pi = c0->path_start + ((j==1)? c0->path_count-1: 0); ent_path_index *index = af_arritm( &world->ent_path_index, pi ); @@ -411,8 +432,8 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id, v3_add( (v3f){0.0f,0.1f,0.0f}, temp_alignments[j], temp_alignments[j]); } - - for( int j=0; jpath_count; j ++ ){ + for( int j=0; jpath_count; j ++ ) + { ent_path_index *index = af_arritm( &world->ent_path_index, c0->path_start+j ); ent_route_node *rn = af_arritm( &world->ent_route_node, @@ -429,9 +450,9 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id, p[1][3] -= (float)rn->ref_total * 0.5f; rn->ref_count ++; - if( j+1 < c0->path_count ){ - index = af_arritm( &world->ent_path_index, - c0->path_start+j+1 ); + if( j+1 < c0->path_count ) + { + index = af_arritm( &world->ent_path_index, c0->path_start+j+1 ); rn = af_arritm( &world->ent_route_node, index->index ); if( j+1 == c0->path_count-1 ) @@ -442,7 +463,8 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id, p[2][3] = rn->ref_count; p[2][3] -= (float)rn->ref_total * 0.5f; } - else{ + else + { v3_copy( end_gate->co[0], p[2] ); v3_add( (v3f){0.0f,0.1f,0.0f}, p[2], p[2] ); p[2][3] = collector->ref_count; @@ -552,9 +574,11 @@ void world_gen_routes_ent_init( world_instance *world ) { vg_info( "Initializing routes\n" ); - for( u32 i=0; ient_gate); i++ ){ + for( u32 i=0; ient_gate); i++ ) + { ent_gate *gate = af_arritm( &world->ent_gate, i ); - for( u32 j=0; j<4; j++ ){ + for( u32 j=0; j<4; j++ ) + { gate->routes[j] = 0xffff; } } @@ -582,42 +606,48 @@ void world_gen_routes_ent_init( world_instance *world ) } } - for( u32 j=0; jcheckpoints_count; j++ ){ + for( u32 j=0; jcheckpoints_count; j++ ) + { u32 id = route->checkpoints_start + j; ent_checkpoint *cp = af_arritm(&world->ent_checkpoint,id); ent_gate *gate = af_arritm( &world->ent_gate, cp->gate_index ); - for( u32 k=0; k<4; k++ ){ - if( gate->routes[k] == 0xffff ){ + for( u32 k=0; k<4; k++ ) + { + if( gate->routes[k] == 0xffff ) + { gate->routes[k] = i; break; } } - if( (gate->flags & k_ent_gate_linked) & - !(gate->flags & k_ent_gate_nonlocal) ){ - gate = af_arritm(&world->ent_gate, gate->target ); + if( (gate->flags & k_ent_gate_linked) && !(gate->flags & k_ent_gate_nonlocal) ) + { + ent_gate *recording_gate = af_arritm( &world->ent_gate, gate->target ); + + bool assigned = 0; - for( u32 k=0; k<4; k++ ){ - if( gate->routes[k] == i ){ - vg_error( "already assigned route to gate\n" ); + for( u32 k=0; k<4; k++ ) + { + if( recording_gate->routes[k] == i ) + { + vg_error( "Already assigned route to gate. Possibly the gate is referenced twice by the route.\n" ); break; } - if( gate->routes[k] == 0xffff ){ - gate->routes[k] = i; - break; + + if( !assigned && (recording_gate->routes[k] == 0xffff) ) + { + recording_gate->routes[k] = i; + assigned = 1; } } } } } - for( u32 i=0; ient_gate); i++ ){ - ent_gate *gate = af_arritm( &world->ent_gate, i ); - } - - for( u32 i=0; ient_checkpoint); i++ ){ + for( u32 i=0; ient_checkpoint); i++ ) + { ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, i ); cp->best_time = 0.0; } @@ -744,21 +774,30 @@ void world_routes_update_timer_texts( world_instance *world ) { world_render.timer_text_count = 0; - for( u32 i=0; ient_route); i++ ){ + for( u32 i=0; ient_route); i++ ) + { ent_route *route = af_arritm( &world->ent_route, i ); - if( route->active_checkpoint != 0xffff ){ + if( route->active_checkpoint != 0xffff ) + { u32 next = route->active_checkpoint+1; next = next % route->checkpoints_count; next += route->checkpoints_start; ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, next ); ent_gate *gate = af_arritm( &world->ent_gate, cp->gate_index ); - ent_gate *dest = af_arritm( &world->ent_gate, gate->target ); + ent_gate *dest; + + if( gate->flags & k_ent_gate_passive ) + dest = gate; + else + dest = af_arritm( &world->ent_gate, gate->target ); u32 j=0; - for( ; j<4; j++ ){ - if( dest->routes[j] == i ){ + for( ; j<4; j++ ) + { + if( dest->routes[j] == i ) + { break; } } @@ -768,9 +807,7 @@ void world_routes_update_timer_texts( world_instance *world ) depth = 0.4f, size = 0.4f; - struct timer_text *text = - &world_render.timer_texts[ world_render.timer_text_count ++ ]; - + struct timer_text *text = &world_render.timer_texts[ world_render.timer_text_count ++ ]; text->gate = gate; text->route = route; @@ -831,7 +868,8 @@ void world_routes_update_timer_texts( world_instance *world ) { 0.92f - align_r, h1, depth }, }; - if( dest->route_count == 1 ){ + if( dest->route_count == 1 ) + { positions[0][0] = -align_r*0.5f; positions[0][1] = h1; } @@ -840,8 +878,7 @@ void world_routes_update_timer_texts( world_instance *world ) ent_gate_get_mdl_mtx( gate, mmdl ); m3x3_copy( mmdl, text->transform ); - float ratio = v3_length(text->transform[0]) / - v3_length(text->transform[1]); + float ratio = v3_length(text->transform[0]) / v3_length(text->transform[1]); m3x3_scale( text->transform, (v3f){ size, size*ratio, 0.1f } ); m4x3_mulv( mmdl, positions[j], text->transform[3] ); @@ -849,18 +886,24 @@ void world_routes_update_timer_texts( world_instance *world ) } } -void world_routes_fracture( world_instance *world, ent_gate *gate, - v3f imp_co, v3f imp_v ) +void world_routes_fracture( world_instance *world, ent_gate *gate, v3f imp_co, v3f imp_v ) { world_render.text_particle_count = 0; - for( u32 i=0; igate != gate ) continue; + if( text->gate != gate ) + continue; m4x3f transform; - m4x3_mul( gate->transport, text->transform, transform ); + if( gate->flags & k_ent_gate_passive ) + m4x3_copy( text->transform, transform ); + else + { + m4x3_mul( gate->transport, text->transform, transform ); + } v3f co, s; v4f q; @@ -874,16 +917,19 @@ void world_routes_fracture( world_instance *world, ent_gate *gate, v3_muls( text->route->colour, brightness, colour ); colour[3] = 1.0f-text->route->factive; - for( u32 j=0;; j++ ){ + for( u32 j=0;; j++ ) + { char c = text->text[j]; - if( !c ) break; + if( !c ) + break; ent_glyph *glyph = font3d_glyph( &gui.font, 0, c ); - if( !glyph ) continue; + if( !glyph ) + continue; - if( c >= (u32)'0' && c <= (u32)'9' && glyph->indice_count ){ - struct text_particle *particle = - &world_render.text_particles[world_render.text_particle_count++]; + if( (c >= (u32)'0') && (c <= (u32)'9') && glyph->indice_count ) + { + struct text_particle *particle = &world_render.text_particles[world_render.text_particle_count++]; particle->glyph = glyph; v4_copy( colour, particle->colour ); @@ -921,13 +967,15 @@ void world_routes_fracture( world_instance *world, ent_gate *gate, } } -static void render_gate_markers( m4x3f world_mmdl, int run_id, ent_gate *gate ){ - for( u32 j=0; j<4; j++ ){ - if( gate->routes[j] == run_id ){ +static void render_gate_markers( m4x3f world_mmdl, int run_id, ent_gate *gate ) +{ + for( u32 j=0; j<4; j++ ) + { + if( gate->routes[j] == run_id ) + { m4x3f mmdl; m4x3_copy( gate->to_world, mmdl ); - m3x3_scale( mmdl, (v3f){ gate->dimensions[0], - gate->dimensions[1], 1.0f } ); + m3x3_scale( mmdl, (v3f){ gate->dimensions[0], gate->dimensions[1], 1.0f } ); m4x3_mul( world_mmdl, mmdl, mmdl ); shader_model_gate_uMdl( mmdl ); @@ -955,7 +1003,8 @@ void render_world_routes( world_instance *world, shader_scene_route_uPv( cam->mtx.pv ); - if( viewing_from_hub ){ + if( viewing_from_hub ) + { m4x4f m4mdl, pvm; m4x3_expand( mmdl, m4mdl ); m4x4_mul( cam->mtx_prev.pv, m4mdl, pvm ); @@ -970,7 +1019,8 @@ void render_world_routes( world_instance *world, v3_normalize( mnormal[2] ); shader_scene_route_uNormalMtx( mnormal ); } - else{ + else + { shader_scene_route_uMdl( mmdl ); shader_scene_route_uPvmPrev( cam->mtx_prev.pv ); m3x3f ident; @@ -982,7 +1032,8 @@ void render_world_routes( world_instance *world, mesh_bind( &world->mesh_route_lines ); - for( u32 i=0; ient_route); i++ ){ + for( u32 i=0; ient_route); i++ ) + { ent_route *route = af_arritm( &world->ent_route, i ); f32 t = viewing_from_hub? 1.0f: route->factive; @@ -997,10 +1048,12 @@ void render_world_routes( world_instance *world, /* timers * ---------------------------------------------------- */ - if( !viewing_from_gate && !viewing_from_hub ){ + if( !viewing_from_gate && !viewing_from_hub ) + { font3d_bind( &gui.font, k_font_shader_default, 0, world, cam ); - for( u32 i=0; imdl ); shader_model_font_uColour( particle->colour ); - mesh_drawn( particle->glyph->indice_start, - particle->glyph->indice_count ); + mesh_drawn( particle->glyph->indice_start, particle->glyph->indice_count ); } } @@ -1055,8 +1108,10 @@ void render_world_routes( world_instance *world, glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); glDisable( GL_CULL_FACE ); - if( viewing_from_hub ){ - for( u32 i=0; ient_route); i++ ){ + if( viewing_from_hub ) + { + for( u32 i=0; ient_route); i++ ) + { ent_route *route = af_arritm( &world->ent_route, i ); v4f colour; @@ -1065,7 +1120,8 @@ void render_world_routes( world_instance *world, shader_model_gate_uColour( colour ); - for( u32 j=0; jent_gate); j ++ ){ + for( u32 j=0; jent_gate); j ++ ) + { ent_gate *gate = af_arritm( &world->ent_gate, j ); if( !(gate->flags & k_ent_gate_nonlocal) ) render_gate_markers( mmdl, i, gate ); diff --git a/src/world_routes_ui.c b/src/world_routes_ui.c index ed430ca..0dabcd5 100644 --- a/src/world_routes_ui.c +++ b/src/world_routes_ui.c @@ -3,7 +3,8 @@ #include "world_routes.h" #include "player.h" -static u32 v4_rgba( v4f colour ){ +static u32 v4_rgba( v4f colour ) +{ u32 r = vg_minf(1.0f,colour[0])*255.0f, g = vg_minf(1.0f,colour[1])*255.0f, b = vg_minf(1.0f,colour[2])*255.0f, @@ -12,9 +13,8 @@ static u32 v4_rgba( v4f colour ){ return r | (g<<8) | (b<<16) | (a<<24); } -static void ent_route_imgui( ui_context *ctx, - world_instance *world, ent_route *route, - ui_point inout_cursor ){ +static void ent_route_imgui( ui_context *ctx, world_instance *world, ent_route *route, ui_point inout_cursor ) +{ if( route->flags & k_ent_route_flag_out_of_zone ) return; @@ -30,16 +30,20 @@ static void ent_route_imgui( ui_context *ctx, } blocks[ route->checkpoints_count ]; - for( u32 i=0; icheckpoints_count; i++ ){ + for( u32 i=0; icheckpoints_count; i++ ) + { u32 cpid = i+route->active_checkpoint+1; cpid %= route->checkpoints_count; cpid += route->checkpoints_start; ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, cpid ); ent_gate *rg = af_arritm( &world->ent_gate, cp->gate_index ); - rg = af_arritm( &world->ent_gate, rg->target ); - if( last_version+1 == rg->timing_version ) { + if( !(rg->flags & k_ent_gate_passive) ) + rg = af_arritm( &world->ent_gate, rg->target ); + + if( last_version+1 == rg->timing_version ) + { struct time_block *block = &blocks[ valid_sections ++ ]; block->clean = (rg->flags & k_ent_gate_clean_pass)? 1: 0; block->length = rg->timing_time - last_time; @@ -52,7 +56,8 @@ static void ent_route_imgui( ui_context *ctx, last_cp = cp; } - if( last_version+1 == _world.current_run_version ){ + if( last_version+1 == _world.current_run_version ) + { struct time_block *block = &blocks[ valid_sections ++ ]; block->clean = localplayer.rewinded_since_last_gate? 0: 1; block->length = _world.time - last_time; @@ -152,8 +157,7 @@ static void ent_route_imgui( ui_context *ctx, inout_cursor[1] += h + 4; vg_slewf( &route->ui_residual, 0.0f, vg.time_frame_delta ); - route->ui_stopper = vg_lerpf( route->ui_stopper, (f32)x*0.5f, - vg.time_frame_delta ); + route->ui_stopper = vg_lerpf( route->ui_stopper, (f32)x*0.5f, vg.time_frame_delta ); } void world_routes_imgui( ui_context *ctx, world_instance *world ) diff --git a/src/world_volumes.c b/src/world_volumes.c index d4fe4c5..5e8ba75 100644 --- a/src/world_volumes.c +++ b/src/world_volumes.c @@ -1,10 +1,28 @@ #include "world_volumes.h" +void world_volumes_start( world_instance *world ) +{ + for( u32 i=0; ient_volume); i ++ ) + { + ent_volume *volume = af_arritm( &world->ent_volume, i ); + + if( volume->flags & k_ent_volume_flag_autorun ) + { + ent_call basecall; + basecall.id = mdl_entity_id( k_ent_volume, i ); + basecall.data = NULL; + basecall.function = 0; + entity_call( world, &basecall ); + } + } +} + void world_volumes_update( world_instance *world, v3f pos ) { /* filter and check the existing ones */ u32 j=0; - for( u32 i=0; i<_world.active_trigger_volume_count; i++ ){ + for( u32 i=0; i<_world.active_trigger_volume_count; i++ ) + { i32 idx = _world.active_trigger_volumes[i]; ent_volume *volume = af_arritm( &world->ent_volume, idx ); @@ -18,11 +36,13 @@ void world_volumes_update( world_instance *world, v3f pos ) boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}}; vg_line_boxf_transformed( volume->to_world, cube, 0xff00ccff ); } - else{ + else + { /* * LEGACY BEHAVIOUR: < v104 does not have leave events */ - if( world->meta.version >= 104 ){ + if( world->meta.version >= 104 ) + { ent_call basecall; basecall.function = k_ent_function_trigger_leave; basecall.id = mdl_entity_id( k_ent_volume, idx ); @@ -39,7 +59,8 @@ void world_volumes_update( world_instance *world, v3f pos ) u32 random_ticks = 0; - while( random_accum > 0.1f ){ + while( random_accum > 0.1f ) + { random_accum -= 0.1f; random_ticks ++; } @@ -50,7 +71,8 @@ void world_volumes_update( world_instance *world, v3f pos ) bh_iter_init_range( 0, &it, pos, radius ); i32 idx; - while( bh_next( world->entity_bh, &it, &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 ); @@ -60,10 +82,12 @@ void world_volumes_update( world_instance *world, v3f pos ) ent_volume *volume = af_arritm( &world->ent_volume, index ); boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}}; - if( volume->flags & k_ent_volume_flag_particles ){ + if( volume->flags & k_ent_volume_flag_particles ) + { vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff ); - for( int j=0; j - VG_ARRAY_LEN(_world.active_trigger_volumes) ) continue; + if( _world.active_trigger_volume_count > VG_ARRAY_LEN(_world.active_trigger_volumes) ) + continue; v3f local; m4x3_mulv( volume->to_local, pos, local ); diff --git a/src/world_volumes.h b/src/world_volumes.h index 2d84e9e..ba88a03 100644 --- a/src/world_volumes.h +++ b/src/world_volumes.h @@ -3,3 +3,4 @@ #include "vg/vg_bvh.h" void world_volumes_update( world_instance *world, v3f pos ); +void world_volumes_start( world_instance *world );