New flying game turkey added. Zombie swarms added. Enemies from areas can now be encountered in those areas they do not leave the area unless invading.

This commit is contained in:
Storm Dragon
2026-02-06 18:51:36 -05:00
parent 1220cfefe2
commit 8cd2e1d5a9
10 changed files with 546 additions and 57 deletions

View File

@@ -44,6 +44,8 @@ class Bandit {
timer move_timer;
timer attack_timer;
int move_interval;
int home_start;
int home_end;
// Wandering behavior properties
string behavior_state; // "aggressive" or "wandering"
@@ -52,11 +54,25 @@ class Bandit {
int wander_direction_change_interval;
Bandit(int pos, int expansion_start, int expansion_end, string invader = "bandit") {
int range_start = expansion_start;
int range_end = expansion_end;
if (range_start > range_end) {
int temp = range_start;
range_start = range_end;
range_end = temp;
}
// Spawn somewhere in the expanded area
position = random(expansion_start, expansion_end);
if (pos < range_start || pos > range_end) {
position = random(range_start, range_end);
} else {
position = pos;
}
health = BANDIT_HEALTH;
sound_handle = -1;
invader_type = invader;
home_start = range_start;
home_end = range_end;
// Choose random alert sound
alert_sound = pick_invader_alert_sound(invader_type);
@@ -114,20 +130,68 @@ Bandit@ get_bandit_at(int pos) {
return null;
}
void spawn_bandit(int expansion_start, int expansion_end, const string&in invader_type = "bandit") {
int spawn_x = -1;
for (int attempts = 0; attempts < 20; attempts++) {
int candidate = random(expansion_start, expansion_end);
if (get_bandit_at(candidate) == null) {
spawn_x = candidate;
break;
}
}
if (spawn_x == -1) {
spawn_x = random(expansion_start, expansion_end);
int pick_bandit_spawn_position(int range_start, int range_end) {
int start = range_start;
int end = range_end;
if (start > end) {
int temp = start;
start = end;
end = temp;
}
Bandit@ b = Bandit(spawn_x, expansion_start, expansion_end, invader_type);
for (int attempts = 0; attempts < 20; attempts++) {
int candidate = random(start, end);
if (candidate == x) continue;
if (get_bandit_at(candidate) != null) continue;
return candidate;
}
for (int candidate = start; candidate <= end; candidate++) {
if (candidate == x) continue;
if (get_bandit_at(candidate) != null) continue;
return candidate;
}
return -1;
}
int count_bandits_in_range(int range_start, int range_end) {
int start = range_start;
int end = range_end;
if (start > end) {
int temp = start;
start = end;
end = temp;
}
int count = 0;
for (uint i = 0; i < bandits.length(); i++) {
if (bandits[i].position >= start && bandits[i].position <= end) {
count++;
}
}
return count;
}
void spawn_bandit(int expansion_start, int expansion_end, const string&in invader_type = "bandit") {
int spawn_x = pick_bandit_spawn_position(expansion_start, expansion_end);
if (spawn_x == -1) return;
int home_start = expansion_start;
int home_end = expansion_end;
if (expanded_area_start != -1 && spawn_x >= expanded_area_start) {
int area_start = -1;
int area_end = -1;
if (get_audio_area_bounds_for_position(spawn_x, area_start, area_end)) {
home_start = area_start;
home_end = area_end;
}
}
Bandit@ b = Bandit(spawn_x, home_start, home_end, invader_type);
if (!invasion_active) {
b.behavior_state = "wandering";
}
bandits.insert_last(b);
// Play looping sound that follows the bandit
int[] areaStarts;
@@ -226,6 +290,15 @@ void try_attack_barricade_bandit(Bandit@ bandit) {
}
void update_bandit(Bandit@ bandit, bool audio_active) {
bool enforce_home = (!invasion_active && bandit.home_start <= bandit.home_end);
if (enforce_home) {
if (bandit.position < bandit.home_start) {
bandit.position = bandit.home_start;
} else if (bandit.position > bandit.home_end) {
bandit.position = bandit.home_end;
}
}
// Update looping sound position
if (!audio_active) {
if (bandit.sound_handle != -1) {
@@ -277,6 +350,10 @@ void update_bandit(Bandit@ bandit, bool audio_active) {
// Check bounds
if (target_x >= 0 && target_x < MAP_SIZE) {
if (enforce_home && (target_x < bandit.home_start || target_x > bandit.home_end)) {
bandit.wander_direction = -bandit.wander_direction;
return;
}
// Don't wander into base if barricade is up
if (target_x <= BASE_END && barricade_health > 0) {
// Change direction instead
@@ -321,6 +398,10 @@ void update_bandit(Bandit@ bandit, bool audio_active) {
int target_x = bandit.position + direction;
if (target_x < 0 || target_x >= MAP_SIZE) return;
if (enforce_home && (target_x < bandit.home_start || target_x > bandit.home_end)) {
return;
}
// Don't enter base if barricade is up
if (target_x <= BASE_END && barricade_health > 0) {
try_attack_barricade_bandit(bandit);