zombie-escape 1.5.4__py3-none-any.whl → 1.7.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. zombie_escape/__about__.py +1 -1
  2. zombie_escape/entities.py +501 -537
  3. zombie_escape/entities_constants.py +102 -0
  4. zombie_escape/gameplay/__init__.py +75 -2
  5. zombie_escape/gameplay/ambient.py +50 -0
  6. zombie_escape/gameplay/constants.py +46 -0
  7. zombie_escape/gameplay/footprints.py +60 -0
  8. zombie_escape/gameplay/interactions.py +354 -0
  9. zombie_escape/gameplay/layout.py +190 -0
  10. zombie_escape/gameplay/movement.py +220 -0
  11. zombie_escape/gameplay/spawn.py +618 -0
  12. zombie_escape/gameplay/state.py +137 -0
  13. zombie_escape/gameplay/survivors.py +306 -0
  14. zombie_escape/gameplay/utils.py +147 -0
  15. zombie_escape/gameplay_constants.py +0 -148
  16. zombie_escape/level_blueprints.py +123 -10
  17. zombie_escape/level_constants.py +6 -13
  18. zombie_escape/locales/ui.en.json +10 -1
  19. zombie_escape/locales/ui.ja.json +10 -1
  20. zombie_escape/models.py +15 -9
  21. zombie_escape/render.py +42 -27
  22. zombie_escape/render_assets.py +533 -23
  23. zombie_escape/render_constants.py +57 -22
  24. zombie_escape/rng.py +9 -9
  25. zombie_escape/screens/__init__.py +59 -29
  26. zombie_escape/screens/game_over.py +3 -3
  27. zombie_escape/screens/gameplay.py +45 -27
  28. zombie_escape/screens/title.py +5 -2
  29. zombie_escape/stage_constants.py +34 -1
  30. zombie_escape/zombie_escape.py +30 -12
  31. {zombie_escape-1.5.4.dist-info → zombie_escape-1.7.1.dist-info}/METADATA +1 -1
  32. zombie_escape-1.7.1.dist-info/RECORD +45 -0
  33. zombie_escape/gameplay/logic.py +0 -1917
  34. zombie_escape-1.5.4.dist-info/RECORD +0 -35
  35. {zombie_escape-1.5.4.dist-info → zombie_escape-1.7.1.dist-info}/WHEEL +0 -0
  36. {zombie_escape-1.5.4.dist-info → zombie_escape-1.7.1.dist-info}/entry_points.txt +0 -0
  37. {zombie_escape-1.5.4.dist-info → zombie_escape-1.7.1.dist-info}/licenses/LICENSE.txt +0 -0
zombie_escape/render.py CHANGED
@@ -5,29 +5,28 @@ from enum import Enum
5
5
  from typing import Any, Callable
6
6
 
7
7
  import pygame
8
- from pygame import sprite, surface
9
8
  import pygame.surfarray as pg_surfarray # type: ignore
9
+ from pygame import sprite, surface
10
10
 
11
11
  from .colors import (
12
12
  BLACK,
13
13
  BLUE,
14
14
  FOOTPRINT_COLOR,
15
- INTERNAL_WALL_COLOR,
16
15
  LIGHT_GRAY,
17
16
  ORANGE,
18
17
  YELLOW,
19
18
  get_environment_palette,
20
19
  )
20
+ from .entities import Camera, Car, Flashlight, FuelCan, Player, Survivor, Wall
21
+ from .font_utils import load_font
21
22
  from .gameplay_constants import (
22
23
  DEFAULT_FLASHLIGHT_SPAWN_COUNT,
23
24
  SURVIVAL_FAKE_CLOCK_RATIO,
24
25
  )
25
- from .entities import Camera, Car, Flashlight, FuelCan, Player, Survivor
26
- from .font_utils import load_font
27
26
  from .localization import get_font_settings
28
27
  from .localization import translate as tr
29
28
  from .models import GameData, Stage
