More refactor, start splitting large unwieldy files into easier to manage components.
This commit is contained in:
@@ -6,6 +6,10 @@ sound_pool p(100);
|
|||||||
|
|
||||||
#include "src/constants.nvgt"
|
#include "src/constants.nvgt"
|
||||||
#include "src/player.nvgt"
|
#include "src/player.nvgt"
|
||||||
|
#include "src/creature_base.nvgt"
|
||||||
|
#include "src/creature_death.nvgt"
|
||||||
|
#include "src/world_object_base.nvgt"
|
||||||
|
#include "src/enemies/undead.nvgt"
|
||||||
#include "src/world_state.nvgt"
|
#include "src/world_state.nvgt"
|
||||||
#include "src/ui.nvgt"
|
#include "src/ui.nvgt"
|
||||||
#include "src/inventory.nvgt"
|
#include "src/inventory.nvgt"
|
||||||
|
|||||||
+3
-3
@@ -166,9 +166,9 @@ void release_sling_attack(int player_x) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then check for zombie
|
// Then check for undead
|
||||||
Zombie@ zombie = get_zombie_at(check_x);
|
Undead@ undead = get_zombie_at(check_x);
|
||||||
if (zombie != null) {
|
if (undead != null) {
|
||||||
target_x = check_x;
|
target_x = check_x;
|
||||||
hit_bandit = false;
|
hit_bandit = false;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// Base class for ground creatures (enemies and game animals)
|
||||||
|
// Provides common fields and methods for creatures that move on the ground
|
||||||
|
|
||||||
|
class CreatureBase {
|
||||||
|
int position;
|
||||||
|
int health;
|
||||||
|
int sound_handle = -1;
|
||||||
|
timer move_timer;
|
||||||
|
timer attack_timer;
|
||||||
|
|
||||||
|
// Common sound cleanup method
|
||||||
|
void destroy_sound() {
|
||||||
|
if (sound_handle != -1) {
|
||||||
|
p.destroy_sound(sound_handle);
|
||||||
|
sound_handle = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Unified death handling functions for creatures
|
||||||
|
// Ensures consistent death behavior: stop sound -> play death sound -> create drop
|
||||||
|
|
||||||
|
// Handle creature death with sound cleanup and optional drop
|
||||||
|
// This consolidates the death pattern used across zombies, bandits, boars, etc.
|
||||||
|
void handle_creature_death(int creature_pos, string death_sound, float volume_step, string drop_type = "") {
|
||||||
|
// Play death sound at creature position
|
||||||
|
play_creature_death_sound(death_sound, x, creature_pos, volume_step);
|
||||||
|
|
||||||
|
// Create world drop if specified
|
||||||
|
if (drop_type != "") {
|
||||||
|
add_world_drop(creature_pos, drop_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup sound handle before death (should be called before handle_creature_death)
|
||||||
|
void cleanup_creature_sound(int sound_handle_ref) {
|
||||||
|
if (sound_handle_ref != -1) {
|
||||||
|
p.destroy_sound(sound_handle_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
// Undead creatures (zombies, vampires, ghosts, etc.)
|
||||||
|
// Currently only zombies are implemented
|
||||||
|
|
||||||
|
string[] undead_zombie_sounds = {"sounds/enemies/zombie1.ogg"};
|
||||||
|
|
||||||
|
class Undead {
|
||||||
|
int position;
|
||||||
|
int health;
|
||||||
|
string undead_type; // "zombie", future: "vampire", "ghost", etc.
|
||||||
|
string voice_sound;
|
||||||
|
int sound_handle;
|
||||||
|
timer move_timer;
|
||||||
|
timer groan_timer;
|
||||||
|
timer attack_timer;
|
||||||
|
int next_groan_delay;
|
||||||
|
|
||||||
|
Undead(int pos, string type = "zombie") {
|
||||||
|
position = pos;
|
||||||
|
undead_type = type;
|
||||||
|
health = ZOMBIE_HEALTH;
|
||||||
|
int sound_index = random(0, undead_zombie_sounds.length() - 1);
|
||||||
|
voice_sound = undead_zombie_sounds[sound_index];
|
||||||
|
sound_handle = -1;
|
||||||
|
move_timer.restart();
|
||||||
|
groan_timer.restart();
|
||||||
|
attack_timer.restart();
|
||||||
|
next_groan_delay = random(ZOMBIE_GROAN_MIN_DELAY, ZOMBIE_GROAN_MAX_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Undead@[] undeads;
|
||||||
|
|
||||||
|
void clear_undeads() {
|
||||||
|
if (undeads.length() == 0) return;
|
||||||
|
|
||||||
|
for (uint i = 0; i < undeads.length(); i++) {
|
||||||
|
if (undeads[i].sound_handle != -1) {
|
||||||
|
p.destroy_sound(undeads[i].sound_handle);
|
||||||
|
undeads[i].sound_handle = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
undeads.resize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Undead@ get_undead_at(int pos) {
|
||||||
|
for (uint i = 0; i < undeads.length(); i++) {
|
||||||
|
if (undeads[i].position == pos) {
|
||||||
|
return @undeads[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spawn_undead() {
|
||||||
|
int spawn_x = -1;
|
||||||
|
for (int attempts = 0; attempts < 20; attempts++) {
|
||||||
|
int candidate = random(BASE_END + 1, MAP_SIZE - 1);
|
||||||
|
if (get_undead_at(candidate) == null) {
|
||||||
|
spawn_x = candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (spawn_x == -1) {
|
||||||
|
spawn_x = random(BASE_END + 1, MAP_SIZE - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Undead@ z = Undead(spawn_x, "zombie");
|
||||||
|
undeads.insert_last(z);
|
||||||
|
z.sound_handle = play_creature_voice(z.voice_sound, x, spawn_x, ZOMBIE_SOUND_VOLUME_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void try_attack_barricade_undead(Undead@ undead) {
|
||||||
|
if (barricade_health <= 0) return;
|
||||||
|
if (undead.attack_timer.elapsed < ZOMBIE_ATTACK_INTERVAL) return;
|
||||||
|
|
||||||
|
undead.attack_timer.restart();
|
||||||
|
int damage = random(ZOMBIE_DAMAGE_MIN, ZOMBIE_DAMAGE_MAX);
|
||||||
|
barricade_health -= damage;
|
||||||
|
if (barricade_health < 0) barricade_health = 0;
|
||||||
|
|
||||||
|
play_creature_attack_sound("sounds/enemies/zombie_hits_player.ogg", x, undead.position, ZOMBIE_SOUND_VOLUME_STEP);
|
||||||
|
|
||||||
|
// Resident defense counter-attack
|
||||||
|
if (can_residents_defend()) {
|
||||||
|
int counterDamage = perform_resident_defense();
|
||||||
|
if (counterDamage > 0) {
|
||||||
|
undead.health -= counterDamage;
|
||||||
|
if (undead.health <= 0 && x <= BASE_END) {
|
||||||
|
speak_with_history("Residents killed an attacking zombie.", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (barricade_health == 0) {
|
||||||
|
notify("The barricade has fallen!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool can_undead_attack_player(Undead@ undead) {
|
||||||
|
if (player_health <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (barricade_health > 0 && x <= BASE_END) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(undead.position - x) > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return y <= ZOMBIE_ATTACK_MAX_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool try_attack_player_undead(Undead@ undead) {
|
||||||
|
if (!can_undead_attack_player(undead)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (undead.attack_timer.elapsed < ZOMBIE_ATTACK_INTERVAL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
undead.attack_timer.restart();
|
||||||
|
int damage = random(ZOMBIE_DAMAGE_MIN, ZOMBIE_DAMAGE_MAX);
|
||||||
|
player_health -= damage;
|
||||||
|
if (player_health < 0) {
|
||||||
|
player_health = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
play_creature_attack_sound("sounds/enemies/zombie_hits_player.ogg", x, undead.position, ZOMBIE_SOUND_VOLUME_STEP);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_undead(Undead@ undead) {
|
||||||
|
if (undead.groan_timer.elapsed > undead.next_groan_delay) {
|
||||||
|
undead.groan_timer.restart();
|
||||||
|
undead.next_groan_delay = random(ZOMBIE_GROAN_MIN_DELAY, ZOMBIE_GROAN_MAX_DELAY);
|
||||||
|
undead.sound_handle = play_creature_voice(undead.voice_sound, x, undead.position, ZOMBIE_SOUND_VOLUME_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (try_attack_player_undead(undead)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (undead.move_timer.elapsed < ZOMBIE_MOVE_INTERVAL) return;
|
||||||
|
undead.move_timer.restart();
|
||||||
|
|
||||||
|
if (barricade_health > 0 && undead.position == BASE_END + 1) {
|
||||||
|
try_attack_barricade_undead(undead);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int direction = 0;
|
||||||
|
if (x > BASE_END) {
|
||||||
|
if (x > undead.position) {
|
||||||
|
direction = 1;
|
||||||
|
} else if (x < undead.position) {
|
||||||
|
direction = -1;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
direction = random(-1, 1);
|
||||||
|
if (direction == 0) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int target_x = undead.position + direction;
|
||||||
|
if (target_x < 0 || target_x >= MAP_SIZE) return;
|
||||||
|
|
||||||
|
if (target_x <= BASE_END && barricade_health > 0) {
|
||||||
|
try_attack_barricade_undead(undead);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
undead.position = target_x;
|
||||||
|
play_creature_footstep(x, undead.position, BASE_END, GRASS_END, ZOMBIE_FOOTSTEP_MAX_DISTANCE, ZOMBIE_SOUND_VOLUME_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_undeads() {
|
||||||
|
if (is_daytime) {
|
||||||
|
clear_undeads();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (undeads.length() < ZOMBIE_MAX_COUNT) {
|
||||||
|
spawn_undead();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint i = 0; i < undeads.length(); i++) {
|
||||||
|
update_undead(undeads[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool damage_undead_at(int pos, int damage) {
|
||||||
|
for (uint i = 0; i < undeads.length(); i++) {
|
||||||
|
if (undeads[i].position == pos) {
|
||||||
|
undeads[i].health -= damage;
|
||||||
|
if (undeads[i].health <= 0) {
|
||||||
|
if (undeads[i].sound_handle != -1) {
|
||||||
|
p.destroy_sound(undeads[i].sound_handle);
|
||||||
|
undeads[i].sound_handle = -1;
|
||||||
|
}
|
||||||
|
play_creature_death_sound("sounds/enemies/enemy_falls.ogg", x, pos, ZOMBIE_SOUND_VOLUME_STEP);
|
||||||
|
undeads.remove_at(i);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backward compatibility aliases (to be removed after full refactoring)
|
||||||
|
Undead@[]@ zombies = @undeads; // Array alias for backward compatibility
|
||||||
|
Undead@ get_zombie_at(int pos) { return get_undead_at(pos); }
|
||||||
|
bool damage_zombie_at(int pos, int damage) { return damage_undead_at(pos, damage); }
|
||||||
|
void update_zombies() { update_undeads(); }
|
||||||
|
void clear_zombies() { clear_undeads(); }
|
||||||
|
void spawn_zombie() { spawn_undead(); }
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// Base class for simple world objects (buildings and structures)
|
||||||
|
// Provides common position field for world objects that only need to track location
|
||||||
|
|
||||||
|
class WorldLocationBase {
|
||||||
|
int position;
|
||||||
|
|
||||||
|
WorldLocationBase(int pos) {
|
||||||
|
position = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-203
@@ -7,35 +7,10 @@ int barricade_health = 0;
|
|||||||
bool barricade_initialized = false;
|
bool barricade_initialized = false;
|
||||||
int residents_count = 0;
|
int residents_count = 0;
|
||||||
|
|
||||||
string[] zombie_sounds = {"sounds/enemies/zombie1.ogg"};
|
|
||||||
string[] bandit_sounds = {"sounds/enemies/bandit1.ogg", "sounds/enemies/bandit2.ogg"};
|
string[] bandit_sounds = {"sounds/enemies/bandit1.ogg", "sounds/enemies/bandit2.ogg"};
|
||||||
string[] goose_sounds = {"sounds/game/goose.ogg"};
|
string[] goose_sounds = {"sounds/game/goose.ogg"};
|
||||||
string[] boar_sounds = {"sounds/game/boar.ogg"};
|
string[] boar_sounds = {"sounds/game/boar.ogg"};
|
||||||
|
|
||||||
class Zombie {
|
|
||||||
int position;
|
|
||||||
int health;
|
|
||||||
string voice_sound;
|
|
||||||
int sound_handle;
|
|
||||||
timer move_timer;
|
|
||||||
timer groan_timer;
|
|
||||||
timer attack_timer;
|
|
||||||
int next_groan_delay;
|
|
||||||
|
|
||||||
Zombie(int pos) {
|
|
||||||
position = pos;
|
|
||||||
health = ZOMBIE_HEALTH;
|
|
||||||
int sound_index = random(0, zombie_sounds.length() - 1);
|
|
||||||
voice_sound = zombie_sounds[sound_index];
|
|
||||||
sound_handle = -1;
|
|
||||||
move_timer.restart();
|
|
||||||
groan_timer.restart();
|
|
||||||
attack_timer.restart();
|
|
||||||
next_groan_delay = random(ZOMBIE_GROAN_MIN_DELAY, ZOMBIE_GROAN_MAX_DELAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Zombie@[] zombies;
|
|
||||||
|
|
||||||
class Bandit {
|
class Bandit {
|
||||||
int position;
|
int position;
|
||||||
int health;
|
int health;
|
||||||
@@ -792,184 +767,7 @@ int add_barricade_health(int amount) {
|
|||||||
return barricade_health - before;
|
return barricade_health - before;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_zombies() {
|
// Zombie functions moved to src/enemies/undead.nvgt
|
||||||
if (zombies.length() == 0) return;
|
|
||||||
|
|
||||||
for (uint i = 0; i < zombies.length(); i++) {
|
|
||||||
if (zombies[i].sound_handle != -1) {
|
|
||||||
p.destroy_sound(zombies[i].sound_handle);
|
|
||||||
zombies[i].sound_handle = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zombies.resize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Zombie@ get_zombie_at(int pos) {
|
|
||||||
for (uint i = 0; i < zombies.length(); i++) {
|
|
||||||
if (zombies[i].position == pos) {
|
|
||||||
return @zombies[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void spawn_zombie() {
|
|
||||||
int spawn_x = -1;
|
|
||||||
for (int attempts = 0; attempts < 20; attempts++) {
|
|
||||||
int candidate = random(BASE_END + 1, MAP_SIZE - 1);
|
|
||||||
if (get_zombie_at(candidate) == null) {
|
|
||||||
spawn_x = candidate;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (spawn_x == -1) {
|
|
||||||
spawn_x = random(BASE_END + 1, MAP_SIZE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Zombie@ z = Zombie(spawn_x);
|
|
||||||
zombies.insert_last(z);
|
|
||||||
z.sound_handle = play_creature_voice(z.voice_sound, x, spawn_x, ZOMBIE_SOUND_VOLUME_STEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void try_attack_barricade(Zombie@ zombie) {
|
|
||||||
if (barricade_health <= 0) return;
|
|
||||||
if (zombie.attack_timer.elapsed < ZOMBIE_ATTACK_INTERVAL) return;
|
|
||||||
|
|
||||||
zombie.attack_timer.restart();
|
|
||||||
int damage = random(ZOMBIE_DAMAGE_MIN, ZOMBIE_DAMAGE_MAX);
|
|
||||||
barricade_health -= damage;
|
|
||||||
if (barricade_health < 0) barricade_health = 0;
|
|
||||||
|
|
||||||
play_creature_attack_sound("sounds/enemies/zombie_hits_player.ogg", x, zombie.position, 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) {
|
|
||||||
speak_with_history("Residents killed an attacking zombie.", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (barricade_health == 0) {
|
|
||||||
notify("The barricade has fallen!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool can_zombie_attack_player(Zombie@ zombie) {
|
|
||||||
if (player_health <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (barricade_health > 0 && x <= BASE_END) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (abs(zombie.position - x) > 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return y <= ZOMBIE_ATTACK_MAX_HEIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool try_attack_player(Zombie@ zombie) {
|
|
||||||
if (!can_zombie_attack_player(zombie)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (zombie.attack_timer.elapsed < ZOMBIE_ATTACK_INTERVAL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
zombie.attack_timer.restart();
|
|
||||||
int damage = random(ZOMBIE_DAMAGE_MIN, ZOMBIE_DAMAGE_MAX);
|
|
||||||
player_health -= damage;
|
|
||||||
if (player_health < 0) {
|
|
||||||
player_health = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
play_creature_attack_sound("sounds/enemies/zombie_hits_player.ogg", x, zombie.position, ZOMBIE_SOUND_VOLUME_STEP);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_zombie(Zombie@ zombie) {
|
|
||||||
if (zombie.groan_timer.elapsed > zombie.next_groan_delay) {
|
|
||||||
zombie.groan_timer.restart();
|
|
||||||
zombie.next_groan_delay = random(ZOMBIE_GROAN_MIN_DELAY, ZOMBIE_GROAN_MAX_DELAY);
|
|
||||||
zombie.sound_handle = play_creature_voice(zombie.voice_sound, x, zombie.position, ZOMBIE_SOUND_VOLUME_STEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (try_attack_player(zombie)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zombie.move_timer.elapsed < ZOMBIE_MOVE_INTERVAL) return;
|
|
||||||
zombie.move_timer.restart();
|
|
||||||
|
|
||||||
if (barricade_health > 0 && zombie.position == BASE_END + 1) {
|
|
||||||
try_attack_barricade(zombie);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int direction = 0;
|
|
||||||
if (x > BASE_END) {
|
|
||||||
if (x > zombie.position) {
|
|
||||||
direction = 1;
|
|
||||||
} else if (x < zombie.position) {
|
|
||||||
direction = -1;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
direction = random(-1, 1);
|
|
||||||
if (direction == 0) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int target_x = zombie.position + direction;
|
|
||||||
if (target_x < 0 || target_x >= MAP_SIZE) return;
|
|
||||||
|
|
||||||
if (target_x <= BASE_END && barricade_health > 0) {
|
|
||||||
try_attack_barricade(zombie);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
zombie.position = target_x;
|
|
||||||
play_creature_footstep(x, zombie.position, BASE_END, GRASS_END, ZOMBIE_FOOTSTEP_MAX_DISTANCE, ZOMBIE_SOUND_VOLUME_STEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_zombies() {
|
|
||||||
if (is_daytime) {
|
|
||||||
clear_zombies();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (zombies.length() < ZOMBIE_MAX_COUNT) {
|
|
||||||
spawn_zombie();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint i = 0; i < zombies.length(); i++) {
|
|
||||||
update_zombie(zombies[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool damage_zombie_at(int pos, int damage) {
|
|
||||||
for (uint i = 0; i < zombies.length(); i++) {
|
|
||||||
if (zombies[i].position == pos) {
|
|
||||||
zombies[i].health -= damage;
|
|
||||||
if (zombies[i].health <= 0) {
|
|
||||||
if (zombies[i].sound_handle != -1) {
|
|
||||||
p.destroy_sound(zombies[i].sound_handle);
|
|
||||||
zombies[i].sound_handle = -1;
|
|
||||||
}
|
|
||||||
play_creature_death_sound("sounds/enemies/enemy_falls.ogg", x, pos, ZOMBIE_SOUND_VOLUME_STEP);
|
|
||||||
zombies.remove_at(i);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
WorldHerbGarden@ get_herb_garden_at(int pos) {
|
WorldHerbGarden@ get_herb_garden_at(int pos) {
|
||||||
for (uint i = 0; i < world_herb_gardens.length(); i++) {
|
for (uint i = 0; i < world_herb_gardens.length(); i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user