diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ccff983 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/.editor_settings +/.internal +/build +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/README.md b/README.md index ba676c7..41a4a66 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,12 @@ -# sample-third-person-playground -Third person playground with a player controlled character and interactive gameplay elements +# 3D third person game sample + +* 2D tilemap +* 3D models +* Shadows + + +## Credits + +* Textures by Kenney (https://www.kenney.nl) +* Models by Mesh2Motion (https://mesh2motion.org/) +* Models by KayKit (https://kaylousberg.itch.io/) diff --git a/app.appmanifest b/app.appmanifest new file mode 100644 index 0000000..32a92b4 --- /dev/null +++ b/app.appmanifest @@ -0,0 +1,111 @@ +platforms: + armv7-ios: + context: + excludeLibs: [image, liveupdate] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [image_null, liveupdate_null] + frameworks: [] + linkFlags: [] + arm64-ios: + context: + excludeLibs: [image, liveupdate] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [image_null, liveupdate_null] + frameworks: [] + linkFlags: [] + x86_64-ios: + context: + excludeLibs: [image, liveupdate] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [image_null, liveupdate_null] + frameworks: [] + linkFlags: [] + armv7-android: + context: + excludeLibs: [image, liveupdate] + excludeJars: [] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [image_null, liveupdate_null] + linkFlags: [] + jetifier: true + arm64-android: + context: + excludeLibs: [image, liveupdate] + excludeJars: [] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [image_null, liveupdate_null] + linkFlags: [] + jetifier: true + arm64-osx: + context: + excludeLibs: [image, liveupdate, graphics_vulkan, platform_vulkan, MoltenVK] + excludeSymbols: [ScriptTypesExt, ScriptImageExt, GraphicsAdapterVulkan] + symbols: [GraphicsAdapterOpenGL] + libs: [image_null, liveupdate_null, graphics, platform] + frameworks: [OpenGL] + linkFlags: [] + x86_64-osx: + context: + excludeLibs: [image, liveupdate, graphics_vulkan, platform_vulkan, MoltenVK] + excludeSymbols: [ScriptTypesExt, ScriptImageExt, GraphicsAdapterVulkan] + symbols: [GraphicsAdapterOpenGL] + libs: [image_null, liveupdate_null, graphics, platform] + frameworks: [OpenGL] + linkFlags: [] + x86_64-linux: + context: + excludeLibs: [image, liveupdate] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [image_null, liveupdate_null] + linkFlags: [] + arm64-linux: + context: + excludeLibs: [image, liveupdate] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [image_null, liveupdate_null] + linkFlags: [] + x86-win32: + context: + excludeLibs: [libimage, libliveupdate] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [libimage_null.lib, libliveupdate_null.lib] + linkFlags: [] + x86_64-win32: + context: + excludeLibs: [libimage, libliveupdate] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [libimage_null.lib, libliveupdate_null.lib] + linkFlags: [] + js-web: + context: + excludeLibs: [image, liveupdate] + excludeJsLibs: [] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [image_null, liveupdate_null] + linkFlags: [] + wasm-web: + context: + excludeLibs: [image, liveupdate] + excludeJsLibs: [] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [image_null, liveupdate_null] + linkFlags: [] + wasm_pthread-web: + context: + excludeLibs: [image, liveupdate] + excludeJsLibs: [] + excludeSymbols: [ScriptTypesExt, ScriptImageExt] + symbols: [] + libs: [image_null, liveupdate_null] + linkFlags: [] diff --git a/assets/game.atlas b/assets/game.atlas new file mode 100644 index 0000000..c7d6053 --- /dev/null +++ b/assets/game.atlas @@ -0,0 +1,7 @@ +images { + image: "/assets/images/alpha.png" +} +images { + image: "/assets/images/cicle.png" +} +margin: 2 diff --git a/assets/images/alpha.png b/assets/images/alpha.png new file mode 100644 index 0000000..bc257de Binary files /dev/null and b/assets/images/alpha.png differ diff --git a/assets/images/cicle.png b/assets/images/cicle.png new file mode 100644 index 0000000..a63dbd8 Binary files /dev/null and b/assets/images/cicle.png differ diff --git a/assets/models/character/character.glb b/assets/models/character/character.glb new file mode 100644 index 0000000..5fc512d Binary files /dev/null and b/assets/models/character/character.glb differ diff --git a/assets/models/character/character.model b/assets/models/character/character.model new file mode 100644 index 0000000..074336b --- /dev/null +++ b/assets/models/character/character.model @@ -0,0 +1,17 @@ +mesh: "/assets/models/character/character.glb" +skeleton: "/assets/models/character/character.glb" +animations: "/assets/models/character/character.glb" +default_animation: "Idle_Loop" +name: "character_mesh2motion" +materials { + name: "M_Main.001" + material: "/shadow_mapping/materials/high/diffuse_skinning.material" + textures { + sampler: "tex0" + texture: "/assets/models/character/character.png" + } + textures { + sampler: "tex_depth" + texture: "/assets/models/character/character.png" + } +} diff --git a/assets/models/character/character.png b/assets/models/character/character.png new file mode 100644 index 0000000..6c53611 Binary files /dev/null and b/assets/models/character/character.png differ diff --git a/assets/models/forest/collections/pier.collection b/assets/models/forest/collections/pier.collection new file mode 100644 index 0000000..28a73de --- /dev/null +++ b/assets/models/forest/collections/pier.collection @@ -0,0 +1,322 @@ +name: "pier" +instances { + id: "wall" + prototype: "/assets/models/forest/gameobjects/wall.go" + position { + x: 399.0 + z: 38.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "wall2" + prototype: "/assets/models/forest/gameobjects/wall.go" + position { + x: 53.0 + z: 394.0 + } + rotation { + y: -0.7126409 + w: 0.701529 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "wall1" + prototype: "/assets/models/forest/gameobjects/wall.go" + position { + x: 53.0 + z: -311.0 + } + rotation { + y: -0.7126409 + w: 0.701529 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +scale_along_z: 0 +embedded_instances { + id: "pallet1" + data: "components {\n" + " id: \"model_tiers\"\n" + " component: \"/shadow_mapping/model_tiers.script\"\n" + "}\n" + "embedded_components {\n" + " id: \"model\"\n" + " type: \"model\"\n" + " data: \"mesh: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "skeleton: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "name: \\\"{{NAME}}\\\"\\n" + "materials {\\n" + " name: \\\"resource\\\"\\n" + " material: \\\"/shadow_mapping/materials/high/diffuse.material\\\"\\n" + " textures {\\n" + " sampler: \\\"tex0\\\"\\n" + " texture: \\\"/assets/models/forest/resource_texture.png\\\"\\n" + " }\\n" + "}\\n" + "\"\n" + "}\n" + "" + position { + x: -116.0 + y: 11.0 + z: 188.0 + } + rotation { + y: -1.0 + w: 6.123234E-17 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +embedded_instances { + id: "pallet2" + data: "components {\n" + " id: \"model_tiers\"\n" + " component: \"/shadow_mapping/model_tiers.script\"\n" + "}\n" + "embedded_components {\n" + " id: \"model\"\n" + " type: \"model\"\n" + " data: \"mesh: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "skeleton: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "name: \\\"{{NAME}}\\\"\\n" + "materials {\\n" + " name: \\\"resource\\\"\\n" + " material: \\\"/shadow_mapping/materials/high/diffuse.material\\\"\\n" + " textures {\\n" + " sampler: \\\"tex0\\\"\\n" + " texture: \\\"/assets/models/forest/resource_texture.png\\\"\\n" + " }\\n" + "}\\n" + "\"\n" + "}\n" + "" + position { + x: 183.0 + y: 11.0 + z: 188.0 + } + rotation { + y: -1.0 + w: 6.123234E-17 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +embedded_instances { + id: "pallet4" + data: "components {\n" + " id: \"model_tiers\"\n" + " component: \"/shadow_mapping/model_tiers.script\"\n" + "}\n" + "embedded_components {\n" + " id: \"model\"\n" + " type: \"model\"\n" + " data: \"mesh: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "skeleton: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "name: \\\"{{NAME}}\\\"\\n" + "materials {\\n" + " name: \\\"resource\\\"\\n" + " material: \\\"/shadow_mapping/materials/high/diffuse.material\\\"\\n" + " textures {\\n" + " sampler: \\\"tex0\\\"\\n" + " texture: \\\"/assets/models/forest/resource_texture.png\\\"\\n" + " }\\n" + "}\\n" + "\"\n" + "}\n" + "" + position { + x: -312.0 + z: -101.0 + } + rotation { + z: 0.19936794 + w: 0.9799247 + } + scale3 { + x: 100.0 + y: 200.0 + z: 200.0 + } +} +embedded_instances { + id: "pallet5" + data: "components {\n" + " id: \"model_tiers\"\n" + " component: \"/shadow_mapping/model_tiers.script\"\n" + "}\n" + "embedded_components {\n" + " id: \"model\"\n" + " type: \"model\"\n" + " data: \"mesh: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "skeleton: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "name: \\\"{{NAME}}\\\"\\n" + "materials {\\n" + " name: \\\"resource\\\"\\n" + " material: \\\"/shadow_mapping/materials/high/diffuse.material\\\"\\n" + " textures {\\n" + " sampler: \\\"tex0\\\"\\n" + " texture: \\\"/assets/models/forest/resource_texture.png\\\"\\n" + " }\\n" + "}\\n" + "\"\n" + "}\n" + "" + position { + x: -312.0 + z: 188.0 + } + rotation { + z: 0.19936794 + w: 0.9799247 + } + scale3 { + x: 100.0 + y: 200.0 + z: 200.0 + } +} +embedded_instances { + id: "pallet3" + data: "components {\n" + " id: \"model_tiers\"\n" + " component: \"/shadow_mapping/model_tiers.script\"\n" + "}\n" + "embedded_components {\n" + " id: \"model\"\n" + " type: \"model\"\n" + " data: \"mesh: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "skeleton: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "name: \\\"{{NAME}}\\\"\\n" + "materials {\\n" + " name: \\\"resource\\\"\\n" + " material: \\\"/shadow_mapping/materials/high/diffuse.material\\\"\\n" + " textures {\\n" + " sampler: \\\"tex0\\\"\\n" + " texture: \\\"/assets/models/forest/resource_texture.png\\\"\\n" + " }\\n" + "}\\n" + "\"\n" + "}\n" + "" + position { + x: 187.0 + y: 11.0 + z: -114.0 + } + rotation { + y: -1.0 + w: 6.123234E-17 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +embedded_instances { + id: "pallet" + data: "components {\n" + " id: \"model_tiers\"\n" + " component: \"/shadow_mapping/model_tiers.script\"\n" + "}\n" + "embedded_components {\n" + " id: \"model\"\n" + " type: \"model\"\n" + " data: \"mesh: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "skeleton: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "name: \\\"{{NAME}}\\\"\\n" + "materials {\\n" + " name: \\\"resource\\\"\\n" + " material: \\\"/shadow_mapping/materials/high/diffuse.material\\\"\\n" + " textures {\\n" + " sampler: \\\"tex0\\\"\\n" + " texture: \\\"/assets/models/forest/resource_texture.png\\\"\\n" + " }\\n" + "}\\n" + "\"\n" + "}\n" + "" + position { + x: -116.0 + y: 11.0 + z: -111.0 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +embedded_instances { + id: "collider" + data: "embedded_components {\n" + " id: \"collisionobject\"\n" + " type: \"collisionobject\"\n" + " data: \"type: COLLISION_OBJECT_TYPE_STATIC\\n" + "mass: 0.0\\n" + "friction: 0.1\\n" + "restitution: 0.5\\n" + "group: \\\"env\\\"\\n" + "mask: \\\"ball\\\"\\n" + "mask: \\\"player\\\"\\n" + "embedded_collision_shape {\\n" + " shapes {\\n" + " shape_type: TYPE_BOX\\n" + " position {\\n" + " x: 33.96\\n" + " y: 20.99\\n" + " }\\n" + " rotation {\\n" + " }\\n" + " index: 0\\n" + " count: 3\\n" + " }\\n" + " shapes {\\n" + " shape_type: TYPE_BOX\\n" + " position {\\n" + " x: -310.0\\n" + " y: -6.0\\n" + " }\\n" + " rotation {\\n" + " z: 0.2332732\\n" + " w: 0.9724113\\n" + " }\\n" + " index: 3\\n" + " count: 3\\n" + " }\\n" + " data: 305.0\\n" + " data: 50.0\\n" + " data: 295.0\\n" + " data: 70.0\\n" + " data: 50.0\\n" + " data: 295.0\\n" + "}\\n" + "\"\n" + "}\n" + "" + position { + z: 39.0 + } +} diff --git a/assets/models/forest/collections/rise.collection b/assets/models/forest/collections/rise.collection new file mode 100644 index 0000000..dcf00fc --- /dev/null +++ b/assets/models/forest/collections/rise.collection @@ -0,0 +1,124 @@ +name: "rise" +scale_along_z: 0 +embedded_instances { + id: "pallet" + data: "components {\n" + " id: \"model_tiers\"\n" + " component: \"/shadow_mapping/model_tiers.script\"\n" + "}\n" + "embedded_components {\n" + " id: \"model\"\n" + " type: \"model\"\n" + " data: \"mesh: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "skeleton: \\\"/assets/models/forest/sources/Pallet_Wood.gltf\\\"\\n" + "name: \\\"{{NAME}}\\\"\\n" + "materials {\\n" + " name: \\\"resource\\\"\\n" + " material: \\\"/shadow_mapping/materials/high/diffuse.material\\\"\\n" + " textures {\\n" + " sampler: \\\"tex0\\\"\\n" + " texture: \\\"/assets/models/forest/resource_texture.png\\\"\\n" + " }\\n" + "}\\n" + "\"\n" + "}\n" + "" + position { + x: 379.0 + y: 35.0 + z: -310.0 + } + rotation { + x: -0.063478015 + y: -0.22889434 + z: 0.25958985 + w: 0.9360508 + } + scale3 { + x: 200.0 + y: 210.0 + z: 200.0 + } +} +embedded_instances { + id: "wood_planks" + data: "components {\n" + " id: \"model_tiers\"\n" + " component: \"/shadow_mapping/model_tiers.script\"\n" + "}\n" + "embedded_components {\n" + " id: \"collisionobject\"\n" + " type: \"collisionobject\"\n" + " data: \"type: COLLISION_OBJECT_TYPE_STATIC\\n" + "mass: 0.0\\n" + "friction: 0.1\\n" + "restitution: 0.5\\n" + "group: \\\"env\\\"\\n" + "mask: \\\"ball\\\"\\n" + "mask: \\\"player\\\"\\n" + "embedded_collision_shape {\\n" + " shapes {\\n" + " shape_type: TYPE_BOX\\n" + " position {\\n" + " y: 0.3\\n" + " }\\n" + " rotation {\\n" + " }\\n" + " index: 0\\n" + " count: 3\\n" + " }\\n" + " shapes {\\n" + " shape_type: TYPE_BOX\\n" + " position {\\n" + " x: -1.404259\\n" + " y: 0.114286\\n" + " z: 0.041135\\n" + " }\\n" + " rotation {\\n" + " z: 0.25881904\\n" + " w: 0.9659258\\n" + " }\\n" + " index: 3\\n" + " count: 3\\n" + " }\\n" + " data: 0.840772\\n" + " data: 0.3246425\\n" + " data: 0.7755415\\n" + " data: 0.75\\n" + " data: 0.15\\n" + " data: 0.55\\n" + "}\\n" + "\"\n" + "}\n" + "embedded_components {\n" + " id: \"model\"\n" + " type: \"model\"\n" + " data: \"mesh: \\\"/assets/models/forest/sources/Wood_Planks_Stack_Medium.gltf\\\"\\n" + "skeleton: \\\"/assets/models/forest/sources/Wood_Planks_Stack_Medium.gltf\\\"\\n" + "name: \\\"{{NAME}}\\\"\\n" + "materials {\\n" + " name: \\\"resource\\\"\\n" + " material: \\\"/shadow_mapping/materials/high/diffuse.material\\\"\\n" + " textures {\\n" + " sampler: \\\"tex0\\\"\\n" + " texture: \\\"/assets/models/forest/resource_texture.png\\\"\\n" + " }\\n" + "}\\n" + "\"\n" + "}\n" + "" + position { + x: 674.0 + y: -10.0 + z: -168.0 + } + rotation { + y: -0.22629432 + w: 0.974059 + } + scale3 { + x: 280.0 + y: 280.0 + z: 280.0 + } +} diff --git a/assets/models/forest/forest_texture.png b/assets/models/forest/forest_texture.png new file mode 100644 index 0000000..3674554 Binary files /dev/null and b/assets/models/forest/forest_texture.png differ diff --git a/assets/models/forest/gameobjects/fuel_barell.go b/assets/models/forest/gameobjects/fuel_barell.go new file mode 100644 index 0000000..f3a417a --- /dev/null +++ b/assets/models/forest/gameobjects/fuel_barell.go @@ -0,0 +1,53 @@ +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} +embedded_components { + id: "model" + type: "model" + data: "mesh: \"/assets/models/forest/sources/Fuel_C_Barrel.gltf\"\n" + "skeleton: \"/assets/models/forest/sources/Fuel_C_Barrel.gltf\"\n" + "name: \"{{NAME}}\"\n" + "materials {\n" + " name: \"resource\"\n" + " material: \"/shadow_mapping/materials/high/diffuse.material\"\n" + " textures {\n" + " sampler: \"tex0\"\n" + " texture: \"/assets/models/forest/resource_texture.png\"\n" + " }\n" + "}\n" + "" + position { + y: -0.5 + } +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_DYNAMIC\n" + "mass: 5.0\n" + "friction: 0.9\n" + "restitution: 0.5\n" + "group: \"ball\"\n" + "mask: \"player\"\n" + "mask: \"ground\"\n" + "mask: \"ball\"\n" + "mask: \"env\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " }\n" + " data: 0.3735\n" + " data: 0.5\n" + " data: 0.372039\n" + "}\n" + "linear_damping: 0.8\n" + "angular_damping: 0.5\n" + "" +} diff --git a/assets/models/forest/gameobjects/gold_bar.go b/assets/models/forest/gameobjects/gold_bar.go new file mode 100644 index 0000000..54391fb --- /dev/null +++ b/assets/models/forest/gameobjects/gold_bar.go @@ -0,0 +1,54 @@ +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_DYNAMIC\n" + "mass: 20.0\n" + "friction: 0.95\n" + "restitution: 0.7\n" + "group: \"gold\"\n" + "mask: \"player\"\n" + "mask: \"ground\"\n" + "mask: \"ball\"\n" + "mask: \"env\"\n" + "mask: \"gold\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " }\n" + " data: 0.1959175\n" + " data: 0.128296\n" + " data: 0.3538555\n" + "}\n" + "linear_damping: 0.9\n" + "angular_damping: 0.7\n" + "" +} +embedded_components { + id: "model" + type: "model" + data: "mesh: \"/assets/models/forest/sources/Gold_Bar.gltf\"\n" + "skeleton: \"/assets/models/forest/sources/Grass_1_C_Color1.glb\"\n" + "name: \"{{NAME}}\"\n" + "materials {\n" + " name: \"resource\"\n" + " material: \"/shadow_mapping/materials/high/diffuse.material\"\n" + " textures {\n" + " sampler: \"tex0\"\n" + " texture: \"/assets/models/forest/resource_texture.png\"\n" + " }\n" + "}\n" + "" + position { + y: -0.13 + } +} diff --git a/assets/models/forest/gameobjects/grass.go b/assets/models/forest/gameobjects/grass.go new file mode 100644 index 0000000..c41b768 --- /dev/null +++ b/assets/models/forest/gameobjects/grass.go @@ -0,0 +1,8 @@ +components { + id: "model" + component: "/assets/models/forest/models/grass_1.model" +} +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} diff --git a/assets/models/forest/gameobjects/pallet.go b/assets/models/forest/gameobjects/pallet.go new file mode 100644 index 0000000..77b06bc --- /dev/null +++ b/assets/models/forest/gameobjects/pallet.go @@ -0,0 +1,47 @@ +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} +embedded_components { + id: "model" + type: "model" + data: "mesh: \"/assets/models/forest/sources/Pallet_Wood.gltf\"\n" + "skeleton: \"/assets/models/forest/sources/Pallet_Wood.gltf\"\n" + "name: \"{{NAME}}\"\n" + "materials {\n" + " name: \"resource\"\n" + " material: \"/shadow_mapping/materials/high/diffuse.material\"\n" + " textures {\n" + " sampler: \"tex0\"\n" + " texture: \"/assets/models/forest/resource_texture.png\"\n" + " }\n" + "}\n" + "" +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_STATIC\n" + "mass: 0.0\n" + "friction: 0.1\n" + "restitution: 0.5\n" + "group: \"env\"\n" + "mask: \"ball\"\n" + "mask: \"player\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " y: 0.15\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " }\n" + " data: 0.75\n" + " data: 0.15\n" + " data: 0.75\n" + "}\n" + "" +} diff --git a/assets/models/forest/gameobjects/pallet_covered.go b/assets/models/forest/gameobjects/pallet_covered.go new file mode 100644 index 0000000..cffdf5f --- /dev/null +++ b/assets/models/forest/gameobjects/pallet_covered.go @@ -0,0 +1,48 @@ +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} +embedded_components { + id: "model" + type: "model" + data: "mesh: \"/assets/models/forest/sources/Pallet_Wood_Covered_B.gltf\"\n" + "skeleton: \"/assets/models/forest/sources/Pallet_Wood_Covered_B.gltf\"\n" + "name: \"{{NAME}}\"\n" + "materials {\n" + " name: \"resource\"\n" + " material: \"/shadow_mapping/materials/high/diffuse.material\"\n" + " textures {\n" + " sampler: \"tex0\"\n" + " texture: \"/assets/models/forest/resource_texture.png\"\n" + " }\n" + "}\n" + "" +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_STATIC\n" + "mass: 0.0\n" + "friction: 0.1\n" + "restitution: 0.5\n" + "group: \"env\"\n" + "mask: \"ball\"\n" + "mask: \"player\"\n" + "mask: \"gold\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " y: 0.15\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " }\n" + " data: 0.75\n" + " data: 0.15\n" + " data: 0.75\n" + "}\n" + "" +} diff --git a/assets/models/forest/gameobjects/rock.go b/assets/models/forest/gameobjects/rock.go new file mode 100644 index 0000000..f1fd4ac --- /dev/null +++ b/assets/models/forest/gameobjects/rock.go @@ -0,0 +1,35 @@ +components { + id: "model" + component: "/assets/models/forest/models/rock_1.model" +} +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_STATIC\n" + "mass: 0.0\n" + "friction: 0.1\n" + "restitution: 0.5\n" + "group: \"env\"\n" + "mask: \"ball\"\n" + "mask: \"player\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " x: 0.3\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " }\n" + " data: 2.5\n" + " data: 2.0\n" + " data: 2.0\n" + "}\n" + "" +} diff --git a/assets/models/forest/gameobjects/tree.go b/assets/models/forest/gameobjects/tree.go new file mode 100644 index 0000000..f7466ed --- /dev/null +++ b/assets/models/forest/gameobjects/tree.go @@ -0,0 +1,35 @@ +components { + id: "model" + component: "/assets/models/forest/models/tree_1.model" +} +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_STATIC\n" + "mass: 0.0\n" + "friction: 0.1\n" + "restitution: 0.5\n" + "group: \"env\"\n" + "mask: \"ball\"\n" + "mask: \"player\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " y: 3.0\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " }\n" + " data: 0.2993205\n" + " data: 3.5\n" + " data: 0.272852\n" + "}\n" + "" +} diff --git a/assets/models/forest/gameobjects/wall.go b/assets/models/forest/gameobjects/wall.go new file mode 100644 index 0000000..9421ef9 --- /dev/null +++ b/assets/models/forest/gameobjects/wall.go @@ -0,0 +1,28 @@ +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_STATIC\n" + "mass: 0.0\n" + "friction: 0.1\n" + "restitution: 0.5\n" + "group: \"env\"\n" + "mask: \"ball\"\n" + "mask: \"player\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " x: -0.04\n" + " y: 0.99\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " }\n" + " data: 0.5\n" + " data: 1.89509\n" + " data: 2.988252\n" + "}\n" + "" +} diff --git a/assets/models/forest/gameobjects/wood_1.go b/assets/models/forest/gameobjects/wood_1.go new file mode 100644 index 0000000..936d03a --- /dev/null +++ b/assets/models/forest/gameobjects/wood_1.go @@ -0,0 +1,47 @@ +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} +embedded_components { + id: "model" + type: "model" + data: "mesh: \"/assets/models/forest/sources/Wood_Log_B.gltf\"\n" + "skeleton: \"/assets/models/forest/sources/Wood_Log_B.gltf\"\n" + "name: \"{{NAME}}\"\n" + "materials {\n" + " name: \"resource\"\n" + " material: \"/shadow_mapping/materials/high/diffuse.material\"\n" + " textures {\n" + " sampler: \"tex0\"\n" + " texture: \"/assets/models/forest/resource_texture.png\"\n" + " }\n" + "}\n" + "" +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_STATIC\n" + "mass: 0.0\n" + "friction: 0.1\n" + "restitution: 0.5\n" + "group: \"env\"\n" + "mask: \"ball\"\n" + "mask: \"player\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " y: 0.8\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " }\n" + " data: 0.275\n" + " data: 1.191809\n" + " data: 0.675\n" + "}\n" + "" +} diff --git a/assets/models/forest/gameobjects/wood_2.go b/assets/models/forest/gameobjects/wood_2.go new file mode 100644 index 0000000..c8119bf --- /dev/null +++ b/assets/models/forest/gameobjects/wood_2.go @@ -0,0 +1,47 @@ +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} +embedded_components { + id: "model" + type: "model" + data: "mesh: \"/assets/models/forest/sources/Wood_Log_A.gltf\"\n" + "skeleton: \"/assets/models/forest/sources/Wood_Log_A.gltf\"\n" + "name: \"{{NAME}}\"\n" + "materials {\n" + " name: \"resource\"\n" + " material: \"/shadow_mapping/materials/high/diffuse.material\"\n" + " textures {\n" + " sampler: \"tex0\"\n" + " texture: \"/assets/models/forest/resource_texture.png\"\n" + " }\n" + "}\n" + "" +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_STATIC\n" + "mass: 0.0\n" + "friction: 0.1\n" + "restitution: 0.5\n" + "group: \"env\"\n" + "mask: \"ball\"\n" + "mask: \"player\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " y: 0.8\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " }\n" + " data: 0.275\n" + " data: 1.191809\n" + " data: 0.675\n" + "}\n" + "" +} diff --git a/assets/models/forest/gameobjects/wood_planks.go b/assets/models/forest/gameobjects/wood_planks.go new file mode 100644 index 0000000..e669c0d --- /dev/null +++ b/assets/models/forest/gameobjects/wood_planks.go @@ -0,0 +1,47 @@ +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} +embedded_components { + id: "model" + type: "model" + data: "mesh: \"/assets/models/forest/sources/Wood_Planks_Stack_Medium.gltf\"\n" + "skeleton: \"/assets/models/forest/sources/Wood_Planks_Stack_Medium.gltf\"\n" + "name: \"{{NAME}}\"\n" + "materials {\n" + " name: \"resource\"\n" + " material: \"/shadow_mapping/materials/high/diffuse.material\"\n" + " textures {\n" + " sampler: \"tex0\"\n" + " texture: \"/assets/models/forest/resource_texture.png\"\n" + " }\n" + "}\n" + "" +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_STATIC\n" + "mass: 0.0\n" + "friction: 0.1\n" + "restitution: 0.5\n" + "group: \"env\"\n" + "mask: \"ball\"\n" + "mask: \"player\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " y: 0.3\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " }\n" + " data: 0.840772\n" + " data: 0.3246425\n" + " data: 0.7755415\n" + "}\n" + "" +} diff --git a/assets/models/forest/models/grass_1.model b/assets/models/forest/models/grass_1.model new file mode 100644 index 0000000..347cd56 --- /dev/null +++ b/assets/models/forest/models/grass_1.model @@ -0,0 +1,11 @@ +mesh: "/assets/models/forest/sources/Grass_1_C_Color1.glb" +skeleton: "/assets/models/forest/sources/Grass_1_C_Color1.glb" +name: "tree_4_b_color1" +materials { + name: "forest.004" + material: "/shadow_mapping/materials/high/diffuse.material" + textures { + sampler: "tex0" + texture: "/assets/models/forest/forest_texture.png" + } +} diff --git a/assets/models/forest/models/rock_1.model b/assets/models/forest/models/rock_1.model new file mode 100644 index 0000000..7d39baf --- /dev/null +++ b/assets/models/forest/models/rock_1.model @@ -0,0 +1,11 @@ +mesh: "/assets/models/forest/sources/Rock_3_R_Color1.glb" +name: "rock_1" +materials { + name: "forest.015" + material: "/shadow_mapping/materials/high/diffuse.material" + textures { + sampler: "tex0" + texture: "/assets/models/forest/forest_texture.png" + } +} +create_go_bones: false diff --git a/assets/models/forest/models/tree_1.model b/assets/models/forest/models/tree_1.model new file mode 100644 index 0000000..6426ae6 --- /dev/null +++ b/assets/models/forest/models/tree_1.model @@ -0,0 +1,11 @@ +mesh: "/assets/models/forest/sources/Tree_4_B_Color1.glb" +skeleton: "/assets/models/forest/sources/Tree_4_B_Color1.glb" +name: "tree_4_b_color1" +materials { + name: "forest.001" + material: "/shadow_mapping/materials/high/diffuse.material" + textures { + sampler: "tex0" + texture: "/assets/models/forest/forest_texture.png" + } +} diff --git a/assets/models/forest/resource_texture.png b/assets/models/forest/resource_texture.png new file mode 100644 index 0000000..b0e6fab Binary files /dev/null and b/assets/models/forest/resource_texture.png differ diff --git a/assets/models/forest/sources/Fuel_C_Barrel.bin b/assets/models/forest/sources/Fuel_C_Barrel.bin new file mode 100644 index 0000000..42fda50 Binary files /dev/null and b/assets/models/forest/sources/Fuel_C_Barrel.bin differ diff --git a/assets/models/forest/sources/Fuel_C_Barrel.gltf b/assets/models/forest/sources/Fuel_C_Barrel.gltf new file mode 100644 index 0000000..91349ca --- /dev/null +++ b/assets/models/forest/sources/Fuel_C_Barrel.gltf @@ -0,0 +1,136 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v3.4.50", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Fuel_C_Barrel" + } + ], + "materials" : [ + { + "name" : "resource", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 0.5 + } + } + ], + "meshes" : [ + { + "name" : "Fuel_C_Barrel", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "TEXCOORD_0" : 1, + "NORMAL" : 2 + }, + "indices" : 3, + "material" : 0 + } + ] + } + ], + "textures" : [ + { + "sampler" : 0, + "source" : 0 + } + ], + "images" : [ + { + "mimeType" : "image/png", + "name" : "resource_bits_texture", + "uri" : "resource_bits_texture.png" + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 795, + "max" : [ + 0.375, + 1.0075005292892456, + 0.3749999701976776 + ], + "min" : [ + -0.375, + 0, + -0.375 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 795, + "type" : "VEC2" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 795, + "type" : "VEC3" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 2604, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 9540, + "byteOffset" : 0, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 6360, + "byteOffset" : 9540, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 9540, + "byteOffset" : 15900, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 5208, + "byteOffset" : 25440, + "target" : 34963 + } + ], + "samplers" : [ + { + "magFilter" : 9729, + "minFilter" : 9987 + } + ], + "buffers" : [ + { + "byteLength" : 30648, + "uri" : "Fuel_C_Barrel.bin" + } + ] +} diff --git a/assets/models/forest/sources/Gold_Bar.bin b/assets/models/forest/sources/Gold_Bar.bin new file mode 100644 index 0000000..1314952 Binary files /dev/null and b/assets/models/forest/sources/Gold_Bar.bin differ diff --git a/assets/models/forest/sources/Gold_Bar.gltf b/assets/models/forest/sources/Gold_Bar.gltf new file mode 100644 index 0000000..7894f10 --- /dev/null +++ b/assets/models/forest/sources/Gold_Bar.gltf @@ -0,0 +1,136 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v3.4.50", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Gold_Bar" + } + ], + "materials" : [ + { + "name" : "resource", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 0.5 + } + } + ], + "meshes" : [ + { + "name" : "Gold_Bar", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "TEXCOORD_0" : 1, + "NORMAL" : 2 + }, + "indices" : 3, + "material" : 0 + } + ] + } + ], + "textures" : [ + { + "sampler" : 0, + "source" : 0 + } + ], + "images" : [ + { + "mimeType" : "image/png", + "name" : "resource_bits_texture", + "uri" : "resource_bits_texture.png" + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 100, + "max" : [ + 0.20000000298023224, + 0.2499999701976776, + 0.4000000059604645 + ], + "min" : [ + -0.20000000298023224, + 1.862645149230957e-08, + -0.4000000059604645 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 100, + "type" : "VEC2" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 100, + "type" : "VEC3" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 324, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 1200, + "byteOffset" : 0, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 800, + "byteOffset" : 1200, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 1200, + "byteOffset" : 2000, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 648, + "byteOffset" : 3200, + "target" : 34963 + } + ], + "samplers" : [ + { + "magFilter" : 9729, + "minFilter" : 9987 + } + ], + "buffers" : [ + { + "byteLength" : 3848, + "uri" : "Gold_Bar.bin" + } + ] +} diff --git a/assets/models/forest/sources/Grass_1_C_Color1.glb b/assets/models/forest/sources/Grass_1_C_Color1.glb new file mode 100644 index 0000000..ffa140c Binary files /dev/null and b/assets/models/forest/sources/Grass_1_C_Color1.glb differ diff --git a/assets/models/forest/sources/Pallet_Wood.bin b/assets/models/forest/sources/Pallet_Wood.bin new file mode 100644 index 0000000..c1b9836 Binary files /dev/null and b/assets/models/forest/sources/Pallet_Wood.bin differ diff --git a/assets/models/forest/sources/Pallet_Wood.gltf b/assets/models/forest/sources/Pallet_Wood.gltf new file mode 100644 index 0000000..dbcbe04 --- /dev/null +++ b/assets/models/forest/sources/Pallet_Wood.gltf @@ -0,0 +1,136 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v3.4.50", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Pallet_Wood" + } + ], + "materials" : [ + { + "name" : "resource", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 0.5 + } + } + ], + "meshes" : [ + { + "name" : "Pallet_Wood", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "TEXCOORD_0" : 1, + "NORMAL" : 2 + }, + "indices" : 3, + "material" : 0 + } + ] + } + ], + "textures" : [ + { + "sampler" : 0, + "source" : 0 + } + ], + "images" : [ + { + "mimeType" : "image/png", + "name" : "resource_bits_texture", + "uri" : "resource_bits_texture.png" + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 378, + "max" : [ + 0.7762372493743896, + 0.30000030994415283, + 0.7505994439125061 + ], + "min" : [ + -0.7757527828216553, + -6.386198680985444e-09, + -0.7505992650985718 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 378, + "type" : "VEC2" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 378, + "type" : "VEC3" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 576, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 4536, + "byteOffset" : 0, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 3024, + "byteOffset" : 4536, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 4536, + "byteOffset" : 7560, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 1152, + "byteOffset" : 12096, + "target" : 34963 + } + ], + "samplers" : [ + { + "magFilter" : 9729, + "minFilter" : 9987 + } + ], + "buffers" : [ + { + "byteLength" : 13248, + "uri" : "Pallet_Wood.bin" + } + ] +} diff --git a/assets/models/forest/sources/Pallet_Wood_Covered_B.bin b/assets/models/forest/sources/Pallet_Wood_Covered_B.bin new file mode 100644 index 0000000..cc8716e Binary files /dev/null and b/assets/models/forest/sources/Pallet_Wood_Covered_B.bin differ diff --git a/assets/models/forest/sources/Pallet_Wood_Covered_B.gltf b/assets/models/forest/sources/Pallet_Wood_Covered_B.gltf new file mode 100644 index 0000000..a88406f --- /dev/null +++ b/assets/models/forest/sources/Pallet_Wood_Covered_B.gltf @@ -0,0 +1,136 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v3.4.50", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Pallet_Wood_Covered_B" + } + ], + "materials" : [ + { + "name" : "resource", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 0.5 + } + } + ], + "meshes" : [ + { + "name" : "Pallet_Wood_Covered_B", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "TEXCOORD_0" : 1, + "NORMAL" : 2 + }, + "indices" : 3, + "material" : 0 + } + ] + } + ], + "textures" : [ + { + "sampler" : 0, + "source" : 0 + } + ], + "images" : [ + { + "mimeType" : "image/png", + "name" : "resource_bits_texture", + "uri" : "resource_bits_texture.png" + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 432, + "max" : [ + 0.8621161580085754, + 0.29999998211860657, + 0.8621161580085754 + ], + "min" : [ + -0.8621161580085754, + -6.386198680985444e-09, + -0.8621161580085754 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 432, + "type" : "VEC2" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 432, + "type" : "VEC3" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 1098, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 5184, + "byteOffset" : 0, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 3456, + "byteOffset" : 5184, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 5184, + "byteOffset" : 8640, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 2196, + "byteOffset" : 13824, + "target" : 34963 + } + ], + "samplers" : [ + { + "magFilter" : 9729, + "minFilter" : 9987 + } + ], + "buffers" : [ + { + "byteLength" : 16020, + "uri" : "Pallet_Wood_Covered_B.bin" + } + ] +} diff --git a/assets/models/forest/sources/Rock_3_R_Color1.glb b/assets/models/forest/sources/Rock_3_R_Color1.glb new file mode 100644 index 0000000..eca0fa0 Binary files /dev/null and b/assets/models/forest/sources/Rock_3_R_Color1.glb differ diff --git a/assets/models/forest/sources/Stone_Chunks_Large.bin b/assets/models/forest/sources/Stone_Chunks_Large.bin new file mode 100644 index 0000000..ee28fb8 Binary files /dev/null and b/assets/models/forest/sources/Stone_Chunks_Large.bin differ diff --git a/assets/models/forest/sources/Stone_Chunks_Large.gltf b/assets/models/forest/sources/Stone_Chunks_Large.gltf new file mode 100644 index 0000000..17b9182 --- /dev/null +++ b/assets/models/forest/sources/Stone_Chunks_Large.gltf @@ -0,0 +1,136 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v3.4.50", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Stone_Chunks_Large" + } + ], + "materials" : [ + { + "name" : "resource", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 0.5 + } + } + ], + "meshes" : [ + { + "name" : "Stone_Chunks_Large", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "TEXCOORD_0" : 1, + "NORMAL" : 2 + }, + "indices" : 3, + "material" : 0 + } + ] + } + ], + "textures" : [ + { + "sampler" : 0, + "source" : 0 + } + ], + "images" : [ + { + "mimeType" : "image/png", + "name" : "resource_bits_texture", + "uri" : "resource_bits_texture.png" + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 2516, + "max" : [ + 0.736940860748291, + 1.0401904582977295, + 0.6740157008171082 + ], + "min" : [ + -0.7641547322273254, + -0.03707057237625122, + -0.6718781590461731 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 2516, + "type" : "VEC2" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 2516, + "type" : "VEC3" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 4734, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 30192, + "byteOffset" : 0, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 20128, + "byteOffset" : 30192, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 30192, + "byteOffset" : 50320, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 9468, + "byteOffset" : 80512, + "target" : 34963 + } + ], + "samplers" : [ + { + "magFilter" : 9729, + "minFilter" : 9987 + } + ], + "buffers" : [ + { + "byteLength" : 89980, + "uri" : "Stone_Chunks_Large.bin" + } + ] +} diff --git a/assets/models/forest/sources/Tree_4_B_Color1.glb b/assets/models/forest/sources/Tree_4_B_Color1.glb new file mode 100644 index 0000000..348ef4b Binary files /dev/null and b/assets/models/forest/sources/Tree_4_B_Color1.glb differ diff --git a/assets/models/forest/sources/Wood_Log_A.bin b/assets/models/forest/sources/Wood_Log_A.bin new file mode 100644 index 0000000..91a737b Binary files /dev/null and b/assets/models/forest/sources/Wood_Log_A.bin differ diff --git a/assets/models/forest/sources/Wood_Log_A.gltf b/assets/models/forest/sources/Wood_Log_A.gltf new file mode 100644 index 0000000..bed16dd --- /dev/null +++ b/assets/models/forest/sources/Wood_Log_A.gltf @@ -0,0 +1,136 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v3.4.50", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Wood_Log_A" + } + ], + "materials" : [ + { + "name" : "resource", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 0.5 + } + } + ], + "meshes" : [ + { + "name" : "Wood_Log_A", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "TEXCOORD_0" : 1, + "NORMAL" : 2 + }, + "indices" : 3, + "material" : 0 + } + ] + } + ], + "textures" : [ + { + "sampler" : 0, + "source" : 0 + } + ], + "images" : [ + { + "mimeType" : "image/png", + "name" : "resource_bits_texture", + "uri" : "resource_bits_texture.png" + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 1118, + "max" : [ + 0.3650985658168793, + 0.45747488737106323, + 0.6750365495681763 + ], + "min" : [ + -0.35627028346061707, + -0.2758808434009552, + -0.6749634742736816 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 1118, + "type" : "VEC2" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 1118, + "type" : "VEC3" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 2268, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 13416, + "byteOffset" : 0, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 8944, + "byteOffset" : 13416, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 13416, + "byteOffset" : 22360, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 4536, + "byteOffset" : 35776, + "target" : 34963 + } + ], + "samplers" : [ + { + "magFilter" : 9729, + "minFilter" : 9987 + } + ], + "buffers" : [ + { + "byteLength" : 40312, + "uri" : "Wood_Log_A.bin" + } + ] +} diff --git a/assets/models/forest/sources/Wood_Log_B.bin b/assets/models/forest/sources/Wood_Log_B.bin new file mode 100644 index 0000000..68fa537 Binary files /dev/null and b/assets/models/forest/sources/Wood_Log_B.bin differ diff --git a/assets/models/forest/sources/Wood_Log_B.gltf b/assets/models/forest/sources/Wood_Log_B.gltf new file mode 100644 index 0000000..d94a79c --- /dev/null +++ b/assets/models/forest/sources/Wood_Log_B.gltf @@ -0,0 +1,136 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v3.4.50", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Wood_Log_B" + } + ], + "materials" : [ + { + "name" : "resource", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 0.5 + } + } + ], + "meshes" : [ + { + "name" : "Wood_Log_B", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "TEXCOORD_0" : 1, + "NORMAL" : 2 + }, + "indices" : 3, + "material" : 0 + } + ] + } + ], + "textures" : [ + { + "sampler" : 0, + "source" : 0 + } + ], + "images" : [ + { + "mimeType" : "image/png", + "name" : "resource_bits_texture", + "uri" : "resource_bits_texture.png" + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 860, + "max" : [ + 0.2745094895362854, + 0.2747161388397217, + 0.6750365495681763 + ], + "min" : [ + -0.2745342254638672, + -0.2758808434009552, + -0.6749634742736816 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 860, + "type" : "VEC2" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 860, + "type" : "VEC3" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 1740, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 10320, + "byteOffset" : 0, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 6880, + "byteOffset" : 10320, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 10320, + "byteOffset" : 17200, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 3480, + "byteOffset" : 27520, + "target" : 34963 + } + ], + "samplers" : [ + { + "magFilter" : 9729, + "minFilter" : 9987 + } + ], + "buffers" : [ + { + "byteLength" : 31000, + "uri" : "Wood_Log_B.bin" + } + ] +} diff --git a/assets/models/forest/sources/Wood_Planks_Stack_Medium.bin b/assets/models/forest/sources/Wood_Planks_Stack_Medium.bin new file mode 100644 index 0000000..1fa1419 Binary files /dev/null and b/assets/models/forest/sources/Wood_Planks_Stack_Medium.bin differ diff --git a/assets/models/forest/sources/Wood_Planks_Stack_Medium.gltf b/assets/models/forest/sources/Wood_Planks_Stack_Medium.gltf new file mode 100644 index 0000000..4948959 --- /dev/null +++ b/assets/models/forest/sources/Wood_Planks_Stack_Medium.gltf @@ -0,0 +1,136 @@ +{ + "asset" : { + "generator" : "Khronos glTF Blender I/O v3.4.50", + "version" : "2.0" + }, + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Wood_Planks_Stack_Medium" + } + ], + "materials" : [ + { + "name" : "resource", + "pbrMetallicRoughness" : { + "baseColorTexture" : { + "index" : 0 + }, + "metallicFactor" : 0, + "roughnessFactor" : 0.5 + } + } + ], + "meshes" : [ + { + "name" : "Wood_Planks_Stack_Medium", + "primitives" : [ + { + "attributes" : { + "POSITION" : 0, + "TEXCOORD_0" : 1, + "NORMAL" : 2 + }, + "indices" : 3, + "material" : 0 + } + ] + } + ], + "textures" : [ + { + "sampler" : 0, + "source" : 0 + } + ], + "images" : [ + { + "mimeType" : "image/png", + "name" : "resource_bits_texture", + "uri" : "resource_bits_texture.png" + } + ], + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 1334, + "max" : [ + 0.8330650329589844, + 0.6165961027145386, + 0.8040671348571777 + ], + "min" : [ + -0.8330650329589844, + -0.00659605860710144, + -0.8111829161643982 + ], + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 1334, + "type" : "VEC2" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 1334, + "type" : "VEC3" + }, + { + "bufferView" : 3, + "componentType" : 5123, + "count" : 2112, + "type" : "SCALAR" + } + ], + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 16008, + "byteOffset" : 0, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 10672, + "byteOffset" : 16008, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 16008, + "byteOffset" : 26680, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 4224, + "byteOffset" : 42688, + "target" : 34963 + } + ], + "samplers" : [ + { + "magFilter" : 9729, + "minFilter" : 9987 + } + ], + "buffers" : [ + { + "byteLength" : 46912, + "uri" : "Wood_Planks_Stack_Medium.bin" + } + ] +} diff --git a/assets/models/platformer/gameobjects/ball.go b/assets/models/platformer/gameobjects/ball.go new file mode 100644 index 0000000..c4bc51c --- /dev/null +++ b/assets/models/platformer/gameobjects/ball.go @@ -0,0 +1,36 @@ +components { + id: "model" + component: "/assets/models/platformer/models/ball.model" +} +components { + id: "model_tiers" + component: "/shadow_mapping/model_tiers.script" +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_DYNAMIC\n" + "mass: 5.0\n" + "friction: 0.9\n" + "restitution: 0.5\n" + "group: \"ball\"\n" + "mask: \"player\"\n" + "mask: \"ground\"\n" + "mask: \"ball\"\n" + "mask: \"env\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_SPHERE\n" + " position {\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 1\n" + " }\n" + " data: 1.0\n" + "}\n" + "linear_damping: 0.8\n" + "angular_damping: 0.5\n" + "" +} diff --git a/assets/models/platformer/models/ball.model b/assets/models/platformer/models/ball.model new file mode 100644 index 0000000..582b02a --- /dev/null +++ b/assets/models/platformer/models/ball.model @@ -0,0 +1,10 @@ +mesh: "/assets/models/platformer/sources/ball.glb" +name: "ball" +materials { + name: "platformer.002" + material: "/shadow_mapping/materials/high/diffuse.material" + textures { + sampler: "tex0" + texture: "/assets/models/platformer/platformer_texture.png" + } +} diff --git a/assets/models/platformer/platformer_texture.png b/assets/models/platformer/platformer_texture.png new file mode 100755 index 0000000..7fb200c Binary files /dev/null and b/assets/models/platformer/platformer_texture.png differ diff --git a/assets/models/platformer/sources/ball.glb b/assets/models/platformer/sources/ball.glb new file mode 100644 index 0000000..7418a8f Binary files /dev/null and b/assets/models/platformer/sources/ball.glb differ diff --git a/assets/tilemap/surface_tilesheet.png b/assets/tilemap/surface_tilesheet.png new file mode 100644 index 0000000..a816e69 Binary files /dev/null and b/assets/tilemap/surface_tilesheet.png differ diff --git a/game.project b/game.project new file mode 100644 index 0000000..0fb0674 --- /dev/null +++ b/game.project @@ -0,0 +1,60 @@ +[bootstrap] +main_collection = /game/game.collectionc +render = /render/custom.renderc + +[script] +shared_state = 1 + +[display] +width = 1136 +height = 640 +high_dpi = 1 +display_profiles = /render/custom.display_profilesc + +[android] +input_method = HiddenInputField +package = com.defold.sample.thirdpersonplayground + +[project] +dependencies = +title = ThirdPersonPlayground + +[physics] +type = 3D +scale = 0.01 +gravity_y = -2500.0 +max_collisions = 128 +max_contacts = 256 +trigger_overlap_capacity = 32 +use_fixed_timestep = 1 + +[osx] +bundle_identifier = com.defold.sample.thirdpersonplayground + +[ios] +bundle_identifier = com.defold.sample.thirdpersonplayground + +[html5] +scale_mode = stretch + +[native_extension] +app_manifest = /app.appmanifest + +[render] +clear_color_red = 1.0 +clear_color_green = 1.0 +clear_color_blue = 1.0 + +[graphics] +texture_profiles = /render/custom.texture_profiles + +[input] +game_binding = /input/game.input_bindingc + +[tilemap] +max_tile_count = 4096 + +[engine] +fixed_update_frequency = 60 +max_time_step = 1.0 + diff --git a/game/controller.gui b/game/controller.gui new file mode 100644 index 0000000..df080e1 --- /dev/null +++ b/game/controller.gui @@ -0,0 +1,74 @@ +script: "/game/controller.gui_script" +textures { + name: "game" + texture: "/assets/game.atlas" +} +nodes { + position { + x: 852.0 + y: 320.0 + } + size { + x: 568.0 + y: 640.0 + } + type: TYPE_BOX + texture: "game/alpha" + id: "joystick_area" + xanchor: XANCHOR_RIGHT + yanchor: YANCHOR_BOTTOM + layer: "img" + inherit_alpha: true +} +nodes { + position { + x: 803.0 + y: 336.0 + } + size { + x: 250.0 + y: 250.0 + } + color { + x: 0.6 + y: 0.702 + } + type: TYPE_BOX + texture: "game/cicle" + id: "joystick_back" + xanchor: XANCHOR_RIGHT + yanchor: YANCHOR_BOTTOM + layer: "img" + inherit_alpha: true + alpha: 0.3 +} +nodes { + position { + x: 803.0 + y: 336.0 + } + size { + x: 100.0 + y: 100.0 + } + color { + x: 0.6 + y: 0.702 + } + type: TYPE_BOX + texture: "game/cicle" + id: "joystick_move" + xanchor: XANCHOR_RIGHT + yanchor: YANCHOR_BOTTOM + layer: "img" + inherit_alpha: true + alpha: 0.75 +} +layers { + name: "img" +} +layers { + name: "txt" +} +material: "/builtins/materials/gui.material" +adjust_reference: ADJUST_REFERENCE_PARENT diff --git a/game/controller.gui_script b/game/controller.gui_script new file mode 100644 index 0000000..8012bb3 --- /dev/null +++ b/game/controller.gui_script @@ -0,0 +1,48 @@ +function init(self) + msg.post(".", "acquire_input_focus") + + self.joystick_area = gui.get_node("joystick_area") + self.joystick_back = gui.get_node("joystick_back") + self.joystick_move = gui.get_node("joystick_move") + self.center = gui.get_position(self.joystick_move) + self.position = vmath.vector3(self.center) + self.direction = vmath.vector3(0, 0, 1) + self.max_distance = gui.get_size(self.joystick_back).x / 2 + self.joystick_active = false +end + +function on_input(self, action_id, action) + if action_id == hash("touch") then + if self.joystick_active then + if action.released then + ---Reset position + self.joystick_active = false + gui.set_position(self.joystick_move, self.center) + msg.post("game:/player/character", hash("MOVE"), { direction = self.direction, strength = 0 }) + else + self.direction.x = action.x - self.center.x + self.direction.y = action.y - self.center.y + local length = vmath.length(self.direction) + if length ~= 0 then + self.direction = vmath.normalize(self.direction) + end + self.position.x = action.x + self.position.y = action.y + if length > self.max_distance then + self.position.x = self.center.x + self.direction.x * self.max_distance + self.position.y = self.center.y + self.direction.y * self.max_distance + length = self.max_distance + end + gui.set_position(self.joystick_move, self.position) + msg.post("game:/player/character", hash("MOVE"), { direction = self.direction, strength = length / self.max_distance }) + end + elseif gui.pick_node(self.joystick_area, action.x, action.y) and action.pressed then + self.center.x = action.x + self.center.y = action.y + self.direction.z = 1 + gui.set_position(self.joystick_back, self.center) + gui.set_position(self.joystick_move, self.center) + self.joystick_active = true + end + end +end diff --git a/game/game.collection b/game/game.collection new file mode 100644 index 0000000..2014c22 --- /dev/null +++ b/game/game.collection @@ -0,0 +1,38 @@ +name: "game" +collection_instances { + id: "player" + collection: "/game/player.collection" + rotation { + y: -0.26723838 + w: 0.96363044 + } +} +collection_instances { + id: "world" + collection: "/game/world.collection" +} +scale_along_z: 0 +embedded_instances { + id: "game" + data: "components {\n" + " id: \"shadows\"\n" + " component: \"/game/shadows.script\"\n" + "}\n" + "" +} +embedded_instances { + id: "controller" + data: "components {\n" + " id: \"gui\"\n" + " component: \"/game/controller.gui\"\n" + "}\n" + "" +} +embedded_instances { + id: "tier_service" + data: "components {\n" + " id: \"tier_service\"\n" + " component: \"/shadow_mapping/tier_service.script\"\n" + "}\n" + "" +} diff --git a/game/player.collection b/game/player.collection new file mode 100644 index 0000000..0c2497a --- /dev/null +++ b/game/player.collection @@ -0,0 +1,116 @@ +name: "player" +scale_along_z: 0 +embedded_instances { + id: "character" + children: "camera" + children: "character_rotation" + data: "components {\n" + " id: \"collisions\"\n" + " component: \"/game/player_collisions.script\"\n" + "}\n" + "components {\n" + " id: \"player\"\n" + " component: \"/game/player_controller.script\"\n" + "}\n" + "embedded_components {\n" + " id: \"collisionobject\"\n" + " type: \"collisionobject\"\n" + " data: \"type: COLLISION_OBJECT_TYPE_DYNAMIC\\n" + "mass: 80.0\\n" + "friction: 0.9\\n" + "restitution: 0.0\\n" + "group: \\\"player\\\"\\n" + "mask: \\\"ground\\\"\\n" + "mask: \\\"ball\\\"\\n" + "mask: \\\"env\\\"\\n" + "mask: \\\"gold\\\"\\n" + "mask: \\\"gold_target\\\"\\n" + "embedded_collision_shape {\\n" + " shapes {\\n" + " shape_type: TYPE_BOX\\n" + " position {\\n" + " y: 50.0\\n" + " }\\n" + " rotation {\\n" + " }\\n" + " index: 0\\n" + " count: 3\\n" + " }\\n" + " data: 50.0\\n" + " data: 50.0\\n" + " data: 50.0\\n" + "}\\n" + "linear_damping: 0.99\\n" + "angular_damping: 0.9\\n" + "locked_rotation: true\\n" + "\"\n" + "}\n" + "" +} +embedded_instances { + id: "camera" + data: "embedded_components {\n" + " id: \"camera\"\n" + " type: \"camera\"\n" + " data: \"aspect_ratio: 1.0\\n" + "fov: 0.7854\\n" + "near_z: 0.1\\n" + "far_z: 5000.0\\n" + "auto_aspect_ratio: 1\\n" + "\"\n" + "}\n" + "" + position { + y: 1660.0 + z: 830.0 + } + rotation { + x: -0.4539905 + w: 0.8910065 + } +} +embedded_instances { + id: "character_rotation" + children: "character_model" + data: "" +} +embedded_instances { + id: "character_model" + data: "components {\n" + " id: \"model\"\n" + " component: \"/assets/models/character/character.model\"\n" + " rotation {\n" + " x: -0.70710677\n" + " w: 0.70710677\n" + " }\n" + "}\n" + "components {\n" + " id: \"model_tiers\"\n" + " component: \"/shadow_mapping/model_tiers.script\"\n" + " properties {\n" + " id: \"low_material\"\n" + " value: \"/shadow_mapping/materials/low/diffuse_skinning.material\"\n" + " type: PROPERTY_TYPE_HASH\n" + " }\n" + " properties {\n" + " id: \"mid_material\"\n" + " value: \"/shadow_mapping/materials/mid/diffuse_skinning.material\"\n" + " type: PROPERTY_TYPE_HASH\n" + " }\n" + " properties {\n" + " id: \"high_material\"\n" + " value: \"/shadow_mapping/materials/high/diffuse_skinning.material\"\n" + " type: PROPERTY_TYPE_HASH\n" + " }\n" + "}\n" + "" + rotation { + x: 0.70710677 + w: 0.70710677 + } + scale3 { + x: 150.0 + y: 150.0 + z: 150.0 + } +} diff --git a/game/player_collisions.script b/game/player_collisions.script new file mode 100644 index 0000000..55bcfe1 --- /dev/null +++ b/game/player_collisions.script @@ -0,0 +1,66 @@ +local MSG_CONTACT_POINT_RESPONSE = hash("contact_point_response") +local MSG_TRIGGER_RESPONSE = hash("trigger_response") + +local GROUP_GOLD = hash("gold") +local GROUP_GOLD_TARGET = hash("gold_target") + +function init(self) + ---Get hand bone from a model + self.url_hand = model.get_go("/player/character_model#model", "DEF-handL") + self.gold_release_position = go.get_position("/world/gold_release_position") + self.bars = {} +end + +function on_message(self, message_id, message, sender) + -- Handle collision + if message_id == MSG_CONTACT_POINT_RESPONSE then + if message.other_group == GROUP_GOLD then + ---If we already added bar to the stack then we skip code + for key, bar in pairs(self.bars) do + if bar.go_id == message.other_id then + return + end + end + local bar_body = msg.url(nil, message.other_id, "collisionobject") + ---Attach the bar to the bone + go.set_parent(message.other_id, self.url_hand, true) + ---Disable the bar body + msg.post(bar_body, "disable") + ---Move the bar to a new position + local stack_position = vmath.vector3(0, - #self.bars * 0.2, 0) + go.animate(message.other_id, "position", go.PLAYBACK_ONCE_FORWARD, stack_position, go.EASING_OUTSINE, 0.5) + go.animate(message.other_id, "rotation", go.PLAYBACK_ONCE_FORWARD, vmath.quat_rotation_z(math.rad(180)), + go.EASING_OUTSINE, 0.5) + ---Collect the gold bar to a table + self.bars[#self.bars + 1] = { + body_id = bar_body, + go_id = message.other_id + } + end + elseif message_id == MSG_TRIGGER_RESPONSE then + if message.other_group == GROUP_GOLD_TARGET then + if message.enter and #self.bars > 0 then + ---Start a timer to remove gold bars + ---This can also be done in the update function + self.remove_timer = timer.delay(0.3, true, function() + if #self.bars > 0 then + ---Remove a gold bar from the model + local bar = table.remove(self.bars) + go.set_parent(bar.go_id, nil, true) + ---Move the gold bar to the gold release position + go.animate(bar.go_id, "position", go.PLAYBACK_ONCE_FORWARD, self.gold_release_position, + go.EASING_OUTSINE, 0.2, 0, function() + ---Enable the body of the gold bar. + go.set_position(self.gold_release_position, bar.body_id) + msg.post(bar.body_id, "enable") + end) + end + end) + elseif self.remove_timer then + ---On exit cancel a timer + timer.cancel(self.remove_timer) + self.remove_timer = nil + end + end + end +end diff --git a/game/player_controller.script b/game/player_controller.script new file mode 100644 index 0000000..cd0dbbb --- /dev/null +++ b/game/player_controller.script @@ -0,0 +1,118 @@ +local ACCELERATION = 800 +local ROTATION_SPEED = 200 -- degrees per second (for keyboard controls) +local MIN_VELOCITY_FOR_MOVING = 1 +local MIN_VELOCITY_FOR_RUNNING = 700 + +local ACTION_FORWARD = hash("forward") +local ACTION_BACK = hash("back") +local ACTION_LEFT = hash("left") +local ACTION_RIGHT = hash("right") + +--- Character animation states +local STATES = { + IDLE = 1, + WALKING = 2, + RUN = 3, +} + +local function rotate_point(point, phi) + local cos = math.cos(phi) + local sin = math.sin(phi) + local result = vmath.vector3() + result.x = point.x * cos - point.y * sin + result.y = point.x * sin + point.y * cos + return result +end + +local function play_anim(anim_id, playback, play_properties, complete_function) + model.play_anim("/player/character_model#model", anim_id, playback, play_properties, complete_function) +end + +local function run(self) + if self.state ~= STATES.RUN then + self.state = STATES.RUN + play_anim("Jog_Fwd_Loop", go.PLAYBACK_LOOP_FORWARD, { blend_duration = 0.2 }) + end +end + +local function walk(self) + if self.state ~= STATES.WALKING then + self.state = STATES.WALKING + play_anim("Walk_Loop", go.PLAYBACK_LOOP_FORWARD, { blend_duration = 0.2 }) + end +end + +local function idle(self) + if self.state ~= STATES.IDLE then + self.state = STATES.IDLE + play_anim("Idle_Loop", go.PLAYBACK_LOOP_FORWARD, { blend_duration = 0.2 }) + end +end + +function init(self) + msg.post(".", "acquire_input_focus") + + self.state = STATES.IDLE + -- Direction of rotation (-1 = counter clockwise, 1 = clockwise, 0 = no rotation) + self.rotation = 0 + -- Direction of movement (-1 = backwards, 1 = forwards, 0 = no movement) + self.movement = 0 + + -- the force to apply to the player, in Newton + self.force = vmath.vector3() + + -- Base rotation of the player character in the world. This rotation should not change + -- and it is only set at "design time" in the game.collection. The child game object + -- /player/character_rotation is the one we rotate to visually rotate the player model + self.base_rotation = math.rad(go.get("/player/character", "euler.y")) + self.direction = vmath.vector3(math.sin(self.base_rotation), -math.cos(self.base_rotation), 0) +end + +function update(self, dt) + -- Update animations based on current velocity + local velocity = vmath.length(go.get("#collisionobject", "linear_velocity")) + if velocity >= MIN_VELOCITY_FOR_RUNNING then + run(self) + elseif velocity > MIN_VELOCITY_FOR_MOVING then + walk(self) + else + idle(self) + end + + -- Apply a new rotation to the character + local rotation = math.atan2(self.direction.x, -self.direction.y) + if self.rotation ~= 0 then + rotation = rotation - self.rotation * math.rad(ROTATION_SPEED) * dt + self.direction.x = math.sin(rotation) + self.direction.y = -math.cos(rotation) + end + go.set_rotation(vmath.quat_rotation_y(rotation - self.base_rotation), "/player/character_rotation") +end + +function fixed_update(self, dt) + -- Apply force to a character if moving + if self.movement ~= 0 then + self.force.x = self.direction.x * self.movement * ACCELERATION * 1000 + self.force.z = -self.direction.y * self.movement * ACCELERATION * 1000 + msg.post("#collisionobject", "apply_force", { force = self.force, position = go.get_position() }) + end +end + +function on_message(self, message_id, message, sender) + if message_id == hash("MOVE") then + self.direction = rotate_point(message.direction, self.base_rotation) + self.movement = message.strength + end +end + +function on_input(self, action_id, action) + if action_id == ACTION_FORWARD then + self.movement = action.value + elseif action_id == ACTION_BACK then + self.movement = -action.value + elseif action_id == ACTION_LEFT then + self.rotation = -action.value + elseif action_id == ACTION_RIGHT then + self.rotation = action.value + end +end \ No newline at end of file diff --git a/game/shadows.script b/game/shadows.script new file mode 100644 index 0000000..78adc7d --- /dev/null +++ b/game/shadows.script @@ -0,0 +1,15 @@ +local shadow_mapping = require "shadow_mapping.shadow_mapping" + +function init(self) + ---Shadows settings + local width = 10000 + local height = 10000 + local near = 1 + local far = 20000 + local proj = vmath.matrix4_orthographic(-width / 2, width / 2, -height / 2, height / 2, near, far) + shadow_mapping.set_light_projection(proj) + + local position = vmath.vector3(-535, 8264, 5604) + local rotation = vmath.quat_rotation_y(math.rad(-5)) * vmath.quat_rotation_x(math.rad(-58)) + shadow_mapping.calculate_light_transform(position, rotation) +end diff --git a/game/surface/surface.tilemap b/game/surface/surface.tilemap new file mode 100644 index 0000000..192f144 --- /dev/null +++ b/game/surface/surface.tilemap @@ -0,0 +1,14676 @@ +tile_set: "/game/surface/surface_tiles.tilesource" +layers { + id: "map" + z: 0.0 + cell { + x: 14 + y: -24 + tile: 186 + } + cell { + x: 1 + y: -23 + tile: 186 + } + cell { + x: 2 + y: -23 + tile: 186 + } + cell { + x: 3 + y: -23 + tile: 186 + } + cell { + x: 4 + y: -23 + tile: 186 + } + cell { + x: 5 + y: -23 + tile: 186 + } + cell { + x: 6 + y: -23 + tile: 186 + } + cell { + x: 7 + y: -23 + tile: 186 + } + cell { + x: 8 + y: -23 + tile: 186 + } + cell { + x: 9 + y: -23 + tile: 186 + } + cell { + x: 10 + y: -23 + tile: 186 + } + cell { + x: 11 + y: -23 + tile: 186 + } + cell { + x: 12 + y: -23 + tile: 186 + } + cell { + x: 13 + y: -23 + tile: 186 + } + cell { + x: 14 + y: -23 + tile: 186 + } + cell { + x: 15 + y: -23 + tile: 186 + } + cell { + x: 16 + y: -23 + tile: 186 + } + cell { + x: 17 + y: -23 + tile: 186 + } + cell { + x: 18 + y: -23 + tile: 186 + } + cell { + x: 19 + y: -23 + tile: 186 + } + cell { + x: 20 + y: -23 + tile: 186 + } + cell { + x: 21 + y: -23 + tile: 186 + } + cell { + x: 22 + y: -23 + tile: 186 + } + cell { + x: 23 + y: -23 + tile: 186 + } + cell { + x: 0 + y: -22 + tile: 186 + } + cell { + x: 1 + y: -22 + tile: 186 + } + cell { + x: 2 + y: -22 + tile: 186 + } + cell { + x: 3 + y: -22 + tile: 186 + } + cell { + x: 4 + y: -22 + tile: 186 + } + cell { + x: 5 + y: -22 + tile: 186 + } + cell { + x: 6 + y: -22 + tile: 186 + } + cell { + x: 7 + y: -22 + tile: 186 + } + cell { + x: 8 + y: -22 + tile: 186 + } + cell { + x: 9 + y: -22 + tile: 186 + } + cell { + x: 10 + y: -22 + tile: 186 + } + cell { + x: 11 + y: -22 + tile: 186 + } + cell { + x: 12 + y: -22 + tile: 186 + } + cell { + x: 13 + y: -22 + tile: 186 + } + cell { + x: 14 + y: -22 + tile: 186 + } + cell { + x: 15 + y: -22 + tile: 186 + } + cell { + x: 16 + y: -22 + tile: 186 + } + cell { + x: 17 + y: -22 + tile: 186 + } + cell { + x: 18 + y: -22 + tile: 186 + } + cell { + x: 19 + y: -22 + tile: 186 + } + cell { + x: 20 + y: -22 + tile: 186 + } + cell { + x: 21 + y: -22 + tile: 186 + } + cell { + x: 22 + y: -22 + tile: 186 + } + cell { + x: 23 + y: -22 + tile: 186 + } + cell { + x: 24 + y: -22 + tile: 186 + } + cell { + x: 25 + y: -22 + tile: 186 + } + cell { + x: -6 + y: -22 + tile: 186 + } + cell { + x: -4 + y: -22 + tile: 186 + } + cell { + x: -3 + y: -22 + tile: 186 + } + cell { + x: -2 + y: -22 + tile: 186 + } + cell { + x: -1 + y: -22 + tile: 186 + } + cell { + x: 0 + y: -21 + tile: 186 + } + cell { + x: 1 + y: -21 + tile: 186 + } + cell { + x: 2 + y: -21 + tile: 186 + } + cell { + x: 3 + y: -21 + tile: 186 + } + cell { + x: 4 + y: -21 + tile: 186 + } + cell { + x: 5 + y: -21 + tile: 186 + } + cell { + x: 6 + y: -21 + tile: 186 + } + cell { + x: 7 + y: -21 + tile: 186 + } + cell { + x: 8 + y: -21 + tile: 186 + } + cell { + x: 9 + y: -21 + tile: 186 + } + cell { + x: 10 + y: -21 + tile: 186 + } + cell { + x: 11 + y: -21 + tile: 186 + } + cell { + x: 12 + y: -21 + tile: 186 + } + cell { + x: 13 + y: -21 + tile: 186 + } + cell { + x: 14 + y: -21 + tile: 23 + } + cell { + x: 15 + y: -21 + tile: 186 + } + cell { + x: 16 + y: -21 + tile: 186 + } + cell { + x: 17 + y: -21 + tile: 186 + } + cell { + x: 18 + y: -21 + tile: 186 + } + cell { + x: 19 + y: -21 + tile: 186 + } + cell { + x: 20 + y: -21 + tile: 186 + } + cell { + x: 21 + y: -21 + tile: 186 + } + cell { + x: 22 + y: -21 + tile: 186 + } + cell { + x: 23 + y: -21 + tile: 186 + } + cell { + x: 24 + y: -21 + tile: 186 + } + cell { + x: 25 + y: -21 + tile: 186 + } + cell { + x: 26 + y: -21 + tile: 186 + } + cell { + x: -6 + y: -21 + tile: 186 + } + cell { + x: -5 + y: -21 + tile: 186 + } + cell { + x: -4 + y: -21 + tile: 186 + } + cell { + x: -3 + y: -21 + tile: 186 + } + cell { + x: -2 + y: -21 + tile: 186 + } + cell { + x: -1 + y: -21 + tile: 186 + } + cell { + x: 0 + y: -20 + tile: 186 + } + cell { + x: 1 + y: -20 + tile: 186 + } + cell { + x: 2 + y: -20 + tile: 186 + } + cell { + x: 3 + y: -20 + tile: 86 + } + cell { + x: 4 + y: -20 + tile: 86 + } + cell { + x: 5 + y: -20 + tile: 186 + } + cell { + x: 6 + y: -20 + tile: 86 + } + cell { + x: 7 + y: -20 + tile: 86 + } + cell { + x: 8 + y: -20 + tile: 86 + } + cell { + x: 9 + y: -20 + tile: 86 + } + cell { + x: 10 + y: -20 + tile: 86 + } + cell { + x: 11 + y: -20 + tile: 86 + } + cell { + x: 12 + y: -20 + tile: 86 + } + cell { + x: 13 + y: -20 + tile: 23 + } + cell { + x: 14 + y: -20 + tile: 23 + } + cell { + x: 15 + y: -20 + tile: 23 + } + cell { + x: 16 + y: -20 + tile: 23 + } + cell { + x: 17 + y: -20 + tile: 23 + } + cell { + x: 18 + y: -20 + tile: 23 + } + cell { + x: 19 + y: -20 + tile: 186 + } + cell { + x: 20 + y: -20 + tile: 186 + } + cell { + x: 21 + y: -20 + tile: 186 + } + cell { + x: 22 + y: -20 + tile: 186 + } + cell { + x: 23 + y: -20 + tile: 186 + } + cell { + x: 24 + y: -20 + tile: 186 + } + cell { + x: 25 + y: -20 + tile: 186 + } + cell { + x: 26 + y: -20 + tile: 186 + } + cell { + x: -6 + y: -20 + tile: 186 + } + cell { + x: -5 + y: -20 + tile: 186 + } + cell { + x: -4 + y: -20 + tile: 186 + } + cell { + x: -3 + y: -20 + tile: 186 + } + cell { + x: -2 + y: -20 + tile: 186 + } + cell { + x: -1 + y: -20 + tile: 186 + } + cell { + x: 0 + y: -19 + tile: 86 + } + cell { + x: 1 + y: -19 + tile: 86 + } + cell { + x: 2 + y: -19 + tile: 86 + } + cell { + x: 3 + y: -19 + tile: 86 + } + cell { + x: 4 + y: -19 + tile: 86 + } + cell { + x: 5 + y: -19 + tile: 86 + } + cell { + x: 6 + y: -19 + tile: 86 + } + cell { + x: 7 + y: -19 + tile: 86 + } + cell { + x: 8 + y: -19 + tile: 86 + } + cell { + x: 9 + y: -19 + tile: 86 + } + cell { + x: 10 + y: -19 + tile: 86 + } + cell { + x: 11 + y: -19 + tile: 86 + } + cell { + x: 12 + y: -19 + tile: 23 + } + cell { + x: 13 + y: -19 + tile: 23 + } + cell { + x: 14 + y: -19 + tile: 23 + } + cell { + x: 15 + y: -19 + tile: 23 + } + cell { + x: 16 + y: -19 + tile: 23 + } + cell { + x: 17 + y: -19 + tile: 23 + } + cell { + x: 18 + y: -19 + tile: 23 + } + cell { + x: 19 + y: -19 + tile: 23 + } + cell { + x: 20 + y: -19 + tile: 23 + } + cell { + x: 21 + y: -19 + tile: 23 + } + cell { + x: 22 + y: -19 + tile: 23 + } + cell { + x: 23 + y: -19 + tile: 23 + } + cell { + x: 24 + y: -19 + tile: 23 + } + cell { + x: 25 + y: -19 + tile: 186 + } + cell { + x: 26 + y: -19 + tile: 186 + } + cell { + x: 27 + y: -19 + tile: 186 + } + cell { + x: -6 + y: -19 + tile: 186 + } + cell { + x: -5 + y: -19 + tile: 186 + } + cell { + x: -4 + y: -19 + tile: 186 + } + cell { + x: -3 + y: -19 + tile: 186 + } + cell { + x: -2 + y: -19 + tile: 186 + } + cell { + x: -1 + y: -19 + tile: 186 + } + cell { + x: 0 + y: -18 + tile: 86 + } + cell { + x: 1 + y: -18 + tile: 86 + } + cell { + x: 2 + y: -18 + tile: 86 + } + cell { + x: 3 + y: -18 + tile: 86 + } + cell { + x: 4 + y: -18 + tile: 86 + } + cell { + x: 5 + y: -18 + tile: 86 + } + cell { + x: 6 + y: -18 + tile: 86 + } + cell { + x: 7 + y: -18 + tile: 86 + } + cell { + x: 8 + y: -18 + tile: 86 + } + cell { + x: 9 + y: -18 + tile: 23 + } + cell { + x: 10 + y: -18 + tile: 23 + } + cell { + x: 11 + y: -18 + tile: 23 + } + cell { + x: 12 + y: -18 + tile: 23 + } + cell { + x: 13 + y: -18 + tile: 23 + } + cell { + x: 14 + y: -18 + tile: 23 + } + cell { + x: 15 + y: -18 + tile: 23 + } + cell { + x: 16 + y: -18 + tile: 23 + } + cell { + x: 17 + y: -18 + tile: 23 + } + cell { + x: 18 + y: -18 + tile: 23 + } + cell { + x: 19 + y: -18 + tile: 23 + } + cell { + x: 20 + y: -18 + tile: 23 + } + cell { + x: 21 + y: -18 + tile: 23 + } + cell { + x: 22 + y: -18 + tile: 23 + } + cell { + x: 23 + y: -18 + tile: 23 + } + cell { + x: 24 + y: -18 + tile: 23 + } + cell { + x: 25 + y: -18 + tile: 23 + } + cell { + x: 26 + y: -18 + tile: 186 + } + cell { + x: 27 + y: -18 + tile: 186 + } + cell { + x: -7 + y: -18 + tile: 186 + } + cell { + x: -6 + y: -18 + tile: 186 + } + cell { + x: -5 + y: -18 + tile: 186 + } + cell { + x: -4 + y: -18 + tile: 186 + } + cell { + x: -3 + y: -18 + tile: 186 + } + cell { + x: -2 + y: -18 + tile: 86 + } + cell { + x: -1 + y: -18 + tile: 86 + } + cell { + x: 0 + y: -17 + tile: 86 + } + cell { + x: 1 + y: -17 + tile: 86 + } + cell { + x: 2 + y: -17 + tile: 86 + } + cell { + x: 3 + y: -17 + tile: 86 + } + cell { + x: 4 + y: -17 + tile: 86 + } + cell { + x: 5 + y: -17 + tile: 23 + } + cell { + x: 6 + y: -17 + tile: 23 + } + cell { + x: 7 + y: -17 + tile: 23 + } + cell { + x: 8 + y: -17 + tile: 23 + } + cell { + x: 9 + y: -17 + tile: 23 + } + cell { + x: 10 + y: -17 + tile: 23 + } + cell { + x: 11 + y: -17 + tile: 23 + } + cell { + x: 12 + y: -17 + tile: 23 + } + cell { + x: 13 + y: -17 + tile: 23 + } + cell { + x: 14 + y: -17 + tile: 23 + } + cell { + x: 15 + y: -17 + tile: 23 + } + cell { + x: 16 + y: -17 + tile: 23 + } + cell { + x: 17 + y: -17 + tile: 23 + } + cell { + x: 18 + y: -17 + tile: 23 + } + cell { + x: 19 + y: -17 + tile: 23 + } + cell { + x: 20 + y: -17 + tile: 23 + } + cell { + x: 21 + y: -17 + tile: 23 + } + cell { + x: 22 + y: -17 + tile: 23 + } + cell { + x: 23 + y: -17 + tile: 23 + } + cell { + x: 24 + y: -17 + tile: 23 + } + cell { + x: 25 + y: -17 + tile: 23 + } + cell { + x: 26 + y: -17 + tile: 186 + } + cell { + x: 27 + y: -17 + tile: 186 + } + cell { + x: -7 + y: -17 + tile: 186 + } + cell { + x: -6 + y: -17 + tile: 186 + } + cell { + x: -5 + y: -17 + tile: 186 + } + cell { + x: -4 + y: -17 + tile: 186 + } + cell { + x: -3 + y: -17 + tile: 86 + } + cell { + x: -2 + y: -17 + tile: 86 + } + cell { + x: -1 + y: -17 + tile: 86 + } + cell { + x: 0 + y: -16 + tile: 86 + } + cell { + x: 1 + y: -16 + tile: 86 + } + cell { + x: 2 + y: -16 + tile: 86 + } + cell { + x: 3 + y: -16 + tile: 23 + } + cell { + x: 4 + y: -16 + tile: 23 + } + cell { + x: 5 + y: -16 + tile: 23 + } + cell { + x: 6 + y: -16 + tile: 23 + } + cell { + x: 7 + y: -16 + tile: 23 + } + cell { + x: 8 + y: -16 + tile: 23 + } + cell { + x: 9 + y: -16 + tile: 23 + } + cell { + x: 10 + y: -16 + tile: 23 + } + cell { + x: 11 + y: -16 + tile: 23 + } + cell { + x: 12 + y: -16 + tile: 23 + } + cell { + x: 13 + y: -16 + tile: 23 + } + cell { + x: 14 + y: -16 + tile: 23 + } + cell { + x: 15 + y: -16 + tile: 23 + } + cell { + x: 16 + y: -16 + tile: 23 + } + cell { + x: 17 + y: -16 + tile: 23 + } + cell { + x: 18 + y: -16 + tile: 23 + } + cell { + x: 19 + y: -16 + tile: 23 + } + cell { + x: 20 + y: -16 + tile: 23 + } + cell { + x: 21 + y: -16 + tile: 23 + } + cell { + x: 22 + y: -16 + tile: 23 + } + cell { + x: 23 + y: -16 + tile: 23 + } + cell { + x: 24 + y: -16 + tile: 23 + } + cell { + x: 25 + y: -16 + tile: 23 + } + cell { + x: 26 + y: -16 + tile: 186 + } + cell { + x: 27 + y: -16 + tile: 186 + } + cell { + x: -8 + y: -16 + tile: 186 + } + cell { + x: -7 + y: -16 + tile: 186 + } + cell { + x: -6 + y: -16 + tile: 186 + } + cell { + x: -5 + y: -16 + tile: 186 + } + cell { + x: -4 + y: -16 + tile: 86 + } + cell { + x: -3 + y: -16 + tile: 86 + } + cell { + x: -2 + y: -16 + tile: 86 + } + cell { + x: -1 + y: -16 + tile: 86 + } + cell { + x: 0 + y: -15 + tile: 86 + } + cell { + x: 1 + y: -15 + tile: 86 + } + cell { + x: 2 + y: -15 + tile: 23 + } + cell { + x: 3 + y: -15 + tile: 23 + } + cell { + x: 4 + y: -15 + tile: 23 + } + cell { + x: 5 + y: -15 + tile: 23 + } + cell { + x: 6 + y: -15 + tile: 23 + } + cell { + x: 7 + y: -15 + tile: 23 + } + cell { + x: 8 + y: -15 + tile: 23 + } + cell { + x: 9 + y: -15 + tile: 23 + } + cell { + x: 10 + y: -15 + tile: 23 + } + cell { + x: 11 + y: -15 + tile: 23 + } + cell { + x: 12 + y: -15 + tile: 23 + } + cell { + x: 13 + y: -15 + tile: 23 + } + cell { + x: 14 + y: -15 + tile: 23 + } + cell { + x: 15 + y: -15 + tile: 23 + } + cell { + x: 16 + y: -15 + tile: 23 + } + cell { + x: 17 + y: -15 + tile: 23 + } + cell { + x: 18 + y: -15 + tile: 23 + } + cell { + x: 19 + y: -15 + tile: 23 + } + cell { + x: 20 + y: -15 + tile: 23 + } + cell { + x: 21 + y: -15 + tile: 23 + } + cell { + x: 22 + y: -15 + tile: 23 + } + cell { + x: 23 + y: -15 + tile: 23 + } + cell { + x: 24 + y: -15 + tile: 23 + } + cell { + x: 25 + y: -15 + tile: 186 + } + cell { + x: 26 + y: -15 + tile: 186 + } + cell { + x: 27 + y: -15 + tile: 186 + } + cell { + x: 28 + y: -15 + tile: 186 + } + cell { + x: -8 + y: -15 + tile: 186 + } + cell { + x: -7 + y: -15 + tile: 186 + } + cell { + x: -6 + y: -15 + tile: 186 + } + cell { + x: -5 + y: -15 + tile: 186 + } + cell { + x: -4 + y: -15 + tile: 86 + } + cell { + x: -3 + y: -15 + tile: 86 + } + cell { + x: -2 + y: -15 + tile: 86 + } + cell { + x: -1 + y: -15 + tile: 86 + } + cell { + x: 0 + y: -14 + tile: 23 + } + cell { + x: 1 + y: -14 + tile: 23 + } + cell { + x: 2 + y: -14 + tile: 23 + } + cell { + x: 3 + y: -14 + tile: 23 + } + cell { + x: 4 + y: -14 + tile: 23 + } + cell { + x: 5 + y: -14 + tile: 23 + } + cell { + x: 6 + y: -14 + tile: 23 + } + cell { + x: 7 + y: -14 + tile: 23 + } + cell { + x: 8 + y: -14 + tile: 23 + } + cell { + x: 9 + y: -14 + tile: 23 + } + cell { + x: 10 + y: -14 + tile: 23 + } + cell { + x: 11 + y: -14 + tile: 23 + } + cell { + x: 12 + y: -14 + tile: 23 + } + cell { + x: 13 + y: -14 + tile: 23 + } + cell { + x: 14 + y: -14 + tile: 23 + } + cell { + x: 15 + y: -14 + tile: 23 + } + cell { + x: 16 + y: -14 + tile: 23 + } + cell { + x: 17 + y: -14 + tile: 23 + } + cell { + x: 18 + y: -14 + tile: 23 + } + cell { + x: 19 + y: -14 + tile: 23 + } + cell { + x: 20 + y: -14 + tile: 23 + } + cell { + x: 21 + y: -14 + tile: 23 + } + cell { + x: 22 + y: -14 + tile: 23 + } + cell { + x: 23 + y: -14 + tile: 23 + } + cell { + x: 24 + y: -14 + tile: 23 + } + cell { + x: 25 + y: -14 + tile: 186 + } + cell { + x: 26 + y: -14 + tile: 186 + } + cell { + x: 27 + y: -14 + tile: 186 + } + cell { + x: 28 + y: -14 + tile: 186 + } + cell { + x: -8 + y: -14 + tile: 186 + } + cell { + x: -7 + y: -14 + tile: 186 + } + cell { + x: -6 + y: -14 + tile: 186 + } + cell { + x: -5 + y: -14 + tile: 186 + } + cell { + x: -4 + y: -14 + tile: 186 + } + cell { + x: -3 + y: -14 + tile: 86 + } + cell { + x: -2 + y: -14 + tile: 86 + } + cell { + x: -1 + y: -14 + tile: 86 + } + cell { + x: 0 + y: -13 + tile: 23 + } + cell { + x: 1 + y: -13 + tile: 23 + } + cell { + x: 2 + y: -13 + tile: 23 + } + cell { + x: 3 + y: -13 + tile: 23 + } + cell { + x: 4 + y: -13 + tile: 23 + } + cell { + x: 5 + y: -13 + tile: 23 + } + cell { + x: 6 + y: -13 + tile: 23 + } + cell { + x: 7 + y: -13 + tile: 23 + } + cell { + x: 8 + y: -13 + tile: 23 + } + cell { + x: 9 + y: -13 + tile: 23 + } + cell { + x: 10 + y: -13 + tile: 23 + } + cell { + x: 11 + y: -13 + tile: 23 + } + cell { + x: 12 + y: -13 + tile: 23 + } + cell { + x: 13 + y: -13 + tile: 23 + } + cell { + x: 14 + y: -13 + tile: 23 + } + cell { + x: 15 + y: -13 + tile: 23 + } + cell { + x: 16 + y: -13 + tile: 23 + } + cell { + x: 17 + y: -13 + tile: 23 + } + cell { + x: 18 + y: -13 + tile: 23 + } + cell { + x: 19 + y: -13 + tile: 23 + } + cell { + x: 20 + y: -13 + tile: 23 + } + cell { + x: 21 + y: -13 + tile: 23 + } + cell { + x: 22 + y: -13 + tile: 23 + } + cell { + x: 23 + y: -13 + tile: 23 + } + cell { + x: 24 + y: -13 + tile: 23 + } + cell { + x: 25 + y: -13 + tile: 186 + } + cell { + x: 26 + y: -13 + tile: 186 + } + cell { + x: 27 + y: -13 + tile: 186 + } + cell { + x: 28 + y: -13 + tile: 186 + } + cell { + x: -8 + y: -13 + tile: 186 + } + cell { + x: -7 + y: -13 + tile: 186 + } + cell { + x: -6 + y: -13 + tile: 186 + } + cell { + x: -5 + y: -13 + tile: 186 + } + cell { + x: -4 + y: -13 + tile: 86 + } + cell { + x: -3 + y: -13 + tile: 86 + } + cell { + x: -2 + y: -13 + tile: 86 + } + cell { + x: -1 + y: -13 + tile: 86 + } + cell { + x: 0 + y: -12 + tile: 23 + } + cell { + x: 1 + y: -12 + tile: 23 + } + cell { + x: 2 + y: -12 + tile: 23 + } + cell { + x: 3 + y: -12 + tile: 23 + } + cell { + x: 4 + y: -12 + tile: 23 + } + cell { + x: 5 + y: -12 + tile: 23 + } + cell { + x: 6 + y: -12 + tile: 23 + } + cell { + x: 7 + y: -12 + tile: 23 + } + cell { + x: 8 + y: -12 + tile: 23 + } + cell { + x: 9 + y: -12 + tile: 23 + } + cell { + x: 10 + y: -12 + tile: 23 + } + cell { + x: 11 + y: -12 + tile: 23 + } + cell { + x: 12 + y: -12 + tile: 23 + } + cell { + x: 13 + y: -12 + tile: 23 + } + cell { + x: 14 + y: -12 + tile: 23 + } + cell { + x: 15 + y: -12 + tile: 23 + } + cell { + x: 16 + y: -12 + tile: 23 + } + cell { + x: 17 + y: -12 + tile: 23 + } + cell { + x: 18 + y: -12 + tile: 23 + } + cell { + x: 19 + y: -12 + tile: 23 + } + cell { + x: 20 + y: -12 + tile: 23 + } + cell { + x: 21 + y: -12 + tile: 23 + } + cell { + x: 22 + y: -12 + tile: 23 + } + cell { + x: 23 + y: -12 + tile: 23 + } + cell { + x: 24 + y: -12 + tile: 23 + } + cell { + x: 25 + y: -12 + tile: 23 + } + cell { + x: 26 + y: -12 + tile: 186 + } + cell { + x: 27 + y: -12 + tile: 186 + } + cell { + x: 28 + y: -12 + tile: 186 + } + cell { + x: -7 + y: -12 + tile: 186 + } + cell { + x: -6 + y: -12 + tile: 186 + } + cell { + x: -5 + y: -12 + tile: 186 + } + cell { + x: -4 + y: -12 + tile: 86 + } + cell { + x: -3 + y: -12 + tile: 86 + } + cell { + x: -2 + y: -12 + tile: 86 + } + cell { + x: -1 + y: -12 + tile: 86 + } + cell { + x: 0 + y: -11 + tile: 23 + } + cell { + x: 1 + y: -11 + tile: 23 + } + cell { + x: 2 + y: -11 + tile: 23 + } + cell { + x: 3 + y: -11 + tile: 23 + } + cell { + x: 4 + y: -11 + tile: 23 + } + cell { + x: 5 + y: -11 + tile: 23 + } + cell { + x: 6 + y: -11 + tile: 23 + } + cell { + x: 7 + y: -11 + tile: 23 + } + cell { + x: 8 + y: -11 + tile: 23 + } + cell { + x: 9 + y: -11 + tile: 23 + } + cell { + x: 10 + y: -11 + tile: 23 + } + cell { + x: 11 + y: -11 + tile: 23 + } + cell { + x: 12 + y: -11 + tile: 23 + } + cell { + x: 13 + y: -11 + tile: 23 + } + cell { + x: 14 + y: -11 + tile: 23 + } + cell { + x: 15 + y: -11 + tile: 23 + } + cell { + x: 16 + y: -11 + tile: 23 + } + cell { + x: 17 + y: -11 + tile: 23 + } + cell { + x: 18 + y: -11 + tile: 23 + } + cell { + x: 19 + y: -11 + tile: 23 + } + cell { + x: 20 + y: -11 + tile: 23 + } + cell { + x: 21 + y: -11 + tile: 23 + } + cell { + x: 22 + y: -11 + tile: 23 + } + cell { + x: 23 + y: -11 + tile: 23 + } + cell { + x: 24 + y: -11 + tile: 23 + } + cell { + x: 25 + y: -11 + tile: 23 + } + cell { + x: 26 + y: -11 + tile: 186 + } + cell { + x: 27 + y: -11 + tile: 186 + } + cell { + x: 28 + y: -11 + tile: 186 + } + cell { + x: -7 + y: -11 + tile: 186 + } + cell { + x: -6 + y: -11 + tile: 186 + } + cell { + x: -5 + y: -11 + tile: 186 + } + cell { + x: -4 + y: -11 + tile: 86 + } + cell { + x: -3 + y: -11 + tile: 86 + } + cell { + x: -2 + y: -11 + tile: 86 + } + cell { + x: -1 + y: -11 + tile: 86 + } + cell { + x: 0 + y: -10 + tile: 23 + } + cell { + x: 1 + y: -10 + tile: 23 + } + cell { + x: 2 + y: -10 + tile: 23 + } + cell { + x: 3 + y: -10 + tile: 23 + } + cell { + x: 4 + y: -10 + tile: 23 + } + cell { + x: 5 + y: -10 + tile: 23 + } + cell { + x: 6 + y: -10 + tile: 23 + } + cell { + x: 7 + y: -10 + tile: 23 + } + cell { + x: 8 + y: -10 + tile: 23 + } + cell { + x: 9 + y: -10 + tile: 23 + } + cell { + x: 10 + y: -10 + tile: 23 + } + cell { + x: 11 + y: -10 + tile: 23 + } + cell { + x: 12 + y: -10 + tile: 23 + } + cell { + x: 13 + y: -10 + tile: 23 + } + cell { + x: 14 + y: -10 + tile: 23 + } + cell { + x: 15 + y: -10 + tile: 23 + } + cell { + x: 16 + y: -10 + tile: 23 + } + cell { + x: 17 + y: -10 + tile: 23 + } + cell { + x: 18 + y: -10 + tile: 23 + } + cell { + x: 19 + y: -10 + tile: 23 + } + cell { + x: 20 + y: -10 + tile: 23 + } + cell { + x: 21 + y: -10 + tile: 23 + } + cell { + x: 22 + y: -10 + tile: 23 + } + cell { + x: 23 + y: -10 + tile: 23 + } + cell { + x: 24 + y: -10 + tile: 23 + } + cell { + x: 25 + y: -10 + tile: 23 + } + cell { + x: 26 + y: -10 + tile: 186 + } + cell { + x: 27 + y: -10 + tile: 186 + } + cell { + x: 28 + y: -10 + tile: 186 + } + cell { + x: 29 + y: -10 + tile: 186 + } + cell { + x: -8 + y: -10 + tile: 186 + } + cell { + x: -7 + y: -10 + tile: 186 + } + cell { + x: -6 + y: -10 + tile: 186 + } + cell { + x: -5 + y: -10 + tile: 186 + } + cell { + x: -4 + y: -10 + tile: 186 + } + cell { + x: -3 + y: -10 + tile: 86 + } + cell { + x: -2 + y: -10 + tile: 86 + } + cell { + x: -1 + y: -10 + tile: 23 + } + cell { + x: 0 + y: -9 + tile: 23 + } + cell { + x: 1 + y: -9 + tile: 23 + } + cell { + x: 2 + y: -9 + tile: 23 + } + cell { + x: 3 + y: -9 + tile: 23 + } + cell { + x: 4 + y: -9 + tile: 23 + } + cell { + x: 5 + y: -9 + tile: 23 + } + cell { + x: 6 + y: -9 + tile: 23 + } + cell { + x: 7 + y: -9 + tile: 23 + } + cell { + x: 8 + y: -9 + tile: 23 + } + cell { + x: 9 + y: -9 + tile: 23 + } + cell { + x: 10 + y: -9 + tile: 23 + } + cell { + x: 11 + y: -9 + tile: 23 + } + cell { + x: 12 + y: -9 + tile: 23 + } + cell { + x: 13 + y: -9 + tile: 23 + } + cell { + x: 14 + y: -9 + tile: 23 + } + cell { + x: 15 + y: -9 + tile: 23 + } + cell { + x: 16 + y: -9 + tile: 23 + } + cell { + x: 17 + y: -9 + tile: 23 + } + cell { + x: 18 + y: -9 + tile: 23 + } + cell { + x: 19 + y: -9 + tile: 23 + } + cell { + x: 20 + y: -9 + tile: 23 + } + cell { + x: 21 + y: -9 + tile: 23 + } + cell { + x: 22 + y: -9 + tile: 23 + } + cell { + x: 23 + y: -9 + tile: 23 + } + cell { + x: 24 + y: -9 + tile: 23 + } + cell { + x: 25 + y: -9 + tile: 186 + } + cell { + x: 26 + y: -9 + tile: 186 + } + cell { + x: 27 + y: -9 + tile: 186 + } + cell { + x: 28 + y: -9 + tile: 186 + } + cell { + x: 29 + y: -9 + tile: 186 + } + cell { + x: -8 + y: -9 + tile: 186 + } + cell { + x: -7 + y: -9 + tile: 186 + } + cell { + x: -6 + y: -9 + tile: 186 + } + cell { + x: -5 + y: -9 + tile: 186 + } + cell { + x: -4 + y: -9 + tile: 86 + } + cell { + x: -3 + y: -9 + tile: 86 + } + cell { + x: -2 + y: -9 + tile: 86 + } + cell { + x: -1 + y: -9 + tile: 23 + } + cell { + x: 0 + y: -8 + tile: 23 + } + cell { + x: 1 + y: -8 + tile: 23 + } + cell { + x: 2 + y: -8 + tile: 23 + } + cell { + x: 3 + y: -8 + tile: 23 + } + cell { + x: 4 + y: -8 + tile: 23 + } + cell { + x: 5 + y: -8 + tile: 23 + } + cell { + x: 6 + y: -8 + tile: 23 + } + cell { + x: 7 + y: -8 + tile: 23 + } + cell { + x: 8 + y: -8 + tile: 23 + } + cell { + x: 9 + y: -8 + tile: 23 + } + cell { + x: 10 + y: -8 + tile: 23 + } + cell { + x: 11 + y: -8 + tile: 23 + } + cell { + x: 12 + y: -8 + tile: 23 + } + cell { + x: 13 + y: -8 + tile: 23 + } + cell { + x: 14 + y: -8 + tile: 23 + } + cell { + x: 15 + y: -8 + tile: 23 + } + cell { + x: 16 + y: -8 + tile: 23 + } + cell { + x: 17 + y: -8 + tile: 23 + } + cell { + x: 18 + y: -8 + tile: 23 + } + cell { + x: 19 + y: -8 + tile: 23 + } + cell { + x: 20 + y: -8 + tile: 23 + } + cell { + x: 21 + y: -8 + tile: 23 + } + cell { + x: 22 + y: -8 + tile: 23 + } + cell { + x: 23 + y: -8 + tile: 23 + } + cell { + x: 24 + y: -8 + tile: 186 + } + cell { + x: 25 + y: -8 + tile: 186 + } + cell { + x: 26 + y: -8 + tile: 186 + } + cell { + x: 27 + y: -8 + tile: 186 + } + cell { + x: 28 + y: -8 + tile: 186 + } + cell { + x: 29 + y: -8 + tile: 186 + } + cell { + x: -8 + y: -8 + tile: 186 + } + cell { + x: -7 + y: -8 + tile: 186 + } + cell { + x: -6 + y: -8 + tile: 186 + } + cell { + x: -5 + y: -8 + tile: 186 + } + cell { + x: -4 + y: -8 + tile: 86 + } + cell { + x: -3 + y: -8 + tile: 86 + } + cell { + x: -2 + y: -8 + tile: 86 + } + cell { + x: -1 + y: -8 + tile: 23 + } + cell { + x: 0 + y: -7 + tile: 23 + } + cell { + x: 1 + y: -7 + tile: 23 + } + cell { + x: 2 + y: -7 + tile: 23 + } + cell { + x: 3 + y: -7 + tile: 23 + } + cell { + x: 4 + y: -7 + tile: 23 + } + cell { + x: 5 + y: -7 + tile: 23 + } + cell { + x: 6 + y: -7 + tile: 23 + } + cell { + x: 7 + y: -7 + tile: 23 + } + cell { + x: 8 + y: -7 + tile: 23 + } + cell { + x: 9 + y: -7 + tile: 23 + } + cell { + x: 10 + y: -7 + tile: 23 + } + cell { + x: 11 + y: -7 + tile: 23 + } + cell { + x: 12 + y: -7 + tile: 23 + } + cell { + x: 13 + y: -7 + tile: 23 + } + cell { + x: 14 + y: -7 + tile: 23 + } + cell { + x: 15 + y: -7 + tile: 23 + } + cell { + x: 16 + y: -7 + tile: 23 + } + cell { + x: 17 + y: -7 + tile: 23 + } + cell { + x: 18 + y: -7 + tile: 23 + } + cell { + x: 19 + y: -7 + tile: 23 + } + cell { + x: 20 + y: -7 + tile: 23 + } + cell { + x: 21 + y: -7 + tile: 23 + } + cell { + x: 22 + y: -7 + tile: 23 + } + cell { + x: 23 + y: -7 + tile: 23 + } + cell { + x: 24 + y: -7 + tile: 23 + } + cell { + x: 25 + y: -7 + tile: 186 + } + cell { + x: 26 + y: -7 + tile: 186 + } + cell { + x: 27 + y: -7 + tile: 186 + } + cell { + x: 28 + y: -7 + tile: 186 + } + cell { + x: 29 + y: -7 + tile: 186 + } + cell { + x: 30 + y: -7 + tile: 186 + } + cell { + x: 32 + y: -7 + tile: 186 + } + cell { + x: 33 + y: -7 + tile: 186 + } + cell { + x: 35 + y: -7 + tile: 186 + } + cell { + x: 36 + y: -7 + tile: 186 + } + cell { + x: -9 + y: -7 + tile: 186 + } + cell { + x: -8 + y: -7 + tile: 186 + } + cell { + x: -7 + y: -7 + tile: 186 + } + cell { + x: -6 + y: -7 + tile: 186 + } + cell { + x: -5 + y: -7 + tile: 186 + } + cell { + x: -4 + y: -7 + tile: 86 + } + cell { + x: -3 + y: -7 + tile: 86 + } + cell { + x: -2 + y: -7 + tile: 86 + } + cell { + x: -1 + y: -7 + tile: 23 + } + cell { + x: 0 + y: -6 + tile: 23 + } + cell { + x: 1 + y: -6 + tile: 23 + } + cell { + x: 2 + y: -6 + tile: 23 + } + cell { + x: 3 + y: -6 + tile: 23 + } + cell { + x: 4 + y: -6 + tile: 23 + } + cell { + x: 5 + y: -6 + tile: 23 + } + cell { + x: 6 + y: -6 + tile: 23 + } + cell { + x: 7 + y: -6 + tile: 23 + } + cell { + x: 8 + y: -6 + tile: 23 + } + cell { + x: 9 + y: -6 + tile: 23 + } + cell { + x: 10 + y: -6 + tile: 23 + } + cell { + x: 11 + y: -6 + tile: 23 + } + cell { + x: 12 + y: -6 + tile: 23 + } + cell { + x: 13 + y: -6 + tile: 23 + } + cell { + x: 14 + y: -6 + tile: 23 + } + cell { + x: 15 + y: -6 + tile: 23 + } + cell { + x: 16 + y: -6 + tile: 23 + } + cell { + x: 17 + y: -6 + tile: 23 + } + cell { + x: 18 + y: -6 + tile: 23 + } + cell { + x: 19 + y: -6 + tile: 23 + } + cell { + x: 20 + y: -6 + tile: 23 + } + cell { + x: 21 + y: -6 + tile: 23 + } + cell { + x: 22 + y: -6 + tile: 23 + } + cell { + x: 23 + y: -6 + tile: 23 + } + cell { + x: 24 + y: -6 + tile: 23 + } + cell { + x: 25 + y: -6 + tile: 23 + } + cell { + x: 26 + y: -6 + tile: 186 + } + cell { + x: 27 + y: -6 + tile: 186 + } + cell { + x: 28 + y: -6 + tile: 186 + } + cell { + x: 29 + y: -6 + tile: 186 + } + cell { + x: 30 + y: -6 + tile: 186 + } + cell { + x: 31 + y: -6 + tile: 186 + } + cell { + x: 32 + y: -6 + tile: 186 + } + cell { + x: 33 + y: -6 + tile: 186 + } + cell { + x: 34 + y: -6 + tile: 186 + } + cell { + x: 35 + y: -6 + tile: 186 + } + cell { + x: 36 + y: -6 + tile: 186 + } + cell { + x: 37 + y: -6 + tile: 186 + } + cell { + x: 38 + y: -6 + tile: 186 + } + cell { + x: 39 + y: -6 + tile: 186 + } + cell { + x: 40 + y: -6 + tile: 186 + } + cell { + x: 41 + y: -6 + tile: 186 + } + cell { + x: 42 + y: -6 + tile: 186 + } + cell { + x: 43 + y: -6 + tile: 186 + } + cell { + x: -9 + y: -6 + tile: 186 + } + cell { + x: -8 + y: -6 + tile: 186 + } + cell { + x: -7 + y: -6 + tile: 186 + } + cell { + x: -6 + y: -6 + tile: 186 + } + cell { + x: -5 + y: -6 + tile: 186 + } + cell { + x: -4 + y: -6 + tile: 186 + } + cell { + x: -3 + y: -6 + tile: 86 + } + cell { + x: -2 + y: -6 + tile: 86 + } + cell { + x: -1 + y: -6 + tile: 23 + } + cell { + x: 0 + y: -5 + tile: 23 + } + cell { + x: 1 + y: -5 + tile: 23 + } + cell { + x: 2 + y: -5 + tile: 23 + } + cell { + x: 3 + y: -5 + tile: 23 + } + cell { + x: 4 + y: -5 + tile: 23 + } + cell { + x: 5 + y: -5 + tile: 23 + } + cell { + x: 6 + y: -5 + tile: 23 + } + cell { + x: 7 + y: -5 + tile: 23 + } + cell { + x: 8 + y: -5 + tile: 23 + } + cell { + x: 9 + y: -5 + tile: 23 + } + cell { + x: 10 + y: -5 + tile: 23 + } + cell { + x: 11 + y: -5 + tile: 23 + } + cell { + x: 12 + y: -5 + tile: 23 + } + cell { + x: 13 + y: -5 + tile: 23 + } + cell { + x: 14 + y: -5 + tile: 23 + } + cell { + x: 15 + y: -5 + tile: 23 + } + cell { + x: 16 + y: -5 + tile: 23 + } + cell { + x: 17 + y: -5 + tile: 23 + } + cell { + x: 18 + y: -5 + tile: 23 + } + cell { + x: 19 + y: -5 + tile: 23 + } + cell { + x: 20 + y: -5 + tile: 23 + } + cell { + x: 21 + y: -5 + tile: 23 + } + cell { + x: 22 + y: -5 + tile: 23 + } + cell { + x: 23 + y: -5 + tile: 23 + } + cell { + x: 24 + y: -5 + tile: 23 + } + cell { + x: 25 + y: -5 + tile: 23 + } + cell { + x: 26 + y: -5 + tile: 186 + } + cell { + x: 27 + y: -5 + tile: 186 + } + cell { + x: 28 + y: -5 + tile: 186 + } + cell { + x: 29 + y: -5 + tile: 186 + } + cell { + x: 30 + y: -5 + tile: 186 + } + cell { + x: 31 + y: -5 + tile: 186 + } + cell { + x: 32 + y: -5 + tile: 186 + } + cell { + x: 33 + y: -5 + tile: 186 + } + cell { + x: 34 + y: -5 + tile: 186 + } + cell { + x: 35 + y: -5 + tile: 186 + } + cell { + x: 36 + y: -5 + tile: 186 + } + cell { + x: 37 + y: -5 + tile: 186 + } + cell { + x: 38 + y: -5 + tile: 186 + } + cell { + x: 39 + y: -5 + tile: 186 + } + cell { + x: 40 + y: -5 + tile: 186 + } + cell { + x: 41 + y: -5 + tile: 186 + } + cell { + x: 42 + y: -5 + tile: 186 + } + cell { + x: 43 + y: -5 + tile: 186 + } + cell { + x: -9 + y: -5 + tile: 186 + } + cell { + x: -8 + y: -5 + tile: 186 + } + cell { + x: -7 + y: -5 + tile: 186 + } + cell { + x: -6 + y: -5 + tile: 186 + } + cell { + x: -5 + y: -5 + tile: 186 + } + cell { + x: -4 + y: -5 + tile: 86 + } + cell { + x: -3 + y: -5 + tile: 86 + } + cell { + x: -2 + y: -5 + tile: 86 + } + cell { + x: -1 + y: -5 + tile: 23 + } + cell { + x: 0 + y: -4 + tile: 23 + } + cell { + x: 1 + y: -4 + tile: 23 + } + cell { + x: 2 + y: -4 + tile: 23 + } + cell { + x: 3 + y: -4 + tile: 23 + } + cell { + x: 4 + y: -4 + tile: 23 + } + cell { + x: 5 + y: -4 + tile: 23 + } + cell { + x: 6 + y: -4 + tile: 23 + } + cell { + x: 7 + y: -4 + tile: 23 + } + cell { + x: 8 + y: -4 + tile: 23 + } + cell { + x: 9 + y: -4 + tile: 23 + } + cell { + x: 10 + y: -4 + tile: 23 + } + cell { + x: 11 + y: -4 + tile: 23 + } + cell { + x: 12 + y: -4 + tile: 23 + } + cell { + x: 13 + y: -4 + tile: 23 + } + cell { + x: 14 + y: -4 + tile: 23 + } + cell { + x: 15 + y: -4 + tile: 23 + } + cell { + x: 16 + y: -4 + tile: 23 + } + cell { + x: 17 + y: -4 + tile: 23 + } + cell { + x: 18 + y: -4 + tile: 23 + } + cell { + x: 19 + y: -4 + tile: 23 + } + cell { + x: 20 + y: -4 + tile: 23 + } + cell { + x: 21 + y: -4 + tile: 23 + } + cell { + x: 22 + y: -4 + tile: 23 + } + cell { + x: 23 + y: -4 + tile: 23 + } + cell { + x: 24 + y: -4 + tile: 23 + } + cell { + x: 25 + y: -4 + tile: 23 + } + cell { + x: 26 + y: -4 + tile: 186 + } + cell { + x: 27 + y: -4 + tile: 186 + } + cell { + x: 28 + y: -4 + tile: 186 + } + cell { + x: 29 + y: -4 + tile: 186 + } + cell { + x: 30 + y: -4 + tile: 186 + } + cell { + x: 31 + y: -4 + tile: 186 + } + cell { + x: 32 + y: -4 + tile: 186 + } + cell { + x: 33 + y: -4 + tile: 186 + } + cell { + x: 34 + y: -4 + tile: 186 + } + cell { + x: 35 + y: -4 + tile: 186 + } + cell { + x: 36 + y: -4 + tile: 186 + } + cell { + x: 37 + y: -4 + tile: 186 + } + cell { + x: 38 + y: -4 + tile: 186 + } + cell { + x: 39 + y: -4 + tile: 186 + } + cell { + x: 40 + y: -4 + tile: 186 + } + cell { + x: 41 + y: -4 + tile: 186 + } + cell { + x: 42 + y: -4 + tile: 186 + } + cell { + x: 43 + y: -4 + tile: 186 + } + cell { + x: 44 + y: -4 + tile: 186 + } + cell { + x: 45 + y: -4 + tile: 186 + } + cell { + x: 46 + y: -4 + tile: 186 + } + cell { + x: -9 + y: -4 + tile: 186 + } + cell { + x: -8 + y: -4 + tile: 186 + } + cell { + x: -7 + y: -4 + tile: 186 + } + cell { + x: -6 + y: -4 + tile: 186 + } + cell { + x: -5 + y: -4 + tile: 186 + } + cell { + x: -4 + y: -4 + tile: 86 + } + cell { + x: -3 + y: -4 + tile: 86 + } + cell { + x: -2 + y: -4 + tile: 86 + } + cell { + x: -1 + y: -4 + tile: 23 + } + cell { + x: 0 + y: -3 + tile: 23 + } + cell { + x: 1 + y: -3 + tile: 23 + } + cell { + x: 2 + y: -3 + tile: 23 + } + cell { + x: 3 + y: -3 + tile: 23 + } + cell { + x: 4 + y: -3 + tile: 23 + } + cell { + x: 5 + y: -3 + tile: 23 + } + cell { + x: 6 + y: -3 + tile: 23 + } + cell { + x: 7 + y: -3 + tile: 23 + } + cell { + x: 8 + y: -3 + tile: 23 + } + cell { + x: 9 + y: -3 + tile: 23 + } + cell { + x: 10 + y: -3 + tile: 23 + } + cell { + x: 11 + y: -3 + tile: 23 + } + cell { + x: 12 + y: -3 + tile: 23 + } + cell { + x: 13 + y: -3 + tile: 23 + } + cell { + x: 14 + y: -3 + tile: 23 + } + cell { + x: 15 + y: -3 + tile: 23 + } + cell { + x: 16 + y: -3 + tile: 23 + } + cell { + x: 17 + y: -3 + tile: 23 + } + cell { + x: 18 + y: -3 + tile: 23 + } + cell { + x: 19 + y: -3 + tile: 23 + } + cell { + x: 20 + y: -3 + tile: 23 + } + cell { + x: 21 + y: -3 + tile: 23 + } + cell { + x: 22 + y: -3 + tile: 23 + } + cell { + x: 23 + y: -3 + tile: 23 + } + cell { + x: 24 + y: -3 + tile: 23 + } + cell { + x: 25 + y: -3 + tile: 23 + } + cell { + x: 26 + y: -3 + tile: 23 + } + cell { + x: 27 + y: -3 + tile: 23 + } + cell { + x: 28 + y: -3 + tile: 186 + } + cell { + x: 29 + y: -3 + tile: 186 + } + cell { + x: 30 + y: -3 + tile: 186 + } + cell { + x: 31 + y: -3 + tile: 186 + } + cell { + x: 32 + y: -3 + tile: 186 + } + cell { + x: 33 + y: -3 + tile: 186 + } + cell { + x: 34 + y: -3 + tile: 186 + } + cell { + x: 35 + y: -3 + tile: 186 + } + cell { + x: 36 + y: -3 + tile: 186 + } + cell { + x: 37 + y: -3 + tile: 186 + } + cell { + x: 38 + y: -3 + tile: 186 + } + cell { + x: 39 + y: -3 + tile: 186 + } + cell { + x: 40 + y: -3 + tile: 186 + } + cell { + x: 41 + y: -3 + tile: 186 + } + cell { + x: 42 + y: -3 + tile: 186 + } + cell { + x: 43 + y: -3 + tile: 186 + } + cell { + x: 44 + y: -3 + tile: 186 + } + cell { + x: 45 + y: -3 + tile: 186 + } + cell { + x: 46 + y: -3 + tile: 186 + } + cell { + x: 47 + y: -3 + tile: 186 + } + cell { + x: -9 + y: -3 + tile: 186 + } + cell { + x: -8 + y: -3 + tile: 186 + } + cell { + x: -7 + y: -3 + tile: 186 + } + cell { + x: -6 + y: -3 + tile: 186 + } + cell { + x: -5 + y: -3 + tile: 86 + } + cell { + x: -4 + y: -3 + tile: 86 + } + cell { + x: -3 + y: -3 + tile: 86 + } + cell { + x: -2 + y: -3 + tile: 23 + } + cell { + x: -1 + y: -3 + tile: 23 + } + cell { + x: 0 + y: -2 + tile: 23 + } + cell { + x: 1 + y: -2 + tile: 23 + } + cell { + x: 2 + y: -2 + tile: 23 + } + cell { + x: 3 + y: -2 + tile: 23 + } + cell { + x: 4 + y: -2 + tile: 23 + } + cell { + x: 5 + y: -2 + tile: 23 + } + cell { + x: 6 + y: -2 + tile: 23 + } + cell { + x: 7 + y: -2 + tile: 23 + } + cell { + x: 8 + y: -2 + tile: 23 + } + cell { + x: 9 + y: -2 + tile: 23 + } + cell { + x: 10 + y: -2 + tile: 23 + } + cell { + x: 11 + y: -2 + tile: 23 + } + cell { + x: 12 + y: -2 + tile: 23 + } + cell { + x: 13 + y: -2 + tile: 23 + } + cell { + x: 14 + y: -2 + tile: 23 + } + cell { + x: 15 + y: -2 + tile: 23 + } + cell { + x: 16 + y: -2 + tile: 23 + } + cell { + x: 17 + y: -2 + tile: 23 + } + cell { + x: 18 + y: -2 + tile: 23 + } + cell { + x: 19 + y: -2 + tile: 23 + } + cell { + x: 20 + y: -2 + tile: 23 + } + cell { + x: 21 + y: -2 + tile: 23 + } + cell { + x: 22 + y: -2 + tile: 23 + } + cell { + x: 23 + y: -2 + tile: 23 + } + cell { + x: 24 + y: -2 + tile: 23 + } + cell { + x: 25 + y: -2 + tile: 23 + } + cell { + x: 26 + y: -2 + tile: 23 + } + cell { + x: 27 + y: -2 + tile: 23 + } + cell { + x: 28 + y: -2 + tile: 186 + } + cell { + x: 29 + y: -2 + tile: 186 + } + cell { + x: 30 + y: -2 + tile: 186 + } + cell { + x: 31 + y: -2 + tile: 186 + } + cell { + x: 32 + y: -2 + tile: 186 + } + cell { + x: 33 + y: -2 + tile: 186 + } + cell { + x: 34 + y: -2 + tile: 186 + } + cell { + x: 35 + y: -2 + tile: 186 + } + cell { + x: 36 + y: -2 + tile: 186 + } + cell { + x: 37 + y: -2 + tile: 186 + } + cell { + x: 38 + y: -2 + tile: 186 + } + cell { + x: 39 + y: -2 + tile: 186 + } + cell { + x: 40 + y: -2 + tile: 186 + } + cell { + x: 41 + y: -2 + tile: 186 + } + cell { + x: 42 + y: -2 + tile: 186 + } + cell { + x: 43 + y: -2 + tile: 186 + } + cell { + x: 44 + y: -2 + tile: 186 + } + cell { + x: 45 + y: -2 + tile: 186 + } + cell { + x: 46 + y: -2 + tile: 186 + } + cell { + x: 47 + y: -2 + tile: 186 + } + cell { + x: 48 + y: -2 + tile: 186 + } + cell { + x: -9 + y: -2 + tile: 186 + } + cell { + x: -8 + y: -2 + tile: 186 + } + cell { + x: -7 + y: -2 + tile: 186 + } + cell { + x: -6 + y: -2 + tile: 186 + } + cell { + x: -5 + y: -2 + tile: 86 + } + cell { + x: -4 + y: -2 + tile: 86 + } + cell { + x: -3 + y: -2 + tile: 23 + } + cell { + x: -2 + y: -2 + tile: 23 + } + cell { + x: -1 + y: -2 + tile: 23 + } + cell { + x: 0 + y: -1 + tile: 23 + } + cell { + x: 1 + y: -1 + tile: 23 + } + cell { + x: 2 + y: -1 + tile: 23 + } + cell { + x: 3 + y: -1 + tile: 23 + } + cell { + x: 4 + y: -1 + tile: 23 + } + cell { + x: 5 + y: -1 + tile: 23 + } + cell { + x: 6 + y: -1 + tile: 23 + } + cell { + x: 7 + y: -1 + tile: 23 + } + cell { + x: 8 + y: -1 + tile: 23 + } + cell { + x: 9 + y: -1 + tile: 23 + } + cell { + x: 10 + y: -1 + tile: 23 + } + cell { + x: 11 + y: -1 + tile: 23 + } + cell { + x: 12 + y: -1 + tile: 23 + } + cell { + x: 13 + y: -1 + tile: 23 + } + cell { + x: 14 + y: -1 + tile: 23 + } + cell { + x: 15 + y: -1 + tile: 23 + } + cell { + x: 16 + y: -1 + tile: 23 + } + cell { + x: 17 + y: -1 + tile: 23 + } + cell { + x: 18 + y: -1 + tile: 23 + } + cell { + x: 19 + y: -1 + tile: 23 + } + cell { + x: 20 + y: -1 + tile: 23 + } + cell { + x: 21 + y: -1 + tile: 23 + } + cell { + x: 22 + y: -1 + tile: 23 + } + cell { + x: 23 + y: -1 + tile: 23 + } + cell { + x: 24 + y: -1 + tile: 23 + } + cell { + x: 25 + y: -1 + tile: 23 + } + cell { + x: 26 + y: -1 + tile: 23 + } + cell { + x: 27 + y: -1 + tile: 23 + } + cell { + x: 28 + y: -1 + tile: 186 + } + cell { + x: 29 + y: -1 + tile: 186 + } + cell { + x: 30 + y: -1 + tile: 186 + } + cell { + x: 31 + y: -1 + tile: 186 + } + cell { + x: 32 + y: -1 + tile: 186 + } + cell { + x: 33 + y: -1 + tile: 186 + } + cell { + x: 34 + y: -1 + tile: 186 + } + cell { + x: 35 + y: -1 + tile: 186 + } + cell { + x: 36 + y: -1 + tile: 186 + } + cell { + x: 37 + y: -1 + tile: 186 + } + cell { + x: 38 + y: -1 + tile: 186 + } + cell { + x: 39 + y: -1 + tile: 186 + } + cell { + x: 40 + y: -1 + tile: 186 + } + cell { + x: 41 + y: -1 + tile: 186 + } + cell { + x: 42 + y: -1 + tile: 186 + } + cell { + x: 43 + y: -1 + tile: 186 + } + cell { + x: 44 + y: -1 + tile: 186 + } + cell { + x: 45 + y: -1 + tile: 186 + } + cell { + x: 46 + y: -1 + tile: 186 + } + cell { + x: 47 + y: -1 + tile: 186 + } + cell { + x: 48 + y: -1 + tile: 186 + } + cell { + x: 49 + y: -1 + tile: 186 + } + cell { + x: -10 + y: -1 + tile: 186 + } + cell { + x: -9 + y: -1 + tile: 186 + } + cell { + x: -8 + y: -1 + tile: 186 + } + cell { + x: -7 + y: -1 + tile: 186 + } + cell { + x: -6 + y: -1 + tile: 186 + } + cell { + x: -5 + y: -1 + tile: 86 + } + cell { + x: -4 + y: -1 + tile: 23 + } + cell { + x: -3 + y: -1 + tile: 23 + } + cell { + x: -2 + y: -1 + tile: 23 + } + cell { + x: -1 + y: -1 + tile: 23 + } + cell { + x: 0 + y: 0 + tile: 23 + } + cell { + x: 1 + y: 0 + tile: 23 + } + cell { + x: 2 + y: 0 + tile: 23 + } + cell { + x: 3 + y: 0 + tile: 23 + } + cell { + x: 4 + y: 0 + tile: 23 + } + cell { + x: 5 + y: 0 + tile: 23 + } + cell { + x: 6 + y: 0 + tile: 23 + } + cell { + x: 7 + y: 0 + tile: 23 + } + cell { + x: 8 + y: 0 + tile: 23 + } + cell { + x: 9 + y: 0 + tile: 23 + } + cell { + x: 10 + y: 0 + tile: 23 + } + cell { + x: 11 + y: 0 + tile: 23 + } + cell { + x: 12 + y: 0 + tile: 23 + } + cell { + x: 13 + y: 0 + tile: 23 + } + cell { + x: 14 + y: 0 + tile: 23 + } + cell { + x: 15 + y: 0 + tile: 23 + } + cell { + x: 16 + y: 0 + tile: 23 + } + cell { + x: 17 + y: 0 + tile: 23 + } + cell { + x: 18 + y: 0 + tile: 23 + } + cell { + x: 19 + y: 0 + tile: 23 + } + cell { + x: 20 + y: 0 + tile: 23 + } + cell { + x: 21 + y: 0 + tile: 23 + } + cell { + x: 22 + y: 0 + tile: 23 + } + cell { + x: 23 + y: 0 + tile: 23 + } + cell { + x: 24 + y: 0 + tile: 23 + } + cell { + x: 25 + y: 0 + tile: 23 + } + cell { + x: 26 + y: 0 + tile: 23 + } + cell { + x: 27 + y: 0 + tile: 91 + } + cell { + x: 28 + y: 0 + tile: 91 + } + cell { + x: 29 + y: 0 + tile: 91 + } + cell { + x: 30 + y: 0 + tile: 91 + } + cell { + x: 31 + y: 0 + tile: 91 + } + cell { + x: 32 + y: 0 + tile: 186 + } + cell { + x: 33 + y: 0 + tile: 91 + } + cell { + x: 34 + y: 0 + tile: 91 + } + cell { + x: 35 + y: 0 + tile: 91 + } + cell { + x: 36 + y: 0 + tile: 91 + } + cell { + x: 37 + y: 0 + tile: 91 + } + cell { + x: 38 + y: 0 + tile: 91 + } + cell { + x: 39 + y: 0 + tile: 91 + } + cell { + x: 40 + y: 0 + tile: 186 + } + cell { + x: 41 + y: 0 + tile: 186 + } + cell { + x: 42 + y: 0 + tile: 186 + } + cell { + x: 43 + y: 0 + tile: 186 + } + cell { + x: 44 + y: 0 + tile: 186 + } + cell { + x: 45 + y: 0 + tile: 186 + } + cell { + x: 46 + y: 0 + tile: 186 + } + cell { + x: 47 + y: 0 + tile: 186 + } + cell { + x: 48 + y: 0 + tile: 186 + } + cell { + x: 49 + y: 0 + tile: 186 + } + cell { + x: 50 + y: 0 + tile: 186 + } + cell { + x: 51 + y: 0 + tile: 186 + } + cell { + x: -9 + y: 0 + tile: 186 + } + cell { + x: -8 + y: 0 + tile: 186 + } + cell { + x: -7 + y: 0 + tile: 186 + } + cell { + x: -6 + y: 0 + tile: 186 + } + cell { + x: -5 + y: 0 + tile: 23 + } + cell { + x: -4 + y: 0 + tile: 23 + } + cell { + x: -3 + y: 0 + tile: 23 + } + cell { + x: -2 + y: 0 + tile: 23 + } + cell { + x: -1 + y: 0 + tile: 23 + } + cell { + x: 0 + y: 1 + tile: 23 + } + cell { + x: 1 + y: 1 + tile: 23 + } + cell { + x: 2 + y: 1 + tile: 23 + } + cell { + x: 3 + y: 1 + tile: 23 + } + cell { + x: 4 + y: 1 + tile: 23 + } + cell { + x: 5 + y: 1 + tile: 23 + } + cell { + x: 6 + y: 1 + tile: 23 + } + cell { + x: 7 + y: 1 + tile: 23 + } + cell { + x: 8 + y: 1 + tile: 23 + } + cell { + x: 9 + y: 1 + tile: 23 + } + cell { + x: 10 + y: 1 + tile: 23 + } + cell { + x: 11 + y: 1 + tile: 23 + } + cell { + x: 12 + y: 1 + tile: 23 + } + cell { + x: 13 + y: 1 + tile: 23 + } + cell { + x: 14 + y: 1 + tile: 23 + } + cell { + x: 15 + y: 1 + tile: 23 + } + cell { + x: 16 + y: 1 + tile: 23 + } + cell { + x: 17 + y: 1 + tile: 23 + } + cell { + x: 18 + y: 1 + tile: 23 + } + cell { + x: 19 + y: 1 + tile: 23 + } + cell { + x: 20 + y: 1 + tile: 23 + } + cell { + x: 21 + y: 1 + tile: 23 + } + cell { + x: 22 + y: 1 + tile: 23 + } + cell { + x: 23 + y: 1 + tile: 23 + } + cell { + x: 24 + y: 1 + tile: 23 + } + cell { + x: 25 + y: 1 + tile: 23 + } + cell { + x: 26 + y: 1 + tile: 23 + } + cell { + x: 27 + y: 1 + tile: 91 + } + cell { + x: 28 + y: 1 + tile: 91 + } + cell { + x: 29 + y: 1 + tile: 91 + } + cell { + x: 30 + y: 1 + tile: 91 + } + cell { + x: 31 + y: 1 + tile: 91 + } + cell { + x: 32 + y: 1 + tile: 91 + } + cell { + x: 33 + y: 1 + tile: 91 + } + cell { + x: 34 + y: 1 + tile: 91 + } + cell { + x: 35 + y: 1 + tile: 91 + } + cell { + x: 36 + y: 1 + tile: 91 + } + cell { + x: 37 + y: 1 + tile: 91 + } + cell { + x: 38 + y: 1 + tile: 91 + } + cell { + x: 39 + y: 1 + tile: 91 + } + cell { + x: 40 + y: 1 + tile: 91 + } + cell { + x: 41 + y: 1 + tile: 186 + } + cell { + x: 42 + y: 1 + tile: 186 + } + cell { + x: 43 + y: 1 + tile: 186 + } + cell { + x: 44 + y: 1 + tile: 186 + } + cell { + x: 45 + y: 1 + tile: 186 + } + cell { + x: 46 + y: 1 + tile: 186 + } + cell { + x: 47 + y: 1 + tile: 186 + } + cell { + x: 48 + y: 1 + tile: 186 + } + cell { + x: 49 + y: 1 + tile: 186 + } + cell { + x: 50 + y: 1 + tile: 186 + } + cell { + x: 51 + y: 1 + tile: 186 + } + cell { + x: -9 + y: 1 + tile: 186 + } + cell { + x: -8 + y: 1 + tile: 186 + } + cell { + x: -7 + y: 1 + tile: 186 + } + cell { + x: -6 + y: 1 + tile: 186 + } + cell { + x: -5 + y: 1 + tile: 23 + } + cell { + x: -4 + y: 1 + tile: 23 + } + cell { + x: -3 + y: 1 + tile: 23 + } + cell { + x: -2 + y: 1 + tile: 23 + } + cell { + x: -1 + y: 1 + tile: 23 + } + cell { + x: 0 + y: 2 + tile: 23 + } + cell { + x: 1 + y: 2 + tile: 23 + } + cell { + x: 2 + y: 2 + tile: 23 + } + cell { + x: 3 + y: 2 + tile: 23 + } + cell { + x: 4 + y: 2 + tile: 23 + } + cell { + x: 5 + y: 2 + tile: 23 + } + cell { + x: 6 + y: 2 + tile: 23 + } + cell { + x: 7 + y: 2 + tile: 23 + } + cell { + x: 8 + y: 2 + tile: 23 + } + cell { + x: 9 + y: 2 + tile: 23 + } + cell { + x: 10 + y: 2 + tile: 23 + } + cell { + x: 11 + y: 2 + tile: 23 + } + cell { + x: 12 + y: 2 + tile: 23 + } + cell { + x: 13 + y: 2 + tile: 23 + } + cell { + x: 14 + y: 2 + tile: 23 + } + cell { + x: 15 + y: 2 + tile: 23 + } + cell { + x: 16 + y: 2 + tile: 23 + } + cell { + x: 17 + y: 2 + tile: 23 + } + cell { + x: 18 + y: 2 + tile: 23 + } + cell { + x: 19 + y: 2 + tile: 23 + } + cell { + x: 20 + y: 2 + tile: 23 + } + cell { + x: 21 + y: 2 + tile: 23 + } + cell { + x: 22 + y: 2 + tile: 23 + } + cell { + x: 23 + y: 2 + tile: 23 + } + cell { + x: 24 + y: 2 + tile: 23 + } + cell { + x: 25 + y: 2 + tile: 23 + } + cell { + x: 26 + y: 2 + tile: 91 + } + cell { + x: 27 + y: 2 + tile: 91 + } + cell { + x: 28 + y: 2 + tile: 91 + } + cell { + x: 29 + y: 2 + tile: 91 + } + cell { + x: 30 + y: 2 + tile: 91 + } + cell { + x: 31 + y: 2 + tile: 91 + } + cell { + x: 32 + y: 2 + tile: 91 + } + cell { + x: 33 + y: 2 + tile: 91 + } + cell { + x: 34 + y: 2 + tile: 91 + } + cell { + x: 35 + y: 2 + tile: 91 + } + cell { + x: 36 + y: 2 + tile: 91 + } + cell { + x: 37 + y: 2 + tile: 91 + } + cell { + x: 38 + y: 2 + tile: 91 + } + cell { + x: 39 + y: 2 + tile: 91 + } + cell { + x: 40 + y: 2 + tile: 91 + } + cell { + x: 41 + y: 2 + tile: 186 + } + cell { + x: 42 + y: 2 + tile: 186 + } + cell { + x: 43 + y: 2 + tile: 186 + } + cell { + x: 44 + y: 2 + tile: 186 + } + cell { + x: 45 + y: 2 + tile: 186 + } + cell { + x: 46 + y: 2 + tile: 186 + } + cell { + x: 47 + y: 2 + tile: 186 + } + cell { + x: 48 + y: 2 + tile: 186 + } + cell { + x: 49 + y: 2 + tile: 186 + } + cell { + x: 50 + y: 2 + tile: 186 + } + cell { + x: 51 + y: 2 + tile: 186 + } + cell { + x: 52 + y: 2 + tile: 186 + } + cell { + x: -9 + y: 2 + tile: 186 + } + cell { + x: -8 + y: 2 + tile: 186 + } + cell { + x: -7 + y: 2 + tile: 186 + } + cell { + x: -6 + y: 2 + tile: 186 + } + cell { + x: -5 + y: 2 + tile: 186 + } + cell { + x: -4 + y: 2 + tile: 23 + } + cell { + x: -3 + y: 2 + tile: 23 + } + cell { + x: -2 + y: 2 + tile: 23 + } + cell { + x: -1 + y: 2 + tile: 23 + } + cell { + x: 0 + y: 3 + tile: 23 + } + cell { + x: 1 + y: 3 + tile: 23 + } + cell { + x: 2 + y: 3 + tile: 23 + } + cell { + x: 3 + y: 3 + tile: 23 + } + cell { + x: 4 + y: 3 + tile: 23 + } + cell { + x: 5 + y: 3 + tile: 23 + } + cell { + x: 6 + y: 3 + tile: 23 + } + cell { + x: 7 + y: 3 + tile: 23 + } + cell { + x: 8 + y: 3 + tile: 23 + } + cell { + x: 9 + y: 3 + tile: 23 + } + cell { + x: 10 + y: 3 + tile: 23 + } + cell { + x: 11 + y: 3 + tile: 23 + } + cell { + x: 12 + y: 3 + tile: 23 + } + cell { + x: 13 + y: 3 + tile: 23 + } + cell { + x: 14 + y: 3 + tile: 23 + } + cell { + x: 15 + y: 3 + tile: 23 + } + cell { + x: 16 + y: 3 + tile: 23 + } + cell { + x: 17 + y: 3 + tile: 23 + } + cell { + x: 18 + y: 3 + tile: 23 + } + cell { + x: 19 + y: 3 + tile: 23 + } + cell { + x: 20 + y: 3 + tile: 23 + } + cell { + x: 21 + y: 3 + tile: 23 + } + cell { + x: 22 + y: 3 + tile: 23 + } + cell { + x: 23 + y: 3 + tile: 23 + } + cell { + x: 24 + y: 3 + tile: 23 + } + cell { + x: 25 + y: 3 + tile: 23 + } + cell { + x: 26 + y: 3 + tile: 91 + } + cell { + x: 27 + y: 3 + tile: 91 + } + cell { + x: 28 + y: 3 + tile: 91 + } + cell { + x: 29 + y: 3 + tile: 91 + } + cell { + x: 30 + y: 3 + tile: 91 + } + cell { + x: 31 + y: 3 + tile: 91 + } + cell { + x: 32 + y: 3 + tile: 91 + } + cell { + x: 33 + y: 3 + tile: 91 + } + cell { + x: 34 + y: 3 + tile: 91 + } + cell { + x: 35 + y: 3 + tile: 91 + } + cell { + x: 36 + y: 3 + tile: 91 + } + cell { + x: 37 + y: 3 + tile: 91 + } + cell { + x: 38 + y: 3 + tile: 91 + } + cell { + x: 39 + y: 3 + tile: 91 + } + cell { + x: 40 + y: 3 + tile: 91 + } + cell { + x: 41 + y: 3 + tile: 186 + } + cell { + x: 42 + y: 3 + tile: 186 + } + cell { + x: 43 + y: 3 + tile: 186 + } + cell { + x: 44 + y: 3 + tile: 186 + } + cell { + x: 45 + y: 3 + tile: 186 + } + cell { + x: 46 + y: 3 + tile: 186 + } + cell { + x: 47 + y: 3 + tile: 186 + } + cell { + x: 48 + y: 3 + tile: 186 + } + cell { + x: 49 + y: 3 + tile: 186 + } + cell { + x: 50 + y: 3 + tile: 186 + } + cell { + x: 51 + y: 3 + tile: 186 + } + cell { + x: 52 + y: 3 + tile: 186 + } + cell { + x: 53 + y: 3 + tile: 186 + } + cell { + x: -9 + y: 3 + tile: 186 + } + cell { + x: -8 + y: 3 + tile: 186 + } + cell { + x: -7 + y: 3 + tile: 186 + } + cell { + x: -6 + y: 3 + tile: 186 + } + cell { + x: -5 + y: 3 + tile: 186 + } + cell { + x: -4 + y: 3 + tile: 23 + } + cell { + x: -3 + y: 3 + tile: 23 + } + cell { + x: -2 + y: 3 + tile: 23 + } + cell { + x: -1 + y: 3 + tile: 23 + } + cell { + x: 0 + y: 4 + tile: 23 + } + cell { + x: 1 + y: 4 + tile: 23 + } + cell { + x: 2 + y: 4 + tile: 23 + } + cell { + x: 3 + y: 4 + tile: 23 + } + cell { + x: 4 + y: 4 + tile: 23 + } + cell { + x: 5 + y: 4 + tile: 23 + } + cell { + x: 6 + y: 4 + tile: 23 + } + cell { + x: 7 + y: 4 + tile: 23 + } + cell { + x: 8 + y: 4 + tile: 23 + } + cell { + x: 9 + y: 4 + tile: 23 + } + cell { + x: 10 + y: 4 + tile: 23 + } + cell { + x: 11 + y: 4 + tile: 23 + } + cell { + x: 12 + y: 4 + tile: 23 + } + cell { + x: 13 + y: 4 + tile: 23 + } + cell { + x: 14 + y: 4 + tile: 23 + } + cell { + x: 15 + y: 4 + tile: 23 + } + cell { + x: 16 + y: 4 + tile: 23 + } + cell { + x: 17 + y: 4 + tile: 23 + } + cell { + x: 18 + y: 4 + tile: 23 + } + cell { + x: 19 + y: 4 + tile: 23 + } + cell { + x: 20 + y: 4 + tile: 23 + } + cell { + x: 21 + y: 4 + tile: 23 + } + cell { + x: 22 + y: 4 + tile: 23 + } + cell { + x: 23 + y: 4 + tile: 23 + } + cell { + x: 24 + y: 4 + tile: 23 + } + cell { + x: 25 + y: 4 + tile: 91 + } + cell { + x: 26 + y: 4 + tile: 91 + } + cell { + x: 27 + y: 4 + tile: 91 + } + cell { + x: 28 + y: 4 + tile: 91 + } + cell { + x: 29 + y: 4 + tile: 91 + } + cell { + x: 30 + y: 4 + tile: 91 + } + cell { + x: 31 + y: 4 + tile: 91 + } + cell { + x: 32 + y: 4 + tile: 91 + } + cell { + x: 33 + y: 4 + tile: 91 + } + cell { + x: 34 + y: 4 + tile: 91 + } + cell { + x: 35 + y: 4 + tile: 91 + } + cell { + x: 36 + y: 4 + tile: 91 + } + cell { + x: 37 + y: 4 + tile: 91 + } + cell { + x: 38 + y: 4 + tile: 91 + } + cell { + x: 39 + y: 4 + tile: 91 + } + cell { + x: 40 + y: 4 + tile: 91 + } + cell { + x: 41 + y: 4 + tile: 186 + } + cell { + x: 42 + y: 4 + tile: 186 + } + cell { + x: 43 + y: 4 + tile: 186 + } + cell { + x: 44 + y: 4 + tile: 186 + } + cell { + x: 45 + y: 4 + tile: 186 + } + cell { + x: 46 + y: 4 + tile: 186 + } + cell { + x: 47 + y: 4 + tile: 186 + } + cell { + x: 48 + y: 4 + tile: 186 + } + cell { + x: 49 + y: 4 + tile: 186 + } + cell { + x: 50 + y: 4 + tile: 186 + } + cell { + x: 51 + y: 4 + tile: 186 + } + cell { + x: 52 + y: 4 + tile: 186 + } + cell { + x: 53 + y: 4 + tile: 186 + } + cell { + x: -9 + y: 4 + tile: 186 + } + cell { + x: -8 + y: 4 + tile: 186 + } + cell { + x: -7 + y: 4 + tile: 186 + } + cell { + x: -6 + y: 4 + tile: 186 + } + cell { + x: -5 + y: 4 + tile: 186 + } + cell { + x: -4 + y: 4 + tile: 23 + } + cell { + x: -3 + y: 4 + tile: 23 + } + cell { + x: -2 + y: 4 + tile: 23 + } + cell { + x: -1 + y: 4 + tile: 23 + } + cell { + x: 0 + y: 5 + tile: 23 + } + cell { + x: 1 + y: 5 + tile: 23 + } + cell { + x: 2 + y: 5 + tile: 23 + } + cell { + x: 3 + y: 5 + tile: 23 + } + cell { + x: 4 + y: 5 + tile: 23 + } + cell { + x: 5 + y: 5 + tile: 23 + } + cell { + x: 6 + y: 5 + tile: 23 + } + cell { + x: 7 + y: 5 + tile: 23 + } + cell { + x: 8 + y: 5 + tile: 23 + } + cell { + x: 9 + y: 5 + tile: 23 + } + cell { + x: 10 + y: 5 + tile: 23 + } + cell { + x: 11 + y: 5 + tile: 23 + } + cell { + x: 12 + y: 5 + tile: 23 + } + cell { + x: 13 + y: 5 + tile: 23 + } + cell { + x: 14 + y: 5 + tile: 23 + } + cell { + x: 15 + y: 5 + tile: 23 + } + cell { + x: 16 + y: 5 + tile: 23 + } + cell { + x: 17 + y: 5 + tile: 23 + } + cell { + x: 18 + y: 5 + tile: 23 + } + cell { + x: 19 + y: 5 + tile: 23 + } + cell { + x: 20 + y: 5 + tile: 23 + } + cell { + x: 21 + y: 5 + tile: 23 + } + cell { + x: 22 + y: 5 + tile: 23 + } + cell { + x: 23 + y: 5 + tile: 23 + } + cell { + x: 24 + y: 5 + tile: 91 + } + cell { + x: 25 + y: 5 + tile: 91 + } + cell { + x: 26 + y: 5 + tile: 91 + } + cell { + x: 27 + y: 5 + tile: 91 + } + cell { + x: 28 + y: 5 + tile: 91 + } + cell { + x: 29 + y: 5 + tile: 91 + } + cell { + x: 30 + y: 5 + tile: 91 + } + cell { + x: 31 + y: 5 + tile: 91 + } + cell { + x: 32 + y: 5 + tile: 91 + } + cell { + x: 33 + y: 5 + tile: 91 + } + cell { + x: 34 + y: 5 + tile: 91 + } + cell { + x: 35 + y: 5 + tile: 91 + } + cell { + x: 36 + y: 5 + tile: 91 + } + cell { + x: 37 + y: 5 + tile: 91 + } + cell { + x: 38 + y: 5 + tile: 91 + } + cell { + x: 39 + y: 5 + tile: 91 + } + cell { + x: 40 + y: 5 + tile: 91 + } + cell { + x: 41 + y: 5 + tile: 186 + } + cell { + x: 42 + y: 5 + tile: 186 + } + cell { + x: 43 + y: 5 + tile: 186 + } + cell { + x: 44 + y: 5 + tile: 186 + } + cell { + x: 45 + y: 5 + tile: 186 + } + cell { + x: 46 + y: 5 + tile: 186 + } + cell { + x: 47 + y: 5 + tile: 186 + } + cell { + x: 48 + y: 5 + tile: 186 + } + cell { + x: 49 + y: 5 + tile: 186 + } + cell { + x: 50 + y: 5 + tile: 186 + } + cell { + x: 51 + y: 5 + tile: 186 + } + cell { + x: 52 + y: 5 + tile: 186 + } + cell { + x: 53 + y: 5 + tile: 186 + } + cell { + x: -9 + y: 5 + tile: 186 + } + cell { + x: -8 + y: 5 + tile: 186 + } + cell { + x: -7 + y: 5 + tile: 186 + } + cell { + x: -6 + y: 5 + tile: 186 + } + cell { + x: -5 + y: 5 + tile: 186 + } + cell { + x: -4 + y: 5 + tile: 23 + } + cell { + x: -3 + y: 5 + tile: 23 + } + cell { + x: -2 + y: 5 + tile: 23 + } + cell { + x: -1 + y: 5 + tile: 23 + } + cell { + x: 0 + y: 6 + tile: 23 + } + cell { + x: 1 + y: 6 + tile: 23 + } + cell { + x: 2 + y: 6 + tile: 23 + } + cell { + x: 3 + y: 6 + tile: 23 + } + cell { + x: 4 + y: 6 + tile: 23 + } + cell { + x: 5 + y: 6 + tile: 23 + } + cell { + x: 6 + y: 6 + tile: 23 + } + cell { + x: 7 + y: 6 + tile: 23 + } + cell { + x: 8 + y: 6 + tile: 23 + } + cell { + x: 9 + y: 6 + tile: 23 + } + cell { + x: 10 + y: 6 + tile: 23 + } + cell { + x: 11 + y: 6 + tile: 23 + } + cell { + x: 12 + y: 6 + tile: 23 + } + cell { + x: 13 + y: 6 + tile: 23 + } + cell { + x: 14 + y: 6 + tile: 23 + } + cell { + x: 15 + y: 6 + tile: 23 + } + cell { + x: 16 + y: 6 + tile: 23 + } + cell { + x: 17 + y: 6 + tile: 23 + } + cell { + x: 18 + y: 6 + tile: 23 + } + cell { + x: 19 + y: 6 + tile: 23 + } + cell { + x: 20 + y: 6 + tile: 23 + } + cell { + x: 21 + y: 6 + tile: 23 + } + cell { + x: 22 + y: 6 + tile: 23 + } + cell { + x: 23 + y: 6 + tile: 23 + } + cell { + x: 24 + y: 6 + tile: 91 + } + cell { + x: 25 + y: 6 + tile: 91 + } + cell { + x: 26 + y: 6 + tile: 91 + } + cell { + x: 27 + y: 6 + tile: 91 + } + cell { + x: 28 + y: 6 + tile: 91 + } + cell { + x: 29 + y: 6 + tile: 91 + } + cell { + x: 30 + y: 6 + tile: 91 + } + cell { + x: 31 + y: 6 + tile: 91 + } + cell { + x: 32 + y: 6 + tile: 91 + } + cell { + x: 33 + y: 6 + tile: 91 + } + cell { + x: 34 + y: 6 + tile: 91 + } + cell { + x: 35 + y: 6 + tile: 91 + } + cell { + x: 36 + y: 6 + tile: 91 + } + cell { + x: 37 + y: 6 + tile: 91 + } + cell { + x: 38 + y: 6 + tile: 91 + } + cell { + x: 39 + y: 6 + tile: 91 + } + cell { + x: 40 + y: 6 + tile: 91 + } + cell { + x: 41 + y: 6 + tile: 186 + } + cell { + x: 42 + y: 6 + tile: 186 + } + cell { + x: 43 + y: 6 + tile: 186 + } + cell { + x: 44 + y: 6 + tile: 186 + } + cell { + x: 45 + y: 6 + tile: 186 + } + cell { + x: 46 + y: 6 + tile: 186 + } + cell { + x: 47 + y: 6 + tile: 186 + } + cell { + x: 48 + y: 6 + tile: 186 + } + cell { + x: 49 + y: 6 + tile: 186 + } + cell { + x: 50 + y: 6 + tile: 186 + } + cell { + x: 51 + y: 6 + tile: 186 + } + cell { + x: 52 + y: 6 + tile: 186 + } + cell { + x: 53 + y: 6 + tile: 186 + } + cell { + x: 54 + y: 6 + tile: 186 + } + cell { + x: -9 + y: 6 + tile: 186 + } + cell { + x: -8 + y: 6 + tile: 186 + } + cell { + x: -7 + y: 6 + tile: 186 + } + cell { + x: -6 + y: 6 + tile: 186 + } + cell { + x: -5 + y: 6 + tile: 186 + } + cell { + x: -4 + y: 6 + tile: 23 + } + cell { + x: -3 + y: 6 + tile: 23 + } + cell { + x: -2 + y: 6 + tile: 23 + } + cell { + x: -1 + y: 6 + tile: 23 + } + cell { + x: 0 + y: 7 + tile: 23 + } + cell { + x: 1 + y: 7 + tile: 23 + } + cell { + x: 2 + y: 7 + tile: 23 + } + cell { + x: 3 + y: 7 + tile: 23 + } + cell { + x: 4 + y: 7 + tile: 23 + } + cell { + x: 5 + y: 7 + tile: 23 + } + cell { + x: 6 + y: 7 + tile: 23 + } + cell { + x: 7 + y: 7 + tile: 23 + } + cell { + x: 8 + y: 7 + tile: 23 + } + cell { + x: 9 + y: 7 + tile: 23 + } + cell { + x: 10 + y: 7 + tile: 23 + } + cell { + x: 11 + y: 7 + tile: 23 + } + cell { + x: 12 + y: 7 + tile: 23 + } + cell { + x: 13 + y: 7 + tile: 23 + } + cell { + x: 14 + y: 7 + tile: 23 + } + cell { + x: 15 + y: 7 + tile: 23 + } + cell { + x: 16 + y: 7 + tile: 23 + } + cell { + x: 17 + y: 7 + tile: 23 + } + cell { + x: 18 + y: 7 + tile: 23 + } + cell { + x: 19 + y: 7 + tile: 23 + } + cell { + x: 20 + y: 7 + tile: 23 + } + cell { + x: 21 + y: 7 + tile: 23 + } + cell { + x: 22 + y: 7 + tile: 23 + } + cell { + x: 23 + y: 7 + tile: 23 + } + cell { + x: 24 + y: 7 + tile: 91 + } + cell { + x: 25 + y: 7 + tile: 91 + } + cell { + x: 26 + y: 7 + tile: 91 + } + cell { + x: 27 + y: 7 + tile: 91 + } + cell { + x: 28 + y: 7 + tile: 91 + } + cell { + x: 29 + y: 7 + tile: 91 + } + cell { + x: 30 + y: 7 + tile: 91 + } + cell { + x: 31 + y: 7 + tile: 91 + } + cell { + x: 32 + y: 7 + tile: 91 + } + cell { + x: 33 + y: 7 + tile: 91 + } + cell { + x: 34 + y: 7 + tile: 91 + } + cell { + x: 35 + y: 7 + tile: 91 + } + cell { + x: 36 + y: 7 + tile: 91 + } + cell { + x: 37 + y: 7 + tile: 91 + } + cell { + x: 38 + y: 7 + tile: 91 + } + cell { + x: 39 + y: 7 + tile: 91 + } + cell { + x: 40 + y: 7 + tile: 186 + } + cell { + x: 41 + y: 7 + tile: 186 + } + cell { + x: 42 + y: 7 + tile: 186 + } + cell { + x: 43 + y: 7 + tile: 186 + } + cell { + x: 44 + y: 7 + tile: 186 + } + cell { + x: 45 + y: 7 + tile: 186 + } + cell { + x: 46 + y: 7 + tile: 186 + } + cell { + x: 47 + y: 7 + tile: 186 + } + cell { + x: 48 + y: 7 + tile: 186 + } + cell { + x: 49 + y: 7 + tile: 186 + } + cell { + x: 50 + y: 7 + tile: 186 + } + cell { + x: 51 + y: 7 + tile: 186 + } + cell { + x: 52 + y: 7 + tile: 186 + } + cell { + x: 53 + y: 7 + tile: 186 + } + cell { + x: 54 + y: 7 + tile: 186 + } + cell { + x: 55 + y: 7 + tile: 186 + } + cell { + x: -9 + y: 7 + tile: 186 + } + cell { + x: -8 + y: 7 + tile: 186 + } + cell { + x: -7 + y: 7 + tile: 186 + } + cell { + x: -6 + y: 7 + tile: 186 + } + cell { + x: -5 + y: 7 + tile: 186 + } + cell { + x: -4 + y: 7 + tile: 23 + } + cell { + x: -3 + y: 7 + tile: 23 + } + cell { + x: -2 + y: 7 + tile: 23 + } + cell { + x: -1 + y: 7 + tile: 23 + } + cell { + x: 0 + y: 8 + tile: 23 + } + cell { + x: 1 + y: 8 + tile: 23 + } + cell { + x: 2 + y: 8 + tile: 23 + } + cell { + x: 3 + y: 8 + tile: 23 + } + cell { + x: 4 + y: 8 + tile: 23 + } + cell { + x: 5 + y: 8 + tile: 23 + } + cell { + x: 6 + y: 8 + tile: 23 + } + cell { + x: 7 + y: 8 + tile: 23 + } + cell { + x: 8 + y: 8 + tile: 23 + } + cell { + x: 9 + y: 8 + tile: 23 + } + cell { + x: 10 + y: 8 + tile: 23 + } + cell { + x: 11 + y: 8 + tile: 23 + } + cell { + x: 12 + y: 8 + tile: 23 + } + cell { + x: 13 + y: 8 + tile: 23 + } + cell { + x: 14 + y: 8 + tile: 23 + } + cell { + x: 15 + y: 8 + tile: 23 + } + cell { + x: 16 + y: 8 + tile: 23 + } + cell { + x: 17 + y: 8 + tile: 23 + } + cell { + x: 18 + y: 8 + tile: 23 + } + cell { + x: 19 + y: 8 + tile: 23 + } + cell { + x: 20 + y: 8 + tile: 23 + } + cell { + x: 21 + y: 8 + tile: 23 + } + cell { + x: 22 + y: 8 + tile: 23 + } + cell { + x: 23 + y: 8 + tile: 23 + } + cell { + x: 24 + y: 8 + tile: 91 + } + cell { + x: 25 + y: 8 + tile: 91 + } + cell { + x: 26 + y: 8 + tile: 91 + } + cell { + x: 27 + y: 8 + tile: 91 + } + cell { + x: 28 + y: 8 + tile: 91 + } + cell { + x: 29 + y: 8 + tile: 91 + } + cell { + x: 30 + y: 8 + tile: 91 + } + cell { + x: 31 + y: 8 + tile: 91 + } + cell { + x: 32 + y: 8 + tile: 91 + } + cell { + x: 33 + y: 8 + tile: 91 + } + cell { + x: 34 + y: 8 + tile: 91 + } + cell { + x: 35 + y: 8 + tile: 91 + } + cell { + x: 36 + y: 8 + tile: 91 + } + cell { + x: 37 + y: 8 + tile: 91 + } + cell { + x: 38 + y: 8 + tile: 91 + } + cell { + x: 39 + y: 8 + tile: 91 + } + cell { + x: 40 + y: 8 + tile: 186 + } + cell { + x: 41 + y: 8 + tile: 186 + } + cell { + x: 42 + y: 8 + tile: 186 + } + cell { + x: 43 + y: 8 + tile: 186 + } + cell { + x: 44 + y: 8 + tile: 186 + } + cell { + x: 45 + y: 8 + tile: 186 + } + cell { + x: 46 + y: 8 + tile: 186 + } + cell { + x: 47 + y: 8 + tile: 186 + } + cell { + x: 48 + y: 8 + tile: 186 + } + cell { + x: 49 + y: 8 + tile: 186 + } + cell { + x: 50 + y: 8 + tile: 186 + } + cell { + x: 51 + y: 8 + tile: 186 + } + cell { + x: 52 + y: 8 + tile: 186 + } + cell { + x: 53 + y: 8 + tile: 186 + } + cell { + x: 54 + y: 8 + tile: 186 + } + cell { + x: 55 + y: 8 + tile: 186 + } + cell { + x: -9 + y: 8 + tile: 186 + } + cell { + x: -8 + y: 8 + tile: 186 + } + cell { + x: -7 + y: 8 + tile: 186 + } + cell { + x: -6 + y: 8 + tile: 186 + } + cell { + x: -5 + y: 8 + tile: 186 + } + cell { + x: -4 + y: 8 + tile: 23 + } + cell { + x: -3 + y: 8 + tile: 23 + } + cell { + x: -2 + y: 8 + tile: 23 + } + cell { + x: -1 + y: 8 + tile: 23 + } + cell { + x: 0 + y: 9 + tile: 28 + } + cell { + x: 1 + y: 9 + tile: 28 + } + cell { + x: 2 + y: 9 + tile: 28 + } + cell { + x: 3 + y: 9 + tile: 23 + } + cell { + x: 4 + y: 9 + tile: 23 + } + cell { + x: 5 + y: 9 + tile: 23 + } + cell { + x: 6 + y: 9 + tile: 23 + } + cell { + x: 7 + y: 9 + tile: 23 + } + cell { + x: 8 + y: 9 + tile: 23 + } + cell { + x: 9 + y: 9 + tile: 23 + } + cell { + x: 10 + y: 9 + tile: 23 + } + cell { + x: 11 + y: 9 + tile: 23 + } + cell { + x: 12 + y: 9 + tile: 23 + } + cell { + x: 13 + y: 9 + tile: 23 + } + cell { + x: 14 + y: 9 + tile: 23 + } + cell { + x: 15 + y: 9 + tile: 23 + } + cell { + x: 16 + y: 9 + tile: 23 + } + cell { + x: 17 + y: 9 + tile: 23 + } + cell { + x: 18 + y: 9 + tile: 23 + } + cell { + x: 19 + y: 9 + tile: 23 + } + cell { + x: 20 + y: 9 + tile: 23 + } + cell { + x: 21 + y: 9 + tile: 23 + } + cell { + x: 22 + y: 9 + tile: 23 + } + cell { + x: 23 + y: 9 + tile: 23 + } + cell { + x: 24 + y: 9 + tile: 91 + } + cell { + x: 25 + y: 9 + tile: 91 + } + cell { + x: 26 + y: 9 + tile: 91 + } + cell { + x: 27 + y: 9 + tile: 91 + } + cell { + x: 28 + y: 9 + tile: 91 + } + cell { + x: 29 + y: 9 + tile: 91 + } + cell { + x: 30 + y: 9 + tile: 91 + } + cell { + x: 31 + y: 9 + tile: 91 + } + cell { + x: 32 + y: 9 + tile: 91 + } + cell { + x: 33 + y: 9 + tile: 91 + } + cell { + x: 34 + y: 9 + tile: 91 + } + cell { + x: 35 + y: 9 + tile: 91 + } + cell { + x: 36 + y: 9 + tile: 91 + } + cell { + x: 37 + y: 9 + tile: 91 + } + cell { + x: 38 + y: 9 + tile: 91 + } + cell { + x: 39 + y: 9 + tile: 91 + } + cell { + x: 40 + y: 9 + tile: 186 + } + cell { + x: 41 + y: 9 + tile: 186 + } + cell { + x: 42 + y: 9 + tile: 186 + } + cell { + x: 43 + y: 9 + tile: 186 + } + cell { + x: 44 + y: 9 + tile: 186 + } + cell { + x: 45 + y: 9 + tile: 186 + } + cell { + x: 46 + y: 9 + tile: 186 + } + cell { + x: 47 + y: 9 + tile: 186 + } + cell { + x: 48 + y: 9 + tile: 186 + } + cell { + x: 49 + y: 9 + tile: 186 + } + cell { + x: 50 + y: 9 + tile: 186 + } + cell { + x: 51 + y: 9 + tile: 186 + } + cell { + x: 52 + y: 9 + tile: 186 + } + cell { + x: 53 + y: 9 + tile: 186 + } + cell { + x: 54 + y: 9 + tile: 186 + } + cell { + x: 55 + y: 9 + tile: 186 + } + cell { + x: 56 + y: 9 + tile: 186 + } + cell { + x: -9 + y: 9 + tile: 186 + } + cell { + x: -8 + y: 9 + tile: 186 + } + cell { + x: -7 + y: 9 + tile: 186 + } + cell { + x: -6 + y: 9 + tile: 186 + } + cell { + x: -5 + y: 9 + tile: 186 + } + cell { + x: -4 + y: 9 + tile: 23 + } + cell { + x: -3 + y: 9 + tile: 23 + } + cell { + x: -2 + y: 9 + tile: 23 + } + cell { + x: -1 + y: 9 + tile: 23 + } + cell { + x: 0 + y: 10 + tile: 28 + } + cell { + x: 1 + y: 10 + tile: 28 + } + cell { + x: 2 + y: 10 + tile: 28 + } + cell { + x: 3 + y: 10 + tile: 23 + } + cell { + x: 4 + y: 10 + tile: 23 + } + cell { + x: 5 + y: 10 + tile: 23 + } + cell { + x: 6 + y: 10 + tile: 23 + } + cell { + x: 7 + y: 10 + tile: 23 + } + cell { + x: 8 + y: 10 + tile: 23 + } + cell { + x: 9 + y: 10 + tile: 23 + } + cell { + x: 10 + y: 10 + tile: 23 + } + cell { + x: 11 + y: 10 + tile: 23 + } + cell { + x: 12 + y: 10 + tile: 23 + } + cell { + x: 13 + y: 10 + tile: 23 + } + cell { + x: 14 + y: 10 + tile: 23 + } + cell { + x: 15 + y: 10 + tile: 23 + } + cell { + x: 16 + y: 10 + tile: 23 + } + cell { + x: 17 + y: 10 + tile: 23 + } + cell { + x: 18 + y: 10 + tile: 23 + } + cell { + x: 19 + y: 10 + tile: 23 + } + cell { + x: 20 + y: 10 + tile: 23 + } + cell { + x: 21 + y: 10 + tile: 23 + } + cell { + x: 22 + y: 10 + tile: 23 + } + cell { + x: 23 + y: 10 + tile: 23 + } + cell { + x: 24 + y: 10 + tile: 91 + } + cell { + x: 25 + y: 10 + tile: 91 + } + cell { + x: 26 + y: 10 + tile: 91 + } + cell { + x: 27 + y: 10 + tile: 91 + } + cell { + x: 28 + y: 10 + tile: 91 + } + cell { + x: 29 + y: 10 + tile: 91 + } + cell { + x: 30 + y: 10 + tile: 91 + } + cell { + x: 31 + y: 10 + tile: 91 + } + cell { + x: 32 + y: 10 + tile: 91 + } + cell { + x: 33 + y: 10 + tile: 91 + } + cell { + x: 34 + y: 10 + tile: 91 + } + cell { + x: 35 + y: 10 + tile: 91 + } + cell { + x: 36 + y: 10 + tile: 91 + } + cell { + x: 37 + y: 10 + tile: 91 + } + cell { + x: 38 + y: 10 + tile: 91 + } + cell { + x: 39 + y: 10 + tile: 91 + } + cell { + x: 40 + y: 10 + tile: 186 + } + cell { + x: 41 + y: 10 + tile: 186 + } + cell { + x: 42 + y: 10 + tile: 186 + } + cell { + x: 43 + y: 10 + tile: 186 + } + cell { + x: 44 + y: 10 + tile: 186 + } + cell { + x: 45 + y: 10 + tile: 186 + } + cell { + x: 46 + y: 10 + tile: 186 + } + cell { + x: 47 + y: 10 + tile: 186 + } + cell { + x: 48 + y: 10 + tile: 186 + } + cell { + x: 49 + y: 10 + tile: 186 + } + cell { + x: 50 + y: 10 + tile: 186 + } + cell { + x: 51 + y: 10 + tile: 186 + } + cell { + x: 52 + y: 10 + tile: 186 + } + cell { + x: 53 + y: 10 + tile: 186 + } + cell { + x: 54 + y: 10 + tile: 186 + } + cell { + x: 55 + y: 10 + tile: 186 + } + cell { + x: 56 + y: 10 + tile: 186 + } + cell { + x: -9 + y: 10 + tile: 186 + } + cell { + x: -8 + y: 10 + tile: 186 + } + cell { + x: -7 + y: 10 + tile: 186 + } + cell { + x: -6 + y: 10 + tile: 186 + } + cell { + x: -5 + y: 10 + tile: 23 + } + cell { + x: -4 + y: 10 + tile: 23 + } + cell { + x: -3 + y: 10 + tile: 23 + } + cell { + x: -2 + y: 10 + tile: 23 + } + cell { + x: -1 + y: 10 + tile: 23 + } + cell { + x: 0 + y: 11 + tile: 28 + } + cell { + x: 1 + y: 11 + tile: 28 + } + cell { + x: 2 + y: 11 + tile: 28 + } + cell { + x: 3 + y: 11 + tile: 23 + } + cell { + x: 4 + y: 11 + tile: 23 + } + cell { + x: 5 + y: 11 + tile: 23 + } + cell { + x: 6 + y: 11 + tile: 23 + } + cell { + x: 7 + y: 11 + tile: 23 + } + cell { + x: 8 + y: 11 + tile: 23 + } + cell { + x: 9 + y: 11 + tile: 23 + } + cell { + x: 10 + y: 11 + tile: 23 + } + cell { + x: 11 + y: 11 + tile: 23 + } + cell { + x: 12 + y: 11 + tile: 23 + } + cell { + x: 13 + y: 11 + tile: 23 + } + cell { + x: 14 + y: 11 + tile: 23 + } + cell { + x: 15 + y: 11 + tile: 23 + } + cell { + x: 16 + y: 11 + tile: 23 + } + cell { + x: 17 + y: 11 + tile: 23 + } + cell { + x: 18 + y: 11 + tile: 23 + } + cell { + x: 19 + y: 11 + tile: 23 + } + cell { + x: 20 + y: 11 + tile: 23 + } + cell { + x: 21 + y: 11 + tile: 23 + } + cell { + x: 22 + y: 11 + tile: 23 + } + cell { + x: 23 + y: 11 + tile: 23 + } + cell { + x: 24 + y: 11 + tile: 23 + } + cell { + x: 25 + y: 11 + tile: 91 + } + cell { + x: 26 + y: 11 + tile: 91 + } + cell { + x: 27 + y: 11 + tile: 91 + } + cell { + x: 28 + y: 11 + tile: 91 + } + cell { + x: 29 + y: 11 + tile: 91 + } + cell { + x: 30 + y: 11 + tile: 91 + } + cell { + x: 31 + y: 11 + tile: 91 + } + cell { + x: 32 + y: 11 + tile: 91 + } + cell { + x: 33 + y: 11 + tile: 91 + } + cell { + x: 34 + y: 11 + tile: 91 + } + cell { + x: 35 + y: 11 + tile: 91 + } + cell { + x: 36 + y: 11 + tile: 91 + } + cell { + x: 37 + y: 11 + tile: 91 + } + cell { + x: 38 + y: 11 + tile: 91 + } + cell { + x: 39 + y: 11 + tile: 91 + } + cell { + x: 40 + y: 11 + tile: 91 + } + cell { + x: 41 + y: 11 + tile: 186 + } + cell { + x: 42 + y: 11 + tile: 186 + } + cell { + x: 43 + y: 11 + tile: 186 + } + cell { + x: 44 + y: 11 + tile: 186 + } + cell { + x: 45 + y: 11 + tile: 186 + } + cell { + x: 46 + y: 11 + tile: 186 + } + cell { + x: 47 + y: 11 + tile: 186 + } + cell { + x: 48 + y: 11 + tile: 186 + } + cell { + x: 49 + y: 11 + tile: 186 + } + cell { + x: 50 + y: 11 + tile: 186 + } + cell { + x: 51 + y: 11 + tile: 186 + } + cell { + x: 52 + y: 11 + tile: 186 + } + cell { + x: 53 + y: 11 + tile: 186 + } + cell { + x: 54 + y: 11 + tile: 186 + } + cell { + x: 55 + y: 11 + tile: 186 + } + cell { + x: 56 + y: 11 + tile: 186 + } + cell { + x: -9 + y: 11 + tile: 186 + } + cell { + x: -8 + y: 11 + tile: 186 + } + cell { + x: -7 + y: 11 + tile: 186 + } + cell { + x: -6 + y: 11 + tile: 186 + } + cell { + x: -5 + y: 11 + tile: 23 + } + cell { + x: -4 + y: 11 + tile: 23 + } + cell { + x: -3 + y: 11 + tile: 23 + } + cell { + x: -2 + y: 11 + tile: 23 + } + cell { + x: -1 + y: 11 + tile: 23 + } + cell { + x: 0 + y: 12 + tile: 23 + } + cell { + x: 1 + y: 12 + tile: 23 + } + cell { + x: 2 + y: 12 + tile: 23 + } + cell { + x: 3 + y: 12 + tile: 23 + } + cell { + x: 4 + y: 12 + tile: 23 + } + cell { + x: 5 + y: 12 + tile: 23 + } + cell { + x: 6 + y: 12 + tile: 23 + } + cell { + x: 7 + y: 12 + tile: 23 + } + cell { + x: 8 + y: 12 + tile: 23 + } + cell { + x: 9 + y: 12 + tile: 23 + } + cell { + x: 10 + y: 12 + tile: 23 + } + cell { + x: 11 + y: 12 + tile: 23 + } + cell { + x: 12 + y: 12 + tile: 23 + } + cell { + x: 13 + y: 12 + tile: 23 + } + cell { + x: 14 + y: 12 + tile: 23 + } + cell { + x: 15 + y: 12 + tile: 23 + } + cell { + x: 16 + y: 12 + tile: 23 + } + cell { + x: 17 + y: 12 + tile: 23 + } + cell { + x: 18 + y: 12 + tile: 23 + } + cell { + x: 19 + y: 12 + tile: 23 + } + cell { + x: 20 + y: 12 + tile: 23 + } + cell { + x: 21 + y: 12 + tile: 23 + } + cell { + x: 22 + y: 12 + tile: 23 + } + cell { + x: 23 + y: 12 + tile: 23 + } + cell { + x: 24 + y: 12 + tile: 23 + } + cell { + x: 25 + y: 12 + tile: 91 + } + cell { + x: 26 + y: 12 + tile: 91 + } + cell { + x: 27 + y: 12 + tile: 91 + } + cell { + x: 28 + y: 12 + tile: 91 + } + cell { + x: 29 + y: 12 + tile: 91 + } + cell { + x: 30 + y: 12 + tile: 91 + } + cell { + x: 31 + y: 12 + tile: 91 + } + cell { + x: 32 + y: 12 + tile: 91 + } + cell { + x: 33 + y: 12 + tile: 91 + } + cell { + x: 34 + y: 12 + tile: 91 + } + cell { + x: 35 + y: 12 + tile: 91 + } + cell { + x: 36 + y: 12 + tile: 91 + } + cell { + x: 37 + y: 12 + tile: 91 + } + cell { + x: 38 + y: 12 + tile: 91 + } + cell { + x: 39 + y: 12 + tile: 91 + } + cell { + x: 40 + y: 12 + tile: 91 + } + cell { + x: 41 + y: 12 + tile: 186 + } + cell { + x: 42 + y: 12 + tile: 186 + } + cell { + x: 43 + y: 12 + tile: 186 + } + cell { + x: 44 + y: 12 + tile: 186 + } + cell { + x: 45 + y: 12 + tile: 186 + } + cell { + x: 46 + y: 12 + tile: 186 + } + cell { + x: 47 + y: 12 + tile: 186 + } + cell { + x: 48 + y: 12 + tile: 186 + } + cell { + x: 49 + y: 12 + tile: 186 + } + cell { + x: 50 + y: 12 + tile: 186 + } + cell { + x: 51 + y: 12 + tile: 186 + } + cell { + x: 52 + y: 12 + tile: 186 + } + cell { + x: 53 + y: 12 + tile: 186 + } + cell { + x: 54 + y: 12 + tile: 186 + } + cell { + x: 55 + y: 12 + tile: 186 + } + cell { + x: 56 + y: 12 + tile: 186 + } + cell { + x: -9 + y: 12 + tile: 186 + } + cell { + x: -8 + y: 12 + tile: 186 + } + cell { + x: -7 + y: 12 + tile: 186 + } + cell { + x: -6 + y: 12 + tile: 186 + } + cell { + x: -5 + y: 12 + tile: 23 + } + cell { + x: -4 + y: 12 + tile: 23 + } + cell { + x: -3 + y: 12 + tile: 23 + } + cell { + x: -2 + y: 12 + tile: 23 + } + cell { + x: -1 + y: 12 + tile: 23 + } + cell { + x: 0 + y: 13 + tile: 23 + } + cell { + x: 1 + y: 13 + tile: 23 + } + cell { + x: 2 + y: 13 + tile: 23 + } + cell { + x: 3 + y: 13 + tile: 23 + } + cell { + x: 4 + y: 13 + tile: 23 + } + cell { + x: 5 + y: 13 + tile: 23 + } + cell { + x: 6 + y: 13 + tile: 23 + } + cell { + x: 7 + y: 13 + tile: 23 + } + cell { + x: 8 + y: 13 + tile: 23 + } + cell { + x: 9 + y: 13 + tile: 23 + } + cell { + x: 10 + y: 13 + tile: 23 + } + cell { + x: 11 + y: 13 + tile: 23 + } + cell { + x: 12 + y: 13 + tile: 23 + } + cell { + x: 13 + y: 13 + tile: 23 + } + cell { + x: 14 + y: 13 + tile: 23 + } + cell { + x: 15 + y: 13 + tile: 23 + } + cell { + x: 16 + y: 13 + tile: 23 + } + cell { + x: 17 + y: 13 + tile: 23 + } + cell { + x: 18 + y: 13 + tile: 23 + } + cell { + x: 19 + y: 13 + tile: 23 + } + cell { + x: 20 + y: 13 + tile: 23 + } + cell { + x: 21 + y: 13 + tile: 23 + } + cell { + x: 22 + y: 13 + tile: 23 + } + cell { + x: 23 + y: 13 + tile: 23 + } + cell { + x: 24 + y: 13 + tile: 23 + } + cell { + x: 25 + y: 13 + tile: 91 + } + cell { + x: 26 + y: 13 + tile: 91 + } + cell { + x: 27 + y: 13 + tile: 91 + } + cell { + x: 28 + y: 13 + tile: 91 + } + cell { + x: 29 + y: 13 + tile: 91 + } + cell { + x: 30 + y: 13 + tile: 91 + } + cell { + x: 31 + y: 13 + tile: 91 + } + cell { + x: 32 + y: 13 + tile: 91 + } + cell { + x: 33 + y: 13 + tile: 91 + } + cell { + x: 34 + y: 13 + tile: 91 + } + cell { + x: 35 + y: 13 + tile: 91 + } + cell { + x: 36 + y: 13 + tile: 91 + } + cell { + x: 37 + y: 13 + tile: 91 + } + cell { + x: 38 + y: 13 + tile: 91 + } + cell { + x: 39 + y: 13 + tile: 91 + } + cell { + x: 40 + y: 13 + tile: 91 + } + cell { + x: 41 + y: 13 + tile: 186 + } + cell { + x: 42 + y: 13 + tile: 186 + } + cell { + x: 43 + y: 13 + tile: 186 + } + cell { + x: 44 + y: 13 + tile: 186 + } + cell { + x: 45 + y: 13 + tile: 186 + } + cell { + x: 46 + y: 13 + tile: 186 + } + cell { + x: 47 + y: 13 + tile: 186 + } + cell { + x: 48 + y: 13 + tile: 186 + } + cell { + x: 49 + y: 13 + tile: 186 + } + cell { + x: 50 + y: 13 + tile: 186 + } + cell { + x: 51 + y: 13 + tile: 186 + } + cell { + x: 52 + y: 13 + tile: 186 + } + cell { + x: 53 + y: 13 + tile: 186 + } + cell { + x: 54 + y: 13 + tile: 186 + } + cell { + x: 55 + y: 13 + tile: 186 + } + cell { + x: 56 + y: 13 + tile: 186 + } + cell { + x: -9 + y: 13 + tile: 186 + } + cell { + x: -8 + y: 13 + tile: 186 + } + cell { + x: -7 + y: 13 + tile: 186 + } + cell { + x: -6 + y: 13 + tile: 186 + } + cell { + x: -5 + y: 13 + tile: 23 + } + cell { + x: -4 + y: 13 + tile: 23 + } + cell { + x: -3 + y: 13 + tile: 23 + } + cell { + x: -2 + y: 13 + tile: 23 + } + cell { + x: -1 + y: 13 + tile: 23 + } + cell { + x: 0 + y: 14 + tile: 23 + } + cell { + x: 1 + y: 14 + tile: 23 + } + cell { + x: 2 + y: 14 + tile: 23 + } + cell { + x: 3 + y: 14 + tile: 23 + } + cell { + x: 4 + y: 14 + tile: 23 + } + cell { + x: 5 + y: 14 + tile: 23 + } + cell { + x: 6 + y: 14 + tile: 23 + } + cell { + x: 7 + y: 14 + tile: 23 + } + cell { + x: 8 + y: 14 + tile: 23 + } + cell { + x: 9 + y: 14 + tile: 23 + } + cell { + x: 10 + y: 14 + tile: 23 + } + cell { + x: 11 + y: 14 + tile: 23 + } + cell { + x: 12 + y: 14 + tile: 23 + } + cell { + x: 13 + y: 14 + tile: 23 + } + cell { + x: 14 + y: 14 + tile: 23 + } + cell { + x: 15 + y: 14 + tile: 23 + } + cell { + x: 16 + y: 14 + tile: 23 + } + cell { + x: 17 + y: 14 + tile: 23 + } + cell { + x: 18 + y: 14 + tile: 23 + } + cell { + x: 19 + y: 14 + tile: 23 + } + cell { + x: 20 + y: 14 + tile: 23 + } + cell { + x: 21 + y: 14 + tile: 23 + } + cell { + x: 22 + y: 14 + tile: 23 + } + cell { + x: 23 + y: 14 + tile: 23 + } + cell { + x: 24 + y: 14 + tile: 23 + } + cell { + x: 25 + y: 14 + tile: 91 + } + cell { + x: 26 + y: 14 + tile: 91 + } + cell { + x: 27 + y: 14 + tile: 91 + } + cell { + x: 28 + y: 14 + tile: 91 + } + cell { + x: 29 + y: 14 + tile: 91 + } + cell { + x: 30 + y: 14 + tile: 91 + } + cell { + x: 31 + y: 14 + tile: 91 + } + cell { + x: 32 + y: 14 + tile: 91 + } + cell { + x: 33 + y: 14 + tile: 91 + } + cell { + x: 34 + y: 14 + tile: 91 + } + cell { + x: 35 + y: 14 + tile: 91 + } + cell { + x: 36 + y: 14 + tile: 91 + } + cell { + x: 37 + y: 14 + tile: 91 + } + cell { + x: 38 + y: 14 + tile: 91 + } + cell { + x: 39 + y: 14 + tile: 91 + } + cell { + x: 40 + y: 14 + tile: 91 + } + cell { + x: 41 + y: 14 + tile: 186 + } + cell { + x: 42 + y: 14 + tile: 186 + } + cell { + x: 43 + y: 14 + tile: 186 + } + cell { + x: 44 + y: 14 + tile: 186 + } + cell { + x: 45 + y: 14 + tile: 186 + } + cell { + x: 46 + y: 14 + tile: 186 + } + cell { + x: 47 + y: 14 + tile: 186 + } + cell { + x: 48 + y: 14 + tile: 186 + } + cell { + x: 49 + y: 14 + tile: 186 + } + cell { + x: 50 + y: 14 + tile: 186 + } + cell { + x: 51 + y: 14 + tile: 186 + } + cell { + x: 52 + y: 14 + tile: 186 + } + cell { + x: 53 + y: 14 + tile: 186 + } + cell { + x: 54 + y: 14 + tile: 186 + } + cell { + x: 55 + y: 14 + tile: 186 + } + cell { + x: 56 + y: 14 + tile: 186 + } + cell { + x: -9 + y: 14 + tile: 186 + } + cell { + x: -8 + y: 14 + tile: 186 + } + cell { + x: -7 + y: 14 + tile: 186 + } + cell { + x: -6 + y: 14 + tile: 23 + } + cell { + x: -5 + y: 14 + tile: 23 + } + cell { + x: -4 + y: 14 + tile: 23 + } + cell { + x: -3 + y: 14 + tile: 23 + } + cell { + x: -2 + y: 14 + tile: 23 + } + cell { + x: -1 + y: 14 + tile: 23 + } + cell { + x: 0 + y: 15 + tile: 23 + } + cell { + x: 1 + y: 15 + tile: 23 + } + cell { + x: 2 + y: 15 + tile: 23 + } + cell { + x: 3 + y: 15 + tile: 23 + } + cell { + x: 4 + y: 15 + tile: 23 + } + cell { + x: 5 + y: 15 + tile: 23 + } + cell { + x: 6 + y: 15 + tile: 23 + } + cell { + x: 7 + y: 15 + tile: 23 + } + cell { + x: 8 + y: 15 + tile: 23 + } + cell { + x: 9 + y: 15 + tile: 23 + } + cell { + x: 10 + y: 15 + tile: 23 + } + cell { + x: 11 + y: 15 + tile: 23 + } + cell { + x: 12 + y: 15 + tile: 23 + } + cell { + x: 13 + y: 15 + tile: 23 + } + cell { + x: 14 + y: 15 + tile: 23 + } + cell { + x: 15 + y: 15 + tile: 23 + } + cell { + x: 16 + y: 15 + tile: 23 + } + cell { + x: 17 + y: 15 + tile: 23 + } + cell { + x: 18 + y: 15 + tile: 23 + } + cell { + x: 19 + y: 15 + tile: 23 + } + cell { + x: 20 + y: 15 + tile: 23 + } + cell { + x: 21 + y: 15 + tile: 23 + } + cell { + x: 22 + y: 15 + tile: 23 + } + cell { + x: 23 + y: 15 + tile: 23 + } + cell { + x: 24 + y: 15 + tile: 23 + } + cell { + x: 25 + y: 15 + tile: 91 + } + cell { + x: 26 + y: 15 + tile: 91 + } + cell { + x: 27 + y: 15 + tile: 91 + } + cell { + x: 28 + y: 15 + tile: 91 + } + cell { + x: 29 + y: 15 + tile: 91 + } + cell { + x: 30 + y: 15 + tile: 91 + } + cell { + x: 31 + y: 15 + tile: 91 + } + cell { + x: 32 + y: 15 + tile: 91 + } + cell { + x: 33 + y: 15 + tile: 91 + } + cell { + x: 34 + y: 15 + tile: 91 + } + cell { + x: 35 + y: 15 + tile: 91 + } + cell { + x: 36 + y: 15 + tile: 91 + } + cell { + x: 37 + y: 15 + tile: 91 + } + cell { + x: 38 + y: 15 + tile: 91 + } + cell { + x: 39 + y: 15 + tile: 91 + } + cell { + x: 40 + y: 15 + tile: 186 + } + cell { + x: 41 + y: 15 + tile: 186 + } + cell { + x: 42 + y: 15 + tile: 186 + } + cell { + x: 43 + y: 15 + tile: 186 + } + cell { + x: 44 + y: 15 + tile: 186 + } + cell { + x: 45 + y: 15 + tile: 186 + } + cell { + x: 46 + y: 15 + tile: 186 + } + cell { + x: 47 + y: 15 + tile: 186 + } + cell { + x: 48 + y: 15 + tile: 186 + } + cell { + x: 49 + y: 15 + tile: 186 + } + cell { + x: 50 + y: 15 + tile: 186 + } + cell { + x: 51 + y: 15 + tile: 186 + } + cell { + x: 52 + y: 15 + tile: 186 + } + cell { + x: 53 + y: 15 + tile: 186 + } + cell { + x: 54 + y: 15 + tile: 186 + } + cell { + x: 55 + y: 15 + tile: 186 + } + cell { + x: 56 + y: 15 + tile: 186 + } + cell { + x: -9 + y: 15 + tile: 186 + } + cell { + x: -8 + y: 15 + tile: 186 + } + cell { + x: -7 + y: 15 + tile: 186 + } + cell { + x: -6 + y: 15 + tile: 23 + } + cell { + x: -5 + y: 15 + tile: 23 + } + cell { + x: -4 + y: 15 + tile: 23 + } + cell { + x: -3 + y: 15 + tile: 23 + } + cell { + x: -2 + y: 15 + tile: 23 + } + cell { + x: -1 + y: 15 + tile: 23 + } + cell { + x: 0 + y: 16 + tile: 23 + } + cell { + x: 1 + y: 16 + tile: 23 + } + cell { + x: 2 + y: 16 + tile: 23 + } + cell { + x: 3 + y: 16 + tile: 23 + } + cell { + x: 4 + y: 16 + tile: 23 + } + cell { + x: 5 + y: 16 + tile: 23 + } + cell { + x: 6 + y: 16 + tile: 23 + } + cell { + x: 7 + y: 16 + tile: 23 + } + cell { + x: 8 + y: 16 + tile: 23 + } + cell { + x: 9 + y: 16 + tile: 23 + } + cell { + x: 10 + y: 16 + tile: 23 + } + cell { + x: 11 + y: 16 + tile: 23 + } + cell { + x: 12 + y: 16 + tile: 23 + } + cell { + x: 13 + y: 16 + tile: 23 + } + cell { + x: 14 + y: 16 + tile: 23 + } + cell { + x: 15 + y: 16 + tile: 23 + } + cell { + x: 16 + y: 16 + tile: 23 + } + cell { + x: 17 + y: 16 + tile: 23 + } + cell { + x: 18 + y: 16 + tile: 23 + } + cell { + x: 19 + y: 16 + tile: 23 + } + cell { + x: 20 + y: 16 + tile: 23 + } + cell { + x: 21 + y: 16 + tile: 23 + } + cell { + x: 22 + y: 16 + tile: 23 + } + cell { + x: 23 + y: 16 + tile: 23 + } + cell { + x: 24 + y: 16 + tile: 23 + } + cell { + x: 25 + y: 16 + tile: 23 + } + cell { + x: 26 + y: 16 + tile: 91 + } + cell { + x: 27 + y: 16 + tile: 91 + } + cell { + x: 28 + y: 16 + tile: 91 + } + cell { + x: 29 + y: 16 + tile: 91 + } + cell { + x: 30 + y: 16 + tile: 91 + } + cell { + x: 31 + y: 16 + tile: 91 + } + cell { + x: 32 + y: 16 + tile: 91 + } + cell { + x: 33 + y: 16 + tile: 91 + } + cell { + x: 34 + y: 16 + tile: 91 + } + cell { + x: 35 + y: 16 + tile: 91 + } + cell { + x: 36 + y: 16 + tile: 91 + } + cell { + x: 37 + y: 16 + tile: 91 + } + cell { + x: 38 + y: 16 + tile: 91 + } + cell { + x: 39 + y: 16 + tile: 91 + } + cell { + x: 40 + y: 16 + tile: 186 + } + cell { + x: 41 + y: 16 + tile: 186 + } + cell { + x: 42 + y: 16 + tile: 186 + } + cell { + x: 43 + y: 16 + tile: 186 + } + cell { + x: 44 + y: 16 + tile: 186 + } + cell { + x: 45 + y: 16 + tile: 186 + } + cell { + x: 46 + y: 16 + tile: 186 + } + cell { + x: 47 + y: 16 + tile: 186 + } + cell { + x: 48 + y: 16 + tile: 186 + } + cell { + x: 49 + y: 16 + tile: 186 + } + cell { + x: 50 + y: 16 + tile: 186 + } + cell { + x: 51 + y: 16 + tile: 186 + } + cell { + x: 52 + y: 16 + tile: 186 + } + cell { + x: 53 + y: 16 + tile: 186 + } + cell { + x: 54 + y: 16 + tile: 186 + } + cell { + x: 55 + y: 16 + tile: 186 + } + cell { + x: 56 + y: 16 + tile: 186 + } + cell { + x: -9 + y: 16 + tile: 186 + } + cell { + x: -8 + y: 16 + tile: 186 + } + cell { + x: -7 + y: 16 + tile: 186 + } + cell { + x: -6 + y: 16 + tile: 23 + } + cell { + x: -5 + y: 16 + tile: 23 + } + cell { + x: -4 + y: 16 + tile: 23 + } + cell { + x: -3 + y: 16 + tile: 23 + } + cell { + x: -2 + y: 16 + tile: 23 + } + cell { + x: -1 + y: 16 + tile: 23 + } + cell { + x: 0 + y: 17 + tile: 23 + } + cell { + x: 1 + y: 17 + tile: 23 + } + cell { + x: 2 + y: 17 + tile: 23 + } + cell { + x: 3 + y: 17 + tile: 23 + } + cell { + x: 4 + y: 17 + tile: 23 + } + cell { + x: 5 + y: 17 + tile: 23 + } + cell { + x: 6 + y: 17 + tile: 23 + } + cell { + x: 7 + y: 17 + tile: 23 + } + cell { + x: 8 + y: 17 + tile: 23 + } + cell { + x: 9 + y: 17 + tile: 23 + } + cell { + x: 10 + y: 17 + tile: 23 + } + cell { + x: 11 + y: 17 + tile: 23 + } + cell { + x: 12 + y: 17 + tile: 23 + } + cell { + x: 13 + y: 17 + tile: 23 + } + cell { + x: 14 + y: 17 + tile: 23 + } + cell { + x: 15 + y: 17 + tile: 23 + } + cell { + x: 16 + y: 17 + tile: 23 + } + cell { + x: 17 + y: 17 + tile: 23 + } + cell { + x: 18 + y: 17 + tile: 23 + } + cell { + x: 19 + y: 17 + tile: 23 + } + cell { + x: 20 + y: 17 + tile: 23 + } + cell { + x: 21 + y: 17 + tile: 23 + } + cell { + x: 22 + y: 17 + tile: 23 + } + cell { + x: 23 + y: 17 + tile: 23 + } + cell { + x: 24 + y: 17 + tile: 23 + } + cell { + x: 25 + y: 17 + tile: 23 + } + cell { + x: 26 + y: 17 + tile: 91 + } + cell { + x: 27 + y: 17 + tile: 91 + } + cell { + x: 28 + y: 17 + tile: 91 + } + cell { + x: 29 + y: 17 + tile: 91 + } + cell { + x: 30 + y: 17 + tile: 91 + } + cell { + x: 31 + y: 17 + tile: 91 + } + cell { + x: 32 + y: 17 + tile: 91 + } + cell { + x: 33 + y: 17 + tile: 91 + } + cell { + x: 34 + y: 17 + tile: 91 + } + cell { + x: 35 + y: 17 + tile: 91 + } + cell { + x: 36 + y: 17 + tile: 91 + } + cell { + x: 37 + y: 17 + tile: 91 + } + cell { + x: 38 + y: 17 + tile: 91 + } + cell { + x: 39 + y: 17 + tile: 91 + } + cell { + x: 40 + y: 17 + tile: 186 + } + cell { + x: 41 + y: 17 + tile: 186 + } + cell { + x: 42 + y: 17 + tile: 186 + } + cell { + x: 43 + y: 17 + tile: 186 + } + cell { + x: 44 + y: 17 + tile: 186 + } + cell { + x: 45 + y: 17 + tile: 186 + } + cell { + x: 46 + y: 17 + tile: 186 + } + cell { + x: 47 + y: 17 + tile: 186 + } + cell { + x: 48 + y: 17 + tile: 186 + } + cell { + x: 49 + y: 17 + tile: 186 + } + cell { + x: 50 + y: 17 + tile: 186 + } + cell { + x: 51 + y: 17 + tile: 186 + } + cell { + x: 52 + y: 17 + tile: 186 + } + cell { + x: 53 + y: 17 + tile: 186 + } + cell { + x: 54 + y: 17 + tile: 186 + } + cell { + x: 55 + y: 17 + tile: 186 + } + cell { + x: 56 + y: 17 + tile: 186 + } + cell { + x: -9 + y: 17 + tile: 186 + } + cell { + x: -8 + y: 17 + tile: 186 + } + cell { + x: -7 + y: 17 + tile: 186 + } + cell { + x: -6 + y: 17 + tile: 23 + } + cell { + x: -5 + y: 17 + tile: 23 + } + cell { + x: -4 + y: 17 + tile: 23 + } + cell { + x: -3 + y: 17 + tile: 23 + } + cell { + x: -2 + y: 17 + tile: 23 + } + cell { + x: -1 + y: 17 + tile: 23 + } + cell { + x: 0 + y: 18 + tile: 23 + } + cell { + x: 1 + y: 18 + tile: 23 + } + cell { + x: 2 + y: 18 + tile: 23 + } + cell { + x: 3 + y: 18 + tile: 23 + } + cell { + x: 4 + y: 18 + tile: 23 + } + cell { + x: 5 + y: 18 + tile: 23 + } + cell { + x: 6 + y: 18 + tile: 23 + } + cell { + x: 7 + y: 18 + tile: 23 + } + cell { + x: 8 + y: 18 + tile: 23 + } + cell { + x: 9 + y: 18 + tile: 23 + } + cell { + x: 10 + y: 18 + tile: 23 + } + cell { + x: 11 + y: 18 + tile: 23 + } + cell { + x: 12 + y: 18 + tile: 23 + } + cell { + x: 13 + y: 18 + tile: 23 + } + cell { + x: 14 + y: 18 + tile: 23 + } + cell { + x: 15 + y: 18 + tile: 23 + } + cell { + x: 16 + y: 18 + tile: 23 + } + cell { + x: 17 + y: 18 + tile: 23 + } + cell { + x: 18 + y: 18 + tile: 23 + } + cell { + x: 19 + y: 18 + tile: 23 + } + cell { + x: 20 + y: 18 + tile: 23 + } + cell { + x: 21 + y: 18 + tile: 23 + } + cell { + x: 22 + y: 18 + tile: 23 + } + cell { + x: 23 + y: 18 + tile: 23 + } + cell { + x: 24 + y: 18 + tile: 23 + } + cell { + x: 25 + y: 18 + tile: 23 + } + cell { + x: 26 + y: 18 + tile: 91 + } + cell { + x: 27 + y: 18 + tile: 91 + } + cell { + x: 28 + y: 18 + tile: 96 + } + cell { + x: 29 + y: 18 + tile: 96 + } + cell { + x: 30 + y: 18 + tile: 96 + } + cell { + x: 31 + y: 18 + tile: 96 + } + cell { + x: 32 + y: 18 + tile: 96 + } + cell { + x: 33 + y: 18 + tile: 96 + } + cell { + x: 34 + y: 18 + tile: 96 + } + cell { + x: 35 + y: 18 + tile: 96 + } + cell { + x: 36 + y: 18 + tile: 91 + } + cell { + x: 37 + y: 18 + tile: 91 + } + cell { + x: 38 + y: 18 + tile: 91 + } + cell { + x: 39 + y: 18 + tile: 91 + } + cell { + x: 40 + y: 18 + tile: 186 + } + cell { + x: 41 + y: 18 + tile: 186 + } + cell { + x: 42 + y: 18 + tile: 186 + } + cell { + x: 43 + y: 18 + tile: 186 + } + cell { + x: 44 + y: 18 + tile: 186 + } + cell { + x: 45 + y: 18 + tile: 186 + } + cell { + x: 46 + y: 18 + tile: 186 + } + cell { + x: 47 + y: 18 + tile: 186 + } + cell { + x: 48 + y: 18 + tile: 186 + } + cell { + x: 49 + y: 18 + tile: 186 + } + cell { + x: 50 + y: 18 + tile: 186 + } + cell { + x: 51 + y: 18 + tile: 186 + } + cell { + x: 52 + y: 18 + tile: 186 + } + cell { + x: 53 + y: 18 + tile: 186 + } + cell { + x: 54 + y: 18 + tile: 186 + } + cell { + x: 55 + y: 18 + tile: 186 + } + cell { + x: 56 + y: 18 + tile: 186 + } + cell { + x: -9 + y: 18 + tile: 186 + } + cell { + x: -8 + y: 18 + tile: 186 + } + cell { + x: -7 + y: 18 + tile: 186 + } + cell { + x: -6 + y: 18 + tile: 23 + } + cell { + x: -5 + y: 18 + tile: 23 + } + cell { + x: -4 + y: 18 + tile: 23 + } + cell { + x: -3 + y: 18 + tile: 23 + } + cell { + x: -2 + y: 18 + tile: 23 + } + cell { + x: -1 + y: 18 + tile: 23 + } + cell { + x: 0 + y: 19 + tile: 23 + } + cell { + x: 1 + y: 19 + tile: 23 + } + cell { + x: 2 + y: 19 + tile: 23 + } + cell { + x: 3 + y: 19 + tile: 23 + } + cell { + x: 4 + y: 19 + tile: 23 + } + cell { + x: 5 + y: 19 + tile: 23 + } + cell { + x: 6 + y: 19 + tile: 23 + } + cell { + x: 7 + y: 19 + tile: 23 + } + cell { + x: 8 + y: 19 + tile: 23 + } + cell { + x: 9 + y: 19 + tile: 23 + } + cell { + x: 10 + y: 19 + tile: 23 + } + cell { + x: 11 + y: 19 + tile: 23 + } + cell { + x: 12 + y: 19 + tile: 23 + } + cell { + x: 13 + y: 19 + tile: 23 + } + cell { + x: 14 + y: 19 + tile: 23 + } + cell { + x: 15 + y: 19 + tile: 23 + } + cell { + x: 16 + y: 19 + tile: 23 + } + cell { + x: 17 + y: 19 + tile: 23 + } + cell { + x: 18 + y: 19 + tile: 23 + } + cell { + x: 19 + y: 19 + tile: 23 + } + cell { + x: 20 + y: 19 + tile: 23 + } + cell { + x: 21 + y: 19 + tile: 23 + } + cell { + x: 22 + y: 19 + tile: 23 + } + cell { + x: 23 + y: 19 + tile: 23 + } + cell { + x: 24 + y: 19 + tile: 23 + } + cell { + x: 25 + y: 19 + tile: 23 + } + cell { + x: 26 + y: 19 + tile: 23 + } + cell { + x: 27 + y: 19 + tile: 96 + } + cell { + x: 28 + y: 19 + tile: 96 + } + cell { + x: 29 + y: 19 + tile: 96 + } + cell { + x: 30 + y: 19 + tile: 96 + } + cell { + x: 31 + y: 19 + tile: 96 + } + cell { + x: 32 + y: 19 + tile: 96 + } + cell { + x: 33 + y: 19 + tile: 96 + } + cell { + x: 34 + y: 19 + tile: 96 + } + cell { + x: 35 + y: 19 + tile: 96 + } + cell { + x: 36 + y: 19 + tile: 96 + } + cell { + x: 37 + y: 19 + tile: 96 + } + cell { + x: 38 + y: 19 + tile: 96 + } + cell { + x: 39 + y: 19 + tile: 96 + } + cell { + x: 40 + y: 19 + tile: 186 + } + cell { + x: 41 + y: 19 + tile: 186 + } + cell { + x: 42 + y: 19 + tile: 186 + } + cell { + x: 43 + y: 19 + tile: 186 + } + cell { + x: 44 + y: 19 + tile: 186 + } + cell { + x: 45 + y: 19 + tile: 186 + } + cell { + x: 46 + y: 19 + tile: 186 + } + cell { + x: 47 + y: 19 + tile: 186 + } + cell { + x: 48 + y: 19 + tile: 186 + } + cell { + x: 49 + y: 19 + tile: 186 + } + cell { + x: 50 + y: 19 + tile: 186 + } + cell { + x: 51 + y: 19 + tile: 186 + } + cell { + x: 52 + y: 19 + tile: 186 + } + cell { + x: 53 + y: 19 + tile: 186 + } + cell { + x: 54 + y: 19 + tile: 186 + } + cell { + x: 55 + y: 19 + tile: 186 + } + cell { + x: 56 + y: 19 + tile: 186 + } + cell { + x: -9 + y: 19 + tile: 186 + } + cell { + x: -8 + y: 19 + tile: 186 + } + cell { + x: -7 + y: 19 + tile: 186 + } + cell { + x: -6 + y: 19 + tile: 186 + } + cell { + x: -5 + y: 19 + tile: 23 + } + cell { + x: -4 + y: 19 + tile: 23 + } + cell { + x: -3 + y: 19 + tile: 23 + } + cell { + x: -2 + y: 19 + tile: 23 + } + cell { + x: -1 + y: 19 + tile: 23 + } + cell { + x: 0 + y: 20 + tile: 23 + } + cell { + x: 1 + y: 20 + tile: 23 + } + cell { + x: 2 + y: 20 + tile: 23 + } + cell { + x: 3 + y: 20 + tile: 23 + } + cell { + x: 4 + y: 20 + tile: 23 + } + cell { + x: 5 + y: 20 + tile: 23 + } + cell { + x: 6 + y: 20 + tile: 23 + } + cell { + x: 7 + y: 20 + tile: 23 + } + cell { + x: 8 + y: 20 + tile: 23 + } + cell { + x: 9 + y: 20 + tile: 23 + } + cell { + x: 10 + y: 20 + tile: 23 + } + cell { + x: 11 + y: 20 + tile: 23 + } + cell { + x: 12 + y: 20 + tile: 23 + } + cell { + x: 13 + y: 20 + tile: 23 + } + cell { + x: 14 + y: 20 + tile: 23 + } + cell { + x: 15 + y: 20 + tile: 23 + } + cell { + x: 16 + y: 20 + tile: 23 + } + cell { + x: 17 + y: 20 + tile: 23 + } + cell { + x: 18 + y: 20 + tile: 23 + } + cell { + x: 19 + y: 20 + tile: 23 + } + cell { + x: 20 + y: 20 + tile: 23 + } + cell { + x: 21 + y: 20 + tile: 23 + } + cell { + x: 22 + y: 20 + tile: 23 + } + cell { + x: 23 + y: 20 + tile: 23 + } + cell { + x: 24 + y: 20 + tile: 23 + } + cell { + x: 25 + y: 20 + tile: 96 + } + cell { + x: 26 + y: 20 + tile: 96 + } + cell { + x: 27 + y: 20 + tile: 96 + } + cell { + x: 28 + y: 20 + tile: 96 + } + cell { + x: 29 + y: 20 + tile: 96 + } + cell { + x: 30 + y: 20 + tile: 96 + } + cell { + x: 31 + y: 20 + tile: 96 + } + cell { + x: 32 + y: 20 + tile: 96 + } + cell { + x: 33 + y: 20 + tile: 96 + } + cell { + x: 34 + y: 20 + tile: 96 + } + cell { + x: 35 + y: 20 + tile: 96 + } + cell { + x: 36 + y: 20 + tile: 96 + } + cell { + x: 37 + y: 20 + tile: 96 + } + cell { + x: 38 + y: 20 + tile: 96 + } + cell { + x: 39 + y: 20 + tile: 96 + } + cell { + x: 40 + y: 20 + tile: 186 + } + cell { + x: 41 + y: 20 + tile: 186 + } + cell { + x: 42 + y: 20 + tile: 186 + } + cell { + x: 43 + y: 20 + tile: 186 + } + cell { + x: 44 + y: 20 + tile: 186 + } + cell { + x: 45 + y: 20 + tile: 186 + } + cell { + x: 46 + y: 20 + tile: 186 + } + cell { + x: 47 + y: 20 + tile: 186 + } + cell { + x: 48 + y: 20 + tile: 186 + } + cell { + x: 49 + y: 20 + tile: 186 + } + cell { + x: 50 + y: 20 + tile: 186 + } + cell { + x: 51 + y: 20 + tile: 186 + } + cell { + x: 52 + y: 20 + tile: 186 + } + cell { + x: 53 + y: 20 + tile: 186 + } + cell { + x: 54 + y: 20 + tile: 186 + } + cell { + x: 55 + y: 20 + tile: 186 + } + cell { + x: 56 + y: 20 + tile: 186 + } + cell { + x: -8 + y: 20 + tile: 186 + } + cell { + x: -7 + y: 20 + tile: 186 + } + cell { + x: -6 + y: 20 + tile: 186 + } + cell { + x: -5 + y: 20 + tile: 23 + } + cell { + x: -4 + y: 20 + tile: 23 + } + cell { + x: -3 + y: 20 + tile: 23 + } + cell { + x: -2 + y: 20 + tile: 23 + } + cell { + x: -1 + y: 20 + tile: 23 + } + cell { + x: 0 + y: 21 + tile: 23 + } + cell { + x: 1 + y: 21 + tile: 23 + } + cell { + x: 2 + y: 21 + tile: 23 + } + cell { + x: 3 + y: 21 + tile: 23 + } + cell { + x: 4 + y: 21 + tile: 23 + } + cell { + x: 5 + y: 21 + tile: 23 + } + cell { + x: 6 + y: 21 + tile: 23 + } + cell { + x: 7 + y: 21 + tile: 23 + } + cell { + x: 8 + y: 21 + tile: 23 + } + cell { + x: 9 + y: 21 + tile: 23 + } + cell { + x: 10 + y: 21 + tile: 23 + } + cell { + x: 11 + y: 21 + tile: 23 + } + cell { + x: 12 + y: 21 + tile: 23 + } + cell { + x: 13 + y: 21 + tile: 23 + } + cell { + x: 14 + y: 21 + tile: 23 + } + cell { + x: 15 + y: 21 + tile: 23 + } + cell { + x: 16 + y: 21 + tile: 23 + } + cell { + x: 17 + y: 21 + tile: 23 + } + cell { + x: 18 + y: 21 + tile: 23 + } + cell { + x: 19 + y: 21 + tile: 23 + } + cell { + x: 20 + y: 21 + tile: 23 + } + cell { + x: 21 + y: 21 + tile: 23 + } + cell { + x: 22 + y: 21 + tile: 23 + } + cell { + x: 23 + y: 21 + tile: 23 + } + cell { + x: 24 + y: 21 + tile: 96 + } + cell { + x: 25 + y: 21 + tile: 96 + } + cell { + x: 26 + y: 21 + tile: 96 + } + cell { + x: 27 + y: 21 + tile: 96 + } + cell { + x: 28 + y: 21 + tile: 96 + } + cell { + x: 29 + y: 21 + tile: 96 + } + cell { + x: 30 + y: 21 + tile: 96 + } + cell { + x: 31 + y: 21 + tile: 96 + } + cell { + x: 32 + y: 21 + tile: 96 + } + cell { + x: 33 + y: 21 + tile: 96 + } + cell { + x: 34 + y: 21 + tile: 96 + } + cell { + x: 35 + y: 21 + tile: 96 + } + cell { + x: 36 + y: 21 + tile: 96 + } + cell { + x: 37 + y: 21 + tile: 96 + } + cell { + x: 38 + y: 21 + tile: 96 + } + cell { + x: 39 + y: 21 + tile: 96 + } + cell { + x: 40 + y: 21 + tile: 186 + } + cell { + x: 41 + y: 21 + tile: 186 + } + cell { + x: 42 + y: 21 + tile: 186 + } + cell { + x: 43 + y: 21 + tile: 186 + } + cell { + x: 44 + y: 21 + tile: 186 + } + cell { + x: 45 + y: 21 + tile: 186 + } + cell { + x: 46 + y: 21 + tile: 186 + } + cell { + x: 47 + y: 21 + tile: 186 + } + cell { + x: 48 + y: 21 + tile: 186 + } + cell { + x: 49 + y: 21 + tile: 186 + } + cell { + x: 50 + y: 21 + tile: 186 + } + cell { + x: 51 + y: 21 + tile: 186 + } + cell { + x: 52 + y: 21 + tile: 186 + } + cell { + x: 53 + y: 21 + tile: 186 + } + cell { + x: 54 + y: 21 + tile: 186 + } + cell { + x: 55 + y: 21 + tile: 186 + } + cell { + x: 56 + y: 21 + tile: 186 + } + cell { + x: -8 + y: 21 + tile: 186 + } + cell { + x: -7 + y: 21 + tile: 186 + } + cell { + x: -6 + y: 21 + tile: 186 + } + cell { + x: -5 + y: 21 + tile: 23 + } + cell { + x: -4 + y: 21 + tile: 23 + } + cell { + x: -3 + y: 21 + tile: 23 + } + cell { + x: -2 + y: 21 + tile: 23 + } + cell { + x: -1 + y: 21 + tile: 23 + } + cell { + x: 0 + y: 22 + tile: 23 + } + cell { + x: 1 + y: 22 + tile: 23 + } + cell { + x: 2 + y: 22 + tile: 23 + } + cell { + x: 3 + y: 22 + tile: 23 + } + cell { + x: 4 + y: 22 + tile: 23 + } + cell { + x: 5 + y: 22 + tile: 23 + } + cell { + x: 6 + y: 22 + tile: 23 + } + cell { + x: 7 + y: 22 + tile: 23 + } + cell { + x: 8 + y: 22 + tile: 23 + } + cell { + x: 9 + y: 22 + tile: 23 + } + cell { + x: 10 + y: 22 + tile: 23 + } + cell { + x: 11 + y: 22 + tile: 23 + } + cell { + x: 12 + y: 22 + tile: 23 + } + cell { + x: 13 + y: 22 + tile: 23 + } + cell { + x: 14 + y: 22 + tile: 23 + } + cell { + x: 15 + y: 22 + tile: 23 + } + cell { + x: 16 + y: 22 + tile: 23 + } + cell { + x: 17 + y: 22 + tile: 23 + } + cell { + x: 18 + y: 22 + tile: 23 + } + cell { + x: 19 + y: 22 + tile: 23 + } + cell { + x: 20 + y: 22 + tile: 23 + } + cell { + x: 21 + y: 22 + tile: 23 + } + cell { + x: 22 + y: 22 + tile: 23 + } + cell { + x: 23 + y: 22 + tile: 23 + } + cell { + x: 24 + y: 22 + tile: 96 + } + cell { + x: 25 + y: 22 + tile: 96 + } + cell { + x: 26 + y: 22 + tile: 96 + } + cell { + x: 27 + y: 22 + tile: 96 + } + cell { + x: 28 + y: 22 + tile: 96 + } + cell { + x: 29 + y: 22 + tile: 96 + } + cell { + x: 30 + y: 22 + tile: 96 + } + cell { + x: 31 + y: 22 + tile: 96 + } + cell { + x: 32 + y: 22 + tile: 96 + } + cell { + x: 33 + y: 22 + tile: 96 + } + cell { + x: 34 + y: 22 + tile: 96 + } + cell { + x: 35 + y: 22 + tile: 96 + } + cell { + x: 36 + y: 22 + tile: 96 + } + cell { + x: 37 + y: 22 + tile: 96 + } + cell { + x: 38 + y: 22 + tile: 96 + } + cell { + x: 39 + y: 22 + tile: 96 + } + cell { + x: 40 + y: 22 + tile: 186 + } + cell { + x: 41 + y: 22 + tile: 186 + } + cell { + x: 42 + y: 22 + tile: 186 + } + cell { + x: 43 + y: 22 + tile: 186 + } + cell { + x: 44 + y: 22 + tile: 186 + } + cell { + x: 45 + y: 22 + tile: 186 + } + cell { + x: 46 + y: 22 + tile: 186 + } + cell { + x: 47 + y: 22 + tile: 186 + } + cell { + x: 48 + y: 22 + tile: 186 + } + cell { + x: 49 + y: 22 + tile: 186 + } + cell { + x: 50 + y: 22 + tile: 186 + } + cell { + x: 51 + y: 22 + tile: 186 + } + cell { + x: 52 + y: 22 + tile: 186 + } + cell { + x: 53 + y: 22 + tile: 186 + } + cell { + x: 54 + y: 22 + tile: 186 + } + cell { + x: 55 + y: 22 + tile: 186 + } + cell { + x: 56 + y: 22 + tile: 186 + } + cell { + x: -7 + y: 22 + tile: 186 + } + cell { + x: -6 + y: 22 + tile: 186 + } + cell { + x: -5 + y: 22 + tile: 186 + } + cell { + x: -4 + y: 22 + tile: 23 + } + cell { + x: -3 + y: 22 + tile: 23 + } + cell { + x: -2 + y: 22 + tile: 23 + } + cell { + x: -1 + y: 22 + tile: 23 + } + cell { + x: 0 + y: 23 + tile: 23 + } + cell { + x: 1 + y: 23 + tile: 23 + } + cell { + x: 2 + y: 23 + tile: 23 + } + cell { + x: 3 + y: 23 + tile: 23 + } + cell { + x: 4 + y: 23 + tile: 23 + } + cell { + x: 5 + y: 23 + tile: 23 + } + cell { + x: 6 + y: 23 + tile: 23 + } + cell { + x: 7 + y: 23 + tile: 23 + } + cell { + x: 8 + y: 23 + tile: 23 + } + cell { + x: 9 + y: 23 + tile: 23 + } + cell { + x: 10 + y: 23 + tile: 23 + } + cell { + x: 11 + y: 23 + tile: 23 + } + cell { + x: 12 + y: 23 + tile: 23 + } + cell { + x: 13 + y: 23 + tile: 23 + } + cell { + x: 14 + y: 23 + tile: 23 + } + cell { + x: 15 + y: 23 + tile: 23 + } + cell { + x: 16 + y: 23 + tile: 23 + } + cell { + x: 17 + y: 23 + tile: 23 + } + cell { + x: 18 + y: 23 + tile: 23 + } + cell { + x: 19 + y: 23 + tile: 23 + } + cell { + x: 20 + y: 23 + tile: 23 + } + cell { + x: 21 + y: 23 + tile: 23 + } + cell { + x: 22 + y: 23 + tile: 23 + } + cell { + x: 23 + y: 23 + tile: 23 + } + cell { + x: 24 + y: 23 + tile: 23 + } + cell { + x: 25 + y: 23 + tile: 96 + } + cell { + x: 26 + y: 23 + tile: 96 + } + cell { + x: 27 + y: 23 + tile: 96 + } + cell { + x: 28 + y: 23 + tile: 96 + } + cell { + x: 29 + y: 23 + tile: 96 + } + cell { + x: 30 + y: 23 + tile: 96 + } + cell { + x: 31 + y: 23 + tile: 96 + } + cell { + x: 32 + y: 23 + tile: 96 + } + cell { + x: 33 + y: 23 + tile: 96 + } + cell { + x: 34 + y: 23 + tile: 96 + } + cell { + x: 35 + y: 23 + tile: 96 + } + cell { + x: 36 + y: 23 + tile: 96 + } + cell { + x: 37 + y: 23 + tile: 96 + } + cell { + x: 38 + y: 23 + tile: 96 + } + cell { + x: 39 + y: 23 + tile: 96 + } + cell { + x: 40 + y: 23 + tile: 96 + } + cell { + x: 41 + y: 23 + tile: 186 + } + cell { + x: 42 + y: 23 + tile: 186 + } + cell { + x: 43 + y: 23 + tile: 186 + } + cell { + x: 44 + y: 23 + tile: 186 + } + cell { + x: 45 + y: 23 + tile: 186 + } + cell { + x: 46 + y: 23 + tile: 186 + } + cell { + x: 47 + y: 23 + tile: 186 + } + cell { + x: 48 + y: 23 + tile: 186 + } + cell { + x: 49 + y: 23 + tile: 186 + } + cell { + x: 50 + y: 23 + tile: 186 + } + cell { + x: 51 + y: 23 + tile: 186 + } + cell { + x: 52 + y: 23 + tile: 186 + } + cell { + x: 53 + y: 23 + tile: 186 + } + cell { + x: 54 + y: 23 + tile: 186 + } + cell { + x: 55 + y: 23 + tile: 186 + } + cell { + x: 56 + y: 23 + tile: 186 + } + cell { + x: -7 + y: 23 + tile: 186 + } + cell { + x: -6 + y: 23 + tile: 186 + } + cell { + x: -5 + y: 23 + tile: 186 + } + cell { + x: -4 + y: 23 + tile: 186 + } + cell { + x: -3 + y: 23 + tile: 203 + } + cell { + x: -2 + y: 23 + tile: 23 + } + cell { + x: -1 + y: 23 + tile: 23 + } + cell { + x: 0 + y: 24 + tile: 23 + } + cell { + x: 1 + y: 24 + tile: 23 + } + cell { + x: 2 + y: 24 + tile: 23 + } + cell { + x: 3 + y: 24 + tile: 23 + } + cell { + x: 4 + y: 24 + tile: 23 + } + cell { + x: 5 + y: 24 + tile: 23 + } + cell { + x: 6 + y: 24 + tile: 23 + } + cell { + x: 7 + y: 24 + tile: 23 + } + cell { + x: 8 + y: 24 + tile: 23 + } + cell { + x: 9 + y: 24 + tile: 23 + } + cell { + x: 10 + y: 24 + tile: 23 + } + cell { + x: 11 + y: 24 + tile: 23 + } + cell { + x: 12 + y: 24 + tile: 23 + } + cell { + x: 13 + y: 24 + tile: 23 + } + cell { + x: 14 + y: 24 + tile: 23 + } + cell { + x: 15 + y: 24 + tile: 23 + } + cell { + x: 16 + y: 24 + tile: 23 + } + cell { + x: 17 + y: 24 + tile: 23 + } + cell { + x: 18 + y: 24 + tile: 23 + } + cell { + x: 19 + y: 24 + tile: 23 + } + cell { + x: 20 + y: 24 + tile: 23 + } + cell { + x: 21 + y: 24 + tile: 23 + } + cell { + x: 22 + y: 24 + tile: 23 + } + cell { + x: 23 + y: 24 + tile: 23 + } + cell { + x: 24 + y: 24 + tile: 96 + } + cell { + x: 25 + y: 24 + tile: 96 + } + cell { + x: 26 + y: 24 + tile: 96 + } + cell { + x: 27 + y: 24 + tile: 96 + } + cell { + x: 28 + y: 24 + tile: 96 + } + cell { + x: 29 + y: 24 + tile: 96 + } + cell { + x: 30 + y: 24 + tile: 96 + } + cell { + x: 31 + y: 24 + tile: 96 + } + cell { + x: 32 + y: 24 + tile: 96 + } + cell { + x: 33 + y: 24 + tile: 96 + } + cell { + x: 34 + y: 24 + tile: 96 + } + cell { + x: 35 + y: 24 + tile: 96 + } + cell { + x: 36 + y: 24 + tile: 96 + } + cell { + x: 37 + y: 24 + tile: 96 + } + cell { + x: 38 + y: 24 + tile: 96 + } + cell { + x: 39 + y: 24 + tile: 96 + } + cell { + x: 40 + y: 24 + tile: 186 + } + cell { + x: 41 + y: 24 + tile: 186 + } + cell { + x: 42 + y: 24 + tile: 186 + } + cell { + x: 43 + y: 24 + tile: 186 + } + cell { + x: 44 + y: 24 + tile: 186 + } + cell { + x: 45 + y: 24 + tile: 186 + } + cell { + x: 46 + y: 24 + tile: 186 + } + cell { + x: 47 + y: 24 + tile: 186 + } + cell { + x: 48 + y: 24 + tile: 186 + } + cell { + x: 49 + y: 24 + tile: 186 + } + cell { + x: 50 + y: 24 + tile: 186 + } + cell { + x: 51 + y: 24 + tile: 186 + } + cell { + x: 52 + y: 24 + tile: 186 + } + cell { + x: 53 + y: 24 + tile: 186 + } + cell { + x: 54 + y: 24 + tile: 186 + } + cell { + x: -7 + y: 24 + tile: 186 + } + cell { + x: -6 + y: 24 + tile: 186 + } + cell { + x: -5 + y: 24 + tile: 186 + } + cell { + x: -4 + y: 24 + tile: 186 + } + cell { + x: -3 + y: 24 + tile: 203 + } + cell { + x: -2 + y: 24 + tile: 203 + } + cell { + x: -1 + y: 24 + tile: 203 + } + cell { + x: 0 + y: 25 + tile: 86 + } + cell { + x: 1 + y: 25 + tile: 86 + } + cell { + x: 2 + y: 25 + tile: 86 + } + cell { + x: 3 + y: 25 + tile: 86 + } + cell { + x: 4 + y: 25 + tile: 86 + } + cell { + x: 5 + y: 25 + tile: 86 + } + cell { + x: 6 + y: 25 + tile: 86 + } + cell { + x: 7 + y: 25 + tile: 86 + } + cell { + x: 8 + y: 25 + tile: 86 + } + cell { + x: 9 + y: 25 + tile: 86 + } + cell { + x: 10 + y: 25 + tile: 86 + } + cell { + x: 11 + y: 25 + tile: 86 + } + cell { + x: 12 + y: 25 + tile: 23 + } + cell { + x: 13 + y: 25 + tile: 23 + } + cell { + x: 14 + y: 25 + tile: 23 + } + cell { + x: 15 + y: 25 + tile: 23 + } + cell { + x: 16 + y: 25 + tile: 23 + } + cell { + x: 17 + y: 25 + tile: 23 + } + cell { + x: 18 + y: 25 + tile: 86 + } + cell { + x: 19 + y: 25 + tile: 86 + } + cell { + x: 20 + y: 25 + tile: 86 + } + cell { + x: 21 + y: 25 + tile: 86 + } + cell { + x: 22 + y: 25 + tile: 96 + } + cell { + x: 23 + y: 25 + tile: 96 + } + cell { + x: 24 + y: 25 + tile: 96 + } + cell { + x: 25 + y: 25 + tile: 96 + } + cell { + x: 26 + y: 25 + tile: 96 + } + cell { + x: 27 + y: 25 + tile: 96 + } + cell { + x: 28 + y: 25 + tile: 96 + } + cell { + x: 29 + y: 25 + tile: 96 + } + cell { + x: 30 + y: 25 + tile: 96 + } + cell { + x: 31 + y: 25 + tile: 96 + } + cell { + x: 32 + y: 25 + tile: 96 + } + cell { + x: 33 + y: 25 + tile: 96 + } + cell { + x: 34 + y: 25 + tile: 96 + } + cell { + x: 35 + y: 25 + tile: 96 + } + cell { + x: 36 + y: 25 + tile: 96 + } + cell { + x: 37 + y: 25 + tile: 96 + } + cell { + x: 38 + y: 25 + tile: 96 + } + cell { + x: 39 + y: 25 + tile: 96 + } + cell { + x: 40 + y: 25 + tile: 186 + } + cell { + x: 41 + y: 25 + tile: 186 + } + cell { + x: 42 + y: 25 + tile: 186 + } + cell { + x: 43 + y: 25 + tile: 186 + } + cell { + x: 44 + y: 25 + tile: 186 + } + cell { + x: 45 + y: 25 + tile: 186 + } + cell { + x: 46 + y: 25 + tile: 186 + } + cell { + x: 47 + y: 25 + tile: 186 + } + cell { + x: 48 + y: 25 + tile: 186 + } + cell { + x: 49 + y: 25 + tile: 186 + } + cell { + x: 50 + y: 25 + tile: 186 + } + cell { + x: 51 + y: 25 + tile: 186 + } + cell { + x: 52 + y: 25 + tile: 186 + } + cell { + x: 53 + y: 25 + tile: 186 + } + cell { + x: -6 + y: 25 + tile: 186 + } + cell { + x: -5 + y: 25 + tile: 186 + } + cell { + x: -4 + y: 25 + tile: 186 + } + cell { + x: -3 + y: 25 + tile: 186 + } + cell { + x: -2 + y: 25 + tile: 203 + } + cell { + x: -1 + y: 25 + tile: 203 + } + cell { + x: 0 + y: 26 + tile: 203 + } + cell { + x: 1 + y: 26 + tile: 86 + } + cell { + x: 2 + y: 26 + tile: 86 + } + cell { + x: 3 + y: 26 + tile: 86 + } + cell { + x: 4 + y: 26 + tile: 86 + } + cell { + x: 5 + y: 26 + tile: 86 + } + cell { + x: 6 + y: 26 + tile: 86 + } + cell { + x: 7 + y: 26 + tile: 86 + } + cell { + x: 8 + y: 26 + tile: 86 + } + cell { + x: 9 + y: 26 + tile: 86 + } + cell { + x: 10 + y: 26 + tile: 86 + } + cell { + x: 11 + y: 26 + tile: 86 + } + cell { + x: 12 + y: 26 + tile: 86 + } + cell { + x: 13 + y: 26 + tile: 86 + } + cell { + x: 14 + y: 26 + tile: 86 + } + cell { + x: 15 + y: 26 + tile: 86 + } + cell { + x: 16 + y: 26 + tile: 86 + } + cell { + x: 17 + y: 26 + tile: 86 + } + cell { + x: 18 + y: 26 + tile: 86 + } + cell { + x: 19 + y: 26 + tile: 86 + } + cell { + x: 20 + y: 26 + tile: 86 + } + cell { + x: 21 + y: 26 + tile: 86 + } + cell { + x: 22 + y: 26 + tile: 96 + } + cell { + x: 23 + y: 26 + tile: 96 + } + cell { + x: 24 + y: 26 + tile: 96 + } + cell { + x: 25 + y: 26 + tile: 96 + } + cell { + x: 26 + y: 26 + tile: 96 + } + cell { + x: 27 + y: 26 + tile: 96 + } + cell { + x: 28 + y: 26 + tile: 96 + } + cell { + x: 29 + y: 26 + tile: 96 + } + cell { + x: 30 + y: 26 + tile: 96 + } + cell { + x: 31 + y: 26 + tile: 96 + } + cell { + x: 32 + y: 26 + tile: 96 + } + cell { + x: 33 + y: 26 + tile: 96 + } + cell { + x: 34 + y: 26 + tile: 96 + } + cell { + x: 35 + y: 26 + tile: 96 + } + cell { + x: 36 + y: 26 + tile: 96 + } + cell { + x: 37 + y: 26 + tile: 96 + } + cell { + x: 38 + y: 26 + tile: 96 + } + cell { + x: 39 + y: 26 + tile: 186 + } + cell { + x: 40 + y: 26 + tile: 186 + } + cell { + x: 41 + y: 26 + tile: 186 + } + cell { + x: 42 + y: 26 + tile: 186 + } + cell { + x: 43 + y: 26 + tile: 186 + } + cell { + x: 44 + y: 26 + tile: 186 + } + cell { + x: 45 + y: 26 + tile: 186 + } + cell { + x: 46 + y: 26 + tile: 186 + } + cell { + x: 47 + y: 26 + tile: 186 + } + cell { + x: 48 + y: 26 + tile: 186 + } + cell { + x: 49 + y: 26 + tile: 186 + } + cell { + x: 50 + y: 26 + tile: 186 + } + cell { + x: 51 + y: 26 + tile: 186 + } + cell { + x: 52 + y: 26 + tile: 186 + } + cell { + x: 53 + y: 26 + tile: 186 + } + cell { + x: -4 + y: 26 + tile: 186 + } + cell { + x: -3 + y: 26 + tile: 186 + } + cell { + x: -2 + y: 26 + tile: 203 + } + cell { + x: -1 + y: 26 + tile: 203 + } + cell { + x: 0 + y: 27 + tile: 203 + } + cell { + x: 1 + y: 27 + tile: 203 + } + cell { + x: 2 + y: 27 + tile: 203 + } + cell { + x: 3 + y: 27 + tile: 203 + } + cell { + x: 4 + y: 27 + tile: 86 + } + cell { + x: 5 + y: 27 + tile: 86 + } + cell { + x: 6 + y: 27 + tile: 86 + } + cell { + x: 7 + y: 27 + tile: 86 + } + cell { + x: 8 + y: 27 + tile: 86 + } + cell { + x: 9 + y: 27 + tile: 86 + } + cell { + x: 10 + y: 27 + tile: 86 + } + cell { + x: 11 + y: 27 + tile: 86 + } + cell { + x: 12 + y: 27 + tile: 86 + } + cell { + x: 13 + y: 27 + tile: 86 + } + cell { + x: 14 + y: 27 + tile: 86 + } + cell { + x: 15 + y: 27 + tile: 86 + } + cell { + x: 16 + y: 27 + tile: 86 + } + cell { + x: 17 + y: 27 + tile: 203 + } + cell { + x: 18 + y: 27 + tile: 203 + } + cell { + x: 19 + y: 27 + tile: 203 + } + cell { + x: 20 + y: 27 + tile: 203 + } + cell { + x: 21 + y: 27 + tile: 203 + } + cell { + x: 22 + y: 27 + tile: 203 + } + cell { + x: 23 + y: 27 + tile: 203 + } + cell { + x: 24 + y: 27 + tile: 96 + } + cell { + x: 25 + y: 27 + tile: 96 + } + cell { + x: 26 + y: 27 + tile: 96 + } + cell { + x: 27 + y: 27 + tile: 96 + } + cell { + x: 28 + y: 27 + tile: 96 + } + cell { + x: 29 + y: 27 + tile: 96 + } + cell { + x: 30 + y: 27 + tile: 96 + } + cell { + x: 31 + y: 27 + tile: 96 + } + cell { + x: 32 + y: 27 + tile: 96 + } + cell { + x: 33 + y: 27 + tile: 96 + } + cell { + x: 34 + y: 27 + tile: 96 + } + cell { + x: 35 + y: 27 + tile: 96 + } + cell { + x: 36 + y: 27 + tile: 96 + } + cell { + x: 37 + y: 27 + tile: 96 + } + cell { + x: 38 + y: 27 + tile: 96 + } + cell { + x: 39 + y: 27 + tile: 186 + } + cell { + x: 40 + y: 27 + tile: 186 + } + cell { + x: 41 + y: 27 + tile: 186 + } + cell { + x: 42 + y: 27 + tile: 186 + } + cell { + x: 43 + y: 27 + tile: 186 + } + cell { + x: 44 + y: 27 + tile: 186 + } + cell { + x: 45 + y: 27 + tile: 186 + } + cell { + x: 46 + y: 27 + tile: 186 + } + cell { + x: 47 + y: 27 + tile: 186 + } + cell { + x: 48 + y: 27 + tile: 186 + } + cell { + x: 49 + y: 27 + tile: 186 + } + cell { + x: 50 + y: 27 + tile: 186 + } + cell { + x: 51 + y: 27 + tile: 186 + } + cell { + x: 52 + y: 27 + tile: 186 + } + cell { + x: -3 + y: 27 + tile: 186 + } + cell { + x: -2 + y: 27 + tile: 203 + } + cell { + x: -1 + y: 27 + tile: 203 + } + cell { + x: 0 + y: 28 + tile: 203 + } + cell { + x: 1 + y: 28 + tile: 203 + } + cell { + x: 2 + y: 28 + tile: 203 + } + cell { + x: 3 + y: 28 + tile: 203 + } + cell { + x: 4 + y: 28 + tile: 203 + } + cell { + x: 5 + y: 28 + tile: 203 + } + cell { + x: 6 + y: 28 + tile: 203 + } + cell { + x: 7 + y: 28 + tile: 203 + } + cell { + x: 8 + y: 28 + tile: 203 + } + cell { + x: 9 + y: 28 + tile: 203 + } + cell { + x: 10 + y: 28 + tile: 203 + } + cell { + x: 11 + y: 28 + tile: 203 + } + cell { + x: 12 + y: 28 + tile: 203 + } + cell { + x: 13 + y: 28 + tile: 203 + } + cell { + x: 14 + y: 28 + tile: 203 + } + cell { + x: 15 + y: 28 + tile: 203 + } + cell { + x: 16 + y: 28 + tile: 203 + } + cell { + x: 17 + y: 28 + tile: 203 + } + cell { + x: 18 + y: 28 + tile: 203 + } + cell { + x: 19 + y: 28 + tile: 203 + } + cell { + x: 20 + y: 28 + tile: 203 + } + cell { + x: 21 + y: 28 + tile: 203 + } + cell { + x: 22 + y: 28 + tile: 203 + } + cell { + x: 23 + y: 28 + tile: 203 + } + cell { + x: 24 + y: 28 + tile: 203 + } + cell { + x: 25 + y: 28 + tile: 203 + } + cell { + x: 26 + y: 28 + tile: 203 + } + cell { + x: 27 + y: 28 + tile: 203 + } + cell { + x: 28 + y: 28 + tile: 203 + } + cell { + x: 29 + y: 28 + tile: 203 + } + cell { + x: 30 + y: 28 + tile: 203 + } + cell { + x: 31 + y: 28 + tile: 203 + } + cell { + x: 32 + y: 28 + tile: 203 + } + cell { + x: 33 + y: 28 + tile: 203 + } + cell { + x: 34 + y: 28 + tile: 203 + } + cell { + x: 35 + y: 28 + tile: 186 + } + cell { + x: 36 + y: 28 + tile: 186 + } + cell { + x: 37 + y: 28 + tile: 186 + } + cell { + x: 38 + y: 28 + tile: 186 + } + cell { + x: 39 + y: 28 + tile: 186 + } + cell { + x: 40 + y: 28 + tile: 186 + } + cell { + x: 41 + y: 28 + tile: 186 + } + cell { + x: 42 + y: 28 + tile: 186 + } + cell { + x: 43 + y: 28 + tile: 186 + } + cell { + x: 44 + y: 28 + tile: 186 + } + cell { + x: 45 + y: 28 + tile: 186 + } + cell { + x: 46 + y: 28 + tile: 186 + } + cell { + x: 47 + y: 28 + tile: 186 + } + cell { + x: 48 + y: 28 + tile: 186 + } + cell { + x: 49 + y: 28 + tile: 186 + } + cell { + x: 50 + y: 28 + tile: 186 + } + cell { + x: 51 + y: 28 + tile: 186 + } + cell { + x: -3 + y: 28 + tile: 186 + } + cell { + x: -2 + y: 28 + tile: 203 + } + cell { + x: -1 + y: 28 + tile: 203 + } + cell { + x: 0 + y: 29 + tile: 186 + } + cell { + x: 1 + y: 29 + tile: 186 + } + cell { + x: 2 + y: 29 + tile: 203 + } + cell { + x: 3 + y: 29 + tile: 203 + } + cell { + x: 4 + y: 29 + tile: 203 + } + cell { + x: 5 + y: 29 + tile: 203 + } + cell { + x: 6 + y: 29 + tile: 203 + } + cell { + x: 7 + y: 29 + tile: 203 + } + cell { + x: 8 + y: 29 + tile: 203 + } + cell { + x: 9 + y: 29 + tile: 203 + } + cell { + x: 10 + y: 29 + tile: 203 + } + cell { + x: 11 + y: 29 + tile: 203 + } + cell { + x: 12 + y: 29 + tile: 203 + } + cell { + x: 13 + y: 29 + tile: 186 + } + cell { + x: 14 + y: 29 + tile: 203 + } + cell { + x: 15 + y: 29 + tile: 203 + } + cell { + x: 16 + y: 29 + tile: 203 + } + cell { + x: 17 + y: 29 + tile: 203 + } + cell { + x: 18 + y: 29 + tile: 203 + } + cell { + x: 19 + y: 29 + tile: 203 + } + cell { + x: 20 + y: 29 + tile: 203 + } + cell { + x: 21 + y: 29 + tile: 203 + } + cell { + x: 22 + y: 29 + tile: 203 + } + cell { + x: 23 + y: 29 + tile: 203 + } + cell { + x: 24 + y: 29 + tile: 203 + } + cell { + x: 25 + y: 29 + tile: 203 + } + cell { + x: 26 + y: 29 + tile: 203 + } + cell { + x: 27 + y: 29 + tile: 203 + } + cell { + x: 28 + y: 29 + tile: 203 + } + cell { + x: 29 + y: 29 + tile: 203 + } + cell { + x: 30 + y: 29 + tile: 203 + } + cell { + x: 31 + y: 29 + tile: 186 + } + cell { + x: 32 + y: 29 + tile: 186 + } + cell { + x: 33 + y: 29 + tile: 203 + } + cell { + x: 34 + y: 29 + tile: 203 + } + cell { + x: 35 + y: 29 + tile: 186 + } + cell { + x: 36 + y: 29 + tile: 186 + } + cell { + x: 37 + y: 29 + tile: 186 + } + cell { + x: 38 + y: 29 + tile: 186 + } + cell { + x: 39 + y: 29 + tile: 186 + } + cell { + x: 40 + y: 29 + tile: 186 + } + cell { + x: 41 + y: 29 + tile: 186 + } + cell { + x: 42 + y: 29 + tile: 186 + } + cell { + x: 43 + y: 29 + tile: 186 + } + cell { + x: 44 + y: 29 + tile: 186 + } + cell { + x: 45 + y: 29 + tile: 186 + } + cell { + x: 46 + y: 29 + tile: 186 + } + cell { + x: 47 + y: 29 + tile: 186 + } + cell { + x: 48 + y: 29 + tile: 186 + } + cell { + x: 49 + y: 29 + tile: 186 + } + cell { + x: 50 + y: 29 + tile: 186 + } + cell { + x: 51 + y: 29 + tile: 186 + } + cell { + x: -2 + y: 29 + tile: 186 + } + cell { + x: -1 + y: 29 + tile: 186 + } + cell { + x: 0 + y: 30 + tile: 186 + } + cell { + x: 1 + y: 30 + tile: 186 + } + cell { + x: 2 + y: 30 + tile: 186 + } + cell { + x: 3 + y: 30 + tile: 186 + } + cell { + x: 4 + y: 30 + tile: 186 + } + cell { + x: 5 + y: 30 + tile: 186 + } + cell { + x: 6 + y: 30 + tile: 186 + } + cell { + x: 7 + y: 30 + tile: 186 + } + cell { + x: 8 + y: 30 + tile: 186 + } + cell { + x: 9 + y: 30 + tile: 186 + } + cell { + x: 10 + y: 30 + tile: 203 + } + cell { + x: 11 + y: 30 + tile: 203 + } + cell { + x: 12 + y: 30 + tile: 203 + } + cell { + x: 13 + y: 30 + tile: 203 + } + cell { + x: 14 + y: 30 + tile: 203 + } + cell { + x: 15 + y: 30 + tile: 203 + } + cell { + x: 16 + y: 30 + tile: 203 + } + cell { + x: 17 + y: 30 + tile: 203 + } + cell { + x: 18 + y: 30 + tile: 203 + } + cell { + x: 19 + y: 30 + tile: 203 + } + cell { + x: 20 + y: 30 + tile: 203 + } + cell { + x: 21 + y: 30 + tile: 203 + } + cell { + x: 22 + y: 30 + tile: 203 + } + cell { + x: 23 + y: 30 + tile: 203 + } + cell { + x: 24 + y: 30 + tile: 203 + } + cell { + x: 25 + y: 30 + tile: 203 + } + cell { + x: 26 + y: 30 + tile: 186 + } + cell { + x: 27 + y: 30 + tile: 186 + } + cell { + x: 28 + y: 30 + tile: 186 + } + cell { + x: 29 + y: 30 + tile: 186 + } + cell { + x: 30 + y: 30 + tile: 186 + } + cell { + x: 31 + y: 30 + tile: 186 + } + cell { + x: 32 + y: 30 + tile: 186 + } + cell { + x: 33 + y: 30 + tile: 186 + } + cell { + x: 34 + y: 30 + tile: 186 + } + cell { + x: 35 + y: 30 + tile: 186 + } + cell { + x: 36 + y: 30 + tile: 186 + } + cell { + x: 37 + y: 30 + tile: 186 + } + cell { + x: 38 + y: 30 + tile: 186 + } + cell { + x: 39 + y: 30 + tile: 186 + } + cell { + x: 40 + y: 30 + tile: 186 + } + cell { + x: 41 + y: 30 + tile: 186 + } + cell { + x: 42 + y: 30 + tile: 186 + } + cell { + x: 43 + y: 30 + tile: 186 + } + cell { + x: 44 + y: 30 + tile: 186 + } + cell { + x: 45 + y: 30 + tile: 186 + } + cell { + x: 46 + y: 30 + tile: 186 + } + cell { + x: 47 + y: 30 + tile: 186 + } + cell { + x: 48 + y: 30 + tile: 186 + } + cell { + x: 49 + y: 30 + tile: 186 + } + cell { + x: 50 + y: 30 + tile: 186 + } + cell { + x: 1 + y: 31 + tile: 186 + } + cell { + x: 2 + y: 31 + tile: 186 + } + cell { + x: 3 + y: 31 + tile: 186 + } + cell { + x: 4 + y: 31 + tile: 186 + } + cell { + x: 5 + y: 31 + tile: 186 + } + cell { + x: 6 + y: 31 + tile: 186 + } + cell { + x: 7 + y: 31 + tile: 186 + } + cell { + x: 8 + y: 31 + tile: 186 + } + cell { + x: 9 + y: 31 + tile: 186 + } + cell { + x: 10 + y: 31 + tile: 203 + } + cell { + x: 11 + y: 31 + tile: 203 + } + cell { + x: 12 + y: 31 + tile: 203 + } + cell { + x: 13 + y: 31 + tile: 203 + } + cell { + x: 14 + y: 31 + tile: 186 + } + cell { + x: 15 + y: 31 + tile: 186 + } + cell { + x: 16 + y: 31 + tile: 186 + } + cell { + x: 17 + y: 31 + tile: 186 + } + cell { + x: 18 + y: 31 + tile: 186 + } + cell { + x: 19 + y: 31 + tile: 186 + } + cell { + x: 20 + y: 31 + tile: 186 + } + cell { + x: 21 + y: 31 + tile: 186 + } + cell { + x: 22 + y: 31 + tile: 186 + } + cell { + x: 23 + y: 31 + tile: 186 + } + cell { + x: 24 + y: 31 + tile: 186 + } + cell { + x: 25 + y: 31 + tile: 186 + } + cell { + x: 26 + y: 31 + tile: 186 + } + cell { + x: 27 + y: 31 + tile: 186 + } + cell { + x: 28 + y: 31 + tile: 186 + } + cell { + x: 29 + y: 31 + tile: 186 + } + cell { + x: 30 + y: 31 + tile: 186 + } + cell { + x: 31 + y: 31 + tile: 186 + } + cell { + x: 32 + y: 31 + tile: 186 + } + cell { + x: 33 + y: 31 + tile: 186 + } + cell { + x: 34 + y: 31 + tile: 186 + } + cell { + x: 4 + y: 32 + tile: 186 + } + cell { + x: 7 + y: 32 + tile: 186 + } + cell { + x: 8 + y: 32 + tile: 186 + } + cell { + x: 9 + y: 32 + tile: 186 + } + cell { + x: 10 + y: 32 + tile: 186 + } + cell { + x: 11 + y: 32 + tile: 186 + } + cell { + x: 12 + y: 32 + tile: 186 + } + cell { + x: 13 + y: 32 + tile: 186 + } + cell { + x: 14 + y: 32 + tile: 186 + } + cell { + x: 16 + y: 32 + tile: 186 + } + cell { + x: 17 + y: 32 + tile: 186 + } + cell { + x: 18 + y: 32 + tile: 186 + } + cell { + x: 19 + y: 32 + tile: 186 + } + cell { + x: 24 + y: 32 + tile: 186 + } +} +material: "/builtins/materials/tile_map.material" diff --git a/game/surface/surface_tiles.tilesource b/game/surface/surface_tiles.tilesource new file mode 100644 index 0000000..98bb645 --- /dev/null +++ b/game/surface/surface_tiles.tilesource @@ -0,0 +1,4 @@ +image: "/assets/tilemap/surface_tilesheet.png" +tile_width: 64 +tile_height: 64 +extrude_borders: 2 diff --git a/game/world.collection b/game/world.collection new file mode 100644 index 0000000..4967040 --- /dev/null +++ b/game/world.collection @@ -0,0 +1,1502 @@ +name: "game" +instances { + id: "tree_1" + prototype: "/assets/models/forest/gameobjects/tree.go" + position { + x: 541.0 + z: -1401.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "tree_4" + prototype: "/assets/models/forest/gameobjects/tree.go" + position { + x: -290.0 + z: 978.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "tree_7" + prototype: "/assets/models/forest/gameobjects/tree.go" + position { + x: 878.0 + z: -1350.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "tree_9" + prototype: "/assets/models/forest/gameobjects/tree.go" + position { + x: 1023.0 + z: -573.0 + } + rotation { + y: -0.33751836 + w: 0.9413189 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "tree_2" + prototype: "/assets/models/forest/gameobjects/tree.go" + position { + x: 541.0 + z: -1401.0 + } + rotation { + y: 0.49242356 + w: 0.8703557 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "tree_3" + prototype: "/assets/models/forest/gameobjects/tree.go" + position { + x: -522.0 + z: -516.0 + } + rotation { + y: 0.8838327 + w: 0.46780318 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "tree_8" + prototype: "/assets/models/forest/gameobjects/tree.go" + position { + x: 1308.0 + z: 941.0 + } + rotation { + y: -0.29777622 + w: 0.9546357 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "tree_10" + prototype: "/assets/models/forest/gameobjects/tree.go" + position { + x: -290.0 + z: -1036.0 + } + scale3 { + x: 150.0 + y: 150.0 + z: 150.0 + } +} +instances { + id: "tree_5" + prototype: "/assets/models/forest/gameobjects/tree.go" + position { + x: 77.0 + z: -917.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "tree_6" + prototype: "/assets/models/forest/gameobjects/tree.go" + position { + x: 51.0 + z: -1304.0 + } + rotation { + y: 0.3007058 + w: 0.95371693 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "rock_1" + prototype: "/assets/models/forest/gameobjects/rock.go" + position { + x: 295.0 + y: 24.0 + z: -1407.0 + } + scale3 { + x: 50.0 + y: 50.0 + z: 50.0 + } +} +instances { + id: "rock_2" + prototype: "/assets/models/forest/gameobjects/rock.go" + position { + x: 739.0 + y: 24.0 + z: -1407.0 + } + rotation { + y: -0.6141761 + w: 0.789169 + } + scale3 { + x: 60.0 + y: 60.0 + z: 60.0 + } +} +instances { + id: "rock_3" + prototype: "/assets/models/forest/gameobjects/rock.go" + position { + x: 1553.0 + y: 32.0 + z: -206.0 + } + rotation { + y: -0.3289684 + w: 0.94434094 + } + scale3 { + x: 35.0 + y: 35.0 + z: 35.0 + } +} +instances { + id: "rock_4" + prototype: "/assets/models/forest/gameobjects/rock.go" + position { + x: 1452.0 + y: 43.0 + z: -259.0 + } + rotation { + y: -0.79620945 + w: 0.6050211 + } + scale3 { + x: 40.0 + y: 40.0 + z: 40.0 + } +} +instances { + id: "rock_5" + prototype: "/assets/models/forest/gameobjects/rock.go" + position { + x: -678.0 + y: 52.0 + z: 839.0 + } + rotation { + y: -0.3289684 + w: 0.94434094 + } + scale3 { + x: 75.0 + y: 75.0 + z: 75.0 + } +} +instances { + id: "grass_1" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 462.0 + y: 10.0 + z: -939.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_2" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 293.0 + z: -995.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_3" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 547.0 + z: -993.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_4" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 418.0 + z: -982.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_5" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 348.0 + z: -961.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_6" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 492.0 + z: -1022.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_7" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 414.0 + z: -1041.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_8" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 348.0 + z: -1022.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_12" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 391.0 + y: 10.0 + z: -905.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_9" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 524.0 + y: 10.0 + z: -925.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_10" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 450.0 + y: 10.0 + z: -865.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "grass_11" + prototype: "/assets/models/forest/gameobjects/grass.go" + position { + x: 309.0 + y: 10.0 + z: -892.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "ball1" + prototype: "/assets/models/platformer/gameobjects/ball.go" + position { + y: 190.0 + z: 342.0 + } + scale3 { + x: 50.0 + y: 50.0 + z: 50.0 + } +} +instances { + id: "ball2" + prototype: "/assets/models/platformer/gameobjects/ball.go" + position { + x: 183.0 + y: 224.0 + z: 342.0 + } + scale3 { + x: 50.0 + y: 50.0 + z: 50.0 + } +} +instances { + id: "ball3" + prototype: "/assets/models/platformer/gameobjects/ball.go" + position { + y: 111.0 + z: 236.0 + } + scale3 { + x: 50.0 + y: 50.0 + z: 50.0 + } +} +instances { + id: "wood2" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: -513.0 + y: 32.0 + z: -964.0 + } + rotation { + y: 0.03389595 + w: 0.99942535 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood26" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: 1506.0 + y: 32.0 + z: 1240.0 + } + rotation { + x: 1.1805682E-15 + y: 0.7804033 + z: -2.0898566E-16 + w: 0.62527645 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood10" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: -8.0 + y: 32.0 + z: -1585.0 + } + rotation { + y: -0.6489133 + w: 0.76086235 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood23" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: 880.0 + y: 32.0 + z: 1141.0 + } + rotation { + y: 0.582396 + w: 0.81290525 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood9" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: -285.0 + y: 32.0 + z: -1473.0 + } + rotation { + y: -0.40211812 + w: 0.9155878 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood11" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: 292.0 + y: 32.0 + z: -1698.0 + } + rotation { + y: -0.60686386 + w: 0.79480577 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood6" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: -708.0 + y: 32.0 + z: -238.0 + } + rotation { + y: -0.022698449 + w: 0.9997423 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood24" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: 1194.0 + y: 32.0 + z: 1246.0 + } + rotation { + y: 0.70710677 + w: 0.70710677 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood18" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: 1516.0 + y: 32.0 + z: -412.0 + } + rotation { + y: -0.7250102 + w: 0.6887381 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood12" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: 889.0 + y: 32.0 + z: -1658.0 + } + rotation { + x: -1.1012651E-15 + y: 0.5661378 + z: 4.9152644E-16 + w: 0.8243106 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood19" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: 1847.0 + y: 32.0 + z: -443.0 + } + rotation { + y: -0.788601 + w: 0.6149053 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood3" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: -788.0 + y: 32.0 + z: 575.0 + } + rotation { + y: 0.049771246 + w: 0.99876064 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood14" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: 1079.0 + y: 32.0 + z: -1420.0 + } + rotation { + y: -0.99757504 + w: 0.06959881 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood25" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: 2011.0 + y: 32.0 + z: 733.0 + } + rotation { + x: 1.0112643E-15 + y: 0.9977702 + z: 6.4401916E-16 + w: -0.06674298 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood8" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: -446.0 + y: 32.0 + z: -1244.0 + } + rotation { + y: -0.19639404 + w: 0.9805251 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood22" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: 568.0 + y: 32.0 + z: 1114.0 + } + rotation { + y: 0.70710677 + w: 0.70710677 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood29" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: -681.0 + y: 32.0 + z: -511.0 + } + rotation { + x: 0.005613188 + y: 0.059122648 + z: 0.094349556 + w: 0.9937662 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood17" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: 1242.0 + y: 32.0 + z: -535.0 + } + rotation { + x: 2.349075E-16 + y: -0.9170317 + z: -2.7739778E-15 + w: 0.39881438 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood7" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: -551.0 + y: 32.0 + z: -712.0 + } + rotation { + y: -0.40211812 + w: 0.9155878 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood16" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: 1087.0 + y: 32.0 + z: -805.0 + } + rotation { + x: 1.0859346E-15 + y: -0.9818578 + z: -4.152397E-16 + w: 0.18961892 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood21" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: 254.0 + y: 32.0 + z: 1098.0 + } + rotation { + y: 0.60807544 + w: 0.7938792 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood13" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: 596.0 + y: 32.0 + z: -1712.0 + } + rotation { + y: -0.788601 + w: 0.6149053 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood4" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: -732.0 + y: 32.0 + z: 306.0 + } + rotation { + z: 0.12257906 + w: 0.99245876 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood20" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: 2023.0 + y: 32.0 + z: -218.0 + } + rotation { + y: -0.9990273 + w: 0.04409602 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood27" + prototype: "/assets/models/forest/gameobjects/wood_2.go" + position { + x: 1810.0 + y: 32.0 + z: 1226.0 + } + rotation { + x: 1.1321089E-15 + y: 0.6706577 + z: -3.9464634E-16 + w: 0.7417669 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood15" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: 1077.0 + y: 32.0 + z: -1119.0 + } + rotation { + y: -0.99559325 + w: -0.09377703 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood1" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: -53.0 + y: 32.0 + z: 1065.0 + } + rotation { + y: 0.70710677 + w: 0.70710677 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood28" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: 1990.0 + y: 32.0 + z: 1034.0 + } + rotation { + x: 7.2729033E-16 + y: 0.9998578 + z: -4.474243E-16 + w: 0.01686402 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood5" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: -709.0 + y: 32.0 + z: 33.0 + } + rotation { + y: 0.053050198 + w: 0.99859184 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "wood30" + prototype: "/assets/models/forest/gameobjects/wood_1.go" + position { + x: -439.0 + y: 32.0 + z: 1065.0 + } + rotation { + y: 0.63848513 + w: 0.7696341 + } + scale3 { + x: 200.0 + y: 200.0 + z: 200.0 + } +} +instances { + id: "fuel_barell2" + prototype: "/assets/models/forest/gameobjects/fuel_barell.go" + position { + x: 561.0 + y: 75.0 + z: 954.0 + } + scale3 { + x: 150.0 + y: 150.0 + z: 150.0 + } +} +instances { + id: "fuel_barell1" + prototype: "/assets/models/forest/gameobjects/fuel_barell.go" + position { + x: -167.0 + y: 75.0 + z: -849.0 + } + scale3 { + x: 150.0 + y: 150.0 + z: 150.0 + } +} +instances { + id: "pallet_covered" + prototype: "/assets/models/forest/gameobjects/pallet_covered.go" + position { + x: -402.0 + z: 398.0 + } + scale3 { + x: 150.0 + y: 150.0 + z: 150.0 + } +} +instances { + id: "gold_bar8" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 1354.0 + y: 106.0 + z: 775.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 1106.0 + y: 106.0 + z: 826.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar11" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 1491.0 + y: 106.0 + z: -2.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar3" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 140.0 + z: 717.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar5" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 199.0 + y: 176.0 + z: 717.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar12" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 799.0 + y: 106.0 + z: -845.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar2" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 199.0 + y: 91.0 + z: 717.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar4" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 141.0 + y: 54.0 + z: 717.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar13" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 762.0 + y: 106.0 + z: -866.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar7" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 1209.0 + y: 106.0 + z: 794.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar9" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 1624.0 + y: 106.0 + z: 86.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar1" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 199.0 + y: 41.0 + z: 717.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar6" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 114.0 + y: 142.0 + z: 717.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar10" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 1564.0 + y: 106.0 + z: 37.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +instances { + id: "gold_bar14" + prototype: "/assets/models/forest/gameobjects/gold_bar.go" + position { + x: 778.0 + y: 106.0 + z: -919.0 + } + scale3 { + x: 100.0 + y: 100.0 + z: 100.0 + } +} +collection_instances { + id: "pier" + collection: "/assets/models/forest/collections/pier.collection" + position { + x: 2280.0 + y: -1.0 + z: 246.0 + } +} +collection_instances { + id: "rise" + collection: "/assets/models/forest/collections/rise.collection" +} +scale_along_z: 0 +embedded_instances { + id: "surface" + children: "surface_shadow" + data: "components {\n" + " id: \"surface\"\n" + " component: \"/game/surface/surface.tilemap\"\n" + " position {\n" + " x: -500.0\n" + " z: -500.0\n" + " }\n" + " rotation {\n" + " x: 0.70710677\n" + " w: 0.70710677\n" + " }\n" + "}\n" + "embedded_components {\n" + " id: \"collisionobject\"\n" + " type: \"collisionobject\"\n" + " data: \"type: COLLISION_OBJECT_TYPE_STATIC\\n" + "mass: 0.0\\n" + "friction: 0.9\\n" + "restitution: 0.5\\n" + "group: \\\"ground\\\"\\n" + "mask: \\\"ball\\\"\\n" + "mask: \\\"player\\\"\\n" + "mask: \\\"gold\\\"\\n" + "embedded_collision_shape {\\n" + " shapes {\\n" + " shape_type: TYPE_BOX\\n" + " position {\\n" + " }\\n" + " rotation {\\n" + " }\\n" + " index: 0\\n" + " count: 3\\n" + " }\\n" + " data: 5000.0\\n" + " data: 10.0\\n" + " data: 5000.0\\n" + "}\\n" + "\"\n" + "}\n" + "" +} +embedded_instances { + id: "trees" + children: "tree_1" + children: "tree_10" + children: "tree_2" + children: "tree_3" + children: "tree_4" + children: "tree_5" + children: "tree_6" + children: "tree_7" + children: "tree_8" + children: "tree_9" + data: "" +} +embedded_instances { + id: "rocks" + children: "rock_1" + children: "rock_2" + children: "rock_3" + children: "rock_4" + children: "rock_5" + data: "" +} +embedded_instances { + id: "grass" + children: "grass_1" + children: "grass_10" + children: "grass_11" + children: "grass_12" + children: "grass_2" + children: "grass_3" + children: "grass_4" + children: "grass_5" + children: "grass_6" + children: "grass_7" + children: "grass_8" + children: "grass_9" + data: "" +} +embedded_instances { + id: "balls" + children: "ball1" + children: "ball2" + children: "ball3" + data: "" +} +embedded_instances { + id: "woods" + children: "wood1" + children: "wood10" + children: "wood11" + children: "wood12" + children: "wood13" + children: "wood14" + children: "wood15" + children: "wood16" + children: "wood17" + children: "wood18" + children: "wood19" + children: "wood2" + children: "wood20" + children: "wood21" + children: "wood22" + children: "wood23" + children: "wood24" + children: "wood25" + children: "wood26" + children: "wood27" + children: "wood28" + children: "wood29" + children: "wood3" + children: "wood30" + children: "wood4" + children: "wood5" + children: "wood6" + children: "wood7" + children: "wood8" + children: "wood9" + data: "" +} +embedded_instances { + id: "other" + children: "fuel_barell1" + children: "fuel_barell2" + data: "" +} +embedded_instances { + id: "surface_shadow" + data: "components {\n" + " id: \"model_tiers\"\n" + " component: \"/shadow_mapping/model_tiers.script\"\n" + " properties {\n" + " id: \"low_material\"\n" + " value: \"/shadow_mapping/materials/low/diffuse_transparent.material\"\n" + " type: PROPERTY_TYPE_HASH\n" + " }\n" + " properties {\n" + " id: \"mid_material\"\n" + " value: \"/shadow_mapping/materials/mid/diffuse_transparent.material\"\n" + " type: PROPERTY_TYPE_HASH\n" + " }\n" + " properties {\n" + " id: \"high_material\"\n" + " value: \"/shadow_mapping/materials/high/diffuse_transparent.material\"\n" + " type: PROPERTY_TYPE_HASH\n" + " }\n" + "}\n" + "embedded_components {\n" + " id: \"model\"\n" + " type: \"model\"\n" + " data: \"mesh: \\\"/builtins/assets/meshes/quad.dae\\\"\\n" + "name: \\\"{{NAME}}\\\"\\n" + "materials {\\n" + " name: \\\"default\\\"\\n" + " material: \\\"/shadow_mapping/materials/high/diffuse_transparent.material\\\"\\n" + " textures {\\n" + " sampler: \\\"tex0\\\"\\n" + " texture: \\\"/assets/images/alpha.png\\\"\\n" + " }\\n" + "}\\n" + "create_go_bones: false\\n" + "\"\n" + "}\n" + "" + position { + y: 0.01 + } + rotation { + x: 0.70710677 + w: 0.70710677 + } + scale3 { + x: 10000.0 + y: 10000.0 + } +} +embedded_instances { + id: "gold_target" + data: "embedded_components {\n" + " id: \"collisionobject\"\n" + " type: \"collisionobject\"\n" + " data: \"type: COLLISION_OBJECT_TYPE_TRIGGER\\n" + "mass: 0.0\\n" + "friction: 0.1\\n" + "restitution: 0.5\\n" + "group: \\\"gold_target\\\"\\n" + "mask: \\\"player\\\"\\n" + "embedded_collision_shape {\\n" + " shapes {\\n" + " shape_type: TYPE_BOX\\n" + " position {\\n" + " x: -9.0\\n" + " y: 68.0\\n" + " z: 11.0\\n" + " }\\n" + " rotation {\\n" + " }\\n" + " index: 0\\n" + " count: 3\\n" + " }\\n" + " data: 100.0\\n" + " data: 75.0\\n" + " data: 100.0\\n" + "}\\n" + "\"\n" + "}\n" + "" + position { + x: -394.0 + z: 161.0 + } +} +embedded_instances { + id: "gold_release_position" + data: "" + position { + x: -399.0 + y: 360.0 + z: 383.0 + } +} +embedded_instances { + id: "gold_bars" + children: "gold_bar" + children: "gold_bar1" + children: "gold_bar10" + children: "gold_bar11" + children: "gold_bar12" + children: "gold_bar13" + children: "gold_bar14" + children: "gold_bar2" + children: "gold_bar3" + children: "gold_bar4" + children: "gold_bar5" + children: "gold_bar6" + children: "gold_bar7" + children: "gold_bar8" + children: "gold_bar9" + data: "" +} diff --git a/input/game.input_binding b/input/game.input_binding new file mode 100644 index 0000000..dfe7d38 --- /dev/null +++ b/input/game.input_binding @@ -0,0 +1,36 @@ +key_trigger { + input: KEY_LEFT + action: "left" +} +key_trigger { + input: KEY_RIGHT + action: "right" +} +key_trigger { + input: KEY_UP + action: "forward" +} +key_trigger { + input: KEY_DOWN + action: "back" +} +key_trigger { + input: KEY_A + action: "left" +} +key_trigger { + input: KEY_D + action: "right" +} +key_trigger { + input: KEY_W + action: "forward" +} +key_trigger { + input: KEY_S + action: "back" +} +mouse_trigger { + input: MOUSE_BUTTON_1 + action: "touch" +} diff --git a/render/custom.display_profiles b/render/custom.display_profiles new file mode 100644 index 0000000..ae77b03 --- /dev/null +++ b/render/custom.display_profiles @@ -0,0 +1,21 @@ +profiles { + name: "Default" + qualifiers { + width: 1080 + height: 1920 + } +} +profiles { + name: "Landscape" + qualifiers { + width: 1920 + height: 1080 + } +} +profiles { + name: "Portrait" + qualifiers { + width: 1080 + height: 1920 + } +} diff --git a/render/custom.render b/render/custom.render new file mode 100644 index 0000000..94c12ab --- /dev/null +++ b/render/custom.render @@ -0,0 +1,13 @@ +script: "/render/custom.render_script" +render_resources { + name: "shadow_low_material" + path: "/shadow_mapping/materials/low/shadow.material" +} +render_resources { + name: "shadow_mid_material" + path: "/shadow_mapping/materials/mid/shadow.material" +} +render_resources { + name: "shadow_high_material" + path: "/shadow_mapping/materials/high/shadow.material" +} diff --git a/render/custom.render_script b/render/custom.render_script new file mode 100644 index 0000000..229ed3f --- /dev/null +++ b/render/custom.render_script @@ -0,0 +1,294 @@ +local shadow_mapping = require "shadow_mapping.shadow_mapping" +-- Copyright 2020-2025 The Defold Foundation +-- Copyright 2014-2020 King +-- Copyright 2009-2014 Ragnar Svensson, Christian Murray +-- Licensed under the Defold License version 1.0 (the "License"); you may not use +-- this file except in compliance with the License. +-- +-- You may obtain a copy of the License, together with FAQs at +-- https://www.defold.com/license +-- +-- Unless required by applicable law or agreed to in writing, software distributed +-- under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +-- CONDITIONS OF ANY KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations under the License. + +-- +-- message constants +-- +local MSG_CLEAR_COLOR = hash("clear_color") +local MSG_WINDOW_RESIZED = hash("window_resized") +local MSG_SET_VIEW_PROJ = hash("set_view_projection") +local MSG_SET_CAMERA_PROJ = hash("use_camera_projection") +local MSG_USE_STRETCH_PROJ = hash("use_stretch_projection") +local MSG_USE_FIXED_PROJ = hash("use_fixed_projection") +local MSG_USE_FIXED_FIT_PROJ = hash("use_fixed_fit_projection") + +local DEFAULT_NEAR = -1 +local DEFAULT_FAR = 1 +local DEFAULT_ZOOM = 1 + +-- +-- projection that centers content with maintained aspect ratio and optional zoom +-- +local function get_fixed_projection(camera, state) + camera.zoom = camera.zoom or DEFAULT_ZOOM + local projected_width = state.window_width / camera.zoom + local projected_height = state.window_height / camera.zoom + local left = -(projected_width - state.width) / 2 + local bottom = -(projected_height - state.height) / 2 + local right = left + projected_width + local top = bottom + projected_height + return vmath.matrix4_orthographic(left, right, bottom, top, camera.near, camera.far) +end +-- +-- projection that centers and fits content with maintained aspect ratio +-- +local function get_fixed_fit_projection(camera, state) + camera.zoom = math.min(state.window_width / state.width, state.window_height / state.height) + return get_fixed_projection(camera, state) +end +-- +-- projection that stretches content +-- +local function get_stretch_projection(camera, state) + return vmath.matrix4_orthographic(0, state.width, 0, state.height, camera.near, camera.far) +end +-- +-- projection for gui +-- +local function get_gui_projection(camera, state) + return vmath.matrix4_orthographic(0, state.window_width, 0, state.window_height, camera.near, camera.far) +end + +local function update_clear_color(state, color) + if color then + state.clear_buffers[graphics.BUFFER_TYPE_COLOR0_BIT] = color + end +end + +local function update_camera(camera, state) + if camera.projection_fn then + camera.proj = camera.projection_fn(camera, state) + camera.options.frustum = camera.proj * camera.view + end +end + +local function update_state(state) + state.window_width = render.get_window_width() + state.window_height = render.get_window_height() + state.valid = state.window_width > 0 and state.window_height > 0 + if not state.valid then + return false + end + -- Make sure state updated only once when resize window + if state.window_width == state.prev_window_width and state.window_height == state.prev_window_height then + return true + end + state.prev_window_width = state.window_width + state.prev_window_height = state.window_height + state.width = render.get_width() + state.height = render.get_height() + for _, camera in pairs(state.cameras) do + update_camera(camera, state) + end + return true +end + +local function init_camera(camera, projection_fn, near, far, zoom) + camera.view = vmath.matrix4() + camera.near = near == nil and DEFAULT_NEAR or near + camera.far = far == nil and DEFAULT_FAR or far + camera.zoom = zoom == nil and DEFAULT_ZOOM or zoom + camera.projection_fn = projection_fn +end + +local function create_predicates(...) + local arg = { ... } + local predicates = {} + for _, predicate_name in pairs(arg) do + predicates[predicate_name] = render.predicate({ predicate_name }) + end + return predicates +end + +local function create_camera(state, name, is_main_camera) + local camera = {} + camera.options = {} + state.cameras[name] = camera + if is_main_camera then + state.main_camera = camera + end + return camera +end + +local function create_state() + local state = {} + local color = vmath.vector4(0, 0, 0, 0) + color.x = sys.get_config_number("render.clear_color_red", 0) + color.y = sys.get_config_number("render.clear_color_green", 0) + color.z = sys.get_config_number("render.clear_color_blue", 0) + color.w = sys.get_config_number("render.clear_color_alpha", 0) + state.clear_buffers = { + [graphics.BUFFER_TYPE_COLOR0_BIT] = color, + [graphics.BUFFER_TYPE_DEPTH_BIT] = 1, + [graphics.BUFFER_TYPE_STENCIL_BIT] = 0 + } + state.cameras = {} + return state +end + + +local function set_camera_world(state) + local camera_components = camera.get_cameras() + + -- This will set the last enabled camera from the stack of camera components + if #camera_components > 0 then + for i = #camera_components, 1, -1 do + if camera.get_enabled(camera_components[i]) then + local camera_component = state.cameras.camera_component + camera_component.camera = camera_components[i] + camera_component.proj = camera.get_projection(camera_component.camera) + camera_component.view = camera.get_view(camera_component.camera) + render.set_projection(camera_component.proj) + render.set_view(camera_component.view) + camera_component.options.frustum = camera_component.proj * camera_component.view + return camera_component.options + end + end + end + + -- If no active camera was found, we use the default main "camera world" camera + local camera_world = state.cameras.camera_world + render.set_view(camera_world.view) + render.set_projection(camera_world.proj) + return camera_world.options +end + +local function reset_camera_world(state) + -- unbind the camera if a camera component is used + if state.cameras.camera_component.camera then + state.cameras.camera_component.camera = nil + render.set_camera() + end +end + +function init(self) + self.predicates = create_predicates("tile", "gui", "particle", "model", "debug_text") + + -- default is stretch projection. copy from builtins and change for different projection + -- or send a message to the render script to change projection: + -- msg.post("@render:", "use_stretch_projection", { near = -1, far = 1 }) + -- msg.post("@render:", "use_fixed_projection", { near = -1, far = 1, zoom = 2 }) + -- msg.post("@render:", "use_fixed_fit_projection", { near = -1, far = 1 }) + + local state = create_state() + self.state = state + + local camera_world = create_camera(state, "camera_world", true) + init_camera(camera_world, get_stretch_projection) + local camera_gui = create_camera(state, "camera_gui") + init_camera(camera_gui, get_gui_projection) + -- Create a special camera that wraps camera components (if they exist) + -- It will take precedence over any other camera, and not change from messages + local camera_component = create_camera(state, "camera_component") + update_state(state) + shadow_mapping.init() +end + +function update(self) + local state = self.state + if not state.valid then + if not update_state(state) then + return + end + end + + local predicates = self.predicates + -- clear screen buffers + -- + -- turn on depth_mask before `render.clear()` to clear it as well + render.set_depth_mask(true) + render.set_stencil_mask(0xff) + shadow_mapping.prerender() + render.clear(state.clear_buffers) + + -- setup camera view and projection + -- + local draw_options_world = set_camera_world(state) + render.set_viewport(0, 0, state.window_width, state.window_height) + + -- set states used for all the world predicates + render.set_blend_func(graphics.BLEND_FACTOR_SRC_ALPHA, graphics.BLEND_FACTOR_ONE_MINUS_SRC_ALPHA) + render.enable_state(graphics.STATE_DEPTH_TEST) + + -- render models + -- + render.enable_state(graphics.STATE_CULL_FACE) + render.draw(predicates.model, draw_options_world) + render.set_depth_mask(false) + render.disable_state(graphics.STATE_CULL_FACE) + + -- render sprites, tilemaps, particles etc + -- + render.enable_state(graphics.STATE_BLEND) + render.draw(predicates.tile, draw_options_world) + render.draw(predicates.particle, draw_options_world) + render.disable_state(graphics.STATE_DEPTH_TEST) + + -- render shadows + -- + render.disable_state(render.STATE_STENCIL_TEST) + render.enable_state(render.STATE_BLEND) + render.set_blend_func(render.BLEND_SRC_ALPHA, render.BLEND_ONE_MINUS_SRC_ALPHA) + render.disable_state(render.STATE_CULL_FACE) + + shadow_mapping.render_shadow(self) + render.set_viewport(0, 0, state.window_width, state.window_height) + shadow_mapping.render_shadow_model(state.cameras.camera_component.view, state.cameras.camera_component.proj, + state.cameras.camera_component.options.frustrum) + + + + render.draw_debug3d() + + reset_camera_world(state) + + -- render GUI + -- + local camera_gui = state.cameras.camera_gui + render.set_view(camera_gui.view) + render.set_projection(camera_gui.proj) + + render.enable_state(graphics.STATE_STENCIL_TEST) + render.draw(predicates.gui, camera_gui.options) + render.draw(predicates.debug_text, camera_gui.options) + render.disable_state(graphics.STATE_STENCIL_TEST) + render.disable_state(graphics.STATE_BLEND) +end + +function on_message(self, message_id, message) + local state = self.state + local camera = state.main_camera + + if message_id == MSG_CLEAR_COLOR then + update_clear_color(state, message.color) + elseif message_id == MSG_WINDOW_RESIZED then + update_state(state) + elseif message_id == MSG_SET_VIEW_PROJ then + camera.view = message.view + self.camera_projection = message.projection or vmath.matrix4() + update_camera(camera, state) + elseif message_id == MSG_SET_CAMERA_PROJ then + camera.projection_fn = function() return self.camera_projection end + elseif message_id == MSG_USE_STRETCH_PROJ then + init_camera(camera, get_stretch_projection, message.near, message.far) + update_camera(camera, state) + elseif message_id == MSG_USE_FIXED_PROJ then + init_camera(camera, get_fixed_projection, message.near, message.far, message.zoom) + update_camera(camera, state) + elseif message_id == MSG_USE_FIXED_FIT_PROJ then + init_camera(camera, get_fixed_fit_projection, message.near, message.far) + update_camera(camera, state) + end +end diff --git a/render/custom.texture_profiles b/render/custom.texture_profiles new file mode 100644 index 0000000..c64ddea --- /dev/null +++ b/render/custom.texture_profiles @@ -0,0 +1,30 @@ +path_settings { + path: "**" + profile: "Default" +} +profiles { + name: "Default" + platforms { + os: OS_ID_GENERIC + formats { + format: TEXTURE_FORMAT_RGBA + compressor: "BasisU" + compressor_preset: "BASISU_MEDIUM" + } + mipmaps: false + max_texture_size: 2048 + } +} +profiles { + name: "No Prem. Alpha" + platforms { + os: OS_ID_GENERIC + formats { + format: TEXTURE_FORMAT_RGBA + compressor: "Uncompressed" + compressor_preset: "UNCOMPRESSED" + } + mipmaps: false + premultiply_alpha: false + } +} diff --git a/shadow_mapping/materials/high/diffuse.fp b/shadow_mapping/materials/high/diffuse.fp new file mode 100644 index 0000000..4390751 --- /dev/null +++ b/shadow_mapping/materials/high/diffuse.fp @@ -0,0 +1,40 @@ +#version 140 + +in highp vec4 var_position; +in highp vec3 var_normal; +in highp vec2 var_texcoord0; +in highp vec4 var_texcoord0_shadow; +in highp vec4 var_light; + +out vec4 out_fragColor; + +uniform highp sampler2D tex0; +uniform highp sampler2D tex_depth; + +uniform fs_uniforms +{ + uniform highp vec4 ambient_light; +}; + +#include "/shadow_mapping/materials/high/shadows_high.glsl" + +void main() +{ + vec4 color = texture(tex0, var_texcoord0.xy); + + // Diffuse light calculations. + vec3 diff_light = vec3(normalize(var_light.xyz - var_position.xyz)); + diff_light = max(dot(var_normal,diff_light), 0.0) + ambient_light.xyz; + diff_light = clamp(diff_light, 0.6, 1.0); + + // Influence the shadows based on the angle between the surface normal and the direction of the light + // The more orthogonal they are the more perspective artifacts we'll have. It's not exactly physically correct, + // but it's better than nothing! + // float n_to_l_angle = clamp(dot(var_normal, var_light.xyz), 0.0, 1.0); + vec4 depth_proj = var_texcoord0_shadow / var_texcoord0_shadow.w; + float shadow_value = shadow_calculation(depth_proj.xyz); + vec3 color_out = color.rgb * diff_light; + color_out = mix(color_out * 0.75, color_out, shadow_value); + out_fragColor = vec4(color_out,1.0) * color.w; +} + diff --git a/shadow_mapping/materials/high/diffuse.material b/shadow_mapping/materials/high/diffuse.material new file mode 100644 index 0000000..1d0dd84 --- /dev/null +++ b/shadow_mapping/materials/high/diffuse.material @@ -0,0 +1,55 @@ +name: "model" +tags: "shadow_model" +vertex_program: "/shadow_mapping/materials/standard_instanced.vp" +fragment_program: "/shadow_mapping/materials/high/diffuse.fp" +vertex_space: VERTEX_SPACE_LOCAL +vertex_constants { + name: "mtx_view" + type: CONSTANT_TYPE_VIEW +} +vertex_constants { + name: "mtx_proj" + type: CONSTANT_TYPE_PROJECTION +} +vertex_constants { + name: "mtx_light" + type: CONSTANT_TYPE_USER_MATRIX4 + value { + } +} +vertex_constants { + name: "light" + type: CONSTANT_TYPE_USER + value { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } +} +fragment_constants { + name: "ambient_light" + type: CONSTANT_TYPE_USER + value { + x: 0.3 + y: 0.3 + z: 0.3 + w: 0.3 + } +} +samplers { + name: "tex0" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} +samplers { + name: "tex_depth" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 0.0 +} diff --git a/shadow_mapping/materials/high/diffuse_skinning.material b/shadow_mapping/materials/high/diffuse_skinning.material new file mode 100644 index 0000000..af9dccf --- /dev/null +++ b/shadow_mapping/materials/high/diffuse_skinning.material @@ -0,0 +1,63 @@ +name: "model" +tags: "shadow_model_skinned" +vertex_program: "/shadow_mapping/materials/standard_skinning_instanced.vp" +fragment_program: "/shadow_mapping/materials/high/diffuse.fp" +vertex_space: VERTEX_SPACE_LOCAL +vertex_constants { + name: "mtx_view" + type: CONSTANT_TYPE_VIEW +} +vertex_constants { + name: "mtx_proj" + type: CONSTANT_TYPE_PROJECTION +} +vertex_constants { + name: "light" + type: CONSTANT_TYPE_USER + value { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } +} +vertex_constants { + name: "mtx_light" + type: CONSTANT_TYPE_USER_MATRIX4 + value { + } +} +fragment_constants { + name: "ambient_light" + type: CONSTANT_TYPE_USER + value { + x: 0.3 + y: 0.3 + z: 0.3 + w: 0.3 + } +} +samplers { + name: "tex0" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} +samplers { + name: "tex_depth" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 0.0 +} +samplers { + name: "pose_matrix_cache" + wrap_u: WRAP_MODE_REPEAT + wrap_v: WRAP_MODE_REPEAT + filter_min: FILTER_MODE_MIN_NEAREST + filter_mag: FILTER_MODE_MAG_NEAREST + max_anisotropy: 0.0 +} diff --git a/shadow_mapping/materials/high/diffuse_transparent.fp b/shadow_mapping/materials/high/diffuse_transparent.fp new file mode 100644 index 0000000..60a123f --- /dev/null +++ b/shadow_mapping/materials/high/diffuse_transparent.fp @@ -0,0 +1,35 @@ +#version 140 + +in highp vec4 var_position; +in highp vec3 var_normal; +in highp vec2 var_texcoord0; +in highp vec4 var_texcoord0_shadow; +in highp vec4 var_light; + +out vec4 out_fragColor; + +uniform highp sampler2D tex0; +uniform highp sampler2D tex_depth; + +uniform fs_uniforms +{ + uniform highp vec4 intensity; +}; + +#include "/shadow_mapping/materials/high/shadows_high.glsl" + +void main() +{ + vec4 color = texture(tex0, var_texcoord0.xy); + + // Diffuse light calculations. + vec3 ambient_light = vec3(0.4); + vec3 diff_light = vec3(normalize(var_light.xyz - var_position.xyz)); + diff_light = max(dot(var_normal,1.0 - diff_light), 0.0) + ambient_light; + diff_light = clamp(diff_light, 0.6, 1.0); + + vec4 depth_proj = var_texcoord0_shadow / var_texcoord0_shadow.w; + float shadow_value = shadow_calculation(depth_proj.xyz); + out_fragColor = vec4(intensity.r, intensity.g, intensity.b, intensity.w * (1.0 - shadow_value)) * color.w; +} + diff --git a/shadow_mapping/materials/high/diffuse_transparent.material b/shadow_mapping/materials/high/diffuse_transparent.material new file mode 100644 index 0000000..c43b134 --- /dev/null +++ b/shadow_mapping/materials/high/diffuse_transparent.material @@ -0,0 +1,52 @@ +name: "model" +tags: "shadow_surface" +vertex_program: "/shadow_mapping/materials/standard_instanced.vp" +fragment_program: "/shadow_mapping/materials/high/diffuse_transparent.fp" +vertex_space: VERTEX_SPACE_LOCAL +vertex_constants { + name: "mtx_proj" + type: CONSTANT_TYPE_PROJECTION +} +vertex_constants { + name: "light" + type: CONSTANT_TYPE_USER + value { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } +} +vertex_constants { + name: "mtx_light" + type: CONSTANT_TYPE_USER_MATRIX4 + value { + } +} +vertex_constants { + name: "mtx_view" + type: CONSTANT_TYPE_VIEW +} +fragment_constants { + name: "intensity" + type: CONSTANT_TYPE_USER + value { + w: 0.3 + } +} +samplers { + name: "tex0" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} +samplers { + name: "tex_depth" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 0.0 +} diff --git a/shadow_mapping/materials/high/shadow.fp b/shadow_mapping/materials/high/shadow.fp new file mode 100644 index 0000000..8cdc34b --- /dev/null +++ b/shadow_mapping/materials/high/shadow.fp @@ -0,0 +1,16 @@ +#version 140 + +out vec4 out_fragColor; + +vec4 float_to_rgba( float v ) +{ + vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; + enc = fract(enc); + enc -= enc.yzww * vec4(1.0/255.0,1.0/255.0,1.0/255.0,0.0); + return enc; +} + +void main() +{ + out_fragColor = float_to_rgba(gl_FragCoord.z); +} diff --git a/shadow_mapping/materials/high/shadow.material b/shadow_mapping/materials/high/shadow.material new file mode 100644 index 0000000..2809cb2 --- /dev/null +++ b/shadow_mapping/materials/high/shadow.material @@ -0,0 +1,8 @@ +name: "shadow" +tags: "shadow" +vertex_program: "/shadow_mapping/materials/high/shadow.vp" +fragment_program: "/shadow_mapping/materials/high/shadow.fp" +vertex_constants { + name: "mtx_worldviewproj" + type: CONSTANT_TYPE_WORLDVIEWPROJ +} diff --git a/shadow_mapping/materials/high/shadow.vp b/shadow_mapping/materials/high/shadow.vp new file mode 100644 index 0000000..f791037 --- /dev/null +++ b/shadow_mapping/materials/high/shadow.vp @@ -0,0 +1,14 @@ +#version 140 + +in highp vec4 position; + +uniform vs_uniforms +{ + uniform highp mat4 mtx_worldviewproj; +}; + +void main() +{ + gl_Position = mtx_worldviewproj * vec4(position.xyz, 1.0); +} + diff --git a/shadow_mapping/materials/high/shadows_high.glsl b/shadow_mapping/materials/high/shadows_high.glsl new file mode 100644 index 0000000..35ef14a --- /dev/null +++ b/shadow_mapping/materials/high/shadows_high.glsl @@ -0,0 +1,65 @@ +#define SHADOW_MAP_WIDTH 2048.0 +#define SHADOW_MAP_HEIGHT 2048.0 + +float rgba_to_float(vec4 rgba) +{ + return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0)); +} + +float sample_shadow(vec3 depth_data, vec2 offset, vec2 texel_size, float depth_bias) +{ + float depth = rgba_to_float(texture(tex_depth, depth_data.st + offset * texel_size)); + return (depth_data.z - depth_bias > depth) ? 0.0 : 1.0; +} + +float shadow_calculation(vec3 depth_data) +{ + const float depth_bias = 0.0005; + vec2 texel_size = 1.0 / vec2(SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT); + + float shadow = 0.0; + + shadow += sample_shadow(depth_data, vec2(-1.0, -1.0), texel_size, depth_bias); + shadow += sample_shadow(depth_data, vec2( 0.0, -1.0), texel_size, depth_bias); + shadow += sample_shadow(depth_data, vec2( 1.0, -1.0), texel_size, depth_bias); + + shadow += sample_shadow(depth_data, vec2(-1.0, 0.0), texel_size, depth_bias); + shadow += sample_shadow(depth_data, vec2( 0.0, 0.0), texel_size, depth_bias); + shadow += sample_shadow(depth_data, vec2( 1.0, 0.0), texel_size, depth_bias); + + shadow += sample_shadow(depth_data, vec2(-1.0, 1.0), texel_size, depth_bias); + shadow += sample_shadow(depth_data, vec2( 0.0, 1.0), texel_size, depth_bias); + shadow += sample_shadow(depth_data, vec2( 1.0, 1.0), texel_size, depth_bias); + + return shadow / 9.0; +} + +vec2 rand(vec2 co) +{ + return vec2(fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453), + fract(sin(dot(co.yx ,vec2(12.9898,78.233))) * 43758.5453)) * 0.00047; +} + +float shadow_calculation_with_noise(vec3 depth_data) +{ + float depth_bias = 0.0005; + float shadow = 0.0; + float texel_size = 1.0 / 4096.0; //textureSize(tex1, 0); + int y = 0; + for (int x = -1; x <= 1; ++x) + { + vec2 uv = depth_data.xy + vec2(x,y) * texel_size; + vec4 rgba = texture(tex_depth, uv + rand(uv)); + float depth = rgba_to_float(rgba); + shadow += depth_data.z - depth_bias > depth ? 1.0 : 0.0; + } + shadow /= 3.0; + + highp vec2 uv = depth_data.xy; + if (uv.x<0.0) shadow = 0.0; + if (uv.x>1.0) shadow = 0.0; + if (uv.y<0.0) shadow = 0.0; + if (uv.y>1.0) shadow = 0.0; + + return 1.0 - shadow; +} \ No newline at end of file diff --git a/shadow_mapping/materials/low/diffuse.fp b/shadow_mapping/materials/low/diffuse.fp new file mode 100644 index 0000000..b466b1b --- /dev/null +++ b/shadow_mapping/materials/low/diffuse.fp @@ -0,0 +1,26 @@ +#version 140 + +in highp vec4 var_position; +in mediump vec3 var_normal; +in mediump vec2 var_texcoord0; +in mediump vec4 var_texcoord0_shadow; +in mediump vec4 var_light; + +out vec4 out_fragColor; + +uniform mediump sampler2D tex0; + +void main() +{ + vec4 color = texture(tex0, var_texcoord0.xy); + + // Diffuse light calculations. + vec3 ambient_light = vec3(0.3); + vec3 diff_light = vec3(normalize(var_light.xyz - var_position.xyz)); + diff_light = max(dot(var_normal,diff_light), 0.0) + ambient_light; + diff_light = clamp(diff_light, 0.6, 1.0); + vec3 color_out = color.rgb * diff_light; + + out_fragColor = vec4(color_out,1.0) * color.w; +} + diff --git a/shadow_mapping/materials/low/diffuse.material b/shadow_mapping/materials/low/diffuse.material new file mode 100644 index 0000000..8213e1f --- /dev/null +++ b/shadow_mapping/materials/low/diffuse.material @@ -0,0 +1,39 @@ +name: "model" +tags: "shadow_model" +vertex_program: "/shadow_mapping/materials/standard_instanced.vp" +fragment_program: "/shadow_mapping/materials/low/diffuse.fp" +vertex_space: VERTEX_SPACE_LOCAL +vertex_constants { + name: "mtx_view" + type: CONSTANT_TYPE_VIEW +} +vertex_constants { + name: "mtx_proj" + type: CONSTANT_TYPE_PROJECTION +} +vertex_constants { + name: "light" + type: CONSTANT_TYPE_USER + value { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } +} +samplers { + name: "tex0" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} +samplers { + name: "tex_depth" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} diff --git a/shadow_mapping/materials/low/diffuse_skinning.material b/shadow_mapping/materials/low/diffuse_skinning.material new file mode 100644 index 0000000..d407052 --- /dev/null +++ b/shadow_mapping/materials/low/diffuse_skinning.material @@ -0,0 +1,39 @@ +name: "model" +tags: "shadow_model_skinned" +vertex_program: "/shadow_mapping/materials/standard_skinning_instanced.vp" +fragment_program: "/shadow_mapping/materials/low/diffuse.fp" +vertex_space: VERTEX_SPACE_LOCAL +vertex_constants { + name: "mtx_view" + type: CONSTANT_TYPE_VIEW +} +vertex_constants { + name: "mtx_proj" + type: CONSTANT_TYPE_PROJECTION +} +vertex_constants { + name: "light" + type: CONSTANT_TYPE_USER + value { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } +} +samplers { + name: "tex0" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} +samplers { + name: "tex_depth" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} diff --git a/shadow_mapping/materials/low/diffuse_transparent.fp b/shadow_mapping/materials/low/diffuse_transparent.fp new file mode 100644 index 0000000..9ab9644 --- /dev/null +++ b/shadow_mapping/materials/low/diffuse_transparent.fp @@ -0,0 +1,31 @@ +#version 140 + +in highp vec4 var_position; +in mediump vec3 var_normal; +in mediump vec2 var_texcoord0; +in mediump vec4 var_texcoord0_shadow; +in mediump vec4 var_light; + +out vec4 out_fragColor; + +uniform mediump sampler2D tex0; + +uniform fs_uniforms +{ + uniform mediump vec4 intensity; +}; + +void main() +{ + vec4 color = texture(tex0, var_texcoord0.xy); + + // Diffuse light calculations. + vec3 ambient_light = vec3(0.4); + vec3 diff_light = vec3(normalize(var_light.xyz - var_position.xyz)); + diff_light = max(dot(var_normal,1.0 - diff_light), 0.0) + ambient_light; + diff_light = clamp(diff_light, 0.6, 1.0); + float shadow_value = 1.0; + + out_fragColor = vec4(intensity.r, intensity.g, intensity.b, intensity.w * (1.0 - shadow_value)) * color.w; +} + diff --git a/shadow_mapping/materials/low/diffuse_transparent.material b/shadow_mapping/materials/low/diffuse_transparent.material new file mode 100644 index 0000000..9362106 --- /dev/null +++ b/shadow_mapping/materials/low/diffuse_transparent.material @@ -0,0 +1,46 @@ +name: "model" +tags: "shadow_surface" +vertex_program: "/shadow_mapping/materials/standard_instanced.vp" +fragment_program: "/shadow_mapping/materials/low/diffuse_transparent.fp" +vertex_space: VERTEX_SPACE_LOCAL +vertex_constants { + name: "mtx_view" + type: CONSTANT_TYPE_VIEW +} +vertex_constants { + name: "mtx_proj" + type: CONSTANT_TYPE_PROJECTION +} +vertex_constants { + name: "light" + type: CONSTANT_TYPE_USER + value { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } +} +fragment_constants { + name: "intensity" + type: CONSTANT_TYPE_USER + value { + w: 0.3 + } +} +samplers { + name: "tex0" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} +samplers { + name: "tex_depth" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} diff --git a/shadow_mapping/materials/low/shadow.fp b/shadow_mapping/materials/low/shadow.fp new file mode 100644 index 0000000..973d4ed --- /dev/null +++ b/shadow_mapping/materials/low/shadow.fp @@ -0,0 +1,17 @@ +#version 140 + +out vec4 out_fragColor; + +vec4 float_to_rgba( float v ) +{ + vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; + enc = fract(enc); + enc -= enc.yzww * vec4(1.0/255.0,1.0/255.0,1.0/255.0,0.0); + + return enc; +} + +void main() +{ + out_fragColor = float_to_rgba(gl_FragCoord.z); +} diff --git a/shadow_mapping/materials/low/shadow.material b/shadow_mapping/materials/low/shadow.material new file mode 100644 index 0000000..ec7a838 --- /dev/null +++ b/shadow_mapping/materials/low/shadow.material @@ -0,0 +1,8 @@ +name: "shadow" +tags: "shadow" +vertex_program: "/shadow_mapping/materials/low/shadow.vp" +fragment_program: "/shadow_mapping/materials/low/shadow.fp" +vertex_constants { + name: "mtx_worldviewproj" + type: CONSTANT_TYPE_WORLDVIEWPROJ +} diff --git a/shadow_mapping/materials/low/shadow.vp b/shadow_mapping/materials/low/shadow.vp new file mode 100644 index 0000000..1057055 --- /dev/null +++ b/shadow_mapping/materials/low/shadow.vp @@ -0,0 +1,14 @@ +#version 140 + +in mediump vec4 position; + +uniform vs_uniforms +{ + uniform mediump mat4 mtx_worldviewproj; +}; + +void main() +{ + gl_Position = mtx_worldviewproj * vec4(position.xyz, 1.0); +} + diff --git a/shadow_mapping/materials/mid/diffuse.fp b/shadow_mapping/materials/mid/diffuse.fp new file mode 100644 index 0000000..363815f --- /dev/null +++ b/shadow_mapping/materials/mid/diffuse.fp @@ -0,0 +1,29 @@ +#version 140 + +in highp vec4 var_position; +in highp vec3 var_normal; +in highp vec2 var_texcoord0; +in highp vec4 var_texcoord0_shadow; +in highp vec4 var_light; + +out vec4 out_fragColor; + +uniform highp sampler2D tex0; +uniform highp sampler2D tex_depth; + +// #include "/shadow_mapping/materials/mid/shadows_mid.glsl" + +void main() +{ + vec4 color = texture(tex0, var_texcoord0.xy); + + // Diffuse light calculations. + vec3 ambient_light = vec3(0.3); + vec3 diff_light = vec3(normalize(var_light.xyz - var_position.xyz)); + diff_light = max(dot(var_normal,diff_light), 0.0) + ambient_light; + diff_light = clamp(diff_light, 0.6, 1.0); + + vec3 color_out = color.rgb * diff_light; + out_fragColor = vec4(color_out,1.0) * color.w; +} + diff --git a/shadow_mapping/materials/mid/diffuse.material b/shadow_mapping/materials/mid/diffuse.material new file mode 100644 index 0000000..9e15f2e --- /dev/null +++ b/shadow_mapping/materials/mid/diffuse.material @@ -0,0 +1,45 @@ +name: "model" +tags: "shadow_model" +vertex_program: "/shadow_mapping/materials/standard_instanced.vp" +fragment_program: "/shadow_mapping/materials/mid/diffuse.fp" +vertex_space: VERTEX_SPACE_LOCAL +vertex_constants { + name: "mtx_view" + type: CONSTANT_TYPE_VIEW +} +vertex_constants { + name: "mtx_proj" + type: CONSTANT_TYPE_PROJECTION +} +vertex_constants { + name: "light" + type: CONSTANT_TYPE_USER + value { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } +} +vertex_constants { + name: "mtx_light" + type: CONSTANT_TYPE_USER_MATRIX4 + value { + } +} +samplers { + name: "tex0" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} +samplers { + name: "tex_depth" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} diff --git a/shadow_mapping/materials/mid/diffuse_skinning.material b/shadow_mapping/materials/mid/diffuse_skinning.material new file mode 100644 index 0000000..11d9100 --- /dev/null +++ b/shadow_mapping/materials/mid/diffuse_skinning.material @@ -0,0 +1,53 @@ +name: "model" +tags: "shadow_model_skinned" +vertex_program: "/shadow_mapping/materials/standard_skinning_instanced.vp" +fragment_program: "/shadow_mapping/materials/mid/diffuse.fp" +vertex_space: VERTEX_SPACE_LOCAL +vertex_constants { + name: "mtx_view" + type: CONSTANT_TYPE_VIEW +} +vertex_constants { + name: "mtx_proj" + type: CONSTANT_TYPE_PROJECTION +} +vertex_constants { + name: "light" + type: CONSTANT_TYPE_USER + value { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } +} +vertex_constants { + name: "mtx_light" + type: CONSTANT_TYPE_USER_MATRIX4 + value { + } +} +samplers { + name: "tex0" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} +samplers { + name: "tex_depth" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 0.0 +} +samplers { + name: "pose_matrix_cache" + wrap_u: WRAP_MODE_REPEAT + wrap_v: WRAP_MODE_REPEAT + filter_min: FILTER_MODE_MIN_NEAREST + filter_mag: FILTER_MODE_MAG_NEAREST + max_anisotropy: 0.0 +} diff --git a/shadow_mapping/materials/mid/diffuse_transparent.fp b/shadow_mapping/materials/mid/diffuse_transparent.fp new file mode 100644 index 0000000..66788ce --- /dev/null +++ b/shadow_mapping/materials/mid/diffuse_transparent.fp @@ -0,0 +1,35 @@ +#version 140 + +in highp vec4 var_position; +in mediump vec3 var_normal; +in mediump vec2 var_texcoord0; +in mediump vec4 var_texcoord0_shadow; +in mediump vec4 var_light; + +out vec4 out_fragColor; + +uniform lowp sampler2D tex0; +uniform lowp sampler2D tex_depth; + +uniform fs_uniforms +{ + uniform mediump vec4 intensity; +}; + +#include "/shadow_mapping/materials/mid/shadows_mid.glsl" + +void main() +{ + vec4 color = texture(tex0, var_texcoord0.xy); + + // Diffuse light calculations. + vec3 ambient_light = vec3(0.4); + vec3 diff_light = vec3(normalize(var_light.xyz - var_position.xyz)); + diff_light = max(dot(var_normal,1.0 - diff_light), 0.0) + ambient_light; + diff_light = clamp(diff_light, 0.6, 1.0); + + vec4 depth_proj = var_texcoord0_shadow / var_texcoord0_shadow.w; + float shadow_value = shadow_calculation(depth_proj.xyz); + out_fragColor = vec4(intensity.r, intensity.g, intensity.b, intensity.w * (1.0 - shadow_value)) * color.w; +} + diff --git a/shadow_mapping/materials/mid/diffuse_transparent.material b/shadow_mapping/materials/mid/diffuse_transparent.material new file mode 100644 index 0000000..0acc1a9 --- /dev/null +++ b/shadow_mapping/materials/mid/diffuse_transparent.material @@ -0,0 +1,52 @@ +name: "model" +tags: "shadow_surface" +vertex_program: "/shadow_mapping/materials/standard_instanced.vp" +fragment_program: "/shadow_mapping/materials/mid/diffuse_transparent.fp" +vertex_space: VERTEX_SPACE_LOCAL +vertex_constants { + name: "mtx_view" + type: CONSTANT_TYPE_VIEW +} +vertex_constants { + name: "mtx_proj" + type: CONSTANT_TYPE_PROJECTION +} +vertex_constants { + name: "light" + type: CONSTANT_TYPE_USER + value { + x: 1.0 + y: 1.0 + z: 1.0 + w: 1.0 + } +} +vertex_constants { + name: "mtx_light" + type: CONSTANT_TYPE_USER_MATRIX4 + value { + } +} +fragment_constants { + name: "intensity" + type: CONSTANT_TYPE_USER + value { + w: 0.3 + } +} +samplers { + name: "tex0" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} +samplers { + name: "tex_depth" + wrap_u: WRAP_MODE_CLAMP_TO_EDGE + wrap_v: WRAP_MODE_CLAMP_TO_EDGE + filter_min: FILTER_MODE_MIN_LINEAR + filter_mag: FILTER_MODE_MAG_LINEAR + max_anisotropy: 2.0 +} diff --git a/shadow_mapping/materials/mid/shadow.fp b/shadow_mapping/materials/mid/shadow.fp new file mode 100644 index 0000000..8cdc34b --- /dev/null +++ b/shadow_mapping/materials/mid/shadow.fp @@ -0,0 +1,16 @@ +#version 140 + +out vec4 out_fragColor; + +vec4 float_to_rgba( float v ) +{ + vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; + enc = fract(enc); + enc -= enc.yzww * vec4(1.0/255.0,1.0/255.0,1.0/255.0,0.0); + return enc; +} + +void main() +{ + out_fragColor = float_to_rgba(gl_FragCoord.z); +} diff --git a/shadow_mapping/materials/mid/shadow.material b/shadow_mapping/materials/mid/shadow.material new file mode 100644 index 0000000..3ef0146 --- /dev/null +++ b/shadow_mapping/materials/mid/shadow.material @@ -0,0 +1,8 @@ +name: "shadow" +tags: "shadow" +vertex_program: "/shadow_mapping/materials/mid/shadow.vp" +fragment_program: "/shadow_mapping/materials/mid/shadow.fp" +vertex_constants { + name: "mtx_worldviewproj" + type: CONSTANT_TYPE_WORLDVIEWPROJ +} diff --git a/shadow_mapping/materials/mid/shadow.vp b/shadow_mapping/materials/mid/shadow.vp new file mode 100644 index 0000000..f791037 --- /dev/null +++ b/shadow_mapping/materials/mid/shadow.vp @@ -0,0 +1,14 @@ +#version 140 + +in highp vec4 position; + +uniform vs_uniforms +{ + uniform highp mat4 mtx_worldviewproj; +}; + +void main() +{ + gl_Position = mtx_worldviewproj * vec4(position.xyz, 1.0); +} + diff --git a/shadow_mapping/materials/mid/shadows_mid.glsl b/shadow_mapping/materials/mid/shadows_mid.glsl new file mode 100644 index 0000000..cbf1625 --- /dev/null +++ b/shadow_mapping/materials/mid/shadows_mid.glsl @@ -0,0 +1,16 @@ + +// #define SHADOW_MAP_WIDTH 512.0 +// #define SHADOW_MAP_HEIGHT 512.0 + +float rgba_to_float(vec4 rgba) +{ + return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0)); +} + +float shadow_calculation(vec3 depth_data) +{ + const float depth_bias = 0.0005; + float depth = rgba_to_float(texture(tex_depth, depth_data.st)); + float shadow = depth_data.z - depth_bias > depth ? 0.0 : 1.0; + return shadow; +} diff --git a/shadow_mapping/materials/standard.vp b/shadow_mapping/materials/standard.vp new file mode 100644 index 0000000..5516014 --- /dev/null +++ b/shadow_mapping/materials/standard.vp @@ -0,0 +1,38 @@ + +// Positions can be world or local space, since world and normal +// matrices are identity for world vertex space materials. +// If world vertex space is selected, you can remove the +// normal matrix multiplication for optimal performance. + +attribute highp vec4 position; +attribute mediump vec2 texcoord0; +attribute mediump vec3 normal; + +uniform mediump mat4 mtx_worldview; +uniform mediump mat4 mtx_view; +uniform mediump mat4 mtx_world; +uniform mediump mat4 mtx_proj; +uniform mediump mat4 mtx_normal; + +uniform mediump vec4 light; +uniform mediump mat4 mtx_light; + +varying highp vec4 var_position; +varying mediump vec4 var_position_world; +varying mediump vec3 var_normal; +varying mediump vec2 var_texcoord0; +varying mediump vec4 var_texcoord0_shadow; +varying mediump vec4 var_light; + +void main() +{ + vec4 p = mtx_worldview * vec4(position.xyz, 1.0); + var_light = mtx_view * vec4(light.xyz, 1.0); + var_position = p; + var_position_world = mtx_world * vec4(position.xyz, 1.0); + var_texcoord0 = texcoord0; + var_texcoord0_shadow = mtx_light * mtx_world * vec4(position.xyz, 1.0); + var_normal = normalize((mtx_normal * vec4(normal, 0.0)).xyz); + gl_Position = mtx_proj * p; +} + diff --git a/shadow_mapping/materials/standard_instanced.vp b/shadow_mapping/materials/standard_instanced.vp new file mode 100644 index 0000000..bb651d8 --- /dev/null +++ b/shadow_mapping/materials/standard_instanced.vp @@ -0,0 +1,40 @@ +#version 140 + +// Positions can be world or local space, since world and normal +// matrices are identity for world vertex space materials. +// If world vertex space is selected, you can remove the +// normal matrix multiplication for optimal performance. + +in highp vec4 position; +in highp vec2 texcoord0; +in highp vec3 normal; + +in highp mat4 mtx_world; +in highp mat4 mtx_normal; + +out highp vec4 var_position; +out highp vec3 var_normal; +out highp vec2 var_texcoord0; +out highp vec4 var_texcoord0_shadow; +out highp vec4 var_light; + +uniform vs_uniforms +{ + uniform mediump mat4 mtx_view; + uniform mediump mat4 mtx_proj; + uniform mediump vec4 light; + uniform mediump mat4 mtx_light; +}; + +void main() +{ + vec4 pw = mtx_world * vec4(position.xyz, 1.0); + vec4 p = mtx_view * pw; + var_light = mtx_view * vec4(light.xyz, 1.0); + var_position = p; + var_texcoord0 = texcoord0; + var_texcoord0_shadow = mtx_light * pw; + var_normal = normalize((mtx_normal * vec4(normal, 0.0)).xyz); + gl_Position = mtx_proj * p; +} + diff --git a/shadow_mapping/materials/standard_skinning_instanced.vp b/shadow_mapping/materials/standard_skinning_instanced.vp new file mode 100644 index 0000000..e11f7f8 --- /dev/null +++ b/shadow_mapping/materials/standard_skinning_instanced.vp @@ -0,0 +1,46 @@ +#version 140 + +// Positions can be world or local space, since world and normal +// matrices are identity for world vertex space materials. +// If world vertex space is selected, you can remove the +// normal matrix multiplication for optimal performance. + +in highp vec4 position; +in mediump vec2 texcoord0; +in highp vec3 normal; +in mediump vec4 bone_weights; +in mediump vec4 bone_indices; + +in mediump mat4 mtx_world; +in mediump mat4 mtx_normal; +in mediump vec4 animation_data; + +out highp vec4 var_position; +out highp vec3 var_normal; +out mediump vec2 var_texcoord0; +out mediump vec4 var_texcoord0_shadow; +out mediump vec4 var_light; + +uniform vs_uniforms +{ + uniform mediump mat4 mtx_view; + uniform mediump mat4 mtx_proj; + uniform mediump vec4 light; + uniform mediump mat4 mtx_light; +}; + +#include "/builtins/materials/skinning.glsl" + +void main() +{ + vec4 skinned_position = get_skinned_position(position); + vec4 pw = mtx_world * vec4(skinned_position.xyz, 1.0); + vec4 p = mtx_view * pw; + var_light = mtx_view * vec4(light.xyz, 1.0); + var_position = pw; + var_texcoord0 = texcoord0; + var_texcoord0_shadow = mtx_light * pw; + var_normal = normalize((mtx_normal * vec4(normal, 0.0)).xyz); + gl_Position = mtx_proj * p; +} + diff --git a/shadow_mapping/model_tiers.script b/shadow_mapping/model_tiers.script new file mode 100644 index 0000000..452b52e --- /dev/null +++ b/shadow_mapping/model_tiers.script @@ -0,0 +1,23 @@ +local tiers = require("shadow_mapping.tiers") + +go.property("component", msg.url("#model")) + +go.property("low_material", resource.material("/shadow_mapping/materials/low/diffuse.material")) +go.property("mid_material", resource.material("/shadow_mapping/materials/mid/diffuse.material")) +go.property("high_material", resource.material("/shadow_mapping/materials/high/diffuse.material")) + +function init() + tiers.register() +end + +function final() + tiers.unregister() +end + +function on_message(self, message_id, message) + if message_id == tiers.MSG_CHANGE_TIER then + go.set(self.component, tiers.PROP_MATERIAL, self[message.tier]) + elseif message_id == tiers.MSG_REMOVE_FROM_TIER then + tiers.unregister() + end +end diff --git a/shadow_mapping/shadow_mapping.lua b/shadow_mapping/shadow_mapping.lua new file mode 100644 index 0000000..ccbcaf9 --- /dev/null +++ b/shadow_mapping/shadow_mapping.lua @@ -0,0 +1,179 @@ +local M = {} +local tiers = require("shadow_mapping.tiers") + +local BUFFER_WIDTH = 1024 +local BUFFER_HEIGHT = 1024 +local BUFFER_NAME = "shadow_buffer" + +local SHADOW_MATERIAL_NAME = "shadow" +local SHADOW_PREDICATE_NAME = "shadow" +local MODEL_PREDICATE_NAME = "shadow_model" +local SHADOW_SURFACE_PREDICATE_NAME = "shadow_surface" +local MODEL_PREDICATE_SKINNED_NAME = "shadow_model_skinned" + +local FORWARDVEC = vmath.vector3(0, 0, -1) +local UPVEC = vmath.vector3(0, 1, 0) + +local function calculate_view(position, rotation) + local w_forward_vec = vmath.rotate(rotation, FORWARDVEC) + local w_up_vec = vmath.rotate(rotation, UPVEC) + local matrix = vmath.matrix4_look_at(position, position + w_forward_vec, w_up_vec) + return matrix +end + +local function create_depth_buffer(w, h) + local color_params = { + format = render.FORMAT_RGBA, + width = w, + height = h, + min_filter = render.FILTER_NEAREST, + mag_filter = render.FILTER_NEAREST, + u_wrap = render.WRAP_CLAMP_TO_EDGE, + v_wrap = render.WRAP_CLAMP_TO_EDGE + } + + local depth_params = { + format = render.FORMAT_DEPTH, + width = w, + height = h, + min_filter = render.FILTER_NEAREST, + mag_filter = render.FILTER_NEAREST, + u_wrap = render.WRAP_CLAMP_TO_EDGE, + v_wrap = render.WRAP_CLAMP_TO_EDGE + } + + return render.render_target(BUFFER_NAME, + { + [render.BUFFER_COLOR_BIT] = color_params, + [render.BUFFER_DEPTH_BIT] = depth_params + }) +end + +function M.init() + M.shadow_pred = render.predicate({ SHADOW_PREDICATE_NAME }) + M.shadow_surface_pred = render.predicate({ SHADOW_SURFACE_PREDICATE_NAME }) + M.shadow_model_pred = render.predicate({ MODEL_PREDICATE_NAME }) + M.shadow_model_skinned_pred = render.predicate({ MODEL_PREDICATE_SKINNED_NAME }) + + M.light_buffer = create_depth_buffer(BUFFER_WIDTH, BUFFER_HEIGHT) + M.light_transform = vmath.matrix4() + M.light_projection = vmath.matrix4() + M.light_constant_buffer = render.constant_buffer() + + M.bias_matrix = vmath.matrix4() + M.bias_matrix.c0 = vmath.vector4(0.5, 0.0, 0.0, 0.0) + M.bias_matrix.c1 = vmath.vector4(0.0, 0.5, 0.0, 0.0) + M.bias_matrix.c2 = vmath.vector4(0.0, 0.0, 0.5, 0.0) + M.bias_matrix.c3 = vmath.vector4(0.5, 0.5, 0.5, 1.0) +end + +function M.set_light_transform(light_transform) + M.light_transform = vmath.matrix4(light_transform) +end + +function M.set_light_projection(projection) + M.light_projection = vmath.matrix4(projection) +end + +---@param position vector3 +---@param rotation quat quaternion +function M.calculate_light_transform(position, rotation) + local view = calculate_view(position, rotation) + M.light_transform = view +end + +local render_shadow_counter = 0 + +function M.render_shadow(self) + if tiers.is_shadows_ignored() then + return + end + + if not tiers.is_top_tier() then + -- redraw shadows every second frame + render_shadow_counter = render_shadow_counter + 1 + if render_shadow_counter == 2 then + render_shadow_counter = 0 + return + end + end + + local w = render.get_render_target_width(M.light_buffer, render.BUFFER_DEPTH_BIT) + local h = render.get_render_target_height(M.light_buffer, render.BUFFER_DEPTH_BIT) + + render.set_projection(M.light_projection) + render.set_view(M.light_transform) + render.set_viewport(0, 0, w, h) + + render.set_depth_mask(true) + render.set_depth_func(render.COMPARE_FUNC_LEQUAL) + render.enable_state(render.STATE_DEPTH_TEST) + render.disable_state(render.STATE_BLEND) + render.disable_state(render.STATE_CULL_FACE) + + -- This is something I would like to do to fix the "peter panning" issue, + -- but it doesn't really work. Need to flip the normal on the plane I guess. + -- render.set_cull_face(render.FACE_FRONT) + -- render.enable_state(render.STATE_CULL_FACE) + + render.set_render_target(M.light_buffer, { transient = { render.BUFFER_DEPTH_BIT } }) + render.clear({ + [render.BUFFER_COLOR_BIT] = vmath.vector4(0, 0, 0, 1), + [render.BUFFER_DEPTH_BIT] = 1 + }) + render.enable_material(tiers.get_tier_for_material(SHADOW_MATERIAL_NAME)) + render.draw(M.shadow_surface_pred) + render.draw(M.shadow_model_pred) + render.draw(M.shadow_model_skinned_pred) + render.draw(self.predicates.particle) + render.disable_material() + render.set_render_target(render.RENDER_TARGET_DEFAULT) +end + +function M.prerender() + render.set_color_mask(true, true, true, true) + render.set_depth_func(render.COMPARE_FUNC_LEQUAL) +end + +function M.render_shadow_model(view, proj, frustum) + local mtx_light = M.bias_matrix * M.light_projection * M.light_transform + local inv_light = vmath.inv(M.light_transform) + local light = vmath.vector4() + + light.x = inv_light.m03 + light.y = inv_light.m13 + light.z = inv_light.m23 + light.w = 1 + + M.light_constant_buffer.mtx_light = mtx_light + M.light_constant_buffer.light = light + + render.set_projection(proj) + render.enable_state(render.STATE_DEPTH_TEST) + render.disable_state(render.STATE_STENCIL_TEST) + render.enable_state(render.STATE_BLEND) + render.set_blend_func(render.BLEND_SRC_ALPHA, render.BLEND_ONE_MINUS_SRC_ALPHA) + + --render.enable_state(render.STATE_CULL_FACE) + render.set_cull_face(render.FACE_BACK) + --render.disable_state(render.STATE_CULL_FACE) + + render.set_view(view) + render.set_depth_mask(true) + if not tiers.is_shadows_ignored() then + render.enable_texture(1, M.light_buffer, render.BUFFER_COLOR_BIT) + end + render.draw(M.shadow_surface_pred, { frustum = frustum, constants = M.light_constant_buffer }) + render.draw(M.shadow_model_pred, { frustum = frustum, constants = M.light_constant_buffer }) + if not tiers.is_mid_tier() then + render.draw(M.shadow_model_skinned_pred, { frustum = frustum, constants = M.light_constant_buffer }) + end + if not tiers.is_shadows_ignored() then + render.disable_texture(1) + end + if tiers.is_mid_tier() then + render.draw(M.shadow_model_skinned_pred, { frustum = frustum, constants = M.light_constant_buffer }) + end +end + +return M diff --git a/shadow_mapping/tier_service.script b/shadow_mapping/tier_service.script new file mode 100644 index 0000000..ead4cd3 --- /dev/null +++ b/shadow_mapping/tier_service.script @@ -0,0 +1,60 @@ +local tiers = require("shadow_mapping.tiers") + +local COUNT = 6 +local ACCEPTABLE_FRAME_TIME = 0.039 + +local all_tiers = { + [1] = tiers.LOW, + [2] = tiers.MID, + [3] = tiers.HIGH +} + +local function reset_counter(self) + self.count = {} + self.num = 1 + self.decided = false +end + +---Start a timer that will determine if the FPS count is enough or if it’s necessary to decrease shadows quality. +local function decide_on_tier(self, tier_num) + tiers.change_tier(all_tiers[tier_num]) + reset_counter(self) + self.timer = timer.delay(0.5, false, function() + local sum = 0 + for _, v in pairs(self.count) do + sum = sum + v + end + local dt = sum / #self.count + if dt > ACCEPTABLE_FRAME_TIME and tier_num > 1 then + tier_num = tier_num - 1 + decide_on_tier(self, tier_num) + else + self.decided = true + self.timer = nil + end + end) +end + +function init(self) + reset_counter(self) + ---You can send the message tiers.MSG_DECIDE to begin the check once the level is loaded, or simply call this function manually. + decide_on_tier(self, #all_tiers) +end + +function on_message(self, message_id, message, sender) + if message_id == tiers.MSG_DECIDE then + if not self.timer then + decide_on_tier(self, #all_tiers) + end + end +end + +function update(self, dt) + if not self.decided then + self.count[self.num] = dt + self.num = self.num + 1 + if self.num > COUNT then + self.num = 1 + end + end +end diff --git a/shadow_mapping/tiers.lua b/shadow_mapping/tiers.lua new file mode 100644 index 0000000..f85fefb --- /dev/null +++ b/shadow_mapping/tiers.lua @@ -0,0 +1,57 @@ +local M = {} + +M.LOW = "low_material" +M.MID = "mid_material" +M.HIGH = "high_material" + +M.MSG_CHANGE_TIER = hash("MSG_CHANGE_TIER") +M.MSG_DECIDE = hash("MSG_DECIDE") +M.MSG_REMOVE_FROM_TIER = hash("MSG_REMOVE_FROM_TIER") + +M.PROP_MATERIAL = hash("material") + +local current_tier = M.HIGH + +local listeners = {} +local materials = {} + +function M.change_tier(tier) + current_tier = tier + for _, listener in pairs(listeners) do + if go.exists(listener) then + msg.post(listener, M.MSG_CHANGE_TIER, { tier = tier }) + end + end +end + +function M.register() + listeners[tostring(msg.url())] = msg.url() +end + +function M.unregister() + listeners[tostring(msg.url())] = nil +end + +function M.get_tier_for_material(name) + if not materials[name] then + materials[name] = {} + materials[name][M.LOW] = name .. "_" .. M.LOW + materials[name][M.MID] = name .. "_" .. M.MID + materials[name][M.HIGH] = name .. "_" .. M.HIGH + end + return materials[name][current_tier] +end + +function M.is_shadows_ignored() + return M.LOW == current_tier +end + +function M.is_top_tier() + return M.HIGH == current_tier +end + +function M.is_mid_tier() + return M.MID == current_tier +end + +return M