Reed baskets an now be placed in storage for residents to collect fruits and nuts. Should help offset food costs for upkeep.
This commit is contained in:
@@ -1,7 +1,15 @@
|
|||||||
// Base automation helpers
|
// Base automation helpers
|
||||||
int get_food_requirement() {
|
int get_food_requirement() {
|
||||||
if (residents_count <= 0) return 0;
|
if (residents_count <= 0) return 0;
|
||||||
return residents_count; // 1 meat per resident per 8 hours
|
return residents_count; // 1 food per resident per 8 hours
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_total_storage_food() {
|
||||||
|
return get_storage_count(ITEM_MEAT) + get_storage_count(ITEM_SMOKED_FISH) + get_storage_count(ITEM_BASKET_FOOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_any_storage_food() {
|
||||||
|
return get_total_storage_food() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_any_streams() {
|
bool has_any_streams() {
|
||||||
@@ -28,18 +36,28 @@ void consume_food_for_residents() {
|
|||||||
if (needed <= 0) return;
|
if (needed <= 0) return;
|
||||||
int meat_available = get_storage_count(ITEM_MEAT);
|
int meat_available = get_storage_count(ITEM_MEAT);
|
||||||
int smoked_fish_available = get_storage_count(ITEM_SMOKED_FISH);
|
int smoked_fish_available = get_storage_count(ITEM_SMOKED_FISH);
|
||||||
int total_food = meat_available + smoked_fish_available;
|
int basket_food_available = get_storage_count(ITEM_BASKET_FOOD);
|
||||||
|
int total_food = meat_available + smoked_fish_available + basket_food_available;
|
||||||
|
|
||||||
if (total_food >= needed) {
|
if (total_food >= needed) {
|
||||||
|
// Priority: meat -> smoked fish -> basket food
|
||||||
int from_meat = (meat_available >= needed) ? needed : meat_available;
|
int from_meat = (meat_available >= needed) ? needed : meat_available;
|
||||||
add_storage_count(ITEM_MEAT, -from_meat);
|
add_storage_count(ITEM_MEAT, -from_meat);
|
||||||
int remaining = needed - from_meat;
|
int remaining = needed - from_meat;
|
||||||
|
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
add_storage_count(ITEM_SMOKED_FISH, -remaining);
|
int from_fish = (smoked_fish_available >= remaining) ? remaining : smoked_fish_available;
|
||||||
|
add_storage_count(ITEM_SMOKED_FISH, -from_fish);
|
||||||
|
remaining -= from_fish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remaining > 0) {
|
||||||
|
add_storage_count(ITEM_BASKET_FOOD, -remaining);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
set_storage_count(ITEM_MEAT, 0);
|
set_storage_count(ITEM_MEAT, 0);
|
||||||
set_storage_count(ITEM_SMOKED_FISH, 0);
|
set_storage_count(ITEM_SMOKED_FISH, 0);
|
||||||
|
set_storage_count(ITEM_BASKET_FOOD, 0);
|
||||||
if (x <= BASE_END) {
|
if (x <= BASE_END) {
|
||||||
notify("No food, residents are hungry.");
|
notify("No food, residents are hungry.");
|
||||||
}
|
}
|
||||||
@@ -116,8 +134,7 @@ void attempt_resident_fish_smoking() {
|
|||||||
|
|
||||||
void keep_base_fires_fed() {
|
void keep_base_fires_fed() {
|
||||||
if (residents_count <= 0) return;
|
if (residents_count <= 0) return;
|
||||||
int total_food = get_storage_count(ITEM_MEAT) + get_storage_count(ITEM_SMOKED_FISH);
|
if (!has_any_storage_food()) return;
|
||||||
if (total_food <= 0) return;
|
|
||||||
if (get_storage_count(ITEM_STICKS) <= 0 && get_storage_count(ITEM_LOGS) <= 0) return;
|
if (get_storage_count(ITEM_STICKS) <= 0 && get_storage_count(ITEM_LOGS) <= 0) return;
|
||||||
|
|
||||||
for (uint i = 0; i < world_fires.length(); i++) {
|
for (uint i = 0; i < world_fires.length(); i++) {
|
||||||
@@ -318,7 +335,7 @@ void attempt_resident_snare_retrieval() {
|
|||||||
if (residents_count <= 0) return;
|
if (residents_count <= 0) return;
|
||||||
|
|
||||||
// Need food in storage (same limitation as other resident tasks)
|
// Need food in storage (same limitation as other resident tasks)
|
||||||
if (get_storage_count(ITEM_MEAT) <= 0) return;
|
if (!has_any_storage_food()) return;
|
||||||
|
|
||||||
// Check each snare that has a catch
|
// Check each snare that has a catch
|
||||||
for (int i = int(world_snares.length()) - 1; i >= 0; i--) {
|
for (int i = int(world_snares.length()) - 1; i >= 0; i--) {
|
||||||
@@ -368,7 +385,7 @@ void attempt_resident_butchering() {
|
|||||||
if (residents_count <= 0) return;
|
if (residents_count <= 0) return;
|
||||||
|
|
||||||
// Need food in storage (same limitation as other resident tasks)
|
// Need food in storage (same limitation as other resident tasks)
|
||||||
if (get_storage_count(ITEM_MEAT) <= 0) return;
|
if (!has_any_storage_food()) return;
|
||||||
|
|
||||||
// Need game in storage
|
// Need game in storage
|
||||||
if (get_storage_count(ITEM_SMALL_GAME) <= 0 && get_storage_count(ITEM_BOAR_CARCASSES) <= 0) return;
|
if (get_storage_count(ITEM_SMALL_GAME) <= 0 && get_storage_count(ITEM_BOAR_CARCASSES) <= 0) return;
|
||||||
@@ -539,3 +556,63 @@ void attempt_resident_collection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resident foraging - produces baskets of fruits and nuts from reed baskets
|
||||||
|
void attempt_resident_foraging() {
|
||||||
|
// Only during daytime
|
||||||
|
if (!is_daytime) return;
|
||||||
|
|
||||||
|
// Need residents
|
||||||
|
if (residents_count <= 0) return;
|
||||||
|
|
||||||
|
// Need reed baskets in storage
|
||||||
|
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;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
int baskets_produced = 0;
|
||||||
|
int baskets_broken = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < active_foragers; i++) {
|
||||||
|
// Check for basket breakage during foraging
|
||||||
|
if (random(1, 100) <= RESIDENT_TOOL_BREAK_CHANCE) {
|
||||||
|
baskets_broken++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if foraging succeeds
|
||||||
|
if (random(1, 100) > RESIDENT_FORAGING_CHANCE) continue;
|
||||||
|
|
||||||
|
// Check storage capacity
|
||||||
|
if (get_storage_count(ITEM_BASKET_FOOD) >= BASE_STORAGE_MAX) break;
|
||||||
|
|
||||||
|
// Consume a reed basket and produce a basket of fruits and nuts
|
||||||
|
add_storage_count(ITEM_REED_BASKETS, -1);
|
||||||
|
add_storage_count(ITEM_BASKET_FOOD, 1);
|
||||||
|
baskets_produced++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply basket breakage (from failed foraging attempts)
|
||||||
|
if (baskets_broken > 0) {
|
||||||
|
add_storage_count(ITEM_REED_BASKETS, -baskets_broken);
|
||||||
|
if (x <= BASE_END) {
|
||||||
|
string msg = (baskets_broken == 1)
|
||||||
|
? "A resident's basket broke while foraging."
|
||||||
|
: baskets_broken + " baskets broke while foraging.";
|
||||||
|
speak_with_history(msg, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify of production
|
||||||
|
if (baskets_produced > 0 && x <= BASE_END) {
|
||||||
|
if (baskets_produced == 1) {
|
||||||
|
speak_with_history("Resident gathered a basket of fruits and nuts.", true);
|
||||||
|
} else {
|
||||||
|
speak_with_history("Residents gathered " + baskets_produced + " baskets of fruits and nuts.", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -242,6 +242,7 @@ const int FALL_DAMAGE_MAX = 4;
|
|||||||
// Base Automation
|
// Base Automation
|
||||||
const int RESIDENT_SLING_COOLDOWN = 4000; // 4 seconds between shots
|
const int RESIDENT_SLING_COOLDOWN = 4000; // 4 seconds between shots
|
||||||
const int RESIDENT_COLLECTION_CHANCE = 10; // 10% chance per basket per hour
|
const int RESIDENT_COLLECTION_CHANCE = 10; // 10% chance per basket per hour
|
||||||
|
const int RESIDENT_FORAGING_CHANCE = 50; // 50% chance per resident per attempt (twice daily)
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
int abs(int value) {
|
int abs(int value) {
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ const int ITEM_CANOES = 34;
|
|||||||
const int ITEM_FISH = 35;
|
const int ITEM_FISH = 35;
|
||||||
const int ITEM_SMOKED_FISH = 36;
|
const int ITEM_SMOKED_FISH = 36;
|
||||||
const int ITEM_HEAL_SCROLL = 37;
|
const int ITEM_HEAL_SCROLL = 37;
|
||||||
const int ITEM_COUNT = 38; // Total number of item types
|
const int ITEM_BASKET_FOOD = 38;
|
||||||
|
const int ITEM_COUNT = 39; // Total number of item types
|
||||||
|
|
||||||
// Item definition class
|
// Item definition class
|
||||||
class ItemDefinition {
|
class ItemDefinition {
|
||||||
@@ -126,6 +127,7 @@ void init_item_registry() {
|
|||||||
item_registry[ITEM_FISH] = ItemDefinition(ITEM_FISH, "fish", "fish", "Fish", 0.10);
|
item_registry[ITEM_FISH] = ItemDefinition(ITEM_FISH, "fish", "fish", "Fish", 0.10);
|
||||||
item_registry[ITEM_SMOKED_FISH] = ItemDefinition(ITEM_SMOKED_FISH, "smoked fish", "smoked fish", "Smoked Fish", 0.20);
|
item_registry[ITEM_SMOKED_FISH] = ItemDefinition(ITEM_SMOKED_FISH, "smoked fish", "smoked fish", "Smoked Fish", 0.20);
|
||||||
item_registry[ITEM_HEAL_SCROLL] = ItemDefinition(ITEM_HEAL_SCROLL, "heal scrolls", "heal scroll", "Heal Scrolls", 0.50);
|
item_registry[ITEM_HEAL_SCROLL] = ItemDefinition(ITEM_HEAL_SCROLL, "heal scrolls", "heal scroll", "Heal Scrolls", 0.50);
|
||||||
|
item_registry[ITEM_BASKET_FOOD] = ItemDefinition(ITEM_BASKET_FOOD, "baskets of fruits and nuts", "basket of fruits and nuts", "Baskets of Fruits and Nuts", 0.15);
|
||||||
|
|
||||||
// Define display order for inventory menus
|
// Define display order for inventory menus
|
||||||
// This controls the order items appear in menus
|
// This controls the order items appear in menus
|
||||||
@@ -148,6 +150,7 @@ void init_item_registry() {
|
|||||||
// Food items
|
// Food items
|
||||||
ITEM_FISH,
|
ITEM_FISH,
|
||||||
ITEM_SMOKED_FISH,
|
ITEM_SMOKED_FISH,
|
||||||
|
ITEM_BASKET_FOOD,
|
||||||
// Misc items
|
// Misc items
|
||||||
ITEM_INCENSE,
|
ITEM_INCENSE,
|
||||||
ITEM_HEAL_SCROLL,
|
ITEM_HEAL_SCROLL,
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ void run_base_info_menu() {
|
|||||||
int daily_food = residents_count * 3; // 1 per resident per 8 hours = 3 per day
|
int daily_food = residents_count * 3; // 1 per resident per 8 hours = 3 per day
|
||||||
int meat_in_storage = get_storage_count(ITEM_MEAT);
|
int meat_in_storage = get_storage_count(ITEM_MEAT);
|
||||||
int smoked_fish_in_storage = get_storage_count(ITEM_SMOKED_FISH);
|
int smoked_fish_in_storage = get_storage_count(ITEM_SMOKED_FISH);
|
||||||
int total_food = meat_in_storage + smoked_fish_in_storage;
|
int basket_food_in_storage = get_storage_count(ITEM_BASKET_FOOD);
|
||||||
options.insert_last("Food in storage " + meat_in_storage + " meat, " + smoked_fish_in_storage + " smoked fish. Total " + total_food + ". Daily use " + daily_food);
|
int total_food = meat_in_storage + smoked_fish_in_storage + basket_food_in_storage;
|
||||||
|
options.insert_last("Food in storage " + meat_in_storage + " meat, " + smoked_fish_in_storage + " smoked fish, " + basket_food_in_storage + " baskets of fruits and nuts. Total " + total_food + ". Daily use " + daily_food);
|
||||||
} else {
|
} else {
|
||||||
options.insert_last("Storage not built");
|
options.insert_last("Storage not built");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ void update_time() {
|
|||||||
check_ambience_transition();
|
check_ambience_transition();
|
||||||
|
|
||||||
if (is_daytime && residents_count > 0 && barricade_health < BARRICADE_MAX_HEALTH && current_hour % 4 == 0) {
|
if (is_daytime && residents_count > 0 && barricade_health < BARRICADE_MAX_HEALTH && current_hour % 4 == 0) {
|
||||||
if (get_storage_count(ITEM_MEAT) > 0) {
|
if (has_any_storage_food()) {
|
||||||
int gained = add_barricade_health(residents_count);
|
int gained = add_barricade_health(residents_count);
|
||||||
if (gained > 0 && x <= BASE_END) {
|
if (gained > 0 && x <= BASE_END) {
|
||||||
speak_with_history("Residents repaired the barricade. +" + gained + " health.", true);
|
speak_with_history("Residents repaired the barricade. +" + gained + " health.", true);
|
||||||
@@ -412,6 +412,10 @@ void update_time() {
|
|||||||
process_daily_weapon_breakage();
|
process_daily_weapon_breakage();
|
||||||
attempt_daily_quest();
|
attempt_daily_quest();
|
||||||
attempt_resident_butchering();
|
attempt_resident_butchering();
|
||||||
|
attempt_resident_foraging();
|
||||||
|
}
|
||||||
|
if (current_hour == 12) {
|
||||||
|
attempt_resident_foraging();
|
||||||
}
|
}
|
||||||
attempt_daily_invasion();
|
attempt_daily_invasion();
|
||||||
keep_base_fires_fed();
|
keep_base_fires_fed();
|
||||||
|
|||||||
Reference in New Issue
Block a user