diff --git a/src/crafting.nvgt b/src/crafting.nvgt index 8f1f40e..0baf6a9 100644 --- a/src/crafting.nvgt +++ b/src/crafting.nvgt @@ -1,1753 +1,21 @@ -// Crafting menus and recipes -void check_crafting_menu(int x, int base_end_tile) { - if (x <= base_end_tile) { - if (key_pressed(KEY_C)) { - run_crafting_menu(); - } - } -} - -void run_crafting_menu() { - speak_with_history("Crafting menu.", true); - - int selection = 0; - string[] categories = {"Weapons", "Tools", "Materials", "Clothing", "Buildings", "Barricade"}; - int[] category_types = {0, 1, 2, 3, 4, 5}; - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= categories.length()) selection = 0; - speak_with_history(categories[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = categories.length() - 1; - speak_with_history(categories[selection], true); - } - - if (key_pressed(KEY_RETURN)) { - int category = category_types[selection]; - if (category == 0) run_weapons_menu(); - else if (category == 1) run_tools_menu(); - else if (category == 2) run_materials_menu(); - else if (category == 3) run_clothing_menu(); - else if (category == 4) run_buildings_menu(); - else if (category == 5) run_barricade_menu(); - break; - } - } -} - -void run_weapons_menu() { - speak_with_history("Weapons.", true); - - int selection = 0; - string[] options = { - "Spear (1 Stick, 1 Vine, 1 Stone) [Requires Knife]", - "Sling (1 Skin, 2 Vines)" - }; - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_RETURN)) { - if (selection == 0) craft_spear(); - else if (selection == 1) craft_sling(); - break; - } - - if (key_pressed(KEY_TAB)) { - if (selection == 0) craft_spear_max(); - else if (selection == 1) craft_sling_max(); - break; - } - } -} - -void run_tools_menu() { - speak_with_history("Tools.", true); - - int selection = 0; - string[] options = { - "Stone Knife (2 Stones)", - "Snare (1 Stick, 2 Vines)", - "Stone Axe (1 Stick, 1 Vine, 2 Stones) [Requires Knife]", - "Fishing Pole (1 Stick, 2 Vines)", - "Rope (3 Vines)", - "Reed Basket (3 Reeds)", - "Clay Pot (3 Clay)" - }; - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_RETURN)) { - if (selection == 0) craft_knife(); - else if (selection == 1) craft_snare(); - else if (selection == 2) craft_axe(); - else if (selection == 3) craft_fishing_pole(); - else if (selection == 4) craft_rope(); - else if (selection == 5) craft_reed_basket(); - else if (selection == 6) craft_clay_pot(); - break; - } - - if (key_pressed(KEY_TAB)) { - if (selection == 0) craft_knife_max(); - else if (selection == 1) craft_snare_max(); - else if (selection == 2) craft_axe_max(); - else if (selection == 3) craft_fishing_pole_max(); - else if (selection == 4) craft_rope_max(); - else if (selection == 5) craft_reed_basket_max(); - else if (selection == 6) craft_clay_pot_max(); - break; - } - } -} - -void run_materials_menu() { - speak_with_history("Materials.", true); - - int selection = 0; - string[] options = { - "Butcher Small Game (1 Small Game) [Requires Knife and Fire nearby]", - "Incense (6 Sticks, 2 Vines, 1 Reed) [Requires Altar]" - }; - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_RETURN)) { - if (selection == 0) butcher_small_game(); - else if (selection == 1) craft_incense(); - break; - } - - if (key_pressed(KEY_TAB)) { - if (selection == 0) butcher_small_game_max(); - else if (selection == 1) craft_incense_max(); - break; - } - } -} -void run_clothing_menu() { - speak_with_history("Clothing.", true); - - int selection = 0; - string[] options = { - "Skin Hat (1 Skin, 1 Vine)", - "Skin Gloves (1 Skin, 1 Vine)", - "Skin Pants (6 Skins, 3 Vines)", - "Skin Tunic (4 Skins, 2 Vines)", - "Moccasins (2 Skins, 1 Vine)", - "Skin Pouch (2 Skins, 1 Vine)" - }; - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_RETURN)) { - if (selection == 0) craft_skin_hat(); - else if (selection == 1) craft_skin_gloves(); - else if (selection == 2) craft_skin_pants(); - else if (selection == 3) craft_skin_tunic(); - else if (selection == 4) craft_moccasins(); - else if (selection == 5) craft_skin_pouch(); - break; - } - - if (key_pressed(KEY_TAB)) { - if (selection == 0) craft_skin_hat_max(); - else if (selection == 1) craft_skin_gloves_max(); - else if (selection == 2) craft_skin_pants_max(); - else if (selection == 3) craft_skin_tunic_max(); - else if (selection == 4) craft_moccasins_max(); - else if (selection == 5) craft_skin_pouch_max(); - break; - } - } -} - -void run_buildings_menu() { - speak_with_history("Buildings.", true); - - int selection = 0; - 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); - - // Only show herb garden if not already built in base - if (get_herb_garden_at_base() == null) { - options.insert_last("Herb Garden (9 Stones, 3 Vines, 2 Logs) [Base Only]"); - building_types.insert_last(2); - } - - // Only show storage if none built yet - if (world_storages.length() == 0) { - options.insert_last("Storage (6 Logs, 9 Stones, 8 Vines) [Base Only]"); - building_types.insert_last(3); - } - - // Only show pasture if not built - if (world_pastures.length() == 0) { - options.insert_last("Pasture (8 Logs, 20 Vines) [Base Only]"); - building_types.insert_last(4); - } - - // Only show stable if not built - if (world_stables.length() == 0) { - options.insert_last("Stable (10 Logs, 15 Stones, 10 Vines) [Base Only]"); - building_types.insert_last(5); - } - - // Only show altar if not built - if (world_altars.length() == 0) { - options.insert_last("Altar (9 Stones, 3 Sticks) [Base Only]"); - building_types.insert_last(6); - } - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_RETURN)) { - int building = building_types[selection]; - if (building == 0) craft_firepit(); - else if (building == 1) craft_campfire(); - else if (building == 2) craft_herb_garden(); - else if (building == 3) craft_storage(); - else if (building == 4) craft_pasture(); - else if (building == 5) craft_stable(); - else if (building == 6) craft_altar(); - break; - } - } -} - -void run_barricade_menu() { - if (barricade_health >= BARRICADE_MAX_HEALTH) { - speak_with_history("Barricade is already at full health.", true); - return; - } - - speak_with_history("Barricade.", true); - - int selection = 0; - string[] options; - int[] action_types; // 0 = sticks, 1 = vines, 2 = log, 3 = stones - - if (inv_sticks >= BARRICADE_STICK_COST) { - options.insert_last("Reinforce with sticks (" + BARRICADE_STICK_COST + " sticks, +" + BARRICADE_STICK_HEALTH + " health)"); - action_types.insert_last(0); - } - if (inv_vines >= BARRICADE_VINE_COST) { - options.insert_last("Reinforce with vines (" + BARRICADE_VINE_COST + " vines, +" + BARRICADE_VINE_HEALTH + " health)"); - action_types.insert_last(1); - } - if (inv_logs >= BARRICADE_LOG_COST) { - options.insert_last("Reinforce with log (" + BARRICADE_LOG_COST + " log, +" + BARRICADE_LOG_HEALTH + " health)"); - action_types.insert_last(2); - } - if (inv_stones >= BARRICADE_STONE_COST) { - options.insert_last("Reinforce with stones (" + BARRICADE_STONE_COST + " stones, +" + BARRICADE_STONE_HEALTH + " health)"); - action_types.insert_last(3); - } - - if (options.length() == 0) { - speak_with_history("No materials to reinforce the barricade.", true); - return; - } - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_RETURN)) { - int action = action_types[selection]; - if (action == 0) reinforce_barricade_with_sticks(); - else if (action == 1) reinforce_barricade_with_vines(); - else if (action == 2) reinforce_barricade_with_log(); - else if (action == 3) reinforce_barricade_with_stones(); - break; - } - - if (key_pressed(KEY_TAB)) { - int action = action_types[selection]; - if (action == 0) reinforce_barricade_max_with_sticks(); - else if (action == 1) reinforce_barricade_max_with_vines(); - else if (action == 2) reinforce_barricade_max_with_log(); - else if (action == 3) reinforce_barricade_max_with_stones(); - break; - } - } -} - -void simulate_crafting(int item_count) { - speak_with_history("Crafting...", true); - // Nothing should take less than 4. - if(item_count < 4) { - item_count = 4; - } - for(int i = 0; i < item_count; i++) { - float pitch = random(85, 115); - p.play_stationary_extended("sounds/crafting.ogg", false, 0, 0, 0, pitch); - - timer t; - while(t.elapsed < 800) { - wait(5); - menu_background_tick(); - } - } - p.play_stationary("sounds/crafting_complete.ogg", false); -} - -void craft_knife() { - string missing = ""; - if (inv_stones < 2) missing += "2 stones "; - - if (missing == "") { - if (inv_knives >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more stone knives.", true); - return; - } - simulate_crafting(2); - inv_stones -= 2; - inv_knives++; - speak_with_history("Crafted a Stone Knife.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_knife_max() { - if (inv_knives >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more stone knives.", true); - return; - } - - int max_possible = inv_stones / 2; - int space = get_personal_stack_limit() - inv_knives; - if (max_possible > space) max_possible = space; - - if (max_possible <= 0) { - speak_with_history("Missing: 2 stones", true); - return; - } - - int total_cost = max_possible * 2; - int craft_time = (total_cost < max_possible * 4) ? max_possible * 4 : total_cost; - simulate_crafting(craft_time); - inv_stones -= (max_possible * 2); - inv_knives += max_possible; - speak_with_history("Crafted " + max_possible + " Stone Knives.", true); -} - -void craft_spear() { - string missing = ""; - if (inv_knives < 1) missing += "Stone Knife "; - if (inv_sticks < 1) missing += "1 stick "; - if (inv_vines < 1) missing += "1 vine "; - if (inv_stones < 1) missing += "1 stone "; - - if (missing == "") { - if (inv_spears >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more spears.", true); - return; - } - simulate_crafting(3); - inv_sticks--; - inv_vines--; - inv_stones--; - inv_spears++; - speak_with_history("Crafted a Spear.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_spear_max() { - if (inv_knives < 1) { - speak_with_history("Missing: Stone Knife", true); - return; - } - if (inv_spears >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more spears.", true); - return; - } - - int max_by_sticks = inv_sticks; - int max_by_vines = inv_vines; - int max_by_stones = inv_stones; - int max_craft = max_by_sticks; - if (max_by_vines < max_craft) max_craft = max_by_vines; - if (max_by_stones < max_craft) max_craft = max_by_stones; - - int space = get_personal_stack_limit() - inv_spears; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_sticks < 1) missing += "1 stick "; - if (inv_vines < 1) missing += "1 vine "; - if (inv_stones < 1) missing += "1 stone "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 3; // 1 stick + 1 vine + 1 stone per spear - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_sticks -= max_craft; - inv_vines -= max_craft; - inv_stones -= max_craft; - inv_spears += max_craft; - speak_with_history("Crafted " + max_craft + " Spears.", true); -} - -void craft_sling() { - string missing = ""; - if (inv_skins < 1) missing += "1 skin "; - if (inv_vines < 2) missing += "2 vines "; - - if (missing == "") { - if (inv_slings >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more slings.", true); - return; - } - simulate_crafting(3); - inv_skins--; - inv_vines -= 2; - inv_slings++; - speak_with_history("Crafted a Sling.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_sling_max() { - if (inv_slings >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more slings.", true); - return; - } - - int max_by_skins = inv_skins; - int max_by_vines = inv_vines / 2; - int max_craft = max_by_skins; - if (max_by_vines < max_craft) max_craft = max_by_vines; - - int space = get_personal_stack_limit() - inv_slings; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_skins < 1) missing += "1 skin "; - if (inv_vines < 2) missing += "2 vines "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 3; // 1 skin + 2 vines per sling - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_skins -= max_craft; - inv_vines -= (max_craft * 2); - inv_slings += max_craft; - speak_with_history("Crafted " + max_craft + " Slings.", true); -} - -void craft_skin_hat() { - string missing = ""; - if (inv_skins < 1) missing += "1 skin "; - if (inv_vines < 1) missing += "1 vine "; - - if (missing == "") { - if (inv_skin_hats >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more skin hats.", true); - return; - } - simulate_crafting(2); - inv_skins--; - inv_vines--; - inv_skin_hats++; - speak_with_history("Crafted a Skin Hat.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_skin_hat_max() { - if (inv_skin_hats >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more skin hats.", true); - return; - } - - int max_by_skins = inv_skins; - int max_by_vines = inv_vines; - int max_craft = max_by_skins; - if (max_by_vines < max_craft) max_craft = max_by_vines; - - int space = get_personal_stack_limit() - inv_skin_hats; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_skins < 1) missing += "1 skin "; - if (inv_vines < 1) missing += "1 vine "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 2; // 1 skin + 1 vine per hat - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_skins -= max_craft; - inv_vines -= max_craft; - inv_skin_hats += max_craft; - speak_with_history("Crafted " + max_craft + " Skin Hats.", true); -} - -void craft_skin_gloves() { - string missing = ""; - if (inv_skins < 1) missing += "1 skin "; - if (inv_vines < 1) missing += "1 vine "; - - if (missing == "") { - if (inv_skin_gloves >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more skin gloves.", true); - return; - } - simulate_crafting(2); - inv_skins--; - inv_vines--; - inv_skin_gloves++; - speak_with_history("Crafted Skin Gloves.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_skin_gloves_max() { - if (inv_skin_gloves >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more skin gloves.", true); - return; - } - - int max_by_skins = inv_skins; - int max_by_vines = inv_vines; - int max_craft = max_by_skins; - if (max_by_vines < max_craft) max_craft = max_by_vines; - - int space = get_personal_stack_limit() - inv_skin_gloves; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_skins < 1) missing += "1 skin "; - if (inv_vines < 1) missing += "1 vine "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 2; // 1 skin + 1 vine per gloves - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_skins -= max_craft; - inv_vines -= max_craft; - inv_skin_gloves += max_craft; - speak_with_history("Crafted " + max_craft + " Skin Gloves.", true); -} - -void craft_skin_pants() { - string missing = ""; - if (inv_skins < 6) missing += "6 skins "; - if (inv_vines < 3) missing += "3 vines "; - - if (missing == "") { - if (inv_skin_pants >= get_personal_stack_limit()) { - 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++; - speak_with_history("Crafted Skin Pants.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_skin_pants_max() { - if (inv_skin_pants >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more skin pants.", true); - return; - } - - int max_by_skins = inv_skins / 6; - int max_by_vines = inv_vines / 3; - int max_craft = max_by_skins; - if (max_by_vines < max_craft) max_craft = max_by_vines; - - int space = get_personal_stack_limit() - inv_skin_pants; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_skins < 6) missing += "6 skins "; - if (inv_vines < 3) missing += "3 vines "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 9; // 6 skins + 3 vines per pants - simulate_crafting(total_cost); - inv_skins -= (max_craft * 6); - inv_vines -= (max_craft * 3); - inv_skin_pants += max_craft; - speak_with_history("Crafted " + max_craft + " Skin Pants.", true); -} - -void craft_skin_tunic() { - string missing = ""; - if (inv_skins < 4) missing += "4 skins "; - if (inv_vines < 2) missing += "2 vines "; - - if (missing == "") { - if (inv_skin_tunics >= get_personal_stack_limit()) { - 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++; - speak_with_history("Crafted a Skin Tunic.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_skin_tunic_max() { - if (inv_skin_tunics >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more skin tunics.", true); - return; - } - - int max_by_skins = inv_skins / 4; - int max_by_vines = inv_vines / 2; - int max_craft = max_by_skins; - if (max_by_vines < max_craft) max_craft = max_by_vines; - - int space = get_personal_stack_limit() - inv_skin_tunics; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_skins < 4) missing += "4 skins "; - if (inv_vines < 2) missing += "2 vines "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 6; // 4 skins + 2 vines per tunic - simulate_crafting(total_cost); - inv_skins -= (max_craft * 4); - inv_vines -= (max_craft * 2); - inv_skin_tunics += max_craft; - speak_with_history("Crafted " + max_craft + " Skin Tunics.", true); -} - -void craft_moccasins() { - string missing = ""; - if (inv_skins < 2) missing += "2 skins "; - if (inv_vines < 1) missing += "1 vine "; - - if (missing == "") { - if (inv_moccasins >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more moccasins.", true); - return; - } - simulate_crafting(3); - inv_skins -= 2; - inv_vines--; - inv_moccasins++; - speak_with_history("Crafted moccasins.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_moccasins_max() { - if (inv_moccasins >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more moccasins.", true); - return; - } - - int max_by_skins = inv_skins / 2; - int max_by_vines = inv_vines; - int max_craft = max_by_skins; - if (max_by_vines < max_craft) max_craft = max_by_vines; - - int space = get_personal_stack_limit() - inv_moccasins; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_skins < 2) missing += "2 skins "; - if (inv_vines < 1) missing += "1 vine "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 3; // 2 skins + 1 vine per moccasins - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_skins -= (max_craft * 2); - inv_vines -= max_craft; - inv_moccasins += max_craft; - speak_with_history("Crafted " + max_craft + " Moccasins.", true); -} - -void craft_skin_pouch() { - string missing = ""; - if (inv_skins < 2) missing += "2 skins "; - if (inv_vines < 1) missing += "1 vine "; - - if (missing == "") { - if (inv_skin_pouches >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more skin pouches.", true); - return; - } - simulate_crafting(3); - inv_skins -= 2; - inv_vines--; - inv_skin_pouches++; - speak_with_history("Crafted a Skin Pouch.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_skin_pouch_max() { - if (inv_skin_pouches >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more skin pouches.", true); - return; - } - - int max_by_skins = inv_skins / 2; - int max_by_vines = inv_vines; - int max_craft = max_by_skins; - if (max_by_vines < max_craft) max_craft = max_by_vines; - - int space = get_personal_stack_limit() - inv_skin_pouches; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_skins < 2) missing += "2 skins "; - if (inv_vines < 1) missing += "1 vine "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 3; // 2 skins + 1 vine per pouch - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_skins -= (max_craft * 2); - inv_vines -= max_craft; - inv_skin_pouches += max_craft; - speak_with_history("Crafted " + max_craft + " Skin Pouches.", true); -} - -void craft_snare() { - string missing = ""; - if (inv_sticks < 1) missing += "1 stick "; - if (inv_vines < 2) missing += "2 vines "; - - if (missing == "") { - if (inv_snares >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more snares.", true); - return; - } - simulate_crafting(3); - inv_sticks--; - inv_vines -= 2; - inv_snares++; - speak_with_history("Crafted a Snare.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_snare_max() { - if (inv_snares >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more snares.", true); - return; - } - - int max_by_sticks = inv_sticks; - int max_by_vines = inv_vines / 2; - int max_craft = max_by_sticks; - if (max_by_vines < max_craft) max_craft = max_by_vines; - - int space = get_personal_stack_limit() - inv_snares; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_sticks < 1) missing += "1 stick "; - if (inv_vines < 2) missing += "2 vines "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 3; // 1 stick + 2 vines per snare - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_sticks -= max_craft; - inv_vines -= (max_craft * 2); - inv_snares += max_craft; - speak_with_history("Crafted " + max_craft + " Snares.", true); -} - -void craft_axe() { - string missing = ""; - if (inv_knives < 1) missing += "Stone Knife "; - if (inv_sticks < 1) missing += "1 stick "; - if (inv_vines < 1) missing += "1 vine "; - if (inv_stones < 2) missing += "2 stones "; - - if (missing == "") { - if (inv_axes >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more stone axes.", true); - return; - } - simulate_crafting(4); - inv_sticks--; - inv_vines--; - inv_stones -= 2; - inv_axes++; - speak_with_history("Crafted a Stone Axe.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_axe_max() { - if (inv_knives < 1) { - speak_with_history("Missing: Stone Knife", true); - return; - } - if (inv_axes >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more stone axes.", true); - return; - } - - int max_by_sticks = inv_sticks; - int max_by_vines = inv_vines; - int max_by_stones = inv_stones / 2; - int max_craft = max_by_sticks; - if (max_by_vines < max_craft) max_craft = max_by_vines; - if (max_by_stones < max_craft) max_craft = max_by_stones; - - int space = get_personal_stack_limit() - inv_axes; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_sticks < 1) missing += "1 stick "; - if (inv_vines < 1) missing += "1 vine "; - if (inv_stones < 2) missing += "2 stones "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 4; // 1 stick + 1 vine + 2 stones per axe - simulate_crafting(total_cost); - inv_sticks -= max_craft; - inv_vines -= max_craft; - inv_stones -= (max_craft * 2); - inv_axes += max_craft; - 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) { - speak_with_history("There is already a firepit here.", true); - return; - } - - string missing = ""; - if (inv_stones < 9) missing += "9 stones "; - - if (missing == "") { - simulate_crafting(9); - inv_stones -= 9; - add_world_firepit(x); - speak_with_history("Firepit built here.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_campfire() { - // Check if there's a firepit within 2 tiles - WorldFirepit@ firepit = get_firepit_near(x, 2); - if (firepit == null) { - speak_with_history("You need a firepit within 2 tiles to build a fire.", true); - return; - } - - string missing = ""; - if (inv_logs < 1) missing += "1 log "; - if (inv_sticks < 2) missing += "2 sticks "; - - if (missing == "") { - simulate_crafting(3); - inv_logs--; - inv_sticks -= 2; - // Build the fire at the firepit location, not player location - add_world_fire(firepit.position); - speak_with_history("Fire built at firepit.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_herb_garden() { - // Can only build in base area - if (x > BASE_END) { - 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) { - speak_with_history("There is already an herb garden in the base.", true); - return; - } - - string missing = ""; - if (inv_stones < 9) missing += "9 stones "; - if (inv_vines < 3) missing += "3 vines "; - if (inv_logs < 2) missing += "2 logs "; - - if (missing == "") { - simulate_crafting(14); - inv_stones -= 9; - inv_vines -= 3; - inv_logs -= 2; - add_world_herb_garden(x); - speak_with_history("Herb garden built. The base now heals faster.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_storage() { - if (x > BASE_END) { - speak_with_history("Storage must be built in the base.", true); - return; - } - if (world_storages.length() > 0) { - speak_with_history("Storage already built.", true); - return; - } - string missing = ""; - if (inv_logs < STORAGE_LOG_COST) missing += STORAGE_LOG_COST + " logs "; - if (inv_stones < STORAGE_STONE_COST) missing += STORAGE_STONE_COST + " stones "; - if (inv_vines < STORAGE_VINE_COST) missing += STORAGE_VINE_COST + " vines "; - - if (missing == "") { - simulate_crafting(23); - inv_logs -= STORAGE_LOG_COST; - inv_stones -= STORAGE_STONE_COST; - inv_vines -= STORAGE_VINE_COST; - add_world_storage(x); - speak_with_history("Storage built.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_pasture() { - if (x > BASE_END) { - speak_with_history("Pasture must be built in the base.", true); - return; - } - if (world_pastures.length() > 0) { - speak_with_history("Pasture already built.", true); - return; - } - string missing = ""; - if (inv_logs < PASTURE_LOG_COST) missing += PASTURE_LOG_COST + " logs "; - if (inv_vines < PASTURE_VINE_COST) missing += PASTURE_VINE_COST + " vines "; - - if (missing == "") { - simulate_crafting(28); - inv_logs -= PASTURE_LOG_COST; - inv_vines -= PASTURE_VINE_COST; - add_world_pasture(x); - speak_with_history("Pasture built.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_stable() { - if (x > BASE_END) { - speak_with_history("Stable must be built in the base.", true); - return; - } - if (world_stables.length() > 0) { - speak_with_history("Stable already built.", true); - return; - } - string missing = ""; - if (inv_logs < STABLE_LOG_COST) missing += STABLE_LOG_COST + " logs "; - if (inv_stones < STABLE_STONE_COST) missing += STABLE_STONE_COST + " stones "; - if (inv_vines < STABLE_VINE_COST) missing += STABLE_VINE_COST + " vines "; - - if (missing == "") { - simulate_crafting(35); - inv_logs -= STABLE_LOG_COST; - inv_stones -= STABLE_STONE_COST; - inv_vines -= STABLE_VINE_COST; - add_world_stable(x); - speak_with_history("Stable built.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_altar() { - if (x > BASE_END) { - speak_with_history("Altar must be built in the base.", true); - return; - } - if (world_altars.length() > 0) { - speak_with_history("Altar already built.", true); - return; - } - string missing = ""; - if (inv_stones < ALTAR_STONE_COST) missing += ALTAR_STONE_COST + " stones "; - if (inv_sticks < ALTAR_STICK_COST) missing += ALTAR_STICK_COST + " sticks "; - - if (missing == "") { - simulate_crafting(12); - inv_stones -= ALTAR_STONE_COST; - inv_sticks -= ALTAR_STICK_COST; - add_world_altar(x); - speak_with_history("Altar built.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void reinforce_barricade_with_sticks() { - if (barricade_health >= BARRICADE_MAX_HEALTH) { - speak_with_history("Barricade is already at full health.", true); - return; - } - if (inv_sticks < BARRICADE_STICK_COST) { - 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); - 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) { - speak_with_history("Barricade is already at full health.", true); - return; - } - if (inv_vines < BARRICADE_VINE_COST) { - 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); - 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) { - speak_with_history("Barricade is already at full health.", true); - return; - } - if (inv_logs < BARRICADE_LOG_COST) { - 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); - 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) { - speak_with_history("Barricade is already at full health.", true); - return; - } - if (inv_stones < BARRICADE_STONE_COST) { - 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); - 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) { - speak_with_history("Barricade is already at full health.", true); - return; - } - - if (inv_sticks < BARRICADE_STICK_COST) { - speak_with_history("Missing: " + BARRICADE_STICK_COST + " sticks", true); - return; - } - - int health_needed = BARRICADE_MAX_HEALTH - barricade_health; - int max_reinforcements = (health_needed + BARRICADE_STICK_HEALTH - 1) / BARRICADE_STICK_HEALTH; - int can_afford = inv_sticks / BARRICADE_STICK_COST; - - int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford; - int total_cost = to_do * BARRICADE_STICK_COST; - - simulate_crafting(total_cost); - inv_sticks -= total_cost; - barricade_health += (to_do * BARRICADE_STICK_HEALTH); - if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; - - 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) { - speak_with_history("Barricade is already at full health.", true); - return; - } - - if (inv_vines < BARRICADE_VINE_COST) { - speak_with_history("Missing: " + BARRICADE_VINE_COST + " vines", true); - return; - } - - int health_needed = BARRICADE_MAX_HEALTH - barricade_health; - int max_reinforcements = (health_needed + BARRICADE_VINE_HEALTH - 1) / BARRICADE_VINE_HEALTH; - int can_afford = inv_vines / BARRICADE_VINE_COST; - - int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford; - int total_cost = to_do * BARRICADE_VINE_COST; - - simulate_crafting(total_cost); - inv_vines -= total_cost; - barricade_health += (to_do * BARRICADE_VINE_HEALTH); - if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; - - 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) { - speak_with_history("Barricade is already at full health.", true); - return; - } - - if (inv_logs < BARRICADE_LOG_COST) { - speak_with_history("Missing: " + BARRICADE_LOG_COST + " log", true); - return; - } - - int health_needed = BARRICADE_MAX_HEALTH - barricade_health; - int max_reinforcements = (health_needed + BARRICADE_LOG_HEALTH - 1) / BARRICADE_LOG_HEALTH; - int can_afford = inv_logs / BARRICADE_LOG_COST; - - int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford; - int total_cost = to_do * BARRICADE_LOG_COST; - - simulate_crafting(total_cost); - inv_logs -= total_cost; - barricade_health += (to_do * BARRICADE_LOG_HEALTH); - if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; - - 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) { - speak_with_history("Barricade is already at full health.", true); - return; - } - - if (inv_stones < BARRICADE_STONE_COST) { - speak_with_history("Missing: " + BARRICADE_STONE_COST + " stones", true); - return; - } - - int health_needed = BARRICADE_MAX_HEALTH - barricade_health; - int max_reinforcements = (health_needed + BARRICADE_STONE_HEALTH - 1) / BARRICADE_STONE_HEALTH; - int can_afford = inv_stones / BARRICADE_STONE_COST; - - int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford; - int total_cost = to_do * BARRICADE_STONE_COST; - - simulate_crafting(total_cost); - inv_stones -= total_cost; - barricade_health += (to_do * BARRICADE_STONE_HEALTH); - if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; - - speak_with_history("Reinforced barricade " + to_do + " times with stones. Health now " + barricade_health + ".", true); -} - -void craft_fishing_pole() { - string missing = ""; - if (inv_sticks < 1) missing += "1 stick "; - if (inv_vines < 2) missing += "2 vines "; - - if (missing == "") { - if (inv_fishing_poles >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more fishing poles.", true); - return; - } - simulate_crafting(3); - inv_sticks--; - inv_vines -= 2; - inv_fishing_poles++; - speak_with_history("Crafted a Fishing Pole.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_fishing_pole_max() { - if (inv_fishing_poles >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more fishing poles.", true); - return; - } - - int max_by_sticks = inv_sticks; - int max_by_vines = inv_vines / 2; - int max_craft = max_by_sticks; - if (max_by_vines < max_craft) max_craft = max_by_vines; - - int space = get_personal_stack_limit() - inv_fishing_poles; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - if (inv_sticks < 1) missing += "1 stick "; - if (inv_vines < 2) missing += "2 vines "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = max_craft * 3; // 1 stick + 2 vines per pole - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_sticks -= max_craft; - inv_vines -= (max_craft * 2); - inv_fishing_poles += max_craft; - speak_with_history("Crafted " + max_craft + " Fishing Poles.", true); -} - -void craft_rope() { - string missing = ""; - if (inv_vines < 3) missing += "3 vines "; - - if (missing == "") { - if (inv_ropes >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more rope.", true); - return; - } - simulate_crafting(3); - inv_vines -= 3; - inv_ropes++; - speak_with_history("Crafted rope.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_rope_max() { - if (inv_ropes >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more rope.", true); - return; - } - - int max_craft = inv_vines / 3; - - int space = get_personal_stack_limit() - inv_ropes; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - speak_with_history("Missing: 3 vines", true); - return; - } - - int total_cost = max_craft * 3; // 3 vines per rope - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_vines -= (max_craft * 3); - inv_ropes += max_craft; - speak_with_history("Crafted " + max_craft + " Rope.", true); -} - -void craft_reed_basket() { - string missing = ""; - if (inv_reeds < 3) missing += "3 reeds "; - - if (missing == "") { - if (inv_reed_baskets >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more reed baskets.", true); - return; - } - simulate_crafting(3); - inv_reeds -= 3; - inv_reed_baskets++; - speak_with_history("Crafted a reed basket.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_reed_basket_max() { - if (inv_reed_baskets >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more reed baskets.", true); - return; - } - - int max_craft = inv_reeds / 3; - - int space = get_personal_stack_limit() - inv_reed_baskets; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - speak_with_history("Missing: 3 reeds", true); - return; - } - - int total_cost = max_craft * 3; // 3 reeds per basket - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_reeds -= (max_craft * 3); - inv_reed_baskets += max_craft; - speak_with_history("Crafted " + max_craft + " Reed Baskets.", true); -} - -void craft_clay_pot() { - string missing = ""; - if (inv_clay < 3) missing += "3 clay "; - - // Check for fire within 3 tiles (can hear it) - WorldFire@ fire = get_fire_within_range(x, 3); - if (fire == null) { - 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()) { - speak_with_history("You can't carry any more clay pots.", true); - return; - } - simulate_crafting(3); - inv_clay -= 3; - inv_clay_pots++; - speak_with_history("Crafted a clay pot.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -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) { - speak_with_history("You need a fire within 3 tiles to craft clay pots.", true); - return; - } - - if (inv_clay_pots >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more clay pots.", true); - return; - } - - int max_craft = inv_clay / 3; - - int space = get_personal_stack_limit() - inv_clay_pots; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - speak_with_history("Missing: 3 clay", true); - return; - } - - int total_cost = max_craft * 3; // 3 clay per pot - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - inv_clay -= (max_craft * 3); - inv_clay_pots += max_craft; - speak_with_history("Crafted " + max_craft + " Clay Pots.", true); -} - -void craft_incense() { - if (world_altars.length() == 0) { - speak_with_history("You need an altar to craft incense.", true); - return; - } - - string missing = ""; - 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 "; - - if (missing == "") { - if (inv_incense >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more incense.", true); - return; - } - simulate_crafting(INCENSE_STICK_COST + INCENSE_VINE_COST + INCENSE_REED_COST); - inv_sticks -= INCENSE_STICK_COST; - inv_vines -= INCENSE_VINE_COST; - inv_reeds -= INCENSE_REED_COST; - inv_incense++; - speak_with_history("Crafted incense.", true); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void craft_incense_max() { - if (world_altars.length() == 0) { - speak_with_history("You need an altar to craft incense.", true); - return; - } - - if (inv_incense >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more incense.", true); - return; - } - - int max_by_sticks = inv_sticks / INCENSE_STICK_COST; - int max_by_vines = inv_vines / INCENSE_VINE_COST; - int max_by_reeds = inv_reeds / INCENSE_REED_COST; - int max_craft = max_by_sticks; - if (max_by_vines < max_craft) max_craft = max_by_vines; - if (max_by_reeds < max_craft) max_craft = max_by_reeds; - - int space = get_personal_stack_limit() - inv_incense; - if (max_craft > space) max_craft = space; - - if (max_craft <= 0) { - string missing = ""; - 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 "; - speak_with_history("Missing: " + missing, true); - return; - } - - int total_cost = (max_craft * INCENSE_STICK_COST) + (max_craft * INCENSE_VINE_COST) + (max_craft * INCENSE_REED_COST); - simulate_crafting(total_cost); - inv_sticks -= (max_craft * INCENSE_STICK_COST); - inv_vines -= (max_craft * INCENSE_VINE_COST); - inv_reeds -= (max_craft * INCENSE_REED_COST); - inv_incense += max_craft; - speak_with_history("Crafted " + max_craft + " Incense.", true); -} - -void butcher_small_game() { - string missing = ""; - - // Check for knife - if (inv_knives < 1) missing += "Stone Knife "; - - // Check for small game or boar - if (inv_small_game < 1 && inv_boar_carcasses < 1) missing += "Game "; - - // Check for fire within 3 tiles (can hear it) - WorldFire@ fire = get_fire_within_range(x, 3); - if (fire == null) { - speak_with_history("You need a fire within 3 tiles to butcher.", true); - return; - } - - if (missing == "") { - if (inv_meat >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more meat.", true); - return; - } - if (inv_skins >= get_personal_stack_limit()) { - speak_with_history("You can't carry any more skins.", true); - return; - } - simulate_crafting(1); - - string game_type = ""; - if (inv_boar_carcasses > 0) { - game_type = "boar carcass"; - inv_boar_carcasses--; - } else { - game_type = inv_small_game_types[0]; - inv_small_game_types.remove_at(0); - inv_small_game--; - } - - if (game_type == "goose") { - inv_meat++; - inv_feathers += random(3, 6); - inv_down += random(1, 3); - 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; - speak_with_history("Butchered boar. Got meat, 3 skins, and 2 sinew.", true); - } else { - inv_meat++; - inv_skins++; - speak_with_history("Butchered " + game_type + ". Got 1 meat and 1 skin.", true); - } - - // Play sound - p.play_stationary("sounds/items/miscellaneous.ogg", false); - } else { - speak_with_history("Missing: " + missing, true); - } -} - -void butcher_small_game_max() { - string missing = ""; - - // Check for knife - if (inv_knives < 1) { - speak_with_history("Missing: Stone Knife", true); - return; - } - - // Check for small game or boar - if (inv_small_game < 1 && inv_boar_carcasses < 1) { - 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) { - speak_with_history("You need a fire within 3 tiles to butcher.", true); - return; - } - - // Calculate space constraints - int meat_space = get_personal_stack_limit() - inv_meat; - int skins_space = get_personal_stack_limit() - inv_skins; - - if (meat_space <= 0) { - speak_with_history("You can't carry any more meat.", true); - return; - } - if (skins_space <= 0) { - speak_with_history("You can't carry any more skins.", true); - return; - } - - // Count available game - int total_game = inv_small_game + inv_boar_carcasses; - - // Determine limiting factor - int max_craft = total_game; - if (meat_space < max_craft) max_craft = meat_space; - if (skins_space < max_craft) max_craft = skins_space; - - if (max_craft <= 0) { - speak_with_history("No space for outputs.", true); - return; - } - - // Each game takes 1 unit of time to butcher, minimum 4 per item - int total_cost = max_craft; // 1 per game - int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; - simulate_crafting(craft_time); - - // Process all game - int total_meat = 0; - int total_skins = 0; - int total_feathers = 0; - int total_down = 0; - int total_sinew = 0; - int geese_count = 0; - int boars_count = 0; - - for (int i = 0; i < max_craft; i++) { - string game_type = ""; - if (inv_boar_carcasses > 0) { - game_type = "boar carcass"; - inv_boar_carcasses--; - boars_count++; - } else { - game_type = inv_small_game_types[0]; - inv_small_game_types.remove_at(0); - inv_small_game--; - if (game_type == "goose") geese_count++; - } - - if (game_type == "goose") { - total_meat++; - total_feathers += random(3, 6); - total_down += random(1, 3); - } else if (game_type == "boar carcass") { - total_meat += random(2, 3); - total_skins += 3; - total_sinew += 2; - } else { - total_meat++; - total_skins++; - } - } - - // Add all outputs at once - inv_meat += total_meat; - inv_skins += total_skins; - inv_feathers += total_feathers; - inv_down += total_down; - inv_sinew += total_sinew; - - // Build result message - string result = "Butchered " + max_craft + " game. Got " + total_meat + " meat"; - if (total_skins > 0) result += ", " + total_skins + " skins"; - if (total_feathers > 0) result += ", feathers"; - if (total_down > 0) result += ", and down"; - if (total_sinew > 0) result += ", and " + total_sinew + " sinew"; - result += "."; - - speak_with_history(result, true); - p.play_stationary("sounds/items/miscellaneous.ogg", false); -} +// Crafting Orchestrator +// +// This file coordinates the crafting system that was previously defined here. +// Individual crafting modules have been split into focused files: +// +// Core (src/crafting/): +// - crafting_core.nvgt - menu entry points and shared helpers +// - craft_weapons.nvgt - weapon recipes +// - craft_tools.nvgt - tool recipes +// - craft_materials.nvgt - material recipes +// - craft_clothing.nvgt - clothing recipes +// - craft_buildings.nvgt - building placement +// - craft_barricade.nvgt - barricade reinforcement + +#include "src/crafting/crafting_core.nvgt" +#include "src/crafting/craft_weapons.nvgt" +#include "src/crafting/craft_tools.nvgt" +#include "src/crafting/craft_materials.nvgt" +#include "src/crafting/craft_clothing.nvgt" +#include "src/crafting/craft_buildings.nvgt" +#include "src/crafting/craft_barricade.nvgt" diff --git a/src/crafting/craft_barricade.nvgt b/src/crafting/craft_barricade.nvgt new file mode 100644 index 0000000..2c4537e --- /dev/null +++ b/src/crafting/craft_barricade.nvgt @@ -0,0 +1,242 @@ +// Crafting barricade reinforcements +void run_barricade_menu() { + if (barricade_health >= BARRICADE_MAX_HEALTH) { + speak_with_history("Barricade is already at full health.", true); + return; + } + + speak_with_history("Barricade.", true); + + int selection = 0; + string[] options; + int[] action_types; // 0 = sticks, 1 = vines, 2 = log, 3 = stones + + if (inv_sticks >= BARRICADE_STICK_COST) { + options.insert_last("Reinforce with sticks (" + BARRICADE_STICK_COST + " sticks, +" + BARRICADE_STICK_HEALTH + " health)"); + action_types.insert_last(0); + } + if (inv_vines >= BARRICADE_VINE_COST) { + options.insert_last("Reinforce with vines (" + BARRICADE_VINE_COST + " vines, +" + BARRICADE_VINE_HEALTH + " health)"); + action_types.insert_last(1); + } + if (inv_logs >= BARRICADE_LOG_COST) { + options.insert_last("Reinforce with log (" + BARRICADE_LOG_COST + " log, +" + BARRICADE_LOG_HEALTH + " health)"); + action_types.insert_last(2); + } + if (inv_stones >= BARRICADE_STONE_COST) { + options.insert_last("Reinforce with stones (" + BARRICADE_STONE_COST + " stones, +" + BARRICADE_STONE_HEALTH + " health)"); + action_types.insert_last(3); + } + + if (options.length() == 0) { + speak_with_history("No materials to reinforce the barricade.", true); + return; + } + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_RETURN)) { + int action = action_types[selection]; + if (action == 0) reinforce_barricade_with_sticks(); + else if (action == 1) reinforce_barricade_with_vines(); + else if (action == 2) reinforce_barricade_with_log(); + else if (action == 3) reinforce_barricade_with_stones(); + break; + } + + if (key_pressed(KEY_TAB)) { + int action = action_types[selection]; + if (action == 0) reinforce_barricade_max_with_sticks(); + else if (action == 1) reinforce_barricade_max_with_vines(); + else if (action == 2) reinforce_barricade_max_with_log(); + else if (action == 3) reinforce_barricade_max_with_stones(); + break; + } + } +} + +void reinforce_barricade_with_sticks() { + if (barricade_health >= BARRICADE_MAX_HEALTH) { + speak_with_history("Barricade is already at full health.", true); + return; + } + if (inv_sticks < BARRICADE_STICK_COST) { + 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); + 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) { + speak_with_history("Barricade is already at full health.", true); + return; + } + if (inv_vines < BARRICADE_VINE_COST) { + 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); + 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) { + speak_with_history("Barricade is already at full health.", true); + return; + } + if (inv_logs < BARRICADE_LOG_COST) { + 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); + 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) { + speak_with_history("Barricade is already at full health.", true); + return; + } + if (inv_stones < BARRICADE_STONE_COST) { + 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); + 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) { + speak_with_history("Barricade is already at full health.", true); + return; + } + + if (inv_sticks < BARRICADE_STICK_COST) { + speak_with_history("Missing: " + BARRICADE_STICK_COST + " sticks", true); + return; + } + + int health_needed = BARRICADE_MAX_HEALTH - barricade_health; + int max_reinforcements = (health_needed + BARRICADE_STICK_HEALTH - 1) / BARRICADE_STICK_HEALTH; + int can_afford = inv_sticks / BARRICADE_STICK_COST; + + int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford; + int total_cost = to_do * BARRICADE_STICK_COST; + + simulate_crafting(total_cost); + inv_sticks -= total_cost; + barricade_health += (to_do * BARRICADE_STICK_HEALTH); + if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; + + 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) { + speak_with_history("Barricade is already at full health.", true); + return; + } + + if (inv_vines < BARRICADE_VINE_COST) { + speak_with_history("Missing: " + BARRICADE_VINE_COST + " vines", true); + return; + } + + int health_needed = BARRICADE_MAX_HEALTH - barricade_health; + int max_reinforcements = (health_needed + BARRICADE_VINE_HEALTH - 1) / BARRICADE_VINE_HEALTH; + int can_afford = inv_vines / BARRICADE_VINE_COST; + + int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford; + int total_cost = to_do * BARRICADE_VINE_COST; + + simulate_crafting(total_cost); + inv_vines -= total_cost; + barricade_health += (to_do * BARRICADE_VINE_HEALTH); + if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; + + 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) { + speak_with_history("Barricade is already at full health.", true); + return; + } + + if (inv_logs < BARRICADE_LOG_COST) { + speak_with_history("Missing: " + BARRICADE_LOG_COST + " log", true); + return; + } + + int health_needed = BARRICADE_MAX_HEALTH - barricade_health; + int max_reinforcements = (health_needed + BARRICADE_LOG_HEALTH - 1) / BARRICADE_LOG_HEALTH; + int can_afford = inv_logs / BARRICADE_LOG_COST; + + int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford; + int total_cost = to_do * BARRICADE_LOG_COST; + + simulate_crafting(total_cost); + inv_logs -= total_cost; + barricade_health += (to_do * BARRICADE_LOG_HEALTH); + if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; + + 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) { + speak_with_history("Barricade is already at full health.", true); + return; + } + + if (inv_stones < BARRICADE_STONE_COST) { + speak_with_history("Missing: " + BARRICADE_STONE_COST + " stones", true); + return; + } + + int health_needed = BARRICADE_MAX_HEALTH - barricade_health; + int max_reinforcements = (health_needed + BARRICADE_STONE_HEALTH - 1) / BARRICADE_STONE_HEALTH; + int can_afford = inv_stones / BARRICADE_STONE_COST; + + int to_do = (max_reinforcements < can_afford) ? max_reinforcements : can_afford; + int total_cost = to_do * BARRICADE_STONE_COST; + + simulate_crafting(total_cost); + inv_stones -= total_cost; + barricade_health += (to_do * BARRICADE_STONE_HEALTH); + if (barricade_health > BARRICADE_MAX_HEALTH) barricade_health = BARRICADE_MAX_HEALTH; + + speak_with_history("Reinforced barricade " + to_do + " times with stones. Health now " + barricade_health + ".", true); +} diff --git a/src/crafting/craft_buildings.nvgt b/src/crafting/craft_buildings.nvgt new file mode 100644 index 0000000..21763a1 --- /dev/null +++ b/src/crafting/craft_buildings.nvgt @@ -0,0 +1,251 @@ +// Crafting buildings +void run_buildings_menu() { + speak_with_history("Buildings.", true); + + int selection = 0; + 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); + + // Only show herb garden if not already built in base + if (get_herb_garden_at_base() == null) { + options.insert_last("Herb Garden (9 Stones, 3 Vines, 2 Logs) [Base Only]"); + building_types.insert_last(2); + } + + // Only show storage if none built yet + if (world_storages.length() == 0) { + options.insert_last("Storage (6 Logs, 9 Stones, 8 Vines) [Base Only]"); + building_types.insert_last(3); + } + + // Only show pasture if not built + if (world_pastures.length() == 0) { + options.insert_last("Pasture (8 Logs, 20 Vines) [Base Only]"); + building_types.insert_last(4); + } + + // Only show stable if not built + if (world_stables.length() == 0) { + options.insert_last("Stable (10 Logs, 15 Stones, 10 Vines) [Base Only]"); + building_types.insert_last(5); + } + + // Only show altar if not built + if (world_altars.length() == 0) { + options.insert_last("Altar (9 Stones, 3 Sticks) [Base Only]"); + building_types.insert_last(6); + } + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_RETURN)) { + int building = building_types[selection]; + if (building == 0) craft_firepit(); + else if (building == 1) craft_campfire(); + else if (building == 2) craft_herb_garden(); + else if (building == 3) craft_storage(); + else if (building == 4) craft_pasture(); + else if (building == 5) craft_stable(); + else if (building == 6) craft_altar(); + break; + } + } +} + +void craft_firepit() { + // Check if there's already a firepit here + if (get_firepit_at(x) != null) { + speak_with_history("There is already a firepit here.", true); + return; + } + + string missing = ""; + if (inv_stones < 9) missing += "9 stones "; + + if (missing == "") { + simulate_crafting(9); + inv_stones -= 9; + add_world_firepit(x); + speak_with_history("Firepit built here.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_campfire() { + // Check if there's a firepit within 2 tiles + WorldFirepit@ firepit = get_firepit_near(x, 2); + if (firepit == null) { + speak_with_history("You need a firepit within 2 tiles to build a fire.", true); + return; + } + + string missing = ""; + if (inv_logs < 1) missing += "1 log "; + if (inv_sticks < 2) missing += "2 sticks "; + + if (missing == "") { + simulate_crafting(3); + inv_logs--; + inv_sticks -= 2; + // Build the fire at the firepit location, not player location + add_world_fire(firepit.position); + speak_with_history("Fire built at firepit.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_herb_garden() { + // Can only build in base area + if (x > BASE_END) { + 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) { + speak_with_history("There is already an herb garden in the base.", true); + return; + } + + string missing = ""; + if (inv_stones < 9) missing += "9 stones "; + if (inv_vines < 3) missing += "3 vines "; + if (inv_logs < 2) missing += "2 logs "; + + if (missing == "") { + simulate_crafting(14); + inv_stones -= 9; + inv_vines -= 3; + inv_logs -= 2; + add_world_herb_garden(x); + speak_with_history("Herb garden built. The base now heals faster.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_storage() { + if (x > BASE_END) { + speak_with_history("Storage must be built in the base.", true); + return; + } + if (world_storages.length() > 0) { + speak_with_history("Storage already built.", true); + return; + } + string missing = ""; + if (inv_logs < STORAGE_LOG_COST) missing += STORAGE_LOG_COST + " logs "; + if (inv_stones < STORAGE_STONE_COST) missing += STORAGE_STONE_COST + " stones "; + if (inv_vines < STORAGE_VINE_COST) missing += STORAGE_VINE_COST + " vines "; + + if (missing == "") { + simulate_crafting(23); + inv_logs -= STORAGE_LOG_COST; + inv_stones -= STORAGE_STONE_COST; + inv_vines -= STORAGE_VINE_COST; + add_world_storage(x); + speak_with_history("Storage built.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_pasture() { + if (x > BASE_END) { + speak_with_history("Pasture must be built in the base.", true); + return; + } + if (world_pastures.length() > 0) { + speak_with_history("Pasture already built.", true); + return; + } + string missing = ""; + if (inv_logs < PASTURE_LOG_COST) missing += PASTURE_LOG_COST + " logs "; + if (inv_vines < PASTURE_VINE_COST) missing += PASTURE_VINE_COST + " vines "; + + if (missing == "") { + simulate_crafting(28); + inv_logs -= PASTURE_LOG_COST; + inv_vines -= PASTURE_VINE_COST; + add_world_pasture(x); + speak_with_history("Pasture built.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_stable() { + if (x > BASE_END) { + speak_with_history("Stable must be built in the base.", true); + return; + } + if (world_stables.length() > 0) { + speak_with_history("Stable already built.", true); + return; + } + string missing = ""; + if (inv_logs < STABLE_LOG_COST) missing += STABLE_LOG_COST + " logs "; + if (inv_stones < STABLE_STONE_COST) missing += STABLE_STONE_COST + " stones "; + if (inv_vines < STABLE_VINE_COST) missing += STABLE_VINE_COST + " vines "; + + if (missing == "") { + simulate_crafting(35); + inv_logs -= STABLE_LOG_COST; + inv_stones -= STABLE_STONE_COST; + inv_vines -= STABLE_VINE_COST; + add_world_stable(x); + speak_with_history("Stable built.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_altar() { + if (x > BASE_END) { + speak_with_history("Altar must be built in the base.", true); + return; + } + if (world_altars.length() > 0) { + speak_with_history("Altar already built.", true); + return; + } + string missing = ""; + if (inv_stones < ALTAR_STONE_COST) missing += ALTAR_STONE_COST + " stones "; + if (inv_sticks < ALTAR_STICK_COST) missing += ALTAR_STICK_COST + " sticks "; + + if (missing == "") { + simulate_crafting(12); + inv_stones -= ALTAR_STONE_COST; + inv_sticks -= ALTAR_STICK_COST; + add_world_altar(x); + speak_with_history("Altar built.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} diff --git a/src/crafting/craft_clothing.nvgt b/src/crafting/craft_clothing.nvgt new file mode 100644 index 0000000..5494cf2 --- /dev/null +++ b/src/crafting/craft_clothing.nvgt @@ -0,0 +1,359 @@ +// Crafting clothing +void run_clothing_menu() { + speak_with_history("Clothing.", true); + + int selection = 0; + string[] options = { + "Skin Hat (1 Skin, 1 Vine)", + "Skin Gloves (1 Skin, 1 Vine)", + "Skin Pants (6 Skins, 3 Vines)", + "Skin Tunic (4 Skins, 2 Vines)", + "Moccasins (2 Skins, 1 Vine)", + "Skin Pouch (2 Skins, 1 Vine)" + }; + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_RETURN)) { + if (selection == 0) craft_skin_hat(); + else if (selection == 1) craft_skin_gloves(); + else if (selection == 2) craft_skin_pants(); + else if (selection == 3) craft_skin_tunic(); + else if (selection == 4) craft_moccasins(); + else if (selection == 5) craft_skin_pouch(); + break; + } + + if (key_pressed(KEY_TAB)) { + if (selection == 0) craft_skin_hat_max(); + else if (selection == 1) craft_skin_gloves_max(); + else if (selection == 2) craft_skin_pants_max(); + else if (selection == 3) craft_skin_tunic_max(); + else if (selection == 4) craft_moccasins_max(); + else if (selection == 5) craft_skin_pouch_max(); + break; + } + } +} + +void craft_skin_hat() { + string missing = ""; + if (inv_skins < 1) missing += "1 skin "; + if (inv_vines < 1) missing += "1 vine "; + + if (missing == "") { + if (inv_skin_hats >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more skin hats.", true); + return; + } + simulate_crafting(2); + inv_skins--; + inv_vines--; + inv_skin_hats++; + speak_with_history("Crafted a Skin Hat.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_skin_hat_max() { + if (inv_skin_hats >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more skin hats.", true); + return; + } + + int max_by_skins = inv_skins; + int max_by_vines = inv_vines; + int max_craft = max_by_skins; + if (max_by_vines < max_craft) max_craft = max_by_vines; + + int space = get_personal_stack_limit() - inv_skin_hats; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_skins < 1) missing += "1 skin "; + if (inv_vines < 1) missing += "1 vine "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 2; // 1 skin + 1 vine per hat + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_skins -= max_craft; + inv_vines -= max_craft; + inv_skin_hats += max_craft; + speak_with_history("Crafted " + max_craft + " Skin Hats.", true); +} + +void craft_skin_gloves() { + string missing = ""; + if (inv_skins < 1) missing += "1 skin "; + if (inv_vines < 1) missing += "1 vine "; + + if (missing == "") { + if (inv_skin_gloves >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more skin gloves.", true); + return; + } + simulate_crafting(2); + inv_skins--; + inv_vines--; + inv_skin_gloves++; + speak_with_history("Crafted Skin Gloves.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_skin_gloves_max() { + if (inv_skin_gloves >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more skin gloves.", true); + return; + } + + int max_by_skins = inv_skins; + int max_by_vines = inv_vines; + int max_craft = max_by_skins; + if (max_by_vines < max_craft) max_craft = max_by_vines; + + int space = get_personal_stack_limit() - inv_skin_gloves; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_skins < 1) missing += "1 skin "; + if (inv_vines < 1) missing += "1 vine "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 2; // 1 skin + 1 vine per gloves + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_skins -= max_craft; + inv_vines -= max_craft; + inv_skin_gloves += max_craft; + speak_with_history("Crafted " + max_craft + " Skin Gloves.", true); +} + +void craft_skin_pants() { + string missing = ""; + if (inv_skins < 6) missing += "6 skins "; + if (inv_vines < 3) missing += "3 vines "; + + if (missing == "") { + if (inv_skin_pants >= get_personal_stack_limit()) { + 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++; + speak_with_history("Crafted Skin Pants.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_skin_pants_max() { + if (inv_skin_pants >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more skin pants.", true); + return; + } + + int max_by_skins = inv_skins / 6; + int max_by_vines = inv_vines / 3; + int max_craft = max_by_skins; + if (max_by_vines < max_craft) max_craft = max_by_vines; + + int space = get_personal_stack_limit() - inv_skin_pants; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_skins < 6) missing += "6 skins "; + if (inv_vines < 3) missing += "3 vines "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 9; // 6 skins + 3 vines per pants + simulate_crafting(total_cost); + inv_skins -= (max_craft * 6); + inv_vines -= (max_craft * 3); + inv_skin_pants += max_craft; + speak_with_history("Crafted " + max_craft + " Skin Pants.", true); +} + +void craft_skin_tunic() { + string missing = ""; + if (inv_skins < 4) missing += "4 skins "; + if (inv_vines < 2) missing += "2 vines "; + + if (missing == "") { + if (inv_skin_tunics >= get_personal_stack_limit()) { + 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++; + speak_with_history("Crafted a Skin Tunic.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_skin_tunic_max() { + if (inv_skin_tunics >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more skin tunics.", true); + return; + } + + int max_by_skins = inv_skins / 4; + int max_by_vines = inv_vines / 2; + int max_craft = max_by_skins; + if (max_by_vines < max_craft) max_craft = max_by_vines; + + int space = get_personal_stack_limit() - inv_skin_tunics; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_skins < 4) missing += "4 skins "; + if (inv_vines < 2) missing += "2 vines "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 6; // 4 skins + 2 vines per tunic + simulate_crafting(total_cost); + inv_skins -= (max_craft * 4); + inv_vines -= (max_craft * 2); + inv_skin_tunics += max_craft; + speak_with_history("Crafted " + max_craft + " Skin Tunics.", true); +} + +void craft_moccasins() { + string missing = ""; + if (inv_skins < 2) missing += "2 skins "; + if (inv_vines < 1) missing += "1 vine "; + + if (missing == "") { + if (inv_moccasins >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more moccasins.", true); + return; + } + simulate_crafting(3); + inv_skins -= 2; + inv_vines--; + inv_moccasins++; + speak_with_history("Crafted moccasins.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_moccasins_max() { + if (inv_moccasins >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more moccasins.", true); + return; + } + + int max_by_skins = inv_skins / 2; + int max_by_vines = inv_vines; + int max_craft = max_by_skins; + if (max_by_vines < max_craft) max_craft = max_by_vines; + + int space = get_personal_stack_limit() - inv_moccasins; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_skins < 2) missing += "2 skins "; + if (inv_vines < 1) missing += "1 vine "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 3; // 2 skins + 1 vine per moccasins + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_skins -= (max_craft * 2); + inv_vines -= max_craft; + inv_moccasins += max_craft; + speak_with_history("Crafted " + max_craft + " Moccasins.", true); +} + +void craft_skin_pouch() { + string missing = ""; + if (inv_skins < 2) missing += "2 skins "; + if (inv_vines < 1) missing += "1 vine "; + + if (missing == "") { + if (inv_skin_pouches >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more skin pouches.", true); + return; + } + simulate_crafting(3); + inv_skins -= 2; + inv_vines--; + inv_skin_pouches++; + speak_with_history("Crafted a Skin Pouch.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_skin_pouch_max() { + if (inv_skin_pouches >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more skin pouches.", true); + return; + } + + int max_by_skins = inv_skins / 2; + int max_by_vines = inv_vines; + int max_craft = max_by_skins; + if (max_by_vines < max_craft) max_craft = max_by_vines; + + int space = get_personal_stack_limit() - inv_skin_pouches; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_skins < 2) missing += "2 skins "; + if (inv_vines < 1) missing += "1 vine "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 3; // 2 skins + 1 vine per pouch + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_skins -= (max_craft * 2); + inv_vines -= max_craft; + inv_skin_pouches += max_craft; + speak_with_history("Crafted " + max_craft + " Skin Pouches.", true); +} diff --git a/src/crafting/craft_materials.nvgt b/src/crafting/craft_materials.nvgt new file mode 100644 index 0000000..6427875 --- /dev/null +++ b/src/crafting/craft_materials.nvgt @@ -0,0 +1,277 @@ +// Crafting materials +void run_materials_menu() { + speak_with_history("Materials.", true); + + int selection = 0; + string[] options = { + "Butcher Small Game (1 Small Game) [Requires Knife and Fire nearby]", + "Incense (6 Sticks, 2 Vines, 1 Reed) [Requires Altar]" + }; + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_RETURN)) { + if (selection == 0) butcher_small_game(); + else if (selection == 1) craft_incense(); + break; + } + + if (key_pressed(KEY_TAB)) { + if (selection == 0) butcher_small_game_max(); + else if (selection == 1) craft_incense_max(); + break; + } + } +} + +void craft_incense() { + if (world_altars.length() == 0) { + speak_with_history("You need an altar to craft incense.", true); + return; + } + + string missing = ""; + 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 "; + + if (missing == "") { + if (inv_incense >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more incense.", true); + return; + } + simulate_crafting(INCENSE_STICK_COST + INCENSE_VINE_COST + INCENSE_REED_COST); + inv_sticks -= INCENSE_STICK_COST; + inv_vines -= INCENSE_VINE_COST; + inv_reeds -= INCENSE_REED_COST; + inv_incense++; + speak_with_history("Crafted incense.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_incense_max() { + if (world_altars.length() == 0) { + speak_with_history("You need an altar to craft incense.", true); + return; + } + + if (inv_incense >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more incense.", true); + return; + } + + int max_by_sticks = inv_sticks / INCENSE_STICK_COST; + int max_by_vines = inv_vines / INCENSE_VINE_COST; + int max_by_reeds = inv_reeds / INCENSE_REED_COST; + int max_craft = max_by_sticks; + if (max_by_vines < max_craft) max_craft = max_by_vines; + if (max_by_reeds < max_craft) max_craft = max_by_reeds; + + int space = get_personal_stack_limit() - inv_incense; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + 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 "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = (max_craft * INCENSE_STICK_COST) + (max_craft * INCENSE_VINE_COST) + (max_craft * INCENSE_REED_COST); + simulate_crafting(total_cost); + inv_sticks -= (max_craft * INCENSE_STICK_COST); + inv_vines -= (max_craft * INCENSE_VINE_COST); + inv_reeds -= (max_craft * INCENSE_REED_COST); + inv_incense += max_craft; + speak_with_history("Crafted " + max_craft + " Incense.", true); +} + +void butcher_small_game() { + string missing = ""; + + // Check for knife + if (inv_knives < 1) missing += "Stone Knife "; + + // Check for small game or boar + if (inv_small_game < 1 && inv_boar_carcasses < 1) missing += "Game "; + + // Check for fire within 3 tiles (can hear it) + WorldFire@ fire = get_fire_within_range(x, 3); + if (fire == null) { + speak_with_history("You need a fire within 3 tiles to butcher.", true); + return; + } + + if (missing == "") { + if (inv_meat >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more meat.", true); + return; + } + if (inv_skins >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more skins.", true); + return; + } + simulate_crafting(1); + + string game_type = ""; + if (inv_boar_carcasses > 0) { + game_type = "boar carcass"; + inv_boar_carcasses--; + } else { + game_type = inv_small_game_types[0]; + inv_small_game_types.remove_at(0); + inv_small_game--; + } + + if (game_type == "goose") { + inv_meat++; + inv_feathers += random(3, 6); + inv_down += random(1, 3); + 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; + speak_with_history("Butchered boar. Got meat, 3 skins, and 2 sinew.", true); + } else { + inv_meat++; + inv_skins++; + speak_with_history("Butchered " + game_type + ". Got 1 meat and 1 skin.", true); + } + + // Play sound + p.play_stationary("sounds/items/miscellaneous.ogg", false); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void butcher_small_game_max() { + string missing = ""; + + // Check for knife + if (inv_knives < 1) { + speak_with_history("Missing: Stone Knife", true); + return; + } + + // Check for small game or boar + if (inv_small_game < 1 && inv_boar_carcasses < 1) { + 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) { + speak_with_history("You need a fire within 3 tiles to butcher.", true); + return; + } + + // Calculate space constraints + int meat_space = get_personal_stack_limit() - inv_meat; + int skins_space = get_personal_stack_limit() - inv_skins; + + if (meat_space <= 0) { + speak_with_history("You can't carry any more meat.", true); + return; + } + if (skins_space <= 0) { + speak_with_history("You can't carry any more skins.", true); + return; + } + + // Count available game + int total_game = inv_small_game + inv_boar_carcasses; + + // Determine limiting factor + int max_craft = total_game; + if (meat_space < max_craft) max_craft = meat_space; + if (skins_space < max_craft) max_craft = skins_space; + + if (max_craft <= 0) { + speak_with_history("No space for outputs.", true); + return; + } + + // Each game takes 1 unit of time to butcher, minimum 4 per item + int total_cost = max_craft; // 1 per game + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + + // Process all game + int total_meat = 0; + int total_skins = 0; + int total_feathers = 0; + int total_down = 0; + int total_sinew = 0; + int geese_count = 0; + int boars_count = 0; + + for (int i = 0; i < max_craft; i++) { + string game_type = ""; + if (inv_boar_carcasses > 0) { + game_type = "boar carcass"; + inv_boar_carcasses--; + boars_count++; + } else { + game_type = inv_small_game_types[0]; + inv_small_game_types.remove_at(0); + inv_small_game--; + if (game_type == "goose") geese_count++; + } + + if (game_type == "goose") { + total_meat++; + total_feathers += random(3, 6); + total_down += random(1, 3); + } else if (game_type == "boar carcass") { + total_meat += random(2, 3); + total_skins += 3; + total_sinew += 2; + } else { + total_meat++; + total_skins++; + } + } + + // Add all outputs at once + inv_meat += total_meat; + inv_skins += total_skins; + inv_feathers += total_feathers; + inv_down += total_down; + inv_sinew += total_sinew; + + // Build result message + string result = "Butchered " + max_craft + " game. Got " + total_meat + " meat"; + if (total_skins > 0) result += ", " + total_skins + " skins"; + if (total_feathers > 0) result += ", feathers"; + if (total_down > 0) result += ", and down"; + if (total_sinew > 0) result += ", and " + total_sinew + " sinew"; + result += "."; + + speak_with_history(result, true); + p.play_stationary("sounds/items/miscellaneous.ogg", false); +} diff --git a/src/crafting/craft_tools.nvgt b/src/crafting/craft_tools.nvgt new file mode 100644 index 0000000..c86c0c0 --- /dev/null +++ b/src/crafting/craft_tools.nvgt @@ -0,0 +1,341 @@ +// Crafting tools +void run_tools_menu() { + speak_with_history("Tools.", true); + + int selection = 0; + string[] options = { + "Stone Knife (2 Stones)", + "Snare (1 Stick, 2 Vines)", + "Stone Axe (1 Stick, 1 Vine, 2 Stones) [Requires Knife]", + "Fishing Pole (1 Stick, 2 Vines)", + "Rope (3 Vines)", + "Reed Basket (3 Reeds)", + "Clay Pot (3 Clay)" + }; + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_RETURN)) { + if (selection == 0) craft_knife(); + else if (selection == 1) craft_snare(); + else if (selection == 2) craft_axe(); + else if (selection == 3) craft_fishing_pole(); + else if (selection == 4) craft_rope(); + else if (selection == 5) craft_reed_basket(); + else if (selection == 6) craft_clay_pot(); + break; + } + + if (key_pressed(KEY_TAB)) { + if (selection == 0) craft_knife_max(); + else if (selection == 1) craft_snare_max(); + else if (selection == 2) craft_axe_max(); + else if (selection == 3) craft_fishing_pole_max(); + else if (selection == 4) craft_rope_max(); + else if (selection == 5) craft_reed_basket_max(); + else if (selection == 6) craft_clay_pot_max(); + break; + } + } +} + +void craft_knife() { + string missing = ""; + if (inv_stones < 2) missing += "2 stones "; + + if (missing == "") { + if (inv_knives >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more stone knives.", true); + return; + } + simulate_crafting(2); + inv_stones -= 2; + inv_knives++; + speak_with_history("Crafted a Stone Knife.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_knife_max() { + if (inv_knives >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more stone knives.", true); + return; + } + + int max_possible = inv_stones / 2; + int space = get_personal_stack_limit() - inv_knives; + if (max_possible > space) max_possible = space; + + if (max_possible <= 0) { + speak_with_history("Missing: 2 stones", true); + return; + } + + int total_cost = max_possible * 2; + int craft_time = (total_cost < max_possible * 4) ? max_possible * 4 : total_cost; + simulate_crafting(craft_time); + inv_stones -= (max_possible * 2); + inv_knives += max_possible; + speak_with_history("Crafted " + max_possible + " Stone Knives.", true); +} + +void craft_snare() { + string missing = ""; + if (inv_sticks < 1) missing += "1 stick "; + if (inv_vines < 2) missing += "2 vines "; + + if (missing == "") { + if (inv_snares >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more snares.", true); + return; + } + simulate_crafting(3); + inv_sticks--; + inv_vines -= 2; + inv_snares++; + speak_with_history("Crafted a Snare.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_snare_max() { + if (inv_snares >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more snares.", true); + return; + } + + int max_by_sticks = inv_sticks; + int max_by_vines = inv_vines / 2; + int max_craft = max_by_sticks; + if (max_by_vines < max_craft) max_craft = max_by_vines; + + int space = get_personal_stack_limit() - inv_snares; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_sticks < 1) missing += "1 stick "; + if (inv_vines < 2) missing += "2 vines "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 3; // 1 stick + 2 vines per snare + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_sticks -= max_craft; + inv_vines -= (max_craft * 2); + inv_snares += max_craft; + speak_with_history("Crafted " + max_craft + " Snares.", true); +} + +void craft_fishing_pole() { + string missing = ""; + if (inv_sticks < 1) missing += "1 stick "; + if (inv_vines < 2) missing += "2 vines "; + + if (missing == "") { + if (inv_fishing_poles >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more fishing poles.", true); + return; + } + simulate_crafting(3); + inv_sticks--; + inv_vines -= 2; + inv_fishing_poles++; + speak_with_history("Crafted a Fishing Pole.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_fishing_pole_max() { + if (inv_fishing_poles >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more fishing poles.", true); + return; + } + + int max_by_sticks = inv_sticks; + int max_by_vines = inv_vines / 2; + int max_craft = max_by_sticks; + if (max_by_vines < max_craft) max_craft = max_by_vines; + + int space = get_personal_stack_limit() - inv_fishing_poles; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_sticks < 1) missing += "1 stick "; + if (inv_vines < 2) missing += "2 vines "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 3; // 1 stick + 2 vines per pole + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_sticks -= max_craft; + inv_vines -= (max_craft * 2); + inv_fishing_poles += max_craft; + speak_with_history("Crafted " + max_craft + " Fishing Poles.", true); +} + +void craft_rope() { + string missing = ""; + if (inv_vines < 3) missing += "3 vines "; + + if (missing == "") { + if (inv_ropes >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more rope.", true); + return; + } + simulate_crafting(3); + inv_vines -= 3; + inv_ropes++; + speak_with_history("Crafted rope.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_rope_max() { + if (inv_ropes >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more rope.", true); + return; + } + + int max_craft = inv_vines / 3; + + int space = get_personal_stack_limit() - inv_ropes; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + speak_with_history("Missing: 3 vines", true); + return; + } + + int total_cost = max_craft * 3; // 3 vines per rope + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_vines -= (max_craft * 3); + inv_ropes += max_craft; + speak_with_history("Crafted " + max_craft + " Rope.", true); +} + +void craft_reed_basket() { + string missing = ""; + if (inv_reeds < 3) missing += "3 reeds "; + + if (missing == "") { + if (inv_reed_baskets >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more reed baskets.", true); + return; + } + simulate_crafting(3); + inv_reeds -= 3; + inv_reed_baskets++; + speak_with_history("Crafted a reed basket.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_reed_basket_max() { + if (inv_reed_baskets >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more reed baskets.", true); + return; + } + + int max_craft = inv_reeds / 3; + + int space = get_personal_stack_limit() - inv_reed_baskets; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + speak_with_history("Missing: 3 reeds", true); + return; + } + + int total_cost = max_craft * 3; // 3 reeds per basket + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_reeds -= (max_craft * 3); + inv_reed_baskets += max_craft; + speak_with_history("Crafted " + max_craft + " Reed Baskets.", true); +} + +void craft_clay_pot() { + string missing = ""; + if (inv_clay < 3) missing += "3 clay "; + + // Check for fire within 3 tiles (can hear it) + WorldFire@ fire = get_fire_within_range(x, 3); + if (fire == null) { + 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()) { + speak_with_history("You can't carry any more clay pots.", true); + return; + } + simulate_crafting(3); + inv_clay -= 3; + inv_clay_pots++; + speak_with_history("Crafted a clay pot.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +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) { + speak_with_history("You need a fire within 3 tiles to craft clay pots.", true); + return; + } + + if (inv_clay_pots >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more clay pots.", true); + return; + } + + int max_craft = inv_clay / 3; + + int space = get_personal_stack_limit() - inv_clay_pots; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + speak_with_history("Missing: 3 clay", true); + return; + } + + int total_cost = max_craft * 3; // 3 clay per pot + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_clay -= (max_craft * 3); + inv_clay_pots += max_craft; + speak_with_history("Crafted " + max_craft + " Clay Pots.", true); +} diff --git a/src/crafting/craft_weapons.nvgt b/src/crafting/craft_weapons.nvgt new file mode 100644 index 0000000..044035f --- /dev/null +++ b/src/crafting/craft_weapons.nvgt @@ -0,0 +1,217 @@ +// Crafting weapons +void run_weapons_menu() { + speak_with_history("Weapons.", true); + + int selection = 0; + string[] options = { + "Spear (1 Stick, 1 Vine, 1 Stone) [Requires Knife]", + "Sling (1 Skin, 2 Vines)" + }; + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_RETURN)) { + if (selection == 0) craft_spear(); + else if (selection == 1) craft_sling(); + break; + } + + if (key_pressed(KEY_TAB)) { + if (selection == 0) craft_spear_max(); + else if (selection == 1) craft_sling_max(); + break; + } + } +} + +void craft_spear() { + string missing = ""; + if (inv_knives < 1) missing += "Stone Knife "; + if (inv_sticks < 1) missing += "1 stick "; + if (inv_vines < 1) missing += "1 vine "; + if (inv_stones < 1) missing += "1 stone "; + + if (missing == "") { + if (inv_spears >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more spears.", true); + return; + } + simulate_crafting(3); + inv_sticks--; + inv_vines--; + inv_stones--; + inv_spears++; + speak_with_history("Crafted a Spear.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_spear_max() { + if (inv_knives < 1) { + speak_with_history("Missing: Stone Knife", true); + return; + } + if (inv_spears >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more spears.", true); + return; + } + + int max_by_sticks = inv_sticks; + int max_by_vines = inv_vines; + int max_by_stones = inv_stones; + int max_craft = max_by_sticks; + if (max_by_vines < max_craft) max_craft = max_by_vines; + if (max_by_stones < max_craft) max_craft = max_by_stones; + + int space = get_personal_stack_limit() - inv_spears; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_sticks < 1) missing += "1 stick "; + if (inv_vines < 1) missing += "1 vine "; + if (inv_stones < 1) missing += "1 stone "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 3; // 1 stick + 1 vine + 1 stone per spear + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_sticks -= max_craft; + inv_vines -= max_craft; + inv_stones -= max_craft; + inv_spears += max_craft; + speak_with_history("Crafted " + max_craft + " Spears.", true); +} + +void craft_sling() { + string missing = ""; + if (inv_skins < 1) missing += "1 skin "; + if (inv_vines < 2) missing += "2 vines "; + + if (missing == "") { + if (inv_slings >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more slings.", true); + return; + } + simulate_crafting(3); + inv_skins--; + inv_vines -= 2; + inv_slings++; + speak_with_history("Crafted a Sling.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_sling_max() { + if (inv_slings >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more slings.", true); + return; + } + + int max_by_skins = inv_skins; + int max_by_vines = inv_vines / 2; + int max_craft = max_by_skins; + if (max_by_vines < max_craft) max_craft = max_by_vines; + + int space = get_personal_stack_limit() - inv_slings; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_skins < 1) missing += "1 skin "; + if (inv_vines < 2) missing += "2 vines "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 3; // 1 skin + 2 vines per sling + int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; + simulate_crafting(craft_time); + inv_skins -= max_craft; + inv_vines -= (max_craft * 2); + inv_slings += max_craft; + speak_with_history("Crafted " + max_craft + " Slings.", true); +} + +void craft_axe() { + string missing = ""; + if (inv_knives < 1) missing += "Stone Knife "; + if (inv_sticks < 1) missing += "1 stick "; + if (inv_vines < 1) missing += "1 vine "; + if (inv_stones < 2) missing += "2 stones "; + + if (missing == "") { + if (inv_axes >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more stone axes.", true); + return; + } + simulate_crafting(4); + inv_sticks--; + inv_vines--; + inv_stones -= 2; + inv_axes++; + speak_with_history("Crafted a Stone Axe.", true); + } else { + speak_with_history("Missing: " + missing, true); + } +} + +void craft_axe_max() { + if (inv_knives < 1) { + speak_with_history("Missing: Stone Knife", true); + return; + } + if (inv_axes >= get_personal_stack_limit()) { + speak_with_history("You can't carry any more stone axes.", true); + return; + } + + int max_by_sticks = inv_sticks; + int max_by_vines = inv_vines; + int max_by_stones = inv_stones / 2; + int max_craft = max_by_sticks; + if (max_by_vines < max_craft) max_craft = max_by_vines; + if (max_by_stones < max_craft) max_craft = max_by_stones; + + int space = get_personal_stack_limit() - inv_axes; + if (max_craft > space) max_craft = space; + + if (max_craft <= 0) { + string missing = ""; + if (inv_sticks < 1) missing += "1 stick "; + if (inv_vines < 1) missing += "1 vine "; + if (inv_stones < 2) missing += "2 stones "; + speak_with_history("Missing: " + missing, true); + return; + } + + int total_cost = max_craft * 4; // 1 stick + 1 vine + 2 stones per axe + simulate_crafting(total_cost); + inv_sticks -= max_craft; + inv_vines -= max_craft; + inv_stones -= (max_craft * 2); + inv_axes += max_craft; + speak_with_history("Crafted " + max_craft + " Stone Axes.", true); +} diff --git a/src/crafting/crafting_core.nvgt b/src/crafting/crafting_core.nvgt new file mode 100644 index 0000000..4800caf --- /dev/null +++ b/src/crafting/crafting_core.nvgt @@ -0,0 +1,67 @@ +// Crafting core menu and shared helpers +void check_crafting_menu(int x, int base_end_tile) { + if (x <= base_end_tile) { + if (key_pressed(KEY_C)) { + run_crafting_menu(); + } + } +} + +void run_crafting_menu() { + speak_with_history("Crafting menu.", true); + + int selection = 0; + string[] categories = {"Weapons", "Tools", "Materials", "Clothing", "Buildings", "Barricade"}; + int[] category_types = {0, 1, 2, 3, 4, 5}; + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= categories.length()) selection = 0; + speak_with_history(categories[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = categories.length() - 1; + speak_with_history(categories[selection], true); + } + + if (key_pressed(KEY_RETURN)) { + int category = category_types[selection]; + if (category == 0) run_weapons_menu(); + else if (category == 1) run_tools_menu(); + else if (category == 2) run_materials_menu(); + else if (category == 3) run_clothing_menu(); + else if (category == 4) run_buildings_menu(); + else if (category == 5) run_barricade_menu(); + break; + } + } +} + +void simulate_crafting(int item_count) { + speak_with_history("Crafting...", true); + // Nothing should take less than 4. + if(item_count < 4) { + item_count = 4; + } + for(int i = 0; i < item_count; i++) { + float pitch = random(85, 115); + p.play_stationary_extended("sounds/crafting.ogg", false, 0, 0, 0, pitch); + + timer t; + while(t.elapsed < 800) { + wait(5); + menu_background_tick(); + } + } + p.play_stationary("sounds/crafting_complete.ogg", false); +} diff --git a/src/inventory_menus.nvgt b/src/inventory_menus.nvgt index 5815c34..62d53e1 100644 --- a/src/inventory_menus.nvgt +++ b/src/inventory_menus.nvgt @@ -1,4 +1,31 @@ -// Inventory and base menus +// Inventory and menu system orchestrator +// This file loads all menu subsystems in the correct dependency order + +// Menu utilities (must be first - provides menu_background_tick used by all menus) +#include "menus/menu_utils.nvgt" + +// Personal inventory +#include "menus/inventory_core.nvgt" + +// Base storage +#include "menus/storage_menu.nvgt" + +// Equipment management +#include "menus/equipment_menu.nvgt" + +// Action menu (context-sensitive) +#include "menus/action_menu.nvgt" + +// Character info display +#include "menus/character_info.nvgt" + +// Base info display +#include "menus/base_info.nvgt" + +// Altar/sacrifice menu +#include "menus/altar_menu.nvgt" + +// Main key check functions (called from main game loop) void check_inventory_keys(int x) { if (key_pressed(KEY_P)) { show_character_info(); @@ -16,1104 +43,3 @@ void check_inventory_keys(int x) { } } } - -void check_action_menu(int x) { - if (key_pressed(KEY_A)) { - run_action_menu(x); - } -} - -void menu_background_tick() { - update_time(); - update_environment(); - update_snares(); - update_fires(); - update_zombies(); - 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); - } - } - - // Death check - if (player_health <= 0) { - speak_with_history("You have died.", true); - wait(2000); - exit(); - } -} - -int get_storage_total_items() { - int total = 0; - total += storage_stones; - total += storage_sticks; - total += storage_vines; - total += storage_reeds; - total += storage_logs; - total += storage_clay; - total += storage_small_game; - total += storage_meat; - total += storage_skins; - total += storage_spears; - total += storage_slings; - total += storage_axes; - total += storage_snares; - total += storage_knives; - total += storage_fishing_poles; - total += storage_ropes; - total += storage_reed_baskets; - total += storage_clay_pots; - total += storage_skin_hats; - total += storage_skin_gloves; - total += storage_skin_pants; - total += storage_skin_tunics; - total += storage_moccasins; - total += storage_skin_pouches; - return total; -} - -string get_base_fire_status() { - int total = 0; - int burning = 0; - for (uint i = 0; i < world_fires.length(); i++) { - if (world_fires[i].position <= BASE_END) { - total++; - if (world_fires[i].is_burning()) { - burning++; - } - } - } - if (total == 0) return "No fires in base"; - return "Fires in base: " + burning + " burning, " + total + " total"; -} - -void run_base_info_menu() { - if (x > BASE_END) { - speak_with_history("You are not in the base.", true); - return; - } - - speak_with_history("Base info.", true); - - int selection = 0; - string[] options; - options.insert_last("Barricade health " + barricade_health + " of " + BARRICADE_MAX_HEALTH); - options.insert_last("Residents " + residents_count); - - if (world_storages.length() > 0) { - options.insert_last("Storage built. Total items " + get_storage_total_items()); - int daily_food = get_daily_food_requirement(); - options.insert_last("Food in storage " + storage_meat + " meat. Daily use " + daily_food); - } else { - options.insert_last("Storage not built"); - } - - options.insert_last(get_base_fire_status()); - - if (world_altars.length() > 0) options.insert_last("Altar built"); - else options.insert_last("Altar not built"); - - if (get_herb_garden_at_base() != null) options.insert_last("Herb garden built"); - else options.insert_last("Herb garden not built"); - - if (world_pastures.length() > 0) options.insert_last("Pasture built"); - else options.insert_last("Pasture not built"); - - if (world_stables.length() > 0) options.insert_last("Stable built"); - else options.insert_last("Stable not built"); - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - speak_with_history(options[selection], true); - } - } -} - -string join_string_list(const string[]@ items) { - if (@items == null || items.length() == 0) return ""; - string result = items[0]; - for (uint i = 1; i < items.length(); i++) { - result += ", " + items[i]; - } - return result; -} - -void show_character_info() { - string[] equipped_clothing; - string[] missing_slots; - - if (equipped_head == EQUIP_HAT) equipped_clothing.insert_last("Skin Hat"); - else missing_slots.insert_last("head"); - if (equipped_torso == EQUIP_TUNIC) equipped_clothing.insert_last("Skin Tunic"); - else missing_slots.insert_last("torso"); - if (equipped_arms == EQUIP_POUCH) equipped_clothing.insert_last("Skin Pouch"); - else missing_slots.insert_last("arms"); - if (equipped_hands == EQUIP_GLOVES) equipped_clothing.insert_last("Skin Gloves"); - else missing_slots.insert_last("hands"); - if (equipped_legs == EQUIP_PANTS) equipped_clothing.insert_last("Skin Pants"); - else missing_slots.insert_last("legs"); - if (equipped_feet == EQUIP_MOCCASINS) equipped_clothing.insert_last("Moccasins"); - else missing_slots.insert_last("feet"); - - string info = "Character info. "; - info += "Health " + player_health + " of " + max_health + ". "; - info += "Weapon " + get_equipped_weapon_name() + ". "; - if (equipped_clothing.length() > 0) { - info += "Clothing equipped: " + join_string_list(equipped_clothing) + ". "; - } else { - info += "No clothing equipped. "; - } - if (missing_slots.length() > 0) { - info += "Missing " + join_string_list(missing_slots) + ". "; - } - info += "Favor " + format_favor(favor) + ". "; - info += "Speed " + get_speed_status() + "."; - speak_with_history(info, true); -} - -int prompt_transfer_amount(const string prompt, int max_amount) { - string input = ui_input_box("Inventory", prompt + " (max " + max_amount + ")", ""); - int amount = parse_int(input); - if (amount <= 0) return 0; - if (amount > max_amount) amount = max_amount; - return amount; -} - -void move_small_game_to_storage(int amount) { - for (int i = 0; i < amount; i++) { - string game_type = "small game"; - if (inv_small_game_types.length() > 0) { - game_type = inv_small_game_types[0]; - inv_small_game_types.remove_at(0); - } - storage_small_game_types.insert_last(game_type); - } -} - -void move_small_game_to_personal(int amount) { - for (int i = 0; i < amount; i++) { - string game_type = "small game"; - if (storage_small_game_types.length() > 0) { - game_type = storage_small_game_types[0]; - storage_small_game_types.remove_at(0); - } - inv_small_game_types.insert_last(game_type); - } -} - -void deposit_item(int item_type) { - int available = get_personal_count(item_type); - if (available <= 0) { - speak_with_history("Nothing to deposit.", true); - return; - } - 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 max_transfer = (available < capacity) ? available : capacity; - int amount = prompt_transfer_amount("Deposit how many?", max_transfer); - if (amount <= 0) return; - - if (item_type == ITEM_STICKS) { inv_sticks -= amount; storage_sticks += amount; } - else if (item_type == ITEM_VINES) { inv_vines -= amount; storage_vines += amount; } - else if (item_type == ITEM_REEDS) { inv_reeds -= amount; storage_reeds += amount; } - else if (item_type == ITEM_STONES) { inv_stones -= amount; storage_stones += amount; } - else if (item_type == ITEM_LOGS) { inv_logs -= amount; storage_logs += amount; } - else if (item_type == ITEM_CLAY) { inv_clay -= amount; storage_clay += amount; } - else if (item_type == ITEM_SMALL_GAME) { inv_small_game -= amount; storage_small_game += amount; move_small_game_to_storage(amount); } - else if (item_type == ITEM_MEAT) { inv_meat -= amount; storage_meat += amount; } - else if (item_type == ITEM_SKINS) { inv_skins -= amount; storage_skins += amount; } - else if (item_type == ITEM_FEATHERS) { inv_feathers -= amount; storage_feathers += amount; } - else if (item_type == ITEM_DOWN) { inv_down -= amount; storage_down += amount; } - else if (item_type == ITEM_INCENSE) { inv_incense -= amount; storage_incense += amount; } - else if (item_type == ITEM_SPEARS) { inv_spears -= amount; storage_spears += amount; } - else if (item_type == ITEM_SLINGS) { inv_slings -= amount; storage_slings += amount; } - else if (item_type == ITEM_AXES) { inv_axes -= amount; storage_axes += amount; } - else if (item_type == ITEM_SNARES) { inv_snares -= amount; storage_snares += amount; } - else if (item_type == ITEM_KNIVES) { inv_knives -= amount; storage_knives += amount; } - else if (item_type == ITEM_FISHING_POLES) { inv_fishing_poles -= amount; storage_fishing_poles += amount; } - else if (item_type == ITEM_ROPES) { inv_ropes -= amount; storage_ropes += amount; } - else if (item_type == ITEM_REED_BASKETS) { inv_reed_baskets -= amount; storage_reed_baskets += amount; } - else if (item_type == ITEM_CLAY_POTS) { inv_clay_pots -= amount; storage_clay_pots += amount; } - else if (item_type == ITEM_SKIN_HATS) { inv_skin_hats -= amount; storage_skin_hats += amount; } - else if (item_type == ITEM_SKIN_GLOVES) { inv_skin_gloves -= amount; storage_skin_gloves += amount; } - else if (item_type == ITEM_SKIN_PANTS) { inv_skin_pants -= amount; storage_skin_pants += amount; } - else if (item_type == ITEM_SKIN_TUNICS) { inv_skin_tunics -= amount; storage_skin_tunics += amount; } - else if (item_type == ITEM_MOCCASINS) { inv_moccasins -= amount; storage_moccasins += amount; } - else if (item_type == ITEM_SKIN_POUCHES) { inv_skin_pouches -= amount; storage_skin_pouches += amount; } - - cleanup_equipment_after_inventory_change(); - 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) { - speak_with_history("Nothing to deposit.", true); - return; - } - - 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 amount = (available < capacity) ? available : capacity; - - if (item_type == ITEM_STICKS) { inv_sticks -= amount; storage_sticks += amount; } - else if (item_type == ITEM_VINES) { inv_vines -= amount; storage_vines += amount; } - else if (item_type == ITEM_REEDS) { inv_reeds -= amount; storage_reeds += amount; } - else if (item_type == ITEM_STONES) { inv_stones -= amount; storage_stones += amount; } - else if (item_type == ITEM_LOGS) { inv_logs -= amount; storage_logs += amount; } - else if (item_type == ITEM_CLAY) { inv_clay -= amount; storage_clay += amount; } - else if (item_type == ITEM_SMALL_GAME) { inv_small_game -= amount; storage_small_game += amount; move_small_game_to_storage(amount); } - else if (item_type == ITEM_MEAT) { inv_meat -= amount; storage_meat += amount; } - else if (item_type == ITEM_SKINS) { inv_skins -= amount; storage_skins += amount; } - else if (item_type == ITEM_FEATHERS) { inv_feathers -= amount; storage_feathers += amount; } - else if (item_type == ITEM_DOWN) { inv_down -= amount; storage_down += amount; } - else if (item_type == ITEM_INCENSE) { inv_incense -= amount; storage_incense += amount; } - else if (item_type == ITEM_SPEARS) { inv_spears -= amount; storage_spears += amount; } - else if (item_type == ITEM_SLINGS) { inv_slings -= amount; storage_slings += amount; } - else if (item_type == ITEM_AXES) { inv_axes -= amount; storage_axes += amount; } - else if (item_type == ITEM_SNARES) { inv_snares -= amount; storage_snares += amount; } - else if (item_type == ITEM_KNIVES) { inv_knives -= amount; storage_knives += amount; } - else if (item_type == ITEM_FISHING_POLES) { inv_fishing_poles -= amount; storage_fishing_poles += amount; } - else if (item_type == ITEM_ROPES) { inv_ropes -= amount; storage_ropes += amount; } - else if (item_type == ITEM_REED_BASKETS) { inv_reed_baskets -= amount; storage_reed_baskets += amount; } - else if (item_type == ITEM_CLAY_POTS) { inv_clay_pots -= amount; storage_clay_pots += amount; } - else if (item_type == ITEM_SKIN_HATS) { inv_skin_hats -= amount; storage_skin_hats += amount; } - else if (item_type == ITEM_SKIN_GLOVES) { inv_skin_gloves -= amount; storage_skin_gloves += amount; } - else if (item_type == ITEM_SKIN_PANTS) { inv_skin_pants -= amount; storage_skin_pants += amount; } - else if (item_type == ITEM_SKIN_TUNICS) { inv_skin_tunics -= amount; storage_skin_tunics += amount; } - else if (item_type == ITEM_MOCCASINS) { inv_moccasins -= amount; storage_moccasins += amount; } - else if (item_type == ITEM_SKIN_POUCHES) { inv_skin_pouches -= amount; storage_skin_pouches += amount; } - - cleanup_equipment_after_inventory_change(); - 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) { - speak_with_history("Nothing to withdraw.", true); - return; - } - int capacity = get_personal_stack_limit() - get_personal_count(item_type); - if (capacity <= 0) { - speak_with_history("You can't carry any more " + get_item_label(item_type) + ".", true); - return; - } - int max_transfer = (available < capacity) ? available : capacity; - int amount = prompt_transfer_amount("Withdraw how many?", max_transfer); - if (amount <= 0) return; - - if (item_type == ITEM_STICKS) { storage_sticks -= amount; inv_sticks += amount; } - else if (item_type == ITEM_VINES) { storage_vines -= amount; inv_vines += amount; } - else if (item_type == ITEM_REEDS) { storage_reeds -= amount; inv_reeds += amount; } - else if (item_type == ITEM_STONES) { storage_stones -= amount; inv_stones += amount; } - else if (item_type == ITEM_LOGS) { storage_logs -= amount; inv_logs += amount; } - else if (item_type == ITEM_CLAY) { storage_clay -= amount; inv_clay += amount; } - else if (item_type == ITEM_SMALL_GAME) { storage_small_game -= amount; inv_small_game += amount; move_small_game_to_personal(amount); } - else if (item_type == ITEM_MEAT) { storage_meat -= amount; inv_meat += amount; } - else if (item_type == ITEM_SKINS) { storage_skins -= amount; inv_skins += amount; } - else if (item_type == ITEM_FEATHERS) { storage_feathers -= amount; inv_feathers += amount; } - else if (item_type == ITEM_DOWN) { storage_down -= amount; inv_down += amount; } - else if (item_type == ITEM_INCENSE) { storage_incense -= amount; inv_incense += amount; } - else if (item_type == ITEM_SPEARS) { storage_spears -= amount; inv_spears += amount; } - else if (item_type == ITEM_SLINGS) { storage_slings -= amount; inv_slings += amount; } - else if (item_type == ITEM_AXES) { storage_axes -= amount; inv_axes += amount; } - else if (item_type == ITEM_SNARES) { storage_snares -= amount; inv_snares += amount; } - else if (item_type == ITEM_KNIVES) { storage_knives -= amount; inv_knives += amount; } - else if (item_type == ITEM_FISHING_POLES) { storage_fishing_poles -= amount; inv_fishing_poles += amount; } - else if (item_type == ITEM_ROPES) { storage_ropes -= amount; inv_ropes += amount; } - else if (item_type == ITEM_REED_BASKETS) { storage_reed_baskets -= amount; inv_reed_baskets += amount; } - else if (item_type == ITEM_CLAY_POTS) { storage_clay_pots -= amount; inv_clay_pots += amount; } - else if (item_type == ITEM_SKIN_HATS) { storage_skin_hats -= amount; inv_skin_hats += amount; } - else if (item_type == ITEM_SKIN_GLOVES) { storage_skin_gloves -= amount; inv_skin_gloves += amount; } - else if (item_type == ITEM_SKIN_PANTS) { storage_skin_pants -= amount; inv_skin_pants += amount; } - else if (item_type == ITEM_SKIN_TUNICS) { storage_skin_tunics -= amount; inv_skin_tunics += amount; } - 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; } - - 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) { - speak_with_history("Nothing to withdraw.", true); - return; - } - - int personal_limit = get_personal_stack_limit(); - int current_personal = get_personal_count(item_type); - int space = personal_limit - current_personal; - - if (space <= 0) { - speak_with_history("Can't carry any more.", true); - return; - } - - int amount = (available < space) ? available : space; - - if (item_type == ITEM_STICKS) { storage_sticks -= amount; inv_sticks += amount; } - else if (item_type == ITEM_VINES) { storage_vines -= amount; inv_vines += amount; } - else if (item_type == ITEM_REEDS) { storage_reeds -= amount; inv_reeds += amount; } - else if (item_type == ITEM_STONES) { storage_stones -= amount; inv_stones += amount; } - else if (item_type == ITEM_LOGS) { storage_logs -= amount; inv_logs += amount; } - else if (item_type == ITEM_CLAY) { storage_clay -= amount; inv_clay += amount; } - else if (item_type == ITEM_SMALL_GAME) { storage_small_game -= amount; inv_small_game += amount; move_small_game_to_personal(amount); } - else if (item_type == ITEM_MEAT) { storage_meat -= amount; inv_meat += amount; } - else if (item_type == ITEM_SKINS) { storage_skins -= amount; inv_skins += amount; } - else if (item_type == ITEM_FEATHERS) { storage_feathers -= amount; inv_feathers += amount; } - else if (item_type == ITEM_DOWN) { storage_down -= amount; inv_down += amount; } - else if (item_type == ITEM_INCENSE) { storage_incense -= amount; inv_incense += amount; } - else if (item_type == ITEM_SPEARS) { storage_spears -= amount; inv_spears += amount; } - else if (item_type == ITEM_SLINGS) { storage_slings -= amount; inv_slings += amount; } - else if (item_type == ITEM_AXES) { storage_axes -= amount; inv_axes += amount; } - else if (item_type == ITEM_SNARES) { storage_snares -= amount; inv_snares += amount; } - else if (item_type == ITEM_KNIVES) { storage_knives -= amount; inv_knives += amount; } - else if (item_type == ITEM_FISHING_POLES) { storage_fishing_poles -= amount; inv_fishing_poles += amount; } - else if (item_type == ITEM_ROPES) { storage_ropes -= amount; inv_ropes += amount; } - else if (item_type == ITEM_REED_BASKETS) { storage_reed_baskets -= amount; inv_reed_baskets += amount; } - else if (item_type == ITEM_CLAY_POTS) { storage_clay_pots -= amount; inv_clay_pots += amount; } - else if (item_type == ITEM_SKIN_HATS) { storage_skin_hats -= amount; inv_skin_hats += amount; } - else if (item_type == ITEM_SKIN_GLOVES) { storage_skin_gloves -= amount; inv_skin_gloves += amount; } - else if (item_type == ITEM_SKIN_PANTS) { storage_skin_pants -= amount; inv_skin_pants += amount; } - else if (item_type == ITEM_SKIN_TUNICS) { storage_skin_tunics -= amount; inv_skin_tunics += amount; } - 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; } - - 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) { - speak_with_history("Nothing to sacrifice.", true); - return; - } - - if (item_type == ITEM_STICKS) inv_sticks--; - else if (item_type == ITEM_VINES) inv_vines--; - else if (item_type == ITEM_REEDS) inv_reeds--; - else if (item_type == ITEM_STONES) inv_stones--; - else if (item_type == ITEM_LOGS) inv_logs--; - else if (item_type == ITEM_CLAY) inv_clay--; - else if (item_type == ITEM_SMALL_GAME) { - inv_small_game--; - if (inv_small_game_types.length() > 0) { - inv_small_game_types.remove_at(0); - } - } - else if (item_type == ITEM_MEAT) inv_meat--; - else if (item_type == ITEM_SKINS) inv_skins--; - else if (item_type == ITEM_FEATHERS) inv_feathers--; - else if (item_type == ITEM_DOWN) inv_down--; - else if (item_type == ITEM_INCENSE) inv_incense--; - else if (item_type == ITEM_SPEARS) inv_spears--; - else if (item_type == ITEM_SLINGS) inv_slings--; - else if (item_type == ITEM_AXES) inv_axes--; - else if (item_type == ITEM_SNARES) inv_snares--; - else if (item_type == ITEM_KNIVES) inv_knives--; - else if (item_type == ITEM_FISHING_POLES) inv_fishing_poles--; - else if (item_type == ITEM_ROPES) inv_ropes--; - else if (item_type == ITEM_REED_BASKETS) inv_reed_baskets--; - else if (item_type == ITEM_CLAY_POTS) inv_clay_pots--; - else if (item_type == ITEM_SKIN_HATS) inv_skin_hats--; - else if (item_type == ITEM_SKIN_GLOVES) inv_skin_gloves--; - else if (item_type == ITEM_SKIN_PANTS) inv_skin_pants--; - else if (item_type == ITEM_SKIN_TUNICS) inv_skin_tunics--; - else if (item_type == ITEM_MOCCASINS) inv_moccasins--; - else if (item_type == ITEM_SKIN_POUCHES) inv_skin_pouches--; - - cleanup_equipment_after_inventory_change(); - double favor_gain = get_item_favor_value(item_type); - favor += favor_gain; - 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) { - speak_with_history("Nothing to sacrifice.", true); - return; - } - - double favor_per_item = get_item_favor_value(item_type); - - if (item_type == ITEM_STICKS) { inv_sticks = 0; } - else if (item_type == ITEM_VINES) { inv_vines = 0; } - else if (item_type == ITEM_REEDS) { inv_reeds = 0; } - else if (item_type == ITEM_STONES) { inv_stones = 0; } - else if (item_type == ITEM_LOGS) { inv_logs = 0; } - else if (item_type == ITEM_CLAY) { inv_clay = 0; } - else if (item_type == ITEM_SMALL_GAME) { - inv_small_game = 0; - inv_small_game_types.resize(0); - } - else if (item_type == ITEM_MEAT) { inv_meat = 0; } - else if (item_type == ITEM_SKINS) { inv_skins = 0; } - else if (item_type == ITEM_FEATHERS) { inv_feathers = 0; } - else if (item_type == ITEM_DOWN) { inv_down = 0; } - else if (item_type == ITEM_INCENSE) { inv_incense = 0; } - else if (item_type == ITEM_SPEARS) { inv_spears = 0; } - else if (item_type == ITEM_SLINGS) { inv_slings = 0; } - else if (item_type == ITEM_AXES) { inv_axes = 0; } - else if (item_type == ITEM_SNARES) { inv_snares = 0; } - else if (item_type == ITEM_KNIVES) { inv_knives = 0; } - else if (item_type == ITEM_FISHING_POLES) { inv_fishing_poles = 0; } - else if (item_type == ITEM_ROPES) { inv_ropes = 0; } - else if (item_type == ITEM_REED_BASKETS) { inv_reed_baskets = 0; } - else if (item_type == ITEM_CLAY_POTS) { inv_clay_pots = 0; } - else if (item_type == ITEM_SKIN_HATS) { inv_skin_hats = 0; } - else if (item_type == ITEM_SKIN_GLOVES) { inv_skin_gloves = 0; } - else if (item_type == ITEM_SKIN_PANTS) { inv_skin_pants = 0; } - else if (item_type == ITEM_SKIN_TUNICS) { inv_skin_tunics = 0; } - else if (item_type == ITEM_MOCCASINS) { inv_moccasins = 0; } - else if (item_type == ITEM_SKIN_POUCHES) { inv_skin_pouches = 0; } - - cleanup_equipment_after_inventory_change(); - double total_favor = favor_per_item * available; - favor += total_favor; - - 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) { - options.resize(0); - item_types.resize(0); - options.insert_last("Sticks: " + inv_sticks); item_types.insert_last(ITEM_STICKS); - options.insert_last("Vines: " + inv_vines); item_types.insert_last(ITEM_VINES); - options.insert_last("Reeds: " + inv_reeds); item_types.insert_last(ITEM_REEDS); - options.insert_last("Stones: " + inv_stones); item_types.insert_last(ITEM_STONES); - options.insert_last("Logs: " + inv_logs); item_types.insert_last(ITEM_LOGS); - options.insert_last("Clay: " + inv_clay); item_types.insert_last(ITEM_CLAY); - options.insert_last("Small Game: " + inv_small_game); item_types.insert_last(ITEM_SMALL_GAME); - options.insert_last("Meat: " + inv_meat); item_types.insert_last(ITEM_MEAT); - options.insert_last("Skins: " + inv_skins); item_types.insert_last(ITEM_SKINS); - options.insert_last("Feathers: " + inv_feathers); item_types.insert_last(ITEM_FEATHERS); - options.insert_last("Down: " + inv_down); item_types.insert_last(ITEM_DOWN); - options.insert_last("Incense: " + inv_incense); item_types.insert_last(ITEM_INCENSE); - options.insert_last("Spears: " + inv_spears); item_types.insert_last(ITEM_SPEARS); - options.insert_last("Slings: " + inv_slings); item_types.insert_last(ITEM_SLINGS); - options.insert_last("Axes: " + inv_axes); item_types.insert_last(ITEM_AXES); - options.insert_last("Snares: " + inv_snares); item_types.insert_last(ITEM_SNARES); - options.insert_last("Knives: " + inv_knives); item_types.insert_last(ITEM_KNIVES); - options.insert_last("Fishing Poles: " + inv_fishing_poles); item_types.insert_last(ITEM_FISHING_POLES); - options.insert_last("Ropes: " + inv_ropes); item_types.insert_last(ITEM_ROPES); - options.insert_last("Reed Baskets: " + inv_reed_baskets); item_types.insert_last(ITEM_REED_BASKETS); - options.insert_last("Clay Pots: " + inv_clay_pots); item_types.insert_last(ITEM_CLAY_POTS); - options.insert_last("Skin Hats: " + inv_skin_hats); item_types.insert_last(ITEM_SKIN_HATS); - options.insert_last("Skin Gloves: " + inv_skin_gloves); item_types.insert_last(ITEM_SKIN_GLOVES); - options.insert_last("Skin Pants: " + inv_skin_pants); item_types.insert_last(ITEM_SKIN_PANTS); - options.insert_last("Skin Tunics: " + inv_skin_tunics); item_types.insert_last(ITEM_SKIN_TUNICS); - options.insert_last("Moccasins: " + inv_moccasins); item_types.insert_last(ITEM_MOCCASINS); - options.insert_last("Skin Pouches: " + inv_skin_pouches); item_types.insert_last(ITEM_SKIN_POUCHES); -} - -void build_storage_inventory_options(string[]@ options, int[]@ item_types) { - options.resize(0); - item_types.resize(0); - options.insert_last("Sticks: " + storage_sticks); item_types.insert_last(ITEM_STICKS); - options.insert_last("Vines: " + storage_vines); item_types.insert_last(ITEM_VINES); - options.insert_last("Reeds: " + storage_reeds); item_types.insert_last(ITEM_REEDS); - options.insert_last("Stones: " + storage_stones); item_types.insert_last(ITEM_STONES); - options.insert_last("Logs: " + storage_logs); item_types.insert_last(ITEM_LOGS); - options.insert_last("Clay: " + storage_clay); item_types.insert_last(ITEM_CLAY); - options.insert_last("Small Game: " + storage_small_game); item_types.insert_last(ITEM_SMALL_GAME); - options.insert_last("Meat: " + storage_meat); item_types.insert_last(ITEM_MEAT); - options.insert_last("Skins: " + storage_skins); item_types.insert_last(ITEM_SKINS); - options.insert_last("Feathers: " + storage_feathers); item_types.insert_last(ITEM_FEATHERS); - options.insert_last("Down: " + storage_down); item_types.insert_last(ITEM_DOWN); - options.insert_last("Incense: " + storage_incense); item_types.insert_last(ITEM_INCENSE); - options.insert_last("Spears: " + storage_spears); item_types.insert_last(ITEM_SPEARS); - options.insert_last("Slings: " + storage_slings); item_types.insert_last(ITEM_SLINGS); - options.insert_last("Axes: " + storage_axes); item_types.insert_last(ITEM_AXES); - options.insert_last("Snares: " + storage_snares); item_types.insert_last(ITEM_SNARES); - options.insert_last("Knives: " + storage_knives); item_types.insert_last(ITEM_KNIVES); - options.insert_last("Fishing Poles: " + storage_fishing_poles); item_types.insert_last(ITEM_FISHING_POLES); - options.insert_last("Ropes: " + storage_ropes); item_types.insert_last(ITEM_ROPES); - options.insert_last("Reed Baskets: " + storage_reed_baskets); item_types.insert_last(ITEM_REED_BASKETS); - options.insert_last("Clay Pots: " + storage_clay_pots); item_types.insert_last(ITEM_CLAY_POTS); - options.insert_last("Skin Hats: " + storage_skin_hats); item_types.insert_last(ITEM_SKIN_HATS); - options.insert_last("Skin Gloves: " + storage_skin_gloves); item_types.insert_last(ITEM_SKIN_GLOVES); - options.insert_last("Skin Pants: " + storage_skin_pants); item_types.insert_last(ITEM_SKIN_PANTS); - options.insert_last("Skin Tunics: " + storage_skin_tunics); item_types.insert_last(ITEM_SKIN_TUNICS); - options.insert_last("Moccasins: " + storage_moccasins); item_types.insert_last(ITEM_MOCCASINS); - options.insert_last("Skin Pouches: " + storage_skin_pouches); item_types.insert_last(ITEM_SKIN_POUCHES); -} - -void show_inventory() { - string info = "Inventory: "; - info += inv_sticks + " sticks, "; - info += inv_vines + " vines, "; - info += inv_reeds + " reeds, "; - info += inv_stones + " stones, "; - info += inv_logs + " logs, "; - info += inv_clay + " clay, "; - info += inv_small_game + " small game, "; - info += inv_meat + " meat, "; - info += inv_skins + " skins, "; - info += inv_feathers + " feathers, "; - info += inv_down + " down, "; - 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."; - speak_with_history(info, true); -} - -void run_inventory_root_menu() { - speak_with_history("Inventory menu.", true); - - int selection = 0; - string[] options = {"Personal inventory", "Base storage"}; - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_RETURN)) { - if (selection == 0) run_inventory_menu(true); - else run_storage_menu(); - break; - } - } -} - -void run_inventory_menu(bool allow_deposit) { - speak_with_history("Inventory menu.", true); - - int selection = 0; - string[] options; - int[] item_types; - build_personal_inventory_options(options, item_types); - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - 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; - 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; - speak_with_history(options[selection], true); - } - } -} - -void run_storage_menu() { - if (world_storages.length() == 0) { - speak_with_history("No storage built.", true); - return; - } - - speak_with_history("Base storage.", true); - - int selection = 0; - string[] options; - int[] item_types; - build_storage_inventory_options(options, item_types); - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - 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; - 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; - speak_with_history(options[selection], true); - } - } -} - -void check_altar_menu(int player_x) { - if (!key_pressed(KEY_S)) return; - - // Must be in base - if (player_x > BASE_END) { - speak_with_history("Must be in base to use altar.", true); - return; - } - - // Must have altar - if (world_altars.length() == 0) { - speak_with_history("No altar built.", true); - return; - } - - run_altar_menu(); -} - -void run_altar_menu() { - speak_with_history("Altar. Favor " + format_favor(favor) + ".", true); - - int selection = 0; - string[] options; - int[] item_types; - build_personal_inventory_options(options, item_types); - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - 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; - 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; - speak_with_history(options[selection], true); - } - } -} - -void try_place_snare(int x) { - if (inv_snares > 0) { - // Prevent placing if one already exists here - if (get_snare_at(x) != null) { - speak_with_history("There is already a snare here.", true); - return; - } - - inv_snares--; - add_world_snare(x); - speak_with_history("Snare set.", true); - } else { - speak_with_history("No snares to place.", true); - } -} - -void try_feed_fire_stick(WorldFire@ fire) { - if (inv_sticks > 0 && fire != null) { - inv_sticks--; - fire.add_fuel(300000); // 5 minutes - speak_with_history("You dump an arm load of sticks into the fire.", true); - p.play_stationary("sounds/actions/feed_fire.ogg", false); - } -} - -void try_feed_fire_vine(WorldFire@ fire) { - if (inv_vines > 0 && fire != null) { - inv_vines--; - fire.add_fuel(60000); // 1 minute - speak_with_history("You toss a fiew vines and leaves into the fire.", true); - p.play_stationary("sounds/actions/feed_fire.ogg", false); - } -} - -void try_feed_fire_log(WorldFire@ fire) { - if (inv_logs > 0 && fire != null) { - inv_logs--; - fire.add_fuel(720000); // 12 minutes - 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) { - speak_with_history("No altar built.", true); - return; - } - if (inv_clay_pots <= 0) { - speak_with_history("You need a clay pot to burn incense.", true); - return; - } - if (inv_incense <= 0) { - speak_with_history("No incense to burn.", true); - return; - } - - inv_incense--; - incense_hours_remaining += INCENSE_HOURS_PER_STICK; - incense_burning = 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) { - speak_with_history("No sticks to feed fire.", true); - return; - } - - int amount = inv_sticks; - int fuel_added = amount * 300000; // 5 minutes per stick - inv_sticks = 0; - - fire.add_fuel(fuel_added); - p.play_stationary("sounds/actions/feed_fire.ogg", false); - speak_with_history("Dumped " + amount + " sticks into the fire.", true); -} - -void try_feed_fire_vine_max(WorldFire@ fire) { - if (inv_vines <= 0 || fire == null) { - speak_with_history("No vines to feed fire.", true); - return; - } - - int amount = inv_vines; - int fuel_added = amount * 60000; // 1 minute per vine - inv_vines = 0; - - fire.add_fuel(fuel_added); - p.play_stationary("sounds/actions/feed_fire.ogg", false); - speak_with_history("Dumped " + amount + " vines into the fire.", true); -} - -void try_feed_fire_log_max(WorldFire@ fire) { - if (inv_logs <= 0 || fire == null) { - speak_with_history("No logs to feed fire.", true); - return; - } - - int amount = inv_logs; - int fuel_added = amount * 720000; // 12 minutes per log - inv_logs = 0; - - fire.add_fuel(fuel_added); - p.play_stationary("sounds/actions/feed_fire.ogg", false); - speak_with_history("Dumped " + amount + " logs into the fire.", true); -} - -void try_burn_incense_max() { - if (world_altars.length() == 0) { - speak_with_history("No altar built.", true); - return; - } - if (inv_clay_pots <= 0) { - speak_with_history("You need a clay pot to burn incense.", true); - return; - } - if (inv_incense <= 0) { - speak_with_history("No incense to burn.", true); - return; - } - - int amount = inv_incense; - int total_hours = amount * INCENSE_HOURS_PER_STICK; - inv_incense = 0; - inv_clay_pots--; - - incense_hours_remaining += total_hours; - incense_burning = true; - - speak_with_history("Burned " + amount + " incense. +" + total_hours + " hours.", true); -} - -void check_equipment_menu() { - if (key_pressed(KEY_E)) { - // Check if player has any equipment - 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) { - speak_with_history("Nothing to equip.", true); - } else { - run_equipment_menu(); - } - } -} - -void run_action_menu(int x) { - speak_with_history("Action menu.", true); - - int selection = 0; - string[] options; - int[] action_types; // Track what action each option corresponds to - - // Check if fire is nearby - WorldFire@ nearby_fire = get_fire_near(x); - bool can_feed_fire = nearby_fire != null; - - // Build menu options dynamically - options.insert_last("Place Snare"); - action_types.insert_last(0); - - if (can_feed_fire) { - if (inv_sticks > 0) { - options.insert_last("Feed fire with stick"); - action_types.insert_last(1); - } - if (inv_vines > 0) { - options.insert_last("Feed fire with vine"); - action_types.insert_last(2); - } - if (inv_logs > 0) { - options.insert_last("Feed fire with log"); - action_types.insert_last(3); - } - } - - if (x <= BASE_END && world_altars.length() > 0 && inv_incense > 0) { - options.insert_last("Burn incense"); - action_types.insert_last(4); - } - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_RETURN)) { - int action = action_types[selection]; - if (action == 0) { - try_place_snare(x); - } else if (action == 1) { - try_feed_fire_stick(nearby_fire); - } else if (action == 2) { - try_feed_fire_vine(nearby_fire); - } else if (action == 3) { - try_feed_fire_log(nearby_fire); - } else if (action == 4) { - try_burn_incense(); - } - break; - } - - if (key_pressed(KEY_TAB)) { - int action = action_types[selection]; - if (action == 0) { - speak_with_history("Can't do that.", true); - } else if (action == 1) { - try_feed_fire_stick_max(nearby_fire); - } else if (action == 2) { - try_feed_fire_vine_max(nearby_fire); - } else if (action == 3) { - try_feed_fire_log_max(nearby_fire); - } else if (action == 4) { - try_burn_incense_max(); - } - break; - } - } -} - -void run_equipment_menu() { - speak_with_history("Equipment menu.", true); - - int selection = 0; - string[] options; - int[] equipment_types; - - // Build menu dynamically based on what player has - if (inv_spears > 0) { - string status = equipment_is_equipped(EQUIP_SPEAR) ? " (equipped)" : ""; - options.insert_last("Spear" + status); - equipment_types.insert_last(EQUIP_SPEAR); - } - if (inv_slings > 0) { - string status = equipment_is_equipped(EQUIP_SLING) ? " (equipped)" : ""; - options.insert_last("Sling" + status); - equipment_types.insert_last(EQUIP_SLING); - } - if (inv_axes > 0) { - string status = equipment_is_equipped(EQUIP_AXE) ? " (equipped)" : ""; - options.insert_last("Stone Axe" + status); - equipment_types.insert_last(EQUIP_AXE); - } - if (inv_skin_hats > 0) { - string status = equipment_is_equipped(EQUIP_HAT) ? " (equipped)" : ""; - options.insert_last("Skin Hat" + status); - equipment_types.insert_last(EQUIP_HAT); - } - if (inv_skin_gloves > 0) { - string status = equipment_is_equipped(EQUIP_GLOVES) ? " (equipped)" : ""; - options.insert_last("Skin Gloves" + status); - equipment_types.insert_last(EQUIP_GLOVES); - } - if (inv_skin_pants > 0) { - string status = equipment_is_equipped(EQUIP_PANTS) ? " (equipped)" : ""; - options.insert_last("Skin Pants" + status); - equipment_types.insert_last(EQUIP_PANTS); - } - if (inv_skin_tunics > 0) { - string status = equipment_is_equipped(EQUIP_TUNIC) ? " (equipped)" : ""; - options.insert_last("Skin Tunic" + status); - equipment_types.insert_last(EQUIP_TUNIC); - } - if (inv_moccasins > 0) { - string status = equipment_is_equipped(EQUIP_MOCCASINS) ? " (equipped)" : ""; - options.insert_last("Moccasins" + status); - equipment_types.insert_last(EQUIP_MOCCASINS); - } - if (inv_skin_pouches > 0) { - string status = equipment_is_equipped(EQUIP_POUCH) ? " (equipped)" : ""; - options.insert_last("Skin Pouch" + status); - equipment_types.insert_last(EQUIP_POUCH); - } - - while(true) { - wait(5); - menu_background_tick(); - if (key_pressed(KEY_ESCAPE)) { - speak_with_history("Closed.", true); - break; - } - - if (key_pressed(KEY_DOWN)) { - selection++; - if (selection >= options.length()) selection = 0; - speak_with_history(options[selection], true); - } - - if (key_pressed(KEY_UP)) { - selection--; - if (selection < 0) selection = options.length() - 1; - 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; - 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); - speak_with_history(get_equipment_name(equip_type) + " unequipped.", true); - } else { - equip_equipment_type(equip_type); - speak_with_history(get_equipment_name(equip_type) + " equipped.", true); - } - update_max_health_from_equipment(); - break; - } - } -} diff --git a/src/menus/action_menu.nvgt b/src/menus/action_menu.nvgt new file mode 100644 index 0000000..7333146 --- /dev/null +++ b/src/menus/action_menu.nvgt @@ -0,0 +1,230 @@ +// Action menu system +// Context-sensitive action menu for placing snares, feeding fires, burning incense + +void check_action_menu(int x) { + if (key_pressed(KEY_A)) { + run_action_menu(x); + } +} + +void try_place_snare(int x) { + if (inv_snares > 0) { + // Prevent placing if one already exists here + if (get_snare_at(x) != null) { + speak_with_history("There is already a snare here.", true); + return; + } + + inv_snares--; + add_world_snare(x); + speak_with_history("Snare set.", true); + } else { + speak_with_history("No snares to place.", true); + } +} + +void try_feed_fire_stick(WorldFire@ fire) { + if (inv_sticks > 0 && fire != null) { + inv_sticks--; + fire.add_fuel(300000); // 5 minutes + speak_with_history("You dump an arm load of sticks into the fire.", true); + p.play_stationary("sounds/actions/feed_fire.ogg", false); + } +} + +void try_feed_fire_vine(WorldFire@ fire) { + if (inv_vines > 0 && fire != null) { + inv_vines--; + fire.add_fuel(60000); // 1 minute + speak_with_history("You toss a fiew vines and leaves into the fire.", true); + p.play_stationary("sounds/actions/feed_fire.ogg", false); + } +} + +void try_feed_fire_log(WorldFire@ fire) { + if (inv_logs > 0 && fire != null) { + inv_logs--; + fire.add_fuel(720000); // 12 minutes + 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) { + speak_with_history("No altar built.", true); + return; + } + if (inv_clay_pots <= 0) { + speak_with_history("You need a clay pot to burn incense.", true); + return; + } + if (inv_incense <= 0) { + speak_with_history("No incense to burn.", true); + return; + } + + inv_incense--; + incense_hours_remaining += INCENSE_HOURS_PER_STICK; + incense_burning = 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) { + speak_with_history("No sticks to feed fire.", true); + return; + } + + int amount = inv_sticks; + int fuel_added = amount * 300000; // 5 minutes per stick + inv_sticks = 0; + + fire.add_fuel(fuel_added); + p.play_stationary("sounds/actions/feed_fire.ogg", false); + speak_with_history("Dumped " + amount + " sticks into the fire.", true); +} + +void try_feed_fire_vine_max(WorldFire@ fire) { + if (inv_vines <= 0 || fire == null) { + speak_with_history("No vines to feed fire.", true); + return; + } + + int amount = inv_vines; + int fuel_added = amount * 60000; // 1 minute per vine + inv_vines = 0; + + fire.add_fuel(fuel_added); + p.play_stationary("sounds/actions/feed_fire.ogg", false); + speak_with_history("Dumped " + amount + " vines into the fire.", true); +} + +void try_feed_fire_log_max(WorldFire@ fire) { + if (inv_logs <= 0 || fire == null) { + speak_with_history("No logs to feed fire.", true); + return; + } + + int amount = inv_logs; + int fuel_added = amount * 720000; // 12 minutes per log + inv_logs = 0; + + fire.add_fuel(fuel_added); + p.play_stationary("sounds/actions/feed_fire.ogg", false); + speak_with_history("Dumped " + amount + " logs into the fire.", true); +} + +void try_burn_incense_max() { + if (world_altars.length() == 0) { + speak_with_history("No altar built.", true); + return; + } + if (inv_clay_pots <= 0) { + speak_with_history("You need a clay pot to burn incense.", true); + return; + } + if (inv_incense <= 0) { + speak_with_history("No incense to burn.", true); + return; + } + + int amount = inv_incense; + int total_hours = amount * INCENSE_HOURS_PER_STICK; + inv_incense = 0; + inv_clay_pots--; + + incense_hours_remaining += total_hours; + incense_burning = true; + + speak_with_history("Burned " + amount + " incense. +" + total_hours + " hours.", true); +} + +void run_action_menu(int x) { + speak_with_history("Action menu.", true); + + int selection = 0; + string[] options; + int[] action_types; // Track what action each option corresponds to + + // Check if fire is nearby + WorldFire@ nearby_fire = get_fire_near(x); + bool can_feed_fire = nearby_fire != null; + + // Build menu options dynamically + options.insert_last("Place Snare"); + action_types.insert_last(0); + + if (can_feed_fire) { + if (inv_sticks > 0) { + options.insert_last("Feed fire with stick"); + action_types.insert_last(1); + } + if (inv_vines > 0) { + options.insert_last("Feed fire with vine"); + action_types.insert_last(2); + } + if (inv_logs > 0) { + options.insert_last("Feed fire with log"); + action_types.insert_last(3); + } + } + + if (x <= BASE_END && world_altars.length() > 0 && inv_incense > 0) { + options.insert_last("Burn incense"); + action_types.insert_last(4); + } + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_RETURN)) { + int action = action_types[selection]; + if (action == 0) { + try_place_snare(x); + } else if (action == 1) { + try_feed_fire_stick(nearby_fire); + } else if (action == 2) { + try_feed_fire_vine(nearby_fire); + } else if (action == 3) { + try_feed_fire_log(nearby_fire); + } else if (action == 4) { + try_burn_incense(); + } + break; + } + + if (key_pressed(KEY_TAB)) { + int action = action_types[selection]; + if (action == 0) { + speak_with_history("Can't do that.", true); + } else if (action == 1) { + try_feed_fire_stick_max(nearby_fire); + } else if (action == 2) { + try_feed_fire_vine_max(nearby_fire); + } else if (action == 3) { + try_feed_fire_log_max(nearby_fire); + } else if (action == 4) { + try_burn_incense_max(); + } + break; + } + } +} diff --git a/src/menus/altar_menu.nvgt b/src/menus/altar_menu.nvgt new file mode 100644 index 0000000..b7928d7 --- /dev/null +++ b/src/menus/altar_menu.nvgt @@ -0,0 +1,157 @@ +// Altar/sacrifice menu system +// Functions for sacrificing items at the altar + +void check_altar_menu(int player_x) { + if (!key_pressed(KEY_S)) return; + + // Must be in base + if (player_x > BASE_END) { + speak_with_history("Must be in base to use altar.", true); + return; + } + + // Must have altar + if (world_altars.length() == 0) { + speak_with_history("No altar built.", true); + return; + } + + run_altar_menu(); +} + +void sacrifice_item(int item_type) { + int available = get_personal_count(item_type); + if (available <= 0) { + speak_with_history("Nothing to sacrifice.", true); + return; + } + + if (item_type == ITEM_STICKS) inv_sticks--; + else if (item_type == ITEM_VINES) inv_vines--; + else if (item_type == ITEM_REEDS) inv_reeds--; + else if (item_type == ITEM_STONES) inv_stones--; + else if (item_type == ITEM_LOGS) inv_logs--; + else if (item_type == ITEM_CLAY) inv_clay--; + else if (item_type == ITEM_SMALL_GAME) { + inv_small_game--; + if (inv_small_game_types.length() > 0) { + inv_small_game_types.remove_at(0); + } + } + else if (item_type == ITEM_MEAT) inv_meat--; + else if (item_type == ITEM_SKINS) inv_skins--; + else if (item_type == ITEM_FEATHERS) inv_feathers--; + else if (item_type == ITEM_DOWN) inv_down--; + else if (item_type == ITEM_INCENSE) inv_incense--; + else if (item_type == ITEM_SPEARS) inv_spears--; + else if (item_type == ITEM_SLINGS) inv_slings--; + else if (item_type == ITEM_AXES) inv_axes--; + else if (item_type == ITEM_SNARES) inv_snares--; + else if (item_type == ITEM_KNIVES) inv_knives--; + else if (item_type == ITEM_FISHING_POLES) inv_fishing_poles--; + else if (item_type == ITEM_ROPES) inv_ropes--; + else if (item_type == ITEM_REED_BASKETS) inv_reed_baskets--; + else if (item_type == ITEM_CLAY_POTS) inv_clay_pots--; + else if (item_type == ITEM_SKIN_HATS) inv_skin_hats--; + else if (item_type == ITEM_SKIN_GLOVES) inv_skin_gloves--; + else if (item_type == ITEM_SKIN_PANTS) inv_skin_pants--; + else if (item_type == ITEM_SKIN_TUNICS) inv_skin_tunics--; + else if (item_type == ITEM_MOCCASINS) inv_moccasins--; + else if (item_type == ITEM_SKIN_POUCHES) inv_skin_pouches--; + + cleanup_equipment_after_inventory_change(); + double favor_gain = get_item_favor_value(item_type); + favor += favor_gain; + 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) { + speak_with_history("Nothing to sacrifice.", true); + return; + } + + double favor_per_item = get_item_favor_value(item_type); + + if (item_type == ITEM_STICKS) { inv_sticks = 0; } + else if (item_type == ITEM_VINES) { inv_vines = 0; } + else if (item_type == ITEM_REEDS) { inv_reeds = 0; } + else if (item_type == ITEM_STONES) { inv_stones = 0; } + else if (item_type == ITEM_LOGS) { inv_logs = 0; } + else if (item_type == ITEM_CLAY) { inv_clay = 0; } + else if (item_type == ITEM_SMALL_GAME) { + inv_small_game = 0; + inv_small_game_types.resize(0); + } + else if (item_type == ITEM_MEAT) { inv_meat = 0; } + else if (item_type == ITEM_SKINS) { inv_skins = 0; } + else if (item_type == ITEM_FEATHERS) { inv_feathers = 0; } + else if (item_type == ITEM_DOWN) { inv_down = 0; } + else if (item_type == ITEM_INCENSE) { inv_incense = 0; } + else if (item_type == ITEM_SPEARS) { inv_spears = 0; } + else if (item_type == ITEM_SLINGS) { inv_slings = 0; } + else if (item_type == ITEM_AXES) { inv_axes = 0; } + else if (item_type == ITEM_SNARES) { inv_snares = 0; } + else if (item_type == ITEM_KNIVES) { inv_knives = 0; } + else if (item_type == ITEM_FISHING_POLES) { inv_fishing_poles = 0; } + else if (item_type == ITEM_ROPES) { inv_ropes = 0; } + else if (item_type == ITEM_REED_BASKETS) { inv_reed_baskets = 0; } + else if (item_type == ITEM_CLAY_POTS) { inv_clay_pots = 0; } + else if (item_type == ITEM_SKIN_HATS) { inv_skin_hats = 0; } + else if (item_type == ITEM_SKIN_GLOVES) { inv_skin_gloves = 0; } + else if (item_type == ITEM_SKIN_PANTS) { inv_skin_pants = 0; } + else if (item_type == ITEM_SKIN_TUNICS) { inv_skin_tunics = 0; } + else if (item_type == ITEM_MOCCASINS) { inv_moccasins = 0; } + else if (item_type == ITEM_SKIN_POUCHES) { inv_skin_pouches = 0; } + + cleanup_equipment_after_inventory_change(); + double total_favor = favor_per_item * available; + favor += total_favor; + + speak_with_history("Sacrificed " + available + " " + get_item_label(item_type) + ". Favor +" + format_favor(total_favor) + ". Total " + format_favor(favor) + ".", true); +} + +void run_altar_menu() { + speak_with_history("Altar. Favor " + format_favor(favor) + ".", true); + + int selection = 0; + string[] options; + int[] item_types; + build_personal_inventory_options(options, item_types); + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + 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; + 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; + speak_with_history(options[selection], true); + } + } +} diff --git a/src/menus/base_info.nvgt b/src/menus/base_info.nvgt new file mode 100644 index 0000000..79cba29 --- /dev/null +++ b/src/menus/base_info.nvgt @@ -0,0 +1,59 @@ +// Base info display +// Functions for displaying base status and buildings + +void run_base_info_menu() { + if (x > BASE_END) { + speak_with_history("You are not in the base.", true); + return; + } + + speak_with_history("Base info.", true); + + int selection = 0; + string[] options; + options.insert_last("Barricade health " + barricade_health + " of " + BARRICADE_MAX_HEALTH); + options.insert_last("Residents " + residents_count); + + if (world_storages.length() > 0) { + options.insert_last("Storage built. Total items " + get_storage_total_items()); + int daily_food = get_daily_food_requirement(); + options.insert_last("Food in storage " + storage_meat + " meat. Daily use " + daily_food); + } else { + options.insert_last("Storage not built"); + } + + options.insert_last(get_base_fire_status()); + + if (world_altars.length() > 0) options.insert_last("Altar built"); + else options.insert_last("Altar not built"); + + if (get_herb_garden_at_base() != null) options.insert_last("Herb garden built"); + else options.insert_last("Herb garden not built"); + + if (world_pastures.length() > 0) options.insert_last("Pasture built"); + else options.insert_last("Pasture not built"); + + if (world_stables.length() > 0) options.insert_last("Stable built"); + else options.insert_last("Stable not built"); + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + speak_with_history(options[selection], true); + } + } +} diff --git a/src/menus/character_info.nvgt b/src/menus/character_info.nvgt new file mode 100644 index 0000000..dd5781d --- /dev/null +++ b/src/menus/character_info.nvgt @@ -0,0 +1,35 @@ +// Character info display +// Functions for displaying character stats and equipment + +void show_character_info() { + string[] equipped_clothing; + string[] missing_slots; + + if (equipped_head == EQUIP_HAT) equipped_clothing.insert_last("Skin Hat"); + else missing_slots.insert_last("head"); + if (equipped_torso == EQUIP_TUNIC) equipped_clothing.insert_last("Skin Tunic"); + else missing_slots.insert_last("torso"); + if (equipped_arms == EQUIP_POUCH) equipped_clothing.insert_last("Skin Pouch"); + else missing_slots.insert_last("arms"); + if (equipped_hands == EQUIP_GLOVES) equipped_clothing.insert_last("Skin Gloves"); + else missing_slots.insert_last("hands"); + if (equipped_legs == EQUIP_PANTS) equipped_clothing.insert_last("Skin Pants"); + else missing_slots.insert_last("legs"); + if (equipped_feet == EQUIP_MOCCASINS) equipped_clothing.insert_last("Moccasins"); + else missing_slots.insert_last("feet"); + + string info = "Character info. "; + info += "Health " + player_health + " of " + max_health + ". "; + info += "Weapon " + get_equipped_weapon_name() + ". "; + if (equipped_clothing.length() > 0) { + info += "Clothing equipped: " + join_string_list(equipped_clothing) + ". "; + } else { + info += "No clothing equipped. "; + } + if (missing_slots.length() > 0) { + info += "Missing " + join_string_list(missing_slots) + ". "; + } + info += "Favor " + format_favor(favor) + ". "; + info += "Speed " + get_speed_status() + "."; + speak_with_history(info, true); +} diff --git a/src/menus/equipment_menu.nvgt b/src/menus/equipment_menu.nvgt new file mode 100644 index 0000000..301c166 --- /dev/null +++ b/src/menus/equipment_menu.nvgt @@ -0,0 +1,111 @@ +// Equipment menu system +// Functions for managing equipment (weapons and clothing) + +void check_equipment_menu() { + if (key_pressed(KEY_E)) { + // Check if player has any equipment + 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) { + speak_with_history("Nothing to equip.", true); + } else { + run_equipment_menu(); + } + } +} + +void run_equipment_menu() { + speak_with_history("Equipment menu.", true); + + int selection = 0; + string[] options; + int[] equipment_types; + + // Build menu dynamically based on what player has + if (inv_spears > 0) { + string status = equipment_is_equipped(EQUIP_SPEAR) ? " (equipped)" : ""; + options.insert_last("Spear" + status); + equipment_types.insert_last(EQUIP_SPEAR); + } + if (inv_slings > 0) { + string status = equipment_is_equipped(EQUIP_SLING) ? " (equipped)" : ""; + options.insert_last("Sling" + status); + equipment_types.insert_last(EQUIP_SLING); + } + if (inv_axes > 0) { + string status = equipment_is_equipped(EQUIP_AXE) ? " (equipped)" : ""; + options.insert_last("Stone Axe" + status); + equipment_types.insert_last(EQUIP_AXE); + } + if (inv_skin_hats > 0) { + string status = equipment_is_equipped(EQUIP_HAT) ? " (equipped)" : ""; + options.insert_last("Skin Hat" + status); + equipment_types.insert_last(EQUIP_HAT); + } + if (inv_skin_gloves > 0) { + string status = equipment_is_equipped(EQUIP_GLOVES) ? " (equipped)" : ""; + options.insert_last("Skin Gloves" + status); + equipment_types.insert_last(EQUIP_GLOVES); + } + if (inv_skin_pants > 0) { + string status = equipment_is_equipped(EQUIP_PANTS) ? " (equipped)" : ""; + options.insert_last("Skin Pants" + status); + equipment_types.insert_last(EQUIP_PANTS); + } + if (inv_skin_tunics > 0) { + string status = equipment_is_equipped(EQUIP_TUNIC) ? " (equipped)" : ""; + options.insert_last("Skin Tunic" + status); + equipment_types.insert_last(EQUIP_TUNIC); + } + if (inv_moccasins > 0) { + string status = equipment_is_equipped(EQUIP_MOCCASINS) ? " (equipped)" : ""; + options.insert_last("Moccasins" + status); + equipment_types.insert_last(EQUIP_MOCCASINS); + } + if (inv_skin_pouches > 0) { + string status = equipment_is_equipped(EQUIP_POUCH) ? " (equipped)" : ""; + options.insert_last("Skin Pouch" + status); + equipment_types.insert_last(EQUIP_POUCH); + } + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + 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; + 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); + speak_with_history(get_equipment_name(equip_type) + " unequipped.", true); + } else { + equip_equipment_type(equip_type); + speak_with_history(get_equipment_name(equip_type) + " equipped.", true); + } + update_max_health_from_equipment(); + break; + } + } +} diff --git a/src/menus/inventory_core.nvgt b/src/menus/inventory_core.nvgt new file mode 100644 index 0000000..348d277 --- /dev/null +++ b/src/menus/inventory_core.nvgt @@ -0,0 +1,131 @@ +// Personal inventory menu system +// Functions for displaying and managing personal inventory + +void build_personal_inventory_options(string[]@ options, int[]@ item_types) { + options.resize(0); + item_types.resize(0); + options.insert_last("Sticks: " + inv_sticks); item_types.insert_last(ITEM_STICKS); + options.insert_last("Vines: " + inv_vines); item_types.insert_last(ITEM_VINES); + options.insert_last("Reeds: " + inv_reeds); item_types.insert_last(ITEM_REEDS); + options.insert_last("Stones: " + inv_stones); item_types.insert_last(ITEM_STONES); + options.insert_last("Logs: " + inv_logs); item_types.insert_last(ITEM_LOGS); + options.insert_last("Clay: " + inv_clay); item_types.insert_last(ITEM_CLAY); + options.insert_last("Small Game: " + inv_small_game); item_types.insert_last(ITEM_SMALL_GAME); + options.insert_last("Meat: " + inv_meat); item_types.insert_last(ITEM_MEAT); + options.insert_last("Skins: " + inv_skins); item_types.insert_last(ITEM_SKINS); + options.insert_last("Feathers: " + inv_feathers); item_types.insert_last(ITEM_FEATHERS); + options.insert_last("Down: " + inv_down); item_types.insert_last(ITEM_DOWN); + options.insert_last("Incense: " + inv_incense); item_types.insert_last(ITEM_INCENSE); + options.insert_last("Spears: " + inv_spears); item_types.insert_last(ITEM_SPEARS); + options.insert_last("Slings: " + inv_slings); item_types.insert_last(ITEM_SLINGS); + options.insert_last("Axes: " + inv_axes); item_types.insert_last(ITEM_AXES); + options.insert_last("Snares: " + inv_snares); item_types.insert_last(ITEM_SNARES); + options.insert_last("Knives: " + inv_knives); item_types.insert_last(ITEM_KNIVES); + options.insert_last("Fishing Poles: " + inv_fishing_poles); item_types.insert_last(ITEM_FISHING_POLES); + options.insert_last("Ropes: " + inv_ropes); item_types.insert_last(ITEM_ROPES); + options.insert_last("Reed Baskets: " + inv_reed_baskets); item_types.insert_last(ITEM_REED_BASKETS); + options.insert_last("Clay Pots: " + inv_clay_pots); item_types.insert_last(ITEM_CLAY_POTS); + options.insert_last("Skin Hats: " + inv_skin_hats); item_types.insert_last(ITEM_SKIN_HATS); + options.insert_last("Skin Gloves: " + inv_skin_gloves); item_types.insert_last(ITEM_SKIN_GLOVES); + options.insert_last("Skin Pants: " + inv_skin_pants); item_types.insert_last(ITEM_SKIN_PANTS); + options.insert_last("Skin Tunics: " + inv_skin_tunics); item_types.insert_last(ITEM_SKIN_TUNICS); + options.insert_last("Moccasins: " + inv_moccasins); item_types.insert_last(ITEM_MOCCASINS); + options.insert_last("Skin Pouches: " + inv_skin_pouches); item_types.insert_last(ITEM_SKIN_POUCHES); +} + +void show_inventory() { + string info = "Inventory: "; + info += inv_sticks + " sticks, "; + info += inv_vines + " vines, "; + info += inv_reeds + " reeds, "; + info += inv_stones + " stones, "; + info += inv_logs + " logs, "; + info += inv_clay + " clay, "; + info += inv_small_game + " small game, "; + info += inv_meat + " meat, "; + info += inv_skins + " skins, "; + info += inv_feathers + " feathers, "; + info += inv_down + " down, "; + 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."; + speak_with_history(info, true); +} + +void run_inventory_root_menu() { + speak_with_history("Inventory menu.", true); + + int selection = 0; + string[] options = {"Personal inventory", "Base storage"}; + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_RETURN)) { + if (selection == 0) run_inventory_menu(true); + else run_storage_menu(); + break; + } + } +} + +void run_inventory_menu(bool allow_deposit) { + speak_with_history("Inventory menu.", true); + + int selection = 0; + string[] options; + int[] item_types; + build_personal_inventory_options(options, item_types); + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + 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; + 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; + speak_with_history(options[selection], true); + } + } +} diff --git a/src/menus/menu_utils.nvgt b/src/menus/menu_utils.nvgt new file mode 100644 index 0000000..e108876 --- /dev/null +++ b/src/menus/menu_utils.nvgt @@ -0,0 +1,92 @@ +// Menu utility functions +// Helper functions used across multiple menu systems + +void menu_background_tick() { + update_time(); + update_environment(); + update_snares(); + update_fires(); + update_zombies(); + 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); + } + } + + // Death check + if (player_health <= 0) { + speak_with_history("You have died.", true); + wait(2000); + exit(); + } +} + +string join_string_list(const string[]@ items) { + if (@items == null || items.length() == 0) return ""; + string result = items[0]; + for (uint i = 1; i < items.length(); i++) { + result += ", " + items[i]; + } + return result; +} + +int get_storage_total_items() { + int total = 0; + total += storage_stones; + total += storage_sticks; + total += storage_vines; + total += storage_reeds; + total += storage_logs; + total += storage_clay; + total += storage_small_game; + total += storage_meat; + total += storage_skins; + total += storage_spears; + total += storage_slings; + total += storage_axes; + total += storage_snares; + total += storage_knives; + total += storage_fishing_poles; + total += storage_ropes; + total += storage_reed_baskets; + total += storage_clay_pots; + total += storage_skin_hats; + total += storage_skin_gloves; + total += storage_skin_pants; + total += storage_skin_tunics; + total += storage_moccasins; + total += storage_skin_pouches; + return total; +} + +string get_base_fire_status() { + int total = 0; + int burning = 0; + for (uint i = 0; i < world_fires.length(); i++) { + if (world_fires[i].position <= BASE_END) { + total++; + if (world_fires[i].is_burning()) { + burning++; + } + } + } + if (total == 0) return "No fires in base"; + return "Fires in base: " + burning + " burning, " + total + " total"; +} diff --git a/src/menus/storage_menu.nvgt b/src/menus/storage_menu.nvgt new file mode 100644 index 0000000..082773c --- /dev/null +++ b/src/menus/storage_menu.nvgt @@ -0,0 +1,302 @@ +// Base storage menu system +// Functions for interacting with base storage (deposit/withdraw items) + +void move_small_game_to_storage(int amount) { + for (int i = 0; i < amount; i++) { + string game_type = "small game"; + if (inv_small_game_types.length() > 0) { + game_type = inv_small_game_types[0]; + inv_small_game_types.remove_at(0); + } + storage_small_game_types.insert_last(game_type); + } +} + +void move_small_game_to_personal(int amount) { + for (int i = 0; i < amount; i++) { + string game_type = "small game"; + if (storage_small_game_types.length() > 0) { + game_type = storage_small_game_types[0]; + storage_small_game_types.remove_at(0); + } + inv_small_game_types.insert_last(game_type); + } +} + +int prompt_transfer_amount(const string prompt, int max_amount) { + string input = ui_input_box("Inventory", prompt + " (max " + max_amount + ")", ""); + int amount = parse_int(input); + if (amount <= 0) return 0; + if (amount > max_amount) amount = max_amount; + return amount; +} + +void deposit_item(int item_type) { + int available = get_personal_count(item_type); + if (available <= 0) { + speak_with_history("Nothing to deposit.", true); + return; + } + 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 max_transfer = (available < capacity) ? available : capacity; + int amount = prompt_transfer_amount("Deposit how many?", max_transfer); + if (amount <= 0) return; + + if (item_type == ITEM_STICKS) { inv_sticks -= amount; storage_sticks += amount; } + else if (item_type == ITEM_VINES) { inv_vines -= amount; storage_vines += amount; } + else if (item_type == ITEM_REEDS) { inv_reeds -= amount; storage_reeds += amount; } + else if (item_type == ITEM_STONES) { inv_stones -= amount; storage_stones += amount; } + else if (item_type == ITEM_LOGS) { inv_logs -= amount; storage_logs += amount; } + else if (item_type == ITEM_CLAY) { inv_clay -= amount; storage_clay += amount; } + else if (item_type == ITEM_SMALL_GAME) { inv_small_game -= amount; storage_small_game += amount; move_small_game_to_storage(amount); } + else if (item_type == ITEM_MEAT) { inv_meat -= amount; storage_meat += amount; } + else if (item_type == ITEM_SKINS) { inv_skins -= amount; storage_skins += amount; } + else if (item_type == ITEM_FEATHERS) { inv_feathers -= amount; storage_feathers += amount; } + else if (item_type == ITEM_DOWN) { inv_down -= amount; storage_down += amount; } + else if (item_type == ITEM_INCENSE) { inv_incense -= amount; storage_incense += amount; } + else if (item_type == ITEM_SPEARS) { inv_spears -= amount; storage_spears += amount; } + else if (item_type == ITEM_SLINGS) { inv_slings -= amount; storage_slings += amount; } + else if (item_type == ITEM_AXES) { inv_axes -= amount; storage_axes += amount; } + else if (item_type == ITEM_SNARES) { inv_snares -= amount; storage_snares += amount; } + else if (item_type == ITEM_KNIVES) { inv_knives -= amount; storage_knives += amount; } + else if (item_type == ITEM_FISHING_POLES) { inv_fishing_poles -= amount; storage_fishing_poles += amount; } + else if (item_type == ITEM_ROPES) { inv_ropes -= amount; storage_ropes += amount; } + else if (item_type == ITEM_REED_BASKETS) { inv_reed_baskets -= amount; storage_reed_baskets += amount; } + else if (item_type == ITEM_CLAY_POTS) { inv_clay_pots -= amount; storage_clay_pots += amount; } + else if (item_type == ITEM_SKIN_HATS) { inv_skin_hats -= amount; storage_skin_hats += amount; } + else if (item_type == ITEM_SKIN_GLOVES) { inv_skin_gloves -= amount; storage_skin_gloves += amount; } + else if (item_type == ITEM_SKIN_PANTS) { inv_skin_pants -= amount; storage_skin_pants += amount; } + else if (item_type == ITEM_SKIN_TUNICS) { inv_skin_tunics -= amount; storage_skin_tunics += amount; } + else if (item_type == ITEM_MOCCASINS) { inv_moccasins -= amount; storage_moccasins += amount; } + else if (item_type == ITEM_SKIN_POUCHES) { inv_skin_pouches -= amount; storage_skin_pouches += amount; } + + cleanup_equipment_after_inventory_change(); + 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) { + speak_with_history("Nothing to deposit.", true); + return; + } + + 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 amount = (available < capacity) ? available : capacity; + + if (item_type == ITEM_STICKS) { inv_sticks -= amount; storage_sticks += amount; } + else if (item_type == ITEM_VINES) { inv_vines -= amount; storage_vines += amount; } + else if (item_type == ITEM_REEDS) { inv_reeds -= amount; storage_reeds += amount; } + else if (item_type == ITEM_STONES) { inv_stones -= amount; storage_stones += amount; } + else if (item_type == ITEM_LOGS) { inv_logs -= amount; storage_logs += amount; } + else if (item_type == ITEM_CLAY) { inv_clay -= amount; storage_clay += amount; } + else if (item_type == ITEM_SMALL_GAME) { inv_small_game -= amount; storage_small_game += amount; move_small_game_to_storage(amount); } + else if (item_type == ITEM_MEAT) { inv_meat -= amount; storage_meat += amount; } + else if (item_type == ITEM_SKINS) { inv_skins -= amount; storage_skins += amount; } + else if (item_type == ITEM_FEATHERS) { inv_feathers -= amount; storage_feathers += amount; } + else if (item_type == ITEM_DOWN) { inv_down -= amount; storage_down += amount; } + else if (item_type == ITEM_INCENSE) { inv_incense -= amount; storage_incense += amount; } + else if (item_type == ITEM_SPEARS) { inv_spears -= amount; storage_spears += amount; } + else if (item_type == ITEM_SLINGS) { inv_slings -= amount; storage_slings += amount; } + else if (item_type == ITEM_AXES) { inv_axes -= amount; storage_axes += amount; } + else if (item_type == ITEM_SNARES) { inv_snares -= amount; storage_snares += amount; } + else if (item_type == ITEM_KNIVES) { inv_knives -= amount; storage_knives += amount; } + else if (item_type == ITEM_FISHING_POLES) { inv_fishing_poles -= amount; storage_fishing_poles += amount; } + else if (item_type == ITEM_ROPES) { inv_ropes -= amount; storage_ropes += amount; } + else if (item_type == ITEM_REED_BASKETS) { inv_reed_baskets -= amount; storage_reed_baskets += amount; } + else if (item_type == ITEM_CLAY_POTS) { inv_clay_pots -= amount; storage_clay_pots += amount; } + else if (item_type == ITEM_SKIN_HATS) { inv_skin_hats -= amount; storage_skin_hats += amount; } + else if (item_type == ITEM_SKIN_GLOVES) { inv_skin_gloves -= amount; storage_skin_gloves += amount; } + else if (item_type == ITEM_SKIN_PANTS) { inv_skin_pants -= amount; storage_skin_pants += amount; } + else if (item_type == ITEM_SKIN_TUNICS) { inv_skin_tunics -= amount; storage_skin_tunics += amount; } + else if (item_type == ITEM_MOCCASINS) { inv_moccasins -= amount; storage_moccasins += amount; } + else if (item_type == ITEM_SKIN_POUCHES) { inv_skin_pouches -= amount; storage_skin_pouches += amount; } + + cleanup_equipment_after_inventory_change(); + 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) { + speak_with_history("Nothing to withdraw.", true); + return; + } + int capacity = get_personal_stack_limit() - get_personal_count(item_type); + if (capacity <= 0) { + speak_with_history("You can't carry any more " + get_item_label(item_type) + ".", true); + return; + } + int max_transfer = (available < capacity) ? available : capacity; + int amount = prompt_transfer_amount("Withdraw how many?", max_transfer); + if (amount <= 0) return; + + if (item_type == ITEM_STICKS) { storage_sticks -= amount; inv_sticks += amount; } + else if (item_type == ITEM_VINES) { storage_vines -= amount; inv_vines += amount; } + else if (item_type == ITEM_REEDS) { storage_reeds -= amount; inv_reeds += amount; } + else if (item_type == ITEM_STONES) { storage_stones -= amount; inv_stones += amount; } + else if (item_type == ITEM_LOGS) { storage_logs -= amount; inv_logs += amount; } + else if (item_type == ITEM_CLAY) { storage_clay -= amount; inv_clay += amount; } + else if (item_type == ITEM_SMALL_GAME) { storage_small_game -= amount; inv_small_game += amount; move_small_game_to_personal(amount); } + else if (item_type == ITEM_MEAT) { storage_meat -= amount; inv_meat += amount; } + else if (item_type == ITEM_SKINS) { storage_skins -= amount; inv_skins += amount; } + else if (item_type == ITEM_FEATHERS) { storage_feathers -= amount; inv_feathers += amount; } + else if (item_type == ITEM_DOWN) { storage_down -= amount; inv_down += amount; } + else if (item_type == ITEM_INCENSE) { storage_incense -= amount; inv_incense += amount; } + else if (item_type == ITEM_SPEARS) { storage_spears -= amount; inv_spears += amount; } + else if (item_type == ITEM_SLINGS) { storage_slings -= amount; inv_slings += amount; } + else if (item_type == ITEM_AXES) { storage_axes -= amount; inv_axes += amount; } + else if (item_type == ITEM_SNARES) { storage_snares -= amount; inv_snares += amount; } + else if (item_type == ITEM_KNIVES) { storage_knives -= amount; inv_knives += amount; } + else if (item_type == ITEM_FISHING_POLES) { storage_fishing_poles -= amount; inv_fishing_poles += amount; } + else if (item_type == ITEM_ROPES) { storage_ropes -= amount; inv_ropes += amount; } + else if (item_type == ITEM_REED_BASKETS) { storage_reed_baskets -= amount; inv_reed_baskets += amount; } + else if (item_type == ITEM_CLAY_POTS) { storage_clay_pots -= amount; inv_clay_pots += amount; } + else if (item_type == ITEM_SKIN_HATS) { storage_skin_hats -= amount; inv_skin_hats += amount; } + else if (item_type == ITEM_SKIN_GLOVES) { storage_skin_gloves -= amount; inv_skin_gloves += amount; } + else if (item_type == ITEM_SKIN_PANTS) { storage_skin_pants -= amount; inv_skin_pants += amount; } + else if (item_type == ITEM_SKIN_TUNICS) { storage_skin_tunics -= amount; inv_skin_tunics += amount; } + 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; } + + 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) { + speak_with_history("Nothing to withdraw.", true); + return; + } + + int personal_limit = get_personal_stack_limit(); + int current_personal = get_personal_count(item_type); + int space = personal_limit - current_personal; + + if (space <= 0) { + speak_with_history("Can't carry any more.", true); + return; + } + + int amount = (available < space) ? available : space; + + if (item_type == ITEM_STICKS) { storage_sticks -= amount; inv_sticks += amount; } + else if (item_type == ITEM_VINES) { storage_vines -= amount; inv_vines += amount; } + else if (item_type == ITEM_REEDS) { storage_reeds -= amount; inv_reeds += amount; } + else if (item_type == ITEM_STONES) { storage_stones -= amount; inv_stones += amount; } + else if (item_type == ITEM_LOGS) { storage_logs -= amount; inv_logs += amount; } + else if (item_type == ITEM_CLAY) { storage_clay -= amount; inv_clay += amount; } + else if (item_type == ITEM_SMALL_GAME) { storage_small_game -= amount; inv_small_game += amount; move_small_game_to_personal(amount); } + else if (item_type == ITEM_MEAT) { storage_meat -= amount; inv_meat += amount; } + else if (item_type == ITEM_SKINS) { storage_skins -= amount; inv_skins += amount; } + else if (item_type == ITEM_FEATHERS) { storage_feathers -= amount; inv_feathers += amount; } + else if (item_type == ITEM_DOWN) { storage_down -= amount; inv_down += amount; } + else if (item_type == ITEM_INCENSE) { storage_incense -= amount; inv_incense += amount; } + else if (item_type == ITEM_SPEARS) { storage_spears -= amount; inv_spears += amount; } + else if (item_type == ITEM_SLINGS) { storage_slings -= amount; inv_slings += amount; } + else if (item_type == ITEM_AXES) { storage_axes -= amount; inv_axes += amount; } + else if (item_type == ITEM_SNARES) { storage_snares -= amount; inv_snares += amount; } + else if (item_type == ITEM_KNIVES) { storage_knives -= amount; inv_knives += amount; } + else if (item_type == ITEM_FISHING_POLES) { storage_fishing_poles -= amount; inv_fishing_poles += amount; } + else if (item_type == ITEM_ROPES) { storage_ropes -= amount; inv_ropes += amount; } + else if (item_type == ITEM_REED_BASKETS) { storage_reed_baskets -= amount; inv_reed_baskets += amount; } + else if (item_type == ITEM_CLAY_POTS) { storage_clay_pots -= amount; inv_clay_pots += amount; } + else if (item_type == ITEM_SKIN_HATS) { storage_skin_hats -= amount; inv_skin_hats += amount; } + else if (item_type == ITEM_SKIN_GLOVES) { storage_skin_gloves -= amount; inv_skin_gloves += amount; } + else if (item_type == ITEM_SKIN_PANTS) { storage_skin_pants -= amount; inv_skin_pants += amount; } + else if (item_type == ITEM_SKIN_TUNICS) { storage_skin_tunics -= amount; inv_skin_tunics += amount; } + 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; } + + speak_with_history("Withdrew " + amount + " " + get_item_label(item_type) + ".", true); +} + +void build_storage_inventory_options(string[]@ options, int[]@ item_types) { + options.resize(0); + item_types.resize(0); + options.insert_last("Sticks: " + storage_sticks); item_types.insert_last(ITEM_STICKS); + options.insert_last("Vines: " + storage_vines); item_types.insert_last(ITEM_VINES); + options.insert_last("Reeds: " + storage_reeds); item_types.insert_last(ITEM_REEDS); + options.insert_last("Stones: " + storage_stones); item_types.insert_last(ITEM_STONES); + options.insert_last("Logs: " + storage_logs); item_types.insert_last(ITEM_LOGS); + options.insert_last("Clay: " + storage_clay); item_types.insert_last(ITEM_CLAY); + options.insert_last("Small Game: " + storage_small_game); item_types.insert_last(ITEM_SMALL_GAME); + options.insert_last("Meat: " + storage_meat); item_types.insert_last(ITEM_MEAT); + options.insert_last("Skins: " + storage_skins); item_types.insert_last(ITEM_SKINS); + options.insert_last("Feathers: " + storage_feathers); item_types.insert_last(ITEM_FEATHERS); + options.insert_last("Down: " + storage_down); item_types.insert_last(ITEM_DOWN); + options.insert_last("Incense: " + storage_incense); item_types.insert_last(ITEM_INCENSE); + options.insert_last("Spears: " + storage_spears); item_types.insert_last(ITEM_SPEARS); + options.insert_last("Slings: " + storage_slings); item_types.insert_last(ITEM_SLINGS); + options.insert_last("Axes: " + storage_axes); item_types.insert_last(ITEM_AXES); + options.insert_last("Snares: " + storage_snares); item_types.insert_last(ITEM_SNARES); + options.insert_last("Knives: " + storage_knives); item_types.insert_last(ITEM_KNIVES); + options.insert_last("Fishing Poles: " + storage_fishing_poles); item_types.insert_last(ITEM_FISHING_POLES); + options.insert_last("Ropes: " + storage_ropes); item_types.insert_last(ITEM_ROPES); + options.insert_last("Reed Baskets: " + storage_reed_baskets); item_types.insert_last(ITEM_REED_BASKETS); + options.insert_last("Clay Pots: " + storage_clay_pots); item_types.insert_last(ITEM_CLAY_POTS); + options.insert_last("Skin Hats: " + storage_skin_hats); item_types.insert_last(ITEM_SKIN_HATS); + options.insert_last("Skin Gloves: " + storage_skin_gloves); item_types.insert_last(ITEM_SKIN_GLOVES); + options.insert_last("Skin Pants: " + storage_skin_pants); item_types.insert_last(ITEM_SKIN_PANTS); + options.insert_last("Skin Tunics: " + storage_skin_tunics); item_types.insert_last(ITEM_SKIN_TUNICS); + options.insert_last("Moccasins: " + storage_moccasins); item_types.insert_last(ITEM_MOCCASINS); + options.insert_last("Skin Pouches: " + storage_skin_pouches); item_types.insert_last(ITEM_SKIN_POUCHES); +} + +void run_storage_menu() { + if (world_storages.length() == 0) { + speak_with_history("No storage built.", true); + return; + } + + speak_with_history("Base storage.", true); + + int selection = 0; + string[] options; + int[] item_types; + build_storage_inventory_options(options, item_types); + + while(true) { + wait(5); + menu_background_tick(); + if (key_pressed(KEY_ESCAPE)) { + speak_with_history("Closed.", true); + break; + } + + if (key_pressed(KEY_DOWN)) { + selection++; + if (selection >= options.length()) selection = 0; + speak_with_history(options[selection], true); + } + + if (key_pressed(KEY_UP)) { + selection--; + if (selection < 0) selection = options.length() - 1; + 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; + 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; + speak_with_history(options[selection], true); + } + } +}