Forum

Help me out - bot sound bug

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Help me out - bot sound bug

Postby Orion » Thu May 10, 2007 5:57 pm

Hi.

When I play with my bots and when they die underwater, they don't play the water death sound, plays the normal death sounds instead, unless if they're killed by slime, lava, or water damage, not even pain sounds are played underwater, just the outwater pain sounds.
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby Urre » Fri May 11, 2007 9:20 am

Could we see some code perhaps? Does your bot loop through the clients subroutines for such things, or does it have its own routines? If i remember correctly it was the latter.
I was once a Quake modder
User avatar
Urre
 
Posts: 1109
Joined: Fri Nov 05, 2004 2:36 am
Location: Moon

Postby Orion » Fri May 11, 2007 2:34 pm

Here's its thinking code...

Code: Select all
void() BotThink =
{
   local float r, oyaw;
   
   self.nextthink = time;
   self.think = BotThink;
   
   self.waterlevel = SetWaterlevel ();
   
   if (self.nextframe_time <= time)
   {
      if ((self.frame == $light1 || self.frame == $light2) && (self.weapon != IT_LIGHTNING || time - self.attack_finished >= 0.1))
         self.nextframe = bot_run;
      if ((self.frame == $nailatt1 || self.frame == $nailatt2)
      && ((self.weapon != IT_NAILGUN && self.weapon != IT_SUPER_NAILGUN) || time - self.attack_finished >= 0.1))
         self.nextframe = bot_run;
      
      self.nextframe_time = time + 0.1;
      self.nextframe ();
   }
   
   CheckRules ();
   WaterMove ();
   
   if (self.waterlevel == 2)
      CheckWaterJump ();
   
// gibber charges can force a non-moving pause time   
   if (time < self.pausetime)
   {
      self.velocity = '0 0 0';
      self.frame = $axattc2;
      self.weaponframe = 2;
   }
   
   if (self.deadflag)
      return;
   
   if ((self.jump_flag < -300) && (self.flags & FL_ONGROUND) )
   {
      if (pointcontents(self.origin) == CONTENT_WATER)
         sound (self, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM);
      else if (self.jump_flag < -650)
      {
         r = 5;
         r = (r * (self.jump_flag / 300)) * -1;
         deathmsg = 12;
         T_Damage (self, world, world, r);
         sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
      }
      else
         sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
   }

   self.jump_flag = self.velocity_z;

   if (random() < frametime*2)
      BotJump (0);
   
   CheckPowerups ();
   
   if (self.enemy == world)
   {
      GetEnemy ();
      GetItems ();
      
      if (OnPlat(self))
         return;
      
      if ( (self.lip < time && self.goalentity != world) || self.goalentity.model == string_null
      || (self.goalentity.touch == weapon_touch && self.items & self.goalentity.weapon) )
         self.goalentity = world;
      
      if (self.goalentity != world)
      {
         if (Should_RJ())
            return;
         
         BotMoveToGoal ();
      }
      else
         BotWalkMove ();
   }
   
   if (self.enemy != world)
   {
      if (self.enemy.health <= 0 || self.enemy.deadflag != DEAD_NO)
      {
         self.enemy = world;
         self.goalentity = world;
         return;
      }
      
      if (self.search_time < time && !Accessable(self, self.enemy))
      {
         self.enemy = world;
         self.goalentity = world;
         return;
      }
      
      if (self.weapon == IT_AXE)
         BotMoveToGoal ();
      else
         BotFightMove ();
      
      if (time < self.reaction_time)
         return;
      
      if (Accessable(self, self.enemy))
      {
         SuperDamageSound ();
         BotAttack ();
      }
      else
         self.ideal_pitch = 0;
      
      if (self.angles_x != self.ideal_pitch)
      {
         oyaw = self.yaw_speed;
         self.yaw_speed = (frametime / 0.1) * (self.yaw_speed / 10);
         ChangePitch ();
         self.yaw_speed = oyaw;
      }
   }
};



And the waterlevel check

