62a65f599d
Remove the is_hidden_in_tunnel() checks from Explosion.draw() and Gas.draw() so explosions and gas clouds remain visible when their center falls inside a tunnel cell. Logic already spawned them in tunnel cells, but they were rendered invisible because the draw path returned early.
83 lines
3.5 KiB
Python
83 lines
3.5 KiB
Python
from .unit import Unit, UnitType
|
|
from engine.collision_system import CollisionLayer, shrink_bbox
|
|
import random
|
|
|
|
# Costanti
|
|
AGE_THRESHOLD = 200
|
|
GAS_BBOX_SHRINK = 0.3 # central 40% of the tile is poisonous
|
|
|
|
class Gas(Unit):
|
|
draw_on_top = True
|
|
|
|
def __init__(self, game, position=(0,0), id=None, parent_id=None):
|
|
super().__init__(game, position, id, collision_layer=CollisionLayer.GAS, unit_type=UnitType.GAS)
|
|
self.parent_id = parent_id
|
|
# Specific attributes for gas
|
|
self.speed = 50
|
|
self.fight = False
|
|
self.age = 0
|
|
if parent_id:
|
|
self.age = round(random.uniform(0, AGE_THRESHOLD))
|
|
self.spreading_cells = []
|
|
self.last_spreading_cells = []
|
|
|
|
|
|
def move(self):
|
|
if self.age > AGE_THRESHOLD:
|
|
self.die()
|
|
return
|
|
self.age += 1
|
|
|
|
# Register a smaller bbox so rats must be well inside the tile to be gassed
|
|
cell_bbox = (
|
|
self.position[0] * self.game.cell_size,
|
|
self.position[1] * self.game.cell_size,
|
|
(self.position[0] + 1) * self.game.cell_size,
|
|
(self.position[1] + 1) * self.game.cell_size,
|
|
)
|
|
self.bbox = shrink_bbox(cell_bbox, GAS_BBOX_SHRINK)
|
|
|
|
if self.age % self.speed:
|
|
return
|
|
parent = self.game.unit_manager.get_unit_by_id(self.parent_id)
|
|
if (parent) or self.parent_id is None:
|
|
print(f"Gas at {self.position} is spreading")
|
|
# Spread gas to adjacent cells
|
|
|
|
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
|
|
new_x = self.position[0] + dx
|
|
new_y = self.position[1] + dy
|
|
if not self.game.map.is_wall(new_x, new_y):
|
|
if not any(unit.type == UnitType.GAS for unit in self.game.units.values() if unit.position == (new_x, new_y)):
|
|
print(f"Spreading gas from {self.position} to ({new_x}, {new_y})")
|
|
self.game.unit_manager.spawn_unit(Gas, (new_x, new_y), parent_id=self.parent_id if self.parent_id else self.id)
|
|
|
|
def collisions(self):
|
|
"""Poison rats that overlap the shrunk gas tile in Pass 2."""
|
|
for _, victim_id in self.game.collision_system.get_collisions_for_unit(
|
|
self.id, CollisionLayer.GAS, tolerance=0
|
|
):
|
|
victim = self.game.unit_manager.get_unit_by_id(victim_id)
|
|
if victim and victim.type in [UnitType.RAT_MALE, UnitType.RAT_FEMALE] and victim.id in self.game.units:
|
|
victim.gassed += 1
|
|
|
|
def die(self, unit=None, score=None):
|
|
if not unit:
|
|
unit = self
|
|
self.game.units.pop(unit.id)
|
|
|
|
|
|
def draw(self):
|
|
image = self.game.graphics.assets["BMP_GAS"]
|
|
image_size = self.game.render_engine.get_image_size(image)
|
|
self.rat_image = image
|
|
partial_x, partial_y = 0, 0
|
|
|
|
x_pos = self.position_before[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x
|
|
y_pos = self.position_before[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y
|
|
self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit")
|
|
for cell in self.spreading_cells:
|
|
x_pos = cell[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2 + partial_x
|
|
y_pos = cell[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2 + partial_y
|
|
self.game.render_engine.draw_image(x_pos, y_pos, image, anchor="nw", tag="unit")
|