import utils import numpy as np import pathing class Player: def __init__(self, x, y): self.x = x self.y = y self.symbol = '@' self.name = 'You' self.hp = 10 self.damage = 2 class Enemy: def __init__(self, x, y, symbol): self.x = x self.y = y self.symbol = symbol self.name = 'Python' self.hp = 5 self.damage = 1 self.hearing_distance = 5 class ECS: def __init__(self): self.entities = {} self.facts = {} self.id_counter = 0 def entity(self): self.id_counter += 1 return self.id_counter def set(self, entity_id, obj): name = obj.__class__.__qualname__ target = self.entities.get(name, {}) target[entity_id] = obj self.entities[name] = target def query(self, cls): return self.entities[cls.__qualname__].items() class Systems: def __init__(self, ecs, ui, the_map): self.ecs = ecs self.map = the_map self.ui = ui self.height = self.map.height self.width = self.map.width self.paths = np.full((self.height, self.width), utils.PATH_LIMIT, dtype=int) def move_enemies(self): in_grid = np.full((self.map.height, self.map.width), 1, dtype=int) in_grid[self.player.y, self.player.x] = 0 pathing.calculate_paths(self.map, self.paths, in_grid) # for every enemy (actors[0] is player) for enemy in self.actors[1:]: nearby = utils.compass(enemy.x, enemy.y) our_path = self.paths[enemy.y, enemy.x] if our_path > enemy.hearing_distance: continue for x, y in nearby: if self.paths[y, x] <= our_path and not self.actor_collision(enemy, x, y): enemy.x = x enemy.y = y break def death(self, target): self.actors.remove(target) self.ui.post_status(f"Killed {target.name}") def combat(self, actor, target): target.hp -= actor.damage if target.hp > 0: self.ui.post_status(f"HIT {target.name} for {actor.damage}") else: self.death(target) def actor_collision(self, actor, x, y): for target in self.actors: if target != actor and target.x == x and target.y == y: return target return None def collision(self, actor, x, y): if self.map.collision(x, y): return True target = self.actor_collision(actor, x, y) if target: self.combat(actor, target) return True return False def move_player(self, actor, x, y): if not self.collision(actor, x, y): actor.x = x actor.y = y def spawn_actors(self, enemy_count): x, y = self.map.spawn() self.player = Player(x, y) self.actors = [self.player] for i in range(0, enemy_count): x, y = self.map.spawn() enemy = Enemy(x, y, '{') self.actors.append(enemy)