before the storm
[carveJwlIkooP6JGAAIwe30JlM.git] / player.h
index 97c799ee61ca7d151999b14ca0aa5a9c38b4621d..6fb74dcf6427c5c6ce6a709399f77edb9a9dadec 100644 (file)
--- a/player.h
+++ b/player.h
@@ -1,3 +1,7 @@
+/*
+ * Copyright 2021-2022 (C) Mount0 Software, Harry Godden - All Rights Reserved
+ */
+
 #ifndef PLAYER_H
 #define PLAYER_H
 
@@ -46,6 +50,7 @@ static struct gplayer
 
    /* TODO: eugh */
    m3x3f gate_vr_frame, gate_vr_pstep_frame;
+   int on_board_frame, in_air_frame;
 
    v3f a, v_last, m, bob, vl;
 
@@ -93,7 +98,7 @@ static struct gplayer
          walk_timer,
          fonboard;
 
-   v3f last_step_pos;
+v3f last_step_pos;
    int step_phase;
 }
 player = 
@@ -108,6 +113,11 @@ player =
  * Player API
  */
 
+static float *player_get_pos(void)
+{
+   return player.rb.co;
+}
+
 
 /*
  * Free camera movement
@@ -811,7 +821,19 @@ static void player_do_motion(void)
          
          world_routes_activate_gate( i );
          player.rb_gate_frame = player.rb;
+         player.in_air_frame = player.in_air;
+         player.on_board_frame = player.on_board;
+
+         if( !player.on_board )
+         {
+            v3f fwd_dir = {cosf(player.angles[0]),
+                           0.0f,
+                           sinf(player.angles[0])};
+            m3x3_mulv( gate->transport, fwd_dir, fwd_dir );
 
+            player.angles[0] = atan2f( fwd_dir[2], fwd_dir[0] );
+         }
+         
          m3x3_copy( player.vr, player.gate_vr_frame );
          m3x3_copy( player.vr_pstep, player.gate_vr_pstep_frame );
 
@@ -914,7 +936,6 @@ static void player_animate(void)
 
    offset[0] = vg_clampf( offset[0], -0.8f, 0.8f );
    offset[1] = vg_clampf( offset[1], -0.5f, 0.0f );
-   offset[1] = 0.0f;
 
    /* 
     * Animation blending
@@ -1014,7 +1035,7 @@ static void player_animate(void)
 
    skeleton_lerp_pose( sk, ground_pose, air_pose, player.ffly, apose );
 
-   float add_grab_mod = player.ffly * player.grab;
+   float add_grab_mod = 1.0f - player.ffly*player.grab;
 
    /* additive effects */
    apose[player.mdl.id_hip-1].co[0] += offset[0]*add_grab_mod;
@@ -1043,9 +1064,13 @@ static void player_animate(void)
 static void player_camera_update(void)
 {
    /* Update camera matrices */
-   m4x3_identity( player.camera );
-   m4x3_rotate_y( player.camera, -player.angles[0] );
-   m4x3_rotate_x( player.camera, -player.angles[1] );
+   v4f qyaw, qpitch, qcam;
+   q_axis_angle( qyaw, (v3f){ 0.0f, 1.0f, 0.0f }, -player.angles[0] ); 
+   q_axis_angle( qpitch, (v3f){ 1.0f, 0.0f, 0.0f }, -player.angles[1] ); 
+
+   q_mul( qyaw, qpitch, qcam );
+   q_m3x3( qcam, player.camera );
+
    v3_copy( player.camera_pos, player.camera[3] );
    m4x3_invert_affine( player.camera, player.camera_inverse );
 }
@@ -1214,6 +1239,41 @@ static void player_audio(void)
 
    /* Tunnel / occlusion */
    audio_sample_occlusion( player.camera[3] );
+
+   int sprite_avail = -1;
+   for( int i=0; i<vg_list_size(ambient_sprites); i++ )
+   {
+      if( !audio_player_is_playing( &ambient_sprites[i] ) )
+      {
+         sprite_avail = i;
+         break;
+      }
+   }
+   
+   if( sprite_avail != -1 )
+   {
+      v3f waterpos;
+      enum audio_sprite_type sprite_type = 
+         audio_sample_sprite_random( player.rb.co, waterpos );
+
+      if( sprite_type != k_audio_sprite_type_none )
+      {
+         audio_player *avail = &ambient_sprites[ sprite_avail ];
+
+         audio_player_set_vol( avail, 20.0f );
+         audio_player_set_flags( avail, AUDIO_FLAG_SPACIAL_3D );
+         audio_player_set_position( avail, waterpos );
+
+         if( sprite_type == k_audio_sprite_type_grass )
+         {
+            audio_player_playclip( avail, &audio_grass[rand()%4] );
+         }
+         else if( sprite_type == k_audio_sprite_type_water )
+         {
+            audio_player_playclip( avail, &audio_water[rand()%6] );
+         }
+      }
+   }
    
    if( freecam || player.is_dead || !player.on_board )
    {
@@ -1338,6 +1398,8 @@ static int reset_player( int argc, char const *argv[] )
    m3x3_identity( player.gate_vr_pstep_frame );
 
    player.rb_gate_frame = player.rb;
+   player.on_board_frame = player.on_board;
+   player.in_air_frame = player.in_air;
    return 1;
 }
 
@@ -1350,10 +1412,20 @@ static void player_update(void)
    if( vg_get_axis("grabl")>0.0f)
    {
       player.rb = player.rb_gate_frame;
+      player.on_board = player.on_board_frame;
+      player.in_air = player.in_air_frame;
       m3x3_copy( player.gate_vr_frame, player.vr );
       m3x3_copy( player.gate_vr_pstep_frame, player.vr_pstep );
       player.is_dead = 0;
       player.in_air = 1;
+
+
+      if( !player.on_board )
+      {
+         player.angles[0] = atan2f( -player.rb.forward[2], 
+                                    -player.rb.forward[0] );
+      }
+
       m3x3_identity( player.vr );
 
       player.mdl.shoes[0] = 1;