import pygame import math from game.config import ENEMY_DATA, PATH_WAYPOINTS, COLOR_BLACK, COLOR_GREEN, COLOR_RED, COLOR_BLUE from game.utils import distance class Enemy: def __init__(self, enemy_type, waypoints=None): data = ENEMY_DATA[enemy_type] self.type = enemy_type self.max_hp = data["hp"] self.hp = self.max_hp self.base_speed = data["speed"] self.speed = self.base_speed self.reward = data["reward"] self.color = data["color"] self.size = data["size"] self.alive = True self.reached_end = False # Shield self.max_shield = data.get("shield_hp", 0) self.shield_hp = self.max_shield # Poison DoT self.poison_timer = 0 self.poison_dps = 0 # Healer self.heal_range = data.get("heal_range", 0) self.heal_amount = data.get("heal_amount", 0) self.heal_interval = data.get("heal_interval", 2.0) self.heal_timer = self.heal_interval self.waypoints = waypoints or PATH_WAYPOINTS self.x, self.y = self.waypoints[0] self.waypoint_index = 1 self.slow_timer = 0 def apply_slow(self, factor, duration): self.speed = self.base_speed * factor self.slow_timer = duration def apply_poison(self, dps, duration): self.poison_dps = dps self.poison_timer = duration def take_damage(self, damage): if self.shield_hp > 0: absorbed = min(self.shield_hp, damage) self.shield_hp -= absorbed damage -= absorbed if damage > 0: self.hp -= damage if self.hp <= 0: self.hp = 0 self.alive = False def update(self, dt, enemies=None): if not self.alive: return # Poison DoT if self.poison_timer > 0: self.poison_timer -= dt self.hp -= self.poison_dps * dt if self.hp <= 0: self.hp = 0 self.alive = False return # Slow if self.slow_timer > 0: self.slow_timer -= dt if self.slow_timer <= 0: self.speed = self.base_speed # Healer ability if self.type == "healer" and enemies: self.heal_timer -= dt if self.heal_timer <= 0: self.heal_timer = self.heal_interval for e in enemies: if e is not self and e.alive and distance(self.x, self.y, e.x, e.y) <= self.heal_range: e.hp = min(e.hp + self.heal_amount, e.max_hp) # Movement if self.waypoint_index >= len(self.waypoints): self.reached_end = True self.alive = False return tx, ty = self.waypoints[self.waypoint_index] dx = tx - self.x dy = ty - self.y dist = math.hypot(dx, dy) move = self.speed * 60 * dt if dist <= move: self.x, self.y = tx, ty self.waypoint_index += 1 else: self.x += dx / dist * move self.y += dy / dist * move def draw(self, surface): if not self.alive: return ix, iy = int(self.x), int(self.y) # Healer aura if self.type == "healer": aura = pygame.Surface((self.heal_range * 2, self.heal_range * 2), pygame.SRCALPHA) pygame.draw.circle(aura, (255, 130, 170, 30), (self.heal_range, self.heal_range), self.heal_range) surface.blit(aura, (ix - self.heal_range, iy - self.heal_range)) # Poison tint if self.poison_timer > 0: pygame.draw.circle(surface, (0, 180, 0), (ix, iy), self.size + 3) pygame.draw.circle(surface, self.color, (ix, iy), self.size) pygame.draw.circle(surface, COLOR_BLACK, (ix, iy), self.size, 2) # Boss eyes if self.type == "boss": for offset in [(-6, -6), (6, -6)]: pygame.draw.circle(surface, (255, 200, 0), (ix + offset[0], iy + offset[1]), 4) pygame.draw.circle(surface, COLOR_BLACK, (ix + offset[0], iy + offset[1]), 4, 1) # Shield ring if self.type == "shield" and self.shield_hp > 0: shield_ratio = self.shield_hp / self.max_shield arc_color = COLOR_BLUE pygame.draw.circle(surface, arc_color, (ix, iy), self.size + 4, 2) # Swarm wings if self.type == "swarm": for dx_off in [-4, 4]: pygame.draw.line(surface, (200, 255, 200), (ix + dx_off, iy - 3), (ix + dx_off * 2, iy - 7), 1) # Healer cross if self.type == "healer": pygame.draw.rect(surface, (255, 255, 255), (ix - 1, iy - 5, 3, 10)) pygame.draw.rect(surface, (255, 255, 255), (ix - 5, iy - 1, 10, 3)) # Health bar bar_w = self.size * 2 + 4 if self.type == "boss": bar_w = self.size * 3 bar_h = 4 bx = ix - bar_w // 2 by = iy - self.size - 8 ratio = self.hp / self.max_hp pygame.draw.rect(surface, COLOR_RED, (bx, by, bar_w, bar_h)) pygame.draw.rect(surface, COLOR_GREEN, (bx, by, int(bar_w * ratio), bar_h)) # Shield bar if self.max_shield > 0 and self.shield_hp > 0: s_bar_h = 3 s_ratio = self.shield_hp / self.max_shield pygame.draw.rect(surface, (80, 80, 80), (bx, by - s_bar_h - 1, bar_w, s_bar_h)) pygame.draw.rect(surface, COLOR_BLUE, (bx, by - s_bar_h - 1, int(bar_w * s_ratio), s_bar_h))