zombie-escape 1.12.0__py3-none-any.whl → 1.12.3__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.
- zombie_escape/__about__.py +1 -1
- zombie_escape/colors.py +22 -14
- zombie_escape/entities.py +236 -49
- zombie_escape/entities_constants.py +6 -2
- zombie_escape/gameplay/footprints.py +4 -0
- zombie_escape/gameplay/interactions.py +19 -7
- zombie_escape/gameplay/layout.py +18 -14
- zombie_escape/gameplay/movement.py +23 -1
- zombie_escape/gameplay/spawn.py +92 -50
- zombie_escape/gameplay/state.py +15 -9
- zombie_escape/gameplay/survivors.py +9 -1
- zombie_escape/gameplay/utils.py +40 -21
- zombie_escape/level_blueprints.py +87 -4
- zombie_escape/models.py +5 -4
- zombie_escape/render.py +51 -16
- zombie_escape/render_assets.py +325 -124
- zombie_escape/render_constants.py +11 -0
- zombie_escape/screens/game_over.py +3 -3
- zombie_escape/screens/gameplay.py +4 -0
- zombie_escape/stage_constants.py +5 -5
- zombie_escape/zombie_escape.py +1 -1
- {zombie_escape-1.12.0.dist-info → zombie_escape-1.12.3.dist-info}/METADATA +4 -3
- zombie_escape-1.12.3.dist-info/RECORD +47 -0
- zombie_escape-1.12.0.dist-info/RECORD +0 -47
- {zombie_escape-1.12.0.dist-info → zombie_escape-1.12.3.dist-info}/WHEEL +0 -0
- {zombie_escape-1.12.0.dist-info → zombie_escape-1.12.3.dist-info}/entry_points.txt +0 -0
- {zombie_escape-1.12.0.dist-info → zombie_escape-1.12.3.dist-info}/licenses/LICENSE.txt +0 -0
zombie_escape/gameplay/utils.py
CHANGED
|
@@ -25,7 +25,8 @@ def rect_visible_on_screen(camera: Camera | None, rect: pygame.Rect) -> bool:
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
def _scatter_positions_on_walkable(
|
|
28
|
-
walkable_cells: list[
|
|
28
|
+
walkable_cells: list[tuple[int, int]],
|
|
29
|
+
cell_size: int,
|
|
29
30
|
spawn_rate: float,
|
|
30
31
|
*,
|
|
31
32
|
jitter_ratio: float = 0.35,
|
|
@@ -35,17 +36,21 @@ def _scatter_positions_on_walkable(
|
|
|
35
36
|
return positions
|
|
36
37
|
|
|
37
38
|
clamped_rate = max(0.0, min(1.0, spawn_rate))
|
|
38
|
-
for
|
|
39
|
+
for cell_x, cell_y in walkable_cells:
|
|
39
40
|
if RNG.random() >= clamped_rate:
|
|
40
41
|
continue
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
jitter_extent = cell_size * jitter_ratio
|
|
43
|
+
jitter_x = RNG.uniform(-jitter_extent, jitter_extent)
|
|
44
|
+
jitter_y = RNG.uniform(-jitter_extent, jitter_extent)
|
|
45
|
+
base_x = (cell_x * cell_size) + (cell_size / 2)
|
|
46
|
+
base_y = (cell_y * cell_size) + (cell_size / 2)
|
|
47
|
+
positions.append((int(base_x + jitter_x), int(base_y + jitter_y)))
|
|
44
48
|
return positions
|
|
45
49
|
|
|
46
50
|
|
|
47
51
|
def find_interior_spawn_positions(
|
|
48
|
-
walkable_cells: list[
|
|
52
|
+
walkable_cells: list[tuple[int, int]],
|
|
53
|
+
cell_size: int,
|
|
49
54
|
spawn_rate: float,
|
|
50
55
|
*,
|
|
51
56
|
player: Player | None = None,
|
|
@@ -53,12 +58,14 @@ def find_interior_spawn_positions(
|
|
|
53
58
|
) -> list[tuple[int, int]]:
|
|
54
59
|
positions = _scatter_positions_on_walkable(
|
|
55
60
|
walkable_cells,
|
|
61
|
+
cell_size,
|
|
56
62
|
spawn_rate,
|
|
57
63
|
jitter_ratio=0.35,
|
|
58
64
|
)
|
|
59
65
|
if not positions and spawn_rate > 0:
|
|
60
66
|
positions = _scatter_positions_on_walkable(
|
|
61
67
|
walkable_cells,
|
|
68
|
+
cell_size,
|
|
62
69
|
spawn_rate * 1.5,
|
|
63
70
|
jitter_ratio=0.35,
|
|
64
71
|
)
|
|
@@ -78,7 +85,8 @@ def find_interior_spawn_positions(
|
|
|
78
85
|
|
|
79
86
|
|
|
80
87
|
def find_nearby_offscreen_spawn_position(
|
|
81
|
-
walkable_cells: list[
|
|
88
|
+
walkable_cells: list[tuple[int, int]],
|
|
89
|
+
cell_size: int,
|
|
82
90
|
*,
|
|
83
91
|
player: Player | None = None,
|
|
84
92
|
camera: Camera | None = None,
|
|
@@ -104,10 +112,14 @@ def find_nearby_offscreen_spawn_position(
|
|
|
104
112
|
None if max_player_dist is None else max_player_dist * max_player_dist
|
|
105
113
|
)
|
|
106
114
|
for _ in range(max(1, attempts)):
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
cell_x, cell_y = RNG.choice(walkable_cells)
|
|
116
|
+
jitter_extent = cell_size * 0.35
|
|
117
|
+
jitter_x = RNG.uniform(-jitter_extent, jitter_extent)
|
|
118
|
+
jitter_y = RNG.uniform(-jitter_extent, jitter_extent)
|
|
119
|
+
candidate = (
|
|
120
|
+
int((cell_x * cell_size) + (cell_size / 2) + jitter_x),
|
|
121
|
+
int((cell_y * cell_size) + (cell_size / 2) + jitter_y),
|
|
122
|
+
)
|
|
111
123
|
if player is not None and (
|
|
112
124
|
min_distance_sq is not None or max_distance_sq is not None
|
|
113
125
|
):
|
|
@@ -123,8 +135,11 @@ def find_nearby_offscreen_spawn_position(
|
|
|
123
135
|
return candidate
|
|
124
136
|
if player is not None and (min_distance_sq is not None or max_distance_sq is not None):
|
|
125
137
|
for _ in range(20):
|
|
126
|
-
|
|
127
|
-
center = (
|
|
138
|
+
cell_x, cell_y = RNG.choice(walkable_cells)
|
|
139
|
+
center = (
|
|
140
|
+
(cell_x * cell_size) + (cell_size / 2),
|
|
141
|
+
(cell_y * cell_size) + (cell_size / 2),
|
|
142
|
+
)
|
|
128
143
|
if view_rect is not None and view_rect.collidepoint(center):
|
|
129
144
|
continue
|
|
130
145
|
dx = center[0] - player.x
|
|
@@ -134,15 +149,19 @@ def find_nearby_offscreen_spawn_position(
|
|
|
134
149
|
continue
|
|
135
150
|
if max_distance_sq is not None and dist_sq > max_distance_sq:
|
|
136
151
|
continue
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
152
|
+
fallback_extent = cell_size * 0.2
|
|
153
|
+
fallback_x = RNG.uniform(-fallback_extent, fallback_extent)
|
|
154
|
+
fallback_y = RNG.uniform(-fallback_extent, fallback_extent)
|
|
155
|
+
return (int(center[0] + fallback_x), int(center[1] + fallback_y))
|
|
156
|
+
fallback_cell_x, fallback_cell_y = RNG.choice(walkable_cells)
|
|
157
|
+
fallback_center_x = (fallback_cell_x * cell_size) + (cell_size / 2)
|
|
158
|
+
fallback_center_y = (fallback_cell_y * cell_size) + (cell_size / 2)
|
|
159
|
+
fallback_extent = cell_size * 0.35
|
|
160
|
+
fallback_x = RNG.uniform(-fallback_extent, fallback_extent)
|
|
161
|
+
fallback_y = RNG.uniform(-fallback_extent, fallback_extent)
|
|
143
162
|
return (
|
|
144
|
-
int(
|
|
145
|
-
int(
|
|
163
|
+
int(fallback_center_x + fallback_x),
|
|
164
|
+
int(fallback_center_y + fallback_y),
|
|
146
165
|
)
|
|
147
166
|
|
|
148
167
|
|
|
@@ -218,9 +218,10 @@ def _place_walls_grid_wire(
|
|
|
218
218
|
grid[y][x] = "1"
|
|
219
219
|
|
|
220
220
|
|
|
221
|
-
def
|
|
221
|
+
def _place_walls_sparse_moore(
|
|
222
222
|
grid: list[list[str]],
|
|
223
223
|
*,
|
|
224
|
+
density: float = SPARSE_WALL_DENSITY,
|
|
224
225
|
forbidden_cells: set[tuple[int, int]] | None = None,
|
|
225
226
|
) -> None:
|
|
226
227
|
"""Place isolated wall tiles at a low density, avoiding adjacency."""
|
|
@@ -234,7 +235,7 @@ def _place_walls_sparse(
|
|
|
234
235
|
continue
|
|
235
236
|
if grid[y][x] != ".":
|
|
236
237
|
continue
|
|
237
|
-
if RNG.random() >=
|
|
238
|
+
if RNG.random() >= density:
|
|
238
239
|
continue
|
|
239
240
|
if (
|
|
240
241
|
grid[y - 1][x] == "1"
|
|
@@ -250,11 +251,40 @@ def _place_walls_sparse(
|
|
|
250
251
|
grid[y][x] = "1"
|
|
251
252
|
|
|
252
253
|
|
|
254
|
+
def _place_walls_sparse_ortho(
|
|
255
|
+
grid: list[list[str]],
|
|
256
|
+
*,
|
|
257
|
+
density: float = SPARSE_WALL_DENSITY,
|
|
258
|
+
forbidden_cells: set[tuple[int, int]] | None = None,
|
|
259
|
+
) -> None:
|
|
260
|
+
"""Place isolated wall tiles at a low density, avoiding orthogonal adjacency."""
|
|
261
|
+
cols, rows = len(grid[0]), len(grid)
|
|
262
|
+
forbidden = _collect_exit_adjacent_cells(grid)
|
|
263
|
+
if forbidden_cells:
|
|
264
|
+
forbidden |= forbidden_cells
|
|
265
|
+
for y in range(2, rows - 2):
|
|
266
|
+
for x in range(2, cols - 2):
|
|
267
|
+
if (x, y) in forbidden:
|
|
268
|
+
continue
|
|
269
|
+
if grid[y][x] != ".":
|
|
270
|
+
continue
|
|
271
|
+
if RNG.random() >= density:
|
|
272
|
+
continue
|
|
273
|
+
if (
|
|
274
|
+
grid[y - 1][x] == "1"
|
|
275
|
+
or grid[y + 1][x] == "1"
|
|
276
|
+
or grid[y][x - 1] == "1"
|
|
277
|
+
or grid[y][x + 1] == "1"
|
|
278
|
+
):
|
|
279
|
+
continue
|
|
280
|
+
grid[y][x] = "1"
|
|
281
|
+
|
|
253
282
|
WALL_ALGORITHMS = {
|
|
254
283
|
"default": _place_walls_default,
|
|
255
284
|
"empty": _place_walls_empty,
|
|
256
285
|
"grid_wire": _place_walls_grid_wire,
|
|
257
|
-
"
|
|
286
|
+
"sparse_moore": _place_walls_sparse_moore,
|
|
287
|
+
"sparse_ortho": _place_walls_sparse_ortho,
|
|
258
288
|
}
|
|
259
289
|
|
|
260
290
|
|
|
@@ -321,6 +351,56 @@ def _generate_random_blueprint(
|
|
|
321
351
|
reserved_cells.add((zx, zy))
|
|
322
352
|
|
|
323
353
|
# Select and run the wall placement algorithm (after reserving spawns)
|
|
354
|
+
sparse_density = SPARSE_WALL_DENSITY
|
|
355
|
+
original_wall_algo = wall_algo
|
|
356
|
+
if wall_algo == "sparse":
|
|
357
|
+
print(
|
|
358
|
+
"WARNING: 'sparse' is deprecated. Use 'sparse_moore' instead."
|
|
359
|
+
)
|
|
360
|
+
wall_algo = "sparse_moore"
|
|
361
|
+
elif wall_algo.startswith("sparse."):
|
|
362
|
+
print(
|
|
363
|
+
"WARNING: 'sparse.<int>%' is deprecated. Use "
|
|
364
|
+
"'sparse_moore.<int>%' instead."
|
|
365
|
+
)
|
|
366
|
+
suffix = wall_algo[len("sparse.") :]
|
|
367
|
+
wall_algo = "sparse_moore"
|
|
368
|
+
if suffix.endswith("%") and suffix[:-1].isdigit():
|
|
369
|
+
percent = int(suffix[:-1])
|
|
370
|
+
if 0 <= percent <= 100:
|
|
371
|
+
sparse_density = percent / 100.0
|
|
372
|
+
else:
|
|
373
|
+
print(
|
|
374
|
+
"WARNING: Sparse wall density must be 0-100%. "
|
|
375
|
+
f"Got '{suffix}'. Falling back to default sparse density."
|
|
376
|
+
)
|
|
377
|
+
else:
|
|
378
|
+
print(
|
|
379
|
+
"WARNING: Invalid sparse wall format. Use "
|
|
380
|
+
"'sparse_moore.<int>%' or 'sparse_ortho.<int>%'. "
|
|
381
|
+
f"Got '{original_wall_algo}'. Falling back to default sparse density."
|
|
382
|
+
)
|
|
383
|
+
if wall_algo.startswith("sparse_moore.") or wall_algo.startswith("sparse_ortho."):
|
|
384
|
+
base, suffix = wall_algo.split(".", 1)
|
|
385
|
+
if suffix.endswith("%") and suffix[:-1].isdigit():
|
|
386
|
+
percent = int(suffix[:-1])
|
|
387
|
+
if 0 <= percent <= 100:
|
|
388
|
+
sparse_density = percent / 100.0
|
|
389
|
+
wall_algo = base
|
|
390
|
+
else:
|
|
391
|
+
print(
|
|
392
|
+
"WARNING: Sparse wall density must be 0-100%. "
|
|
393
|
+
f"Got '{suffix}'. Falling back to default sparse density."
|
|
394
|
+
)
|
|
395
|
+
wall_algo = base
|
|
396
|
+
else:
|
|
397
|
+
print(
|
|
398
|
+
"WARNING: Invalid sparse wall format. Use "
|
|
399
|
+
"'sparse_moore.<int>%' or 'sparse_ortho.<int>%'. "
|
|
400
|
+
f"Got '{wall_algo}'. Falling back to default sparse density."
|
|
401
|
+
)
|
|
402
|
+
wall_algo = base
|
|
403
|
+
|
|
324
404
|
if wall_algo not in WALL_ALGORITHMS:
|
|
325
405
|
print(
|
|
326
406
|
f"WARNING: Unknown wall algorithm '{wall_algo}'. Falling back to 'default'."
|
|
@@ -328,7 +408,10 @@ def _generate_random_blueprint(
|
|
|
328
408
|
wall_algo = "default"
|
|
329
409
|
|
|
330
410
|
algo_func = WALL_ALGORITHMS[wall_algo]
|
|
331
|
-
|
|
411
|
+
if wall_algo in {"sparse_moore", "sparse_ortho"}:
|
|
412
|
+
algo_func(grid, density=sparse_density, forbidden_cells=reserved_cells)
|
|
413
|
+
else:
|
|
414
|
+
algo_func(grid, forbidden_cells=reserved_cells)
|
|
332
415
|
|
|
333
416
|
steel_beams = _place_steel_beams(
|
|
334
417
|
grid, chance=steel_chance, forbidden_cells=reserved_cells
|
zombie_escape/models.py
CHANGED
|
@@ -26,10 +26,9 @@ if TYPE_CHECKING: # pragma: no cover - typing-only imports
|
|
|
26
26
|
class LevelLayout:
|
|
27
27
|
"""Container for level layout rectangles and cell sets."""
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
walkable_cells: list[pygame.Rect]
|
|
29
|
+
field_rect: pygame.Rect
|
|
30
|
+
outside_cells: set[tuple[int, int]]
|
|
31
|
+
walkable_cells: list[tuple[int, int]]
|
|
33
32
|
outer_wall_cells: set[tuple[int, int]]
|
|
34
33
|
wall_cells: set[tuple[int, int]]
|
|
35
34
|
fall_spawn_cells: set[tuple[int, int]]
|
|
@@ -106,6 +105,8 @@ class ProgressState:
|
|
|
106
105
|
falling_zombies: list[FallingZombie]
|
|
107
106
|
falling_spawn_carry: int
|
|
108
107
|
dust_rings: list[DustRing]
|
|
108
|
+
player_wall_target_cell: tuple[int, int] | None
|
|
109
|
+
player_wall_target_ttl: int
|
|
109
110
|
|
|
110
111
|
|
|
111
112
|
@dataclass
|
zombie_escape/render.py
CHANGED
|
@@ -807,11 +807,16 @@ def _draw_play_area(
|
|
|
807
807
|
camera: Camera,
|
|
808
808
|
assets: RenderAssets,
|
|
809
809
|
palette: Any,
|
|
810
|
-
|
|
811
|
-
|
|
810
|
+
field_rect: pygame.Rect,
|
|
811
|
+
outside_cells: set[tuple[int, int]],
|
|
812
812
|
fall_spawn_cells: set[tuple[int, int]],
|
|
813
813
|
) -> tuple[int, int, int, int, set[tuple[int, int]]]:
|
|
814
|
-
xs, ys, xe, ye =
|
|
814
|
+
xs, ys, xe, ye = (
|
|
815
|
+
field_rect.left,
|
|
816
|
+
field_rect.top,
|
|
817
|
+
field_rect.right,
|
|
818
|
+
field_rect.bottom,
|
|
819
|
+
)
|
|
815
820
|
xs //= assets.internal_wall_grid_snap
|
|
816
821
|
ys //= assets.internal_wall_grid_snap
|
|
817
822
|
xe //= assets.internal_wall_grid_snap
|
|
@@ -826,15 +831,6 @@ def _draw_play_area(
|
|
|
826
831
|
play_area_screen_rect = camera.apply_rect(play_area_rect)
|
|
827
832
|
pygame.draw.rect(screen, palette.floor_primary, play_area_screen_rect)
|
|
828
833
|
|
|
829
|
-
outside_cells = {
|
|
830
|
-
(r.x // assets.internal_wall_grid_snap, r.y // assets.internal_wall_grid_snap)
|
|
831
|
-
for r in outside_rects
|
|
832
|
-
}
|
|
833
|
-
for rect_obj in outside_rects:
|
|
834
|
-
sr = camera.apply_rect(rect_obj)
|
|
835
|
-
if sr.colliderect(screen.get_rect()):
|
|
836
|
-
pygame.draw.rect(screen, palette.outside, sr)
|
|
837
|
-
|
|
838
834
|
view_world = pygame.Rect(
|
|
839
835
|
-camera.camera.x,
|
|
840
836
|
-camera.camera.y,
|
|
@@ -855,6 +851,19 @@ def _draw_play_area(
|
|
|
855
851
|
for y in range(start_y, end_y):
|
|
856
852
|
for x in range(start_x, end_x):
|
|
857
853
|
if (x, y) in outside_cells:
|
|
854
|
+
lx, ly = (
|
|
855
|
+
x * assets.internal_wall_grid_snap,
|
|
856
|
+
y * assets.internal_wall_grid_snap,
|
|
857
|
+
)
|
|
858
|
+
r = pygame.Rect(
|
|
859
|
+
lx,
|
|
860
|
+
ly,
|
|
861
|
+
assets.internal_wall_grid_snap,
|
|
862
|
+
assets.internal_wall_grid_snap,
|
|
863
|
+
)
|
|
864
|
+
sr = camera.apply_rect(r)
|
|
865
|
+
if sr.colliderect(screen.get_rect()):
|
|
866
|
+
pygame.draw.rect(screen, palette.outside, sr)
|
|
858
867
|
continue
|
|
859
868
|
use_secondary = ((x // 2) + (y // 2)) % 2 == 0
|
|
860
869
|
if (x, y) in fall_spawn_cells:
|
|
@@ -966,11 +975,15 @@ def _draw_entity_shadows(
|
|
|
966
975
|
*,
|
|
967
976
|
light_source_pos: tuple[int, int] | None,
|
|
968
977
|
exclude_car: Car | None,
|
|
978
|
+
outside_cells: set[tuple[int, int]] | None,
|
|
979
|
+
cell_size: int,
|
|
969
980
|
shadow_radius: int = int(ZOMBIE_RADIUS * ENTITY_SHADOW_RADIUS_MULT),
|
|
970
981
|
alpha: int = ENTITY_SHADOW_ALPHA,
|
|
971
982
|
) -> bool:
|
|
972
983
|
if light_source_pos is None or shadow_radius <= 0:
|
|
973
984
|
return False
|
|
985
|
+
if cell_size <= 0:
|
|
986
|
+
outside_cells = None
|
|
974
987
|
shadow_surface = _get_shadow_circle_surface(
|
|
975
988
|
shadow_radius,
|
|
976
989
|
alpha,
|
|
@@ -990,6 +1003,13 @@ def _draw_entity_shadows(
|
|
|
990
1003
|
continue
|
|
991
1004
|
if not isinstance(entity, (Zombie, Survivor, Car)):
|
|
992
1005
|
continue
|
|
1006
|
+
if outside_cells:
|
|
1007
|
+
cell = (
|
|
1008
|
+
int(entity.rect.centerx // cell_size),
|
|
1009
|
+
int(entity.rect.centery // cell_size),
|
|
1010
|
+
)
|
|
1011
|
+
if cell in outside_cells:
|
|
1012
|
+
continue
|
|
993
1013
|
cx, cy = entity.rect.center
|
|
994
1014
|
dx = cx - px
|
|
995
1015
|
dy = cy - py
|
|
@@ -1022,6 +1042,8 @@ def _draw_single_entity_shadow(
|
|
|
1022
1042
|
*,
|
|
1023
1043
|
entity: pygame.sprite.Sprite | None,
|
|
1024
1044
|
light_source_pos: tuple[int, int] | None,
|
|
1045
|
+
outside_cells: set[tuple[int, int]] | None,
|
|
1046
|
+
cell_size: int,
|
|
1025
1047
|
shadow_radius: int,
|
|
1026
1048
|
alpha: int,
|
|
1027
1049
|
edge_softness: float = ENTITY_SHADOW_EDGE_SOFTNESS,
|
|
@@ -1033,6 +1055,13 @@ def _draw_single_entity_shadow(
|
|
|
1033
1055
|
or shadow_radius <= 0
|
|
1034
1056
|
):
|
|
1035
1057
|
return False
|
|
1058
|
+
if outside_cells and cell_size > 0:
|
|
1059
|
+
cell = (
|
|
1060
|
+
int(entity.rect.centerx // cell_size),
|
|
1061
|
+
int(entity.rect.centery // cell_size),
|
|
1062
|
+
)
|
|
1063
|
+
if cell in outside_cells:
|
|
1064
|
+
return False
|
|
1036
1065
|
shadow_surface = _get_shadow_circle_surface(
|
|
1037
1066
|
shadow_radius,
|
|
1038
1067
|
alpha,
|
|
@@ -1464,8 +1493,8 @@ def draw(
|
|
|
1464
1493
|
|
|
1465
1494
|
camera = game_data.camera
|
|
1466
1495
|
stage = game_data.stage
|
|
1467
|
-
|
|
1468
|
-
|
|
1496
|
+
field_rect = game_data.layout.field_rect
|
|
1497
|
+
outside_cells = game_data.layout.outside_cells
|
|
1469
1498
|
all_sprites = game_data.groups.all_sprites
|
|
1470
1499
|
fog_surfaces = game_data.fog
|
|
1471
1500
|
footprints = state.footprints
|
|
@@ -1493,8 +1522,8 @@ def draw(
|
|
|
1493
1522
|
camera,
|
|
1494
1523
|
assets,
|
|
1495
1524
|
palette,
|
|
1496
|
-
|
|
1497
|
-
|
|
1525
|
+
field_rect,
|
|
1526
|
+
outside_cells,
|
|
1498
1527
|
game_data.layout.fall_spawn_cells,
|
|
1499
1528
|
)
|
|
1500
1529
|
shadow_layer = _get_shadow_layer(screen.get_size())
|
|
@@ -1520,6 +1549,8 @@ def draw(
|
|
|
1520
1549
|
all_sprites,
|
|
1521
1550
|
light_source_pos=fov_target.rect.center if fov_target else None,
|
|
1522
1551
|
exclude_car=active_car if player.in_car else None,
|
|
1552
|
+
outside_cells=outside_cells,
|
|
1553
|
+
cell_size=game_data.cell_size,
|
|
1523
1554
|
)
|
|
1524
1555
|
player_shadow_alpha = max(1, int(ENTITY_SHADOW_ALPHA * PLAYER_SHADOW_ALPHA_MULT))
|
|
1525
1556
|
player_shadow_radius = int(ZOMBIE_RADIUS * PLAYER_SHADOW_RADIUS_MULT)
|
|
@@ -1529,6 +1560,8 @@ def draw(
|
|
|
1529
1560
|
camera,
|
|
1530
1561
|
entity=active_car,
|
|
1531
1562
|
light_source_pos=fov_target.rect.center if fov_target else None,
|
|
1563
|
+
outside_cells=outside_cells,
|
|
1564
|
+
cell_size=game_data.cell_size,
|
|
1532
1565
|
shadow_radius=player_shadow_radius,
|
|
1533
1566
|
alpha=player_shadow_alpha,
|
|
1534
1567
|
)
|
|
@@ -1538,6 +1571,8 @@ def draw(
|
|
|
1538
1571
|
camera,
|
|
1539
1572
|
entity=player,
|
|
1540
1573
|
light_source_pos=fov_target.rect.center if fov_target else None,
|
|
1574
|
+
outside_cells=outside_cells,
|
|
1575
|
+
cell_size=game_data.cell_size,
|
|
1541
1576
|
shadow_radius=player_shadow_radius,
|
|
1542
1577
|
alpha=player_shadow_alpha,
|
|
1543
1578
|
)
|