class_name PixelPeople extends RefCounted ## Authored side-view poses on a 16x18 grid. No neighbouring atlas characters ## are used as animation frames. All motion is presentation-only. const COATS := [Color("688da0"), Color("b87659"), Color("a69a63"), Color("89789e"), Color("638d72")] const SKINS := [Color("edc49d"), Color("c99371"), Color("a56f50")] const INK := Color("303c40") static func pose(mode: StringName, frame: int, variant: int, staff: bool) -> Array[Dictionary]: var marks: Array[Dictionary] = [] var skin: Color = SKINS[posmod(variant, SKINS.size())] var coat: Color = Color("719d94") if staff else COATS[posmod(variant, COATS.size())] var phase := posmod(frame, 8) var walk := mode == &"walk" or mode == &"carry_walk" var work := mode in [&"work", &"clean", &"eat"] var stride := [0, 1, 2, 1, 0, -1, -2, -1][phase] as int var bob := -1 if walk and phase in [2, 6] else 0 if mode == &"standard_room_sleep": # General-room presentation only: same16x18 actor grid and original skin. # Breathing follows existing visual frame; no Clock, guest or service change. var breathing := -1 if phase in [2, 3, 4] else 0 mark(marks, Rect2(2, 14, 13, 2), INK) mark(marks, Rect2(2, 11, 5, 4), Color("eee5c9")) mark(marks, Rect2(3, 12, 4, 3), skin) mark(marks, Rect2(2, 12, 2, 3), INK) mark(marks, Rect2(5, 13, 2, 1), INK) mark(marks, Rect2(7, 11 + breathing, 8, 5 - breathing), INK) mark(marks, Rect2(8, 12 + breathing, 6, 3 - breathing), Color("608d84")) mark(marks, Rect2(8, 12 + breathing, 6, 1), Color("eee5c9")) mark(marks, Rect2(9, 14 + breathing, 4, 1), Color("719d94")) mark(marks, Rect2(6, 13 + breathing, 2, 1), skin) mark(marks, Rect2(14, 14, 1, 2), INK) return marks if mode in [&"sleep", &"collapsed"]: mark(marks, Rect2(2, 14, 12, 2), INK) mark(marks, Rect2(3, 12, 4, 3), skin) mark(marks, Rect2(2, 12, 2, 3), INK) mark(marks, Rect2(7, 12, 6, 3), coat) mark(marks, Rect2(13, 13, 2, 2), INK) if mode == &"sleep": mark(marks, Rect2(3 + phase / 3, 8 - phase / 3, 2, 1), Color("eee6c7")) return marks # Far arm and leg, then silhouette, face, near arm and leg. mark(marks, Rect2(6, 8 + bob, 2, 5), coat.darkened(0.25)) var far := -stride if walk else 0 var near := stride if walk else 0 mark(marks, Rect2(7 + far, 12 + bob, 2, 4 - bob), INK.lightened(0.12)) mark(marks, Rect2(7 + far, 16, 3, 1), INK) mark(marks, Rect2(6, 6 + bob, 5, 7), INK) mark(marks, Rect2(7, 7 + bob, 4, 5), coat) mark(marks, Rect2(7, 1 + bob, 4, 5), skin) mark(marks, Rect2(6, 1 + bob, 4, 2), INK) mark(marks, Rect2(6, 3 + bob, 1, 2), INK) mark(marks, Rect2(11, 3 + bob, 1, 2), skin) mark(marks, Rect2(10, 3 + bob, 1, 1), INK) mark(marks, Rect2(8, 6 + bob, 2, 1), skin) mark(marks, Rect2(8 + near, 12 + bob, 2, 4 - bob), INK) mark(marks, Rect2(8 + near, 16, 3, 1), INK) var arm := -stride if walk else 0 if work: arm = 2 if phase < 4 else 1 mark(marks, Rect2(9 + arm, 8 + bob, 2, 3), coat.lightened(0.12)) mark(marks, Rect2(9 + arm, 11 + bob, 2, 1), skin) if staff: mark(marks, Rect2(7, 9 + bob, 2, 3), Color("e3dfc2")) if mode in [&"carry", &"carry_walk"]: mark(marks, Rect2(10, 8 + bob, 5, 5), Color("956940")) mark(marks, Rect2(10, 8 + bob, 5, 1), Color("d3ad6b")) mark(marks, Rect2(12, 9 + bob, 1, 4), Color("b48850")) elif mode == &"clean": mark(marks, Rect2(11 + arm, 9, 1, 7), Color("af9059")) mark(marks, Rect2(9 + arm, 16, 5, 1), Color("d8bc78")) elif mode == &"eat": mark(marks, Rect2(11, 6 if phase < 4 else 10, 3, 2), Color("f3ebcf")) elif mode == &"work": mark(marks, Rect2(11, 12, 4, 1), Color("efe7ce")) mark(marks, Rect2(12 + phase % 2, 10, 1, 2), Color("805e44")) elif mode == &"wait": mark(marks, Rect2(9, 9, 3, 1), skin) return marks static func mark(marks: Array[Dictionary], rect: Rect2, color: Color) -> void: marks.append({&"rect": rect, &"color": color}) static func draw(canvas: CanvasItem, origin: Vector2, pixel: float, mode: StringName, frame: int, variant: int, staff: bool, facing_left: bool) -> void: for item: Dictionary in pose(mode, frame, variant, staff): var rect: Rect2 = item[&"rect"] if facing_left: rect.position.x = 16 - rect.end.x canvas.draw_rect(Rect2(origin + rect.position * pixel, rect.size * pixel), item[&"color"])