#!/usr/bin/env python3
"""Build original vector site symbols, review PNGs and the game's single atlas.
Requires rsvg-convert and Pillow. Runtime texture import is done in Workbench.
"""
from pathlib import Path
import io
import subprocess
from PIL import Image, ImageDraw, ImageFont
ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / 'art/map-markers'
RUNTIME = ROOT / 'addons/core/UI/Textures/ERR'
VIOLET = '#B277F0'
# All symbols use a 64-unit grid and a generous quiet border for small map sizes.
SYMBOLS = [
('unknown', 'Unknown location', 'mark-question', ''),
('radio', 'Radio station', 'radio', ''),
('extraction', 'Extraction pickup', 'helicopters', ''),
('camp', 'Camp / outpost', 'building', ''),
('supplies', 'Supply depot', 'supplies', ''),
('mortar', 'Mortar position', 'artilleryFireMission', ''),
('hospital', 'Field hospital', 'medical', ''),
('prison', 'Prison', 'prison', ''),
('roadblock', 'Roadblock', 'roadblock', ''),
('factory', 'Industrial site', 'factory', ''),
('minefield', 'Minefield', 'minefield', ''),
('crash', 'Aircraft wreck', 'crash', ''),
]
def svg(symbol):
return f'\n'
def main():
OUT.mkdir(parents=True, exist_ok=True)
RUNTIME.mkdir(parents=True, exist_ok=True)
atlas = Image.new('RGBA', (512, 512))
sheet = Image.new('RGB', (1200, 1050), '#f2f0f5')
draw = ImageDraw.Draw(sheet)
font_path = '/usr/share/fonts/TTF/DejaVuSans.ttf'
title = ImageFont.truetype(font_path, 32)
label = ImageFont.truetype(font_path, 19)
note = ImageFont.truetype(font_path, 16)
draw.text((40, 26), 'CO10 ESCAPE / MAP MARKERS', font=title, fill='#21152f')
draw.text((40, 74), 'Violet circles · black symbols · transparent outside · actual 36 px samples below', font=note, fill='#544662')
definitions = []
for i, (name, caption, image_name, symbol) in enumerate(SYMBOLS):
source = OUT / (name + '.svg')
source.write_text(svg(symbol))
png = subprocess.check_output(['rsvg-convert', str(source)])
(OUT / (name + '.png')).write_bytes(png)
icon = Image.open(io.BytesIO(png)).convert('RGBA')
x, y = i % 4 * 128, i // 4 * 128
atlas.alpha_composite(icon.resize((128, 128), Image.Resampling.LANCZOS), (x, y))
definitions.append(f' ImageSetDefClass "{image_name}" {{\n Pos {x} {y}\n Size 128 128\n Flags 0 0\n }}')
sx, sy = 40 + i % 4 * 290, 135 + i // 4 * 295
sheet.paste(icon.resize((160, 160), Image.Resampling.LANCZOS), (sx + 50, sy), icon.resize((160, 160), Image.Resampling.LANCZOS))
draw.text((sx + 130, sy + 178), caption, font=label, fill='#21152f', anchor='mt')
small = icon.resize((36, 36), Image.Resampling.LANCZOS)
for j, bg in enumerate(('#d5d3b2', '#303b32')):
px = sx + 82 + j * 55
draw.rectangle((px-4, sy+215, px+39, sy+258), fill=bg)
sheet.paste(small, (px, sy + 219), small)
atlas.save(RUNTIME / 'SiteMarkers.png')
sheet.save(OUT / 'preview.png')
(RUNTIME / 'SiteMarkers.imageset').write_text('ImageSetClass {\n RefSize 512 512\n Textures {\n ImageSetTextureClass {\n screenSize FHD\n size 512 512\n path "{ADEE022D9F06C05A}UI/Textures/ERR/SiteMarkers.edds"\n }\n }\n Images {\n' + '\n'.join(definitions) + '\n }\n}\n')
print(OUT / 'preview.png')
if __name__ == '__main__':
main()