Files
wuwiandClaude Opus 5 14a1e5d261 Let the tour be a choice, and give her a body of her own
The court screen picks WHO as well as WHERE now: two tiles above the court
rows, men's or women's singles, remembered like the court is. No new stage —
three rows and a pair of buttons already fill a phone, so the tiles go side by
side and the tap count from splash to play does not change.

Everything downstream is one line: drawChar already built every frame name off
a single prefix, so SK() appends '_f' when the women's tour is picked and falls
straight through to the men's frame for anything without a twin. The horde, the
officials and the ball boys are shared — they are staff, not the draw — but the
turned CPU is not: a male corpse opposite a female player reads as a bug.

Her frames came back as a different woman in every batch — blonde in one,
auburn in the next, greyscale line art in a third — because each was anchored on
the MAN whose pose it was. "newart" repaints the character and "state" is welded
to the corpse palette, so neither could say "the same living woman, a new pose".
That mode now exists, and every batch anchors on her own settled frame.

The death is drawn to frame 3 and recoloured after it. The generator will not
draw a dead woman in any wording worth using; frames 4 and 5 survive that
because by then she is flat and then a heap of cloth, so they are the men's
drawing with the blue shorts painted into her white (see assets/_die_f.py). The
collapse still falls 224/159/117/103/43 straight through the handoff.

Her first bounce frames reached to the shoulder, which is a catching pose, not
patting a ball — redrawn low rather than bending BOUNCE_IDLE to fit a wrong
drawing, so both tours share one apex and the ball meets her palm.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 12:22:21 +02:00

33 lines
1.8 KiB
Python

# 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)')