Files
draugnorak/src/crafting/craft_materials.nvgt
T

510 lines
18 KiB
Plaintext

// 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);
}