summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/make-jiangnan-art.py77
1 files changed, 75 insertions, 2 deletions
diff --git a/scripts/make-jiangnan-art.py b/scripts/make-jiangnan-art.py
index 2e1dee0..9abb4b8 100644
--- a/scripts/make-jiangnan-art.py
+++ b/scripts/make-jiangnan-art.py
@@ -99,7 +99,7 @@ def verify_png(path, expected_w, expected_h):
def build_world_atlas():
- c = Canvas(800, 32)
+ c = Canvas(896, 32)
tile = 32
def slot(index):
@@ -474,6 +474,79 @@ def build_world_atlas():
puff(x0 + 15, 6, 5, 4, smoke_mid)
puff(x0 + 18, 2, 3, 2, smoke_faint)
+ # --- Street-side Chinese details (P17): stone lantern, water vat, market stall.
+ # Baked into the atlas exactly like every other tile; the game only blits these
+ # cells and never builds the shapes procedurally.
+
+ # slot(25) 石灯笼 (stone lantern): pedestal, shaft, lit chamber, flared cap + finial.
+ warm_lamp = (238, 200, 128, 255)
+ x0 = slot(25)
+ c.rect(x0 + 10, 26, 12, 4, stone)
+ c.rect(x0 + 10, 26, 12, 1, stone_light)
+ c.rect(x0 + 10, 29, 12, 1, stone_dark)
+ c.rect(x0 + 14, 18, 4, 8, stone)
+ c.rect(x0 + 14, 18, 1, 8, stone_light)
+ c.rect(x0 + 18, 18, 1, 8, stone_dark)
+ c.rect(x0 + 11, 12, 10, 7, stone)
+ c.rect(x0 + 11, 12, 10, 1, stone_light)
+ c.rect(x0 + 13, 14, 6, 4, warm_lamp)
+ c.set(x0 + 14, 15, (252, 232, 176, 255))
+ c.rect(x0 + 9, 9, 14, 3, stone)
+ c.rect(x0 + 9, 9, 14, 1, stone_light)
+ c.rect(x0 + 6, 8, 20, 1, stone_dark)
+ c.rect(x0 + 15, 5, 2, 3, stone)
+ c.set(x0 + 16, 4, stone_light)
+ c.outline(x0, 0, 32, 32)
+
+ # slot(26) 水缸 (water vat): barrel body with iron hoops, stone rim, still water.
+ vat = (96, 112, 106, 255)
+ vat_light = (134, 148, 140, 255)
+ vat_dark = (66, 78, 74, 255)
+ vat_water = (74, 122, 152, 255)
+ vat_water_hi = (150, 192, 208, 255)
+ x0 = slot(26)
+ c.rect(x0 + 6, 14, 20, 15, vat)
+ c.rect(x0 + 6, 14, 20, 1, vat_light)
+ c.rect(x0 + 6, 28, 20, 1, vat_dark)
+ for hoop_y in (18, 22, 26):
+ c.rect(x0 + 6, hoop_y, 20, 1, vat_dark)
+ for side_x in (4, 27):
+ c.rect(x0 + side_x, 17, 2, 10, vat)
+ c.rect(x0 + side_x, 17, 1, 10, vat_light)
+ c.rect(x0 + 8, 30, 16, 1, (52, 62, 58, 255))
+ c.rect(x0 + 4, 12, 24, 3, vat_light)
+ c.rect(x0 + 6, 14, 20, 2, vat_water)
+ c.rect(x0 + 9, 14, 8, 1, vat_water_hi)
+ c.set(x0 + 20, 14, vat_water_hi)
+ c.outline(x0, 0, 32, 32)
+
+ # slot(27) 摊贩摊位 (market stall): wood frame, striped awning, counter, wares.
+ awning_cloth = (196, 92, 74, 255)
+ awning_cream = (238, 222, 196, 255)
+ crate = (140, 96, 52, 255)
+ x0 = slot(27)
+ c.rect(x0 + 5, 8, 2, 22, wood)
+ c.rect(x0 + 25, 8, 2, 22, wood)
+ c.rect(x0 + 5, 8, 1, 22, wood_light)
+ c.rect(x0 + 25, 8, 1, 22, wood_light)
+ for i in range(0, 32, 8):
+ c.rect(x0 + i, 6, 8, 6, awning_cloth if (i // 8) % 2 == 0 else awning_cream)
+ c.rect(x0, 6, 32, 1, (150, 66, 54, 255))
+ c.rect(x0, 11, 32, 1, (120, 52, 44, 255))
+ c.rect(x0 + 3, 20, 26, 3, wood)
+ c.rect(x0 + 3, 20, 26, 1, wood_light)
+ c.rect(x0 + 3, 22, 26, 1, wood_dark)
+ c.rect(x0 + 7, 16, 7, 4, crate)
+ c.rect(x0 + 7, 16, 7, 1, (176, 128, 74, 255))
+ c.rect(x0 + 17, 16, 7, 4, crate)
+ c.rect(x0 + 17, 16, 7, 1, (176, 128, 74, 255))
+ for gx in (9, 12, 19, 22):
+ c.set(x0 + gx, 15, (86, 139, 68, 255))
+ c.set(x0 + 13, 15, (196, 92, 96, 255))
+ c.set(x0 + 20, 15, (222, 188, 92, 255))
+ c.rect(x0 + 3, 23, 26, 6, (83, 52, 39, 255))
+ c.outline(x0, 0, 32, 32)
+
return c
@@ -811,7 +884,7 @@ def build_interior_atlas():
def main():
ASSET_DIR.mkdir(parents=True, exist_ok=True)
targets = [
- ("jiangnan-world.png", build_world_atlas(), 800, 32),
+ ("jiangnan-world.png", build_world_atlas(), 896, 32),
("jiangnan-characters.png", build_character_atlas(), 3840, 48),
("jiangnan-interior.png", build_interior_atlas(), 392, 96),
]