Residents now consume items other than food for clothing repairs etc.

This commit is contained in:
Storm Dragon
2026-02-06 14:51:01 -05:00
parent 5834793376
commit 1220cfefe2
5 changed files with 134 additions and 27 deletions

View File

@@ -561,6 +561,83 @@ void process_daily_weapon_breakage() {
}
}
void attempt_resident_clothing_repairs() {
if (residents_count <= 0) return;
int threshold = BASE_STORAGE_MAX / 2;
if (threshold < RESIDENT_CLOTHING_REPAIR_COST) {
threshold = RESIDENT_CLOTHING_REPAIR_COST;
}
int vines_used = 0;
int skins_used = 0;
int down_used = 0;
int repairs_done = 0;
for (int i = 0; i < residents_count; i++) {
int best_item = -1;
int best_count = -1;
int vines_count = get_storage_count(ITEM_VINES);
if (vines_count >= RESIDENT_CLOTHING_REPAIR_COST && vines_count > threshold && vines_count > best_count) {
best_item = ITEM_VINES;
best_count = vines_count;
}
int skins_count = get_storage_count(ITEM_SKINS);
if (skins_count >= RESIDENT_CLOTHING_REPAIR_COST && skins_count > threshold && skins_count > best_count) {
best_item = ITEM_SKINS;
best_count = skins_count;
}
int down_count = get_storage_count(ITEM_DOWN);
if (down_count >= RESIDENT_CLOTHING_REPAIR_COST && down_count > threshold && down_count > best_count) {
best_item = ITEM_DOWN;
best_count = down_count;
}
if (best_item == -1) break;
add_storage_count(best_item, -RESIDENT_CLOTHING_REPAIR_COST);
repairs_done++;
if (best_item == ITEM_VINES) {
vines_used += RESIDENT_CLOTHING_REPAIR_COST;
} else if (best_item == ITEM_SKINS) {
skins_used += RESIDENT_CLOTHING_REPAIR_COST;
} else if (best_item == ITEM_DOWN) {
down_used += RESIDENT_CLOTHING_REPAIR_COST;
}
}
if (repairs_done > 0 && x <= BASE_END) {
string msg = (repairs_done == 1)
? "A resident is mending clothing."
: "Residents are mending clothing.";
string[] materials;
if (vines_used > 0) materials.insert_last(vines_used + " vines");
if (skins_used > 0) materials.insert_last(skins_used + " skins");
if (down_used > 0) materials.insert_last(down_used + " down");
if (materials.length() > 0) {
msg += " Used ";
for (uint i = 0; i < materials.length(); i++) {
if (i > 0) {
if (i == materials.length() - 1) {
msg += " and ";
} else {
msg += ", ";
}
}
msg += materials[i];
}
msg += ".";
}
speak_with_history(msg, true);
}
}
// Resident snare retrieval
void attempt_resident_snare_retrieval() {
// Only during daytime

View File

@@ -74,6 +74,7 @@ const int WIGHT_DAMAGE_MIN = 6;
const int WIGHT_DAMAGE_MAX = 8;
const int WIGHT_SPAWN_CHANCE_START = 5;
const int WIGHT_SPAWN_CHANCE_STEP = 5;
const int SPECIAL_UNDEAD_SPAWN_DAYS_PER_EXTRA = 9;
// Vampyr settings (undead abductor)
const int VAMPYR_HEALTH = 40;
@@ -214,6 +215,7 @@ const int RESIDENT_SNARE_CHECK_CHANCE = 15; // 15% chance per hour to check sna
const int RESIDENT_FISHING_CHANCE = 6; // 6% chance per resident per hour to catch a fish
const int RESIDENT_SMOKE_FISH_CHANCE = 10; // 10% chance per hour to smoke a stored fish
const int RESIDENT_TOOL_BREAK_CHANCE = 2; // 2% chance tools break during resident use (fishing poles, knives, baskets)
const int RESIDENT_CLOTHING_REPAIR_COST = 5;
const float PLAYER_ITEM_BREAK_CHANCE_MIN = 1.0;
const float PLAYER_ITEM_BREAK_CHANCE_MAX = 100.0;
const float PLAYER_ITEM_BREAK_CHANCE_INCREMENT = 0.1;

View File

@@ -12,9 +12,9 @@ string[] undead_vampyr_sounds = {
string[] undead_resident_sounds = {"sounds/enemies/undead_resident1.ogg"};
int wight_spawn_chance = WIGHT_SPAWN_CHANCE_START;
bool wight_spawned_this_night = false;
int wight_spawned_this_night_count = 0;
int vampyr_spawn_chance = VAMPYR_SPAWN_CHANCE_START;
bool vampyr_spawned_this_night = false;
int vampyr_spawned_this_night_count = 0;
int get_undead_base_health(const string &in undead_type) {
if (undead_type == "wight") return WIGHT_HEALTH;
@@ -90,22 +90,37 @@ class Undead {
}
Undead@[] undeads;
bool has_wight() {
int count_wights() {
int count = 0;
for (uint i = 0; i < undeads.length(); i++) {
if (undeads[i].undead_type == "wight") {
return true;
count++;
}
}
return false;
return count;
}
bool has_wight() {
return count_wights() > 0;
}
int count_vampyrs() {
int count = 0;
for (uint i = 0; i < undeads.length(); i++) {
if (undeads[i].undead_type == "vampyr") {
count++;
}
}
return count;
}
bool has_vampyr() {
for (uint i = 0; i < undeads.length(); i++) {
if (undeads[i].undead_type == "vampyr") {
return true;
}
}
return false;
return count_vampyrs() > 0;
}
int get_night_special_undead_spawn_limit(int day) {
if (day < 1) day = 1;
return 1 + (day / SPECIAL_UNDEAD_SPAWN_DAYS_PER_EXTRA);
}
void update_undead_weapon_range_audio() {
@@ -414,7 +429,7 @@ void update_undeads() {
void attempt_hourly_wight_spawn() {
if (current_hour == 19) {
wight_spawned_this_night = false;
wight_spawned_this_night_count = 0;
}
if (is_daytime) {
@@ -425,19 +440,20 @@ void attempt_hourly_wight_spawn() {
return;
}
if (wight_spawned_this_night) {
return;
int wight_count = count_wights();
if (wight_spawned_this_night_count < wight_count) {
wight_spawned_this_night_count = wight_count;
}
if (has_wight()) {
wight_spawned_this_night = true;
int spawn_limit = get_night_special_undead_spawn_limit(current_day);
if (wight_spawned_this_night_count >= spawn_limit) {
return;
}
int roll = random(1, 100);
if (roll <= wight_spawn_chance) {
spawn_undead("wight");
wight_spawned_this_night = true;
wight_spawned_this_night_count++;
wight_spawn_chance = WIGHT_SPAWN_CHANCE_START;
return;
}
@@ -448,7 +464,7 @@ void attempt_hourly_wight_spawn() {
void attempt_hourly_vampyr_spawn() {
if (current_hour == 19) {
vampyr_spawned_this_night = false;
vampyr_spawned_this_night_count = 0;
}
if (is_daytime) {
@@ -463,19 +479,20 @@ void attempt_hourly_vampyr_spawn() {
return;
}
if (vampyr_spawned_this_night) {
return;
int vampyr_count = count_vampyrs();
if (vampyr_spawned_this_night_count < vampyr_count) {
vampyr_spawned_this_night_count = vampyr_count;
}
if (has_vampyr()) {
vampyr_spawned_this_night = true;
int spawn_limit = get_night_special_undead_spawn_limit(current_day);
if (vampyr_spawned_this_night_count >= spawn_limit) {
return;
}
int roll = random(1, 100);
if (roll <= vampyr_spawn_chance) {
spawn_undead("vampyr");
vampyr_spawned_this_night = true;
vampyr_spawned_this_night_count++;
vampyr_spawn_chance = VAMPYR_SPAWN_CHANCE_START;
return;
}

View File

@@ -885,9 +885,9 @@ bool save_game_state() {
saveData.set("player_item_break_pending_type", playerItemBreakPendingType);
saveData.set("quest_roll_done_today", quest_roll_done_today);
saveData.set("wight_spawn_chance", wight_spawn_chance);
saveData.set("wight_spawned_this_night", wight_spawned_this_night);
saveData.set("wight_spawned_this_night", wight_spawned_this_night_count);
saveData.set("vampyr_spawn_chance", vampyr_spawn_chance);
saveData.set("vampyr_spawned_this_night", vampyr_spawned_this_night);
saveData.set("vampyr_spawned_this_night", vampyr_spawned_this_night_count);
string[] questData;
for (uint i = 0; i < quest_queue.length(); i++) {
questData.insert_last("" + quest_queue[i]);
@@ -1337,11 +1337,21 @@ bool load_game_state_from_file(const string&in filename) {
reset_player_item_break_audio_state();
quest_roll_done_today = get_bool(saveData, "quest_roll_done_today", false);
wight_spawn_chance = int(get_number(saveData, "wight_spawn_chance", WIGHT_SPAWN_CHANCE_START));
wight_spawned_this_night = get_bool(saveData, "wight_spawned_this_night", false);
if (has_number_key(saveData, "wight_spawned_this_night")) {
wight_spawned_this_night_count = int(get_number(saveData, "wight_spawned_this_night", 0));
} else {
wight_spawned_this_night_count = get_bool(saveData, "wight_spawned_this_night", false) ? 1 : 0;
}
if (wight_spawned_this_night_count < 0) wight_spawned_this_night_count = 0;
if (wight_spawn_chance < WIGHT_SPAWN_CHANCE_START) wight_spawn_chance = WIGHT_SPAWN_CHANCE_START;
if (wight_spawn_chance > 100) wight_spawn_chance = 100;
vampyr_spawn_chance = int(get_number(saveData, "vampyr_spawn_chance", VAMPYR_SPAWN_CHANCE_START));
vampyr_spawned_this_night = get_bool(saveData, "vampyr_spawned_this_night", false);
if (has_number_key(saveData, "vampyr_spawned_this_night")) {
vampyr_spawned_this_night_count = int(get_number(saveData, "vampyr_spawned_this_night", 0));
} else {
vampyr_spawned_this_night_count = get_bool(saveData, "vampyr_spawned_this_night", false) ? 1 : 0;
}
if (vampyr_spawned_this_night_count < 0) vampyr_spawned_this_night_count = 0;
if (vampyr_spawn_chance < VAMPYR_SPAWN_CHANCE_START) vampyr_spawn_chance = VAMPYR_SPAWN_CHANCE_START;
if (vampyr_spawn_chance > 100) vampyr_spawn_chance = 100;

View File

@@ -623,6 +623,7 @@ void update_time() {
process_daily_weapon_breakage();
attempt_daily_quest();
attempt_resident_butchering();
attempt_resident_clothing_repairs();
}
if (should_attempt_resident_foraging(current_hour)) {
attempt_resident_foraging();