Invasions should happen even if loading from save.
This commit is contained in:
@@ -37,3 +37,115 @@ void keep_base_fires_fed() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resident defense functions
|
||||||
|
int get_available_defense_weapons() {
|
||||||
|
int count = storage_spears;
|
||||||
|
// Slings only count if stones are available
|
||||||
|
if (storage_slings > 0 && storage_stones > 0) {
|
||||||
|
count += storage_slings;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool can_residents_defend() {
|
||||||
|
if (residents_count <= 0) return false;
|
||||||
|
return get_available_defense_weapons() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool choose_defense_weapon() {
|
||||||
|
// Returns true for spear, false for sling
|
||||||
|
int spearCount = storage_spears;
|
||||||
|
int slingCount = (storage_slings > 0 && storage_stones > 0) ? storage_slings : 0;
|
||||||
|
int total = spearCount + slingCount;
|
||||||
|
|
||||||
|
if (total == 0) return true;
|
||||||
|
if (slingCount == 0) return true;
|
||||||
|
if (spearCount == 0) return false;
|
||||||
|
|
||||||
|
int roll = random(1, total);
|
||||||
|
return roll <= spearCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int perform_resident_defense() {
|
||||||
|
if (!can_residents_defend()) return 0;
|
||||||
|
|
||||||
|
// Choose weapon type randomly weighted by availability
|
||||||
|
bool useSpear = choose_defense_weapon();
|
||||||
|
|
||||||
|
int damage = 0;
|
||||||
|
if (useSpear && storage_spears > 0) {
|
||||||
|
damage = RESIDENT_SPEAR_DAMAGE;
|
||||||
|
play_1d_with_volume_step("sounds/weapons/spear_swing.ogg", x, BASE_END + 1, false, 3.0);
|
||||||
|
} else if (storage_slings > 0 && storage_stones > 0) {
|
||||||
|
damage = random(RESIDENT_SLING_DAMAGE_MIN, RESIDENT_SLING_DAMAGE_MAX);
|
||||||
|
storage_stones--;
|
||||||
|
play_1d_with_volume_step("sounds/weapons/sling_hit.ogg", x, BASE_END + 1, false, 3.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return damage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_daily_weapon_breakage() {
|
||||||
|
if (residents_count <= 0) return;
|
||||||
|
|
||||||
|
int totalWeapons = storage_spears + storage_slings;
|
||||||
|
if (totalWeapons == 0) return;
|
||||||
|
|
||||||
|
// Number of breakage checks = min(residents, weapons)
|
||||||
|
int checksToPerform = (residents_count < totalWeapons) ? residents_count : totalWeapons;
|
||||||
|
|
||||||
|
// Distribute checks among available weapons
|
||||||
|
int spearChecks = 0;
|
||||||
|
int slingChecks = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < checksToPerform; i++) {
|
||||||
|
int remainingSpears = storage_spears - spearChecks;
|
||||||
|
int remainingSlings = storage_slings - slingChecks;
|
||||||
|
int remaining = remainingSpears + remainingSlings;
|
||||||
|
|
||||||
|
if (remaining <= 0) break;
|
||||||
|
|
||||||
|
int roll = random(1, remaining);
|
||||||
|
if (roll <= remainingSpears && remainingSpears > 0) {
|
||||||
|
spearChecks++;
|
||||||
|
} else if (remainingSlings > 0) {
|
||||||
|
slingChecks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform breakage checks
|
||||||
|
int spearsBroken = 0;
|
||||||
|
int slingsBroken = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < spearChecks; i++) {
|
||||||
|
if (random(1, 100) <= RESIDENT_WEAPON_BREAK_CHANCE) {
|
||||||
|
spearsBroken++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < slingChecks; i++) {
|
||||||
|
if (random(1, 100) <= RESIDENT_WEAPON_BREAK_CHANCE) {
|
||||||
|
slingsBroken++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply breakage
|
||||||
|
if (spearsBroken > 0) {
|
||||||
|
storage_spears -= spearsBroken;
|
||||||
|
if (storage_spears < 0) storage_spears = 0;
|
||||||
|
string msg = (spearsBroken == 1)
|
||||||
|
? "A resident's spear broke from wear."
|
||||||
|
: spearsBroken + " spears broke from wear.";
|
||||||
|
notify(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slingsBroken > 0) {
|
||||||
|
storage_slings -= slingsBroken;
|
||||||
|
if (storage_slings < 0) storage_slings = 0;
|
||||||
|
string msg = (slingsBroken == 1)
|
||||||
|
? "A resident's sling broke from wear."
|
||||||
|
: slingsBroken + " slings broke from wear.";
|
||||||
|
notify(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -97,3 +97,9 @@ const double QUEST_FAVOR_PER_POINT = 0.05;
|
|||||||
const int QUEST_STONE_SCORE = 6;
|
const int QUEST_STONE_SCORE = 6;
|
||||||
const int QUEST_LOG_SCORE = 10;
|
const int QUEST_LOG_SCORE = 10;
|
||||||
const int QUEST_SKIN_SCORE = 14;
|
const int QUEST_SKIN_SCORE = 14;
|
||||||
|
|
||||||
|
// Resident defense settings
|
||||||
|
const int RESIDENT_WEAPON_BREAK_CHANCE = 10;
|
||||||
|
const int RESIDENT_SPEAR_DAMAGE = 2;
|
||||||
|
const int RESIDENT_SLING_DAMAGE_MIN = 3;
|
||||||
|
const int RESIDENT_SLING_DAMAGE_MAX = 5;
|
||||||
|
|||||||
@@ -153,12 +153,12 @@ void check_scheduled_invasion() {
|
|||||||
void attempt_daily_invasion() {
|
void attempt_daily_invasion() {
|
||||||
if (current_day < 2) return;
|
if (current_day < 2) return;
|
||||||
if (invasion_triggered_today || invasion_active) return;
|
if (invasion_triggered_today || invasion_active) return;
|
||||||
if (invasion_roll_done_today) return;
|
if (current_hour < 6 || current_hour > 12) return;
|
||||||
invasion_roll_done_today = true;
|
|
||||||
|
|
||||||
int roll = random(1, 100);
|
int roll = random(1, 100);
|
||||||
if (roll > invasion_chance) return;
|
if (roll > invasion_chance) return;
|
||||||
|
|
||||||
|
invasion_triggered_today = true;
|
||||||
schedule_invasion();
|
schedule_invasion();
|
||||||
check_scheduled_invasion();
|
check_scheduled_invasion();
|
||||||
}
|
}
|
||||||
@@ -305,7 +305,6 @@ void update_time() {
|
|||||||
|
|
||||||
check_ambience_transition();
|
check_ambience_transition();
|
||||||
|
|
||||||
// TODO: add resident defense using stored weapons once storage exists.
|
|
||||||
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 (storage_meat > 0) {
|
if (storage_meat > 0) {
|
||||||
int gained = add_barricade_health(residents_count);
|
int gained = add_barricade_health(residents_count);
|
||||||
@@ -317,12 +316,10 @@ void update_time() {
|
|||||||
|
|
||||||
if (current_hour == 6) {
|
if (current_hour == 6) {
|
||||||
save_game_state();
|
save_game_state();
|
||||||
}
|
process_daily_weapon_breakage();
|
||||||
|
|
||||||
if (current_hour == 6) {
|
|
||||||
attempt_daily_invasion();
|
|
||||||
attempt_daily_quest();
|
attempt_daily_quest();
|
||||||
}
|
}
|
||||||
|
attempt_daily_invasion();
|
||||||
keep_base_fires_fed();
|
keep_base_fires_fed();
|
||||||
check_scheduled_invasion();
|
check_scheduled_invasion();
|
||||||
attempt_blessing();
|
attempt_blessing();
|
||||||
|
|||||||
@@ -618,6 +618,17 @@ void try_attack_barricade(Zombie@ zombie) {
|
|||||||
|
|
||||||
play_1d_with_volume_step("sounds/enemies/zombie_hits_player.ogg", x, zombie.position, false, ZOMBIE_SOUND_VOLUME_STEP);
|
play_1d_with_volume_step("sounds/enemies/zombie_hits_player.ogg", x, zombie.position, false, ZOMBIE_SOUND_VOLUME_STEP);
|
||||||
|
|
||||||
|
// Resident defense counter-attack
|
||||||
|
if (can_residents_defend()) {
|
||||||
|
int counterDamage = perform_resident_defense();
|
||||||
|
if (counterDamage > 0) {
|
||||||
|
zombie.health -= counterDamage;
|
||||||
|
if (zombie.health <= 0 && x <= BASE_END) {
|
||||||
|
screen_reader_speak("Residents killed an attacking zombie.", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (barricade_health == 0) {
|
if (barricade_health == 0) {
|
||||||
notify("The barricade has fallen!");
|
notify("The barricade has fallen!");
|
||||||
}
|
}
|
||||||
@@ -859,6 +870,17 @@ void try_attack_barricade_bandit(Bandit@ bandit) {
|
|||||||
p.play_stationary("sounds/weapons/axe_hit.ogg", false);
|
p.play_stationary("sounds/weapons/axe_hit.ogg", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resident defense counter-attack
|
||||||
|
if (can_residents_defend()) {
|
||||||
|
int counterDamage = perform_resident_defense();
|
||||||
|
if (counterDamage > 0) {
|
||||||
|
bandit.health -= counterDamage;
|
||||||
|
if (bandit.health <= 0 && x <= BASE_END) {
|
||||||
|
screen_reader_speak("Residents killed an attacking bandit.", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (barricade_health == 0) {
|
if (barricade_health == 0) {
|
||||||
notify("The barricade has fallen!");
|
notify("The barricade has fallen!");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user