fix bug with player bonk head (one time-per run); add no skate/rewind flag to world
authorhgn <hgodden00@gmail.com>
Mon, 24 Feb 2025 02:09:50 +0000 (02:09 +0000)
committerhgn <hgodden00@gmail.com>
Mon, 24 Feb 2025 02:09:50 +0000 (02:09 +0000)
content_skaterift/maps/dev_heaven/main.mdl
skaterift_blender/sr_main.py
skaterift_blender/sr_mdl.py
src/control_overlay.c
src/entity.h
src/player_replay.c
src/player_skate.c
src/player_walk.c
src/world_render.c
src/world_water.c

index 113569b272a243acd85c8d7814d60419916dd741..99ee2f8c4f984dcde6336927ff331d1d6b2ec0ed 100644 (file)
Binary files a/content_skaterift/maps/dev_heaven/main.mdl and b/content_skaterift/maps/dev_heaven/main.mdl differ
index 24e9101eb8f9cccde244d99ed7307ff5b20f49ac..df9fb17e4dcf9210f445f4c44cc2f492f448c193 100644 (file)
@@ -1879,6 +1879,7 @@ class SR_OBJECT_ENT_WORLD_INFO(bpy.types.PropertyGroup):
    wind_scale: bpy.props.FloatProperty(name="Wind Scale",default=0.5)
 
    water_safe: bpy.props.BoolProperty(name="Water is Safe")
+   no_skating: bpy.props.BoolProperty(name="No Skating")
 
    @staticmethod
    def sr_inspector( layout, data ):
@@ -1894,6 +1895,7 @@ class SR_OBJECT_ENT_WORLD_INFO(bpy.types.PropertyGroup):
          layout.prop( data[0], 'timezone' )
 
       layout.prop( data[0], 'water_safe' )
+      layout.prop( data[0], 'no_skating' )
       layout.prop( data[0], 'wind_scale' )
       layout.prop( data[0], 'skybox' )
    #}
index c086bf1b9d6bdf9df800416d4b27e5f1b894e97d..fafbd7f4a7c5b4b13d3602376cb1fec304e9f09a 100644 (file)
@@ -810,6 +810,9 @@ def _mdl_compiler_compile_entities():
             if obj_data.water_safe:
                flags |= 0x2
 
+            if obj_data.no_skating:
+               flags |= 0x4
+
             worldinfo.flags = flags
             worldinfo.pstr_skybox = _af_pack_string( obj_data.skybox )
             worldinfo.wind_scale = obj_data.wind_scale
index 6d9ac11c915ee0f872ca326d61e1316efddef93d..3d9d6aceb2e04a8161939b92f631e308c4d24565 100644 (file)
@@ -56,10 +56,12 @@ static void colorize( bool press, bool condition )
        chit  = { 1,0.5f,0.2f,0.8f };
 
    if( condition )
+   {
       if( press )
          shader_model_menu_uColour( chit );
       else
          shader_model_menu_uColour( cnorm );
+   }
    else
       shader_model_menu_uColour( cdis );
 }
@@ -355,7 +357,10 @@ void control_overlay_render(void)
       }
       else if( subsytem == k_player_subsystem_walk )
       {
-         colorize( press_y, player_walk.state.activity < k_walk_activity_inone );
+         bool allow = player_walk.state.activity < k_walk_activity_inone;
+         if( _world.main.info.flags & k_world_flag_no_skating )
+            allow = 0;
+         colorize( press_y, allow );
          render_overlay_mesh( ov_text_y_skate );
       }
       else if( subsytem == k_player_subsystem_glide )
@@ -427,7 +432,7 @@ void control_overlay_render(void)
       if( press_dpad_e )
          render_overlay_mesh( ov_dpad_e );
 
-      colorize( press_dpad_w, 1 );
+      colorize( press_dpad_w, !(_world.main.info.flags & k_world_flag_no_skating) );
       render_overlay_mesh( ov_text_dw_rewind );
       if( press_dpad_w )
          render_overlay_mesh( ov_dpad_w );
@@ -683,7 +688,10 @@ void control_overlay_render(void)
       }
       else if( subsytem == k_player_subsystem_walk )
       {
-         colorize( press_e, player_walk.state.activity < k_walk_activity_inone );
+         bool allow = player_walk.state.activity < k_walk_activity_inone;
+         if( _world.main.info.flags & k_world_flag_no_skating )
+            allow = 0;
+         colorize( press_e, allow );
          render_overlay_mesh( ov_text_skate );
       }
 
