Forum

Engine Side Footsteps

Post tutorials on how to do certain tasks within game or engine code here.

Moderator: InsideQC Admins

Re: Engine Side Footsteps

Postby drm_wayne » Tue May 06, 2014 2:29 pm

i had footsteps in qc before with cheap triggers to simulate wood/metal/mud and snow, but i want to have it in the engine ;)
The Node stuff looks interesting ;)
User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm

Re: Engine Side Footsteps

Postby drm_wayne » Wed May 07, 2014 4:16 pm

I got the GetNodePoint stuff to work... well kinda... i dont get the texture under me, only above me which is weird..
How do you call the GetNodePoint?? GetNodePoint(ent->origin, ?whathere?);
User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm

Re: Engine Side Footsteps

Postby Spike » Wed May 07, 2014 4:57 pm

vec3_t end, downdir = {0, 0, -1};
VectorMA(ent->origin, 128, downdir, end);
GetNodePoint(ent->origin, end);
change the 128 for different distances.
will fail when you're in the air or standing over a ledge, also when standing on a steep-enough slope.
(although really, if your center of gravity is over the ledge, you ought to fall off anyway!)
Spike
 
Posts: 2884
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: Engine Side Footsteps

Postby drm_wayne » Wed May 07, 2014 5:27 pm

ahh thx, im still not that good when it comes to the entire vec3_t stuff :wink:
at least it shows now the texturename under me... Now i need to find out how i adapt that to my frootsteps...
User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm

Re: Engine Side Footsteps

Postby r00k » Thu May 08, 2014 2:32 am

Ya what spike said... though if you are in air you shouldn't make a footstep sound! :)

After playing awhile locally hearing generic footsteps for all surfaces its kinda funny to jump online and play DM and hear nothing.. makes me feel like im sliding around on glass! :O

Quake Live's footsteps makes me want this more and more in online games, but the DM community just DOESNT want it :(
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Re: Engine Side Footsteps

Postby drm_wayne » Thu May 08, 2014 5:28 am

Actually i dont play them local, i changed the code so they play with bots too :o
But im using "quiet" steps so you cant hear too much, also:
SNOW maps with snow footsteps makes the map feel so better :mrgreen:
You should update the tutorial 8)
User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm

Re: Engine Side Footsteps

Postby Spike » Thu May 08, 2014 3:10 pm

snow-covered surfaces needs decals or something.
Spike
 
Posts: 2884
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: Engine Side Footsteps

Postby r00k » Fri May 09, 2014 2:37 pm

drm_wayne wrote:Actually i dont play them local, i changed the code so they play with bots too :o
But im using "quiet" steps so you cant hear too much, also:
SNOW maps with snow footsteps makes the map feel so better :mrgreen:
You should update the tutorial 8)


Ya you can enable them with bots by using

Code: Select all
   if (ent == &cl_entities[cl.viewentity])
      {
         e = (int)cl.viewentity;//play my own footsteps locally
      }
      else
      {
         for (i = 0, p = cl_entities ; i < cl.num_entities ; i++, p++)//FrikBots make footstep sounds too!
         {
            if (p == ent)
            {
               e = i;
            }         
         }
      }


I do have a check for
Code: Select all
if (!((ent->modelindex == cl_modelindex[mi_player])||(ent->modelindex == cl_modelindex[mi_md3_player])))//players or frikbots only
      return;

at the top of the function... so monsters are not included, though it would be cool to hear the stomp of a shambler or the clicky-clack of the vore!
Unfortunately, this will also make footstep sounds for multiplayers too! :O which is why the 1st if statement in the functions is compared to !sv.active to abort in online games.
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Re: Engine Side Footsteps

Postby drm_wayne » Thu Aug 06, 2015 12:28 pm

Those footsteps are working fine for Quake, but i adapted the code to another mod which seems to use Halfllife
player hullsizes and the footsptes dont play (they only play if you crouch -.-), also this seems not to work with the shamber.
What do i need to change to make them play?
User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm

Re: Engine Side Footsteps

Postby frag.machine » Thu Aug 06, 2015 9:31 pm

You'll need to change the distance between the entity origin and the dest vector to fit the entity size in use.
This can be done here (change the -32 value to the new Z offset value):
Code: Select all
VectorMA (ent->origin, -32, up, dest);//trace down


Also, since you're using a different model (with probably different number of frames in the walk/run animations), you'll need to change this part, too.

All these small changes makes clear to me this would be handled in a more elegant way in the QuakeC side, not hardcoded in the engine. Oh well...
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2080
Joined: Sat Nov 25, 2006 1:49 pm

Re: Engine Side Footsteps

Postby drm_wayne » Thu Aug 06, 2015 9:45 pm

Thanks, i will try it. And yes in qc its easier. :mrgreen:
User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm

Re: Engine Side Footsteps

Postby r00k » Tue Aug 11, 2015 5:10 am

Yes, originally it was to include sounds based on the material; which i have 99% added just newver made the sounds :(
Darkplaces can do it fine in quakeC, as you can get texture names.
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Re: Engine Side Footsteps

Postby drm_wayne » Tue Aug 11, 2015 6:11 am

Heres what i have (supports 7 different surface types:)
Needs modified if you want to use the Quakeguy (this has been modified for custom player model)

Code: Select all
/*
==================
CL_Footsteps Stuff
==================
*/

#define      SURFACE_NORMAL 0 // Generic Stone
#define      SURFACE_CARPET 1 // Carpet
#define      SURFACE_GRAVEL 2 // Gravel
#define      SURFACE_METAL  3 // Metal
#define      SURFACE_SNOW   4 // Snow
#define      SURFACE_WOODEN 5 // Wood
#define      SURFACE_DIRT   6 // Dirt n mud

char *nodename = "                 "; // lel nothing xD

float plr_surfacetype;

int RecursiveNodePoint (mnode_t *node, vec3_t start, vec3_t end)
{
   float   front, back, frac;
   vec3_t   mid;
   
loc0:
   if (node->contents < 0)
      return false;      // didn't hit anything
   
// calculate mid point
   if (node->plane->type < 3)
   {
      front = start[node->plane->type] - node->plane->dist;
      back = end[node->plane->type] - node->plane->dist;
   }
   else
   {
      front = DotProduct(start, node->plane->normal) - node->plane->dist;
      back = DotProduct(end, node->plane->normal) - node->plane->dist;
   }

   // optimized recursion
   if ((back < 0) == (front < 0))
   {
      node = node->children[front < 0];
      goto loc0;
   }
   
   frac = front / (front-back);
   mid[0] = start[0] + (end[0] - start[0]) * frac;
   mid[1] = start[1] + (end[1] - start[1]) * frac;
   mid[2] = start[2] + (end[2] - start[2]) * frac;
   
// go down front side
   if (RecursiveNodePoint(node->children[front < 0], start, mid))
   {     
      return true;   // hit something
   }
   else
   {
      int      i, ds, dt;
      msurface_t   *surf;

      surf = cl.worldmodel->surfaces + node->firstsurface;
      for (i = 0 ; i < node->numsurfaces ; i++, surf++)
      {
         ds = (int)((float)DotProduct (mid, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]);
         dt = (int)((float)DotProduct (mid, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]);

         if (ds < surf->texturemins[0] || dt < surf->texturemins[1])
            continue;
         
         ds -= surf->texturemins[0];
         dt -= surf->texturemins[1];
         
         if (ds > surf->extents[0] || dt > surf->extents[1])
            continue;

         //nodename = (surf->texinfo->texture->name);
      if (!Q_strncmp(surf->texinfo->texture->name,"carpet",6))
      plr_surfacetype = SURFACE_CARPET;
      else if (!Q_strncmp(surf->texinfo->texture->name,"ground",6))
      plr_surfacetype = SURFACE_GRAVEL;
      else if (!Q_strncmp(surf->texinfo->texture->name,"metal",5))
      plr_surfacetype = SURFACE_METAL;
      else if (!Q_strncmp(surf->texinfo->texture->name,"snow",4))
      plr_surfacetype = SURFACE_SNOW;
      else if (!Q_strncmp(surf->texinfo->texture->name,"wood",4))
      plr_surfacetype = SURFACE_WOODEN;
      else if (!Q_strncmp(surf->texinfo->texture->name,"wet",3))
      plr_surfacetype = SURFACE_DIRT;      
      else
      plr_surfacetype = SURFACE_NORMAL;         
         return true;
      }   
      return RecursiveNodePoint (node->children[front >= 0], mid, end);
   }
}

void GetNodePoint (vec3_t p, vec3_t   end)
{
   RecursiveNodePoint (cl.worldmodel->nodes, p, end);
   Con_DPrintf(nodename);
   Con_DPrintf("\n");    
}

extern sfx_t   *cl_sfx_st_carpet1;
extern sfx_t   *cl_sfx_st_carpet2;
extern sfx_t   *cl_sfx_st_dirt1;
extern sfx_t   *cl_sfx_st_dirt2;
extern sfx_t   *cl_sfx_st_gravel1;
extern sfx_t   *cl_sfx_st_gravel2;
extern sfx_t   *cl_sfx_st_metal1;
extern sfx_t   *cl_sfx_st_metal2;
extern sfx_t   *cl_sfx_st_snow1;
extern sfx_t   *cl_sfx_st_snow2;
extern sfx_t   *cl_sfx_st_stone1;
extern sfx_t   *cl_sfx_st_stone2;
extern sfx_t   *cl_sfx_st_wood1;
extern sfx_t   *cl_sfx_st_wood2;


/*
============
CL_Footsteps
============
*/

void CL_Footsteps(entity_t   *ent, int frame)
{
   if (ent->steptime > cl.time)
      return;
    
   if (TruePointContents(ent->origin) != CONTENTS_EMPTY)// if in water etc.. no sound
      return;   
//TODO: Add support for the axis soldiers too plz!
   if (frame == 2 || frame == 5 ||   frame == 9|| frame == 15 || frame == 18 || frame == 21)
   {
      vec3_t dest, forward, right,up;
     vec3_t end, downdir = {0, 0, -1};
      trace_t   trace;
      float f;
      int   i,e;
      entity_t *p;

      AngleVectors (ent->angles, forward, right, up);

      VectorMA (ent->origin, -42, up, dest);//trace down (Halfllife Player Hulls)
     //VectorMA (ent->origin, -32, up, dest);//trace down (Quake Player Hulls)    
      memset (&trace, 0, sizeof(trace_t));

      trace.fraction = 1;

      SV_RecursiveHullCheck(cl.worldmodel->hulls, 0, 0, 1, ent->origin, dest, &trace);
     VectorMA(ent->origin, 128, downdir, end); //change the 128 for different distances
     GetNodePoint(ent->origin, end);

      if (trace.fraction == 1) //if we didnt hit anything solid  dont make a sound
      {         
        ent->steptime = cl.time + 0.1;//since the player model animates at 10 frames per sec, no need to come back here until time + 1/10...
      //Con_Printf ("trace.fraction == 1\n");   
      return;
      }
     
    e = (int)cl.viewentity;//emit the sound at our location
 
      f = (rand()%4)+1;

      if (plr_surfacetype == SURFACE_NORMAL)
      {
          if (f == 1)
         S_StartSound(0, 0, cl_sfx_st_stone1, ent->origin, 0.60f, 1.0f);
         else
         S_StartSound(0, 0, cl_sfx_st_stone2, ent->origin, 0.60f, 1.0f);
      }
      if (plr_surfacetype == SURFACE_CARPET)
      {   
       if (f == 1)      
         S_StartSound(0, 0, cl_sfx_st_carpet1, ent->origin, 0.60f, 1.0f);
       else
         S_StartSound(0, 0, cl_sfx_st_carpet2, ent->origin, 0.60f, 1.0f);
      }      
      if (plr_surfacetype == SURFACE_GRAVEL)
      {   
       if (f == 1)      
         S_StartSound(0, 0, cl_sfx_st_gravel1, ent->origin, 0.60f, 1.0f);
       else
       S_StartSound(0, 0, cl_sfx_st_gravel2, ent->origin, 0.60f, 1.0f);
      }         
      if (plr_surfacetype == SURFACE_METAL)
      {   
       if (f == 1)      
         S_StartSound(0, 0, cl_sfx_st_metal1, ent->origin, 0.60f, 1.0f);
       else
       S_StartSound(0, 0, cl_sfx_st_metal2, ent->origin, 0.60f, 1.0f);
      }
      if (plr_surfacetype == SURFACE_SNOW)
      {   
       if (f == 1)      
         S_StartSound(0, 0, cl_sfx_st_snow1, ent->origin, 0.60f, 1.0f);
       else
       S_StartSound(0, 0, cl_sfx_st_snow2, ent->origin, 0.60f, 1.0f);
      }
      if (plr_surfacetype == SURFACE_DIRT)
      {   
       if (f == 1)      
         S_StartSound(0, 0, cl_sfx_st_dirt1, ent->origin, 0.60f, 1.0f);
       else
       S_StartSound(0, 0, cl_sfx_st_dirt2, ent->origin, 0.60f, 1.0f);
      }      
      if (plr_surfacetype == SURFACE_WOODEN)
      {   
       if (f == 1)      
         S_StartSound(0, 0, cl_sfx_st_wood1, ent->origin, 0.60f, 1.0f);
       else
       S_StartSound(0, 0, cl_sfx_st_wood2, ent->origin, 0.60f, 1.0f);
      }
    ent->steptime = cl.time + 0.3;
   }
}

User avatar
drm_wayne
 
Posts: 232
Joined: Sat Feb 11, 2012 5:47 pm

Previous

Return to Programming Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest