# p_die4_f.png / p_die5_f.png — the only two sprites in the game that are DERIVED, not drawn. # # python3 assets/_die_f.py # # The women's tour has its own death frames 1-3 (batch player_f_fall). Frames 4 and 5 have no batch: # the image generator refuses to draw a dead woman, in every wording worth trying, and rephrasing # until it complies is not something to automate. It does not matter much — by frame 4 she is flat # and face down and by frame 5 she is a heap of torn cloth — so those two are the MEN'S drawing. # The one thing you could actually see was the men's BLUE SHORTS popping in after three frames of # white skirt, so this repaints the shorts into her kit's white and changes nothing else. # # Re-run this whenever player_death is regenerated, or her last two frames go stale. import os import numpy as np from PIL import Image HERE = os.path.dirname(os.path.abspath(__file__)) for n in ('p_die4', 'p_die5'): a = np.asarray(Image.open(os.path.join(HERE, n + '.png')).convert('RGBA')).astype(np.int16) r, g, b, al = a[..., 0], a[..., 1], a[..., 2], a[..., 3] blue = (b > r + 25) & (b > g + 15) & (al > 40) if not blue.sum(): print(f'{n}: no blue to repaint'); continue # keep the shading ORDER — the darkest short pixel stays the darkest — and move the whole ramp # onto her skirt's range, so the fold shading survives instead of flattening to one white lum = (r * 0.3 + g * 0.59 + b * 0.11)[blue] t = (lum - lum.min()) / max(1, lum.max() - lum.min()) out = a.copy() for c, (dark, light) in enumerate(((150, 246), (156, 248), (168, 252))): out[..., c][blue] = (dark + t * (light - dark)).astype(np.int16) Image.fromarray(out.astype(np.uint8), 'RGBA').save(os.path.join(HERE, n + '_f.png')) print(f'{n}_f.png written ({int(blue.sum())} px repainted)')