Learn sounds menu added. May need more work.
This commit is contained in:
@@ -38,6 +38,7 @@ sound_pool p(300);
|
||||
#include "src/notify.nvgt"
|
||||
#include "src/speech_history.nvgt"
|
||||
#include "src/text_reader.nvgt"
|
||||
#include "src/learn_sounds.nvgt"
|
||||
#include "src/bosses/adventure_system.nvgt"
|
||||
|
||||
int run_main_menu() {
|
||||
@@ -45,7 +46,8 @@ int run_main_menu() {
|
||||
|
||||
int selection = 0;
|
||||
string load_label = has_save_game() ? "Load Game" : "Load Game (no saves found)";
|
||||
string[] options = {"New Game", load_label, "Exit"};
|
||||
string[] options = {"New Game", load_label, "Learn Sounds", "Exit"};
|
||||
int exit_index = options.length() - 1;
|
||||
|
||||
speak_with_history(options[selection], true);
|
||||
|
||||
@@ -72,11 +74,11 @@ int run_main_menu() {
|
||||
}
|
||||
|
||||
if (key_pressed(KEY_ESCAPE)) {
|
||||
return 2;
|
||||
return exit_index;
|
||||
}
|
||||
}
|
||||
|
||||
return 2;
|
||||
return exit_index;
|
||||
}
|
||||
|
||||
void run_game()
|
||||
@@ -119,6 +121,9 @@ void run_game()
|
||||
if (message == "") message = "Unable to load save.";
|
||||
ui_info_box("Draugnorak", "Load Game", message);
|
||||
}
|
||||
} else if (selection == 2) {
|
||||
run_learn_sounds_menu();
|
||||
continue;
|
||||
} else {
|
||||
exit();
|
||||
}
|
||||
|
||||
BIN
sounds/actions/climb_rope.ogg
LFS
BIN
sounds/actions/climb_rope.ogg
LFS
Binary file not shown.
@@ -1111,8 +1111,7 @@ void start_rope_climb(bool climbing_up, int target_x, int target_elevation) {
|
||||
string direction = rope_climb_up ? "up" : "down";
|
||||
speak_with_history("Climbing " + direction + ". " + distance + " feet.", true);
|
||||
|
||||
// Start looping rope climbing sound
|
||||
rope_climb_sound_handle = p.play_stationary("sounds/actions/climb_rope.ogg", true);
|
||||
rope_climb_sound_handle = -1;
|
||||
}
|
||||
|
||||
void update_rope_climbing() {
|
||||
@@ -1132,6 +1131,7 @@ void update_rope_climbing() {
|
||||
// Climbing up
|
||||
if (y < rope_climb_target_y) {
|
||||
y++;
|
||||
p.play_stationary("sounds/actions/climb_rope.ogg", false);
|
||||
|
||||
// Check if we've reached the target
|
||||
if (y >= rope_climb_target_y) {
|
||||
@@ -1142,6 +1142,7 @@ void update_rope_climbing() {
|
||||
// Climbing down
|
||||
if (y > rope_climb_target_y) {
|
||||
y--;
|
||||
p.play_stationary("sounds/actions/climb_rope.ogg", false);
|
||||
|
||||
// Check if we've reached the target
|
||||
if (y <= rope_climb_target_y) {
|
||||
@@ -1157,11 +1158,7 @@ void complete_rope_climb() {
|
||||
x = rope_climb_target_x;
|
||||
y = rope_climb_target_y;
|
||||
|
||||
// Stop looping rope climbing sound
|
||||
if (rope_climb_sound_handle != -1) {
|
||||
p.destroy_sound(rope_climb_sound_handle);
|
||||
rope_climb_sound_handle = -1;
|
||||
}
|
||||
rope_climb_sound_handle = -1;
|
||||
|
||||
// Play footstep for new terrain
|
||||
play_footstep(x, BASE_END, GRASS_END);
|
||||
@@ -1173,11 +1170,7 @@ void check_rope_climb_fall() {
|
||||
if (!rope_climbing) return;
|
||||
|
||||
if (key_down(KEY_LEFT) || key_down(KEY_RIGHT)) {
|
||||
// Stop rope climbing sound
|
||||
if (rope_climb_sound_handle != -1) {
|
||||
p.destroy_sound(rope_climb_sound_handle);
|
||||
rope_climb_sound_handle = -1;
|
||||
}
|
||||
rope_climb_sound_handle = -1;
|
||||
|
||||
int currentElevation = get_mountain_elevation_at(x);
|
||||
int targetElevation = get_mountain_elevation_at(rope_climb_target_x);
|
||||
|
||||
258
src/learn_sounds.nvgt
Normal file
258
src/learn_sounds.nvgt
Normal file
@@ -0,0 +1,258 @@
|
||||
// Learn sounds menu
|
||||
|
||||
// Skip entries can be full file paths or directories (ending with "/").
|
||||
string[] learnSoundSkipList = {
|
||||
"sounds/quests/bone1.ogg",
|
||||
"sounds/quests/bone2.ogg",
|
||||
"sounds/quests/bone3.ogg",
|
||||
"sounds/quests/bone4.ogg",
|
||||
"sounds/quests/bone5.ogg",
|
||||
"sounds/quests/bone6.ogg",
|
||||
"sounds/quests/bone7.ogg",
|
||||
"sounds/quests/bone8.ogg",
|
||||
"sounds/actions/fishpole.ogg",
|
||||
"sounds/actions/hit_ground.ogg",
|
||||
"sounds/nature/"
|
||||
};
|
||||
|
||||
// Description entries: keep paths/texts aligned by index.
|
||||
string[] learnSoundDescriptionPaths = {
|
||||
"sounds/actions/bad_cast.ogg",
|
||||
"sounds/actions/cast_strength.ogg",
|
||||
"sounds/enemies/enter_range.ogg",
|
||||
"sounds/enemies/exit_range.ogg",
|
||||
"sounds/actions/falling.ogg",
|
||||
"sounds/enemies/invasion.ogg",
|
||||
"sounds/items/miscellaneous.ogg"
|
||||
};
|
||||
|
||||
string[] learnSoundDescriptionTexts = {
|
||||
"Your cast missed the water and landed in nearby foliage where it is unlikely to attract fish.",
|
||||
"When casting release control when over water. When catching release when sound is over player.",
|
||||
"An enemy is in range of your currently wielded weapon.",
|
||||
"An enemy is no longer in range of your currently wielded weapon.",
|
||||
"Lowers in pitch as the fall progresses.",
|
||||
"The war drums pound! Prepare for combat!",
|
||||
"You picked up an item for which there is no specific sound."
|
||||
};
|
||||
|
||||
int learnSoundHandle = -1;
|
||||
|
||||
string normalize_path(const string&in path) {
|
||||
return path.replace("\\", "/", true);
|
||||
}
|
||||
|
||||
bool is_directory_skip_entry(const string&in entry) {
|
||||
if (entry.length() == 0) return false;
|
||||
if (entry.substr(entry.length() - 1) == "/") return true;
|
||||
return directory_exists(entry);
|
||||
}
|
||||
|
||||
bool should_skip_sound_path(const string&in path) {
|
||||
string normalizedPath = normalize_path(path);
|
||||
for (uint i = 0; i < learnSoundSkipList.length(); i++) {
|
||||
string entry = normalize_path(learnSoundSkipList[i]);
|
||||
if (entry.length() == 0) continue;
|
||||
|
||||
bool isDir = is_directory_skip_entry(entry);
|
||||
if (isDir) {
|
||||
if (entry.substr(entry.length() - 1) != "/") entry += "/";
|
||||
if (normalizedPath.length() >= entry.length() &&
|
||||
normalizedPath.substr(0, entry.length()) == entry) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (normalizedPath == entry) return true;
|
||||
|
||||
if (entry.find_first("/") < 0 && entry.find_first("\\") < 0) {
|
||||
if (normalizedPath.length() >= entry.length() + 1 &&
|
||||
normalizedPath.substr(normalizedPath.length() - entry.length()) == entry) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
string get_sound_description(const string&in path) {
|
||||
string normalizedPath = normalize_path(path);
|
||||
uint count = learnSoundDescriptionPaths.length();
|
||||
if (learnSoundDescriptionTexts.length() < count) count = learnSoundDescriptionTexts.length();
|
||||
for (uint i = 0; i < count; i++) {
|
||||
if (normalize_path(learnSoundDescriptionPaths[i]) == normalizedPath) {
|
||||
return learnSoundDescriptionTexts[i];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void gather_sound_files(const string&in basePath, string[]@ outFiles) {
|
||||
string[]@ files = find_files(basePath + "/*.ogg");
|
||||
if (@files !is null) {
|
||||
for (uint i = 0; i < files.length(); i++) {
|
||||
outFiles.insert_last(basePath + "/" + files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
string[]@ folders = find_directories(basePath + "/*");
|
||||
if (@folders !is null) {
|
||||
for (uint i = 0; i < folders.length(); i++) {
|
||||
gather_sound_files(basePath + "/" + folders[i], outFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool sort_string_case_insensitive_sounds(const string &in a, const string &in b) {
|
||||
return a.lower() < b.lower();
|
||||
}
|
||||
|
||||
string collapse_spaces(const string&in text) {
|
||||
string result = text;
|
||||
while (result.find_first(" ") > -1) {
|
||||
result = result.replace(" ", " ", true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
string format_doc_label(const string&in filename) {
|
||||
string name = filename;
|
||||
string lowerName = name.lower();
|
||||
if (lowerName.length() > 3 && lowerName.substr(lowerName.length() - 3) == ".md") {
|
||||
name = name.substr(0, name.length() - 3);
|
||||
}
|
||||
name = name.replace("_", " ", true);
|
||||
name = name.replace("-", " ", true);
|
||||
name = collapse_spaces(name);
|
||||
name = name.lower();
|
||||
name.trim_whitespace_this();
|
||||
if (name.length() == 0) return "Document";
|
||||
string first = name.substr(0, 1).upper();
|
||||
if (name.length() == 1) return first;
|
||||
return first + name.substr(1);
|
||||
}
|
||||
|
||||
string get_sound_label_from_path(const string&in soundPath) {
|
||||
string normalizedPath = normalize_path(soundPath);
|
||||
int slashPos = normalizedPath.find_last_of("/");
|
||||
string name = (slashPos >= 0) ? normalizedPath.substr(slashPos + 1) : normalizedPath;
|
||||
string lowerName = name.lower();
|
||||
if (lowerName.length() > 4 && lowerName.substr(lowerName.length() - 4) == ".ogg") {
|
||||
name = name.substr(0, name.length() - 4);
|
||||
}
|
||||
name = name.replace("_", " ", true);
|
||||
name = name.replace("-", " ", true);
|
||||
name = collapse_spaces(name);
|
||||
name = name.lower();
|
||||
name.trim_whitespace_this();
|
||||
if (name.length() == 0) return "Sound";
|
||||
return name;
|
||||
}
|
||||
|
||||
void add_doc_entries(string[]@ labels, string[]@ paths, int[]@ types) {
|
||||
if (!directory_exists("files")) return;
|
||||
|
||||
string[] docFiles;
|
||||
string[]@ mdFiles = find_files("files/*.md");
|
||||
if (@mdFiles !is null) {
|
||||
for (uint i = 0; i < mdFiles.length(); i++) {
|
||||
docFiles.insert_last(mdFiles[i]);
|
||||
}
|
||||
}
|
||||
string[]@ mdCapsFiles = find_files("files/*.MD");
|
||||
if (@mdCapsFiles !is null) {
|
||||
for (uint i = 0; i < mdCapsFiles.length(); i++) {
|
||||
docFiles.insert_last(mdCapsFiles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (docFiles.length() > 1) {
|
||||
docFiles.sort(sort_string_case_insensitive_sounds);
|
||||
}
|
||||
|
||||
for (uint i = 0; i < docFiles.length(); i++) {
|
||||
string label = format_doc_label(docFiles[i]);
|
||||
labels.insert_last(label);
|
||||
paths.insert_last("files/" + docFiles[i]);
|
||||
types.insert_last(1);
|
||||
}
|
||||
}
|
||||
|
||||
void add_sound_entries(string[]@ labels, string[]@ paths, int[]@ types) {
|
||||
string[] soundFiles;
|
||||
gather_sound_files("sounds", soundFiles);
|
||||
if (soundFiles.length() > 1) {
|
||||
soundFiles.sort(sort_string_case_insensitive_sounds);
|
||||
}
|
||||
|
||||
for (uint i = 0; i < soundFiles.length(); i++) {
|
||||
string soundPath = normalize_path(soundFiles[i]);
|
||||
if (should_skip_sound_path(soundPath)) continue;
|
||||
|
||||
string label = get_sound_label_from_path(soundPath);
|
||||
string description = get_sound_description(soundPath);
|
||||
if (description.length() > 0) {
|
||||
label += " - " + description;
|
||||
}
|
||||
labels.insert_last(label);
|
||||
paths.insert_last(soundPath);
|
||||
types.insert_last(0);
|
||||
}
|
||||
}
|
||||
|
||||
void run_learn_sounds_menu() {
|
||||
speak_with_history("Learn sounds.", true);
|
||||
|
||||
string[] labels;
|
||||
string[] entryPaths;
|
||||
int[] entryTypes; // 0 = sound, 1 = document
|
||||
|
||||
add_doc_entries(labels, entryPaths, entryTypes);
|
||||
add_sound_entries(labels, entryPaths, entryTypes);
|
||||
|
||||
if (labels.length() == 0) {
|
||||
speak_with_history("No sounds available.", true);
|
||||
return;
|
||||
}
|
||||
|
||||
int selection = 0;
|
||||
speak_with_history(labels[selection], true);
|
||||
|
||||
while (true) {
|
||||
wait(5);
|
||||
|
||||
if (key_pressed(KEY_ESCAPE)) {
|
||||
speak_with_history("Closed.", true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (key_pressed(KEY_DOWN)) {
|
||||
play_menu_move_sound();
|
||||
selection++;
|
||||
if (selection >= int(labels.length())) selection = 0;
|
||||
speak_with_history(labels[selection], true);
|
||||
}
|
||||
|
||||
if (key_pressed(KEY_UP)) {
|
||||
play_menu_move_sound();
|
||||
selection--;
|
||||
if (selection < 0) selection = int(labels.length()) - 1;
|
||||
speak_with_history(labels[selection], true);
|
||||
}
|
||||
|
||||
if (key_pressed(KEY_RETURN)) {
|
||||
if (entryTypes[selection] == 1) {
|
||||
text_reader_file(entryPaths[selection], labels[selection], true);
|
||||
return;
|
||||
}
|
||||
string soundPath = entryPaths[selection];
|
||||
if (file_exists(soundPath)) {
|
||||
safe_destroy_sound(learnSoundHandle);
|
||||
learnSoundHandle = p.play_stationary(soundPath, false);
|
||||
} else {
|
||||
speak_with_history("Sound not found.", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user