KAZIK/tools/generators/pack_clover_assets.py
Artvasil09 881a0061dc Add native NPC visitors with contracts, Clover slots, Pyramid, and party table scenes
Implement 32x32 BFS visitor navigation and daily contracts system with companion .npc journals; add native assembly scenes for Clover slots, Pyramid cards, Blackjack Party and Russian Party; package animation and sprite packs; add comprehensive offline test suites and rebuild shipping binaries.
2026-10-13 09:47:33 +03:00

48 lines
2 KiB
Python

"""Offline normalization of generated art; the game animates reels in MASM."""
import json
import struct
from pathlib import Path
from PIL import Image
ROOT = Path(__file__).resolve().parents[2]
SOURCE = ROOT / "assets/sprites/clover"
OUTPUT = ROOT / "assets/animations/clover"
def pack(name, frames):
width, height = frames[0].size
pixels = b"".join(frame.tobytes("raw", "BGRA") for frame in frames)
(OUTPUT / name).write_bytes(struct.pack("<4s4I", b"ANM1", width, height,
len(frames), len(pixels)) + pixels)
def main():
OUTPUT.mkdir(parents=True, exist_ok=True)
cabinet = Image.open(SOURCE / "cabinet-v1.png").convert("RGBA")
cabinet = cabinet.resize((640, 480), Image.Resampling.NEAREST)
cabinet.putalpha(255)
pack("cabinet-v1.bin", [cabinet])
sheet = Image.open(SOURCE / "symbols-v1.png").convert("RGBA")
assert 1.8 < sheet.width / sheet.height < 2.2
frames = []
for index in range(7):
column, row = index % 4, index // 4
cell = sheet.crop((round(column * sheet.width / 4), round(row * sheet.height / 2),
round((column + 1) * sheet.width / 4), round((row + 1) * sheet.height / 2)))
bounds = cell.getchannel("A").getbbox()
assert bounds, f"Empty symbol {index}"
cell = cell.crop(bounds)
cell.thumbnail((46, 46), Image.Resampling.NEAREST)
frame = Image.new("RGBA", (56, 56))
frame.paste(cell, ((56 - cell.width) // 2, (56 - cell.height) // 2))
frame.putalpha(frame.getchannel("A").point(lambda value: 255 if value >= 128 else 0))
frames.append(frame)
pack("symbols-v1.bin", frames)
(OUTPUT / "manifest.json").write_text(json.dumps({"symbols": ["clover", "lemon", "cherries",
"bell", "diamond", "chest", "seven"], "cabinet": [640, 480], "symbol": [56, 56],
"runtime": "MASM; five reels, three complete rows, legacy additive combos"}, indent=2) + "\n")
print("Packed Clover 5x3 cabinet and seven alpha-tested symbols")
if __name__ == "__main__":
main()