@@ -699,7 +707,7 @@ void control_overlay_render(void)
       shader_model_menu_uColour( cnorm );
       shader_model_menu_uMdl( mmdl );
 
-      colorize( press_r, 1 );
+      colorize( press_r, !(_world.main.info.flags & k_world_flag_no_skating) );
       draw_key( press_r, 0 );
       render_overlay_mesh( ov_text_rewind );
 
@@ -709,8 +717,7 @@ void control_overlay_render(void)
       mmdl[3][2] = 1.0f - 0.125f;
 
 
-      if( subsytem == k_player_subsystem_skate ||
-          subsytem == k_player_subsystem_walk )
+      if( subsytem == k_player_subsystem_skate || subsytem == k_player_subsystem_walk )
       {
          shader_model_menu_uMdl( mmdl );
          colorize( press_space, !in_air );
index 50e202dcd0afe7709c5747100f0bc6ffbf79bb14..83bb0508fdc2e47943121b4a921ff114ef0c0224 100644 (file)
@@ -484,7 +484,15 @@ struct ent_menuitem{
    };
 };
 
-struct ent_worldinfo{
+enum world_flag
+{
+   k_world_flag_fixed_time = 0x1,
+   k_world_flag_water_is_safe = 0x2,
+   k_world_flag_no_skating = 0x4
+};
+
+struct ent_worldinfo
+{
    u32 pstr_name, pstr_author, pstr_desc;
    f32 timezone;
    u32 pstr_skybox;
index a3e5b7d610652c0414f3daddd62170f74d261743..3c7060fd799fd8bc1d85e3941043ce6efe8362ab 100644 (file)
@@ -762,18 +762,25 @@ void skaterift_replay_post_render(void)
    /* capture the current resume frame at the very last point */
    if( button_down( k_srbind_reset ) )
    {
-      if( skaterift.activity == k_skaterift_default )
+      if( _world.main.info.flags & k_world_flag_no_skating )
       {
-         localplayer.rewinded_since_last_gate = 1;
-         skaterift.activity = k_skaterift_replay;
-         skaterift_record_frame( &player_replay.local, 1 );
-         if( player_replay.local.head )
+         gui_location_print_ccmd( 1, (const char *[]){ KRED "Rewind is not allowed here.." } );
+      }
+      else
+      {
+         if( skaterift.activity == k_skaterift_default )
          {
-            player_replay.local.cursor = player_replay.local.head->time;
-            player_replay.local.cursor_frame = player_replay.local.head;
+            localplayer.rewinded_since_last_gate = 1;
+            skaterift.activity = k_skaterift_replay;
+            skaterift_record_frame( &player_replay.local, 1 );
+            if( player_replay.local.head )
+            {
+               player_replay.local.cursor = player_replay.local.head->time;
+               player_replay.local.cursor_frame = player_replay.local.head;
+            }
+            player_replay.replay_control = k_replay_control_scrub;
+            replay_show_helpers();
          }
-         player_replay.replay_control = k_replay_control_scrub;
-         replay_show_helpers();
       }
    }
 }
index 8d0e0864d1dbb234651ec121a416aa83a2af4803..b95defec5234d4e8aefab4c0ca17aeb7af8168aa 100644 (file)
@@ -2503,8 +2503,7 @@ begin_collision:;
    float t;
    v3f n;
    if( (v3_dist2( head_wp0, head_wp1 ) > 0.001f) &&
-       (spherecast_world( world, head_wp0, head_wp1, 0.2f, &t, n,
-                          k_material_flag_walking ) != -1) )
+       (spherecast_world( world, head_wp0, head_wp1, 0.2f, &t, n, k_material_flag_walking ) != -1) )
    {
       v3_lerp( start_co, localplayer.rb.co, t, localplayer.rb.co );
       rb_update_matrices( &localplayer.rb );
@@ -3458,11 +3457,13 @@ void player__skate_effects( void *_animator, m4x3f *final_mtx,
    struct player_skate_animator *animator = _animator;
 
    v3f vp0, vp1, vpc;
-   if( board ){
+   if( board )
+   {
       v3_copy((v3f){0.0f,0.02f, board->truck_positions[0][2]}, vp1 );
       v3_copy((v3f){0.0f,0.02f, board->truck_positions[1][2]}, vp0 );
    }
-   else{
+   else
+   {
       v3_zero( vp0 );
       v3_zero( vp1 );
    }
@@ -3473,8 +3474,10 @@ void player__skate_effects( void *_animator, m4x3f *final_mtx,
    v3_add( vp0, vp1, vpc );
    v3_muls( vpc, 0.5f, vpc );
 
-   if( animator->surface == k_surface_prop_sand ){
-      if( (animator->slide>0.4f) && (v3_length2(animator->root_v)>4.0f*4.0f) ){
+   if( animator->surface == k_surface_prop_sand )
+   {
+      if( (animator->slide>0.4f) && (v3_length2(animator->root_v)>4.0f*4.0f) )
+      {
          v3f v, co;
          v3_muls( animator->root_v, 0.5f, v );
          v3_lerp( vp0, vp1, vg_randf64(&vg.rand), co );
@@ -3484,53 +3487,46 @@ void player__skate_effects( void *_animator, m4x3f *final_mtx,
       }
    }
 
-   if( animator->grind > 0.5f ){
+   if( animator->grind > 0.5f )
+   {
       int back = 0, front = 0, mid = 0;
 
-      if( animator->activity == k_skate_activity_grind_5050 ){
+      if( animator->activity == k_skate_activity_grind_5050 )
+      {
          back = 1;
          front = 1;
       }
-      else if( animator->activity == k_skate_activity_grind_back50 ){
+      else if( animator->activity == k_skate_activity_grind_back50 )
          back = 1;
-      }
-      else if( animator->activity == k_skate_activity_grind_front50 ){
+      else if( animator->activity == k_skate_activity_grind_front50 )
          front = 1;
-      }
-      else if( animator->activity == k_skate_activity_grind_boardslide ){
+      else if( animator->activity == k_skate_activity_grind_boardslide )
          mid = 1;
-      }
 
-      if( back ){
-         effect_spark_apply( &effect_data->spark, vp0,
-                              animator->root_v, vg.time_delta );
-      }
+      if( back )
+         effect_spark_apply( &effect_data->spark, vp0, animator->root_v, vg.time_delta );
 
-      if( front ){
-         effect_spark_apply( &effect_data->spark, vp1,
-                              animator->root_v, vg.time_delta );
-      }
+      if( front )
+         effect_spark_apply( &effect_data->spark, vp1, animator->root_v, vg.time_delta );
 
-      if( mid ){
-         effect_spark_apply( &effect_data->spark, vpc,
-                              animator->root_v, vg.time_delta );
-      }
+      if( mid )
+         effect_spark_apply( &effect_data->spark, vpc, animator->root_v, vg.time_delta );
    }
 }
 
-void player__skate_post_animate(void){
+void player__skate_post_animate(void)
+{
    struct player_skate_state *state = &player_skate.state;
    localplayer.cam_velocity_influence = 1.0f;
    localplayer.cam_dist = 1.8f;
 
    v3f head = { 0.0f, 1.8f, 0.0f };
-   m4x3_mulv( localplayer.final_mtx[ localplayer.id_head ], 
-              head, state->head_position );
-   m4x3_mulv( localplayer.rb.to_local, 
-              state->head_position, state->head_position );
+   m4x3_mulv( localplayer.final_mtx[ localplayer.id_head ], head, state->head_position );
+   m4x3_mulv( localplayer.rb.to_local, state->head_position, state->head_position );
 }
 
-void player__skate_reset_animator(void){
+void player__skate_reset_animator(void)
+{
    struct player_skate_state *state = &player_skate.state;
 
    memset( &player_skate.animator, 0, sizeof(player_skate.animator) );
@@ -3562,6 +3558,7 @@ void player__skate_clear_mechanics(void)
 
    v3_zero( state->air_init_v );
    v3_zero( state->air_init_co );
+   v3_copy( (v3f){0,0.8f,0}, state->head_position );
 
    state->gravity_bias   = k_gravity;
    v3_copy( localplayer.rb.co, state->prev_pos );
@@ -3584,7 +3581,8 @@ void player__skate_clear_mechanics(void)
 
 #include "network_compression.h"
 
-void player__skate_animator_exchange( bitpack_ctx *ctx, void *data ){
+void player__skate_animator_exchange( bitpack_ctx *ctx, void *data )
+{
    struct player_skate_animator *animator = data;
    
    bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->root_co );
@@ -3636,24 +3634,21 @@ void player__skate_animator_exchange( bitpack_ctx *ctx, void *data ){
    bitpack_bytes( ctx, 1, &animator->activity );
 }
 
-void player__skate_sfx_oneshot( u8 id, v3f pos, f32 volume ){
+void player__skate_sfx_oneshot( u8 id, v3f pos, f32 volume )
+{
    audio_lock();
 
    if( id == k_player_skate_soundeffect_jump ){
-      audio_oneshot_3d( &audio_jumps[vg_randu32(&vg.rand)%2], 
-                        pos, 40.0f, volume );
+      audio_oneshot_3d( &audio_jumps[vg_randu32(&vg.rand)%2], pos, 40.0f, volume );
    }
    else if( id == k_player_skate_soundeffect_tap ){
-      audio_oneshot_3d( &audio_taps[vg_randu32(&vg.rand)%4], 
-                        pos, 40.0f, volume );
+      audio_oneshot_3d( &audio_taps[vg_randu32(&vg.rand)%4], pos, 40.0f, volume );
    }
    else if( id == k_player_skate_soundeffect_land_good ){
-      audio_oneshot_3d( &audio_lands[vg_randu32(&vg.rand)%3], 
-                        pos, 40.0f, volume );
+      audio_oneshot_3d( &audio_lands[vg_randu32(&vg.rand)%3], pos, 40.0f, volume );
    }
    else if( id == k_player_skate_soundeffect_land_bad ){
-      audio_oneshot_3d( &audio_lands[vg_randu32(&vg.rand)%2+3], 
-                        pos, 40.0f, volume );
+      audio_oneshot_3d( &audio_lands[vg_randu32(&vg.rand)%2+3], pos, 40.0f, volume );
    }
    else if( id == k_player_skate_soundeffect_grind_metal ){
       audio_oneshot_3d( &audio_board[3], pos, 40.0f, volume );
index b267ea80acddd39ba5f30edb9507444cc57c0343..fd7aeb669cf89bcfe83df6d79d4316e2357f04f9 100644 (file)
@@ -43,7 +43,8 @@ static float player_xyspeed2(void){
    return v3_length2( (v3f){localplayer.rb.v[0], 0.0f, localplayer.rb.v[2]} );
 }
 
-static void player_walk_generic_to_skate( enum skate_activity init, f32 yaw ){
+static void player_walk_generic_to_skate( enum skate_activity init, f32 yaw )
+{
    localplayer.subsystem = k_player_subsystem_skate;
 
    v3f v;
@@ -255,7 +256,8 @@ static bool player__preupdate_anim( struct skeleton_anim *anim, f32 *t,
    else             return 0;
 }
 
-static void player_walk_pre_sit(void){
+static void player_walk_pre_sit(void)
+{
    struct player_walk *w = &player_walk;
 
    v2f steer;
@@ -270,7 +272,8 @@ static void player_walk_pre_sit(void){
    return;
 }
 
-static void player_walk_pre_sit_up(void){
+static void player_walk_pre_sit_up(void)
+{
    struct player_walk *w = &player_walk;
    
    if( w->state.transition_t > 0.0f )
@@ -298,12 +301,19 @@ static void player_walk_pre_ground(void)
 
    if( button_down( k_srbind_skate ) )
    {
-      if( player_walk_scan_for_drop_in() )
-         w->state.activity = k_walk_activity_odrop_in;
+      if( _world.main.info.flags & k_world_flag_no_skating )
+      {
+         gui_location_print_ccmd( 1, (const char *[]){ KRED "Skating is not allowed here.." } );
+      }
       else
-         w->state.activity = k_walk_activity_oregular;
+      {
+         if( player_walk_scan_for_drop_in() )
+            w->state.activity = k_walk_activity_odrop_in;
+         else
+            w->state.activity = k_walk_activity_oregular;
 
-      w->state.transition_t = 0.0f;
+         w->state.transition_t = 0.0f;
+      }
    }
 
    if( button_down( k_srbind_jump ) )
@@ -318,8 +328,15 @@ static void player_walk_pre_air(void)
    struct player_walk *w = &player_walk;
    if( button_down( k_srbind_skate ) )
    {
-      w->state.activity = k_walk_activity_oair;
-      w->state.transition_t = 0.0f;
+      if( _world.main.info.flags & k_world_flag_no_skating )
+      {
+         gui_location_print_ccmd( 1, (const char *[]){ KRED "Skating is not allowed here.." } );
+      }
+      else
+      {
+         w->state.activity = k_walk_activity_oair;
+         w->state.transition_t = 0.0f;
+      }
    }
 
    if( button_down( k_srbind_jump ) )
@@ -329,7 +346,8 @@ static void player_walk_pre_air(void)
    }
 }
 
-static void player_walk_pre_drop_in(void){
+static void player_walk_pre_drop_in(void)
+{
    struct player_walk *w = &player_walk;
    bool finished = player__preupdate_anim( &w->anim_drop_in, 
                                            &w->state.transition_t, 1.0f );
@@ -337,13 +355,13 @@ static void player_walk_pre_drop_in(void){
       player_walk_drop_in_to_skate();
 }
 
-static void player_walk_pre_caveman(void){
+static void player_walk_pre_caveman(void)
+{
    struct player_walk *w = &player_walk;
-   bool finished = player__preupdate_anim( &w->anim_jump_to_air,
-                                           &w->state.transition_t, 1.0f );
-   if( finished ){
-      player_walk_generic_to_skate( k_skate_activity_air, 
-                                    player_walk.animator.board_yaw );
+   bool finished = player__preupdate_anim( &w->anim_jump_to_air, &w->state.transition_t, 1.0f );
+   if( finished )
+   {
+      player_walk_generic_to_skate( k_skate_activity_air, player_walk.animator.board_yaw );
    }
 }
 
index c363e35147611623e23d79108be207d390e0e5f5..6db609582444c3ed3aec2d0b1c5442a40ecd637a 100644 (file)
@@ -190,31 +190,31 @@ static void world_render_submeshes( world_instance *world,
 /*
  * Render props attached to this material
  */
-static void world_render_props( world_instance *world, u32 material_id,
-                                struct world_pass *pass )
+static void world_render_props( world_instance *world, u32 material_id, struct world_pass *pass )
 {
    struct world_surface *mat = &world->surfaces[ material_id ];
    if( !(mat->flags & WORLD_SURFACE_HAS_PROPS) ) return;
 
    pass->fn_bind( world, mat );
 
-   for( u32 j=0; j<af_arrcount( &world->ent_prop ); j++ ){
+   for( u32 j=0; j<af_arrcount( &world->ent_prop ); j++ )
+   {
       ent_prop *prop = af_arritm( &world->ent_prop, j );
-      if( prop->flags & 0x1 ) continue;
+      if( prop->flags & k_world_flag_fixed_time ) 
+         continue;
 
-      world_render_submeshes( world, pass, &prop->transform, 
-            prop->submesh_start, prop->submesh_count, material_id );
+      world_render_submeshes( world, pass, &prop->transform, prop->submesh_start, prop->submesh_count, material_id );
    }
 }
 
 /*
  * Render traffic models attactched to this material
  */
-static void world_render_traffic( world_instance *world, u32 material_id,
-                                  struct world_pass *pass )
+static void world_render_traffic( world_instance *world, u32 material_id,struct world_pass *pass )
 {
    struct world_surface *mat = &world->surfaces[ material_id ];
-   if( !(mat->flags & WORLD_SURFACE_HAS_TRAFFIC) ) return;
+   if( !(mat->flags & WORLD_SURFACE_HAS_TRAFFIC) ) 
+      return;
 
    pass->fn_bind( world, mat );
 
@@ -506,11 +506,11 @@ static void world_render_challenges( world_instance *world, struct world_pass *p
    u32 objective_count = 0,
        challenge_count = 0;
 
-   u32 challenge_index = mdl_entity_id_id( _world.active_challenge_id );
-   ent_challenge *challenge = af_arritm( &world->ent_challenge, challenge_index );
-
    if( (_world.event == k_world_event_challenge) && (_world.challenge_state == k_challenge_state_running) )
    {
+      u32 challenge_index = mdl_entity_id_id( _world.active_challenge_id );
+      ent_challenge *challenge = af_arritm( &world->ent_challenge, challenge_index );
+
       shader_scene_fxglow_uUvOffset( (v2f){ 8.0f/256.0f, 0.0f } );
       challenge_list[ challenge_count ++ ] = challenge_index;
 
index cf421366724823c91ed19fd7af2b85d8b02a9846..fd25b5608980cde56a356f0ec53530d2d6d263e8 100644 (file)
@@ -239,8 +239,10 @@ static void world_water_drown(void)
 
 bool world_water_player_safe( world_instance *world, f32 allowance )
 {
-   if( !world->water.enabled ) return 1;
-   if( world->info.flags & 0x2 ) return 1;
+   if( !world->water.enabled ) 
+      return 1;
+   if( world->info.flags & k_world_flag_water_is_safe ) 
+      return 1;
 
    if( localplayer.rb.co[1]+allowance < world->water.height )
    {