From 595de51da015bb0486023eb61b784ad500a14f02 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sat, 24 Jan 2026 15:45:26 -0500 Subject: [PATCH] A couple of small bug fixes with crafting. Fishing should now work on mountain streams. --- src/crafting/craft_buildings.nvgt | 50 +++++++++++++++++++++++++++---- src/crafting/craft_clothing.nvgt | 41 +++++++++++++++++++++---- src/environment.nvgt | 4 ++- src/fishing.nvgt | 35 ++++++++++++++++++++-- src/inventory_items.nvgt | 4 +-- 5 files changed, 118 insertions(+), 16 deletions(-) diff --git a/src/crafting/craft_buildings.nvgt b/src/crafting/craft_buildings.nvgt index 10f4a1c..f596f45 100644 --- a/src/crafting/craft_buildings.nvgt +++ b/src/crafting/craft_buildings.nvgt @@ -6,11 +6,31 @@ void run_buildings_menu() { string[] options; int[] building_types; - // Firepit and Fire are always available - options.insert_last("Firepit (9 Stones)"); - building_types.insert_last(0); - options.insert_last("Fire (2 Sticks, 1 Log) [Requires Firepit]"); - building_types.insert_last(1); + bool base_has_firepit = false; + bool base_has_fire = false; + for (uint i = 0; i < world_firepits.length(); i++) { + if (world_firepits[i].position <= BASE_END) { + base_has_firepit = true; + break; + } + } + for (uint i = 0; i < world_fires.length(); i++) { + if (world_fires[i].position <= BASE_END) { + base_has_fire = true; + break; + } + } + + // Firepit and Fire are always available outside base, + // but only one of each can exist in base. + if (x > BASE_END || !base_has_firepit) { + options.insert_last("Firepit (9 Stones)"); + building_types.insert_last(0); + } + if (x > BASE_END || !base_has_fire) { + options.insert_last("Fire (2 Sticks, 1 Log) [Requires Firepit]"); + building_types.insert_last(1); + } // Only show herb garden if not already built in base if (get_herb_garden_at_base() == null) { @@ -77,6 +97,16 @@ void run_buildings_menu() { } void craft_firepit() { + // Only one firepit allowed in base + if (x <= BASE_END) { + for (uint i = 0; i < world_firepits.length(); i++) { + if (world_firepits[i].position <= BASE_END) { + speak_with_history("There is already a firepit in the base.", true); + return; + } + } + } + // Check if there's already a firepit here if (get_firepit_at(x) != null) { speak_with_history("There is already a firepit here.", true); @@ -104,6 +134,16 @@ void craft_campfire() { return; } + // Only one fire allowed in base + if (firepit.position <= BASE_END) { + for (uint i = 0; i < world_fires.length(); i++) { + if (world_fires[i].position <= BASE_END) { + speak_with_history("There is already a fire in the base.", true); + return; + } + } + } + string missing = ""; if (get_personal_count(ITEM_LOGS) < 1) missing += "1 log "; if (get_personal_count(ITEM_STICKS) < 2) missing += "2 sticks "; diff --git a/src/crafting/craft_clothing.nvgt b/src/crafting/craft_clothing.nvgt index 9454849..3f0abdf 100644 --- a/src/crafting/craft_clothing.nvgt +++ b/src/crafting/craft_clothing.nvgt @@ -1,4 +1,35 @@ // Crafting clothing + +// Get total pouches available (unruned + runed) +int get_total_pouch_count() { + int total = get_personal_count(ITEM_SKIN_POUCHES); + total += get_runed_item_count(EQUIP_POUCH, RUNE_SWIFTNESS); + return total; +} + +// Consume pouches for backpack crafting, preferring unruned first +void consume_pouches(int amount) { + int remaining = amount; + + // First consume unruned pouches + int unruned = get_personal_count(ITEM_SKIN_POUCHES); + if (unruned > 0) { + int from_unruned = (unruned >= remaining) ? remaining : unruned; + add_personal_count(ITEM_SKIN_POUCHES, -from_unruned); + remaining -= from_unruned; + } + + // Then consume runed pouches if needed + while (remaining > 0) { + if (get_runed_item_count(EQUIP_POUCH, RUNE_SWIFTNESS) > 0) { + remove_runed_item(EQUIP_POUCH, RUNE_SWIFTNESS); + remaining--; + } else { + break; + } + } +} + void run_clothing_menu() { speak_with_history("Clothing.", true); @@ -365,7 +396,7 @@ void craft_backpack() { string missing = ""; if (get_personal_count(ITEM_SKINS) < 11) missing += "11 skins "; if (get_personal_count(ITEM_VINES) < 5) missing += "5 vines "; - if (get_personal_count(ITEM_SKIN_POUCHES) < 4) missing += "4 skin pouches "; + if (get_total_pouch_count() < 4) missing += "4 skin pouches "; if (missing == "") { if (get_personal_count(ITEM_BACKPACKS) >= get_personal_stack_limit()) { @@ -375,7 +406,7 @@ void craft_backpack() { simulate_crafting(20); add_personal_count(ITEM_SKINS, -11); add_personal_count(ITEM_VINES, -5); - add_personal_count(ITEM_SKIN_POUCHES, -4); + consume_pouches(4); add_personal_count(ITEM_BACKPACKS, 1); speak_with_history("Crafted a Backpack.", true); } else { @@ -391,7 +422,7 @@ void craft_backpack_max() { int max_by_skins = get_personal_count(ITEM_SKINS) / 11; int max_by_vines = get_personal_count(ITEM_VINES) / 5; - int max_by_pouches = get_personal_count(ITEM_SKIN_POUCHES) / 4; + int max_by_pouches = get_total_pouch_count() / 4; int max_craft = max_by_skins; if (max_by_vines < max_craft) max_craft = max_by_vines; if (max_by_pouches < max_craft) max_craft = max_by_pouches; @@ -403,7 +434,7 @@ void craft_backpack_max() { string missing = ""; if (get_personal_count(ITEM_SKINS) < 11) missing += "11 skins "; if (get_personal_count(ITEM_VINES) < 5) missing += "5 vines "; - if (get_personal_count(ITEM_SKIN_POUCHES) < 4) missing += "4 skin pouches "; + if (get_total_pouch_count() < 4) missing += "4 skin pouches "; speak_with_history("Missing: " + missing, true); return; } @@ -412,7 +443,7 @@ void craft_backpack_max() { simulate_crafting(total_cost); add_personal_count(ITEM_SKINS, -(max_craft * 11)); add_personal_count(ITEM_VINES, -(max_craft * 5)); - add_personal_count(ITEM_SKIN_POUCHES, -(max_craft * 4)); + consume_pouches(max_craft * 4); add_personal_count(ITEM_BACKPACKS, max_craft); speak_with_history("Crafted " + max_craft + " Backpacks.", true); } diff --git a/src/environment.nvgt b/src/environment.nvgt index f09c9da..aa973c5 100644 --- a/src/environment.nvgt +++ b/src/environment.nvgt @@ -323,7 +323,9 @@ bool spawn_tree_in_area(int areaStart, int areaEnd) { } void spawn_trees(int grass_start, int grass_end) { - spawn_tree_in_area(grass_start, grass_end); + while (spawn_tree_in_area(grass_start, grass_end)) { + // Keep spawning until max trees reached + } } void get_tree_areas(int[]@ areaStarts, int[]@ areaEnds) { diff --git a/src/fishing.nvgt b/src/fishing.nvgt index d74ba41..3fe136c 100644 --- a/src/fishing.nvgt +++ b/src/fishing.nvgt @@ -11,6 +11,10 @@ const int FISHING_REEL_RETURN_RANGE = 7; string[] fish_types = {"trout", "bass", "salmon", "catfish"}; +bool is_any_water_at(int pos) { + return is_position_in_water(pos) || is_mountain_stream_at(pos); +} + bool is_ctrl_down() { return key_down(KEY_LCTRL) || key_down(KEY_RCTRL); } @@ -47,6 +51,8 @@ void reset_fishing_session() { bool get_nearby_stream(int pos, int range, int &out stream_start, int &out stream_end) { int best_distance = range + 1; + + // Check regular world streams for (uint i = 0; i < world_streams.length(); i++) { int distance = 0; if (pos < world_streams[i].start_position) { @@ -62,6 +68,21 @@ bool get_nearby_stream(int pos, int range, int &out stream_start, int &out strea } } + // Check mountain streams + for (uint i = 0; i < world_mountains.length(); i++) { + for (uint j = 0; j < world_mountains[i].stream_positions.length(); j++) { + int stream_pos = world_mountains[i].start_position + world_mountains[i].stream_positions[j]; + int distance = abs(pos - stream_pos); + + if (distance <= range && distance < best_distance) { + best_distance = distance; + // Mountain streams are single tiles + stream_start = stream_pos; + stream_end = stream_pos; + } + } + } + return best_distance <= range; } @@ -180,7 +201,7 @@ void release_cast() { is_casting = false; stop_fishing_sound(); - if (is_position_in_water(cast_position)) { + if (is_any_water_at(cast_position)) { line_in_water = true; catch_chance = 0; fishing_checks_done = 0; @@ -286,7 +307,7 @@ void release_reel() { return; } - if (is_position_in_water(reel_position)) { + if (is_any_water_at(reel_position)) { if (random(1, 100) <= FISHING_EARLY_ESCAPE_CHANCE) { lose_fish("The fish slipped off in the water."); } else { @@ -362,7 +383,15 @@ void update_fishing() { } if (line_in_water) { - update_waiting_for_fish(); + if (ctrl_pressed && !fish_on_line && !is_reeling) { + line_in_water = false; + catch_chance = 0; + fishing_checks_done = 0; + fishing_timer.restart(); + speak_with_history("You stop fishing.", true); + } else { + update_waiting_for_fish(); + } } if (fish_on_line && ctrl_pressed && !is_reeling) { diff --git a/src/inventory_items.nvgt b/src/inventory_items.nvgt index b889df4..6766fe9 100644 --- a/src/inventory_items.nvgt +++ b/src/inventory_items.nvgt @@ -303,8 +303,8 @@ void cleanup_equipment_after_inventory_change() { if (get_personal_count(ITEM_SKIN_PANTS) <= 0) equipped_legs = EQUIP_NONE; if (get_personal_count(ITEM_SKIN_TUNICS) <= 0) equipped_torso = EQUIP_NONE; if (get_personal_count(ITEM_MOCCASINS) <= 0) equipped_feet = EQUIP_NONE; - if (get_personal_count(ITEM_SKIN_POUCHES) <= 0 && equipped_arms == EQUIP_POUCH) equipped_arms = EQUIP_NONE; - if (get_personal_count(ITEM_BACKPACKS) <= 0 && equipped_arms == EQUIP_BACKPACK) equipped_arms = EQUIP_NONE; + if (get_personal_count(ITEM_SKIN_POUCHES) <= 0 && !has_any_runed_version(EQUIP_POUCH) && equipped_arms == EQUIP_POUCH) equipped_arms = EQUIP_NONE; + if (get_personal_count(ITEM_BACKPACKS) <= 0 && !has_any_runed_version(EQUIP_BACKPACK) && equipped_arms == EQUIP_BACKPACK) equipped_arms = EQUIP_NONE; clamp_arrows_to_quiver_limit(); update_max_health_from_equipment(); }