2024-09-02 01:12:38 +00:00
|
|
|
/*
|
|
|
|
server/utilities/sound_helper.qc
|
|
|
|
|
|
|
|
Logic designed to assist in audio balancing and different types
|
|
|
|
of audio channels.
|
|
|
|
|
|
|
|
Copyright (C) 2021-2024 NZ:P Team
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SOUND_PRIORITY_ALLOWSKIP 0
|
|
|
|
#define SOUND_PRIORITY_PLAYALWAYS 1
|
|
|
|
|
|
|
|
#define SOUND_TYPE_ZOMBIE_QUIET 0
|
|
|
|
#define SOUND_TYPE_ZOMBIE_LOUD 1
|
|
|
|
#define SOUND_TYPE_ZOMBIE_CRAWLER 2
|
|
|
|
#define SOUND_TYPE_MUSIC_ROUND 3
|
|
|
|
#define SOUND_TYPE_WEAPON_FIRE 4
|
|
|
|
#define SOUND_TYPE_WEAPON_OTHER 5
|
|
|
|
#define SOUND_TYPE_WEAPON_PACK 6
|
|
|
|
#define SOUND_TYPE_WEAPON_EXPLODE 7
|
|
|
|
#define SOUND_TYPE_PLAYER_VOICE 8
|
|
|
|
#define SOUND_TYPE_PLAYER_FOOTSTEP 9
|
|
|
|
#define SOUND_TYPE_ENV_OBJECT 10
|
|
|
|
#define SOUND_TYPE_ENV_CHING 11
|
|
|
|
#define SOUND_TYPE_ENV_VOICE 12
|
|
|
|
#define SOUND_TYPE_ENV_MUSIC 13
|
|
|
|
#define SOUND_TYPE_ENV_IMPORTANT 14
|
|
|
|
|
|
|
|
#define SOUND_MAX_ZOMBIE_GROANS 4
|
|
|
|
#define SOUND_MAX_WEAPON_EXPLODE 8
|
|
|
|
#define SOUND_MAX_ENV_VOICE 1
|
|
|
|
|
|
|
|
// On FTE, we should always be using SOUNDFLAG_FOLLOW because we want
|
|
|
|
// sounds like the longer zombie groans to not feel desynconized from
|
|
|
|
// the actual action, other engines don't support this though, so wrap
|
|
|
|
// it.
|
|
|
|
#ifdef FTE
|
|
|
|
|
|
|
|
#define PLAYSOUND(ent, channel, path, volume, attenuation) sound(ent, channel, path, volume, attenuation, 0, SOUNDFLAG_FOLLOW)
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#define PLAYSOUND(ent, channel, path, volume, attenuation) sound(ent, channel, path, volume, attenuation)
|
|
|
|
|
|
|
|
#endif // FTE
|
|
|
|
|
|
|
|
float zombie_groan_times[SOUND_MAX_ZOMBIE_GROANS];
|
|
|
|
float weapon_explode_times[SOUND_MAX_WEAPON_EXPLODE];
|
|
|
|
float environment_voice_times[SOUND_MAX_ENV_VOICE];
|
|
|
|
|
|
|
|
float() Sound_GetEnvironmentVoice =
|
|
|
|
{
|
|
|
|
// Search for an available Explosion slot.
|
|
|
|
for(float i = 0; i < SOUND_MAX_ENV_VOICE; i++) {
|
|
|
|
if (environment_voice_times[i] < time) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// None available.
|
|
|
|
return -1;
|
|
|
|
};
|
|
|
|
|
|
|
|
void(float priority, float index) Sound_SetEnvironmentVoice =
|
|
|
|
{
|
|
|
|
if (priority == SOUND_PRIORITY_PLAYALWAYS)
|
|
|
|
return;
|
|
|
|
|
|
|
|
environment_voice_times[index] = time + 2;
|
|
|
|
};
|
|
|
|
|
|
|
|
float() Sound_GetWeaponExplosion =
|
|
|
|
{
|
|
|
|
// Search for an available Explosion slot.
|
|
|
|
for(float i = 0; i < SOUND_MAX_WEAPON_EXPLODE; i++) {
|
|
|
|
if (weapon_explode_times[i] < time) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// None available.
|
|
|
|
return -1;
|
|
|
|
};
|
|
|
|
|
|
|
|
void(float priority, float index) Sound_SetWeaponExplosion =
|
|
|
|
{
|
|
|
|
if (priority == SOUND_PRIORITY_PLAYALWAYS)
|
|
|
|
return;
|
|
|
|
|
|
|
|
weapon_explode_times[index] = time + 1.2;
|
|
|
|
};
|
|
|
|
|
|
|
|
float() Sound_GetZombieGroan =
|
|
|
|
{
|
|
|
|
// Search for an available Groan slot.
|
|
|
|
for(float i = 0; i < SOUND_MAX_ZOMBIE_GROANS; i++) {
|
|
|
|
if (zombie_groan_times[i] < time) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// None available.
|
|
|
|
return -1;
|
|
|
|
};
|
|
|
|
|
|
|
|
void(float priority, float index) Sound_SetZombieGroan =
|
|
|
|
{
|
|
|
|
if (priority == SOUND_PRIORITY_PLAYALWAYS)
|
|
|
|
return;
|
|
|
|
|
|
|
|
zombie_groan_times[index] = time + 4.5;
|
|
|
|
};
|
|
|
|
|
|
|
|
void(entity source_ent, string path, float type, float priority) Sound_PlaySound =
|
|
|
|
{
|
|
|
|
switch(type) {
|
|
|
|
case SOUND_TYPE_ZOMBIE_QUIET:
|
|
|
|
float zombie_quiet_groan = Sound_GetZombieGroan();
|
|
|
|
if (priority == SOUND_PRIORITY_PLAYALWAYS || zombie_quiet_groan != -1) {
|
2024-09-07 23:56:02 +00:00
|
|
|
PLAYSOUND(source_ent, CHAN_VOICE, path, 0.50, 2);
|
2024-09-02 01:12:38 +00:00
|
|
|
Sound_SetZombieGroan(priority, zombie_quiet_groan);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_ZOMBIE_LOUD:
|
|
|
|
float zombie_loud_groan = Sound_GetZombieGroan();
|
|
|
|
if (priority == SOUND_PRIORITY_PLAYALWAYS || zombie_loud_groan != -1) {
|
|
|
|
PLAYSOUND(source_ent, CHAN_WEAPON, path, 0.70, 1);
|
|
|
|
Sound_SetZombieGroan(priority, zombie_loud_groan);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_ZOMBIE_CRAWLER:
|
|
|
|
float zombie_crawler_groan = Sound_GetZombieGroan();
|
|
|
|
if (priority == SOUND_PRIORITY_PLAYALWAYS || zombie_crawler_groan != -1) {
|
|
|
|
PLAYSOUND(source_ent, CHAN_ITEM, path, 0.60, 1);
|
|
|
|
Sound_SetZombieGroan(priority, zombie_crawler_groan);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_MUSIC_ROUND:
|
|
|
|
PLAYSOUND(source_ent, CHAN_ITEM, path, 0.85, 0);
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_WEAPON_FIRE:
|
|
|
|
PLAYSOUND(source_ent, CHAN_AUTO, path, 0.80, 2);
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_WEAPON_OTHER:
|
|
|
|
PLAYSOUND(source_ent, CHAN_ITEM, path, 0.60, 2);
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_WEAPON_PACK:
|
|
|
|
PLAYSOUND(source_ent, CHAN_ITEM, path, 0.95, 2);
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_WEAPON_EXPLODE:
|
|
|
|
float weapon_explosion_index = Sound_GetWeaponExplosion();
|
|
|
|
if (priority == SOUND_PRIORITY_PLAYALWAYS || weapon_explosion_index != -1) {
|
|
|
|
PLAYSOUND(source_ent, 0, path, 0.70, 1);
|
|
|
|
Sound_SetWeaponExplosion(priority, weapon_explosion_index);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_PLAYER_VOICE:
|
|
|
|
PLAYSOUND(source_ent, CHAN_VOICE, path, 0.90, 2);
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_PLAYER_FOOTSTEP:
|
|
|
|
PLAYSOUND(source_ent, 0, path, 0.40, 3);
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_ENV_OBJECT:
|
|
|
|
PLAYSOUND(source_ent, CHAN_ITEM, path, 0.50, 2);
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_ENV_CHING:
|
|
|
|
PLAYSOUND(source_ent, CHAN_AUTO, path, 0.75, 3);
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_ENV_VOICE:
|
|
|
|
float environment_voice_index = Sound_GetEnvironmentVoice();
|
|
|
|
if (priority == SOUND_PRIORITY_PLAYALWAYS || environment_voice_index != -1) {
|
|
|
|
PLAYSOUND(source_ent, CHAN_VOICE, path, 0.80, 0);
|
|
|
|
Sound_SetEnvironmentVoice(priority, environment_voice_index);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_ENV_MUSIC:
|
|
|
|
PLAYSOUND(source_ent, CHAN_WEAPON, path, 0.75, 3);
|
|
|
|
break;
|
|
|
|
case SOUND_TYPE_ENV_IMPORTANT:
|
|
|
|
PLAYSOUND(source_ent, CHAN_ITEM, path, 1, 2);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|