diff --git a/.DS_Store b/.DS_Store index 29681f836..478583634 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/DEVLOG.md b/DEVLOG.md index 19233c48a..2a7d835d2 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -38,3 +38,61 @@ The "Probna Farma" scene is now a fully interactive, atmospheric prototype ready --- *Signed: Antigravity Agent* + +# DEVLOG - 2026-01-28 + +**Time**: 07:44:02 +**Session Goal**: Asset Generation, Clean Slate, UI & Camp Setup. + +## Achievements + +### 1. Scene Reset +- Cleaned to a minimal robust state (Z-0 Ground + Player only). +- Verified , structure for Defold integration. + +### 2. AI Asset Generation (Survival Style) +- Generated fresh, unified assets based on user references: + - **Campfire**: Simple stone ring, minimalist. + - **Tent**: Blue dome, survival/worn aesthetic. + - **Sleeping Bag**: Brown/patched survival gear. + - **UI**: Health Bar (Rust+Liquid), Inventory Slot (Wood), Action Button, Dialog Panel. + +### 3. Automated Processing Pipeline +- Created scripts to detect, crop, remove magenta background, and deploy generated assets. +- Synced assets to multiple locations for compatibility: + - + - & + - + +## Next Steps +- Finalize Health Bar design (Face icons vs Liquid). +- Implement Camp and UI into the new Defold . + +# DEVLOG - 2026-01-28 + +**Time**: 07:44:02 +**Session Goal**: Asset Generation, Clean Slate, UI & Camp Setup. + +## Achievements + +### 1. Scene Reset +- Cleaned `GrassScene_Clean.js` to a minimal robust state (Z-0 Ground + Player only). +- Verified `main.atlas`, `main.collection` structure for Defold integration. + +### 2. AI Asset Generation (Survival Style) +- Generated fresh, unified assets based on user references: + - **Campfire**: Simple stone ring, minimalist. + - **Tent**: Blue dome, survival/worn aesthetic. + - **Sleeping Bag**: Brown/patched survival gear. + - **UI**: Health Bar (Rust+Liquid), Inventory Slot (Wood), Action Button, Dialog Panel. + +### 3. Automated Processing Pipeline +- Created scripts to detect, crop, remove magenta background, and deploy generated assets. +- Synced assets to multiple locations for compatibility: + - `repos/novafarma/main/assets` + - `repos/novafarma/assets/DEMO_FAZA1/Environment` & `UI` + - `nova farma/main/assets` + +## Next Steps +- Finalize Health Bar design (Face icons vs Liquid). +- Implement Camp and UI into the new Defold `main.collection`. diff --git a/assets/.DS_Store b/assets/.DS_Store index d763ed37a..ec37848cf 100644 Binary files a/assets/.DS_Store and b/assets/.DS_Store differ diff --git a/assets/DEMO_FAZA1/.DS_Store b/assets/DEMO_FAZA1/.DS_Store index af754275a..7fc781082 100644 Binary files a/assets/DEMO_FAZA1/.DS_Store and b/assets/DEMO_FAZA1/.DS_Store differ diff --git a/assets/DEMO_FAZA1/Environment/mud_puddle.png b/assets/DEMO_FAZA1/Environment/mud_puddle.png index 0c0b9fabd..e9582a4b1 100644 Binary files a/assets/DEMO_FAZA1/Environment/mud_puddle.png and b/assets/DEMO_FAZA1/Environment/mud_puddle.png differ diff --git a/assets/DEMO_FAZA1/Environment/obstacle_thorns.png b/assets/DEMO_FAZA1/Environment/obstacle_thorns.png index 1a804326a..8b0325ab3 100644 Binary files a/assets/DEMO_FAZA1/Environment/obstacle_thorns.png and b/assets/DEMO_FAZA1/Environment/obstacle_thorns.png differ diff --git a/assets/DEMO_FAZA1/Environment/sign_danger.png b/assets/DEMO_FAZA1/Environment/sign_danger.png index eb6259a54..5196f37d7 100644 Binary files a/assets/DEMO_FAZA1/Environment/sign_danger.png and b/assets/DEMO_FAZA1/Environment/sign_danger.png differ diff --git a/assets/DEMO_FAZA1/Environment/sotor.png b/assets/DEMO_FAZA1/Environment/sotor.png new file mode 100644 index 000000000..6d5d4cff8 Binary files /dev/null and b/assets/DEMO_FAZA1/Environment/sotor.png differ diff --git a/assets/DEMO_FAZA1/Environment/stream_water.png b/assets/DEMO_FAZA1/Environment/stream_water.png index 26f0e84d9..fa44ce3c0 100644 Binary files a/assets/DEMO_FAZA1/Environment/stream_water.png and b/assets/DEMO_FAZA1/Environment/stream_water.png differ diff --git a/assets/DEMO_FAZA1/Environment/taborni_ogenj.png b/assets/DEMO_FAZA1/Environment/taborni_ogenj.png new file mode 100644 index 000000000..1d1a7f6f0 Binary files /dev/null and b/assets/DEMO_FAZA1/Environment/taborni_ogenj.png differ diff --git a/assets/DEMO_FAZA1/Environment/water_clean_patch.png b/assets/DEMO_FAZA1/Environment/water_clean_patch.png index 6854b55ea..3bc744831 100644 Binary files a/assets/DEMO_FAZA1/Environment/water_clean_patch.png and b/assets/DEMO_FAZA1/Environment/water_clean_patch.png differ diff --git a/assets/DEMO_FAZA1/Ground/ground_dirt_patch.png b/assets/DEMO_FAZA1/Ground/ground_dirt_patch.png index 0eb265c33..a4e64c1e2 100644 Binary files a/assets/DEMO_FAZA1/Ground/ground_dirt_patch.png and b/assets/DEMO_FAZA1/Ground/ground_dirt_patch.png differ diff --git a/assets/DEMO_FAZA1/Ground/ground_pebbles.png b/assets/DEMO_FAZA1/Ground/ground_pebbles.png index 79912f93f..490de2b3c 100644 Binary files a/assets/DEMO_FAZA1/Ground/ground_pebbles.png and b/assets/DEMO_FAZA1/Ground/ground_pebbles.png differ diff --git a/assets/DEMO_FAZA1/Ground/tla_trava_tekstura.png b/assets/DEMO_FAZA1/Ground/tla_trava_tekstura.png index 9d6f51356..881c1abc4 100644 Binary files a/assets/DEMO_FAZA1/Ground/tla_trava_tekstura.png and b/assets/DEMO_FAZA1/Ground/tla_trava_tekstura.png differ diff --git a/assets/DEMO_FAZA1/Items/spalna_vreca.png b/assets/DEMO_FAZA1/Items/spalna_vreca.png new file mode 100644 index 000000000..5ff783744 Binary files /dev/null and b/assets/DEMO_FAZA1/Items/spalna_vreca.png differ diff --git a/assets/DEMO_FAZA1/UI/action_btn.png b/assets/DEMO_FAZA1/UI/action_btn.png new file mode 100644 index 000000000..c0e47e574 Binary files /dev/null and b/assets/DEMO_FAZA1/UI/action_btn.png differ diff --git a/assets/DEMO_FAZA1/UI/dialog_panel.png b/assets/DEMO_FAZA1/UI/dialog_panel.png new file mode 100644 index 000000000..4a2fad6be Binary files /dev/null and b/assets/DEMO_FAZA1/UI/dialog_panel.png differ diff --git a/assets/DEMO_FAZA1/UI/health_bar.png b/assets/DEMO_FAZA1/UI/health_bar.png new file mode 100644 index 000000000..75952cbb9 Binary files /dev/null and b/assets/DEMO_FAZA1/UI/health_bar.png differ diff --git a/assets/DEMO_FAZA1/UI/inventory_slot.png b/assets/DEMO_FAZA1/UI/inventory_slot.png new file mode 100644 index 000000000..b7d934e4a Binary files /dev/null and b/assets/DEMO_FAZA1/UI/inventory_slot.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/bush_hiding_spot.png b/assets/DEMO_FAZA1/Vegetation/bush_hiding_spot.png index 780a8044d..92f258217 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/bush_hiding_spot.png and b/assets/DEMO_FAZA1/Vegetation/bush_hiding_spot.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/drevo_faza_1.png b/assets/DEMO_FAZA1/Vegetation/drevo_faza_1.png index 683a4dcbd..409388359 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/drevo_faza_1.png and b/assets/DEMO_FAZA1/Vegetation/drevo_faza_1.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/drevo_faza_2.png b/assets/DEMO_FAZA1/Vegetation/drevo_faza_2.png index 1b69fd1ba..36cdf8994 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/drevo_faza_2.png and b/assets/DEMO_FAZA1/Vegetation/drevo_faza_2.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/drevo_majhno.png b/assets/DEMO_FAZA1/Vegetation/drevo_majhno.png index 655bcda57..f7ae5f610 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/drevo_majhno.png and b/assets/DEMO_FAZA1/Vegetation/drevo_majhno.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/drevo_srednje.png b/assets/DEMO_FAZA1/Vegetation/drevo_srednje.png index 243a90f6c..b5e23c492 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/drevo_srednje.png and b/assets/DEMO_FAZA1/Vegetation/drevo_srednje.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/drevo_veliko.png b/assets/DEMO_FAZA1/Vegetation/drevo_veliko.png index e8c092e75..c2dd21a04 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/drevo_veliko.png and b/assets/DEMO_FAZA1/Vegetation/drevo_veliko.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/grass_cluster_dense.png b/assets/DEMO_FAZA1/Vegetation/grass_cluster_dense.png index c2fd14c80..ea745efe6 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/grass_cluster_dense.png and b/assets/DEMO_FAZA1/Vegetation/grass_cluster_dense.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/grass_cluster_flowery.png b/assets/DEMO_FAZA1/Vegetation/grass_cluster_flowery.png index bbca31c97..2d2520d32 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/grass_cluster_flowery.png and b/assets/DEMO_FAZA1/Vegetation/grass_cluster_flowery.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/trava_sop.png b/assets/DEMO_FAZA1/Vegetation/trava_sop.png index 5424f3305..5bf4562bd 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/trava_sop.png and b/assets/DEMO_FAZA1/Vegetation/trava_sop.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/visoka_trava.png b/assets/DEMO_FAZA1/Vegetation/visoka_trava.png index c691fe14f..d59d33b41 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/visoka_trava.png and b/assets/DEMO_FAZA1/Vegetation/visoka_trava.png differ diff --git a/assets/DEMO_FAZA1/Vegetation/visoka_trava_v2.png b/assets/DEMO_FAZA1/Vegetation/visoka_trava_v2.png index 85c1ef5df..480960242 100644 Binary files a/assets/DEMO_FAZA1/Vegetation/visoka_trava_v2.png and b/assets/DEMO_FAZA1/Vegetation/visoka_trava_v2.png differ diff --git a/assets/environment/stream_reference.png b/assets/environment/stream_reference.png new file mode 100644 index 000000000..338296bc0 Binary files /dev/null and b/assets/environment/stream_reference.png differ diff --git a/assets/items/campfire.png b/assets/items/campfire.png deleted file mode 100644 index e2d51b7ba..000000000 Binary files a/assets/items/campfire.png and /dev/null differ diff --git a/assets/items/sleeping_bag.png b/assets/items/sleeping_bag.png deleted file mode 100644 index 0a4dae288..000000000 Binary files a/assets/items/sleeping_bag.png and /dev/null differ diff --git a/assets/vegetation/ugly_grass_ref.png b/assets/vegetation/ugly_grass_ref.png new file mode 100644 index 000000000..a48702e9e Binary files /dev/null and b/assets/vegetation/ugly_grass_ref.png differ diff --git a/game.project b/game.project new file mode 100644 index 000000000..befcd0fb2 --- /dev/null +++ b/game.project @@ -0,0 +1,5 @@ +Title: Nova Farma +Version: 1.0 +[bootstrap] +main_collection = /main/main.collection + diff --git a/ground.tilesource b/ground.tilesource new file mode 100644 index 000000000..ec25c84f4 --- /dev/null +++ b/ground.tilesource @@ -0,0 +1,7 @@ +image: "/main/assets/ground_tileset.png" +tile_width: 256 +tile_height: 256 +tile_margin: 0 +tile_spacing: 0 +collision: "" +material_tag: "tile" diff --git a/main.atlas b/main.atlas new file mode 100644 index 000000000..a3c080bcb --- /dev/null +++ b/main.atlas @@ -0,0 +1,11 @@ +images { + image: "/main/assets/tla_trava_tekstura.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/main/assets/stream_water.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +margin: 0 +extrude_borders: 2 +inner_padding: 0 diff --git a/main/assets/action_btn.png b/main/assets/action_btn.png new file mode 100644 index 000000000..c0e47e574 Binary files /dev/null and b/main/assets/action_btn.png differ diff --git a/main/assets/campfire.png b/main/assets/campfire.png new file mode 100644 index 000000000..1d1a7f6f0 Binary files /dev/null and b/main/assets/campfire.png differ diff --git a/main/assets/dialog_panel.png b/main/assets/dialog_panel.png new file mode 100644 index 000000000..4a2fad6be Binary files /dev/null and b/main/assets/dialog_panel.png differ diff --git a/main/assets/ground_tileset.png b/main/assets/ground_tileset.png new file mode 100644 index 000000000..68eb7cee1 Binary files /dev/null and b/main/assets/ground_tileset.png differ diff --git a/main/assets/ground_tileset.tsx b/main/assets/ground_tileset.tsx new file mode 100644 index 000000000..8c7973b7d --- /dev/null +++ b/main/assets/ground_tileset.tsx @@ -0,0 +1,4 @@ + + + + diff --git a/main/assets/health_bar.png b/main/assets/health_bar.png new file mode 100644 index 000000000..75952cbb9 Binary files /dev/null and b/main/assets/health_bar.png differ diff --git a/main/assets/inventory_slot.png b/main/assets/inventory_slot.png new file mode 100644 index 000000000..b7d934e4a Binary files /dev/null and b/main/assets/inventory_slot.png differ diff --git a/main/assets/sleeping_bag.png b/main/assets/sleeping_bag.png new file mode 100644 index 000000000..5ff783744 Binary files /dev/null and b/main/assets/sleeping_bag.png differ diff --git a/main/assets/stream_water.png b/main/assets/stream_water.png new file mode 100644 index 000000000..fa44ce3c0 Binary files /dev/null and b/main/assets/stream_water.png differ diff --git a/main/assets/tent.png b/main/assets/tent.png new file mode 100644 index 000000000..6d5d4cff8 Binary files /dev/null and b/main/assets/tent.png differ diff --git a/main/assets/tla_trava_tekstura.png b/main/assets/tla_trava_tekstura.png new file mode 100644 index 000000000..881c1abc4 Binary files /dev/null and b/main/assets/tla_trava_tekstura.png differ diff --git a/main/ground.go b/main/ground.go new file mode 100644 index 000000000..059f945e9 --- /dev/null +++ b/main/ground.go @@ -0,0 +1,15 @@ +components { + id: "tilemap" + component: "/main/ground.tilemap" + position { + x: 0.0 + y: 0.0 + z: 0.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } +} diff --git a/main/ground.tilemap b/main/ground.tilemap new file mode 100644 index 000000000..8780b6eed --- /dev/null +++ b/main/ground.tilemap @@ -0,0 +1,4208 @@ +tile_set: "/main/ground.tilesource" +layers { + id: "ground" + z: 0.0 + is_visible: 1 + cell { + x: 0 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 1 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 7 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 10 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 11 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 12 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 0 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 2 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 4 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 6 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 7 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 10 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 11 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 16 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 1 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 11 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 16 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 17 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 2 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 5 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 11 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 3 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 5 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 13 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 4 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 1 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 13 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 5 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 13 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 6 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 2 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 7 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 13 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 15 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 7 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 0 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 13 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 18 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 8 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 7 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 13 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 9 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 2 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 13 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 10 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 13 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 17 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 18 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 11 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 5 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 13 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 18 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 12 + y: 19 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 5 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 11 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 13 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 13 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 1 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 11 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 12 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 14 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 2 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 9 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 10 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 11 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 14 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 15 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 10 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 11 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 17 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 16 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 9 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 10 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 11 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 17 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 4 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 10 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 17 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 18 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 8 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 10 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 19 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 8 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 11 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 20 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 0 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 2 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 8 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 21 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 8 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 22 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 6 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 8 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 12 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 23 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 2 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 8 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 13 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 24 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 7 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 8 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 25 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 8 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 26 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 8 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 10 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 12 + tile: 3 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 27 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 10 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 11 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 12 + tile: 2 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 28 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 0 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 1 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 2 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 3 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 4 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 5 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 6 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 7 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 8 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 9 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 10 + tile: 1 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 11 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 12 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 13 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 14 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 15 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 16 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 17 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 18 + tile: 0 + h_flip: 0 + v_flip: 0 + } + cell { + x: 29 + y: 19 + tile: 0 + h_flip: 0 + v_flip: 0 + } +} +material: "/builtins/materials/tile_map.material" +blend_mode: BLEND_MODE_ALPHA diff --git a/main/ground.tilesource b/main/ground.tilesource new file mode 100644 index 000000000..ec25c84f4 --- /dev/null +++ b/main/ground.tilesource @@ -0,0 +1,7 @@ +image: "/main/assets/ground_tileset.png" +tile_width: 256 +tile_height: 256 +tile_margin: 0 +tile_spacing: 0 +collision: "" +material_tag: "tile" diff --git a/main/level1.tmx b/main/level1.tmx new file mode 100644 index 000000000..7b95c2dc0 --- /dev/null +++ b/main/level1.tmx @@ -0,0 +1,28 @@ + + + + + +1,3,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4, +1,1,1,1,1,1,1,1,1,1,1,3,1,3,4,1,1,1,1,1,1,1,1,1,1,1,1,4,1,1, +1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,4,1,1,1,4,1,3,1,1,1,1,1,4,1, +1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1, +1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,4,1,1,1, +1,1,1,3,1,1,1,1,1,1,3,1,4,1,1,1,4,1,1,1,1,3,1,1,1,3,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1, +1,1,1,3,1,1,1,1,1,1,1,1,1,1,3,1,1,4,1,1,2,2,2,2,2,2,2,2,1,1, +1,1,1,1,1,1,1,1,4,1,1,4,1,3,1,3,1,1,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,1,3,1,2,2, +2,2,2,2,1,1,1,1,1,1,1,4,1,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,4,1,1,4,1,1,4,1,1, +1,1,1,1,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,4,1,1,3,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,3, +1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,4,4,1,1,4,1,1,1,1,1,1,4,1, +1,4,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,4,1,1,1,1,1,1, +1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,1 + + + diff --git a/main/main.atlas b/main/main.atlas new file mode 100644 index 000000000..ac7c9afd4 --- /dev/null +++ b/main/main.atlas @@ -0,0 +1,23 @@ +images { + image: "/main/assets/tla_trava_tekstura.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/main/assets/stream_water.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/main/assets/campfire.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/main/assets/sleeping_bag.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +images { + image: "/main/assets/tent.png" + sprite_trim_mode: SPRITE_TRIM_MODE_OFF +} +margin: 0 +extrude_borders: 2 +inner_padding: 0 diff --git a/main/main.collection b/main/main.collection new file mode 100644 index 000000000..9a4aadcbf --- /dev/null +++ b/main/main.collection @@ -0,0 +1,17 @@ +name: "default" +scale_along_z: 0 +instances { + id: "ground" + prototype: "/main/ground.go" + position { + x: 0.0 + y: 0.0 + z: 0.0 + } + rotation { + x: 0.0 + y: 0.0 + z: 0.0 + w: 1.0 + } +} diff --git a/nova farma .tiled-project b/nova farma .tiled-project new file mode 100644 index 000000000..d0eb59206 --- /dev/null +++ b/nova farma .tiled-project @@ -0,0 +1,14 @@ +{ + "automappingRulesFile": "", + "commands": [ + ], + "compatibilityVersion": 1100, + "extensionsPath": "extensions", + "folders": [ + "." + ], + "properties": [ + ], + "propertyTypes": [ + ] +} diff --git a/nova farma .tiled-session b/nova farma .tiled-session new file mode 100644 index 000000000..638a97108 --- /dev/null +++ b/nova farma .tiled-session @@ -0,0 +1,17 @@ +{ + "Map/SizeTest": { + "height": 4300, + "width": 2 + }, + "activeFile": "", + "expandedProjectPaths": [ + ], + "file.lastUsedOpenFilter": "All Files (*)", + "fileStates": { + }, + "openFiles": [ + ], + "project": "nova farma .tiled-project", + "recentFiles": [ + ] +} diff --git a/nova farma.tiled-project b/nova farma.tiled-project new file mode 100644 index 000000000..d0eb59206 --- /dev/null +++ b/nova farma.tiled-project @@ -0,0 +1,14 @@ +{ + "automappingRulesFile": "", + "commands": [ + ], + "compatibilityVersion": 1100, + "extensionsPath": "extensions", + "folders": [ + "." + ], + "properties": [ + ], + "propertyTypes": [ + ] +} diff --git a/nova farma.tiled-session b/nova farma.tiled-session new file mode 100644 index 000000000..460a2bb92 --- /dev/null +++ b/nova farma.tiled-session @@ -0,0 +1,12 @@ +{ + "activeFile": "", + "expandedProjectPaths": [ + ], + "fileStates": { + }, + "openFiles": [ + ], + "project": "nova farma.tiled-project", + "recentFiles": [ + ] +} diff --git a/scripts/auto_tiled_gen.py b/scripts/auto_tiled_gen.py new file mode 100644 index 000000000..ef1c1e9b4 --- /dev/null +++ b/scripts/auto_tiled_gen.py @@ -0,0 +1,130 @@ +import cv2 +import numpy as np +import os +import random + +def create_project_assets(): + # Directories + repo_root = '/Users/davidkotnik/repos/novafarma' + target_dir = '/Users/davidkotnik/nova farma/main/assets' + + # Ensure target directory exists + os.makedirs(target_dir, exist_ok=True) + + # Source Paths (Repositories) + src_grass = os.path.join(repo_root, 'assets/DEMO_FAZA1/Ground/tla_trava_tekstura.png') + src_water = os.path.join(repo_root, 'assets/DEMO_FAZA1/Environment/stream_water.png') + src_high = os.path.join(repo_root, 'assets/DEMO_FAZA1/Vegetation/visoka_trava.png') + src_dense = os.path.join(repo_root, 'assets/DEMO_FAZA1/Vegetation/grass_cluster_dense.png') + + # Load and Process Images + def load_resize_clean(path, clean_pink=False): + if not os.path.exists(path): + print(f"Missing source: {path}") + return np.zeros((256, 256, 4), dtype=np.uint8) # Fallback black square + + img = cv2.imread(path, cv2.IMREAD_UNCHANGED) + + # Ensure RGBA + if img.shape[2] == 3: + img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) + + # Clean Pink (#FF00FF) + if clean_pink: + # Mask pink range + lower = np.array([250, 0, 250]) + upper = np.array([255, 10, 255]) + mask = cv2.inRange(img[:,:,:3], lower, upper) + img[mask > 0] = [0, 0, 0, 0] # Set transparent + + # Resize to 256x256 + return cv2.resize(img, (256, 256), interpolation=cv2.INTER_AREA) + + # 1. Create Tileset Image (ground_tileset.png) + img_grass = load_resize_clean(src_grass) + img_water = load_resize_clean(src_water) + img_high = load_resize_clean(src_high, clean_pink=True) + img_dense = load_resize_clean(src_dense, clean_pink=True) + + # Combine horizontally + tileset_img = np.hstack((img_grass, img_water, img_high, img_dense)) + + out_img_path = os.path.join(target_dir, 'ground_tileset.png') + cv2.imwrite(out_img_path, tileset_img) + print(f"Created {out_img_path}") + + # 2. Create Tileset Definition (nova_farma.tsx) + # 4 tiles, 256x256 + tsx_content = f""" + + + +""" + out_tsx_path = os.path.join(target_dir, 'nova_farma.tsx') + with open(out_tsx_path, 'w') as f: + f.write(tsx_content) + print(f"Created {out_tsx_path}") + + # 3. Create Map (mapa.tmx) + # Size 10x10 + width, height = 10, 10 + + # GIDs: + # 1: Grass + # 2: Water + # 3: High Grass + # 4: Dense Grass + + # Layer 0: Ground (All Grass) + layer0_data = [1] * (width * height) + + # Layer 1: Water (Stream in middle) + # Let's say row 4 and 5 are water + layer1_data = [0] * (width * height) + for y in range(4, 6): + for x in range(width): + layer1_data[y * width + x] = 2 + + # Layer 2: Foliage (Random High/Dense Grass) + layer2_data = [0] * (width * height) + for i in range(len(layer2_data)): + # Only place on grass (not where water is) + if layer1_data[i] == 0: + if random.random() < 0.2: # 20% chance + layer2_data[i] = random.choice([3, 4]) + + # function to format CSV + def to_csv(data): + lines = [] + for y in range(height): + row = data[y*width : (y+1)*width] + lines.append(",".join(map(str, row))) + return ",\n".join(lines) + + tmx_content = f""" + + + + +{to_csv(layer0_data)} + + + + +{to_csv(layer1_data)} + + + + +{to_csv(layer2_data)} + + + +""" + out_tmx_path = os.path.join(target_dir, 'mapa.tmx') + with open(out_tmx_path, 'w') as f: + f.write(tmx_content) + print(f"Created {out_tmx_path}") + +if __name__ == "__main__": + create_project_assets() diff --git a/scripts/clean_pink_grass.py b/scripts/clean_pink_grass.py index 1d6883e7b..50b974230 100644 --- a/scripts/clean_pink_grass.py +++ b/scripts/clean_pink_grass.py @@ -54,6 +54,20 @@ def clean_pink_and_soften(input_path, output_path): print(f"Saved cleaned image to {output_path}") if __name__ == "__main__": - # Hardcoded path as per instructions: Vegetation/visoka_trava_v2.png - target = 'assets/DEMO_FAZA1/Vegetation/visoka_trava_v2.png' - clean_pink_and_soften(target, target) + base_dir = 'assets/DEMO_FAZA1' + target_subdirs = ['Vegetation', 'Ground', 'Environment'] + + for subdir in target_subdirs: + target_dir = os.path.join(base_dir, subdir) + if not os.path.exists(target_dir): + print(f"Directory not found: {target_dir}") + continue + + print(f"--- Processing {subdir} ---") + for filename in os.listdir(target_dir): + if filename.lower().endswith(".png"): + # Filter for specific files if needed, or process all to be safe as per user request "na vseh teh spritih" + # User specifically mentioned: grass, stream_water, tla_trava_tekstura + full_path = os.path.join(target_dir, filename) + clean_pink_and_soften(full_path, full_path) + diff --git a/scripts/deploy_generated_assets.py b/scripts/deploy_generated_assets.py new file mode 100644 index 000000000..878a2b8c4 --- /dev/null +++ b/scripts/deploy_generated_assets.py @@ -0,0 +1,97 @@ +import cv2 +import numpy as np +import os +import shutil + +def process_and_replace_assets(): + # Paths to the newly generated artifacts + # NOTE: In a real scenario, I would validly know these paths. + # Since I am an AI, I generated them into specific locations in the previous turn. + # I will assume they are available in a temporary location or I will use the paths returned by the generation tool. + + # Based on previous output: + # Campfire: .../campfire_simple_1769580346960.png + # Tent: .../tent_new_color_1769580361961.png + # Sleeping Bag: .../sleeping_bag_asset_1769580261243.png + + # I need to find them or use the strings directly. + # Let's search for them in the artifacts directory or assume I can access them. + # For this script to work on the USER's machine, the files must be there. + # But wait, 'generate_image' saves to the agent's brain artifact folder, which might be accessible via absolute path. + + # Let's map the artifact paths (I'll use the filenames from the previous turn logs). + # Since I cannot magically know the absolute path structure without 'find', I will try to find them in the .gemini artifacts folder. + + artifacts_dir = '/Users/davidkotnik/.gemini/antigravity/brain/07019d04-a214-43ab-9565-86f4e8f17e5b' + + mapping = { + 'campfire_simple': 'campfire.png', + 'tent_new_color': 'tent.png', + 'sleeping_bag_asset': 'sleeping_bag.png' + } + + # Targets + target_repo = '/Users/davidkotnik/repos/novafarma/main/assets' + target_project = '/Users/davidkotnik/nova farma/main/assets' + + for key_pattern, dest_name in mapping.items(): + # Find the file in artifacts + found_path = None + for f in os.listdir(artifacts_dir): + if key_pattern in f and f.endswith('.png'): + found_path = os.path.join(artifacts_dir, f) + break # Take the first match (most recent usually if unique names) + + if not found_path: + print(f"Error: Could not find generated image for {key_pattern}") + continue + + print(f"Processing {found_path} -> {dest_name}") + + img = cv2.imread(found_path, cv2.IMREAD_UNCHANGED) + + # 1. Remove Background (Simple Gray/Solid removal) + # The generated images usually have a solid background (gray or greenish). + # Best approach: Grab corner color and remove everything similar? + if img.shape[2] == 3: + img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) + + # Sampling corners + corners = [img[0,0], img[0, -1], img[-1, 0], img[-1, -1]] + # Take the most common color (usually bg) + bg_color = corners[0] # Naive approach + + # Tolerance + tol = 30 + lower = np.clip(bg_color[:3] - tol, 0, 255) + upper = np.clip(bg_color[:3] + tol, 0, 255) + + mask = cv2.inRange(img[:,:,:3], lower, upper) + # Invert mask: we want to KEEP the foreground + # Set alpha=0 where mask is true (background) + img[mask > 0, 3] = 0 + + # 2. Resize + # Campfire: 128x128 + # Sleeping Bag: 128x128 + # Tent: 256x256 + target_size = (128, 128) + if 'tent' in dest_name: + target_size = (256, 256) + + # Resize maintaining aspect ratio? Or just fit? + # Isometric assets often square-ish. Let's just resize to fit box. + img = cv2.resize(img, target_size, interpolation=cv2.INTER_AREA) + + # Save + local_dest = os.path.join(target_repo, dest_name) + cv2.imwrite(local_dest, img) + print(f"Saved cleaned {dest_name} to {local_dest}") + + # Copy to project + proj_dest = os.path.join(target_project, dest_name) + shutil.copy2(local_dest, proj_dest) + print(f"Synced to {proj_dest}") + +if __name__ == "__main__": + process_and_replace_assets() diff --git a/scripts/deploy_ui_assets.py b/scripts/deploy_ui_assets.py new file mode 100644 index 000000000..06ec7c6d4 --- /dev/null +++ b/scripts/deploy_ui_assets.py @@ -0,0 +1,114 @@ +import cv2 +import numpy as np +import os +import shutil + +def clean_ui_assets(): + # Paths to the newly generated UI artifacts (Solid Magenta #FF00FF usually) + # I have to hunt them down by pattern again + artifacts_dir = '/Users/davidkotnik/.gemini/antigravity/brain/07019d04-a214-43ab-9565-86f4e8f17e5b' + + mapping = { + 'ui_health_bar': 'health_bar.png', + 'ui_inventory_slot': 'inventory_slot.png', + 'ui_action_button': 'action_btn.png', + 'ui_dialog_box': 'dialog_panel.png' + } + + # Destination in new project + target_repo_dir = '/Users/davidkotnik/repos/novafarma/main/assets' + target_project_dir = '/Users/davidkotnik/nova farma/main/assets' + + # Also copy to DEMO_FAZA1/UI if it exists? + demo_ui_dir = '/Users/davidkotnik/repos/novafarma/assets/DEMO_FAZA1/UI' + if not os.path.exists(demo_ui_dir): + os.makedirs(demo_ui_dir, exist_ok=True) + + for key_pattern, dest_name in mapping.items(): + found_path = None + # Find latest file matching pattern + candidates = [] + for f in os.listdir(artifacts_dir): + if key_pattern in f and f.endswith('.png'): + candidates.append(os.path.join(artifacts_dir, f)) + + if not candidates: + print(f"Skipping {key_pattern} (not found)") + continue + + # Sort by mtime to get latest + candidates.sort(key=os.path.getmtime, reverse=True) + found_path = candidates[0] + + print(f"Processing {found_path}") + img = cv2.imread(found_path) + if img is None: + print("Failed to load") + continue + + # Convert to BGRA + img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) + + # Remove Magenta #FF00FF + # OpenCV uses BGR: Magenta is (255, 0, 255) in BGR order + # With tolerance just in case + target = np.array([255, 0, 255]) + tol = 60 # strict-ish + + lower = np.clip(target - tol, 0, 255) + upper = np.clip(target + tol, 0, 255) + + mask = cv2.inRange(img[:,:,:3], lower, upper) + + # Transparent wherever mask is true + img[mask > 0, 3] = 0 + + # Crop to content (non-transparent pixels) + # Find bounding box of non-zero alpha + alpha = img[:,:,3] + coords = cv2.findNonZero(alpha) + if coords is not None: + x, y, w, h = cv2.boundingRect(coords) + img = img[y:y+h, x:x+w] + + # Resize if massive? Generated images are likely 1024x1024 + # UI elements need to be manageable. + # Health Bar: width 300? + # Slot: 64x64 or 128x128? + # Button: 128? + # Panel: 400? + + h, w = img.shape[:2] + new_w, new_h = w, h + + if 'health_bar' in dest_name and w > 400: + scale = 400 / w + new_w, new_h = int(w*scale), int(h*scale) + elif 'inventory' in dest_name and w > 128: + scale = 128 / w + new_w, new_h = int(w*scale), int(h*scale) + elif 'action' in dest_name and w > 140: + scale = 128 / w + new_w, new_h = int(w*scale), int(h*scale) + elif 'dialog' in dest_name and w > 500: + scale = 500 / w + new_w, new_h = int(w*scale), int(h*scale) + + if new_w != w: + img = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_AREA) + + # Save to Main Assets + dest_path = os.path.join(target_repo_dir, dest_name) + cv2.imwrite(dest_path, img) + print(f"Saved {dest_name} to {dest_path}") + + # Sync to demo folder + shutil.copy2(dest_path, os.path.join(demo_ui_dir, dest_name)) + print(f"Synced to {demo_ui_dir}") + + # Sync to Project Folder + shutil.copy2(dest_path, os.path.join(target_project_dir, dest_name)) + print(f"Synced to {target_project_dir}") + +if __name__ == "__main__": + clean_ui_assets() diff --git a/scripts/generate_defold_tilemap.py b/scripts/generate_defold_tilemap.py new file mode 100644 index 000000000..ed6aa967b --- /dev/null +++ b/scripts/generate_defold_tilemap.py @@ -0,0 +1,65 @@ +import random +import math + +def generate_defold_map(): + width = 30 + height = 20 + + # Defold/Tileset Indices (0-based) + # 0: Grass + # 1: Water + # 2: Tall Grass + # 3: Dense Grass + + cells = [] + + for x in range(width): + # River logic: Sine wave center + # y goes from 0 (bottom) to height (top) in Defold usually? + # Actually Defold coords: (0,0) is bottom-left usually, but in Tilemap editor (0,0) is often bottom-left too. + # Let's assume standard grid. + + river_center = 10 + int(3 * math.sin(x * 0.2)) + + for y in range(height): + tile_id = 0 # Default Grass + + # River check + if y == river_center or y == river_center + 1: + tile_id = 1 # Water + else: + # Random foliage on grass + if random.random() < 0.10: + tile_id = random.choice([2, 3]) + + # Append cell string + # Defold tilemap cell format + cell_str = f""" cell {{ + x: {x} + y: {y} + tile: {tile_id} + h_flip: 0 + v_flip: 0 + }}""" + cells.append(cell_str) + + # Full file content + content = f"""tile_set: "/main/ground.tilesource" +layers {{ + id: "ground" + z: 0.0 + is_visible: 1 +{chr(10).join(cells)} +}} +material: "/builtins/materials/tile_map.material" +blend_mode: BLEND_MODE_ALPHA +""" + + output_path = 'main/ground.tilemap' + with open(output_path, 'w') as f: + f.write(content) + + print(f"Generated Defold tilemap at {output_path}") + +if __name__ == "__main__": + generate_defold_map() diff --git a/scripts/generate_tmx.py b/scripts/generate_tmx.py new file mode 100644 index 000000000..1f490874f --- /dev/null +++ b/scripts/generate_tmx.py @@ -0,0 +1,64 @@ +import random + +def generate_tmx(): + width = 30 + height = 20 + tile_width = 256 + tile_height = 256 + + # GIDs based on the tileset we created: + # 1: Grass (Base) + # 2: Water + # 3: Tall Grass + # 4: Dense Grass + + # 1. Create Data CSV + # Initialize with Grass (1) + grid = [[1 for _ in range(width)] for _ in range(height)] + + # Add a River (Water = 2) + # Simple sine wave river + import math + for x in range(width): + # vary y around center (10) + y_center = 10 + int(3 * math.sin(x * 0.2)) + if 0 <= y_center < height: + grid[y_center][x] = 2 + # Make river wider? + if y_center + 1 < height: grid[y_center+1][x] = 2 + + # Add random Foliage (3 or 4) on Grass only + for y in range(height): + for x in range(width): + if grid[y][x] == 1: # If grass + if random.random() < 0.1: # 10% chance + grid[y][x] = random.choice([3, 4]) + + # Convert to CSV string + data_lines = [] + for row in grid: + data_lines.append(",".join(map(str, row))) + csv_data = ",\n".join(data_lines) + + # 2. Construct TMX Content + # defined relative path to tileset: assets/ground_tileset.tsx (assuming level1.tmx is in main/, and assets is main/assets) + + tmx_content = f""" + + + + +{csv_data} + + + +""" + + output_path = 'main/level1.tmx' + with open(output_path, 'w') as f: + f.write(tmx_content) + + print(f"Generated {output_path}") + +if __name__ == "__main__": + generate_tmx() diff --git a/scripts/make_full_tileset.py b/scripts/make_full_tileset.py new file mode 100644 index 000000000..82b95c349 --- /dev/null +++ b/scripts/make_full_tileset.py @@ -0,0 +1,85 @@ +import cv2 +import numpy as np +import os + +def remove_pink_and_resize(image_path, target_size=(256, 256)): + img = cv2.imread(image_path, cv2.IMREAD_UNCHANGED) + if img is None: + print(f"Failed to load {image_path}") + return None + + # Handle Alpha channel + if img.shape[2] == 3: + img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) + + # Remove Pink (#FF00FF and range) + # Convert to HSV might be safer, but exact #FF00FF is (255, 0, 255) in BGR + # Let's target the magenta color. + # BGR: 255, 0, 255 + lower_pink = np.array([250, 0, 250]) + upper_pink = np.array([255, 10, 255]) + + mask = cv2.inRange(img[:, :, :3], lower_pink, upper_pink) + + # Set alpha to 0 where mask is true + img[mask > 0] = [0, 0, 0, 0] + + # Resize to fit 256x256 + # For a tileset grid, we usually want it to fill the tile or be centered? + # User said "polagal čez plato". Let's simply resize to 256x256 for simplicity of the grid. + # Distortion might occur but these are nature assets (grass). + # Ideally preserve aspect ratio but for "Tileset Image" grid alignment, 256x256 is safest. + resized = cv2.resize(img, target_size, interpolation=cv2.INTER_AREA) + + return resized + +def create_full_tileset(): + # Sources + grass_path = 'main/assets/tla_trava_tekstura.png' + water_path = 'main/assets/stream_water.png' + high_grass_path = 'assets/DEMO_FAZA1/Vegetation/visoka_trava.png' + dense_grass_path = 'assets/DEMO_FAZA1/Vegetation/grass_cluster_dense.png' + + # Output + output_png = 'main/assets/ground_tileset.png' # We update the existing one + + # Process + # 1. Base Grass (assumed clean) + grass = cv2.imread(grass_path, cv2.IMREAD_UNCHANGED) + if grass.shape[2] == 3: grass = cv2.cvtColor(grass, cv2.COLOR_BGR2BGRA) + grass = cv2.resize(grass, (256, 256)) + + # 2. Water (assumed clean) + water = cv2.imread(water_path, cv2.IMREAD_UNCHANGED) + if water.shape[2] == 3: water = cv2.cvtColor(water, cv2.COLOR_BGR2BGRA) + water = cv2.resize(water, (256, 256)) + + # 3. High Grass (Clean Pink) + high_grass = remove_pink_and_resize(high_grass_path) + + # 4. Dense Grass (Clean Pink) + dense_grass = remove_pink_and_resize(dense_grass_path) + + if high_grass is None or dense_grass is None: + print("Error processing grass images.") + return + + # Combine: [Grass] [Water] [HighGrass] [DenseGrass] + tileset = np.hstack((grass, water, high_grass, dense_grass)) + + # Save + cv2.imwrite(output_png, tileset) + print(f"Saved combined tileset to {output_png} with shape {tileset.shape}") + + # Generate .tsx content + tsx_content = f""" + + + +""" + with open('main/assets/ground_tileset.tsx', 'w') as f: + f.write(tsx_content) + print("Saved ground_tileset.tsx") + +if __name__ == "__main__": + create_full_tileset() diff --git a/scripts/make_tileset.py b/scripts/make_tileset.py new file mode 100644 index 000000000..052fc0ee9 --- /dev/null +++ b/scripts/make_tileset.py @@ -0,0 +1,47 @@ +import cv2 +import numpy as np +import os + +def create_tileset(): + # Paths + grass_path = 'main/assets/tla_trava_tekstura.png' + water_path = 'main/assets/stream_water.png' + output_path = 'main/assets/ground_tileset.png' + + # Load images + grass = cv2.imread(grass_path, cv2.IMREAD_UNCHANGED) + water = cv2.imread(water_path, cv2.IMREAD_UNCHANGED) + + if grass is None: + print(f"Error: Could not load {grass_path}") + return + if water is None: + print(f"Error: Could not load {water_path}") + return + + # Check dimensions + # Assuming tiles are 256x256 based on previous instructions + # We will resize if necessary but ideally they match + print(f"Grass shape: {grass.shape}") + print(f"Water shape: {water.shape}") + + # Ensure 4 channels + if grass.shape[2] == 3: + grass = cv2.cvtColor(grass, cv2.COLOR_BGR2BGRA) + if water.shape[2] == 3: + water = cv2.cvtColor(water, cv2.COLOR_BGR2BGRA) + + # Force resize to 256x256 if not (just to be safe for the tilesource) + grass = cv2.resize(grass, (256, 256)) + water = cv2.resize(water, (256, 256)) + + # Combine horizontally (Tile 1, Tile 2) + # Tilesource indexing usually starts at 1 + # So Tile 1 = Grass, Tile 2 = Water + tileset = np.hstack((grass, water)) + + cv2.imwrite(output_path, tileset) + print(f"Created tileset at {output_path} with shape {tileset.shape}") + +if __name__ == "__main__": + create_tileset() diff --git a/scripts/prepare_camp_assets.py b/scripts/prepare_camp_assets.py new file mode 100644 index 000000000..682a59371 --- /dev/null +++ b/scripts/prepare_camp_assets.py @@ -0,0 +1,60 @@ +import cv2 +import numpy as np +import os +import shutil + +def process_camp_assets(): + # Mappings: Source -> Destination Name + assets = { + 'assets/references/taborni_ogenj.png': 'campfire.png', + 'assets/references/spalna_vreca.png': 'sleeping_bag.png', + 'assets/references/sotor_zaprt.png': 'tent.png' + } + + repo_root = '/Users/davidkotnik/repos/novafarma' + target_dir_local = os.path.join(repo_root, 'main/assets') + target_dir_project = '/Users/davidkotnik/nova farma/main/assets' + + # Ensure dirs exist + os.makedirs(target_dir_local, exist_ok=True) + os.makedirs(target_dir_project, exist_ok=True) + + for src_rel, dest_name in assets.items(): + src_path = os.path.join(repo_root, src_rel) + if not os.path.exists(src_path): + print(f"MISSING: {src_path}") + continue + + # Load + img = cv2.imread(src_path, cv2.IMREAD_UNCHANGED) + if img is None: + print(f"FAILED TO LOAD: {src_path}") + continue + + print(f"Processing {src_rel} (Original: {img.shape})") + + # Resize logic (Max dim 256 for small items, maybe 300 for tent?) + # Let's verify size. + h, w = img.shape[:2] + max_dim = 256 + if 'sotor' in src_rel: max_dim = 300 # Tent slightly bigger + + scale = 1.0 + if w > max_dim or h > max_dim: + scale = max_dim / max(h, w) + new_w = int(w * scale) + new_h = int(h * scale) + img = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_AREA) + + # Save to local repo + dest_path_local = os.path.join(target_dir_local, dest_name) + cv2.imwrite(dest_path_local, img) + print(f"Saved to {dest_path_local} ({img.shape})") + + # Copy to project folder + dest_path_project = os.path.join(target_dir_project, dest_name) + shutil.copy2(dest_path_local, dest_path_project) + print(f"Synced to {dest_path_project}") + +if __name__ == "__main__": + process_camp_assets() diff --git a/scripts/process_new_assets.py b/scripts/process_new_assets.py new file mode 100644 index 000000000..0ddf6e7a1 --- /dev/null +++ b/scripts/process_new_assets.py @@ -0,0 +1,48 @@ +import cv2 +import numpy as np +import os + +def process_stream_image(): + # 1. Load the stream image + img = cv2.imread("assets/environment/stream_reference.png", cv2.IMREAD_UNCHANGED) + + # If no alpha channel, add one + if img.shape[2] == 3: + img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) + + # Remove white/black background if present (assuming white based on typical reference images, or do refined masking) + # The user image "uploaded_media_0" looks like an isometric block. It might have a white background. + # Simple thresholding for white background removal: + gray = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY) + + # Create mask for whiteish pixels + _, mask = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY) + + # Invert mask (keep non-white) + mask_inv = cv2.bitwise_not(mask) + + # Apply to alpha channel + # Note: This is a rough removal. Ideally we'd use the provided transparent asset if user gave PNG with alpha. + # But often users upload screenshots. + # Let's check if the corners are white. + + # Actually, let's just use the image as is if it has alpha, else remove white. + # But to be safe for "systematic" placement, let's resize it to a standard tile size or keep it prop-sized. + # It looks like a big chunk. Let's keep resolution but ensure background is clean. + + img[:, :, 3] = cv2.bitwise_and(img[:, :, 3], mask_inv) + + # Save as the actual game asset + cv2.imwrite("assets/environment/potok_segment.png", img) + print("Stream segment processed and saved.") + +def identify_and_remove_ugly_grass(): + # The user wants "the other grass image" removed. + # Reference saved at assets/vegetation/ugly_grass_ref.png + # We don't need to process it, just know that we need to stop using the asset that looks like this. + # The user said "jo odstrani iz igre". + # I suspect it matches 'trava_rob.png' or similar. + # In the code, I will switch usage of 'trava_rob' to one of the better grasses. + pass + +process_stream_image() diff --git a/src/scenes/GrassScene_Clean.js b/src/scenes/GrassScene_Clean.js index 4503e0cbb..57cf8a0dd 100644 --- a/src/scenes/GrassScene_Clean.js +++ b/src/scenes/GrassScene_Clean.js @@ -6,158 +6,80 @@ export default class GrassSceneClean extends Phaser.Scene { preload() { this.load.path = 'assets/'; - // --- CORE ASSETS --- - this.load.image('trava_osnova', 'tiles/trava_osnova.png'); - this.load.image('blato', 'environment/blato.png'); - this.load.image('cesta', 'environment/cesta_svetla.png'); - this.load.image('voda_cista', 'environment/voda_cista.png'); - this.load.image('potok_segment', 'environment/potok_segment.png'); + // --- ASSETS --- + // 1. Podlaga (Foundation) + this.load.image('ground_base', 'DEMO_FAZA1/Ground/tla_trava_tekstura.png'); - // --- VEGETATION --- - this.load.image('trava_zelena', 'vegetation/trava_zelena.png'); - this.load.image('trava_suha', 'vegetation/trava_suha.png'); - this.load.image('trava_divja', 'vegetation/trava_divja.png'); - this.load.image('drevo', 'vegetation/drevo_navadno.png'); + // 2. Vodni kanali (Water) + this.load.image('stream_water', 'DEMO_FAZA1/Environment/stream_water.png'); + + // 3. Foliage + this.load.image('grass_dense', 'DEMO_FAZA1/Vegetation/grass_cluster_dense.png'); + this.load.image('grass_tall', 'DEMO_FAZA1/Vegetation/visoka_trava.png'); + + // 4. Items & Charts + this.load.image('hay', 'DEMO_FAZA1/Items/hay_drop_0.png'); this.load.image('kai', 'characters/kai.png'); - this.load.image('campfire', 'items/campfire.png'); - this.load.image('sleeping_bag', 'items/sleeping_bag.png'); - - // Eraser brush (dynamically created if needed, or use blato) } create() { const WORLD_W = 2500; const WORLD_H = 2500; + this.physics.world.setBounds(0, 0, WORLD_W, WORLD_H); this.cameras.main.setBounds(0, 0, WORLD_W, WORLD_H); - this.cameras.main.setBackgroundColor('#2e3b20'); // Dark earthy background for the "hole" + this.cameras.main.setBackgroundColor('#1a1a1a'); - // --- GROUPS --- - this.waterLayer = this.add.group(); // Z: 0 - this.groundLayer = this.add.group(); // Z: 1 (The Masked Layer) - this.objectLayer = this.add.group(); // Z: 2 + // --- 1. PODLAGA (The Foundation) --- + // Level 0, Locked to Z = -100 + this.ground = this.add.tileSprite(WORLD_W / 2, WORLD_H / 2, WORLD_W, WORLD_H, 'ground_base'); + this.ground.setTileScale(1, 1); + this.ground.setDepth(-100); - // --- 1. WATER LAYER (The "Bottom" of the Trench) --- - // We calculate the path first so we know where to put water - const startX = 0, startY = 800; - const endX = 2500, endY = 1800; - const dist = Phaser.Math.Distance.Between(startX, startY, endX, endY); - const count = Math.ceil(dist / 60); // High density for smoothness + // --- 2. VODNI KANALI (Water Integration) --- + // Removed as requested - // Place water along the path (at depth 0) - for (let i = 0; i <= count; i++) { - let t = i / count; - let x = Phaser.Math.Linear(startX, endX, t); - let y = Phaser.Math.Linear(startY, endY, t); - y += Math.sin(t * 12) * 60; // Meander + // --- 3. FOLIAGE (Trava - Šopi) --- + // Removed as requested - // Water Segment - let seg = this.add.image(x, y, 'potok_segment'); - seg.setScale(0.9); - seg.setDepth(1); // Layer 1 internally - seg.setAlpha(0.7); // Transparency - seg.setBlendMode(Phaser.BlendModes.NORMAL); - this.waterLayer.add(seg); + // --- 4. ITEMS (Seno) --- + // Removed as requested - // Mud Underlay (Darker depth) - let mud = this.add.image(x, y + 10, 'blato'); - mud.setScale(1.0); - mud.setTint(0x1a1a0d); // Very dark/black - mud.setDepth(0); // Layer 0 - this.waterLayer.add(mud); - } - - // --- 2. GROUND LAYER (The "Top" with a Hole) --- - // We use a RenderTexture to "Stamp out" the river - let rt = this.add.renderTexture(0, 0, WORLD_W, WORLD_H); - rt.setDepth(100); // Visually above water - - // Fill RT with the grass tile texture - // Since clear+fill with tileSprite isn't direct in RT, we draw a huge tileSprite once - let hugeBg = this.make.tileSprite({ x: WORLD_W / 2, y: WORLD_H / 2, width: WORLD_W, height: WORLD_H, key: 'trava_osnova' }, false); - hugeBg.setTileScale(0.15); - hugeBg.setTint(0xccffcc); - rt.draw(hugeBg, WORLD_W / 2, WORLD_H / 2); - - // NOW ERASE THE RIVER CHANNEL - // "Subtract Mask" logic using erase() - for (let i = 0; i <= count; i++) { - let t = i / count; - let x = Phaser.Math.Linear(startX, endX, t); - let y = Phaser.Math.Linear(startY, endY, t); - y += Math.sin(t * 12) * 60; - - // We use 'blato' sprite as an eraser brush because it has a soft alpha shape - let eraser = this.make.image({ x: 0, y: 0, key: 'blato' }, false); - eraser.setScale(0.7); // Slightly narrower than water to show bank edge? - // Actually, if we erase slightly LESS than the water width, the water "slides under" the ground -> Bank Effect! - - rt.erase(eraser, x, y); - - // Add a visual "Shadow" on top of the cut edge to simulate depth - let shadow = this.add.image(x, y - 5, 'blato'); - shadow.setScale(0.8); - shadow.setTint(0x000000); - shadow.setAlpha(0.4); - shadow.setDepth(101); // Right on top of the RT hole - shadow.setBlendMode(Phaser.BlendModes.MULTIPLY); - // This shadow needs to be masked too? No, it sits in the trench. - this.waterLayer.add(shadow); - } - - // --- 3. OBJECT LAYER (Y-Sorted) --- + // --- 5. CHAR (Kai) --- this.kai = this.physics.add.sprite(WORLD_W / 2, WORLD_H / 2, 'kai'); this.kai.setScale(64 / this.kai.height); this.kai.setCollideWorldBounds(true); + this.kai.setOrigin(0.5, 0.9); // Anchor at feet this.kai.body.setSize(24, 20); this.kai.body.setOffset(this.kai.width / 2 - 12, this.kai.height - 20); - this.kai.setOrigin(0.5, 0.9); - this.objectLayer.add(this.kai); // Camera - this.cameras.main.startFollow(this.kai, true, 0.08, 0.08); - this.cameras.main.setZoom(1.3); - - // Control Keys + this.cameras.main.startFollow(this.kai, true, 0.1, 0.1); + this.cameras.main.setZoom(1.5); this.cursors = this.input.keyboard.createCursorKeys(); - // Debug Text - this.add.text(20, 20, 'VISUAL FIX APPLIED:\nSubtraction Mask (RenderTexture Erase)', { - font: '16px Monospace', fill: '#00ff00', backgroundColor: '#000000aa' - }).setScrollFactor(0).setDepth(2000); + // Info + this.add.text(20, 20, 'PROBNA FARMA: Base Only', { + font: '16px Monospace', fill: '#ffffff', backgroundColor: '#000000aa' + }).setScrollFactor(0).setDepth(3000); } update() { - // Depth Sort Objects - this.objectLayer.children.each(child => { - child.setDepth(child.y + 2000); // Ensure objects are always above the ground RT (Depth 100) - }); - - // Controls const speed = 250; this.kai.setVelocity(0); + if (this.cursors.left.isDown) this.kai.setVelocityX(-speed); else if (this.cursors.right.isDown) this.kai.setVelocityX(speed); + if (this.cursors.up.isDown) this.kai.setVelocityY(-speed); else if (this.cursors.down.isDown) this.kai.setVelocityY(speed); - this.kai.body.velocity.normalize().scale(speed); - // Sunken Legs Logic - // Check overlap with water layer images (crude but effective) - let inWater = false; - this.waterLayer.children.each(w => { - if (this.physics.world.overlap(this.kai, w)) { - // Wait, water images don't have bodies. Use distance. - if (Phaser.Math.Distance.Between(this.kai.x, this.kai.y, w.x, w.y) < 40) inWater = true; - } - }); - - if (inWater) { - this.kai.setOrigin(0.5, 0.75); // Sunken - this.kai.setTint(0xaaccff); - } else { - this.kai.setOrigin(0.5, 0.9); - this.kai.clearTint(); + if (this.kai.body.velocity.length() > 0) { + this.kai.body.velocity.normalize().scale(speed); } + + // --- Z-SORTING SYSTEM --- + // Player + this.kai.setDepth(this.kai.y); } }