q_axis_angle( qbias, player->rb.to_world[1], yaw_bias );
q_mulv( qbias, launch_v, launch_v );
-
float gravity_bias = vg_lerpf( 0.85f, 1.4f, vt ),
gravity = k_gravity * gravity_bias;
inf->gravity = gravity;
v3f closest;
if( search_for_grind ){
if( bh_closest_point( world->geo_bh, co1, closest, 1.0f ) != -1 ){
+
+ float min_dist = 0.75f;
+ min_dist *= min_dist;
+
+ if( v3_dist2( closest, launch_co ) < min_dist )
+ search_for_grind = 0;
+
v3f bound[2];
for( int j=0; j<2; j++ ){
v3_add( launch_co, bound[j], bound[j] );
}
- float minh = vg_minf( bound[0][1], bound[1][1] ),
- maxh = vg_maxf( bound[0][1], bound[1][1] );
-
- vg_info( "%f [%f:%f]\n", closest[1], minh, maxh );
+ float limh = vg_minf( 2.0f, t ),
+ minh = vg_minf( bound[0][1], bound[1][1] )-limh,
+ maxh = vg_maxf( bound[0][1], bound[1][1] )+limh;
if( (closest[1] < minh) || (closest[1] > maxh) ){
search_for_grind = 0;
v3_muladds( ve, basis[1], -gravity * t, ve );
if( skate_grind_scansq( player, closest, ve, 0.5f, &grind ) ){
+
/* check alignment */
v2f v0 = { v3_dot( ve, basis[0] ),
v3_dot( ve, basis[2] ) },
float a = v2_dot( v0, v1 );
- if( a >= cosf( VG_PIf * 0.185f ) ){
+ float a_min = cosf( VG_PIf * 0.185f );
+ if( s->grind_cooldown )
+ a_min = cosf( VG_PIf * 0.05f );
+
+ /* check speed */
+ if( (fabsf(v3_dot( ve, grind.dir ))>=k_grind_axel_min_vel) &&
+ (a >= a_min) )
+ {
grind_located = 1;
grind_located_gravity = inf->gravity;
float t1;
v3f n;
- int idx = spherecast_world( world, co0, co1, k_board_radius, &t1, n );
+ float scan_radius = k_board_radius;
+ scan_radius *= vg_clampf( t, 0.02f, 1.0f );
+
+ int idx = spherecast_world( world, co0, co1, scan_radius, &t1, n );
if( idx != -1 ){
v3f co;
v3_lerp( co0, co1, t1, co );
s->state.slip = slip;
s->state.reverse = -vg_signf(vel[2]);
- float S = (float)s->grind_cooldown * (1.0f/20.0f);
- S = vg_minf( S, 1.0f );
-
- vel[0] += vg_cfrictf( vel[0], S * k_friction_lat * k_rb_delta );
- vel[2] += vg_cfrictf( vel[2], S * k_friction_resistance * k_rb_delta );
+ vel[0] += vg_cfrictf( vel[0], k_friction_lat * k_rb_delta );
+ vel[2] += vg_cfrictf( vel[2], k_friction_resistance * k_rb_delta );
/* Pushing additive force */
v3_normalize( jumpdir );
}else{
v3_copy( s->state.up_dir, jumpdir );
+ s->grind_cooldown = 30;
s->state.activity = k_skate_activity_ground;
- s->grind_cooldown = 0;
float tilt = player->input_js1h->axis.value * 0.3f;
tilt *= vg_signf(v3_dot( player->rb.v, s->grind_dir ));
q_axis_angle( qtilt, s->grind_dir, tilt );
q_mulv( qtilt, jumpdir, jumpdir );
}
+ s->surface_cooldown = 10;
float force = k_jump_force*s->state.jump_charge;
v3_muladds( player->rb.v, jumpdir, force, player->rb.v );
s->state.jump_charge = 0.0f;
s->state.jump_time = vg.time;
+ vg_success( PRINTF_v3f( jumpdir ) );
+
v2f steer = { player->input_js1h->axis.value,
player->input_js1v->axis.value };
v2_normalize_clamp( steer );
decay_rate_y = 1.0f;
if( s->state.activity >= k_skate_activity_grind_any ){
+#if 0
decay_rate = 1.0f-vg_lerpf( 3.0f, 20.0f, s->grind_strength ) * k_rb_delta;
decay_rate_y = decay_rate;
+#endif
+ decay_rate = 1.0f-(40.0f*k_rb_delta);
+ decay_rate_y = 1.0f-(10.0f*k_rb_delta);
}
float wx = v3_dot( player->rb.w, player->rb.to_world[0] ) * decay_rate,
vg_line_pt3( jump->apex, 0.02f, 0xffffffff );
}
-#if 0
- vg_line_pt3( s->state.apex, 0.030f, 0xff0000ff );
-#endif
-
audio_lock();
float air = s->state.activity <= k_skate_activity_air_to_grind? 1.0f: 0.0f,
speed = v3_length( player->rb.v ),
attn = vg_minf( 1.0f, speed*0.1f ),
- slide = vg_clampf( fabsf(s->state.slip), 0.0f, 1.0f ),
+ slide = vg_clampf( fabsf(s->state.slip), 0.0f, 1.0f );
+ if( s->state.activity >= k_skate_activity_grind_any ){
+ slide = 0.0f;
+ }
+
+ float
vol_main = sqrtf( (1.0f-air)*attn*(1.0f-slide) * 0.4f ),
vol_air = sqrtf( air *attn * 0.5f ),
vol_slide = sqrtf( (1.0f-air)*attn*slide * 0.25f );
const u32 flags = AUDIO_FLAG_SPACIAL_3D|AUDIO_FLAG_LOOP;
- if( !s->aud_main )
- s->aud_main = audio_request_channel( &audio_board[0], flags );
if( !s->aud_air )
s->aud_air = audio_request_channel( &audio_board[1], flags );
/* brrrrrrrrrrrt sound for tiles and stuff
* --------------------------------------------------------*/
float sidechain_amt = 0.0f,
- hz = speed * 2.0f;
+ hz = vg_maxf( speed * 2.0f, 2.0f );
- if( s->surface == k_surface_prop_tiles )
+ if( (s->surface == k_surface_prop_tiles) &&
+ (s->state.activity < k_skate_activity_grind_any) )
sidechain_amt = 1.0f;
else
sidechain_amt = 0.0f;
audio_set_lfo_frequency( 0, hz );
audio_set_lfo_wave( 0, k_lfo_polynomial_bipolar,
- vg_lerpf( 250.0f, 80.0f, attn ) );
+ vg_lerpf( 250.0f, 80.0f, attn ) );
+
+ if( s->sample_change_cooldown > 0.0f ){
+ s->sample_change_cooldown -= vg.frame_delta;
+ }
+ else{
+ int sample_type = k_skate_sample_concrete;
+
+ if( s->state.activity == k_skate_activity_grind_5050 ){
+ if( s->surface == k_surface_prop_metal )
+ sample_type = k_skate_sample_metal_scrape_generic;
+ else
+ sample_type = k_skate_sample_concrete_scrape_metal;
+ }
+ else if( (s->state.activity == k_skate_activity_grind_back50) ||
+ (s->state.activity == k_skate_activity_grind_front50) ){
+
+ float d = v3_dot( player->rb.to_world[2], s->grind_dir );
+
+ if( s->surface == k_surface_prop_metal ){
+ sample_type = k_skate_sample_metal_scrape_generic;
+ }
+ else{
+ if( d > 0.70710678118654752f )
+ sample_type = k_skate_sample_concrete_scrape_wood;
+ else
+ sample_type = k_skate_sample_concrete_scrape_metal;
+ }
+ }
+ else if( s->state.activity == k_skate_activity_grind_boardslide ){
+ if( s->surface == k_surface_prop_metal )
+ sample_type = k_skate_sample_metal_scrape_generic;
+ else
+ sample_type = k_skate_sample_concrete_scrape_wood;
+ }
+
+ audio_clip *relevant_samples[] = {
+ &audio_board[0],
+ &audio_board[0], /* TODO? */
+ &audio_board[7],
+ &audio_board[6],
+ &audio_board[5]
+ };
+
+ if( (s->main_sample_type != sample_type) || (!s->aud_main) ){
+ s->aud_main =
+ audio_channel_crossfade( s->aud_main, relevant_samples[sample_type],
+ 0.06f, flags );
+ s->sample_change_cooldown = 0.1f;
+ s->main_sample_type = sample_type;
+ }
+ }
if( s->aud_main ){
s->aud_main->colour = 0x00103efe;
struct player_skate *s = &player->_skate;
/* debounces this state manager a little bit */
- if( s->grind_cooldown < 20 ){
- s->grind_cooldown ++;
+ if( s->grind_cooldown ){
+ s->grind_cooldown --;
return k_skate_activity_undefined;
}
, new_activity = table[ res_slide << 2 | res_back50 << 1 | res_front50 ];
if( new_activity == k_skate_activity_undefined ){
- if( s->state.activity >= k_skate_activity_grind_any )
- s->grind_cooldown = 5;
+ if( s->state.activity >= k_skate_activity_grind_any ){
+ s->grind_cooldown = 15;
+ s->surface_cooldown = 10;
+ }
}
else if( new_activity == k_skate_activity_grind_boardslide ){
skate_boardslide_apply( player, &inf_slide );
v3_zero( s->surface_picture );
- for( int i=0; i<k_wheel_count; i++ )
+ int prev_contacts[2];
+
+ for( int i=0; i<k_wheel_count; i++ ){
wheels[i].state = k_collider_state_default;
+ prev_contacts[i] = s->wheel_contacts[i];
+ }
/* check if we can enter or continue grind */
enum skate_activity grindable_activity = skate_availible_grind( player );
v3_add( normal, s->surface_picture, s->surface_picture );
contact_count ++;
+ s->wheel_contacts[i] = 1;
+ }
+ else{
+ s->wheel_contacts[i] = 0;
}
m3x3_mulv( player->rb.to_local, axel, s->truckv0[i] );
}
+ if( s->surface_cooldown ){
+ s->surface_cooldown --;
+ contact_count = 0;
+ }
+
+ if( (prev_contacts[0]+prev_contacts[1] == 1) && (contact_count == 2) ){
+ audio_lock();
+ for( int i=0; i<2; i++ ){
+ if( !prev_contacts[i] ){
+ v3f co;
+ m4x3_mulv( player->rb.to_world, wheels[i].pos, co );
+ audio_oneshot_3d( &audio_taps[rand()%4], co, 40.0f, 0.75f );
+ }
+ }
+ audio_unlock();
+ }
+
if( contact_count ){
s->state.activity = k_skate_activity_ground;
s->state.gravity_bias = k_gravity;
debug_capsule( mtx, capsule.radius, capsule.height, VG__WHITE );
/* add limits */
- for( int i=0; i<s->limit_count; i++ ){
- struct grind_limit *limit = &s->limits[i];
- rb_ct *ct = &manifold[ manifold_len ++ ];
- m4x3_mulv( player->rb.to_world, limit->ra, ct->co );
- m3x3_mulv( player->rb.to_world, limit->n, ct->n );
- ct->p = limit->p;
- ct->type = k_contact_type_default;
+ if( s->state.activity >= k_skate_activity_grind_any ){
+ for( int i=0; i<s->limit_count; i++ ){
+ struct grind_limit *limit = &s->limits[i];
+ rb_ct *ct = &manifold[ manifold_len ++ ];
+ m4x3_mulv( player->rb.to_world, limit->ra, ct->co );
+ m3x3_mulv( player->rb.to_world, limit->n, ct->n );
+ ct->p = limit->p;
+ ct->type = k_contact_type_default;
+ }
}
/*
"undefined (INVALID)",
"grind_any (INVALID)",
"grind_boardslide",
- "grind_noseslide",
- "grind_tailslide",
"grind_back50",
"grind_front50",
"grind_5050"
{
struct player_skate *s = &player->_skate;
s->state.jump_charge = 0.0f;
- s->state.lift_frames = 0;
s->state.flip_rate = 0.0f;
#if 0
s->state.steery = 0.0f;