From 942cbfd011b2b87192f49fd7daa623d9a5b5c94f Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sun, 8 Feb 2026 14:10:02 -0500 Subject: [PATCH] Finally got around to returning to menu on death or exit. I shouldn't have put this off for so long, was painful. Also quest system future proofed if I decide to add anything that might cause death in one of them. --- draugnorak.nvgt | 716 +++++++++++++++-------------- src/crafting/craft_barricade.nvgt | 4 +- src/crafting/craft_buildings.nvgt | 4 +- src/crafting/craft_clothing.nvgt | 4 +- src/crafting/craft_materials.nvgt | 4 +- src/crafting/craft_runes.nvgt | 8 +- src/crafting/craft_tools.nvgt | 4 +- src/crafting/craft_weapons.nvgt | 4 +- src/crafting/crafting_core.nvgt | 8 +- src/fylgja_system.nvgt | 4 +- src/menus/action_menu.nvgt | 4 +- src/menus/altar_menu.nvgt | 4 +- src/menus/base_info.nvgt | 4 +- src/menus/equipment_menu.nvgt | 4 +- src/menus/inventory_core.nvgt | 8 +- src/menus/menu_utils.nvgt | 12 +- src/menus/storage_menu.nvgt | 4 +- src/player.nvgt | 1 + src/quest_system.nvgt | 12 +- src/quests/skeletal_bard_game.nvgt | 10 +- 20 files changed, 446 insertions(+), 377 deletions(-) diff --git a/draugnorak.nvgt b/draugnorak.nvgt index fe3a4f4..f473204 100755 --- a/draugnorak.nvgt +++ b/draugnorak.nvgt @@ -90,400 +90,412 @@ void run_game() init_item_registry(); init_search_pools(); - bool game_started = false; - while (!game_started) { - int selection = run_main_menu(); + while (true) { + bool game_started = false; + while (!game_started) { + int selection = run_main_menu(); - if (selection == 0) { - if (!setup_new_character()) { - continue; - } - start_new_game(); - speak_with_history("New game started.", true); - game_started = true; - } else if (selection == 1) { - if (!has_save_game()) { - ui_info_box("Draugnorak", "Load Game", "No saves found."); - continue; - } - string selectedFile; - if (!select_save_file(selectedFile)) { - continue; - } - if (load_game_state_from_file(selectedFile)) { - speak_with_history("Game loaded.", true); + if (selection == 0) { + if (!setup_new_character()) { + continue; + } + start_new_game(); + speak_with_history("New game started.", true); game_started = true; + } else if (selection == 1) { + if (!has_save_game()) { + ui_info_box("Draugnorak", "Load Game", "No saves found."); + continue; + } + string selectedFile; + if (!select_save_file(selectedFile)) { + continue; + } + if (load_game_state_from_file(selectedFile)) { + speak_with_history("Game loaded.", true); + game_started = true; + } else { + string message = last_save_error; + if (message == "") message = "Unable to load save."; + ui_info_box("Draugnorak", "Load Game", message); + } } else { - string message = last_save_error; - if (message == "") message = "Unable to load save."; - ui_info_box("Draugnorak", "Load Game", message); + exit(); } - } else { - exit(); } - } - while(true) - { - wait(5); - - // Pause toggle - if(key_pressed(KEY_BACK)) - { - game_paused = !game_paused; - if (game_paused) { - p.pause_all(); - speak_with_history("Paused. Press backspace to resume.", true); - } else { + while (game_started) { + wait(5); + + if (return_to_main_menu_requested) { + game_paused = false; + menuBackgroundUpdatesEnabled = true; p.resume_all(); - // Restart all timers to prevent time from accumulating while paused - restart_all_timers(); - speak_with_history("Resumed.", true); + reset_game_state(); + return_to_main_menu_requested = false; + break; } - continue; - } - - // Skip all game logic while paused - if (game_paused) { - continue; - } - + + // Pause toggle + if(key_pressed(KEY_BACK)) + { + game_paused = !game_paused; + if (game_paused) { + p.pause_all(); + speak_with_history("Paused. Press backspace to resume.", true); + } else { + p.resume_all(); + // Restart all timers to prevent time from accumulating while paused + restart_all_timers(); + speak_with_history("Resumed.", true); + } + continue; + } + + // Skip all game logic while paused + if (game_paused) { + continue; + } + if(key_pressed(KEY_ESCAPE)) { int really_exit = ui_question("", "Really exit?"); if (really_exit == 1) { - exit(); + return_to_main_menu_requested = true; + continue; } } - - // Time & Environment updates - update_time(); - update_crossfade(); - update_weather(); - update_environment(); - update_snares(); - update_streams(); - update_fires(); - update_zombies(); - update_bandits(); - update_boars(); - update_flying_creatures(); - update_weapon_range_audio_all(); - update_world_drops(); - update_blessings(); - update_notifications(); - - // Fire damage check (only if not jumping) - WorldFire@ fire_on_tile = get_fire_at(x); - if (fire_on_tile != null && !jumping && fire_damage_timer.elapsed > 1000) { - player_health--; - fire_damage_timer.restart(); - speak_with_history("Burning! " + player_health + " health remaining.", true); - } - - // Healing in base area - if (x <= BASE_END && player_health < max_health) { - WorldHerbGarden@ herb_garden = get_herb_garden_at_base(); - int heal_interval = (herb_garden != null) ? 30000 : 150000; // 30 seconds with garden, 2.5 minutes without - - if (healing_timer.elapsed > heal_interval) { - player_health++; - healing_timer.restart(); - speak_with_history(player_health + " health.", true); + + // Time & Environment updates + update_time(); + update_crossfade(); + update_weather(); + update_environment(); + update_snares(); + update_streams(); + update_fires(); + update_zombies(); + update_bandits(); + update_boars(); + update_flying_creatures(); + update_weapon_range_audio_all(); + update_world_drops(); + update_blessings(); + update_notifications(); + + // Fire damage check (only if not jumping) + WorldFire@ fire_on_tile = get_fire_at(x); + if (fire_on_tile != null && !jumping && fire_damage_timer.elapsed > 1000) { + player_health--; + fire_damage_timer.restart(); + speak_with_history("Burning! " + player_health + " health remaining.", true); } - } - - // Death check - if (player_health <= 0) { - if (!try_consume_heal_scroll()) { - speak_with_history("You have died.", true); - wait(2000); - exit(); - } - } - - if (fylgjaCharging) { - update_fylgja_charge(); - continue; - } - - // Inventory & Actions - check_inventory_keys(x); - check_action_menu(x); - check_adventure_menu(x); - check_crafting_menu(x, BASE_END); - check_altar_menu(x); - check_equipment_menu(); - check_quest_menu(); - check_fylgja_menu(); - check_quick_slot_keys(); - check_time_input(); - check_notification_keys(); - check_speech_history_keys(); - - // Health Key - if (key_pressed(KEY_H)) { - 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 = get_terrain_at_position(x); - if (get_mountain_at(x) !is null) { - terrain += ". Mountains"; - } - speak_with_history(direction_label + ", x " + x + ", y " + y + ", terrain " + terrain, true); - } - - // Base Info Key (base only) - if (key_pressed(KEY_B)) { - run_base_info_menu(); - } - - // Climbing and Falling Updates - update_climbing(); - update_falling(); - update_rope_climbing(); - check_rope_climb_fall(); - update_mountains(); - - // Down arrow to climb down from tree or start rope climb down - if (key_pressed(KEY_DOWN)) { - // Check for pending rope climb (going down) - if (pending_rope_climb_x != -1 && !rope_climbing && !climbing && !falling && !jumping) { - int elevation_change = pending_rope_climb_elevation - y; - if (elevation_change < 0) { - start_rope_climb(false, pending_rope_climb_x, pending_rope_climb_elevation); - pending_rope_climb_x = -1; + + // Healing in base area + if (x <= BASE_END && player_health < max_health) { + WorldHerbGarden@ herb_garden = get_herb_garden_at_base(); + int heal_interval = (herb_garden != null) ? 30000 : 150000; // 30 seconds with garden, 2.5 minutes without + + if (healing_timer.elapsed > heal_interval) { + player_health++; + healing_timer.restart(); + speak_with_history(player_health + " health.", true); } } - // Tree climbing down - else { - Tree@ tree = get_tree_at(x); - if (tree != null && !tree.is_chopped && y > 0 && !jumping && !climbing && !falling && !rope_climbing) { - climb_down_tree(); + + // Death check + if (player_health <= 0) { + if (!try_consume_heal_scroll()) { + speak_with_history("You have died.", true); + wait(2000); + return_to_main_menu_requested = true; + continue; } } - } - - // Jumping Logic - if(key_pressed(KEY_UP)) - { - // Check for pending rope climb (going up) - if (pending_rope_climb_x != -1 && !rope_climbing && !climbing && !falling && !jumping) { - int elevation_change = pending_rope_climb_elevation - y; - if (elevation_change > 0) { - start_rope_climb(true, pending_rope_climb_x, pending_rope_climb_elevation); - pending_rope_climb_x = -1; + + if (fylgjaCharging) { + update_fylgja_charge(); + continue; + } + + // Inventory & Actions + check_inventory_keys(x); + check_action_menu(x); + check_adventure_menu(x); + check_crafting_menu(x, BASE_END); + check_altar_menu(x); + check_equipment_menu(); + check_quest_menu(); + check_fylgja_menu(); + check_quick_slot_keys(); + check_time_input(); + check_notification_keys(); + check_speech_history_keys(); + + // Health Key + if (key_pressed(KEY_H)) { + 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 = get_terrain_at_position(x); + if (get_mountain_at(x) !is null) { + terrain += ". Mountains"; + } + speak_with_history(direction_label + ", x " + x + ", y " + y + ", terrain " + terrain, true); + } + + // Base Info Key (base only) + if (key_pressed(KEY_B)) { + run_base_info_menu(); + } + + // Climbing and Falling Updates + update_climbing(); + update_falling(); + update_rope_climbing(); + check_rope_climb_fall(); + update_mountains(); + + // Down arrow to climb down from tree or start rope climb down + if (key_pressed(KEY_DOWN)) { + // Check for pending rope climb (going down) + if (pending_rope_climb_x != -1 && !rope_climbing && !climbing && !falling && !jumping) { + int elevation_change = pending_rope_climb_elevation - y; + if (elevation_change < 0) { + start_rope_climb(false, pending_rope_climb_x, pending_rope_climb_elevation); + pending_rope_climb_x = -1; + } + } + // Tree climbing down + else { + Tree@ tree = get_tree_at(x); + if (tree != null && !tree.is_chopped && y > 0 && !jumping && !climbing && !falling && !rope_climbing) { + climb_down_tree(); + } } } - else if(!jumping && !climbing && !falling && !rope_climbing) + + // Jumping Logic + if(key_pressed(KEY_UP)) { - // 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 == ground_elevation) { - // Start climbing the tree - start_climbing_tree(x); - } else if (y == ground_elevation) { - // Normal jump (only if on the ground) - p.play_stationary("sounds/jump.ogg", false); - jumping = true; - jumptimer.restart(); + // Check for pending rope climb (going up) + if (pending_rope_climb_x != -1 && !rope_climbing && !climbing && !falling && !jumping) { + int elevation_change = pending_rope_climb_elevation - y; + if (elevation_change > 0) { + start_rope_climb(true, pending_rope_climb_x, pending_rope_climb_elevation); + pending_rope_climb_x = -1; + } + } + 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 == ground_elevation) { + // Start climbing the tree + start_climbing_tree(x); + } else if (y == ground_elevation) { + // Normal jump (only if on the ground) + p.play_stationary("sounds/jump.ogg", false); + jumping = true; + jumptimer.restart(); + } } } - } - - if(jumping && jumptimer.elapsed > 850) - { - jumping = false; - // 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 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; - - bool left_active = key_down(KEY_LEFT); - bool right_active = key_down(KEY_RIGHT); - - // Movement Logic - if (key_pressed(KEY_LEFT) && facing != 0 && !climbing && !falling && !rope_climbing) { - facing = 0; - 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; - speak_with_history("east", true); - walktimer.restart(); - // Cancel pending rope climb when changing direction - pending_rope_climb_x = -1; - } - - if(walktimer.elapsed > movetime) - { - int old_x = x; - - // Check if trying to move left/right while in tree (not in mountain) - MountainRange@ current_mountain = get_mountain_at(x); - Tree@ current_tree = get_tree_at(x); - int ground_elevation = get_mountain_elevation_at(x); - if((left_active || right_active) && y > ground_elevation && !jumping && !falling && !rope_climbing && current_mountain is null && current_tree !is null) { - // Fall out of tree - climbing = false; - start_falling(); - } - - if(left_active && x > 0 && !climbing && !falling && !rope_climbing) + + if(jumping && jumptimer.elapsed > 850) { + jumping = false; + // 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 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; + + bool left_active = key_down(KEY_LEFT); + bool right_active = key_down(KEY_RIGHT); + + // Movement Logic + if (key_pressed(KEY_LEFT) && facing != 0 && !climbing && !falling && !rope_climbing) { facing = 0; - int target_x = x - 1; - // Check mountain movement and deep water - if (can_move_mountain(x, target_x) && can_enter_stream_tile(target_x)) { - x = target_x; - // Always update elevation to match ground (0 if not in mountain) - int new_elevation = get_mountain_elevation_at(x); - if (new_elevation != y) { - y = new_elevation; - } - walktimer.restart(); - if(!jumping) { - play_footstep(x, BASE_END, GRASS_END); - check_snare_collision(x); - } - } + speak_with_history("west", true); + walktimer.restart(); + // Cancel pending rope climb when changing direction + pending_rope_climb_x = -1; } - else if(right_active && x < MAP_SIZE - 1 && !climbing && !falling && !rope_climbing) - { + if (key_pressed(KEY_RIGHT) && facing != 1 && !climbing && !falling && !rope_climbing) { facing = 1; - int target_x = x + 1; - // Check mountain movement and deep water - if (can_move_mountain(x, target_x) && can_enter_stream_tile(target_x)) { - x = target_x; - // Always update elevation to match ground (0 if not in mountain) - int new_elevation = get_mountain_elevation_at(x); - if (new_elevation != y) { - y = new_elevation; + speak_with_history("east", true); + walktimer.restart(); + // Cancel pending rope climb when changing direction + pending_rope_climb_x = -1; + } + + if(walktimer.elapsed > movetime) + { + int old_x = x; + + // Check if trying to move left/right while in tree (not in mountain) + MountainRange@ current_mountain = get_mountain_at(x); + Tree@ current_tree = get_tree_at(x); + int ground_elevation = get_mountain_elevation_at(x); + if((left_active || right_active) && y > ground_elevation && !jumping && !falling && !rope_climbing && current_mountain is null && current_tree !is null) { + // Fall out of tree + climbing = false; + start_falling(); + } + + if(left_active && x > 0 && !climbing && !falling && !rope_climbing) + { + facing = 0; + int target_x = x - 1; + // Check mountain movement and deep water + if (can_move_mountain(x, target_x) && can_enter_stream_tile(target_x)) { + x = target_x; + // Always update elevation to match ground (0 if not in mountain) + int new_elevation = get_mountain_elevation_at(x); + if (new_elevation != y) { + y = new_elevation; + } + walktimer.restart(); + if(!jumping) { + play_footstep(x, BASE_END, GRASS_END); + check_snare_collision(x); + } } - walktimer.restart(); - if(!jumping) { - play_footstep(x, BASE_END, GRASS_END); - check_snare_collision(x); + } + else if(right_active && x < MAP_SIZE - 1 && !climbing && !falling && !rope_climbing) + { + facing = 1; + int target_x = x + 1; + // Check mountain movement and deep water + if (can_move_mountain(x, target_x) && can_enter_stream_tile(target_x)) { + x = target_x; + // Always update elevation to match ground (0 if not in mountain) + int new_elevation = get_mountain_elevation_at(x); + if (new_elevation != y) { + y = new_elevation; + } + walktimer.restart(); + if(!jumping) { + play_footstep(x, BASE_END, GRASS_END); + check_snare_collision(x); + } } } } - } - - // Reset search timer if shift is used with other keys - if((key_down(KEY_LSHIFT) || key_down(KEY_RSHIFT))) { - if(key_pressed(KEY_COMMA) || key_pressed(KEY_PERIOD)) { - searching = false; + + // Reset search timer if shift is used with other keys + if((key_down(KEY_LSHIFT) || key_down(KEY_RSHIFT))) { + if(key_pressed(KEY_COMMA) || key_pressed(KEY_PERIOD)) { + searching = false; + search_delay_timer.restart(); + } + } + + // Searching Logic + bool shift_down = (key_down(KEY_LSHIFT) || key_down(KEY_RSHIFT)); + bool search_key_down = shift_down || key_down(KEY_SLASH) || key_down(KEY_Z); + if (!search_key_down && !searching) { + search_timer.restart(); + } + // Apply rune gathering bonus to search time + int search_time = apply_rune_gather_bonus(2000); + if (search_key_down && search_timer.elapsed > search_time && !searching) + { + searching = true; search_delay_timer.restart(); } - } - - // Searching Logic - bool shift_down = (key_down(KEY_LSHIFT) || key_down(KEY_RSHIFT)); - bool search_key_down = shift_down || key_down(KEY_SLASH) || key_down(KEY_Z); - if (!search_key_down && !searching) { - search_timer.restart(); - } - // Apply rune gathering bonus to search time - int search_time = apply_rune_gather_bonus(2000); - if (search_key_down && search_timer.elapsed > search_time && !searching) - { - searching = true; - search_delay_timer.restart(); - } - - // Complete search after delay - if(searching && search_delay_timer.elapsed >= 1000) - { - searching = false; - search_timer.restart(); - perform_search(x); - } - - update_fishing(); - update_bow_shot(); - - bool ctrl_down = (key_down(KEY_LCTRL) || key_down(KEY_RCTRL)); - - // Bow draw detection - if (bow_equipped) { - if (ctrl_down && !bow_drawing) { - if (get_personal_count(ITEM_ARROWS) > 0) { - bow_drawing = true; - bow_draw_timer.restart(); - p.play_stationary("sounds/weapons/bow_draw.ogg", false); - } else { - speak_ammo_blocked("No arrows."); + + // Complete search after delay + if(searching && search_delay_timer.elapsed >= 1000) + { + searching = false; + search_timer.restart(); + perform_search(x); + } + + update_fishing(); + update_bow_shot(); + + bool ctrl_down = (key_down(KEY_LCTRL) || key_down(KEY_RCTRL)); + + // Bow draw detection + if (bow_equipped) { + if (ctrl_down && !bow_drawing) { + if (get_personal_count(ITEM_ARROWS) > 0) { + bow_drawing = true; + bow_draw_timer.restart(); + p.play_stationary("sounds/weapons/bow_draw.ogg", false); + } else { + speak_ammo_blocked("No arrows."); + } + } + + if (bow_drawing && !ctrl_down) { + release_bow_attack(x); + bow_drawing = false; } } - - if (bow_drawing && !ctrl_down) { - release_bow_attack(x); + if (!bow_equipped && bow_drawing) { bow_drawing = false; } - } - if (!bow_equipped && bow_drawing) { - bow_drawing = false; - } - - // Sling charge detection - if (!bow_equipped && sling_equipped && ctrl_down && !sling_charging) { - if (get_personal_count(ITEM_STONES) > 0) { - sling_charging = true; - sling_charge_timer.restart(); - sling_sound_handle = p.play_stationary("sounds/weapons/sling_swing.ogg", true); - last_sling_stage = -1; - } else { - speak_ammo_blocked("No stones."); + + // Sling charge detection + if (!bow_equipped && sling_equipped && ctrl_down && !sling_charging) { + if (get_personal_count(ITEM_STONES) > 0) { + sling_charging = true; + sling_charge_timer.restart(); + sling_sound_handle = p.play_stationary("sounds/weapons/sling_swing.ogg", true); + last_sling_stage = -1; + } else { + speak_ammo_blocked("No stones."); + } } - } - - // Update sling charge state while holding - if (sling_charging && ctrl_down) { - update_sling_charge(); - } - - // Sling release detection - if (sling_charging && !ctrl_down) { - release_sling_attack(x); - sling_charging = false; - if (sling_sound_handle != -1) { - p.destroy_sound(sling_sound_handle); - sling_sound_handle = -1; + + // Update sling charge state while holding + if (sling_charging && ctrl_down) { + update_sling_charge(); } - } - - // Non-sling weapon attacks (existing pattern) - if (!bow_equipped && !bow_drawing && !sling_equipped && !sling_charging) { - int attack_cooldown = 1000; - if (spear_equipped) attack_cooldown = 800; - if (axe_equipped) attack_cooldown = 1600; - - if (!fishing_pole_equipped && ctrl_down && attack_timer.elapsed > attack_cooldown) { - attack_timer.restart(); - perform_attack(x); + + // Sling release detection + if (sling_charging && !ctrl_down) { + release_sling_attack(x); + sling_charging = false; + if (sling_sound_handle != -1) { + p.destroy_sound(sling_sound_handle); + sling_sound_handle = -1; + } } + + // Non-sling weapon attacks (existing pattern) + if (!bow_equipped && !bow_drawing && !sling_equipped && !sling_charging) { + int attack_cooldown = 1000; + if (spear_equipped) attack_cooldown = 800; + if (axe_equipped) attack_cooldown = 1600; + + if (!fishing_pole_equipped && ctrl_down && attack_timer.elapsed > attack_cooldown) { + attack_timer.restart(); + perform_attack(x); + } + } + + // Audio Listener Update + p.update_listener_1d(x); } - - // Audio Listener Update - p.update_listener_1d(x); } } diff --git a/src/crafting/craft_barricade.nvgt b/src/crafting/craft_barricade.nvgt index 0d30b85..018987a 100644 --- a/src/crafting/craft_barricade.nvgt +++ b/src/crafting/craft_barricade.nvgt @@ -35,7 +35,9 @@ void run_barricade_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/crafting/craft_buildings.nvgt b/src/crafting/craft_buildings.nvgt index 5313375..5982a85 100644 --- a/src/crafting/craft_buildings.nvgt +++ b/src/crafting/craft_buildings.nvgt @@ -98,7 +98,9 @@ void run_buildings_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/crafting/craft_clothing.nvgt b/src/crafting/craft_clothing.nvgt index d99144e..a2b5961 100644 --- a/src/crafting/craft_clothing.nvgt +++ b/src/crafting/craft_clothing.nvgt @@ -58,7 +58,9 @@ void run_clothing_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/crafting/craft_materials.nvgt b/src/crafting/craft_materials.nvgt index bdaa57d..f1a1ee1 100644 --- a/src/crafting/craft_materials.nvgt +++ b/src/crafting/craft_materials.nvgt @@ -13,7 +13,9 @@ void run_materials_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/crafting/craft_runes.nvgt b/src/crafting/craft_runes.nvgt index c7d0705..c481db1 100644 --- a/src/crafting/craft_runes.nvgt +++ b/src/crafting/craft_runes.nvgt @@ -98,7 +98,9 @@ void run_runes_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; @@ -154,7 +156,9 @@ void run_rune_equipment_menu(int rune_type) { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/crafting/craft_tools.nvgt b/src/crafting/craft_tools.nvgt index 66a96ab..6a7a83c 100644 --- a/src/crafting/craft_tools.nvgt +++ b/src/crafting/craft_tools.nvgt @@ -17,7 +17,9 @@ void run_tools_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/crafting/craft_weapons.nvgt b/src/crafting/craft_weapons.nvgt index da6f8e6..3f0d1c1 100644 --- a/src/crafting/craft_weapons.nvgt +++ b/src/crafting/craft_weapons.nvgt @@ -11,7 +11,9 @@ void run_weapons_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/crafting/crafting_core.nvgt b/src/crafting/crafting_core.nvgt index debeb59..e98716e 100644 --- a/src/crafting/crafting_core.nvgt +++ b/src/crafting/crafting_core.nvgt @@ -38,7 +38,9 @@ void run_crafting_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; @@ -86,7 +88,9 @@ void simulate_crafting(int item_count) { timer t; while(t.elapsed < 800) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } } } p.play_stationary("sounds/crafting_complete.ogg", false); diff --git a/src/fylgja_system.nvgt b/src/fylgja_system.nvgt index 11b5498..2e85675 100644 --- a/src/fylgja_system.nvgt +++ b/src/fylgja_system.nvgt @@ -136,7 +136,9 @@ void run_fylgja_menu() { while (true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { return; diff --git a/src/menus/action_menu.nvgt b/src/menus/action_menu.nvgt index 930b452..ea0a7ac 100644 --- a/src/menus/action_menu.nvgt +++ b/src/menus/action_menu.nvgt @@ -263,7 +263,9 @@ void run_action_menu(int x) { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/menus/altar_menu.nvgt b/src/menus/altar_menu.nvgt index 9407459..645e272 100644 --- a/src/menus/altar_menu.nvgt +++ b/src/menus/altar_menu.nvgt @@ -88,7 +88,9 @@ void run_altar_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/menus/base_info.nvgt b/src/menus/base_info.nvgt index b7210ef..823fcd6 100644 --- a/src/menus/base_info.nvgt +++ b/src/menus/base_info.nvgt @@ -56,7 +56,9 @@ void run_base_info_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/menus/equipment_menu.nvgt b/src/menus/equipment_menu.nvgt index 580cd66..fdfd849 100644 --- a/src/menus/equipment_menu.nvgt +++ b/src/menus/equipment_menu.nvgt @@ -160,7 +160,9 @@ void run_equipment_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/menus/inventory_core.nvgt b/src/menus/inventory_core.nvgt index 4ce3790..cd1063f 100644 --- a/src/menus/inventory_core.nvgt +++ b/src/menus/inventory_core.nvgt @@ -81,7 +81,9 @@ void run_inventory_root_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; @@ -124,7 +126,9 @@ void run_inventory_menu(bool allow_deposit) { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/menus/menu_utils.nvgt b/src/menus/menu_utils.nvgt index 43bd85c..15660c3 100644 --- a/src/menus/menu_utils.nvgt +++ b/src/menus/menu_utils.nvgt @@ -1,9 +1,12 @@ // Menu utility functions // Helper functions used across multiple menu systems -void menu_background_tick() { +bool menu_background_tick() { + if (return_to_main_menu_requested) { + return true; + } if (!menuBackgroundUpdatesEnabled) { - return; + return false; } // Keep this list in sync with the main game loop to avoid pausing ambience/weather/time. update_time(); @@ -47,9 +50,12 @@ void menu_background_tick() { if (!try_consume_heal_scroll()) { speak_with_history("You have died.", true); wait(2000); - exit(); + return_to_main_menu_requested = true; + return true; } } + + return false; } void play_menu_move_sound() { diff --git a/src/menus/storage_menu.nvgt b/src/menus/storage_menu.nvgt index b0553d9..90cac2d 100644 --- a/src/menus/storage_menu.nvgt +++ b/src/menus/storage_menu.nvgt @@ -305,7 +305,9 @@ void run_storage_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/player.nvgt b/src/player.nvgt index 2309593..cc1c0c0 100644 --- a/src/player.nvgt +++ b/src/player.nvgt @@ -96,6 +96,7 @@ int last_adventure_day = -1; // Pause state bool game_paused = false; bool menuBackgroundUpdatesEnabled = true; +bool return_to_main_menu_requested = false; // Restart all game timers when resuming from pause // Prevents time from accumulating while paused diff --git a/src/quest_system.nvgt b/src/quest_system.nvgt index c06f436..7b9dfd4 100644 --- a/src/quest_system.nvgt +++ b/src/quest_system.nvgt @@ -50,8 +50,8 @@ int get_quest_chance_from_favor() { return chance; } -void quest_menu_background_tick() { - menu_background_tick(); +bool quest_menu_background_tick() { + return menu_background_tick(); } void quest_boomerang_hit_sound() { @@ -163,6 +163,10 @@ void run_quest(int quest_type) { else if (quest_type == QUEST_ENCHANTED_MELODY) score = run_enchanted_melody(); else if (quest_type == QUEST_ESCAPE_FROM_HEL) score = run_escape_from_hel(); else if (quest_type == QUEST_SKELETAL_BARD) score = run_skeletal_bard(); + if (return_to_main_menu_requested) { + p.resume_all(); + return; + } apply_quest_reward(score); p.resume_all(); } @@ -178,7 +182,9 @@ void run_quest_menu() { while(true) { wait(5); - menu_background_tick(); + if (menu_background_tick()) { + return; + } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; diff --git a/src/quests/skeletal_bard_game.nvgt b/src/quests/skeletal_bard_game.nvgt index 9d4b1c7..21bb3c7 100644 --- a/src/quests/skeletal_bard_game.nvgt +++ b/src/quests/skeletal_bard_game.nvgt @@ -21,7 +21,9 @@ int select_note_count(int minNotes, int maxNotes, int startValue) { while (true) { wait(5); - quest_menu_background_tick(); + if (quest_menu_background_tick()) { + return selection; + } if (key_pressed(KEY_UP)) { if (selection < maxNotes) selection++; @@ -72,6 +74,9 @@ int run_skeletal_bard() { wait(400); int guess = select_note_count(5, 20, 5); + if (return_to_main_menu_requested) { + return 0; + } int diff = length - guess; if (diff < 0) diff = -diff; @@ -82,6 +87,9 @@ int run_skeletal_bard() { speak_with_history("You entered " + guess + " notes and the actual number was " + length + ". " + points + " points. Press Enter to continue.", true); while (true) { wait(5); + if (return_to_main_menu_requested) { + return 0; + } if (key_pressed(KEY_RETURN)) { break; }