diff --git a/src/base_system.nvgt b/src/base_system.nvgt index db0f0fd..74e2927 100644 --- a/src/base_system.nvgt +++ b/src/base_system.nvgt @@ -127,7 +127,7 @@ void attempt_resident_fishing() { if (residents_count <= 0) return; if (get_storage_count(ITEM_FISHING_POLES) <= 0) return; if (!has_any_streams()) return; - if (get_storage_count(ITEM_FISH) >= BASE_STORAGE_MAX) return; + if (get_storage_count(ITEM_FISH) >= get_storage_stack_limit()) return; int active_fishers = residents_count; int poles = get_storage_count(ITEM_FISHING_POLES); @@ -144,7 +144,7 @@ void attempt_resident_fishing() { continue; } if (random(1, 100) > fishing_chance) continue; - if (get_storage_count(ITEM_FISH) >= BASE_STORAGE_MAX) break; + if (get_storage_count(ITEM_FISH) >= get_storage_stack_limit()) break; add_storage_count(ITEM_FISH, 1); add_storage_fish_weight(random(FISH_WEIGHT_MIN, FISH_WEIGHT_MAX)); caught++; @@ -186,7 +186,7 @@ void attempt_resident_fish_smoking() { int weight = (storage_fish_weights.length() > 0) ? storage_fish_weights[0] : get_default_fish_weight(); int yield = get_smoked_fish_yield(weight); - if (get_storage_count(ITEM_SMOKED_FISH) + yield > BASE_STORAGE_MAX) return; + if (get_storage_count(ITEM_SMOKED_FISH) + yield > get_storage_stack_limit()) return; pop_storage_fish_weight(); add_storage_count(ITEM_FISH, -1); @@ -212,21 +212,21 @@ void attempt_livestock_production() { int feathers_produced = 0; for (int i = 0; i < count; i++) { - if (get_storage_count(ITEM_MEAT) < BASE_STORAGE_MAX) { + if (get_storage_count(ITEM_MEAT) < get_storage_stack_limit()) { if (random(1, 100) <= LIVESTOCK_MEAT_CHANCE) { add_storage_count(ITEM_MEAT, 1); meat_produced++; } } - if (get_storage_count(ITEM_SKINS) < BASE_STORAGE_MAX) { + if (get_storage_count(ITEM_SKINS) < get_storage_stack_limit()) { if (random(1, 100) <= LIVESTOCK_SKIN_CHANCE) { add_storage_count(ITEM_SKINS, 1); skins_produced++; } } - if (get_storage_count(ITEM_FEATHERS) < BASE_STORAGE_MAX) { + if (get_storage_count(ITEM_FEATHERS) < get_storage_stack_limit()) { if (random(1, 100) <= LIVESTOCK_FEATHER_CHANCE) { add_storage_count(ITEM_FEATHERS, 1); feathers_produced++; @@ -573,7 +573,7 @@ void process_daily_weapon_breakage() { void attempt_resident_clothing_repairs() { if (residents_count <= 0) return; - int threshold = BASE_STORAGE_MAX / 2; + int threshold = get_storage_stack_limit() / 2; if (threshold < RESIDENT_CLOTHING_REPAIR_COST) { threshold = RESIDENT_CLOTHING_REPAIR_COST; } @@ -678,7 +678,7 @@ void attempt_resident_snare_retrieval() { } // Check if storage has room for small game - if (get_storage_count(ITEM_SMALL_GAME) >= BASE_STORAGE_MAX) continue; + if (get_storage_count(ITEM_SMALL_GAME) >= get_storage_stack_limit()) continue; // Retrieve the game string game_type = snare.catch_type; @@ -761,11 +761,11 @@ void attempt_resident_butchering() { } // Check storage capacity for outputs - if (meat_yield > 0 && get_storage_count(ITEM_MEAT) + meat_yield > BASE_STORAGE_MAX) return; - if (skins_yield > 0 && get_storage_count(ITEM_SKINS) + skins_yield > BASE_STORAGE_MAX) return; - if (feathers_yield > 0 && get_storage_count(ITEM_FEATHERS) + feathers_yield > BASE_STORAGE_MAX) return; - if (down_yield > 0 && get_storage_count(ITEM_DOWN) + down_yield > BASE_STORAGE_MAX) return; - if (sinew_yield > 0 && get_storage_count(ITEM_SINEW) + sinew_yield > BASE_STORAGE_MAX) return; + if (meat_yield > 0 && get_storage_count(ITEM_MEAT) + meat_yield > get_storage_stack_limit()) return; + if (skins_yield > 0 && get_storage_count(ITEM_SKINS) + skins_yield > get_storage_stack_limit()) return; + if (feathers_yield > 0 && get_storage_count(ITEM_FEATHERS) + feathers_yield > get_storage_stack_limit()) return; + if (down_yield > 0 && get_storage_count(ITEM_DOWN) + down_yield > get_storage_stack_limit()) return; + if (sinew_yield > 0 && get_storage_count(ITEM_SINEW) + sinew_yield > get_storage_stack_limit()) return; // Consume the game if (is_boar) { @@ -896,7 +896,7 @@ void attempt_resident_foraging() { if (get_storage_count(ITEM_REED_BASKETS) <= 0) return; // Check if storage has room for basket food - if (get_storage_count(ITEM_BASKET_FOOD) >= BASE_STORAGE_MAX) return; + if (get_storage_count(ITEM_BASKET_FOOD) >= get_storage_stack_limit()) return; // Number of residents who can forage = min(residents, baskets) int active_foragers = (residents_count < get_storage_count(ITEM_REED_BASKETS)) ? residents_count : get_storage_count(ITEM_REED_BASKETS); @@ -917,7 +917,7 @@ void attempt_resident_foraging() { if (random(1, 100) > forage_chance) continue; // Check storage capacity - if (get_storage_count(ITEM_BASKET_FOOD) >= BASE_STORAGE_MAX) break; + if (get_storage_count(ITEM_BASKET_FOOD) >= get_storage_stack_limit()) break; // Consume a reed basket and produce a basket of fruits and nuts add_storage_count(ITEM_REED_BASKETS, -1); diff --git a/src/bosses/bandit_hideout.nvgt b/src/bosses/bandit_hideout.nvgt index 555e8ae..ea84926 100644 --- a/src/bosses/bandit_hideout.nvgt +++ b/src/bosses/bandit_hideout.nvgt @@ -661,7 +661,7 @@ void update_hideout_bandits() { int add_hideout_storage_item(int itemType, int amount) { if (amount <= 0) return 0; - int capacity = BASE_STORAGE_MAX - get_storage_count(itemType); + int capacity = get_storage_stack_limit() - get_storage_count(itemType); if (capacity <= 0) return 0; int addedAmount = amount; if (addedAmount > capacity) addedAmount = capacity; diff --git a/src/constants.nvgt b/src/constants.nvgt index 8edd27f..31f2d9a 100644 --- a/src/constants.nvgt +++ b/src/constants.nvgt @@ -19,7 +19,12 @@ int walk_speed = BASE_WALK_SPEED; int jump_speed = 170; const int MAX_ITEM_STACK = 9; const int POUCH_STACK_BONUS = 2; -const int BASE_STORAGE_MAX = 50; +const int STORAGE_LEVEL_BASE = 0; +const int STORAGE_LEVEL_UPGRADE_1 = 1; +const int STORAGE_LEVEL_UPGRADE_2 = 2; +const int BASE_STORAGE_START_MAX = 9; +const int BASE_STORAGE_UPGRADE_1_MAX = 50; +const int BASE_STORAGE_UPGRADE_2_MAX = 100; const int BLESSING_HEAL_AMOUNT = 3; const int BLESSING_BARRICADE_REPAIR = 20; const int BLESSING_SPEED_DURATION = 300000; @@ -126,6 +131,9 @@ const int BARRICADE_STONE_HEALTH = 20; const int STORAGE_LOG_COST = 6; const int STORAGE_STONE_COST = 9; const int STORAGE_VINE_COST = 8; +const int STORAGE_UPGRADE2_LOG_COST = 12; +const int STORAGE_UPGRADE2_STONE_COST = 18; +const int STORAGE_UPGRADE2_VINE_COST = 16; const int PASTURE_LOG_COST = 8; const int PASTURE_ROPE_COST = 18; const int STABLE_LOG_COST = 10; diff --git a/src/crafting/craft_buildings.nvgt b/src/crafting/craft_buildings.nvgt index 4132aae..5313375 100644 --- a/src/crafting/craft_buildings.nvgt +++ b/src/crafting/craft_buildings.nvgt @@ -18,9 +18,9 @@ bool has_building_options() { if (x > BASE_END || !base_has_firepit) return true; if (x > BASE_END || !base_has_fire) return true; if (get_herb_garden_at_base() == null) return true; - if (world_storages.length() == 0) return true; - if (world_pastures.length() == 0 && world_storages.length() > 0) return true; - if (world_stables.length() == 0 && world_storages.length() > 0) return true; + if (storage_level < STORAGE_LEVEL_UPGRADE_2) return true; + if (world_pastures.length() == 0 && storage_level >= STORAGE_LEVEL_UPGRADE_1) return true; + if (world_stables.length() == 0 && storage_level >= STORAGE_LEVEL_UPGRADE_1) return true; if (world_altars.length() == 0) return true; return false; } @@ -64,21 +64,24 @@ void run_buildings_menu() { 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]"); + // Storage upgrades + if (storage_level < STORAGE_LEVEL_UPGRADE_1) { + options.insert_last("Upgrade Storage (6 Logs, 9 Stones, 8 Vines) [Base Only, 50 each]"); + building_types.insert_last(3); + } else if (storage_level == STORAGE_LEVEL_UPGRADE_1) { + options.insert_last("Upgrade Storage (12 Logs, 18 Stones, 16 Vines) [Base Only, 100 each]"); building_types.insert_last(3); } - // Only show pasture if not built and storage exists - if (world_pastures.length() == 0 && world_storages.length() > 0) { - options.insert_last("Pasture (8 Logs, 18 Ropes) [Base Only, Requires Storage]"); + // Only show pasture if not built and storage is upgraded + if (world_pastures.length() == 0 && storage_level >= STORAGE_LEVEL_UPGRADE_1) { + options.insert_last("Pasture (8 Logs, 18 Ropes) [Base Only, Requires Storage Upgrade]"); building_types.insert_last(4); } - // Only show stable if not built and storage exists - if (world_stables.length() == 0 && world_storages.length() > 0) { - options.insert_last("Stable (10 Logs, 15 Stones, 10 Vines) [Base Only, Requires Storage]"); + // Only show stable if not built and storage is upgraded + if (world_stables.length() == 0 && storage_level >= STORAGE_LEVEL_UPGRADE_1) { + options.insert_last("Stable (10 Logs, 15 Stones, 10 Vines) [Base Only, Requires Storage Upgrade]"); building_types.insert_last(5); } @@ -229,22 +232,39 @@ void craft_storage() { speak_with_history("Storage must be built in the base.", true); return; } - if (world_storages.length() > 0) { - speak_with_history("Storage already built.", true); + if (storage_level >= STORAGE_LEVEL_UPGRADE_2) { + speak_with_history("Storage is fully upgraded.", true); return; } string missing = ""; - if (get_personal_count(ITEM_LOGS) < STORAGE_LOG_COST) missing += STORAGE_LOG_COST + " logs "; - if (get_personal_count(ITEM_STONES) < STORAGE_STONE_COST) missing += STORAGE_STONE_COST + " stones "; - if (get_personal_count(ITEM_VINES) < STORAGE_VINE_COST) missing += STORAGE_VINE_COST + " vines "; + int logCost = STORAGE_LOG_COST; + int stoneCost = STORAGE_STONE_COST; + int vineCost = STORAGE_VINE_COST; + int targetLevel = STORAGE_LEVEL_UPGRADE_1; + int newCapacity = BASE_STORAGE_UPGRADE_1_MAX; + int craftTime = 23; + if (storage_level >= STORAGE_LEVEL_UPGRADE_1) { + logCost = STORAGE_UPGRADE2_LOG_COST; + stoneCost = STORAGE_UPGRADE2_STONE_COST; + vineCost = STORAGE_UPGRADE2_VINE_COST; + targetLevel = STORAGE_LEVEL_UPGRADE_2; + newCapacity = BASE_STORAGE_UPGRADE_2_MAX; + craftTime = 46; + } + if (get_personal_count(ITEM_LOGS) < logCost) missing += logCost + " logs "; + if (get_personal_count(ITEM_STONES) < stoneCost) missing += stoneCost + " stones "; + if (get_personal_count(ITEM_VINES) < vineCost) missing += vineCost + " vines "; if (missing == "") { - simulate_crafting(23); - add_personal_count(ITEM_LOGS, -STORAGE_LOG_COST); - add_personal_count(ITEM_STONES, -STORAGE_STONE_COST); - add_personal_count(ITEM_VINES, -STORAGE_VINE_COST); - add_world_storage(x); - speak_with_history("Storage built.", true); + simulate_crafting(craftTime); + add_personal_count(ITEM_LOGS, -logCost); + add_personal_count(ITEM_STONES, -stoneCost); + add_personal_count(ITEM_VINES, -vineCost); + if (world_storages.length() == 0) { + add_world_storage(x); + } + storage_level = targetLevel; + speak_with_history("Storage upgraded. Capacity is now " + newCapacity + " per item.", true); } else { speak_with_history("Missing: " + missing, true); } @@ -255,8 +275,8 @@ void craft_pasture() { speak_with_history("Pasture must be built in the base.", true); return; } - if (world_storages.length() == 0) { - speak_with_history("Storage must be built before a pasture.", true); + if (storage_level < STORAGE_LEVEL_UPGRADE_1) { + speak_with_history("Storage must be upgraded before a pasture.", true); return; } if (world_pastures.length() > 0) { @@ -283,8 +303,8 @@ void craft_stable() { speak_with_history("Stable must be built in the base.", true); return; } - if (world_storages.length() == 0) { - speak_with_history("Storage must be built before a stable.", true); + if (storage_level < STORAGE_LEVEL_UPGRADE_1) { + speak_with_history("Storage must be upgraded before a stable.", true); return; } if (world_stables.length() > 0) { diff --git a/src/inventory_items.nvgt b/src/inventory_items.nvgt index 2f746be..9d68d5e 100644 --- a/src/inventory_items.nvgt +++ b/src/inventory_items.nvgt @@ -69,6 +69,12 @@ int get_personal_stack_limit() { return limit; } +int get_storage_stack_limit() { + if (storage_level <= STORAGE_LEVEL_BASE) return BASE_STORAGE_START_MAX; + if (storage_level == STORAGE_LEVEL_UPGRADE_1) return BASE_STORAGE_UPGRADE_1_MAX; + return BASE_STORAGE_UPGRADE_2_MAX; +} + int get_arrow_limit() { // Quiver required to hold arrows // Each quiver holds 12 arrows diff --git a/src/menus/storage_menu.nvgt b/src/menus/storage_menu.nvgt index e5b783d..b0553d9 100644 --- a/src/menus/storage_menu.nvgt +++ b/src/menus/storage_menu.nvgt @@ -63,7 +63,7 @@ void deposit_item(int item_type) { speak_with_history("Nothing to deposit.", true); return; } - int capacity = BASE_STORAGE_MAX - get_storage_count(item_type); + int capacity = get_storage_stack_limit() - get_storage_count(item_type); if (capacity <= 0) { speak_with_history("Storage for that item is full.", true); return; @@ -119,7 +119,7 @@ void deposit_item_max(int item_type) { return; } - int capacity = BASE_STORAGE_MAX - get_storage_count(item_type); + int capacity = get_storage_stack_limit() - get_storage_count(item_type); if (capacity <= 0) { speak_with_history("Storage for that item is full.", true); return; diff --git a/src/save_system.nvgt b/src/save_system.nvgt index a00b7f7..f14d5c1 100644 --- a/src/save_system.nvgt +++ b/src/save_system.nvgt @@ -616,6 +616,7 @@ void reset_game_state() { undead_residents_pending = 0; horses_count = 0; livestock_count = 0; + storage_level = STORAGE_LEVEL_BASE; current_hour = 8; current_day = 1; @@ -668,6 +669,7 @@ void start_new_game() { spawn_trees(5, 19); normalize_tree_positions(); init_barricade(); + ensure_base_storage(); init_time(); init_weather(); if (player_name.length() == 0) { @@ -926,6 +928,7 @@ bool save_game_state() { saveData.set("world_undead_residents_pending", undead_residents_pending); saveData.set("world_horses_count", horses_count); saveData.set("world_livestock_count", livestock_count); + saveData.set("world_storage_level", storage_level); saveData.set("world_expanded_terrain_types", join_string_array(expanded_terrain_types)); string[] treeData; @@ -1484,6 +1487,13 @@ bool load_game_state_from_file(const string&in filename) { for (uint i = 0; i < storagePositions.length(); i++) { add_world_storage(parse_int(storagePositions[i])); } + int loadedStorageLevel = int(get_number(saveData, "world_storage_level", -1)); + if (loadedStorageLevel >= STORAGE_LEVEL_BASE && loadedStorageLevel <= STORAGE_LEVEL_UPGRADE_2) { + storage_level = loadedStorageLevel; + } else { + storage_level = (world_storages.length() > 0) ? STORAGE_LEVEL_UPGRADE_1 : STORAGE_LEVEL_BASE; + } + ensure_base_storage(); string[] pasturePositions = get_string_list_or_split(saveData, "pastures_positions"); for (uint i = 0; i < pasturePositions.length(); i++) { diff --git a/src/world/world_buildings.nvgt b/src/world/world_buildings.nvgt index aad0af1..d12ea0e 100644 --- a/src/world/world_buildings.nvgt +++ b/src/world/world_buildings.nvgt @@ -57,6 +57,7 @@ WorldAltar@[] world_altars; int horses_count = 0; int livestock_count = 0; +int storage_level = STORAGE_LEVEL_BASE; // Add functions void add_world_firepit(int pos) { @@ -74,6 +75,12 @@ void add_world_storage(int pos) { world_storages.insert_last(s); } +void ensure_base_storage() { + if (world_storages.length() == 0) { + add_world_storage(0); + } +} + void add_world_pasture(int pos) { WorldPasture@ p = WorldPasture(pos); world_pastures.insert_last(p);