30
- from .render_assets import RenderAssets
29
+ from .render_assets import RenderAssets, resolve_wall_colors
31
30
 
32
31
 
33
32
  def show_message(
@@ -76,8 +75,18 @@ def draw_level_overview(
76
75
  dark_floor = tuple(max(0, int(channel * 0.55)) for channel in base_floor)
77
76
  surface.fill(dark_floor)
78
77
  for wall in wall_group:
79
- color = getattr(wall, "base_color", INTERNAL_WALL_COLOR)
80
- pygame.draw.rect(surface, color, wall.rect)
78
+ if not isinstance(wall, Wall):
79
+ raise TypeError("wall_group must contain Wall instances")
80
+ if wall.max_health > 0:
81
+ health_ratio = max(0.0, min(1.0, wall.health / wall.max_health))
82
+ else:
83
+ health_ratio = 0.0
84
+ fill_color, _ = resolve_wall_colors(
85
+ health_ratio=health_ratio,
86
+ palette_category=wall.palette_category,
87
+ palette=palette,
88
+ )
89
+ pygame.draw.rect(surface, fill_color, wall.rect)
81
90
  now = pygame.time.get_ticks()
82
91
  for fp in footprints:
83
92
  age = now - fp["time"]
@@ -133,7 +142,7 @@ def draw_level_overview(
133
142
  surface.blit(parked.image, parked_rect)
134
143
 
135
144
 
136
- def get_fog_scale(
145
+ def _get_fog_scale(
137
146
  assets: RenderAssets,
138
147
  stage: Stage | None,
139
148
  flashlight_count: int,
@@ -162,12 +171,12 @@ class FogProfile(Enum):
162
171
  self.flashlight_count = flashlight_count
163
172
  self.color = color
164
173
 
165
- def scale(self, assets: RenderAssets, stage: Stage | None) -> float:
174
+ def _scale(self, assets: RenderAssets, stage: Stage | None) -> float:
166
175
  count = max(0, min(self.flashlight_count, _max_flashlight_pickups()))
167
- return get_fog_scale(assets, stage, count)
176
+ return _get_fog_scale(assets, stage, count)
168
177
 
169
178
  @staticmethod
170
- def from_flashlight_count(count: int) -> "FogProfile":
179
+ def _from_flashlight_count(count: int) -> "FogProfile":
171
180
  safe_count = max(0, count)
172
181
  if safe_count >= 2:
173
182
  return FogProfile.DARK2
@@ -193,7 +202,7 @@ def prewarm_fog_overlays(
193
202
  )
194
203
 
195
204
 
196
- def get_hatch_pattern(
205
+ def _get_hatch_pattern(
197
206
  fog_data: dict[str, Any],
198
207
  thickness: int,
199
208
  *,
@@ -248,7 +257,7 @@ def _get_fog_overlay_surfaces(
248
257
  if key in overlays:
249
258
  return overlays[key]
250
259
 
251
- scale = profile.scale(assets, stage)
260
+ scale = profile._scale(assets, stage)
252
261
  max_radius = int(assets.fov_radius * scale)
253
262
  padding = 32
254
263
  coverage_width = max(assets.screen_width * 2, max_radius * 2)
@@ -265,7 +274,7 @@ def _get_fog_overlay_surfaces(
265
274
  ring_surfaces: list[surface.Surface] = []
266
275
  for ring in assets.fog_rings:
267
276
  ring_surface = pygame.Surface((width, height), pygame.SRCALPHA)
268
- pattern = get_hatch_pattern(
277
+ pattern = _get_hatch_pattern(
269
278
  fog_data,
270
279
  ring.thickness,
271
280
  pixel_scale=assets.fog_hatch_pixel_scale,
@@ -393,7 +402,7 @@ def _draw_hint_arrow(
393
402
  pygame.draw.polygon(screen, color, [tip, left, right])
394
403
 
395
404
 
396
- def draw_status_bar(
405
+ def _draw_status_bar(
397
406
  screen: surface.Surface,
398
407
  assets: RenderAssets,
399
408
  config: dict[str, Any],
@@ -483,8 +492,8 @@ def draw(
483
492
 
484
493
  camera = game_data.camera
485
494
  stage = game_data.stage
486
- outer_rect = game_data.areas.outer_rect
487
- outside_rects = game_data.areas.outside_rects or []
495
+ outer_rect = game_data.layout.outer_rect
496
+ outside_rects = game_data.layout.outside_rects or []
488
497
  all_sprites = game_data.groups.all_sprites
489
498
  fog_surfaces = game_data.fog
490
499
  footprints = state.footprints
@@ -492,12 +501,12 @@ def draw(
492
501
  flashlight_count = state.flashlight_count
493
502
  elapsed_play_ms = state.elapsed_play_ms
494
503
  fuel_message_until = state.fuel_message_until
495
- buddy_rescued = state.buddy_rescued
496
504
  buddy_onboard = state.buddy_onboard
497
505
  buddy_required = stage.buddy_required_count if stage else 0
498
506
  survivors_onboard = state.survivors_onboard
499
507
  survivor_messages = list(state.survivor_messages)
500
508
  zombie_group = game_data.groups.zombie_group
509
+ active_car = game_data.car if game_data.car and game_data.car.alive() else None
501
510
 
502
511
  palette = get_environment_palette(state.ambient_palette_key)
503
512
  screen.fill(palette.outside)
@@ -604,7 +613,7 @@ def draw(
604
613
  pygame.draw.rect(screen, (180, 160, 40), indicator_rect, width=1)
605
614
 
606
615
  if hint_target and player:
607
- current_fov_scale = get_fog_scale(
616
+ current_fov_scale = _get_fog_scale(
608
617
  assets,
609
618
  stage,
610
619
  flashlight_count,
@@ -633,7 +642,7 @@ def draw(
633
642
  if state.dawn_ready:
634
643
  profile = FogProfile.DAWN
635
644
  else:
636
- profile = FogProfile.from_flashlight_count(flashlight_count)
645
+ profile = FogProfile._from_flashlight_count(flashlight_count)
637
646
  overlay = _get_fog_overlay_surfaces(
638
647
  fog_surfaces,
639
648
  assets,
@@ -763,16 +772,22 @@ def draw(
763
772
  else:
764
773
  objective_lines.append(tr("objectives.survive_until_dawn"))
765
774
  elif stage and stage.buddy_required_count > 0:
766
- if stage.requires_fuel and not has_fuel:
767
- objective_lines.append(tr("objectives.find_fuel"))
768
- elif not player.in_car:
769
- objective_lines.append(tr("objectives.find_car"))
775
+ buddy_ready = buddy_onboard >= buddy_required
776
+ if not active_car:
777
+ objective_lines.append(tr("objectives.pickup_buddy"))
778
+ if stage.requires_fuel and not has_fuel:
779
+ objective_lines.append(tr("objectives.find_fuel"))
780
+ else:
781
+ objective_lines.append(tr("objectives.find_car"))
770
782
  else:
771
- if buddy_rescued < buddy_required:
772
- objective_lines.append(tr("objectives.escape_with_buddy"))
783
+ if stage.requires_fuel and not has_fuel:
784
+ objective_lines.append(tr("objectives.find_fuel"))
785
+ elif not buddy_ready:
786
+ objective_lines.append(tr("objectives.board_buddy"))
773
787
  objective_lines.append(
774
788
  tr("objectives.buddy_onboard", count=buddy_onboard)
775
789
  )
790
+ objective_lines.append(tr("objectives.escape"))
776
791
  else:
777
792
  objective_lines.append(tr("objectives.escape"))
778
793
  elif stage and stage.requires_fuel and not has_fuel:
@@ -815,7 +830,7 @@ def draw(
815
830
  _render_survival_timer()
816
831
  else:
817
832
  _render_time_accel_indicator()
818
- draw_status_bar(
833
+ _draw_status_bar(
819
834
  screen,
820
835
  assets,
821
836
  config,