// Crafting materials void run_materials_menu() { int selection = 0; string[] options = { "Butcher Game [Requires Game, Knife, Fire nearby]", "Smoke Fish (1 Fish, 1 Stick) [Requires Fire nearby]", "Arrows (2 Sticks, 4 Feathers, 2 Stones) [Requires Quiver]", "Bowstring (3 Sinew) [Requires Fire nearby]", "Incense (6 Sticks, 2 Vines, 1 Reed) [Requires Altar]" }; speak_with_history("Materials. " + options[selection], true); while(true) { wait(5); if (menu_background_tick()) { return; } if (key_pressed(KEY_ESCAPE)) { speak_with_history("Closed.", true); break; } if (key_pressed(KEY_DOWN)) { play_menu_move_sound(); selection++; if (selection >= options.length()) selection = 0; speak_with_history(options[selection], true); } if (key_pressed(KEY_UP)) { play_menu_move_sound(); selection--; if (selection < 0) selection = options.length() - 1; speak_with_history(options[selection], true); } if (key_pressed(KEY_RETURN)) { play_menu_select_sound(); if (selection == 0) butcher_small_game(); else if (selection == 1) craft_smoke_fish(); else if (selection == 2) craft_arrows(); else if (selection == 3) craft_bowstring(); else if (selection == 4) craft_incense(); break; } if (key_pressed(KEY_TAB)) { play_menu_select_sound(); if (selection == 0) butcher_small_game_max(); else if (selection == 1) craft_smoke_fish_max(); else if (selection == 2) craft_arrows_max(); else if (selection == 3) craft_bowstring_max(); else if (selection == 4) craft_incense_max(); break; } } } void craft_arrows() { if (get_personal_count(ITEM_QUIVERS) <= 0) { speak_with_history("You need a quiver to craft arrows.", true); return; } int currentArrows = get_personal_count(ITEM_ARROWS); int capacity = get_arrow_limit() - currentArrows; if (capacity < ARROWS_PER_CRAFT) { speak_with_history("Not enough quiver capacity for arrows.", true); return; } string missing = ""; if (get_personal_count(ITEM_STICKS) < 2) missing += "2 sticks "; if (get_personal_count(ITEM_FEATHERS) < 4) missing += "4 feathers "; if (get_personal_count(ITEM_STONES) < 2) missing += "2 stones "; if (missing == "") { simulate_crafting(8); add_personal_count(ITEM_STICKS, -2); add_personal_count(ITEM_FEATHERS, -4); add_personal_count(ITEM_STONES, -2); add_personal_count(ITEM_ARROWS, ARROWS_PER_CRAFT); speak_with_history("Crafted " + ARROWS_PER_CRAFT + " arrows.", true); } else { speak_with_history("Missing: " + missing, true); } } void craft_arrows_max() { if (get_personal_count(ITEM_QUIVERS) <= 0) { speak_with_history("You need a quiver to craft arrows.", true); return; } int currentArrows = get_personal_count(ITEM_ARROWS); int capacity = get_arrow_limit() - currentArrows; int maxByCapacity = capacity / ARROWS_PER_CRAFT; if (maxByCapacity <= 0) { speak_with_history("Not enough quiver capacity for arrows.", true); return; } int maxBySticks = get_personal_count(ITEM_STICKS) / 2; int maxByFeathers = get_personal_count(ITEM_FEATHERS) / 4; int maxByStones = get_personal_count(ITEM_STONES) / 2; int maxCraft = maxBySticks; if (maxByFeathers < maxCraft) maxCraft = maxByFeathers; if (maxByStones < maxCraft) maxCraft = maxByStones; if (maxByCapacity < maxCraft) maxCraft = maxByCapacity; if (maxCraft <= 0) { string missing = ""; if (get_personal_count(ITEM_STICKS) < 2) missing += "2 sticks "; if (get_personal_count(ITEM_FEATHERS) < 4) missing += "4 feathers "; if (get_personal_count(ITEM_STONES) < 2) missing += "2 stones "; speak_with_history("Missing: " + missing, true); return; } int totalCost = maxCraft * 8; // 2 sticks + 4 feathers + 2 stones per bundle int craftTime = (totalCost < maxCraft * 4) ? maxCraft * 4 : totalCost; simulate_crafting(craftTime); add_personal_count(ITEM_STICKS, -(maxCraft * 2)); add_personal_count(ITEM_FEATHERS, -(maxCraft * 4)); add_personal_count(ITEM_STONES, -(maxCraft * 2)); add_personal_count(ITEM_ARROWS, ARROWS_PER_CRAFT * maxCraft); speak_with_history("Crafted " + (ARROWS_PER_CRAFT * maxCraft) + " arrows.", true); } void craft_bowstring() { WorldFire@ fire = get_fire_within_range(x, 3); if (fire == null) { speak_with_history("You need a fire within 3 tiles to make bowstring.", true); return; } string missing = ""; if (get_personal_count(ITEM_SINEW) < 3) missing += "3 sinew "; if (missing == "") { if (get_personal_count(ITEM_BOWSTRINGS) >= get_personal_stack_limit()) { speak_with_history("You can't carry any more bowstrings.", true); return; } simulate_crafting(3); add_personal_count(ITEM_SINEW, -3); add_personal_count(ITEM_BOWSTRINGS, 1); speak_with_history("Crafted a bowstring.", true); } else { speak_with_history("Missing: " + missing, true); } } void craft_bowstring_max() { WorldFire@ fire = get_fire_within_range(x, 3); if (fire == null) { speak_with_history("You need a fire within 3 tiles to make bowstring.", true); return; } if (get_personal_count(ITEM_BOWSTRINGS) >= get_personal_stack_limit()) { speak_with_history("You can't carry any more bowstrings.", true); return; } int max_by_sinew = get_personal_count(ITEM_SINEW) / 3; int max_craft = max_by_sinew; int space = get_personal_stack_limit() - get_personal_count(ITEM_BOWSTRINGS); if (max_craft > space) max_craft = space; if (max_craft <= 0) { speak_with_history("Missing: 3 sinew", true); return; } int total_cost = max_craft * 3; // 3 sinew per bowstring int craft_time = (total_cost < max_craft * 4) ? max_craft * 4 : total_cost; simulate_crafting(craft_time); add_personal_count(ITEM_SINEW, -(max_craft * 3)); add_personal_count(ITEM_BOWSTRINGS, max_craft); speak_with_history("Crafted " + max_craft + " Bowstrings.", true); } void craft_incense() { if (world_altars.length() == 0) { speak_with_history("You need an altar to craft incense.", true); return; } string missing = ""; if (get_personal_count(ITEM_STICKS) < INCENSE_STICK_COST) missing += INCENSE_STICK_COST + " sticks "; if (get_personal_count(ITEM_VINES) < INCENSE_VINE_COST) missing += INCENSE_VINE_COST + " vines "; if (get_personal_count(ITEM_REEDS) < INCENSE_REED_COST) missing += INCENSE_REED_COST + " reed "; if (missing == "") { if (get_personal_count(ITEM_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); add_personal_count(ITEM_STICKS, -INCENSE_STICK_COST); add_personal_count(ITEM_VINES, -INCENSE_VINE_COST); add_personal_count(ITEM_REEDS, -INCENSE_REED_COST); add_personal_count(ITEM_INCENSE, 1); 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 (get_personal_count(ITEM_INCENSE) >= get_personal_stack_limit()) { speak_with_history("You can't carry any more incense.", true); return; } int max_by_sticks = get_personal_count(ITEM_STICKS) / INCENSE_STICK_COST; int max_by_vines = get_personal_count(ITEM_VINES) / INCENSE_VINE_COST; int max_by_reeds = get_personal_count(ITEM_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() - get_personal_count(ITEM_INCENSE); if (max_craft > space) max_craft = space; if (max_craft <= 0) { string missing = ""; if (get_personal_count(ITEM_STICKS) < INCENSE_STICK_COST) missing += INCENSE_STICK_COST + " sticks "; if (get_personal_count(ITEM_VINES) < INCENSE_VINE_COST) missing += INCENSE_VINE_COST + " vines "; if (get_personal_count(ITEM_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); add_personal_count(ITEM_STICKS, -(max_craft * INCENSE_STICK_COST)); add_personal_count(ITEM_VINES, -(max_craft * INCENSE_VINE_COST)); add_personal_count(ITEM_REEDS, -(max_craft * INCENSE_REED_COST)); add_personal_count(ITEM_INCENSE, max_craft); speak_with_history("Crafted " + max_craft + " Incense.", true); } void craft_smoke_fish() { WorldFire@ fire = get_fire_within_range(x, 3); if (fire == null) { speak_with_history("You need a fire within 3 tiles to smoke fish.", true); return; } string missing = ""; if (get_personal_count(ITEM_FISH) < 1) missing += "1 fish "; if (get_personal_count(ITEM_STICKS) < 1) missing += "1 stick "; if (missing == "") { int weight = (personal_fish_weights.length() > 0) ? personal_fish_weights[0] : get_default_fish_weight(); int yield = get_smoked_fish_yield(weight); int space = get_personal_stack_limit() - get_personal_count(ITEM_SMOKED_FISH); if (space < yield) { speak_with_history("You can't carry any more smoked fish.", true); return; } simulate_crafting(2); pop_personal_fish_weight(); add_personal_count(ITEM_FISH, -1); add_personal_count(ITEM_STICKS, -1); add_personal_count(ITEM_SMOKED_FISH, yield); speak_with_history("Smoked a fish into " + yield + " smoked fish.", true); } else { speak_with_history("Missing: " + missing, true); } } void craft_smoke_fish_max() { WorldFire@ fire = get_fire_within_range(x, 3); if (fire == null) { speak_with_history("You need a fire within 3 tiles to smoke fish.", true); return; } int max_by_fish = get_personal_count(ITEM_FISH); int max_by_sticks = get_personal_count(ITEM_STICKS); int max_craft = max_by_fish; if (max_by_sticks < max_craft) max_craft = max_by_sticks; if (max_craft <= 0) { string missing = ""; if (get_personal_count(ITEM_FISH) < 1) missing += "1 fish "; if (get_personal_count(ITEM_STICKS) < 1) missing += "1 stick "; speak_with_history("Missing: " + missing, true); return; } int space = get_personal_stack_limit() - get_personal_count(ITEM_SMOKED_FISH); if (space <= 0) { speak_with_history("You can't carry any more smoked fish.", true); return; } int fish_to_smoke = 0; int total_yield = 0; for (int i = 0; i < max_craft; i++) { int weight = (i < int(personal_fish_weights.length())) ? personal_fish_weights[i] : get_default_fish_weight(); int yield = get_smoked_fish_yield(weight); if (total_yield + yield > space) break; total_yield += yield; fish_to_smoke++; } if (fish_to_smoke <= 0) { speak_with_history("You can't carry any more smoked fish.", true); return; } int total_cost = fish_to_smoke * 2; int craft_time = (total_cost < fish_to_smoke * 4) ? fish_to_smoke * 4 : total_cost; simulate_crafting(craft_time); for (int i = 0; i < fish_to_smoke; i++) { pop_personal_fish_weight(); } add_personal_count(ITEM_FISH, -fish_to_smoke); add_personal_count(ITEM_STICKS, -fish_to_smoke); add_personal_count(ITEM_SMOKED_FISH, total_yield); speak_with_history("Smoked " + fish_to_smoke + " fish into " + total_yield + " smoked fish.", true); } void butcher_small_game() { string missing = ""; // Check for knife if (get_personal_count(ITEM_KNIVES) < 1) missing += "Stone Knife "; // Check for small game or boar if (get_personal_count(ITEM_SMALL_GAME) < 1 && get_personal_count(ITEM_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 (get_personal_count(ITEM_MEAT) >= get_personal_stack_limit()) { speak_with_history("You can't carry any more meat.", true); return; } if (get_personal_count(ITEM_SKINS) >= get_personal_stack_limit()) { speak_with_history("You can't carry any more skins.", true); return; } simulate_crafting(1); string game_type = ""; if (get_personal_count(ITEM_BOAR_CARCASSES) > 0) { game_type = "boar carcass"; add_personal_count(ITEM_BOAR_CARCASSES, -1); } else { game_type = personal_small_game_types[0]; personal_small_game_types.remove_at(0); add_personal_count(ITEM_SMALL_GAME, -1); } if (game_type == "goose") { add_personal_count(ITEM_MEAT, 1); add_personal_count(ITEM_FEATHERS, random(3, 6)); add_personal_count(ITEM_DOWN, random(1, 3)); speak_with_history("Butchered goose. Got 1 meat, feathers, and down.", true); } else if (game_type == "turkey") { add_personal_count(ITEM_MEAT, 1); add_personal_count(ITEM_FEATHERS, random(1, 4)); speak_with_history("Butchered turkey. Got 1 meat and feathers.", true); } else if (game_type == "boar carcass") { add_personal_count(ITEM_MEAT, random(2, 3)); add_personal_count(ITEM_SKINS, 3); add_personal_count(ITEM_SINEW, 2); speak_with_history("Butchered boar. Got meat, 3 skins, and 2 sinew.", true); } else { add_personal_count(ITEM_MEAT, 1); add_personal_count(ITEM_SKINS, 1); 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 (get_personal_count(ITEM_KNIVES) < 1) { speak_with_history("Missing: Stone Knife", true); return; } // Check for small game or boar if (get_personal_count(ITEM_SMALL_GAME) < 1 && get_personal_count(ITEM_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() - get_personal_count(ITEM_MEAT); int skins_space = get_personal_stack_limit() - get_personal_count(ITEM_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 = get_personal_count(ITEM_SMALL_GAME) + get_personal_count(ITEM_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 turkey_count = 0; int boars_count = 0; for (int i = 0; i < max_craft; i++) { string game_type = ""; if (get_personal_count(ITEM_BOAR_CARCASSES) > 0) { game_type = "boar carcass"; add_personal_count(ITEM_BOAR_CARCASSES, -1); boars_count++; } else { game_type = personal_small_game_types[0]; personal_small_game_types.remove_at(0); add_personal_count(ITEM_SMALL_GAME, -1); if (game_type == "goose") geese_count++; if (game_type == "turkey") turkey_count++; } if (game_type == "goose") { total_meat++; total_feathers += random(3, 6); total_down += random(1, 3); } else if (game_type == "turkey") { total_meat++; total_feathers += random(1, 4); } 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 add_personal_count(ITEM_MEAT, total_meat); add_personal_count(ITEM_SKINS, total_skins); add_personal_count(ITEM_FEATHERS, total_feathers); add_personal_count(ITEM_DOWN, total_down); add_personal_count(ITEM_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); }