143 lines
5.8 KiB
Plaintext
143 lines
5.8 KiB
Plaintext
// Unified creature/enemy audio system
|
|
// Ensures consistent panning and distance behavior for all animated entities
|
|
//
|
|
// *** IMPORTANT: See src/creature_template.nvgt for complete step-by-step guide ***
|
|
// The template file has code examples, a checklist, and enforces consistency.
|
|
//
|
|
// QUICK USAGE GUIDE:
|
|
// This system provides standardized audio functions for all creatures (zombies, bandits, animals).
|
|
// Using these functions ensures all creatures sound consistent to the player.
|
|
//
|
|
// When adding new creatures (goblins, sheep, cattle, horses, etc):
|
|
// 1. Define creature-specific constants in constants.nvgt:
|
|
// const float SHEEP_SOUND_VOLUME_STEP = 3.0;
|
|
// const int SHEEP_FOOTSTEP_MAX_DISTANCE = 5;
|
|
//
|
|
// 2. Use these functions in your creature update code:
|
|
// - play_creature_voice() for periodic sounds (bleats, moos, neighs) - returns handle, store it!
|
|
// - play_creature_footstep() when creature moves
|
|
// - play_creature_attack_sound() when creature attacks player/barricade
|
|
// - play_creature_death_sounds() when creature dies (adds optional *_dies.ogg)
|
|
// - play_creature_hit_sound() when player damages creature
|
|
//
|
|
// 3. IMPORTANT: When creature dies, stop its sound before playing death sound:
|
|
// if (creature.sound_handle != -1) {
|
|
// p.destroy_sound(creature.sound_handle);
|
|
// creature.sound_handle = -1;
|
|
// }
|
|
// play_creature_death_sounds("sounds/enemies/enemy_falls.ogg", creature.voice_sound, x, pos, volume_step);
|
|
//
|
|
// 4. All sounds automatically use consistent panning/volume falloff
|
|
//
|
|
// Example for sheep:
|
|
// sheep.sound_handle = play_creature_voice("sounds/animals/sheep_bleat.ogg", x, sheep.position, SHEEP_SOUND_VOLUME_STEP);
|
|
// play_creature_footstep(x, sheep.position, BASE_END, GRASS_END, SHEEP_FOOTSTEP_MAX_DISTANCE, SHEEP_SOUND_VOLUME_STEP);
|
|
//
|
|
// Death handling example:
|
|
// if (sheep.sound_handle != -1) {
|
|
// p.destroy_sound(sheep.sound_handle);
|
|
// sheep.sound_handle = -1;
|
|
// }
|
|
// play_creature_death_sound("sounds/animals/sheep_death.ogg", x, sheep.position, SHEEP_SOUND_VOLUME_STEP);
|
|
|
|
// Default audio parameters for creatures
|
|
const float CREATURE_DEFAULT_VOLUME_STEP = 3.0;
|
|
const int CREATURE_DEFAULT_FOOTSTEP_DISTANCE = 6;
|
|
|
|
// Plays a creature's voice/alert sound with consistent positioning
|
|
// Returns the sound handle for tracking
|
|
int play_creature_voice(string sound_file, int listener_x, int creature_x,
|
|
float volume_step = CREATURE_DEFAULT_VOLUME_STEP) {
|
|
return play_1d_with_volume_step(sound_file, listener_x, creature_x, false, volume_step);
|
|
}
|
|
|
|
// Plays a creature's footstep sound with consistent positioning
|
|
// Only plays if within max_distance to avoid cluttering the soundscape
|
|
void play_creature_footstep(int listener_x, int creature_x, int base_end, int grass_end,
|
|
int max_distance = CREATURE_DEFAULT_FOOTSTEP_DISTANCE,
|
|
float volume_step = CREATURE_DEFAULT_VOLUME_STEP) {
|
|
int distance = creature_x - listener_x;
|
|
if (distance < 0) {
|
|
distance = -distance;
|
|
}
|
|
|
|
if (distance > max_distance) {
|
|
return;
|
|
}
|
|
|
|
play_positional_footstep(listener_x, creature_x, base_end, grass_end, max_distance, volume_step);
|
|
}
|
|
|
|
// Plays a creature attack sound (hitting player, hitting barricade, etc.)
|
|
void play_creature_attack_sound(string sound_file, int listener_x, int creature_x,
|
|
float volume_step = CREATURE_DEFAULT_VOLUME_STEP) {
|
|
play_1d_with_volume_step(sound_file, listener_x, creature_x, false, volume_step);
|
|
}
|
|
|
|
// Plays a creature death/fall sound
|
|
void play_creature_death_sound(string sound_file, int listener_x, int creature_x,
|
|
float volume_step = CREATURE_DEFAULT_VOLUME_STEP) {
|
|
play_1d_with_volume_step(sound_file, listener_x, creature_x, false, volume_step);
|
|
}
|
|
|
|
string get_creature_death_sound_from_alert(string alert_sound) {
|
|
if (alert_sound == "") {
|
|
return "";
|
|
}
|
|
|
|
string[] parts = alert_sound.split("/");
|
|
string filename = alert_sound;
|
|
if (parts.length() > 0) {
|
|
filename = parts[parts.length() - 1];
|
|
}
|
|
|
|
int dot_index = filename.find(".");
|
|
if (dot_index > 0) {
|
|
filename = filename.substr(0, dot_index);
|
|
}
|
|
|
|
if (filename == "bandit3" || filename == "bandit4") {
|
|
string female_death = "sounds/enemies/bandit_female_dies.ogg";
|
|
if (audio_asset_exists(female_death)) {
|
|
return female_death;
|
|
}
|
|
}
|
|
|
|
// Strip trailing digits (bandit1 -> bandit, goblin2 -> goblin)
|
|
while (filename.length() > 0) {
|
|
string last_char = filename.substr(filename.length() - 1, 1);
|
|
if (last_char >= "0" && last_char <= "9") {
|
|
filename = filename.substr(0, filename.length() - 1);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (filename == "") {
|
|
return "";
|
|
}
|
|
|
|
string death_sound = "sounds/enemies/" + filename + "_dies.ogg";
|
|
if (!audio_asset_exists(death_sound)) {
|
|
return "";
|
|
}
|
|
|
|
return death_sound;
|
|
}
|
|
|
|
void play_creature_death_sounds(string default_sound, string alert_sound, int listener_x, int creature_x,
|
|
float volume_step = CREATURE_DEFAULT_VOLUME_STEP) {
|
|
play_creature_death_sound(default_sound, listener_x, creature_x, volume_step);
|
|
|
|
string death_sound = get_creature_death_sound_from_alert(alert_sound);
|
|
if (death_sound != "" && death_sound != default_sound) {
|
|
play_creature_death_sound(death_sound, listener_x, creature_x, volume_step);
|
|
}
|
|
}
|
|
|
|
// Plays a creature hit/damage sound (when player damages the creature)
|
|
void play_creature_hit_sound(string sound_file, int listener_x, int creature_x,
|
|
float volume_step = CREATURE_DEFAULT_VOLUME_STEP) {
|
|
play_1d_with_volume_step(sound_file, listener_x, creature_x, false, volume_step);
|
|
}
|