Mi2dRPGamEng/engine/placeholder_textures.py

61 lines
2.3 KiB
Python

from __future__ import annotations
from pathlib import Path
from PIL import Image
from engine.defs import DefRegistry
TEXTURE_SIZE = 32
BORDER_SHADE = 0.75
DEPTH_SHADOW_TEXTURE = "tiles/depth_shadow.png"
DEPTH_SHADOW_ALPHA = 90 # out of 255 per stacked copy - see Renderer._draw_depth_shadow
def _checker_image(color: tuple[int, int, int], size: int = TEXTURE_SIZE) -> Image.Image:
img = Image.new("RGBA", (size, size), (*color, 255))
pixels = img.load()
border = max(1, size // 16)
shaded = tuple(int(c * BORDER_SHADE) for c in color)
for y in range(size):
for x in range(size):
if x < border or y < border or x >= size - border or y >= size - border:
pixels[x, y] = (*shaded, 255)
return img
def _ensure_texture(textures_dir: Path, relative_path: str, color: tuple[int, int, int]) -> None:
path = textures_dir / relative_path
if path.exists():
return
path.parent.mkdir(parents=True, exist_ok=True)
_checker_image(color).save(path)
def generate_placeholder_textures(registry: DefRegistry, textures_dir: Path) -> None:
"""Writes a flat-color/checker PNG for every def with a texture path, if missing."""
for layer_def in registry.tile_layer_defs.values():
if layer_def.texture:
_ensure_texture(textures_dir, layer_def.texture, layer_def.color)
for item_def in registry.item_defs.values():
if item_def.texture:
_ensure_texture(textures_dir, item_def.texture, item_def.color)
for part_def in registry.body_part_defs.values():
if part_def.texture:
_ensure_texture(textures_dir, part_def.texture, part_def.color)
def generate_depth_shadow_texture(textures_dir: Path) -> None:
"""A flat black, partially-transparent overlay - Renderer stacks 1+ copies of it on a tile
to darken it proportionally to how far below the camera's reference z-level it sits (see
Renderer._draw_depth_shadow), Dwarf-Fortress-style depth shading. Not keyed to any def
(it's a rendering-only overlay, not game data) but generated the same "only if missing"
way as generate_placeholder_textures.
"""
path = textures_dir / DEPTH_SHADOW_TEXTURE
if path.exists():
return
path.parent.mkdir(parents=True, exist_ok=True)
Image.new("RGBA", (TEXTURE_SIZE, TEXTURE_SIZE), (0, 0, 0, DEPTH_SHADOW_ALPHA)).save(path)