diff --git a/draugnorak.nvgt b/draugnorak.nvgt index ede9bff..c33f4a1 100644 --- a/draugnorak.nvgt +++ b/draugnorak.nvgt @@ -19,15 +19,16 @@ sound_pool p(100); #include "src/audio_utils.nvgt" #include "src/creature_audio.nvgt" #include "src/notify.nvgt" +#include "src/speech_history.nvgt" int run_main_menu() { - screen_reader_speak("Draugnorak. Main menu.", true); + speak_with_history("Draugnorak. Main menu.", true); int selection = 0; string load_label = has_save_game() ? "Load Game" : "Load Game (no save found)"; string[] options = {"New Game", load_label, "Exit"}; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); while(true) { wait(5); @@ -35,13 +36,13 @@ int run_main_menu() { if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { @@ -78,11 +79,11 @@ void main() } } start_new_game(); - screen_reader_speak("New game started.", true); + speak_with_history("New game started.", true); game_started = true; } else if (selection == 1) { if (load_game_state()) { - screen_reader_speak("Game loaded.", true); + speak_with_history("Game loaded.", true); game_started = true; } else { if (has_save_game()) { @@ -108,10 +109,10 @@ void main() game_paused = !game_paused; if (game_paused) { p.pause_all(); - screen_reader_speak("Paused. Press backspace to resume.", true); + speak_with_history("Paused. Press backspace to resume.", true); } else { p.resume_all(); - screen_reader_speak("Resumed.", true); + speak_with_history("Resumed.", true); } continue; } @@ -150,7 +151,7 @@ void main() if (fire_on_tile != null && !jumping && fire_damage_timer.elapsed > 1000) { player_health--; fire_damage_timer.restart(); - screen_reader_speak("Burning! " + player_health + " health remaining.", true); + speak_with_history("Burning! " + player_health + " health remaining.", true); } // Healing in base area @@ -161,13 +162,13 @@ void main() if (healing_timer.elapsed > heal_interval) { player_health++; healing_timer.restart(); - screen_reader_speak(player_health + " health.", true); + speak_with_history(player_health + " health.", true); } } // Death check if (player_health <= 0) { - screen_reader_speak("You have died.", true); + speak_with_history("You have died.", true); wait(2000); exit(); } @@ -182,21 +183,17 @@ void main() check_quick_slot_keys(); check_time_input(); check_notification_keys(); + check_speech_history_keys(); // Health Key if (key_pressed(KEY_H)) { - screen_reader_speak(player_health + " health of " + max_health, true); + speak_with_history(player_health + " health of " + max_health, true); } // Coordinates Key if (key_pressed(KEY_X)) { string direction_label = (facing == 1) ? "east" : "west"; - string terrain_info = ""; - MountainRange@ mountain = get_mountain_at(x); - if (mountain !is null) { - terrain_info = ", elevation " + y + ", " + mountain.get_terrain_at(x); - } - screen_reader_speak(direction_label + ", x " + x + ", y " + y + terrain_info, true); + speak_with_history(direction_label + ", x " + x + ", y " + y, true); } // Base Info Key (base only) @@ -243,13 +240,16 @@ void main() } else if(!jumping && !climbing && !falling && !rope_climbing) { + // Get ground elevation at current position + int ground_elevation = get_mountain_elevation_at(x); + // Check if on tree tile Tree@ tree = get_tree_at(x); - if (tree != null && !tree.is_chopped && y == 0) { + if (tree != null && !tree.is_chopped && y == ground_elevation) { // Start climbing the tree start_climbing_tree(x); - } else if (y == 0) { - // Normal jump + } else if (y == ground_elevation) { + // Normal jump (only if on the ground) p.play_stationary("sounds/jump.ogg", false); jumping = true; jumptimer.restart(); @@ -260,15 +260,16 @@ void main() if(jumping && jumptimer.elapsed > 850) { jumping = false; - y = 0; // Reset y after jump + // Reset y to ground elevation after jump + y = get_mountain_elevation_at(x); play_land_sound(x, BASE_END, GRASS_END); // Check for snare on landing? check_snare_collision(x); } - // Set y to 3 during jump - if(jumping && y == 0) { - y = 3; + // Set y to 3 above ground during jump + if(jumping && y == get_mountain_elevation_at(x)) { + y = get_mountain_elevation_at(x) + 3; } movetime = jumping ? jump_speed : walk_speed; @@ -276,14 +277,14 @@ void main() // Movement Logic if (key_pressed(KEY_LEFT) && facing != 0 && !climbing && !falling && !rope_climbing) { facing = 0; - screen_reader_speak("west", true); + speak_with_history("west", true); walktimer.restart(); // Cancel pending rope climb when changing direction pending_rope_climb_x = -1; } if (key_pressed(KEY_RIGHT) && facing != 1 && !climbing && !falling && !rope_climbing) { facing = 1; - screen_reader_speak("east", true); + speak_with_history("east", true); walktimer.restart(); // Cancel pending rope climb when changing direction pending_rope_climb_x = -1; @@ -295,7 +296,9 @@ void main() // Check if trying to move left/right while in tree (not in mountain) MountainRange@ current_mountain = get_mountain_at(x); - if((key_down(KEY_LEFT) || key_down(KEY_RIGHT)) && y > 0 && !jumping && !falling && !rope_climbing && current_mountain is null) { + Tree@ current_tree = get_tree_at(x); + int ground_elevation = get_mountain_elevation_at(x); + if((key_down(KEY_LEFT) || key_down(KEY_RIGHT)) && y > ground_elevation && !jumping && !falling && !rope_climbing && current_mountain is null && current_tree !is null) { // Fall out of tree climbing = false; start_falling(); @@ -307,9 +310,9 @@ void main() // Check mountain movement if (can_move_mountain(x, x - 1)) { x--; - // Update elevation if in mountain + // Always update elevation to match ground (0 if not in mountain) int new_elevation = get_mountain_elevation_at(x); - if (new_elevation != y && get_mountain_at(x) !is null) { + if (new_elevation != y) { y = new_elevation; } walktimer.restart(); @@ -325,9 +328,9 @@ void main() // Check mountain movement if (can_move_mountain(x, x + 1)) { x++; - // Update elevation if in mountain + // Always update elevation to match ground (0 if not in mountain) int new_elevation = get_mountain_elevation_at(x); - if (new_elevation != y && get_mountain_at(x) !is null) { + if (new_elevation != y) { y = new_elevation; } walktimer.restart(); @@ -377,7 +380,7 @@ void main() sling_sound_handle = p.play_stationary("sounds/weapons/sling_swing.ogg", true); last_sling_stage = -1; } else { - screen_reader_speak("No stones.", true); + speak_with_history("No stones.", true); } } diff --git a/src/base_system.nvgt b/src/base_system.nvgt index bc5c0ab..ba79db5 100644 --- a/src/base_system.nvgt +++ b/src/base_system.nvgt @@ -255,7 +255,7 @@ void attempt_resident_collection() { // Announce only if player is in base if (x <= BASE_END) { - screen_reader_speak("Resident added " + item_name + " to storage.", true); + speak_with_history("Resident added " + item_name + " to storage.", true); } } } diff --git a/src/combat.nvgt b/src/combat.nvgt index 8317b8e..62f3bd6 100644 --- a/src/combat.nvgt +++ b/src/combat.nvgt @@ -134,7 +134,7 @@ void release_sling_attack(int player_x) { // Only hit if released during in-range window (stage 1) if (stage != 1) { - screen_reader_speak("Stone missed.", true); + speak_with_history("Stone missed.", true); return; } @@ -192,7 +192,7 @@ void release_sling_attack(int player_x) { if (tree != null && !tree.is_chopped) { // Stone hits tree but doesn't damage it play_1d_with_volume_step("sounds/weapons/sling_hit.ogg", player_x, check_x, false, PLAYER_WEAPON_SOUND_VOLUME_STEP); - screen_reader_speak("Stone hit tree at " + check_x + ".", true); + speak_with_history("Stone hit tree at " + check_x + ".", true); return; } } @@ -200,7 +200,7 @@ void release_sling_attack(int player_x) { // No target found if (target_x == -1) { - screen_reader_speak("Stone missed.", true); + speak_with_history("Stone missed.", true); return; } diff --git a/src/constants.nvgt b/src/constants.nvgt index e55ad16..aa5b76b 100644 --- a/src/constants.nvgt +++ b/src/constants.nvgt @@ -2,6 +2,7 @@ int MAP_SIZE = 35; const int BASE_END = 4; // 0-4 const int GRASS_END = 19; // 5-19 +const int GRAVEL_START = 20; // 20-34 const int GRAVEL_END = 34; // 20-34 // Expansion configuration @@ -149,7 +150,7 @@ const float FLYING_CREATURE_FADE_OUT_MIN_VOLUME = -40.0; // dB const int MOUNTAIN_SIZE = 60; const int MOUNTAIN_MIN_ELEVATION = 0; const int MOUNTAIN_MAX_ELEVATION = 40; -const int MOUNTAIN_STEEP_THRESHOLD = 6; +const int MOUNTAIN_STEEP_THRESHOLD = 7; const int MOUNTAIN_MAX_SLOPE = 20; const int ROPE_CLIMB_SPEED = 1000; const int MOUNTAIN_STREAM_SOUND_RANGE = 7; diff --git a/src/crafting.nvgt b/src/crafting.nvgt index efe45d5..8f1f40e 100644 --- a/src/crafting.nvgt +++ b/src/crafting.nvgt @@ -8,7 +8,7 @@ void check_crafting_menu(int x, int base_end_tile) { } void run_crafting_menu() { - screen_reader_speak("Crafting menu.", true); + speak_with_history("Crafting menu.", true); int selection = 0; string[] categories = {"Weapons", "Tools", "Materials", "Clothing", "Buildings", "Barricade"}; @@ -18,20 +18,20 @@ void run_crafting_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= categories.length()) selection = 0; - screen_reader_speak(categories[selection], true); + speak_with_history(categories[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = categories.length() - 1; - screen_reader_speak(categories[selection], true); + speak_with_history(categories[selection], true); } if (key_pressed(KEY_RETURN)) { @@ -48,7 +48,7 @@ void run_crafting_menu() { } void run_weapons_menu() { - screen_reader_speak("Weapons.", true); + speak_with_history("Weapons.", true); int selection = 0; string[] options = { @@ -60,20 +60,20 @@ void run_weapons_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { @@ -91,7 +91,7 @@ void run_weapons_menu() { } void run_tools_menu() { - screen_reader_speak("Tools.", true); + speak_with_history("Tools.", true); int selection = 0; string[] options = { @@ -108,20 +108,20 @@ void run_tools_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { @@ -149,7 +149,7 @@ void run_tools_menu() { } void run_materials_menu() { - screen_reader_speak("Materials.", true); + speak_with_history("Materials.", true); int selection = 0; string[] options = { @@ -161,20 +161,20 @@ void run_materials_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { @@ -191,7 +191,7 @@ void run_materials_menu() { } } void run_clothing_menu() { - screen_reader_speak("Clothing.", true); + speak_with_history("Clothing.", true); int selection = 0; string[] options = { @@ -207,20 +207,20 @@ void run_clothing_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { @@ -246,7 +246,7 @@ void run_clothing_menu() { } void run_buildings_menu() { - screen_reader_speak("Buildings.", true); + speak_with_history("Buildings.", true); int selection = 0; string[] options; @@ -292,20 +292,20 @@ void run_buildings_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { @@ -324,11 +324,11 @@ void run_buildings_menu() { void run_barricade_menu() { if (barricade_health >= BARRICADE_MAX_HEALTH) { - screen_reader_speak("Barricade is already at full health.", true); + speak_with_history("Barricade is already at full health.", true); return; } - screen_reader_speak("Barricade.", true); + speak_with_history("Barricade.", true); int selection = 0; string[] options; @@ -352,7 +352,7 @@ void run_barricade_menu() { } if (options.length() == 0) { - screen_reader_speak("No materials to reinforce the barricade.", true); + speak_with_history("No materials to reinforce the barricade.", true); return; } @@ -360,20 +360,20 @@ void run_barricade_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { @@ -397,7 +397,7 @@ void run_barricade_menu() { } void simulate_crafting(int item_count) { - screen_reader_speak("Crafting...", true); + speak_with_history("Crafting...", true); // Nothing should take less than 4. if(item_count < 4) { item_count = 4; @@ -421,21 +421,21 @@ void craft_knife() { if (missing == "") { if (inv_knives >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more stone knives.", true); + speak_with_history("You can't carry any more stone knives.", true); return; } simulate_crafting(2); inv_stones -= 2; inv_knives++; - screen_reader_speak("Crafted a Stone Knife.", true); + speak_with_history("Crafted a Stone Knife.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_knife_max() { if (inv_knives >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more stone knives.", true); + speak_with_history("You can't carry any more stone knives.", true); return; } @@ -444,7 +444,7 @@ void craft_knife_max() { if (max_possible > space) max_possible = space; if (max_possible <= 0) { - screen_reader_speak("Missing: 2 stones", true); + speak_with_history("Missing: 2 stones", true); return; } @@ -453,7 +453,7 @@ void craft_knife_max() { simulate_crafting(craft_time); inv_stones -= (max_possible * 2); inv_knives += max_possible; - screen_reader_speak("Crafted " + max_possible + " Stone Knives.", true); + speak_with_history("Crafted " + max_possible + " Stone Knives.", true); } void craft_spear() { @@ -465,7 +465,7 @@ void craft_spear() { if (missing == "") { if (inv_spears >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more spears.", true); + speak_with_history("You can't carry any more spears.", true); return; } simulate_crafting(3); @@ -473,19 +473,19 @@ void craft_spear() { inv_vines--; inv_stones--; inv_spears++; - screen_reader_speak("Crafted a Spear.", true); + speak_with_history("Crafted a Spear.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_spear_max() { if (inv_knives < 1) { - screen_reader_speak("Missing: Stone Knife", true); + speak_with_history("Missing: Stone Knife", true); return; } if (inv_spears >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more spears.", true); + speak_with_history("You can't carry any more spears.", true); return; } @@ -504,7 +504,7 @@ void craft_spear_max() { if (inv_sticks < 1) missing += "1 stick "; if (inv_vines < 1) missing += "1 vine "; if (inv_stones < 1) missing += "1 stone "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -515,7 +515,7 @@ void craft_spear_max() { inv_vines -= max_craft; inv_stones -= max_craft; inv_spears += max_craft; - screen_reader_speak("Crafted " + max_craft + " Spears.", true); + speak_with_history("Crafted " + max_craft + " Spears.", true); } void craft_sling() { @@ -525,22 +525,22 @@ void craft_sling() { if (missing == "") { if (inv_slings >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more slings.", true); + speak_with_history("You can't carry any more slings.", true); return; } simulate_crafting(3); inv_skins--; inv_vines -= 2; inv_slings++; - screen_reader_speak("Crafted a Sling.", true); + speak_with_history("Crafted a Sling.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_sling_max() { if (inv_slings >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more slings.", true); + speak_with_history("You can't carry any more slings.", true); return; } @@ -556,7 +556,7 @@ void craft_sling_max() { string missing = ""; if (inv_skins < 1) missing += "1 skin "; if (inv_vines < 2) missing += "2 vines "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -566,7 +566,7 @@ void craft_sling_max() { inv_skins -= max_craft; inv_vines -= (max_craft * 2); inv_slings += max_craft; - screen_reader_speak("Crafted " + max_craft + " Slings.", true); + speak_with_history("Crafted " + max_craft + " Slings.", true); } void craft_skin_hat() { @@ -576,22 +576,22 @@ void craft_skin_hat() { if (missing == "") { if (inv_skin_hats >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skin hats.", true); + speak_with_history("You can't carry any more skin hats.", true); return; } simulate_crafting(2); inv_skins--; inv_vines--; inv_skin_hats++; - screen_reader_speak("Crafted a Skin Hat.", true); + speak_with_history("Crafted a Skin Hat.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_skin_hat_max() { if (inv_skin_hats >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skin hats.", true); + speak_with_history("You can't carry any more skin hats.", true); return; } @@ -607,7 +607,7 @@ void craft_skin_hat_max() { string missing = ""; if (inv_skins < 1) missing += "1 skin "; if (inv_vines < 1) missing += "1 vine "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -617,7 +617,7 @@ void craft_skin_hat_max() { inv_skins -= max_craft; inv_vines -= max_craft; inv_skin_hats += max_craft; - screen_reader_speak("Crafted " + max_craft + " Skin Hats.", true); + speak_with_history("Crafted " + max_craft + " Skin Hats.", true); } void craft_skin_gloves() { @@ -627,22 +627,22 @@ void craft_skin_gloves() { if (missing == "") { if (inv_skin_gloves >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skin gloves.", true); + speak_with_history("You can't carry any more skin gloves.", true); return; } simulate_crafting(2); inv_skins--; inv_vines--; inv_skin_gloves++; - screen_reader_speak("Crafted Skin Gloves.", true); + speak_with_history("Crafted Skin Gloves.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_skin_gloves_max() { if (inv_skin_gloves >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skin gloves.", true); + speak_with_history("You can't carry any more skin gloves.", true); return; } @@ -658,7 +658,7 @@ void craft_skin_gloves_max() { string missing = ""; if (inv_skins < 1) missing += "1 skin "; if (inv_vines < 1) missing += "1 vine "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -668,7 +668,7 @@ void craft_skin_gloves_max() { inv_skins -= max_craft; inv_vines -= max_craft; inv_skin_gloves += max_craft; - screen_reader_speak("Crafted " + max_craft + " Skin Gloves.", true); + speak_with_history("Crafted " + max_craft + " Skin Gloves.", true); } void craft_skin_pants() { @@ -678,22 +678,22 @@ void craft_skin_pants() { if (missing == "") { if (inv_skin_pants >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skin pants.", true); + speak_with_history("You can't carry any more skin pants.", true); return; } simulate_crafting(9); inv_skins -= 6; inv_vines -= 3; inv_skin_pants++; - screen_reader_speak("Crafted Skin Pants.", true); + speak_with_history("Crafted Skin Pants.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_skin_pants_max() { if (inv_skin_pants >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skin pants.", true); + speak_with_history("You can't carry any more skin pants.", true); return; } @@ -709,7 +709,7 @@ void craft_skin_pants_max() { string missing = ""; if (inv_skins < 6) missing += "6 skins "; if (inv_vines < 3) missing += "3 vines "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -718,7 +718,7 @@ void craft_skin_pants_max() { inv_skins -= (max_craft * 6); inv_vines -= (max_craft * 3); inv_skin_pants += max_craft; - screen_reader_speak("Crafted " + max_craft + " Skin Pants.", true); + speak_with_history("Crafted " + max_craft + " Skin Pants.", true); } void craft_skin_tunic() { @@ -728,22 +728,22 @@ void craft_skin_tunic() { if (missing == "") { if (inv_skin_tunics >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skin tunics.", true); + speak_with_history("You can't carry any more skin tunics.", true); return; } simulate_crafting(6); inv_skins -= 4; inv_vines -= 2; inv_skin_tunics++; - screen_reader_speak("Crafted a Skin Tunic.", true); + speak_with_history("Crafted a Skin Tunic.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_skin_tunic_max() { if (inv_skin_tunics >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skin tunics.", true); + speak_with_history("You can't carry any more skin tunics.", true); return; } @@ -759,7 +759,7 @@ void craft_skin_tunic_max() { string missing = ""; if (inv_skins < 4) missing += "4 skins "; if (inv_vines < 2) missing += "2 vines "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -768,7 +768,7 @@ void craft_skin_tunic_max() { inv_skins -= (max_craft * 4); inv_vines -= (max_craft * 2); inv_skin_tunics += max_craft; - screen_reader_speak("Crafted " + max_craft + " Skin Tunics.", true); + speak_with_history("Crafted " + max_craft + " Skin Tunics.", true); } void craft_moccasins() { @@ -778,22 +778,22 @@ void craft_moccasins() { if (missing == "") { if (inv_moccasins >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more moccasins.", true); + speak_with_history("You can't carry any more moccasins.", true); return; } simulate_crafting(3); inv_skins -= 2; inv_vines--; inv_moccasins++; - screen_reader_speak("Crafted moccasins.", true); + speak_with_history("Crafted moccasins.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_moccasins_max() { if (inv_moccasins >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more moccasins.", true); + speak_with_history("You can't carry any more moccasins.", true); return; } @@ -809,7 +809,7 @@ void craft_moccasins_max() { string missing = ""; if (inv_skins < 2) missing += "2 skins "; if (inv_vines < 1) missing += "1 vine "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -819,7 +819,7 @@ void craft_moccasins_max() { inv_skins -= (max_craft * 2); inv_vines -= max_craft; inv_moccasins += max_craft; - screen_reader_speak("Crafted " + max_craft + " Moccasins.", true); + speak_with_history("Crafted " + max_craft + " Moccasins.", true); } void craft_skin_pouch() { @@ -829,22 +829,22 @@ void craft_skin_pouch() { if (missing == "") { if (inv_skin_pouches >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skin pouches.", true); + speak_with_history("You can't carry any more skin pouches.", true); return; } simulate_crafting(3); inv_skins -= 2; inv_vines--; inv_skin_pouches++; - screen_reader_speak("Crafted a Skin Pouch.", true); + speak_with_history("Crafted a Skin Pouch.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_skin_pouch_max() { if (inv_skin_pouches >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skin pouches.", true); + speak_with_history("You can't carry any more skin pouches.", true); return; } @@ -860,7 +860,7 @@ void craft_skin_pouch_max() { string missing = ""; if (inv_skins < 2) missing += "2 skins "; if (inv_vines < 1) missing += "1 vine "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -870,7 +870,7 @@ void craft_skin_pouch_max() { inv_skins -= (max_craft * 2); inv_vines -= max_craft; inv_skin_pouches += max_craft; - screen_reader_speak("Crafted " + max_craft + " Skin Pouches.", true); + speak_with_history("Crafted " + max_craft + " Skin Pouches.", true); } void craft_snare() { @@ -880,22 +880,22 @@ void craft_snare() { if (missing == "") { if (inv_snares >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more snares.", true); + speak_with_history("You can't carry any more snares.", true); return; } simulate_crafting(3); inv_sticks--; inv_vines -= 2; inv_snares++; - screen_reader_speak("Crafted a Snare.", true); + speak_with_history("Crafted a Snare.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_snare_max() { if (inv_snares >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more snares.", true); + speak_with_history("You can't carry any more snares.", true); return; } @@ -911,7 +911,7 @@ void craft_snare_max() { string missing = ""; if (inv_sticks < 1) missing += "1 stick "; if (inv_vines < 2) missing += "2 vines "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -921,7 +921,7 @@ void craft_snare_max() { inv_sticks -= max_craft; inv_vines -= (max_craft * 2); inv_snares += max_craft; - screen_reader_speak("Crafted " + max_craft + " Snares.", true); + speak_with_history("Crafted " + max_craft + " Snares.", true); } void craft_axe() { @@ -933,7 +933,7 @@ void craft_axe() { if (missing == "") { if (inv_axes >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more stone axes.", true); + speak_with_history("You can't carry any more stone axes.", true); return; } simulate_crafting(4); @@ -941,19 +941,19 @@ void craft_axe() { inv_vines--; inv_stones -= 2; inv_axes++; - screen_reader_speak("Crafted a Stone Axe.", true); + speak_with_history("Crafted a Stone Axe.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_axe_max() { if (inv_knives < 1) { - screen_reader_speak("Missing: Stone Knife", true); + speak_with_history("Missing: Stone Knife", true); return; } if (inv_axes >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more stone axes.", true); + speak_with_history("You can't carry any more stone axes.", true); return; } @@ -972,7 +972,7 @@ void craft_axe_max() { if (inv_sticks < 1) missing += "1 stick "; if (inv_vines < 1) missing += "1 vine "; if (inv_stones < 2) missing += "2 stones "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -982,13 +982,13 @@ void craft_axe_max() { inv_vines -= max_craft; inv_stones -= (max_craft * 2); inv_axes += max_craft; - screen_reader_speak("Crafted " + max_craft + " Stone Axes.", true); + speak_with_history("Crafted " + max_craft + " Stone Axes.", true); } void craft_firepit() { // Check if there's already a firepit here if (get_firepit_at(x) != null) { - screen_reader_speak("There is already a firepit here.", true); + speak_with_history("There is already a firepit here.", true); return; } @@ -999,9 +999,9 @@ void craft_firepit() { simulate_crafting(9); inv_stones -= 9; add_world_firepit(x); - screen_reader_speak("Firepit built here.", true); + speak_with_history("Firepit built here.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } @@ -1009,7 +1009,7 @@ void craft_campfire() { // Check if there's a firepit within 2 tiles WorldFirepit@ firepit = get_firepit_near(x, 2); if (firepit == null) { - screen_reader_speak("You need a firepit within 2 tiles to build a fire.", true); + speak_with_history("You need a firepit within 2 tiles to build a fire.", true); return; } @@ -1023,22 +1023,22 @@ void craft_campfire() { inv_sticks -= 2; // Build the fire at the firepit location, not player location add_world_fire(firepit.position); - screen_reader_speak("Fire built at firepit.", true); + speak_with_history("Fire built at firepit.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_herb_garden() { // Can only build in base area if (x > BASE_END) { - screen_reader_speak("Herb garden can only be built in the base area.", true); + speak_with_history("Herb garden can only be built in the base area.", true); return; } // Check if there's already an herb garden in the base if (get_herb_garden_at_base() != null) { - screen_reader_speak("There is already an herb garden in the base.", true); + speak_with_history("There is already an herb garden in the base.", true); return; } @@ -1053,19 +1053,19 @@ void craft_herb_garden() { inv_vines -= 3; inv_logs -= 2; add_world_herb_garden(x); - screen_reader_speak("Herb garden built. The base now heals faster.", true); + speak_with_history("Herb garden built. The base now heals faster.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_storage() { if (x > BASE_END) { - screen_reader_speak("Storage must be built in the base.", true); + speak_with_history("Storage must be built in the base.", true); return; } if (world_storages.length() > 0) { - screen_reader_speak("Storage already built.", true); + speak_with_history("Storage already built.", true); return; } string missing = ""; @@ -1079,19 +1079,19 @@ void craft_storage() { inv_stones -= STORAGE_STONE_COST; inv_vines -= STORAGE_VINE_COST; add_world_storage(x); - screen_reader_speak("Storage built.", true); + speak_with_history("Storage built.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_pasture() { if (x > BASE_END) { - screen_reader_speak("Pasture must be built in the base.", true); + speak_with_history("Pasture must be built in the base.", true); return; } if (world_pastures.length() > 0) { - screen_reader_speak("Pasture already built.", true); + speak_with_history("Pasture already built.", true); return; } string missing = ""; @@ -1103,19 +1103,19 @@ void craft_pasture() { inv_logs -= PASTURE_LOG_COST; inv_vines -= PASTURE_VINE_COST; add_world_pasture(x); - screen_reader_speak("Pasture built.", true); + speak_with_history("Pasture built.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_stable() { if (x > BASE_END) { - screen_reader_speak("Stable must be built in the base.", true); + speak_with_history("Stable must be built in the base.", true); return; } if (world_stables.length() > 0) { - screen_reader_speak("Stable already built.", true); + speak_with_history("Stable already built.", true); return; } string missing = ""; @@ -1129,19 +1129,19 @@ void craft_stable() { inv_stones -= STABLE_STONE_COST; inv_vines -= STABLE_VINE_COST; add_world_stable(x); - screen_reader_speak("Stable built.", true); + speak_with_history("Stable built.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_altar() { if (x > BASE_END) { - screen_reader_speak("Altar must be built in the base.", true); + speak_with_history("Altar must be built in the base.", true); return; } if (world_altars.length() > 0) { - screen_reader_speak("Altar already built.", true); + speak_with_history("Altar already built.", true); return; } string missing = ""; @@ -1153,84 +1153,84 @@ void craft_altar() { inv_stones -= ALTAR_STONE_COST; inv_sticks -= ALTAR_STICK_COST; add_world_altar(x); - screen_reader_speak("Altar built.", true); + speak_with_history("Altar built.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void reinforce_barricade_with_sticks() { if (barricade_health >= BARRICADE_MAX_HEALTH) { - screen_reader_speak("Barricade is already at full health.", true); + speak_with_history("Barricade is already at full health.", true); return; } if (inv_sticks < BARRICADE_STICK_COST) { - screen_reader_speak("Not enough sticks.", true); + speak_with_history("Not enough sticks.", true); return; } simulate_crafting(BARRICADE_STICK_COST); inv_sticks -= BARRICADE_STICK_COST; int gained = add_barricade_health(BARRICADE_STICK_HEALTH); - screen_reader_speak("Reinforced barricade with sticks. +" + gained + " health. Now " + barricade_health + " of " + BARRICADE_MAX_HEALTH + ".", true); + speak_with_history("Reinforced barricade with sticks. +" + gained + " health. Now " + barricade_health + " of " + BARRICADE_MAX_HEALTH + ".", true); } void reinforce_barricade_with_vines() { if (barricade_health >= BARRICADE_MAX_HEALTH) { - screen_reader_speak("Barricade is already at full health.", true); + speak_with_history("Barricade is already at full health.", true); return; } if (inv_vines < BARRICADE_VINE_COST) { - screen_reader_speak("Not enough vines.", true); + speak_with_history("Not enough vines.", true); return; } simulate_crafting(BARRICADE_VINE_COST); inv_vines -= BARRICADE_VINE_COST; int gained = add_barricade_health(BARRICADE_VINE_HEALTH); - screen_reader_speak("Reinforced barricade with vines. +" + gained + " health. Now " + barricade_health + " of " + BARRICADE_MAX_HEALTH + ".", true); + speak_with_history("Reinforced barricade with vines. +" + gained + " health. Now " + barricade_health + " of " + BARRICADE_MAX_HEALTH + ".", true); } void reinforce_barricade_with_log() { if (barricade_health >= BARRICADE_MAX_HEALTH) { - screen_reader_speak("Barricade is already at full health.", true); + speak_with_history("Barricade is already at full health.", true); return; } if (inv_logs < BARRICADE_LOG_COST) { - screen_reader_speak("Not enough logs.", true); + speak_with_history("Not enough logs.", true); return; } simulate_crafting(BARRICADE_LOG_COST); inv_logs -= BARRICADE_LOG_COST; int gained = add_barricade_health(BARRICADE_LOG_HEALTH); - screen_reader_speak("Reinforced barricade with log. +" + gained + " health. Now " + barricade_health + " of " + BARRICADE_MAX_HEALTH + ".", true); + speak_with_history("Reinforced barricade with log. +" + gained + " health. Now " + barricade_health + " of " + BARRICADE_MAX_HEALTH + ".", true); } void reinforce_barricade_with_stones() { if (barricade_health >= BARRICADE_MAX_HEALTH) { - screen_reader_speak("Barricade is already at full health.", true); + speak_with_history("Barricade is already at full health.", true); return; } if (inv_stones < BARRICADE_STONE_COST) { - screen_reader_speak("Not enough stones.", true); + speak_with_history("Not enough stones.", true); return; } simulate_crafting(BARRICADE_STONE_COST); inv_stones -= BARRICADE_STONE_COST; int gained = add_barricade_health(BARRICADE_STONE_HEALTH); - screen_reader_speak("Reinforced barricade with stones. +" + gained + " health. Now " + barricade_health + " of " + BARRICADE_MAX_HEALTH + ".", true); + speak_with_history("Reinforced barricade with stones. +" + gained + " health. Now " + barricade_health + " of " + BARRICADE_MAX_HEALTH + ".", true); } void reinforce_barricade_max_with_sticks() { if (barricade_health >= BARRICADE_MAX_HEALTH) { - screen_reader_speak("Barricade is already at full health.", true); + speak_with_history("Barricade is already at full health.", true); return; } if (inv_sticks < BARRICADE_STICK_COST) { - screen_reader_speak("Missing: " + BARRICADE_STICK_COST + " sticks", true); + speak_with_history("Missing: " + BARRICADE_STICK_COST + " sticks", true); return; } @@ -1246,17 +1246,17 @@ void reinforce_barricade_max_with_sticks() { barricade_health += (to_do * BARRICADE_STICK_HEALTH); if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; - screen_reader_speak("Reinforced barricade " + to_do + " times with sticks. Health now " + barricade_health + ".", true); + speak_with_history("Reinforced barricade " + to_do + " times with sticks. Health now " + barricade_health + ".", true); } void reinforce_barricade_max_with_vines() { if (barricade_health >= BARRICADE_MAX_HEALTH) { - screen_reader_speak("Barricade is already at full health.", true); + speak_with_history("Barricade is already at full health.", true); return; } if (inv_vines < BARRICADE_VINE_COST) { - screen_reader_speak("Missing: " + BARRICADE_VINE_COST + " vines", true); + speak_with_history("Missing: " + BARRICADE_VINE_COST + " vines", true); return; } @@ -1272,17 +1272,17 @@ void reinforce_barricade_max_with_vines() { barricade_health += (to_do * BARRICADE_VINE_HEALTH); if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; - screen_reader_speak("Reinforced barricade " + to_do + " times with vines. Health now " + barricade_health + ".", true); + speak_with_history("Reinforced barricade " + to_do + " times with vines. Health now " + barricade_health + ".", true); } void reinforce_barricade_max_with_log() { if (barricade_health >= BARRICADE_MAX_HEALTH) { - screen_reader_speak("Barricade is already at full health.", true); + speak_with_history("Barricade is already at full health.", true); return; } if (inv_logs < BARRICADE_LOG_COST) { - screen_reader_speak("Missing: " + BARRICADE_LOG_COST + " log", true); + speak_with_history("Missing: " + BARRICADE_LOG_COST + " log", true); return; } @@ -1298,17 +1298,17 @@ void reinforce_barricade_max_with_log() { barricade_health += (to_do * BARRICADE_LOG_HEALTH); if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; - screen_reader_speak("Reinforced barricade " + to_do + " times with log. Health now " + barricade_health + ".", true); + speak_with_history("Reinforced barricade " + to_do + " times with log. Health now " + barricade_health + ".", true); } void reinforce_barricade_max_with_stones() { if (barricade_health >= BARRICADE_MAX_HEALTH) { - screen_reader_speak("Barricade is already at full health.", true); + speak_with_history("Barricade is already at full health.", true); return; } if (inv_stones < BARRICADE_STONE_COST) { - screen_reader_speak("Missing: " + BARRICADE_STONE_COST + " stones", true); + speak_with_history("Missing: " + BARRICADE_STONE_COST + " stones", true); return; } @@ -1324,7 +1324,7 @@ void reinforce_barricade_max_with_stones() { barricade_health += (to_do * BARRICADE_STONE_HEALTH); if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; - screen_reader_speak("Reinforced barricade " + to_do + " times with stones. Health now " + barricade_health + ".", true); + speak_with_history("Reinforced barricade " + to_do + " times with stones. Health now " + barricade_health + ".", true); } void craft_fishing_pole() { @@ -1334,22 +1334,22 @@ void craft_fishing_pole() { if (missing == "") { if (inv_fishing_poles >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more fishing poles.", true); + speak_with_history("You can't carry any more fishing poles.", true); return; } simulate_crafting(3); inv_sticks--; inv_vines -= 2; inv_fishing_poles++; - screen_reader_speak("Crafted a Fishing Pole.", true); + speak_with_history("Crafted a Fishing Pole.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_fishing_pole_max() { if (inv_fishing_poles >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more fishing poles.", true); + speak_with_history("You can't carry any more fishing poles.", true); return; } @@ -1365,7 +1365,7 @@ void craft_fishing_pole_max() { string missing = ""; if (inv_sticks < 1) missing += "1 stick "; if (inv_vines < 2) missing += "2 vines "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -1375,7 +1375,7 @@ void craft_fishing_pole_max() { inv_sticks -= max_craft; inv_vines -= (max_craft * 2); inv_fishing_poles += max_craft; - screen_reader_speak("Crafted " + max_craft + " Fishing Poles.", true); + speak_with_history("Crafted " + max_craft + " Fishing Poles.", true); } void craft_rope() { @@ -1384,21 +1384,21 @@ void craft_rope() { if (missing == "") { if (inv_ropes >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more rope.", true); + speak_with_history("You can't carry any more rope.", true); return; } simulate_crafting(3); inv_vines -= 3; inv_ropes++; - screen_reader_speak("Crafted rope.", true); + speak_with_history("Crafted rope.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_rope_max() { if (inv_ropes >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more rope.", true); + speak_with_history("You can't carry any more rope.", true); return; } @@ -1408,7 +1408,7 @@ void craft_rope_max() { if (max_craft > space) max_craft = space; if (max_craft <= 0) { - screen_reader_speak("Missing: 3 vines", true); + speak_with_history("Missing: 3 vines", true); return; } @@ -1417,7 +1417,7 @@ void craft_rope_max() { simulate_crafting(craft_time); inv_vines -= (max_craft * 3); inv_ropes += max_craft; - screen_reader_speak("Crafted " + max_craft + " Rope.", true); + speak_with_history("Crafted " + max_craft + " Rope.", true); } void craft_reed_basket() { @@ -1426,21 +1426,21 @@ void craft_reed_basket() { if (missing == "") { if (inv_reed_baskets >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more reed baskets.", true); + speak_with_history("You can't carry any more reed baskets.", true); return; } simulate_crafting(3); inv_reeds -= 3; inv_reed_baskets++; - screen_reader_speak("Crafted a reed basket.", true); + speak_with_history("Crafted a reed basket.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_reed_basket_max() { if (inv_reed_baskets >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more reed baskets.", true); + speak_with_history("You can't carry any more reed baskets.", true); return; } @@ -1450,7 +1450,7 @@ void craft_reed_basket_max() { if (max_craft > space) max_craft = space; if (max_craft <= 0) { - screen_reader_speak("Missing: 3 reeds", true); + speak_with_history("Missing: 3 reeds", true); return; } @@ -1459,7 +1459,7 @@ void craft_reed_basket_max() { simulate_crafting(craft_time); inv_reeds -= (max_craft * 3); inv_reed_baskets += max_craft; - screen_reader_speak("Crafted " + max_craft + " Reed Baskets.", true); + speak_with_history("Crafted " + max_craft + " Reed Baskets.", true); } void craft_clay_pot() { @@ -1469,21 +1469,21 @@ void craft_clay_pot() { // Check for fire within 3 tiles (can hear it) WorldFire@ fire = get_fire_within_range(x, 3); if (fire == null) { - screen_reader_speak("You need a fire within 3 tiles to craft a clay pot.", true); + speak_with_history("You need a fire within 3 tiles to craft a clay pot.", true); return; } if (missing == "") { if (inv_clay_pots >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more clay pots.", true); + speak_with_history("You can't carry any more clay pots.", true); return; } simulate_crafting(3); inv_clay -= 3; inv_clay_pots++; - screen_reader_speak("Crafted a clay pot.", true); + speak_with_history("Crafted a clay pot.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } @@ -1491,12 +1491,12 @@ void craft_clay_pot_max() { // Check for fire within 3 tiles (can hear it) WorldFire@ fire = get_fire_within_range(x, 3); if (fire == null) { - screen_reader_speak("You need a fire within 3 tiles to craft clay pots.", true); + speak_with_history("You need a fire within 3 tiles to craft clay pots.", true); return; } if (inv_clay_pots >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more clay pots.", true); + speak_with_history("You can't carry any more clay pots.", true); return; } @@ -1506,7 +1506,7 @@ void craft_clay_pot_max() { if (max_craft > space) max_craft = space; if (max_craft <= 0) { - screen_reader_speak("Missing: 3 clay", true); + speak_with_history("Missing: 3 clay", true); return; } @@ -1515,12 +1515,12 @@ void craft_clay_pot_max() { simulate_crafting(craft_time); inv_clay -= (max_craft * 3); inv_clay_pots += max_craft; - screen_reader_speak("Crafted " + max_craft + " Clay Pots.", true); + speak_with_history("Crafted " + max_craft + " Clay Pots.", true); } void craft_incense() { if (world_altars.length() == 0) { - screen_reader_speak("You need an altar to craft incense.", true); + speak_with_history("You need an altar to craft incense.", true); return; } @@ -1531,7 +1531,7 @@ void craft_incense() { if (missing == "") { if (inv_incense >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more incense.", true); + speak_with_history("You can't carry any more incense.", true); return; } simulate_crafting(INCENSE_STICK_COST + INCENSE_VINE_COST + INCENSE_REED_COST); @@ -1539,20 +1539,20 @@ void craft_incense() { inv_vines -= INCENSE_VINE_COST; inv_reeds -= INCENSE_REED_COST; inv_incense++; - screen_reader_speak("Crafted incense.", true); + speak_with_history("Crafted incense.", true); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } void craft_incense_max() { if (world_altars.length() == 0) { - screen_reader_speak("You need an altar to craft incense.", true); + speak_with_history("You need an altar to craft incense.", true); return; } if (inv_incense >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more incense.", true); + speak_with_history("You can't carry any more incense.", true); return; } @@ -1571,7 +1571,7 @@ void craft_incense_max() { if (inv_sticks < INCENSE_STICK_COST) missing += INCENSE_STICK_COST + " sticks "; if (inv_vines < INCENSE_VINE_COST) missing += INCENSE_VINE_COST + " vines "; if (inv_reeds < INCENSE_REED_COST) missing += INCENSE_REED_COST + " reed "; - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); return; } @@ -1581,7 +1581,7 @@ void craft_incense_max() { inv_vines -= (max_craft * INCENSE_VINE_COST); inv_reeds -= (max_craft * INCENSE_REED_COST); inv_incense += max_craft; - screen_reader_speak("Crafted " + max_craft + " Incense.", true); + speak_with_history("Crafted " + max_craft + " Incense.", true); } void butcher_small_game() { @@ -1596,17 +1596,17 @@ void butcher_small_game() { // Check for fire within 3 tiles (can hear it) WorldFire@ fire = get_fire_within_range(x, 3); if (fire == null) { - screen_reader_speak("You need a fire within 3 tiles to butcher.", true); + speak_with_history("You need a fire within 3 tiles to butcher.", true); return; } if (missing == "") { if (inv_meat >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more meat.", true); + speak_with_history("You can't carry any more meat.", true); return; } if (inv_skins >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more skins.", true); + speak_with_history("You can't carry any more skins.", true); return; } simulate_crafting(1); @@ -1625,22 +1625,22 @@ void butcher_small_game() { inv_meat++; inv_feathers += random(3, 6); inv_down += random(1, 3); - screen_reader_speak("Butchered goose. Got 1 meat, feathers, and down.", true); + speak_with_history("Butchered goose. Got 1 meat, feathers, and down.", true); } else if (game_type == "boar carcass") { inv_meat += random(2, 3); inv_skins += 3; inv_sinew += 2; - screen_reader_speak("Butchered boar. Got meat, 3 skins, and 2 sinew.", true); + speak_with_history("Butchered boar. Got meat, 3 skins, and 2 sinew.", true); } else { inv_meat++; inv_skins++; - screen_reader_speak("Butchered " + game_type + ". Got 1 meat and 1 skin.", true); + speak_with_history("Butchered " + game_type + ". Got 1 meat and 1 skin.", true); } // Play sound p.play_stationary("sounds/items/miscellaneous.ogg", false); } else { - screen_reader_speak("Missing: " + missing, true); + speak_with_history("Missing: " + missing, true); } } @@ -1649,20 +1649,20 @@ void butcher_small_game_max() { // Check for knife if (inv_knives < 1) { - screen_reader_speak("Missing: Stone Knife", true); + speak_with_history("Missing: Stone Knife", true); return; } // Check for small game or boar if (inv_small_game < 1 && inv_boar_carcasses < 1) { - screen_reader_speak("Missing: Game", true); + speak_with_history("Missing: Game", true); return; } // Check for fire within 3 tiles (can hear it) WorldFire@ fire = get_fire_within_range(x, 3); if (fire == null) { - screen_reader_speak("You need a fire within 3 tiles to butcher.", true); + speak_with_history("You need a fire within 3 tiles to butcher.", true); return; } @@ -1671,11 +1671,11 @@ void butcher_small_game_max() { int skins_space = get_personal_stack_limit() - inv_skins; if (meat_space <= 0) { - screen_reader_speak("You can't carry any more meat.", true); + speak_with_history("You can't carry any more meat.", true); return; } if (skins_space <= 0) { - screen_reader_speak("You can't carry any more skins.", true); + speak_with_history("You can't carry any more skins.", true); return; } @@ -1688,7 +1688,7 @@ void butcher_small_game_max() { if (skins_space < max_craft) max_craft = skins_space; if (max_craft <= 0) { - screen_reader_speak("No space for outputs.", true); + speak_with_history("No space for outputs.", true); return; } @@ -1748,6 +1748,6 @@ void butcher_small_game_max() { if (total_sinew > 0) result += ", and " + total_sinew + " sinew"; result += "."; - screen_reader_speak(result, true); + speak_with_history(result, true); p.play_stationary("sounds/items/miscellaneous.ogg", false); } diff --git a/src/environment.nvgt b/src/environment.nvgt index c1d47c9..f855cd4 100644 --- a/src/environment.nvgt +++ b/src/environment.nvgt @@ -8,7 +8,7 @@ void apply_falling_damage(int fall_height) { p.play_stationary("sounds/actions/hit_ground.ogg", false); if (fall_height <= SAFE_FALL_HEIGHT) { - screen_reader_speak("Landed safely.", true); + speak_with_history("Landed safely.", true); return; } @@ -23,7 +23,7 @@ void apply_falling_damage(int fall_height) { if (player_health < 0) player_health = 0; // Feedback - screen_reader_speak("Fell " + fall_height + " feet! Took " + damage + " damage. " + player_health + " health remaining.", true); + speak_with_history("Fell " + fall_height + " feet! Took " + damage + " damage. " + player_health + " health remaining.", true); } // Tree Object class Tree { @@ -439,7 +439,7 @@ void damage_tree(int target_x, int damage) { } p.play_stationary("sounds/items/stick.ogg", false); - screen_reader_speak(drop_message, true); + speak_with_history(drop_message, true); } } } @@ -474,24 +474,24 @@ void perform_search(int current_x) if (s != null) { if (s.has_catch) { if (inv_small_game >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more small game.", true); + speak_with_history("You can't carry any more small game.", true); return; } if (inv_snares >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more snares.", true); + speak_with_history("You can't carry any more snares.", true); return; } inv_small_game++; inv_small_game_types.insert_last(s.catch_type); inv_snares++; // Recover snare - screen_reader_speak("Collected " + s.catch_type + " and snare.", true); + speak_with_history("Collected " + s.catch_type + " and snare.", true); } else { if (inv_snares >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more snares.", true); + speak_with_history("You can't carry any more snares.", true); return; } inv_snares++; // Recover snare - screen_reader_speak("Collected snare.", true); + speak_with_history("Collected snare.", true); } p.play_stationary("sounds/items/miscellaneous.ogg", false); remove_snare_at(check_x); @@ -500,7 +500,7 @@ void perform_search(int current_x) } if (random(1, 100) <= 10) { - screen_reader_speak("Found nothing.", true); + speak_with_history("Found nothing.", true); return; } @@ -525,14 +525,14 @@ void perform_search(int current_x) if (inv_reeds < get_personal_stack_limit()) { inv_reeds++; p.play_stationary("sounds/items/stick.ogg", false); - screen_reader_speak("Found a reed.", true); + speak_with_history("Found a reed.", true); return; } } else { if (inv_clay < get_personal_stack_limit()) { inv_clay++; p.play_stationary("sounds/items/clay.ogg", false); - screen_reader_speak("Found clay.", true); + speak_with_history("Found clay.", true); return; } } @@ -540,15 +540,15 @@ void perform_search(int current_x) if (!found_reed && inv_reeds < get_personal_stack_limit()) { inv_reeds++; p.play_stationary("sounds/items/stick.ogg", false); - screen_reader_speak("Found a reed.", true); + speak_with_history("Found a reed.", true); } else if (found_reed && inv_clay < get_personal_stack_limit()) { inv_clay++; p.play_stationary("sounds/items/clay.ogg", false); - screen_reader_speak("Found clay.", true); + speak_with_history("Found clay.", true); } else if (found_reed) { - screen_reader_speak("You can't carry any more reeds.", true); + speak_with_history("You can't carry any more reeds.", true); } else { - screen_reader_speak("You can't carry any more clay.", true); + speak_with_history("You can't carry any more clay.", true); } return; } @@ -573,12 +573,12 @@ void perform_search(int current_x) if(@nearest != null) { if(nearest.is_chopped) { - screen_reader_speak("This tree has been cut down.", true); + speak_with_history("This tree has been cut down.", true); return; } if (nearest.depleted) { - screen_reader_speak("This tree is empty.", true); + speak_with_history("This tree is empty.", true); return; } @@ -592,13 +592,13 @@ void perform_search(int current_x) nearest.sticks--; inv_sticks++; p.play_stationary("sounds/items/stick.ogg", false); - screen_reader_speak("Found a stick.", true); + speak_with_history("Found a stick.", true); took_item = true; } else if (nearest.vines > 0 && inv_vines < get_personal_stack_limit()) { nearest.vines--; inv_vines++; p.play_stationary("sounds/items/vine.ogg", false); - screen_reader_speak("Found a vine.", true); + speak_with_history("Found a vine.", true); took_item = true; } } else { @@ -606,24 +606,24 @@ void perform_search(int current_x) nearest.vines--; inv_vines++; p.play_stationary("sounds/items/vine.ogg", false); - screen_reader_speak("Found a vine.", true); + speak_with_history("Found a vine.", true); took_item = true; } else if (nearest.sticks > 0 && inv_sticks < get_personal_stack_limit()) { nearest.sticks--; inv_sticks++; p.play_stationary("sounds/items/stick.ogg", false); - screen_reader_speak("Found a stick.", true); + speak_with_history("Found a stick.", true); took_item = true; } } if (!took_item) { if (nearest.sticks > 0 && nearest.vines > 0) { - screen_reader_speak("You can't carry any more sticks or vines.", true); + speak_with_history("You can't carry any more sticks or vines.", true); } else if (nearest.sticks > 0) { - screen_reader_speak("You can't carry any more sticks.", true); + speak_with_history("You can't carry any more sticks.", true); } else { - screen_reader_speak("You can't carry any more vines.", true); + speak_with_history("You can't carry any more vines.", true); } return; } @@ -636,27 +636,58 @@ void perform_search(int current_x) } else { - screen_reader_speak("This area has nothing left.", true); + speak_with_history("This area has nothing left.", true); } return; } - // Gravel Area - Stones (20-34) - if (current_x >= 20 && current_x <= 34) + // Stone terrain - check for stones + bool is_stone_terrain = false; + + // Check base gravel area (20-34) + if (current_x >= GRAVEL_START && current_x <= GRAVEL_END) { + is_stone_terrain = true; + } + // Check expanded areas + else if (expanded_area_start != -1 && current_x >= expanded_area_start && current_x <= expanded_area_end) { + // Check for mountain terrain first + MountainRange@ mountain = get_mountain_at(current_x); + if (mountain !is null) { + string terrain = mountain.get_terrain_at(current_x); + if (terrain == "stone" || terrain == "hard_stone") { + is_stone_terrain = true; + } + } else { + // Regular expanded area - check terrain type + int index = current_x - expanded_area_start; + if (index >= 0 && index < int(expanded_terrain_types.length())) { + string terrain = expanded_terrain_types[index]; + // Handle "mountain:terrain" format from older saves + if (terrain.find("mountain:") == 0) { + terrain = terrain.substr(9); + } + if (terrain == "stone" || terrain == "hard_stone") { + is_stone_terrain = true; + } + } + } + } + + if (is_stone_terrain) { if (inv_stones < get_personal_stack_limit()) { inv_stones++; p.play_stationary("sounds/items/stone.ogg", false); - screen_reader_speak("Found a stone.", true); + speak_with_history("Found a stone.", true); } else { - screen_reader_speak("You can't carry any more stones.", true); + speak_with_history("You can't carry any more stones.", true); } return; } - screen_reader_speak("Found nothing.", true); + speak_with_history("Found nothing.", true); } // Climbing functions @@ -669,7 +700,7 @@ void start_climbing_tree(int target_x) { climbing = true; climb_target_y = tree.height; climb_timer.restart(); - screen_reader_speak("Started climbing tree. Height is " + tree.height + " feet.", true); + speak_with_history("Started climbing tree. Height is " + tree.height + " feet.", true); } void update_climbing() { @@ -686,7 +717,7 @@ void update_climbing() { if (y >= climb_target_y) { climbing = false; - screen_reader_speak("Reached the top at " + y + " feet.", true); + speak_with_history("Reached the top at " + y + " feet.", true); } } // Climbing down @@ -697,7 +728,7 @@ void update_climbing() { if (y <= 0) { climbing = false; y = 0; - screen_reader_speak("Safely reached the ground.", true); + speak_with_history("Safely reached the ground.", true); } } } @@ -709,7 +740,7 @@ void climb_down_tree() { climbing = true; climb_target_y = 0; climb_timer.restart(); - screen_reader_speak("Climbing down.", true); + speak_with_history("Climbing down.", true); } void start_falling() { @@ -793,16 +824,16 @@ bool can_move_mountain(int from_x, int to_x) { if (mountain.is_steep_section(from_x, to_x)) { // Need rope if (inv_ropes < 1) { - screen_reader_speak("You'll need a rope to climb there.", true); + speak_with_history("You'll need a rope to climb there.", true); return false; } // Prompt for rope climb int elevation_change = mountain.get_elevation_change(from_x, to_x); if (elevation_change > 0) { - screen_reader_speak("Press up to climb up.", true); + speak_with_history("Press up to climb up.", true); } else { - screen_reader_speak("Press down to climb down.", true); + speak_with_history("Press down to climb down.", true); } // Store pending rope climb info @@ -817,22 +848,40 @@ bool can_move_mountain(int from_x, int to_x) { // Rope climbing functions void start_rope_climb(bool climbing_up, int target_x, int target_elevation) { rope_climbing = true; - rope_climb_up = climbing_up; rope_climb_target_x = target_x; rope_climb_target_y = target_elevation; rope_climb_start_y = y; rope_climb_timer.restart(); - int distance = rope_climb_target_y - y; + // Determine actual climbing direction based on elevation difference + int elevation_diff = target_elevation - y; + if (elevation_diff > 0) { + rope_climb_up = true; + } else if (elevation_diff < 0) { + rope_climb_up = false; + } else { + // Already at target elevation, no climbing needed + rope_climbing = false; + return; + } + + // Calculate distance to climb (use actual distance from current position) + int distance = elevation_diff; if (distance < 0) distance = -distance; - string direction = climbing_up ? "up" : "down"; - screen_reader_speak("Climbing " + direction + ". " + distance + " feet.", true); + string direction = rope_climb_up ? "up" : "down"; + speak_with_history("Climbing " + direction + ". " + distance + " feet.", true); } void update_rope_climbing() { if (!rope_climbing) return; + // Check if we're already at the target (shouldn't happen, but safety check) + if (y == rope_climb_target_y) { + complete_rope_climb(); + return; + } + // Climb at ROPE_CLIMB_SPEED ms per foot if (rope_climb_timer.elapsed > ROPE_CLIMB_SPEED) { rope_climb_timer.restart(); @@ -841,20 +890,24 @@ 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 BEFORE playing the sound if (y >= rope_climb_target_y) { complete_rope_climb(); + } else { + p.play_stationary("sounds/actions/climb_rope.ogg", false); } } } else { // 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 BEFORE playing the sound if (y <= rope_climb_target_y) { complete_rope_climb(); + } else { + p.play_stationary("sounds/actions/climb_rope.ogg", false); } } } @@ -869,7 +922,7 @@ void complete_rope_climb() { // Play footstep for new terrain play_footstep(x, BASE_END, GRASS_END); - screen_reader_speak("Reached elevation " + y + ".", true); + speak_with_history("Reached elevation " + y + ".", true); } void check_rope_climb_fall() { diff --git a/src/flying_creature_template.nvgt b/src/flying_creature_template.nvgt index b49226b..024557e 100644 --- a/src/flying_creature_template.nvgt +++ b/src/flying_creature_template.nvgt @@ -67,5 +67,5 @@ // inv_meat++; // inv_feathers += random(2, 4); // inv_down += random(1, 2); -// screen_reader_speak("Butchered duck. Got 1 meat, feathers, and down.", true); +// speak_with_history("Butchered duck. Got 1 meat, feathers, and down.", true); // } diff --git a/src/inventory_items.nvgt b/src/inventory_items.nvgt index 954b115..93f35c2 100644 --- a/src/inventory_items.nvgt +++ b/src/inventory_items.nvgt @@ -277,18 +277,18 @@ void activate_quick_slot(int slot_index) { int equip_type = quick_slots[slot_index]; if (equip_type < 0) { - screen_reader_speak("No item bound to slot " + slot_index + ".", true); + speak_with_history("No item bound to slot " + slot_index + ".", true); return; } if (!equipment_available(equip_type)) { - screen_reader_speak("Item not available.", true); + speak_with_history("Item not available.", true); return; } equip_equipment_type(equip_type); update_max_health_from_equipment(); - screen_reader_speak(get_equipment_name(equip_type) + " equipped.", true); + speak_with_history(get_equipment_name(equip_type) + " equipped.", true); } void check_quick_slot_keys() { diff --git a/src/inventory_menus.nvgt b/src/inventory_menus.nvgt index b1fda41..5815c34 100644 --- a/src/inventory_menus.nvgt +++ b/src/inventory_menus.nvgt @@ -10,7 +10,7 @@ void check_inventory_keys(int x) { run_inventory_root_menu(); } else { if (in_base && world_storages.length() == 0) { - screen_reader_speak("No storage built.", true); + speak_with_history("No storage built.", true); } run_inventory_menu(false); } @@ -37,7 +37,7 @@ void menu_background_tick() { if (fire_on_tile != null && !jumping && fire_damage_timer.elapsed > 1000) { player_health--; fire_damage_timer.restart(); - screen_reader_speak("Burning! " + player_health + " health remaining.", true); + speak_with_history("Burning! " + player_health + " health remaining.", true); } // Healing in base area @@ -48,13 +48,13 @@ void menu_background_tick() { if (healing_timer.elapsed > heal_interval) { player_health++; healing_timer.restart(); - screen_reader_speak(player_health + " health.", true); + speak_with_history(player_health + " health.", true); } } // Death check if (player_health <= 0) { - screen_reader_speak("You have died.", true); + speak_with_history("You have died.", true); wait(2000); exit(); } @@ -106,11 +106,11 @@ string get_base_fire_status() { void run_base_info_menu() { if (x > BASE_END) { - screen_reader_speak("You are not in the base.", true); + speak_with_history("You are not in the base.", true); return; } - screen_reader_speak("Base info.", true); + speak_with_history("Base info.", true); int selection = 0; string[] options; @@ -143,20 +143,20 @@ void run_base_info_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } } } @@ -200,7 +200,7 @@ void show_character_info() { } info += "Favor " + format_favor(favor) + ". "; info += "Speed " + get_speed_status() + "."; - screen_reader_speak(info, true); + speak_with_history(info, true); } int prompt_transfer_amount(const string prompt, int max_amount) { @@ -236,12 +236,12 @@ void move_small_game_to_personal(int amount) { void deposit_item(int item_type) { int available = get_personal_count(item_type); if (available <= 0) { - screen_reader_speak("Nothing to deposit.", true); + speak_with_history("Nothing to deposit.", true); return; } int capacity = BASE_STORAGE_MAX - get_storage_count(item_type); if (capacity <= 0) { - screen_reader_speak("Storage for that item is full.", true); + speak_with_history("Storage for that item is full.", true); return; } int max_transfer = (available < capacity) ? available : capacity; @@ -277,27 +277,23 @@ void deposit_item(int item_type) { else if (item_type == ITEM_SKIN_POUCHES) { inv_skin_pouches -= amount; storage_skin_pouches += amount; } cleanup_equipment_after_inventory_change(); - screen_reader_speak("Deposited " + amount + " " + get_item_label(item_type) + ".", true); + speak_with_history("Deposited " + amount + " " + get_item_label(item_type) + ".", true); } void deposit_item_max(int item_type) { int available = get_personal_count(item_type); if (available <= 0) { - screen_reader_speak("Nothing to deposit.", true); + speak_with_history("Nothing to deposit.", true); return; } - int storage_total = get_storage_total_items(); - if (storage_total >= BASE_STORAGE_MAX) { - screen_reader_speak("Storage is full.", true); + int capacity = BASE_STORAGE_MAX - get_storage_count(item_type); + if (capacity <= 0) { + speak_with_history("Storage for that item is full.", true); return; } - int capacity = BASE_STORAGE_MAX - storage_total; - int item_storage = get_storage_count(item_type); - int item_capacity = BASE_STORAGE_MAX - item_storage; int amount = (available < capacity) ? available : capacity; - if (amount > item_capacity) amount = item_capacity; if (item_type == ITEM_STICKS) { inv_sticks -= amount; storage_sticks += amount; } else if (item_type == ITEM_VINES) { inv_vines -= amount; storage_vines += amount; } @@ -328,18 +324,18 @@ void deposit_item_max(int item_type) { else if (item_type == ITEM_SKIN_POUCHES) { inv_skin_pouches -= amount; storage_skin_pouches += amount; } cleanup_equipment_after_inventory_change(); - screen_reader_speak("Deposited " + amount + " " + get_item_label(item_type) + ".", true); + speak_with_history("Deposited " + amount + " " + get_item_label(item_type) + ".", true); } void withdraw_item(int item_type) { int available = get_storage_count(item_type); if (available <= 0) { - screen_reader_speak("Nothing to withdraw.", true); + speak_with_history("Nothing to withdraw.", true); return; } int capacity = get_personal_stack_limit() - get_personal_count(item_type); if (capacity <= 0) { - screen_reader_speak("You can't carry any more " + get_item_label(item_type) + ".", true); + speak_with_history("You can't carry any more " + get_item_label(item_type) + ".", true); return; } int max_transfer = (available < capacity) ? available : capacity; @@ -374,13 +370,13 @@ void withdraw_item(int item_type) { else if (item_type == ITEM_MOCCASINS) { storage_moccasins -= amount; inv_moccasins += amount; } else if (item_type == ITEM_SKIN_POUCHES) { storage_skin_pouches -= amount; inv_skin_pouches += amount; } - screen_reader_speak("Withdrew " + amount + " " + get_item_label(item_type) + ".", true); + speak_with_history("Withdrew " + amount + " " + get_item_label(item_type) + ".", true); } void withdraw_item_max(int item_type) { int available = get_storage_count(item_type); if (available <= 0) { - screen_reader_speak("Nothing to withdraw.", true); + speak_with_history("Nothing to withdraw.", true); return; } @@ -389,7 +385,7 @@ void withdraw_item_max(int item_type) { int space = personal_limit - current_personal; if (space <= 0) { - screen_reader_speak("Can't carry any more.", true); + speak_with_history("Can't carry any more.", true); return; } @@ -423,13 +419,13 @@ void withdraw_item_max(int item_type) { else if (item_type == ITEM_MOCCASINS) { storage_moccasins -= amount; inv_moccasins += amount; } else if (item_type == ITEM_SKIN_POUCHES) { storage_skin_pouches -= amount; inv_skin_pouches += amount; } - screen_reader_speak("Withdrew " + amount + " " + get_item_label(item_type) + ".", true); + speak_with_history("Withdrew " + amount + " " + get_item_label(item_type) + ".", true); } void sacrifice_item(int item_type) { int available = get_personal_count(item_type); if (available <= 0) { - screen_reader_speak("Nothing to sacrifice.", true); + speak_with_history("Nothing to sacrifice.", true); return; } @@ -469,13 +465,13 @@ void sacrifice_item(int item_type) { cleanup_equipment_after_inventory_change(); double favor_gain = get_item_favor_value(item_type); favor += favor_gain; - screen_reader_speak("Sacrificed 1 " + get_item_label_singular(item_type) + ". Favor +" + format_favor(favor_gain) + ". Total " + format_favor(favor) + ".", true); + speak_with_history("Sacrificed 1 " + get_item_label_singular(item_type) + ". Favor +" + format_favor(favor_gain) + ". Total " + format_favor(favor) + ".", true); } void sacrifice_item_max(int item_type) { int available = get_personal_count(item_type); if (available <= 0) { - screen_reader_speak("Nothing to sacrifice.", true); + speak_with_history("Nothing to sacrifice.", true); return; } @@ -516,7 +512,7 @@ void sacrifice_item_max(int item_type) { double total_favor = favor_per_item * available; favor += total_favor; - screen_reader_speak("Sacrificed " + available + " " + get_item_label(item_type) + ". Favor +" + format_favor(total_favor) + ". Total " + format_favor(favor) + ".", true); + speak_with_history("Sacrificed " + available + " " + get_item_label(item_type) + ". Favor +" + format_favor(total_favor) + ". Total " + format_favor(favor) + ".", true); } void build_personal_inventory_options(string[]@ options, int[]@ item_types) { @@ -599,11 +595,11 @@ void show_inventory() { info += inv_incense + " incense. "; info += "Tools: " + inv_spears + " spears, " + inv_slings + " slings, " + inv_axes + " axes, " + inv_snares + " snares, " + inv_knives + " knives, " + inv_fishing_poles + " fishing poles, " + inv_ropes + " ropes, " + inv_reed_baskets + " reed baskets, " + inv_clay_pots + " clay pots. "; info += "Clothing: " + inv_skin_hats + " hats, " + inv_skin_gloves + " gloves, " + inv_skin_pants + " pants, " + inv_skin_tunics + " tunics, " + inv_moccasins + " moccasins, " + inv_skin_pouches + " skin pouches."; - screen_reader_speak(info, true); + speak_with_history(info, true); } void run_inventory_root_menu() { - screen_reader_speak("Inventory menu.", true); + speak_with_history("Inventory menu.", true); int selection = 0; string[] options = {"Personal inventory", "Base storage"}; @@ -612,20 +608,20 @@ void run_inventory_root_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { @@ -637,7 +633,7 @@ void run_inventory_root_menu() { } void run_inventory_menu(bool allow_deposit) { - screen_reader_speak("Inventory menu.", true); + speak_with_history("Inventory menu.", true); int selection = 0; string[] options; @@ -648,45 +644,45 @@ void run_inventory_menu(bool allow_deposit) { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (allow_deposit && key_pressed(KEY_RETURN)) { deposit_item(item_types[selection]); build_personal_inventory_options(options, item_types); if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (allow_deposit && key_pressed(KEY_TAB)) { deposit_item_max(item_types[selection]); build_personal_inventory_options(options, item_types); if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } } } void run_storage_menu() { if (world_storages.length() == 0) { - screen_reader_speak("No storage built.", true); + speak_with_history("No storage built.", true); return; } - screen_reader_speak("Base storage.", true); + speak_with_history("Base storage.", true); int selection = 0; string[] options; @@ -697,34 +693,34 @@ void run_storage_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { withdraw_item(item_types[selection]); build_storage_inventory_options(options, item_types); if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_TAB)) { withdraw_item_max(item_types[selection]); build_storage_inventory_options(options, item_types); if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } } } @@ -734,13 +730,13 @@ void check_altar_menu(int player_x) { // Must be in base if (player_x > BASE_END) { - screen_reader_speak("Must be in base to use altar.", true); + speak_with_history("Must be in base to use altar.", true); return; } // Must have altar if (world_altars.length() == 0) { - screen_reader_speak("No altar built.", true); + speak_with_history("No altar built.", true); return; } @@ -748,7 +744,7 @@ void check_altar_menu(int player_x) { } void run_altar_menu() { - screen_reader_speak("Altar. Favor " + format_favor(favor) + ".", true); + speak_with_history("Altar. Favor " + format_favor(favor) + ".", true); int selection = 0; string[] options; @@ -759,34 +755,34 @@ void run_altar_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { sacrifice_item(item_types[selection]); build_personal_inventory_options(options, item_types); if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_TAB)) { sacrifice_item_max(item_types[selection]); build_personal_inventory_options(options, item_types); if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } } } @@ -795,15 +791,15 @@ void try_place_snare(int x) { if (inv_snares > 0) { // Prevent placing if one already exists here if (get_snare_at(x) != null) { - screen_reader_speak("There is already a snare here.", true); + speak_with_history("There is already a snare here.", true); return; } inv_snares--; add_world_snare(x); - screen_reader_speak("Snare set.", true); + speak_with_history("Snare set.", true); } else { - screen_reader_speak("No snares to place.", true); + speak_with_history("No snares to place.", true); } } @@ -811,7 +807,7 @@ void try_feed_fire_stick(WorldFire@ fire) { if (inv_sticks > 0 && fire != null) { inv_sticks--; fire.add_fuel(300000); // 5 minutes - screen_reader_speak("You dump an arm load of sticks into the fire.", true); + speak_with_history("You dump an arm load of sticks into the fire.", true); p.play_stationary("sounds/actions/feed_fire.ogg", false); } } @@ -820,7 +816,7 @@ void try_feed_fire_vine(WorldFire@ fire) { if (inv_vines > 0 && fire != null) { inv_vines--; fire.add_fuel(60000); // 1 minute - screen_reader_speak("You toss a fiew vines and leaves into the fire.", true); + speak_with_history("You toss a fiew vines and leaves into the fire.", true); p.play_stationary("sounds/actions/feed_fire.ogg", false); } } @@ -829,34 +825,34 @@ void try_feed_fire_log(WorldFire@ fire) { if (inv_logs > 0 && fire != null) { inv_logs--; fire.add_fuel(720000); // 12 minutes - screen_reader_speak("You heave a log into the fire.", true); + speak_with_history("You heave a log into the fire.", true); p.play_stationary("sounds/actions/feed_fire.ogg", false); } } void try_burn_incense() { if (world_altars.length() == 0) { - screen_reader_speak("No altar built.", true); + speak_with_history("No altar built.", true); return; } if (inv_clay_pots <= 0) { - screen_reader_speak("You need a clay pot to burn incense.", true); + speak_with_history("You need a clay pot to burn incense.", true); return; } if (inv_incense <= 0) { - screen_reader_speak("No incense to burn.", true); + speak_with_history("No incense to burn.", true); return; } inv_incense--; incense_hours_remaining += INCENSE_HOURS_PER_STICK; incense_burning = true; - screen_reader_speak("Incense burning. " + incense_hours_remaining + " hours remaining.", true); + speak_with_history("Incense burning. " + incense_hours_remaining + " hours remaining.", true); } void try_feed_fire_stick_max(WorldFire@ fire) { if (inv_sticks <= 0 || fire == null) { - screen_reader_speak("No sticks to feed fire.", true); + speak_with_history("No sticks to feed fire.", true); return; } @@ -866,12 +862,12 @@ void try_feed_fire_stick_max(WorldFire@ fire) { fire.add_fuel(fuel_added); p.play_stationary("sounds/actions/feed_fire.ogg", false); - screen_reader_speak("Dumped " + amount + " sticks into the fire.", true); + speak_with_history("Dumped " + amount + " sticks into the fire.", true); } void try_feed_fire_vine_max(WorldFire@ fire) { if (inv_vines <= 0 || fire == null) { - screen_reader_speak("No vines to feed fire.", true); + speak_with_history("No vines to feed fire.", true); return; } @@ -881,12 +877,12 @@ void try_feed_fire_vine_max(WorldFire@ fire) { fire.add_fuel(fuel_added); p.play_stationary("sounds/actions/feed_fire.ogg", false); - screen_reader_speak("Dumped " + amount + " vines into the fire.", true); + speak_with_history("Dumped " + amount + " vines into the fire.", true); } void try_feed_fire_log_max(WorldFire@ fire) { if (inv_logs <= 0 || fire == null) { - screen_reader_speak("No logs to feed fire.", true); + speak_with_history("No logs to feed fire.", true); return; } @@ -896,20 +892,20 @@ void try_feed_fire_log_max(WorldFire@ fire) { fire.add_fuel(fuel_added); p.play_stationary("sounds/actions/feed_fire.ogg", false); - screen_reader_speak("Dumped " + amount + " logs into the fire.", true); + speak_with_history("Dumped " + amount + " logs into the fire.", true); } void try_burn_incense_max() { if (world_altars.length() == 0) { - screen_reader_speak("No altar built.", true); + speak_with_history("No altar built.", true); return; } if (inv_clay_pots <= 0) { - screen_reader_speak("You need a clay pot to burn incense.", true); + speak_with_history("You need a clay pot to burn incense.", true); return; } if (inv_incense <= 0) { - screen_reader_speak("No incense to burn.", true); + speak_with_history("No incense to burn.", true); return; } @@ -921,7 +917,7 @@ void try_burn_incense_max() { incense_hours_remaining += total_hours; incense_burning = true; - screen_reader_speak("Burned " + amount + " incense. +" + total_hours + " hours.", true); + speak_with_history("Burned " + amount + " incense. +" + total_hours + " hours.", true); } void check_equipment_menu() { @@ -930,7 +926,7 @@ void check_equipment_menu() { if (inv_spears == 0 && inv_axes == 0 && inv_slings == 0 && inv_skin_hats == 0 && inv_skin_gloves == 0 && inv_skin_pants == 0 && inv_skin_tunics == 0 && inv_moccasins == 0 && inv_skin_pouches == 0) { - screen_reader_speak("Nothing to equip.", true); + speak_with_history("Nothing to equip.", true); } else { run_equipment_menu(); } @@ -938,7 +934,7 @@ void check_equipment_menu() { } void run_action_menu(int x) { - screen_reader_speak("Action menu.", true); + speak_with_history("Action menu.", true); int selection = 0; string[] options; @@ -976,20 +972,20 @@ void run_action_menu(int x) { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { @@ -1011,7 +1007,7 @@ void run_action_menu(int x) { if (key_pressed(KEY_TAB)) { int action = action_types[selection]; if (action == 0) { - screen_reader_speak("Can't do that.", true); + speak_with_history("Can't do that.", true); } else if (action == 1) { try_feed_fire_stick_max(nearby_fire); } else if (action == 2) { @@ -1027,7 +1023,7 @@ void run_action_menu(int x) { } void run_equipment_menu() { - screen_reader_speak("Equipment menu.", true); + speak_with_history("Equipment menu.", true); int selection = 0; string[] options; @@ -1084,37 +1080,37 @@ void run_equipment_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } int slot_index = get_quick_slot_key(); if (slot_index != -1) { int equip_type = equipment_types[selection]; quick_slots[slot_index] = equip_type; - screen_reader_speak(get_equipment_name(equip_type) + " set to slot " + slot_index + ".", true); + speak_with_history(get_equipment_name(equip_type) + " set to slot " + slot_index + ".", true); } if (key_pressed(KEY_RETURN)) { int equip_type = equipment_types[selection]; if (equipment_is_equipped(equip_type)) { unequip_equipment_type(equip_type); - screen_reader_speak(get_equipment_name(equip_type) + " unequipped.", true); + speak_with_history(get_equipment_name(equip_type) + " unequipped.", true); } else { equip_equipment_type(equip_type); - screen_reader_speak(get_equipment_name(equip_type) + " equipped.", true); + speak_with_history(get_equipment_name(equip_type) + " equipped.", true); } update_max_health_from_equipment(); break; diff --git a/src/notify.nvgt b/src/notify.nvgt index 3e88d6a..728e641 100644 --- a/src/notify.nvgt +++ b/src/notify.nvgt @@ -43,7 +43,7 @@ void update_notifications() { return; // Still playing, wait } // Sound finished, now speak - screen_reader_speak(notification_queue[0], true); + speak_with_history(notification_queue[0], true); notification_queue.remove_at(0); notification_sound_handle = -1; @@ -61,46 +61,46 @@ void check_notification_keys() { // [ for previous notification (older) with position if (key_pressed(KEY_LEFTBRACKET)) { if (notification_history.length() == 0) { - screen_reader_speak("No notifications.", true); + speak_with_history("No notifications.", true); return; } current_notification_index--; if (current_notification_index < 0) { current_notification_index = 0; - screen_reader_speak("Oldest notification.", true); + speak_with_history("Oldest notification. " + notification_history[current_notification_index], true); return; } int position = current_notification_index + 1; - screen_reader_speak(notification_history[current_notification_index] + " " + position + " of " + notification_history.length(), true); + speak_with_history(notification_history[current_notification_index] + " " + position + " of " + notification_history.length(), true); return; } // ] for next notification (newer) with position if (key_pressed(KEY_RIGHTBRACKET)) { if (notification_history.length() == 0) { - screen_reader_speak("No notifications.", true); + speak_with_history("No notifications.", true); return; } current_notification_index++; if (current_notification_index >= notification_history.length()) { current_notification_index = notification_history.length() - 1; - screen_reader_speak("Most recent notification.", true); + speak_with_history("Newest notification. " + notification_history[current_notification_index], true); return; } int position = current_notification_index + 1; - screen_reader_speak(notification_history[current_notification_index] + " " + position + " of " + notification_history.length(), true); + speak_with_history(notification_history[current_notification_index] + " " + position + " of " + notification_history.length(), true); return; } // \ for most recent notification (without position) if (key_pressed(KEY_BACKSLASH)) { if (notification_history.length() == 0) { - screen_reader_speak("No notifications.", true); + speak_with_history("No notifications.", true); return; } current_notification_index = notification_history.length() - 1; - screen_reader_speak(notification_history[current_notification_index], true); + speak_with_history(notification_history[current_notification_index], true); } } diff --git a/src/quest_system.nvgt b/src/quest_system.nvgt index f935309..174238e 100644 --- a/src/quest_system.nvgt +++ b/src/quest_system.nvgt @@ -62,11 +62,11 @@ void attempt_daily_quest() { void check_quest_menu() { if (key_pressed(KEY_Q)) { if (x > BASE_END) { - screen_reader_speak("You are not in the base.", true); + speak_with_history("You are not in the base.", true); return; } if (quest_queue.length() == 0) { - screen_reader_speak("No quests available.", true); + speak_with_history("No quests available.", true); return; } run_quest_menu(); @@ -75,7 +75,7 @@ void check_quest_menu() { void apply_quest_reward(int score) { if (score <= 0) { - screen_reader_speak("No reward earned.", true); + speak_with_history("No reward earned.", true); return; } @@ -97,11 +97,11 @@ void apply_quest_reward(int score) { if (stones_gain > 0) message += " Stones +" + stones_added + "."; if (logs_gain > 0) message += " Logs +" + logs_added + "."; if (skins_gain > 0) message += " Skins +" + skins_added + "."; - screen_reader_speak(message, true); + speak_with_history(message, true); } void run_quest(int quest_type) { - screen_reader_speak(get_quest_description(quest_type), true); + speak_with_history(get_quest_description(quest_type), true); wait(800); p.pause_all(); int score = 0; @@ -113,7 +113,7 @@ void run_quest(int quest_type) { } void run_quest_menu() { - screen_reader_speak("Quest menu.", true); + speak_with_history("Quest menu.", true); int selection = 0; string[] options; @@ -125,20 +125,20 @@ void run_quest_menu() { wait(5); menu_background_tick(); if (key_pressed(KEY_ESCAPE)) { - screen_reader_speak("Closed.", true); + speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { selection++; if (selection >= options.length()) selection = 0; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { selection--; if (selection < 0) selection = options.length() - 1; - screen_reader_speak(options[selection], true); + speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { diff --git a/src/quests/bat_invasion_game.nvgt b/src/quests/bat_invasion_game.nvgt index 6c0ec96..ee3222e 100644 --- a/src/quests/bat_invasion_game.nvgt +++ b/src/quests/bat_invasion_game.nvgt @@ -2,14 +2,14 @@ string[] bat_sounds = {"sounds/quests/bat1.ogg", "sounds/quests/bat2.ogg"}; int run_bat_invasion() { - screen_reader_speak("Bat Invasion. Bats will fly past from left or right. Press space to throw your spear when the bat is centered. Press enter to continue.", true); + speak_with_history("Bat Invasion. Bats will fly past from left or right. Press space to throw your spear when the bat is centered. Press enter to continue.", true); // Wait for enter while (!key_pressed(KEY_RETURN)) { wait(5); } - screen_reader_speak("Starting.", true); + speak_with_history("Starting.", true); wait(500); int turns = 10; @@ -94,6 +94,6 @@ int run_bat_invasion() { wait(400); } - screen_reader_speak("Bat invasion complete. Score " + score + ".", true); + speak_with_history("Bat invasion complete. Score " + score + ".", true); return score; } diff --git a/src/quests/enchanted_melody_game.nvgt b/src/quests/enchanted_melody_game.nvgt index ece2033..214c3a0 100644 --- a/src/quests/enchanted_melody_game.nvgt +++ b/src/quests/enchanted_melody_game.nvgt @@ -20,7 +20,7 @@ int get_note_from_key() { } void run_practice_mode() { - screen_reader_speak("Enchanted Melody. Repeat the magical pattern using F D R E or K J I U, from lowest to highest pitch. Practice the notes now, then press enter to begin, or escape to cancel.", true); + speak_with_history("Enchanted Melody. Repeat the magical pattern using F D R E or K J I U, from lowest to highest pitch. Practice the notes now, then press enter to begin, or escape to cancel.", true); while (true) { wait(5); @@ -52,7 +52,7 @@ int run_enchanted_melody() { return 0; } - screen_reader_speak("Starting. Repeat the pattern.", true); + speak_with_history("Starting. Repeat the pattern.", true); wait(500); int[] pattern; @@ -73,7 +73,7 @@ int run_enchanted_melody() { play_note(note); if (note != pattern[index]) { int score = rounds * 2; - screen_reader_speak("You matched " + rounds + " notes. Score " + score + ".", true); + speak_with_history("You matched " + rounds + " notes. Score " + score + ".", true); return score; } index++; diff --git a/src/quests/escape_from_hel_game.nvgt b/src/quests/escape_from_hel_game.nvgt index bbb7886..09ea5f9 100644 --- a/src/quests/escape_from_hel_game.nvgt +++ b/src/quests/escape_from_hel_game.nvgt @@ -1,13 +1,13 @@ // Escape from Hel quest game int run_escape_from_hel() { - screen_reader_speak("Escape from Hel. You are running from the Draugr, good luck. Press space to jump over open graves as you hear them approach. Press enter to continue.", true); + speak_with_history("Escape from Hel. You are running from the Draugr, good luck. Press space to jump over open graves as you hear them approach. Press enter to continue.", true); // Wait for enter while (!key_pressed(KEY_RETURN)) { wait(5); } - screen_reader_speak("Starting.", true); + speak_with_history("Starting.", true); wait(500); int score = 0; @@ -96,7 +96,7 @@ int run_escape_from_hel() { pit_handle = -1; } p.play_stationary("sounds/quests/fall.ogg", false); - screen_reader_speak("You fell in. Score " + score + ".", true); + speak_with_history("You fell in. Score " + score + ".", true); return score; } diff --git a/src/speech_history.nvgt b/src/speech_history.nvgt new file mode 100644 index 0000000..c66fbba --- /dev/null +++ b/src/speech_history.nvgt @@ -0,0 +1,72 @@ +// Speech History System +// Tracks last 10 unique screen reader announcements for navigation with comma/period + +string[] speech_history; +const int MAX_SPEECH_HISTORY = 10; +int current_speech_index = -1; + +// Main speak function - wrapper around screen_reader_speak with history tracking +void speak_with_history(string message, bool interrupt) { + // Only add to history if not already present (no duplicates) + bool already_exists = false; + for (uint i = 0; i < speech_history.length(); i++) { + if (speech_history[i] == message) { + already_exists = true; + break; + } + } + + // Add to history if not a duplicate + if (!already_exists) { + speech_history.insert_last(message); + + // Keep only last 10 messages + if (speech_history.length() > MAX_SPEECH_HISTORY) { + speech_history.remove_at(0); + } + + // Reset index to most recent + current_speech_index = speech_history.length() - 1; + } + + // Call the built-in screen_reader_speak function + screen_reader_speak(message, interrupt); +} + +void check_speech_history_keys() { + // , (comma) for previous speech message (older) + if (key_pressed(KEY_COMMA)) { + if (speech_history.length() == 0) { + screen_reader_speak("No speech history.", true); + return; + } + + current_speech_index--; + if (current_speech_index < 0) { + current_speech_index = 0; + screen_reader_speak("Oldest message. " + speech_history[current_speech_index], true); + return; + } + int position = current_speech_index + 1; + screen_reader_speak(speech_history[current_speech_index] + " " + position + " of " + speech_history.length(), true); + return; + } + + // . (period) for next speech message (newer) + if (key_pressed(KEY_PERIOD)) { + if (speech_history.length() == 0) { + screen_reader_speak("No speech history.", true); + return; + } + + current_speech_index++; + if (current_speech_index >= speech_history.length()) { + current_speech_index = speech_history.length() - 1; + screen_reader_speak("Newest message. " + speech_history[current_speech_index], true); + return; + } + int position = current_speech_index + 1; + screen_reader_speak(speech_history[current_speech_index] + " " + position + " of " + speech_history.length(), true); + return; + } +} diff --git a/src/time_system.nvgt b/src/time_system.nvgt index 5c6cef0..c124437 100644 --- a/src/time_system.nvgt +++ b/src/time_system.nvgt @@ -305,7 +305,7 @@ void update_blessings() { if (blessing_speed_active && blessing_speed_timer.elapsed >= BLESSING_SPEED_DURATION) { blessing_speed_active = false; update_max_health_from_equipment(); - screen_reader_speak("The speed blessing fades.", true); + speak_with_history("The speed blessing fades.", true); } } @@ -389,7 +389,7 @@ void update_time() { if (storage_meat > 0) { int gained = add_barricade_health(residents_count); if (gained > 0 && x <= BASE_END) { - screen_reader_speak("Residents repaired the barricade. +" + gained + " health.", true); + speak_with_history("Residents repaired the barricade. +" + gained + " health.", true); } } } @@ -432,7 +432,7 @@ void update_incense_burning() { void check_time_input() { if (key_pressed(KEY_T)) { - screen_reader_speak(get_time_string(), true); + speak_with_history(get_time_string(), true); } } diff --git a/src/weather.nvgt b/src/weather.nvgt index 37e9ecc..608d070 100644 --- a/src/weather.nvgt +++ b/src/weather.nvgt @@ -21,6 +21,7 @@ bool rain_fading = false; float rain_fade_from_volume = WEATHER_MIN_VOLUME; float rain_fade_to_volume = WEATHER_MIN_VOLUME; timer rain_fade_timer; +int rain_fade_duration = 0; // Custom duration per fade // Thunder object state class ThunderStrike { @@ -302,6 +303,10 @@ void fade_rain_to_intensity(int new_intensity) { rain_fade_from_volume = get_rain_target_volume(rain_intensity); rain_fade_to_volume = get_rain_target_volume(new_intensity); + // Randomize fade duration: 10-20 seconds for more natural transitions + // Longer fades feel more realistic for rain intensity changes + rain_fade_duration = random(10000, 20000); + // Start rain sound if not playing if (rain_sound_handle == -1 && new_intensity != INTENSITY_NONE) { rain_sound_handle = p.play_stationary(RAIN_SOUND, true); @@ -321,7 +326,7 @@ void update_rain_fade() { return; } - float progress = float(rain_fade_timer.elapsed) / float(WEATHER_FADE_DURATION); + float progress = float(rain_fade_timer.elapsed) / float(rain_fade_duration); if (progress > 1.0) progress = 1.0; float current_vol = rain_fade_from_volume + ((rain_fade_to_volume - rain_fade_from_volume) * progress); @@ -375,24 +380,37 @@ void spawn_thunder() { // Spawn thunder at random distance from player int distance = random(THUNDER_SPAWN_DISTANCE_MIN, THUNDER_SPAWN_DISTANCE_MAX); - - // Determine movement: 20% stationary, 80% moving + + // Determine movement: 20% stationary, 80% moving (randomly toward or away from player) int direction = 0; if (random(1, 100) > 20) { - direction = random(0, 1) == 0 ? -1 : 1; - } - - // Random speed: 50ms (fast rip) to 600ms (slow roll) - int speed = random(50, 600); + // Thunder moves in random direction - may move toward or away from player + int spawn_direction = random(0, 1) == 0 ? -1 : 1; + direction = spawn_direction; // Movement direction matches spawn side + int thunder_pos = x + (distance * spawn_direction); - int thunder_pos = x + (distance * ((direction == 0) ? (random(0, 1) == 0 ? -1 : 1) : direction)); + // Random speed: 100ms (fast rip) to 1200ms (slow roll) - halved from original + int speed = random(100, 1200); - // Play sound at position with custom volume step - int handle = play_1d_with_volume_step(thunder_file, x, thunder_pos, false, THUNDER_SOUND_VOLUME_STEP); + // Play sound at position with custom volume step + int handle = play_1d_with_volume_step(thunder_file, x, thunder_pos, false, THUNDER_SOUND_VOLUME_STEP); - if (handle != -1) { - ThunderStrike@ strike = ThunderStrike(thunder_pos, direction, handle, speed); - active_thunder.insert_last(strike); + if (handle != -1) { + ThunderStrike@ strike = ThunderStrike(thunder_pos, direction, handle, speed); + active_thunder.insert_last(strike); + } + } else { + // Stationary thunder - randomly place on either side + int spawn_side = random(0, 1) == 0 ? -1 : 1; + int thunder_pos = x + (distance * spawn_side); + + // Play sound at position with custom volume step + int handle = play_1d_with_volume_step(thunder_file, x, thunder_pos, false, THUNDER_SOUND_VOLUME_STEP); + + if (handle != -1) { + ThunderStrike@ strike = ThunderStrike(thunder_pos, 0, handle, 0); + active_thunder.insert_last(strike); + } } } diff --git a/src/world_state.nvgt b/src/world_state.nvgt index 7c71dda..2b19ea0 100644 --- a/src/world_state.nvgt +++ b/src/world_state.nvgt @@ -271,12 +271,12 @@ void clear_world_drops() { bool try_pickup_small_game(string game_type) { if (inv_small_game >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more small game.", true); + speak_with_history("You can't carry any more small game.", true); return false; } inv_small_game++; inv_small_game_types.insert_last(game_type); - screen_reader_speak("Picked up " + game_type + ".", true); + speak_with_history("Picked up " + game_type + ".", true); return true; } @@ -286,14 +286,14 @@ bool try_pickup_world_drop(WorldDrop@ drop) { } if (drop.type == "boar carcass") { if (inv_boar_carcasses >= get_personal_stack_limit()) { - screen_reader_speak("You can't carry any more boar carcasses.", true); + speak_with_history("You can't carry any more boar carcasses.", true); return false; } inv_boar_carcasses++; - screen_reader_speak("Picked up boar carcass.", true); + speak_with_history("Picked up boar carcass.", true); return true; } - screen_reader_speak("Picked up " + drop.type + ".", true); + speak_with_history("Picked up " + drop.type + ".", true); return true; } @@ -676,9 +676,9 @@ void check_snare_collision(int player_x) { p.play_stationary("sounds/actions/break_snare.ogg", false); if (s.has_catch) { - screen_reader_speak("You stepped on your snare! The " + s.catch_type + " escaped.", true); + speak_with_history("You stepped on your snare! The " + s.catch_type + " escaped.", true); } else { - screen_reader_speak("You stepped on your snare and broke it!", true); + speak_with_history("You stepped on your snare and broke it!", true); } remove_snare_at(player_x); @@ -848,7 +848,7 @@ void try_attack_barricade(Zombie@ zombie) { if (counterDamage > 0) { zombie.health -= counterDamage; if (zombie.health <= 0 && x <= BASE_END) { - screen_reader_speak("Residents killed an attacking zombie.", true); + speak_with_history("Residents killed an attacking zombie.", true); } } } @@ -994,6 +994,12 @@ WorldHerbGarden@ get_herb_garden_at_base() { void clear_bandits() { if (bandits.length() == 0) return; + for (uint i = 0; i < bandits.length(); i++) { + if (bandits[i].sound_handle != -1) { + p.destroy_sound(bandits[i].sound_handle); + bandits[i].sound_handle = -1; + } + } bandits.resize(0); } @@ -1271,7 +1277,7 @@ void try_attack_barricade_bandit(Bandit@ bandit) { if (counterDamage > 0) { bandit.health -= counterDamage; if (bandit.health <= 0 && x <= BASE_END) { - screen_reader_speak("Residents killed an attacking bandit.", true); + speak_with_history("Residents killed an attacking bandit.", true); } } } @@ -1394,7 +1400,6 @@ bool damage_bandit_at(int pos, int damage) { } play_creature_death_sound("sounds/enemies/enemy_falls.ogg", x, pos, BANDIT_SOUND_VOLUME_STEP); bandits.remove_at(i); - } else { } return true; } @@ -1444,9 +1449,9 @@ class MountainRange { void generate_terrain() { int size = int(elevations.length()); - // Initialize endpoints at moderate elevations - elevations[0] = random(5, 15); - elevations[size - 1] = random(5, 15); + // Initialize endpoints at low elevations (easier transition from flat ground) + elevations[0] = random(0, 5); + elevations[size - 1] = random(0, 5); // Use midpoint displacement for natural terrain midpoint_displace(0, size - 1, 25); @@ -1460,11 +1465,14 @@ class MountainRange { // Smooth to enforce max slope constraint smooth_slopes(); + // Ensure at least one steep climb (≥7 feet) reaches into 10-20 elevation range + ensure_steep_climb(); + // Assign terrain types based on elevation for (int i = 0; i < size; i++) { - if (elevations[i] > 30) { + if (elevations[i] > 20) { terrain_types[i] = "snow"; - } else if (elevations[i] > 15) { + } else if (elevations[i] > 8) { terrain_types[i] = "stone"; } else { terrain_types[i] = "gravel"; @@ -1531,6 +1539,82 @@ class MountainRange { } } + void ensure_steep_climb() { + int size = int(elevations.length()); + + // Check if we already have a steep climb (≥7) to/from 10-20 elevation + bool has_steep_climb = false; + for (int i = 1; i < size; i++) { + int diff = elevations[i] - elevations[i-1]; + if (diff < 0) diff = -diff; + + if (diff >= MOUNTAIN_STEEP_THRESHOLD) { + // Check if either elevation is in 10-20 range + if ((elevations[i] >= 10 && elevations[i] <= 20) || + (elevations[i-1] >= 10 && elevations[i-1] <= 20)) { + has_steep_climb = true; + break; + } + } + } + + // If no steep climb to 10-20 range, create one + if (!has_steep_climb && size >= 10) { + // Pick a random position in the middle 60% of the mountain + int pos = random(int(size * 0.2), int(size * 0.8)); + + // Set up a steep climb: create elevation 15-18 with steep approach + int target_elevation = random(15, 18); + elevations[pos] = target_elevation; + + // Make the approach from left steep (if possible) + if (pos > 0) { + elevations[pos - 1] = target_elevation - MOUNTAIN_STEEP_THRESHOLD - 1; + if (elevations[pos - 1] < MOUNTAIN_MIN_ELEVATION) { + elevations[pos - 1] = MOUNTAIN_MIN_ELEVATION; + } + } + + // Make the approach from right steep (if possible) + if (pos < size - 1) { + elevations[pos + 1] = target_elevation - MOUNTAIN_STEEP_THRESHOLD - 1; + if (elevations[pos + 1] < MOUNTAIN_MIN_ELEVATION) { + elevations[pos + 1] = MOUNTAIN_MIN_ELEVATION; + } + } + + // Re-smooth to ensure slopes aren't too extreme elsewhere + smooth_slopes(); + } + + // Ensure edge transitions aren't too steep (max 20 feet from flat ground) + // First transition: tile 0 to tile 1 + if (size >= 2) { + int first_diff = elevations[1] - elevations[0]; + if (first_diff < 0) first_diff = -first_diff; + if (first_diff > 20) { + if (elevations[1] > elevations[0]) { + elevations[1] = elevations[0] + 20; + } else { + elevations[1] = elevations[0] - 20; + } + } + } + + // Last transition: tile size-2 to tile size-1 + if (size >= 2) { + int last_diff = elevations[size-1] - elevations[size-2]; + if (last_diff < 0) last_diff = -last_diff; + if (last_diff > 20) { + if (elevations[size-2] > elevations[size-1]) { + elevations[size-2] = elevations[size-1] + 20; + } else { + elevations[size-2] = elevations[size-1] - 20; + } + } + } + } + int get_elevation_at(int world_x) { if (world_x < start_position || world_x > end_position) return 0; int index = world_x - start_position;