Haha, you forgot what were the engine functions don't you
DispatchSound is a function I wrote myself
I call this for every sound emitted in the game, to dispatch the sound with the right attenuation in one slot of the bot's ears, for the specified duration of the sound (yep, because in my bot, the sounds LAST in the bot's ears
)
Code:
void DispatchSound (const char *sample, Vector v_origin, float volume, float attenuation)
{
// this function brings the sound to the ears of the bots. Every time a sound is emitted in
// the game somehow, this function has to be called. It cycles through all the bots that are
// playing, and does the appropriate checks in order to determine if this bot will hear that
// sound or not. In case it can, the function places the sound into the bot's ears structure.
int bot_index;
sound_t *sound;
float attenuated_volume;
if (sample == NULL)
return; // reliability check
sound = FindSoundByFilename (sample); // find the sound we want in the global sound database
if (sound->duration == 0)
return; // cancel if sound was not found
// if debug mode is enabled, tell the user we are dispatching a sound around here
if ((DebugLevel.ears > 2) || ((DebugLevel.ears > 1) && IsValidPlayer (pListenserverEntity) && ((v_origin - pListenserverEntity->v.origin).Length () <= 1500)))
printf ("DispatchSound() \"%s\" from (%.1f, %.1f, %.1f): vol %.1f, att %.1f\n", sound->file_path, v_origin.x, v_origin.y, v_origin.z, volume, attenuation);
// cycle through all bot slots
for (bot_index = 0; bot_index < RACC_MAX_CLIENTS; bot_index++)
{
// is this slot used ?
if (bots[bot_index].is_active && IsValidPlayer (bots[bot_index].pEdict))
{
// is this sound NOT attenuated by distance ?
if (attenuation == ATTN_NONE)
BotFeedEar (&bots[bot_index], sound, v_origin, volume); // if so, bot will hear it anyway
// else is that bot within the maximum hearing range of the PAS ?
// FIXME: ATM, I can't tell the difference between all the different attenuations !
else if ((v_origin - bots[bot_index].pEdict->v.origin).Length () < MAX_HEARING_DISTANCE)
{
attenuated_volume = volume * ((MAX_HEARING_DISTANCE - (v_origin - bots[bot_index].pEdict->v.origin).Length ()) / MAX_HEARING_DISTANCE);
BotFeedEar (&bots[bot_index], sound, v_origin, attenuated_volume); // bot hears attenuated sound
}
}
}
return; // done, sound dispatched to all bots in range
}
the BotFeedEar() thingy
Code:
void BotFeedEar (bot_t *pBot, sound_t *sound, Vector v_origin, float volume)
{
// this function is in charge of finding, or freeing if necessary, a slot in the bot's ears
// to put the sound pointed to by sound in. If no free slot is available, the sound that is
// the most about to finish gets overwritten.
static bot_ears_t *pBotEar;
float nearest_fade_date;
char i, selected_index;
if (sound == NULL)
return; // reliability check
pBotEar = &pBot->BotEars; // quick access to ear
// find a free slot in bot's ears
for (selected_index = 0; selected_index < BOT_EAR_SENSITIVITY; selected_index++)
if (pBotEar->noises[selected_index].fade_date < *server.time)
break; // break when a free slot is found
// have we found NO free slot ?
if (selected_index == BOT_EAR_SENSITIVITY)
{
// no free slot found, so overwrite one, preferably the one most close to fade
// FIXME: wrong rule - given several sounds, WHICH ONE are we likely to ignore the most ?
nearest_fade_date = *server.time + 60.0;
selected_index = 0;
for (i = 0; i < BOT_EAR_SENSITIVITY; i++)
if (pBotEar->noises[i].fade_date < nearest_fade_date)
{
nearest_fade_date = pBotEar->noises[i].fade_date;
selected_index = i; // select the sound which is the most "finished"
}
}
// store the sound in that slot of the bot's ear
pBotEar->noises[selected_index].file_path = sound->file_path; // link pointer to sound file path
pBotEar->noises[selected_index].direction = BotEstimateDirection (pBot, v_origin); // remember origin
pBotEar->noises[selected_index].fade_date = *server.time + sound->duration; // duration
pBotEar->noises[selected_index].loudness = sound->loudness * volume; // loudness
pBotEar->new_sound = TRUE; // notify the bot that it is hearing a new noise
pBotEar->new_sound_index = selected_index; // mark new sound index for bot to check it
// if debug mode is high, tell the developer that a new sound is coming to this bot
if ((DebugLevel.ears > 1) && IsValidPlayer (pListenserverEntity) && ((pBot->pEdict->v.origin - pListenserverEntity->v.origin).Length () <= 100))
ServerConsole_printf ("NEW SOUND TO BOT %s's EAR: %s - LOUD %.1f - FAD %.1f\n",
players[ENTINDEX (pBot->pEdict) - 1].connection_name,
pBotEar->noises[selected_index].file_path,
pBotEar->noises[selected_index].loudness,
pBotEar->noises[selected_index].fade_date);
return;
}