Code: Select all
float() SetWaterlevel =
{
   local float type;
   
   type = pointcontents(self.origin + self.view_ofs);
   if (type <= CONTENT_WATER)
   {
      self.watertype = type;
      return 3;
   }
   
   type = pointcontents(self.absmin + '0 0 29');
   if (type <= CONTENT_WATER)
   {
      self.watertype = type;
      return 2;
   }
   
   type = pointcontents(self.absmin + '0 0 2');
   if (type <= CONTENT_WATER)
   {
      self.watertype = type;
      return 1;
   }
   
   self.watertype = 0;
   return 0;
};


He checks his waterlevel every frame... and when he die, he calls DeathSound(). What's wrong here?
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby dayfive » Tue May 15, 2007 9:00 pm

Orion wrote:He checks his waterlevel every frame... and when he die, he calls DeathSound(). What's wrong here?


It looks like it would be calling DeathSound() from Player.qc, which in that function we see

Code: Select all
   // water death sounds
   if (self.waterlevel == 3)
   {
      DeathBubbles(20);
      sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE);
      return;
   }



If it was me, I might try changing that check to something like
Code: Select all
   if (self.waterlevel <= 1)

and see if that doesn't sort the issue. Not sure though...
User avatar
dayfive
 
Posts: 77
Joined: Fri Nov 10, 2006 9:48 pm

Postby Electro » Wed May 16, 2007 7:52 am

for starters you can remove every:

self.watertype = type;

line in the SetWaterlevel function as you're already returning out of it to set the .watertype variable on the bot anyway.

Oh and remove the self.watertype = 0;
same reason :)

Try printing the types too...
eg.
type = pointcontents(self.absmin + '0 0 29');
bprint("waterlevel = ");
bprint(ftos(type));
bprint("\n");

i'm in a hurry... but i have a feeling that it's not being set right in the first place.

good luck!
Benjamin Darling
http://www.bendarling.net/

Reflex - In development competitive arena fps combining modern tech with the speed, precision and freedom of 90's shooters.
http://www.reflexfps.net/
Electro
 
Posts: 312
Joined: Wed Dec 29, 2004 11:25 pm
Location: Brisbane, Australia

Postby Orion » Wed May 16, 2007 3:39 pm

I've tried, but nothing solved the problem! :(
The things that I've done is checking pointcontents instead of waterlevel in PainSound and DeathSound functions, and only if it is not human, I've created a .human float, because the bot's classname is "player" too, this float handles prints, centerprints, stuffcmd, etc...
So, I've put an (if (!self.human)) before the pointcontents check. It looks somethink like this:

Code: Select all
// water death sounds
if (!self.human)
{
   if (pointcontents(self.origin + self.view_ofs) <= CONTENT_WATER)
   {
      DeathBubbles(20);
      sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE);
      return;
   }
}
else
{
   if (self.waterlevel == 3)
   {
      DeathBubbles(20);
      sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE);
      return;
   }
}



But client emulation would be an excellent idea! :)
FBX does that, but I don't like its roaming AI, in maps without wayponts, they camp so much, and I should search for them everytime.
And if I do client emulation, should I rewrite every AI code?
Thanks!
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby FrikaC » Wed May 16, 2007 5:44 pm

FBX's roaming AI is basically turned off, I mentioned in another post on how to re-enable it, which I probably should do in the official release, but ah well.
FrikaC
Site Admin
 
Posts: 1026
Joined: Fri Oct 08, 2004 11:19 pm

Postby Orion » Wed May 16, 2007 9:17 pm

So tell me how here or send a p.m, is it a console command or qc edit?
thx!
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby FrikaC » Wed May 16, 2007 10:28 pm

It's a QC edit.

In bot_way.qc, in the function DynamicWaypoint, there's a comment that reads:
// for speed sake, I won't have bots dynamic waypoint in coop

Immediately after that there's a line that says "if (coop)", if that line is removed or commented out, roaming should work once more. (*crosses fingers*).

Basically because the bots are allowed to dynpoint, they make a tiny waypoint map with their start location as the only point in the map, any attempts to route out from that point fail. By removing the coop line, they'll instead find no points at their start and roam. One would hope.
FrikaC
Site Admin
 
Posts: 1026
Joined: Fri Oct 08, 2004 11:19 pm

Postby Orion » Thu May 17, 2007 12:22 am

Hey guys, I've fixed the bug, thanks for the help! :)
I've just put a SetWaterlevel call in BotDie and bot_pain, and it worked! :D
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest