├── docs ├── Structs │ ├── Boolean.md │ ├── Number.md │ ├── String.md │ ├── Thread.md │ ├── Display.md │ ├── Math.md │ └── PixelBuffer.md ├── .vitepress │ ├── cache │ │ └── deps_temp_c3414293 │ │ │ ├── package.json │ │ │ ├── vitepress___@vue_devtools-api.js │ │ │ └── vitepress___@vue_devtools-api.js.map │ └── config.js ├── public │ └── pack_icon.png ├── Enums │ └── Color.md └── index.md ├── BP ├── texts │ ├── languages.json │ └── en_US.lang ├── pack_icon.png ├── scripts │ ├── enums │ │ └── Color.ts │ ├── Properties.ts │ ├── structs │ │ ├── Thread.ts │ │ ├── Math.ts │ │ ├── Display.ts │ │ ├── Turtle.ts │ │ └── PixelBuffer.ts │ ├── Turtles.ts │ ├── run.ts │ ├── FileSystem.ts │ └── main.ts ├── blocks │ ├── display.json │ └── turtle.json ├── entities │ ├── turtle_controller.json │ └── pixel.json └── manifest.json ├── RP ├── texts │ ├── languages.json │ └── en_US.lang ├── ui │ ├── _ui_defs.json │ └── server_form.json ├── pack_icon.png ├── textures │ ├── entity │ │ ├── blue.png │ │ ├── red.png │ │ ├── green.png │ │ ├── orange.png │ │ ├── pixel.png │ │ ├── purple.png │ │ ├── white.png │ │ ├── yellow.png │ │ └── turtle_controller.png │ ├── turtle │ │ ├── file.png │ │ ├── delete.png │ │ ├── folder.png │ │ ├── go_back.png │ │ ├── new_file.png │ │ └── new_folder.png │ ├── blocks │ │ ├── robot.png │ │ └── display.png │ └── terrain_texture.json ├── blocks.json ├── render_controllers │ ├── turtle_controller.json │ └── pixel.json ├── animations │ └── pixel.animation.json ├── entity │ ├── turtle_controller.json │ └── pixel.json ├── models │ ├── entity │ │ ├── turtle_controller.json │ │ └── pixel.geo.json │ └── blocks │ │ ├── turtle.geo.json │ │ └── display.geo.json └── manifest.json ├── nodeGenerators ├── char.png ├── font_points.js └── pixel_entity.js ├── compiler.config.json ├── .gitmodules ├── .gitignore ├── .vscode └── launch.json ├── package.json ├── .github └── workflows │ └── deploy.yml ├── LICENSE ├── README.md └── examples └── pong.cos /docs/Structs/Boolean.md: -------------------------------------------------------------------------------- 1 | # Boolean -------------------------------------------------------------------------------- /docs/Structs/Number.md: -------------------------------------------------------------------------------- 1 | # Number -------------------------------------------------------------------------------- /docs/Structs/String.md: -------------------------------------------------------------------------------- 1 | # String -------------------------------------------------------------------------------- /BP/texts/languages.json: -------------------------------------------------------------------------------- 1 | [ 2 | "en_US" 3 | ] -------------------------------------------------------------------------------- /RP/texts/languages.json: -------------------------------------------------------------------------------- 1 | [ 2 | "en_US" 3 | ] -------------------------------------------------------------------------------- /docs/.vitepress/cache/deps_temp_c3414293/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /RP/ui/_ui_defs.json: -------------------------------------------------------------------------------- 1 | { 2 | "ui_defs": [ 3 | "ui/server_form.json" 4 | ] 5 | } -------------------------------------------------------------------------------- /BP/pack_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/BP/pack_icon.png -------------------------------------------------------------------------------- /RP/pack_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/pack_icon.png -------------------------------------------------------------------------------- /BP/texts/en_US.lang: -------------------------------------------------------------------------------- 1 | pack.name=CC: Bedrock 2 | pack.description=An embedded programming language in MCBE -------------------------------------------------------------------------------- /nodeGenerators/char.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/nodeGenerators/char.png -------------------------------------------------------------------------------- /RP/textures/entity/blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/entity/blue.png -------------------------------------------------------------------------------- /RP/textures/entity/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/entity/red.png -------------------------------------------------------------------------------- /RP/textures/turtle/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/turtle/file.png -------------------------------------------------------------------------------- /docs/public/pack_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/docs/public/pack_icon.png -------------------------------------------------------------------------------- /RP/textures/blocks/robot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/blocks/robot.png -------------------------------------------------------------------------------- /RP/textures/entity/green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/entity/green.png -------------------------------------------------------------------------------- /RP/textures/entity/orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/entity/orange.png -------------------------------------------------------------------------------- /RP/textures/entity/pixel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/entity/pixel.png -------------------------------------------------------------------------------- /RP/textures/entity/purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/entity/purple.png -------------------------------------------------------------------------------- /RP/textures/entity/white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/entity/white.png -------------------------------------------------------------------------------- /RP/textures/entity/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/entity/yellow.png -------------------------------------------------------------------------------- /RP/textures/turtle/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/turtle/delete.png -------------------------------------------------------------------------------- /RP/textures/turtle/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/turtle/folder.png -------------------------------------------------------------------------------- /RP/textures/blocks/display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/blocks/display.png -------------------------------------------------------------------------------- /RP/textures/turtle/go_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/turtle/go_back.png -------------------------------------------------------------------------------- /RP/textures/turtle/new_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/turtle/new_file.png -------------------------------------------------------------------------------- /RP/blocks.json: -------------------------------------------------------------------------------- 1 | { 2 | "coslang:turtle": { 3 | "sound": "stone" 4 | }, 5 | "coslang:display": { 6 | "sound": "stone" 7 | } 8 | } -------------------------------------------------------------------------------- /RP/textures/turtle/new_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/turtle/new_folder.png -------------------------------------------------------------------------------- /compiler.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "packName": "ComputerCraft", 3 | "resourcePackPath": "/RP/", 4 | "behaviourPackPath": "/BP/" 5 | } 6 | -------------------------------------------------------------------------------- /RP/textures/entity/turtle_controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrederoxDev/CC-Bedrock-Addon/HEAD/RP/textures/entity/turtle_controller.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "BP/scripts/cosmic"] 2 | path = BP/scripts/cosmic 3 | url = https://github.com/FrederoxDev/Cosmic.git 4 | branch = RewriteV3 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Desktop.ini 2 | .DS_Store 3 | !.bridge/ 4 | .bridge/* 5 | !.bridge/compiler/ 6 | !.bridge/extensions 7 | builds 8 | /node_modules/ 9 | err/ 10 | input.cos 11 | dist/ -------------------------------------------------------------------------------- /docs/Structs/Thread.md: -------------------------------------------------------------------------------- 1 | # Thread 2 | 3 | ## Static Methods 4 | 5 | ### Sleep 6 | Pauses the thread for a number of minecraft ticks 7 | - Parameters: [`ticksToWait`](Number) 8 | - Returns: `void` -------------------------------------------------------------------------------- /BP/scripts/enums/Color.ts: -------------------------------------------------------------------------------- 1 | import { NativeEnum } from "../cosmic/src/Struct/NativeEnum"; 2 | 3 | export const Color = new NativeEnum("Color", ["White", "Red", "Orange", "Yellow", "Green", "Blue", "Purple"]) -------------------------------------------------------------------------------- /BP/scripts/Properties.ts: -------------------------------------------------------------------------------- 1 | export const connectedTurtleProp = "connectedTurtle"; 2 | export const turtleFilesProp = "turtleFiles"; 3 | export const turtleIdProp = "turtleId"; 4 | export const nextTurtleIdProp = "nextTurtleId"; -------------------------------------------------------------------------------- /RP/textures/terrain_texture.json: -------------------------------------------------------------------------------- 1 | { 2 | "texture_data": { 3 | "coslang_turtle": { 4 | "textures": "textures/blocks/robot" 5 | }, 6 | "coslang_display": { 7 | "textures": "textures/blocks/display" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /docs/Enums/Color.md: -------------------------------------------------------------------------------- 1 | # Color 2 | The color enum is used for selecting colors for drawing in [PixelBuffers](../Structs/PixelBuffer.md) 3 | 4 | ### Values 5 | - `White` 6 | - `Red` 7 | - `Orange` 8 | - `Yellow` 9 | - `Green` 10 | - `Blue` 11 | - `Purple` -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.3.0", 3 | "configurations": [ 4 | { 5 | "type": "minecraft-js", 6 | "request": "attach", 7 | "name": "Wait for Minecraft Debug Connections", 8 | "mode": "listen", 9 | "localRoot": "${workspaceFolder}/BP/", 10 | "port": 19144 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /RP/render_controllers/turtle_controller.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.8.0", 3 | "render_controllers": { 4 | "controller.render.turtle_controller": { 5 | "geometry": "Geometry.default", 6 | "materials": [ 7 | { 8 | "*": "Material.default" 9 | } 10 | ], 11 | "textures": [ 12 | "Texture.default" 13 | ] 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | hero: 5 | name: "CC: Bedrock" 6 | text: Robots, Computers and more! 7 | tagline: All built from scratch 8 | image: 9 | src: /pack_icon.png 10 | alt: Pack Icon 11 | actions: 12 | - theme: brand 13 | text: Structs 14 | link: Structs/Display 15 | - theme: alt 16 | text: View on GitHub 17 | link: https://github.com/frederoxDev/CC-Bedrock 18 | --- 19 | -------------------------------------------------------------------------------- /RP/texts/en_US.lang: -------------------------------------------------------------------------------- 1 | pack.name=CC: Bedrock 2 | pack.description=An embedded programming language in MCBE 3 | 4 | tile.coslang:turtle.name=Turtle 5 | item.spawn_egg.entity.coslang:turtle_controller.name=Spawn Turtle Controller 6 | entity.coslang:turtle_controller.name=Turtle Controller 7 | tile.coslang:display.name=Display 8 | item.spawn_egg.entity.coslang:pixel.name=Spawn Pixel 9 | entity.coslang:pixel.name=Pixel 10 | 11 | turtle.connect=Connected with %s -------------------------------------------------------------------------------- /RP/animations/pixel.animation.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.8.0", 3 | "animations": { 4 | "animation.pixel.position": { 5 | "loop": true, 6 | "animation_length": 2.58333, 7 | "bones": { 8 | "pos_bone": { 9 | "position": ["query.property('coslang:x')", "query.property('coslang:y')", 0] 10 | }, 11 | "size_bone": { 12 | "scale": ["query.property('coslang:x_size')", "query.property('coslang:y_size')", 1] 13 | } 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /BP/blocks/display.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.19.50", 3 | "minecraft:block": { 4 | "description": { 5 | "identifier": "coslang:display" 6 | }, 7 | "components": { 8 | "minecraft:geometry": "geometry.display", 9 | "minecraft:material_instances": { 10 | "*": { 11 | "texture": "coslang_display", 12 | "render_method": "alpha_test" 13 | } 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /docs/Structs/Display.md: -------------------------------------------------------------------------------- 1 | # Display 2 | 3 | ## Static Methods 4 | 5 | ### Connect 6 | Returns an instance of a display at a specific position 7 | - Parameters: [`x: Number`](Number) [`y: Number`](Number) [`width: Number`](Number) [`height: Number`](Number) 8 | - Returns: [`Display`](Display.md) 9 | 10 | ## Instance Methods 11 | 12 | ### DrawBuffer 13 | Draws the pixel buffer to the screen 14 | - Parameters: [`buffer: PixelBuffer`](PixelBuffer.md) 15 | - Throws: `Will throw an error if pixelBuffer is the wrong size` 16 | - Returns: `void` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "docs:dev": "vitepress dev docs", 4 | "docs:build": "vitepress build docs", 5 | "docs:preview": "vitepress preview docs" 6 | }, 7 | "dependencies": { 8 | "@minecraft/server": "^1.11.0-beta.1.20.80-stable", 9 | "@minecraft/server-ui": "^1.2.0-beta.1.20.80-stable", 10 | "get-pixels": "^3.3.3" 11 | }, 12 | "devDependencies": { 13 | "@types/node": "^18.14.1", 14 | "fs": "^0.0.1-security", 15 | "vitepress": "^1.0.0-alpha.48", 16 | "vue": "^3.2.47" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/Structs/Math.md: -------------------------------------------------------------------------------- 1 | # Math 2 | 3 | ## Static Methods 4 | 5 | ### Sin 6 | Returns the sine of a number in radians 7 | - Parameters: [`x: Number`](Number) 8 | - Returns: [`Number`](Number) 9 | 10 | ### Cos 11 | Returns the cosine of a number in radians 12 | - Parameters: [`x: Number`](Number) 13 | - Returns: [`Number`](Number) 14 | 15 | ### Tan 16 | Returns the tangent of a number in radians 17 | - Parameters: [`x: Number`](Number) 18 | - Returns: [`Number`](Number) 19 | 20 | ### Floor 21 | Rounds the number downwards to the nearest integer 22 | - Parameters: [`x: Number`](Number) 23 | - Returns: [`Number`](Number) -------------------------------------------------------------------------------- /RP/entity/turtle_controller.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "minecraft:client_entity": { 4 | "description": { 5 | "identifier": "coslang:turtle_controller", 6 | "materials": { 7 | "default": "entity_alphatest" 8 | }, 9 | "textures": { 10 | "default": "textures/entity/turtle_controller" 11 | }, 12 | "geometry": { 13 | "default": "geometry.turtle_controller" 14 | }, 15 | "render_controllers": [ 16 | "controller.render.turtle_controller" 17 | ], 18 | "spawn_egg": { 19 | "base_color": "#000000", 20 | "overlay_color": "#FFFFFF" 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /RP/models/entity/turtle_controller.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.12.0", 3 | "minecraft:geometry": [ 4 | { 5 | "description": { 6 | "identifier": "geometry.turtle_controller", 7 | "texture_width": 16, 8 | "texture_height": 16, 9 | "visible_bounds_width": 2, 10 | "visible_bounds_height": 2.5, 11 | "visible_bounds_offset": [0, 0.75, 0] 12 | }, 13 | "bones": [ 14 | // { 15 | // "name": "bone", 16 | // "pivot": [0, 33, 0], 17 | // "cubes": [ 18 | // {"origin": [-0.5, 0, -0.5], "size": [1, 20, 1], "uv": [0, 0]} 19 | // ] 20 | // } 21 | ] 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /RP/render_controllers/pixel.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.8.0", 3 | "render_controllers": { 4 | "controller.render.pixel": { 5 | "geometry": "Geometry.default", 6 | "materials": [ 7 | { 8 | "*": "Material.default" 9 | } 10 | ], 11 | "textures": [ 12 | "q.property('coslang:color') == 0 ? Texture.white : q.property('coslang:color') == 1 ? Texture.red : q.property('coslang:color') == 2 ? Texture.orange : q.property('coslang:color') == 3 ? Texture.yellow : q.property('coslang:color') == 4 ? Texture.green : q.property('coslang:color') == 5 ? Texture.blue : Texture.purple" 13 | ] 14 | } 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /RP/models/entity/pixel.geo.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.12.0", 3 | "minecraft:geometry": [ 4 | { 5 | "description": { 6 | "identifier": "geometry.pixel", 7 | "texture_width": 16, 8 | "texture_height": 16, 9 | "visible_bounds_width": 2, 10 | "visible_bounds_height": 1.5, 11 | "visible_bounds_offset": [0, 0, 0] 12 | }, 13 | "bones": [ 14 | { 15 | "name": "pos_bone", 16 | "pivot": [0, 0, 0] 17 | }, 18 | { 19 | "name": "size_bone", 20 | "parent": "pos_bone", 21 | "pivot": [0, 0, 0], 22 | "cubes": [ 23 | {"origin": [-8, 0, -8], "size": [1, 1, 1], "uv": [0, 0]} 24 | ] 25 | } 26 | ] 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /RP/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": 2, 3 | "metadata": { 4 | "authors": [ 5 | "Frederox" 6 | ], 7 | "generated_with": { 8 | "bridge": [ 9 | "2.6.0" 10 | ], 11 | "dash": [ 12 | "0.10.8" 13 | ] 14 | } 15 | }, 16 | "header": { 17 | "name": "pack.name", 18 | "description": "pack.description", 19 | "min_engine_version": [ 20 | 1, 21 | 19, 22 | 50 23 | ], 24 | "uuid": "d082e888-c1d0-4737-86ab-c2210a90a669", 25 | "version": [ 26 | 1, 27 | 0, 28 | 0 29 | ] 30 | }, 31 | "modules": [ 32 | { 33 | "type": "resources", 34 | "uuid": "35a927f5-dab6-4b3f-8d4c-289bab38bfc1", 35 | "version": [ 36 | 1, 37 | 0, 38 | 0 39 | ] 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /nodeGenerators/font_points.js: -------------------------------------------------------------------------------- 1 | var getPixels = require("get-pixels") 2 | 3 | getPixels("nodeGenerators/char.png", function(err, pixels) { 4 | if(err) { 5 | console.log(err) 6 | console.log("Bad image path") 7 | return 8 | } 9 | 10 | var points = []; 11 | 12 | for (var x = 0; x < 5; x++) { 13 | for (var y = 0; y < 7; y++) { 14 | const red = pixels.get(x, y, 0); 15 | const green = pixels.get(x, y, 1); 16 | const blue = pixels.get(x, y, 2); 17 | const alpha = pixels.get(x, y, 3); 18 | 19 | var isBlack = (red === 0 && green === 0 && blue === 0 && alpha === 255) 20 | if (isBlack) points.push([x, 6 - y]) 21 | } 22 | } 23 | 24 | console.log(JSON.stringify(points)) 25 | }) -------------------------------------------------------------------------------- /BP/entities/turtle_controller.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.19.50", 3 | "minecraft:entity": { 4 | "description": { 5 | "identifier": "coslang:turtle_controller", 6 | "is_summonable": true 7 | }, 8 | "component_groups": {}, 9 | "components": { 10 | "minecraft:collision_box": { 11 | "height": 0, 12 | "width": 0 13 | }, 14 | "minecraft:nameable": { 15 | "allow_name_tag_renaming": false, 16 | "always_show": true 17 | }, 18 | "minecraft:inventory": { 19 | "inventory_size": 16, 20 | "can_be_siphoned_from": true 21 | }, 22 | "minecraft:damage_sensor": { 23 | "triggers": [ 24 | { 25 | "cause": "all", 26 | "deals_damage": false 27 | } 28 | ] 29 | } 30 | }, 31 | "events": {} 32 | } 33 | } -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | on: 3 | workflow_dispatch: {} 4 | push: 5 | branches: 6 | - master 7 | jobs: 8 | deploy: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | pages: write 12 | id-token: write 13 | environment: 14 | name: github-pages 15 | url: ${{ steps.deployment.outputs.page_url }} 16 | steps: 17 | - uses: actions/checkout@v3 18 | with: 19 | fetch-depth: 0 20 | - uses: actions/setup-node@v3 21 | with: 22 | node-version: 16 23 | cache: npm 24 | - run: npm i 25 | - name: Build 26 | run: npm run docs:build 27 | - uses: actions/configure-pages@v2 28 | - uses: actions/upload-pages-artifact@v1 29 | with: 30 | path: docs/.vitepress/dist 31 | - name: Deploy 32 | id: deployment 33 | uses: actions/deploy-pages@v1 -------------------------------------------------------------------------------- /RP/entity/pixel.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "minecraft:client_entity": { 4 | "description": { 5 | "identifier": "coslang:pixel", 6 | "animations": { 7 | "position": "animation.pixel.position" 8 | }, 9 | "scripts": { 10 | "animate": [ 11 | "position" 12 | ] 13 | }, 14 | "materials": { 15 | "default": "entity_alphatest" 16 | }, 17 | "textures": { 18 | "white": "textures/entity/white", 19 | "red": "textures/entity/red", 20 | "orange": "textures/entity/orange", 21 | "yellow": "textures/entity/yellow", 22 | "green": "textures/entity/green", 23 | "blue": "textures/entity/blue", 24 | "purple": "textures/entity/purple" 25 | }, 26 | "geometry": { 27 | "default": "geometry.pixel" 28 | }, 29 | "render_controllers": [ 30 | "controller.render.pixel" 31 | ], 32 | "spawn_egg": { 33 | "base_color": "#000000", 34 | "overlay_color": "#FFFFFF" 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /RP/models/blocks/turtle.geo.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.12.0", 3 | "minecraft:geometry": [ 4 | { 5 | "description": { 6 | "identifier": "geometry.turtle", 7 | "texture_width": 64, 8 | "texture_height": 64, 9 | "visible_bounds_width": 2, 10 | "visible_bounds_height": 2.5, 11 | "visible_bounds_offset": [0, 0.75, 0] 12 | }, 13 | "bones": [ 14 | { 15 | "name": "bb_main", 16 | "pivot": [0, 0, 0], 17 | "cubes": [ 18 | { 19 | "origin": [-6, 2, -6], 20 | "size": [12, 12, 12], 21 | "uv": { 22 | "north": {"uv": [0, 0], "uv_size": [12, 12]}, 23 | "east": {"uv": [0, 12], "uv_size": [12, 12]}, 24 | "south": {"uv": [12, 0], "uv_size": [12, 12]}, 25 | "west": {"uv": [12, 12], "uv_size": [12, 12]}, 26 | "up": {"uv": [0, 24], "uv_size": [12, 12]}, 27 | "down": {"uv": [24, 12], "uv_size": [12, -12]} 28 | } 29 | } 30 | ] 31 | } 32 | ] 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /docs/.vitepress/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | title: 'CC: Bedrock', 3 | base: '/CC-Bedrock/', 4 | head: [ 5 | ['link', { rel: 'icon', href: '/pack_icon.png' }] 6 | ], 7 | themeConfig: { 8 | logo: "/pack_icon.png", 9 | sidebar: [ 10 | { 11 | text: "About", 12 | link: "/" 13 | }, 14 | { 15 | text: "Structs", 16 | items: [ 17 | { text: 'Math', link: 'Structs/Math' }, 18 | { text: 'Thread', link: 'Structs/Thread' }, 19 | { text: 'PixelBuffer', link: 'Structs/PixelBuffer' }, 20 | { text: 'Display', link: 'Structs/Display' }, 21 | ] 22 | }, 23 | { 24 | text: "Enums", 25 | items: [ 26 | { text: "Color", link: "Enums/Color" } 27 | ] 28 | } 29 | ] 30 | } 31 | } -------------------------------------------------------------------------------- /BP/scripts/structs/Thread.ts: -------------------------------------------------------------------------------- 1 | import { system } from "@minecraft/server"; 2 | import { getNumberLiteral } from "../cosmic/src/Primitives/Number"; 3 | import { NativeFunction } from "../cosmic/src/Struct/NativeFunction"; 4 | import { NativeFunctionHelper } from "../cosmic/src/Struct/NativeFunctionHelper"; 5 | import { StructType } from "../cosmic/src/Struct/StructType"; 6 | 7 | export const delayInTicks = (ticks: number): Promise => { 8 | return new Promise(resolve => { 9 | const id = system.runTimeout(() => { 10 | system.clearRun(id); 11 | resolve() 12 | }, ticks) 13 | }); 14 | } 15 | 16 | export const Thread = new StructType("Thread", [], [ 17 | new NativeFunction("Sleep", async (interpreter, ctx, start, end, args) => { 18 | const helper = new NativeFunctionHelper(interpreter, args, 1, start, end); 19 | const ticks = getNumberLiteral(helper.expectType(0, "Number")); 20 | 21 | await delayInTicks(ticks); 22 | return [null, ctx]; 23 | }) 24 | ]) -------------------------------------------------------------------------------- /RP/models/blocks/display.geo.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.12.0", 3 | "minecraft:geometry": [ 4 | { 5 | "description": { 6 | "identifier": "geometry.display", 7 | "texture_width": 16, 8 | "texture_height": 16, 9 | "visible_bounds_width": 3, 10 | "visible_bounds_height": 2.5, 11 | "visible_bounds_offset": [0, 0.75, 0] 12 | }, 13 | "bones": [ 14 | { 15 | "name": "main", 16 | "pivot": [0, 0, 0], 17 | "cubes": [ 18 | { 19 | "origin": [-8, 0, -7], 20 | "size": [16, 16, 15], 21 | "pivot": [0, 0, 0], 22 | "rotation": [0, 180, 0], 23 | "uv": { 24 | "north": {"uv": [0, 0], "uv_size": [4, 4]}, 25 | "east": {"uv": [4, 0], "uv_size": [3.75, 4]}, 26 | "south": {"uv": [0, 4], "uv_size": [4, 4]}, 27 | "west": {"uv": [4, 4], "uv_size": [3.75, 4]}, 28 | "up": {"uv": [7.75, 0], "uv_size": [4, 3.75]}, 29 | "down": {"uv": [7.75, 7.5], "uv_size": [4, -3.75]} 30 | } 31 | } 32 | ] 33 | } 34 | ] 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Frederox 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /BP/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": 2, 3 | "metadata": { 4 | "authors": [ 5 | "Frederox" 6 | ], 7 | "generated_with": { 8 | "bridge": [ 9 | "2.6.0" 10 | ], 11 | "dash": [ 12 | "0.10.8" 13 | ] 14 | } 15 | }, 16 | "header": { 17 | "name": "pack.name", 18 | "description": "pack.description", 19 | "min_engine_version": [ 20 | 1, 21 | 20, 22 | 32 23 | ], 24 | "uuid": "9f8c728c-b703-4bec-8d6f-887430730884", 25 | "version": [ 26 | 1, 27 | 0, 28 | 0 29 | ] 30 | }, 31 | "modules": [ 32 | { 33 | "type": "data", 34 | "uuid": "499d788d-4048-403e-a929-022ab02212e5", 35 | "version": [ 36 | 1, 37 | 0, 38 | 0 39 | ] 40 | }, 41 | { 42 | "type": "script", 43 | "language": "javascript", 44 | "uuid": "fbf18160-8abe-42cc-ab20-1c511799d3aa", 45 | "entry": "scripts/main.js", 46 | "version": [ 47 | 1, 48 | 0, 49 | 0 50 | ] 51 | } 52 | ], 53 | "dependencies": [ 54 | { 55 | "module_name": "@minecraft/server", 56 | "version": "1.11.0-beta" 57 | }, 58 | { 59 | "module_name": "@minecraft/server-gametest", 60 | "version": "1.0.0-beta" 61 | }, 62 | { 63 | "module_name": "@minecraft/server-ui", 64 | "version": "1.2.0-beta" 65 | } 66 | ] 67 | } -------------------------------------------------------------------------------- /docs/Structs/PixelBuffer.md: -------------------------------------------------------------------------------- 1 | # Pixel Buffer 2 | 3 | ## Static Methods 4 | 5 | ### New 6 | Returns an instance of a pixel buffer 7 | - Parameters: [`width: Number`](Number) [`height: Number`](Number) 8 | - Throws: `Width and Height must be greater than 0` 9 | - Throws: `Width and Height must be divisible by 16` 10 | - Returns: [`PixelBuffer`](PixelBuffer.md) 11 | 12 | ## Instance Methods 13 | 14 | ### DrawPixel 15 | Sets a single pixel on screen 16 | - Parameters: [`x: Number`](Number) [`y: Number`](Number) [`color: Color`](./../Enums/Color.md) 17 | - Throws: `Will throw if point is not in screen bounds` 18 | - Returns: `void` 19 | 20 | ### DrawLine 21 | Draws a line between two points 22 | - Parameters: [`x1: Number`](Number) [`y1: Number`](Number) [`x2: Number`](Number) [`y2: Number`](Number) [`color: Color`](../Enums/Color.md) 23 | - Throws: `Will throw if points are not in screen bounds` 24 | - Returns: `void` 25 | 26 | ### DrawCircle 27 | Draws a circle at a point 28 | - Parameters: [`x: Number`](Number) [`y: Number`](Number) [`radius: Number`](Number) [`fill: Boolean`](Number) [`color: Color`](../Enums/Color.md) 29 | - Returns: `void` 30 | 31 | ### DrawText 32 | Draws text from the top left corner of the screen, will wrap around lines 33 | - Parameters: [`text: String`](String) 34 | - Returns: `void` -------------------------------------------------------------------------------- /BP/scripts/structs/Math.ts: -------------------------------------------------------------------------------- 1 | import { getNumberLiteral } from "../cosmic/src/Primitives/Number"; 2 | import { NativeFunction } from "../cosmic/src/Struct/NativeFunction"; 3 | import { NativeFunctionHelper } from "../cosmic/src/Struct/NativeFunctionHelper"; 4 | import { StructType } from "../cosmic/src/Struct/StructType"; 5 | 6 | export const MathStruct = new StructType("Math", [], [ 7 | new NativeFunction("Sin", async (interpreter, ctx, start, end, args) => { 8 | const helper = new NativeFunctionHelper(interpreter, args, 1, start, end); 9 | const value = Math.sin(getNumberLiteral(helper.expectType(0, "Number"))); 10 | return interpreter.number({ value }, ctx); 11 | }), 12 | 13 | new NativeFunction("Cos", async (interpreter, ctx, start, end, args) => { 14 | const helper = new NativeFunctionHelper(interpreter, args, 1, start, end); 15 | const value = Math.cos(getNumberLiteral(helper.expectType(0, "Number"))); 16 | return interpreter.number({ value }, ctx); 17 | }), 18 | 19 | new NativeFunction("Tan", async (interpreter, ctx, start, end, args) => { 20 | const helper = new NativeFunctionHelper(interpreter, args, 1, start, end); 21 | const value = Math.tan(getNumberLiteral(helper.expectType(0, "Number"))); 22 | return interpreter.number({ value }, ctx); 23 | }), 24 | 25 | new NativeFunction("Floor", async (interpreter, ctx, start, end, args) => { 26 | const helper = new NativeFunctionHelper(interpreter, args, 1, start, end); 27 | const value = Math.floor(getNumberLiteral(helper.expectType(0, "Number"))); 28 | return interpreter.number({ value }, ctx); 29 | }) 30 | ]) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CC:BE 2 | 3 | | ![image](https://user-images.githubusercontent.com/69014593/229221307-2523e933-1ee4-44bb-b582-bb0535f33afc.png) | ![image](https://user-images.githubusercontent.com/69014593/229221347-cf41072d-1e11-45cb-ba65-069c518e39ee.png) | 4 | | --------------------------------------- | --------------------------------------- | 5 | | ![image](https://user-images.githubusercontent.com/69014593/229221371-4cb3cba8-1a40-43e2-a975-9e2b2e8e49a0.png) | ![image](https://user-images.githubusercontent.com/69014593/229221948-58b2e0f8-0dde-413a-82ef-e738d332da08.png) | 6 | 7 | 8 | A recreation of the Minecraft Java mod, Computer Craft for Minecraft Bedrock. 9 | 10 | The add-on has been built around a custom programming language called Cosmic, which has been made specifically for this project. 11 | 12 | ## Important 13 | 14 | The add-on is based on cosmic which is my first full scale language, this means you are likely to run into niche issues and bugs with the language. The language is based on a mix of rust and a C like syntax. 15 | 16 | ## Learning Cosmic 17 | 18 | There are example programs in the GitHub Repository under the `examples` directory. Documentation for the language also exists at https://frederoxdev.github.io/CC-Bedrock/ which lists all of the built-in Structs and Enums in CC:BE 19 | 20 | ## Cosmic OS 21 | 22 | The computers in the add-on are running `Cosmic OS` which is the shell interface used for interacting with them. To connect with a computer simply click on it, and type in chat using `>` as a prefix to run commands. Run `>help` for more information. 23 | 24 | ## Credits 25 | 26 | Cosmic Logo - The logo which is being used for cosmic was designed by [OuterCloudStudio](https://github.com/outercloudstudio) 27 | -------------------------------------------------------------------------------- /BP/blocks/turtle.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.19.50", 3 | "minecraft:block": { 4 | "description": { 5 | "identifier": "coslang:turtle", 6 | "properties": { 7 | "coslang:rotation": [ 8 | 0, 9 | 1, 10 | 2, 11 | 3 12 | ] 13 | } 14 | }, 15 | "permutations": [ 16 | { 17 | "condition": "query.block_property('coslang:rotation') == 0", 18 | "components": { 19 | "minecraft:rotation": [ 20 | 0, 21 | 270, 22 | 0 23 | ] 24 | } 25 | }, 26 | { 27 | "condition": "query.block_property('coslang:rotation') == 1", 28 | "components": { 29 | "minecraft:rotation": [ 30 | 0, 31 | 360, 32 | 0 33 | ] 34 | } 35 | }, 36 | { 37 | "condition": "query.block_property('coslang:rotation') == 2", 38 | "components": { 39 | "minecraft:rotation": [ 40 | 0, 41 | 90, 42 | 0 43 | ] 44 | } 45 | }, 46 | { 47 | "condition": "query.block_property('coslang:rotation') == 3", 48 | "components": { 49 | "minecraft:rotation": [ 50 | 0, 51 | 180, 52 | 0 53 | ] 54 | } 55 | } 56 | ], 57 | "components": { 58 | "minecraft:geometry": "geometry.turtle", 59 | "minecraft:material_instances": { 60 | "*": { 61 | "texture": "coslang_turtle", 62 | "render_method": "alpha_test" 63 | } 64 | }, 65 | "minecraft:collision_box": { 66 | "origin": [ 67 | -6, 68 | 2, 69 | -6 70 | ], 71 | "size": [ 72 | 12, 73 | 12, 74 | 12 75 | ] 76 | }, 77 | "minecraft:selection_box": { 78 | "origin": [ 79 | -6, 80 | 2, 81 | -6 82 | ], 83 | "size": [ 84 | 12, 85 | 12, 86 | 12 87 | ] 88 | } 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /examples/pong.cos: -------------------------------------------------------------------------------- 1 | import Display; 2 | import PixelBuffer; 3 | import Thread; 4 | import Math; 5 | import Color; 6 | 7 | fn Main() { 8 | let screenWidth = 48; 9 | let screenHeight = 32; 10 | let display = Display::Connect(-1, -59, 0, 3, 2); 11 | 12 | let paddleHeight = 4; 13 | 14 | let ballRadius = 1; 15 | let ballX = screenWidth / 2; 16 | let ballY = screenHeight / 2; 17 | let ballVelocityY = 2; 18 | let ballVelocityX = 2; 19 | 20 | let ballColor = 0; 21 | 22 | let leftPaddleY = screenHeight / 2; 23 | let rightPaddleY = screenHeight / 2; 24 | 25 | while (true) { 26 | ballX = ballX + ballVelocityX; 27 | ballY = ballY + ballVelocityY; 28 | 29 | if (ballY >= screenHeight - 2 || ballY <= 2) ballVelocityY = ballVelocityY * -1; 30 | if (ballX >= screenWidth - 2 || ballX <= 2) ballVelocityX = ballVelocityX * -1; 31 | 32 | if (ballVelocityX > 0) { 33 | if (rightPaddleY > ballY) rightPaddleY = rightPaddleY - 2; 34 | if (rightPaddleY < ballY) rightPaddleY = rightPaddleY + 2; 35 | } 36 | 37 | if (ballVelocityX < 0) { 38 | if (leftPaddleY > ballY) leftPaddleY = leftPaddleY - 2; 39 | if (leftPaddleY < ballY) leftPaddleY = leftPaddleY + 2; 40 | } 41 | 42 | let buffer = PixelBuffer::New(screenWidth, screenHeight); 43 | buffer.DrawLine(0, leftPaddleY - paddleHeight, 0, leftPaddleY + paddleHeight, 1); 44 | buffer.DrawLine(1, leftPaddleY - paddleHeight, 1, leftPaddleY + paddleHeight, 1); 45 | 46 | buffer.DrawLine(screenWidth - 1, rightPaddleY - paddleHeight, screenWidth - 1, rightPaddleY + paddleHeight, 2); 47 | buffer.DrawLine(screenWidth - 2, rightPaddleY - paddleHeight, screenWidth - 2, rightPaddleY + paddleHeight, 2); 48 | 49 | buffer.DrawCircle(ballX, ballY, ballRadius, true, ballColor); 50 | display.DrawBuffer(buffer); 51 | Thread::Sleep(1); 52 | } 53 | } -------------------------------------------------------------------------------- /nodeGenerators/pixel_entity.js: -------------------------------------------------------------------------------- 1 | const pixel = { 2 | "format_version": "1.19.50", 3 | "minecraft:entity": { 4 | "description": { 5 | "identifier": "coslang:pixel", 6 | "is_spawnable": true, 7 | "is_summonable": true, 8 | "is_experimental": false, 9 | "properties": { 10 | "coslang:x": { 11 | "range": [ 12 | 0, 13 | 15 14 | ], 15 | "client_sync": true, 16 | "default": 0, 17 | "type": "int" 18 | }, 19 | "coslang:x_size": { 20 | "range": [ 21 | 1, 22 | 16 23 | ], 24 | "client_sync": true, 25 | "default": 1, 26 | "type": "int" 27 | }, 28 | "coslang:y": { 29 | "range": [ 30 | 0, 31 | 15 32 | ], 33 | "client_sync": true, 34 | "default": 0, 35 | "type": "int" 36 | }, 37 | "coslang:y_size": { 38 | "range": [ 39 | 1, 40 | 16 41 | ], 42 | "client_sync": true, 43 | "default": 1, 44 | "type": "int" 45 | }, 46 | "coslang:color": { 47 | "type": "int", 48 | "range": [0, 6], 49 | "default": 0, 50 | "client_sync": true 51 | } 52 | } 53 | }, 54 | "component_groups": { 55 | "coslang:despawn": { 56 | "minecraft:instant_despawn": {} 57 | } 58 | }, 59 | "components": { 60 | "minecraft:collision_box": { 61 | "height": 0, 62 | "width": 0 63 | } 64 | }, 65 | "events": { 66 | "coslang:despawn": { 67 | "add": { 68 | "component_groups": [ 69 | "coslang:despawn" 70 | ] 71 | } 72 | } 73 | } 74 | } 75 | } 76 | 77 | for (var x = 0; x < 16; x++) { 78 | for (var y = 0; y < 16; y++) { 79 | pixel["minecraft:entity"].events[`coslang:set_${x}_${y}`] = { 80 | "set_property": { "coslang:x": x, "coslang:y": y } 81 | } 82 | } 83 | } 84 | 85 | for (var x = 1; x < 17; x++) { 86 | for (var y = 1; y < 17; y++) { 87 | pixel["minecraft:entity"].events[`coslang:size_${x}_${y}`] = { 88 | "set_property": { "coslang:x_size": x, "coslang:y_size": y } 89 | } 90 | } 91 | } 92 | 93 | for (var i = 0; i < 7; i++) { 94 | pixel["minecraft:entity"].events[`coslang:set_color_${i}`] = { 95 | "set_property": { "coslang:color": i } 96 | } 97 | } 98 | 99 | console.log(JSON.stringify(pixel)) -------------------------------------------------------------------------------- /BP/scripts/Turtles.ts: -------------------------------------------------------------------------------- 1 | import { ItemStartUseOnAfterEvent, PlayerBreakBlockAfterEvent, PlayerPlaceBlockAfterEvent, Vector, world } from "@minecraft/server"; 2 | import { nextTurtleIdProp, turtleIdProp, connectedTurtleProp, turtleFilesProp } from "./Properties"; 3 | 4 | export const OnTurtlePlace = (e: PlayerPlaceBlockAfterEvent) => { 5 | if (e.block.typeId !== "coslang:turtle") return; 6 | const controller = e.dimension.spawnEntity("coslang:turtle_controller", e.block.location); 7 | const nextId = (world.getDynamicProperty(nextTurtleIdProp) as number) ?? 0; 8 | controller.setDynamicProperty(turtleIdProp, nextId + 1); 9 | // Set default value 10 | controller.setDynamicProperty(turtleFilesProp, 130000) 11 | 12 | const midPos = { 13 | x: e.block.location.x + 0.5, 14 | y: e.block.location.y, 15 | z: e.block.location.z + 0.5 16 | } 17 | controller.teleport(midPos, { dimension: controller.dimension, facingLocation: new Vector(0, 0, 0), keepVelocity: false }) 18 | world.setDynamicProperty(nextTurtleIdProp, nextId + 1); 19 | controller.nameTag = `Turtle: ${nextId + 1}`; 20 | } 21 | 22 | export const OnTurtleBreak = (e: PlayerBreakBlockAfterEvent) => { 23 | if (e.brokenBlockPermutation.type.id !== "coslang:turtle") return; 24 | const turtles = e.dimension.getEntitiesAtBlockLocation(e.block.location) 25 | .filter(entity => entity.typeId == "coslang:turtle_controller"); 26 | 27 | turtles.map(turtle => turtle.kill()) 28 | } 29 | 30 | export const OnTurtleInteract = (e: ItemStartUseOnAfterEvent) => { 31 | const dimension = e.source.dimension 32 | const block = dimension.getBlock(e.block.location); 33 | if (block?.typeId != "coslang:turtle") return; 34 | 35 | const turtles = dimension.getEntitiesAtBlockLocation(e.block.location) 36 | .filter(entity => entity.typeId == "coslang:turtle_controller"); 37 | 38 | if (turtles.length < 1) return console.log("Unable to find turtle controller!"); 39 | if (turtles.length > 1) return console.log("Multiple turtle controllers found!"); 40 | 41 | const turtle = turtles[0]; 42 | const turtleID = turtle.getDynamicProperty(turtleIdProp) as number 43 | e.source.setDynamicProperty(connectedTurtleProp, turtleID!); 44 | world.sendMessage(`Turtle ${turtleID} is now connected!`) 45 | } -------------------------------------------------------------------------------- /RP/ui/server_form.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": "server_form", 3 | "generated_contents": { 4 | "factory": { 5 | "control_ids": { 6 | "input": "@server_form.multiline_input" 7 | } 8 | } 9 | }, 10 | "third_party_server_screen@server_form.base_screen": { 11 | "$screen_content": "server_form.main_screen_content", 12 | "button_mappings": [ 13 | { 14 | "from_button_id": "button.menu_cancel", 15 | "to_button_id": "button.menu_exit", 16 | "mapping_type": "global" 17 | } 18 | ] 19 | }, 20 | "base_screen@common.base_screen": { 21 | "$screen_animations|default": [], 22 | "$is_full_screen_layout|default": true 23 | }, 24 | "multiline_input@server_form.option_text_edit": { 25 | "$option_label": "#custom_text", 26 | "$option_place_holder_text": "#custom_placeholder_text", 27 | "$text_edit_box_placeholder_content_binding_name": "$option_place_holder_text", 28 | "$text_edit_box_placeholder_content_binding_type": "collection", 29 | "$text_edit_box_grid_collection_name": "custom_form", 30 | "$max_text_edit_length": 16777216, 31 | "$text_edit_box_content_binding_type": "collection", 32 | "$text_edit_box_content_binding_name": "#custom_input_text", 33 | "$option_binding_name": "#custom_input_text", 34 | "$text_box_enabled_binding_name": "#custom_input_enabled", 35 | "$text_box_name": "custom_input", 36 | "$label_bindings": [ 37 | { 38 | "binding_name": "#custom_text", 39 | "binding_type": "collection", 40 | "binding_collection_name": "custom_form" 41 | } 42 | ] 43 | }, 44 | "option_text_edit@settings_common.option_generic": { 45 | "$option_place_holder_text|default": "", 46 | "$max_text_edit_length|default": 30, 47 | "$control_name": "server_form.option_text_edit_control" 48 | }, 49 | "option_text_edit_control@common.scrollable_multiline_text_edit_box": { 50 | "$option_text_edit_control_size|default": [ 51 | "100%", 52 | "100px" 53 | ], 54 | "size": "$option_text_edit_control_size", 55 | "max_length": "$max_text_edit_length", 56 | "$text_edit_box_content_binding_name": "$option_binding_name", 57 | "$text_edit_box_binding_collection_name": "$option_binding_name", 58 | "$text_edit_box_binding_type": "global", 59 | "$text_box_enabled_binding_name": "$option_enabled_binding_name", 60 | "enabled": "$enabled", 61 | "$place_holder_text": "$option_place_holder_text", 62 | "$text_box_tts_header": "$option_label", 63 | "$tts_override_control_value|default": " ", 64 | "tts_override_control_value": "$tts_override_control_value", 65 | "variables": [ 66 | { 67 | "requires": "(not $option_enabled_binding_name or not $enabled)", 68 | "$text_box_enabled_binding_name": "#not_data_bound", 69 | "$text_edit_box_enabled_binding_type": "none" 70 | } 71 | ] 72 | } 73 | } -------------------------------------------------------------------------------- /BP/scripts/run.ts: -------------------------------------------------------------------------------- 1 | import { Parser } from "./cosmic/src/Parser"; 2 | import { Tokenize } from "./cosmic/src/Lexer"; 3 | import { Entity, world } from "@minecraft/server" 4 | import { Context } from "./cosmic/src/Context"; 5 | import { NativeFunction } from "./cosmic/src/Struct/NativeFunction"; 6 | import { StructInstance } from "./cosmic/src/Struct/StructInstance"; 7 | import { Interpreter } from "./cosmic/src/Interpreter"; 8 | import { Display } from "./structs/Display"; 9 | import { PixelBuffer } from "./structs/PixelBuffer"; 10 | import { Thread } from "./structs/Thread"; 11 | import { MathStruct } from "./structs/Math"; 12 | import { Color } from "./enums/Color"; 13 | 14 | const logError = (code: string, message: string, startIdx: number, endIdx: number) => { 15 | const lineStart = code.lastIndexOf("\n", startIdx) + 1; 16 | const line = code.substring(lineStart, endIdx); 17 | const lineNum = code.substring(0, startIdx).split("\n").length; 18 | const colNum = startIdx - lineStart + 1; 19 | 20 | world.sendMessage(`\n${lineNum} | ` + line); 21 | world.sendMessage(`${" ".repeat(lineNum.toString().length + 3)}` + "§4" + `${" ".repeat(startIdx - lineStart)}${"^".repeat(endIdx - startIdx)}`); 22 | world.sendMessage(message + `\n§7 at line: ${lineNum}, column: ${colNum}`) 23 | } 24 | 25 | export class TurtleInterpreter { 26 | turtleEntity: Entity; 27 | 28 | constructor(turtleEntity: Entity) { 29 | this.turtleEntity = turtleEntity; 30 | } 31 | 32 | runScript = async (input: string) => { 33 | const tokens = Tokenize(input) 34 | if (!Array.isArray(tokens)) { 35 | logError(input, `${tokens.type}: ${tokens.message}`, tokens.start, tokens.end); 36 | return; 37 | } 38 | 39 | const parser = new Parser(tokens, input); 40 | const [ast, parseError]: any = parser.parse(); 41 | // world.sendMessage(`${ast} ${parseError}`) 42 | 43 | if (parseError !== null) { 44 | world.sendMessage("Parse Error") 45 | logError(input, parser.errMessage, parser.errStart, parser.errEnd); 46 | return; 47 | } 48 | 49 | const globals = new Context() 50 | globals.setSymbol("log", new NativeFunction("log", async (interpreter, ctx, start, end, args) => { 51 | var args = args.map((arg: any) => { 52 | if (arg instanceof StructInstance) { 53 | return arg.selfCtx.getProtected("value") 54 | } else throw new Error("Cannot log") 55 | }) 56 | world.sendMessage("> " + args.join(" ")) 57 | 58 | return [null, ctx]; 59 | })) 60 | 61 | const interpreter = new Interpreter(input, [ 62 | Display, 63 | PixelBuffer, 64 | Thread, 65 | MathStruct 66 | ], [ 67 | Color 68 | ]) 69 | 70 | try { 71 | await interpreter.findTraverseFunc(ast, globals) 72 | world.sendMessage("Finished executing, with 0 errors!") 73 | } 74 | catch (e) { 75 | if (interpreter.errMessage === "") { 76 | world.sendMessage(`${e}, ${e.stack}`) 77 | } 78 | else logError(input, interpreter.errMessage, interpreter.errStart, interpreter.errEnd) 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /docs/.vitepress/cache/deps_temp_c3414293/vitepress___@vue_devtools-api.js: -------------------------------------------------------------------------------- 1 | // node_modules/@vue/devtools-api/lib/esm/env.js 2 | function getDevtoolsGlobalHook() { 3 | return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__; 4 | } 5 | function getTarget() { 6 | return typeof navigator !== "undefined" && typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {}; 7 | } 8 | var isProxyAvailable = typeof Proxy === "function"; 9 | 10 | // node_modules/@vue/devtools-api/lib/esm/const.js 11 | var HOOK_SETUP = "devtools-plugin:setup"; 12 | var HOOK_PLUGIN_SETTINGS_SET = "plugin:settings:set"; 13 | 14 | // node_modules/@vue/devtools-api/lib/esm/time.js 15 | var supported; 16 | var perf; 17 | function isPerformanceSupported() { 18 | var _a; 19 | if (supported !== void 0) { 20 | return supported; 21 | } 22 | if (typeof window !== "undefined" && window.performance) { 23 | supported = true; 24 | perf = window.performance; 25 | } else if (typeof global !== "undefined" && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) { 26 | supported = true; 27 | perf = global.perf_hooks.performance; 28 | } else { 29 | supported = false; 30 | } 31 | return supported; 32 | } 33 | function now() { 34 | return isPerformanceSupported() ? perf.now() : Date.now(); 35 | } 36 | 37 | // node_modules/@vue/devtools-api/lib/esm/proxy.js 38 | var ApiProxy = class { 39 | constructor(plugin, hook) { 40 | this.target = null; 41 | this.targetQueue = []; 42 | this.onQueue = []; 43 | this.plugin = plugin; 44 | this.hook = hook; 45 | const defaultSettings = {}; 46 | if (plugin.settings) { 47 | for (const id in plugin.settings) { 48 | const item = plugin.settings[id]; 49 | defaultSettings[id] = item.defaultValue; 50 | } 51 | } 52 | const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`; 53 | let currentSettings = Object.assign({}, defaultSettings); 54 | try { 55 | const raw = localStorage.getItem(localSettingsSaveId); 56 | const data = JSON.parse(raw); 57 | Object.assign(currentSettings, data); 58 | } catch (e) { 59 | } 60 | this.fallbacks = { 61 | getSettings() { 62 | return currentSettings; 63 | }, 64 | setSettings(value) { 65 | try { 66 | localStorage.setItem(localSettingsSaveId, JSON.stringify(value)); 67 | } catch (e) { 68 | } 69 | currentSettings = value; 70 | }, 71 | now() { 72 | return now(); 73 | } 74 | }; 75 | if (hook) { 76 | hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => { 77 | if (pluginId === this.plugin.id) { 78 | this.fallbacks.setSettings(value); 79 | } 80 | }); 81 | } 82 | this.proxiedOn = new Proxy({}, { 83 | get: (_target, prop) => { 84 | if (this.target) { 85 | return this.target.on[prop]; 86 | } else { 87 | return (...args) => { 88 | this.onQueue.push({ 89 | method: prop, 90 | args 91 | }); 92 | }; 93 | } 94 | } 95 | }); 96 | this.proxiedTarget = new Proxy({}, { 97 | get: (_target, prop) => { 98 | if (this.target) { 99 | return this.target[prop]; 100 | } else if (prop === "on") { 101 | return this.proxiedOn; 102 | } else if (Object.keys(this.fallbacks).includes(prop)) { 103 | return (...args) => { 104 | this.targetQueue.push({ 105 | method: prop, 106 | args, 107 | resolve: () => { 108 | } 109 | }); 110 | return this.fallbacks[prop](...args); 111 | }; 112 | } else { 113 | return (...args) => { 114 | return new Promise((resolve) => { 115 | this.targetQueue.push({ 116 | method: prop, 117 | args, 118 | resolve 119 | }); 120 | }); 121 | }; 122 | } 123 | } 124 | }); 125 | } 126 | async setRealTarget(target) { 127 | this.target = target; 128 | for (const item of this.onQueue) { 129 | this.target.on[item.method](...item.args); 130 | } 131 | for (const item of this.targetQueue) { 132 | item.resolve(await this.target[item.method](...item.args)); 133 | } 134 | } 135 | }; 136 | 137 | // node_modules/@vue/devtools-api/lib/esm/index.js 138 | function setupDevtoolsPlugin(pluginDescriptor, setupFn) { 139 | const descriptor = pluginDescriptor; 140 | const target = getTarget(); 141 | const hook = getDevtoolsGlobalHook(); 142 | const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy; 143 | if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) { 144 | hook.emit(HOOK_SETUP, pluginDescriptor, setupFn); 145 | } else { 146 | const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null; 147 | const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || []; 148 | list.push({ 149 | pluginDescriptor: descriptor, 150 | setupFn, 151 | proxy 152 | }); 153 | if (proxy) 154 | setupFn(proxy.proxiedTarget); 155 | } 156 | } 157 | export { 158 | isPerformanceSupported, 159 | now, 160 | setupDevtoolsPlugin 161 | }; 162 | //# sourceMappingURL=vitepress___@vue_devtools-api.js.map 163 | -------------------------------------------------------------------------------- /BP/scripts/structs/Display.ts: -------------------------------------------------------------------------------- 1 | import { Entity, Vector3, world } from "@minecraft/server"; 2 | import { getNumberLiteral } from "../cosmic/src/Primitives/Number"; 3 | import { NativeFunction } from "../cosmic/src/Struct/NativeFunction"; 4 | import { NativeFunctionHelper } from "../cosmic/src/Struct/NativeFunctionHelper"; 5 | import { StructInstance } from "../cosmic/src/Struct/StructInstance"; 6 | import { StructType } from "../cosmic/src/Struct/StructType"; 7 | console.log = console.warn 8 | 9 | interface PixelData { 10 | x: number, 11 | y: number, 12 | width: number, 13 | height: number, 14 | color: number, 15 | screenX: number, 16 | screenY: number, 17 | } 18 | 19 | const generateLargeDisplayCommands = (pixelBuffer: number[], origin: Vector3, screenWidth: number, screenHeight: number): PixelData[] => { 20 | const commands: PixelData[] = []; 21 | 22 | for (var screenXOffset = 0; screenXOffset < screenWidth; screenXOffset++) { 23 | for (var screenYOffset = 0; screenYOffset < screenHeight; screenYOffset++) { 24 | const screenBuffer: number[] = [] 25 | 26 | // Create a smaller buffer which is 16x16 for that specific screen 27 | for (var i = 0; i < 256; i++) { 28 | const x = (screenXOffset * 16) + i % 16; 29 | const y = (screenYOffset * 16) + Math.floor(i / 16); 30 | screenBuffer.push(pixelBuffer[y * (screenWidth * 16) + x]); 31 | } 32 | 33 | commands.push(...generateDisplayCommands(screenBuffer, screenXOffset, screenYOffset)) 34 | } 35 | } 36 | 37 | return commands; 38 | } 39 | 40 | const generateDisplayCommands = (pixelBuffer: number[], screenX: number, screenY: number): PixelData[] => { 41 | const commands: PixelData[] = []; 42 | var hasDrawn = new Array(256).fill(false); 43 | 44 | const getIdx = (x: number, y: number) => { 45 | return y * 16 + x; 46 | } 47 | 48 | for (var x = 0; x < 16; x++) { 49 | for (var y = 0; y < 16; y++) { 50 | const idx = getIdx(x, y); 51 | if (pixelBuffer[idx] == -1) continue; 52 | if (hasDrawn[idx]) continue; 53 | 54 | var expandY = 0; 55 | while (y + expandY + 1 < 16 && pixelBuffer[getIdx(x, expandY + 1)] === pixelBuffer[idx]) expandY++; 56 | 57 | var expandX = 0; 58 | 59 | for (var setX = x; setX <= x + expandX; setX++) { 60 | for (var setY = y; setY <= y + expandY; setY++) { 61 | hasDrawn[getIdx(setX, setY)] = true; 62 | } 63 | } 64 | 65 | commands.push({ 66 | x, 67 | y, 68 | width: 1 + expandX, 69 | height: 1 + expandY, 70 | color: pixelBuffer[idx], 71 | screenX, 72 | screenY 73 | }); 74 | } 75 | } 76 | 77 | return commands; 78 | } 79 | 80 | export const Display: StructType = new StructType("Display", [], [ 81 | new NativeFunction("Connect", async (interpreter, ctx, start, end, args) => { 82 | const helper = new NativeFunctionHelper(interpreter, args, 5, start, end); 83 | const instance = new StructInstance(Display); 84 | const x = getNumberLiteral(helper.expectType(0, "Number")); 85 | const y = getNumberLiteral(helper.expectType(1, "Number")); 86 | const z = getNumberLiteral(helper.expectType(2, "Number")); 87 | 88 | const width = getNumberLiteral(helper.expectType(3, "Number")); 89 | const height = getNumberLiteral(helper.expectType(4, "Number")); 90 | 91 | instance.selfCtx.setProtected("screenPosition", [x, y, z]); 92 | instance.selfCtx.setProtected("screenSize", [width, height]); 93 | return [instance, ctx]; 94 | }), 95 | 96 | new NativeFunction("DrawBuffer", async (interpreter, ctx, start, end, args) => { 97 | const helper = new NativeFunctionHelper(interpreter, args, 1, start, end); 98 | const buffer = helper.expectType(0, "PixelBuffer") 99 | const pixelBuffer = buffer.selfCtx.getProtected("pixelBuffer"); 100 | const bufferWidth = buffer.selfCtx.getProtected("bufferWidth"); 101 | const bufferHeight = buffer.selfCtx.getProtected("bufferHeight"); 102 | var selfRef = ctx.stack.pop().node as StructInstance; 103 | 104 | const position = selfRef.selfCtx.getProtected<[number, number, number]>("screenPosition"); 105 | const [width, height] = selfRef.selfCtx.getProtected<[number, number]>("screenSize"); 106 | const blockLocation = { x: position[0], y: position[1], z: position[2] } 107 | 108 | if (width * 16 != bufferWidth || height * 16 != bufferHeight) throw interpreter.runtimeErrorCode( 109 | `Incorrect size for buffer expected (${width * 16} x ${height * 16}), instead got (${bufferWidth} x ${bufferHeight})`, 110 | start, end 111 | ) 112 | 113 | const overworld = world.getDimension("overworld") 114 | 115 | for (var screenX = 0; screenX < width; screenX++) { 116 | for (var screenY = 0; screenY < height; screenY++) { 117 | const screenLoc = { x: blockLocation.x + screenX, y: blockLocation.y + screenY, z: blockLocation.z } 118 | overworld.getEntitiesAtBlockLocation(screenLoc) 119 | .filter(e => e.typeId == "coslang:pixel") 120 | .forEach(e => { 121 | e.triggerEvent("coslang:despawn") 122 | }) 123 | } 124 | } 125 | 126 | const pixels = generateLargeDisplayCommands(pixelBuffer, blockLocation, width, height) 127 | const pixelEntities: Entity[] = [] 128 | 129 | for (var i = 0; i < pixels.length; i++) { 130 | const pixel = pixels[i]; 131 | const blockCorner = { 132 | x: blockLocation.x + 0.5 + pixel.screenX, 133 | y: blockLocation.y + pixel.screenY, 134 | z: blockLocation.z + 0.5 135 | } 136 | const pixelEntity = overworld.spawnEntity(`coslang:pixel`, blockCorner); 137 | 138 | if (pixel.color != 0) { 139 | pixelEntity.triggerEvent(`coslang:set_color_${pixel.color}`) 140 | } 141 | 142 | if (pixel.width != 0 && pixel.height != 0) { 143 | pixelEntity.triggerEvent(`coslang:size_${pixel.width}_${pixel.height}`) 144 | } 145 | 146 | pixelEntities.push(pixelEntity); 147 | } 148 | 149 | return [null, ctx]; 150 | }) 151 | ]); -------------------------------------------------------------------------------- /BP/scripts/FileSystem.ts: -------------------------------------------------------------------------------- 1 | import { Player, system } from "@minecraft/server" 2 | import { FormCancelationReason, ModalFormData, ModalFormResponse } from "@minecraft/server-ui" 3 | 4 | export interface Directory { 5 | name: string 6 | type: "Directory" 7 | directories: Directory[] 8 | files: File[] 9 | } 10 | 11 | export interface File { 12 | name: string 13 | type: "File" 14 | content: string 15 | } 16 | 17 | export interface FileError { 18 | type: "FileError", 19 | error: string 20 | } 21 | 22 | console.warn = console.log 23 | 24 | export namespace FileSystem { 25 | export const directoryTree = (directory: Directory, depth: number = 0): string => { 26 | let text = `§3${directory.name}/§r`; 27 | 28 | for (var i = 0; i < directory.directories.length; i++) { 29 | const dir = directory.directories[i]; 30 | const pipe = (i == directory.directories.length - 1 && directory.files.length == 0) ? "└" : "├"; 31 | text += `\n${" │ ".repeat(depth)} ${pipe} ${directoryTree(dir, depth + 1)}` 32 | } 33 | 34 | for (var i = 0; i < directory.files.length; i++) { 35 | const pipe = i == directory.files.length - 1 ? "└" : "├"; 36 | text += `\n${" │ ".repeat(depth)} ${pipe} ${directory.files[i].name}` 37 | } 38 | 39 | if (depth == 0) return `\n${text}` 40 | else return text; 41 | } 42 | 43 | export const resolveDirectory = (root: Directory, path: string[]): Directory | FileError => { 44 | var current: Directory = root; 45 | 46 | for (var i = 0; i < path.length; i++) { 47 | const newPath = current.directories.find(dir => dir.name == path[i]) 48 | if (newPath === undefined) return { type: "FileError", error: `Directory §3${current.name}§r does not contain §3${path[i]}§r` } 49 | current = newPath; 50 | } 51 | 52 | return current; 53 | } 54 | 55 | export const makeDirectory = (dir: Directory, path: string[], dirName: string): Directory | FileError => { 56 | path = [...path] 57 | if (path.length > 0) { 58 | const index = dir.directories.findIndex(f => f.name == path.shift()); 59 | const result = makeDirectory(dir.directories[index], path, dirName) 60 | if (result.type == "FileError") return result; 61 | dir.directories[index] = result; 62 | return dir 63 | } 64 | 65 | // Check it doesnt already exist 66 | if (dir.directories.find(f => f.name == dirName)) return { type: "FileError", error: `${dirName} already exists!` }; 67 | 68 | // Create the new directory and return an instance 69 | dir.directories.push({ 70 | type: "Directory", 71 | name: dirName, 72 | files: [], 73 | directories: [] 74 | }); 75 | return dir; 76 | } 77 | 78 | export const deleteDirectory = (dir: Directory, path: string[], dirName: string): Directory | FileError => { 79 | path = [...path] 80 | if (path.length > 0) { 81 | const index = dir.directories.findIndex(f => f.name == path.shift()); 82 | const result = deleteDirectory(dir.directories[index], path, dirName) 83 | if (result.type == "FileError") return result; 84 | dir.directories[index] = result; 85 | return dir 86 | } 87 | 88 | const dirIndex = dir.directories.findIndex(f => f.name == dirName); 89 | if (dirIndex == -1) return { type: "FileError", error: `directory ${dirName} does not exist!` }; 90 | dir.directories.splice(dirIndex, 1) 91 | return dir; 92 | } 93 | 94 | export const writeFile = (dir: Directory, path: string[], fileName: string, content: string): Directory | FileError => { 95 | path = [...path] 96 | if (path.length > 0) { 97 | const index = dir.directories.findIndex(f => f.name == path.shift()); 98 | const result = writeFile(dir.directories[index], path, fileName, content) 99 | if (result.type == "FileError") return result; 100 | dir.directories[index] = result; 101 | return dir 102 | } 103 | 104 | const fileIdx = dir.files.findIndex(f => f.name == fileName); 105 | if (fileIdx == -1) return { type: "FileError", error: `${fileIdx} does not exist!` }; 106 | 107 | dir.files[fileIdx].content = content; 108 | return dir; 109 | } 110 | 111 | export const readFile = (dir: Directory, path: string[], fileName: string): Directory | File | FileError => { 112 | path = [...path] 113 | if (path.length > 0) { 114 | const index = dir.directories.findIndex(f => f.name == path.shift()); 115 | const result = readFile(dir.directories[index], path, fileName) 116 | if (result.type == "FileError") return result; 117 | dir.directories[index] = result as Directory; 118 | return dir 119 | } 120 | 121 | const file = dir.files.find(f => f.name == fileName); 122 | if (file == undefined) return { type: "FileError", error: `${fileName} does not exist` } 123 | return file; 124 | } 125 | 126 | export const deleteFile = (dir: Directory, path: string[], fileName: string): Directory | FileError => { 127 | path = [...path] 128 | if (path.length > 0) { 129 | const index = dir.directories.findIndex(f => f.name == path.shift()); 130 | const result = deleteFile(dir.directories[index], path, fileName) 131 | if (result.type == "FileError") return result; 132 | dir.directories[index] = result; 133 | return dir 134 | } 135 | 136 | const dirIndex = dir.files.findIndex(f => f.name == fileName); 137 | if (dirIndex == -1) return { type: "FileError", error: `file ${fileName} does not exist!` }; 138 | dir.files.splice(dirIndex, 1) 139 | return dir; 140 | } 141 | 142 | export const makeFile = (dir: Directory, path: string[], fileName: string): Directory | FileError => { 143 | path = [...path] 144 | if (path.length > 0) { 145 | const index = dir.directories.findIndex(f => f.name == path.shift()); 146 | const result = makeFile(dir.directories[index], path, fileName) 147 | if (result.type == "FileError") return result; 148 | dir.directories[index] = result; 149 | return dir; 150 | } 151 | 152 | // Check it doesnt already exist 153 | if (dir.files.find(f => f.name == fileName)) return { type: "FileError", error: `${fileName} already exists!` }; 154 | 155 | // Create the new directory and return an instance 156 | dir.files.push({ 157 | type: "File", 158 | name: fileName, 159 | content: "" 160 | }); 161 | return dir; 162 | } 163 | 164 | function sleep(ms: number) { 165 | return new Promise(resolve => system.runTimeout(resolve, ms * 1)); 166 | } 167 | 168 | export const openFile = async (player: Player, fileName: string, content: string): Promise => { 169 | let res: undefined | ModalFormResponse = undefined; 170 | while (res == undefined || res?.cancelationReason == FormCancelationReason.UserBusy) { 171 | await sleep(10); 172 | const modal = new ModalFormData() 173 | .title(fileName) 174 | .textField("Paste your file:", "", ""); 175 | res = await modal.show(player); 176 | } 177 | return res.formValues![0]; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /BP/scripts/main.ts: -------------------------------------------------------------------------------- 1 | // import { TurtleInterpreter } from "./run"; 2 | import { world, Entity, EntityInventoryComponent } from "@minecraft/server" 3 | import { OnTurtleBreak, OnTurtleInteract, OnTurtlePlace } from "./Turtles"; 4 | import { Directory, File, FileError, FileSystem } from "./FileSystem"; 5 | import { connectedTurtleProp, turtleFilesProp, turtleIdProp } from "./Properties"; 6 | import { TurtleInterpreter } from "./run"; 7 | 8 | world.afterEvents.playerPlaceBlock.subscribe(OnTurtlePlace); 9 | world.afterEvents.playerBreakBlock.subscribe(OnTurtleBreak); 10 | world.afterEvents.itemUseOn.subscribe(OnTurtleInteract); 11 | 12 | var currentPath: string[] = []; 13 | 14 | // Command line 15 | world.beforeEvents.chatSend.subscribe(async e => { 16 | try { 17 | if (!e.message.startsWith(">")) return; 18 | const message = e.message.substring(1).trimStart(); 19 | const [command, ...rest] = message.split(" "); 20 | const turtleId = (e.sender.getDynamicProperty(connectedTurtleProp) as string | undefined); 21 | if (turtleId === undefined) { 22 | world.sendMessage("[No Turtle Connected]") 23 | return; 24 | } 25 | const allTurtles = Array.from(e.sender.dimension.getEntities({ type: "coslang:turtle_controller" })) 26 | 27 | var turtle: Entity | null = null; 28 | for (var i = 0; i < allTurtles.length; i++) { 29 | if (allTurtles[i].getDynamicProperty(turtleIdProp) == turtleId) { 30 | turtle = allTurtles[i]; 31 | break; 32 | } 33 | } 34 | 35 | if (turtle == null) { 36 | world.sendMessage("Turtle with ID " + turtleId + " not found!") 37 | return; 38 | } 39 | 40 | const emptyFS: Directory = { name: "root", type: "Directory", directories: [], files: [] } 41 | const turtleString: string | undefined = allTurtles[i].getDynamicProperty(turtleFilesProp) as string | undefined 42 | const turtleFiles: Directory = turtleString == undefined ? emptyFS : JSON.parse(turtleString); 43 | 44 | e.cancel = true; 45 | 46 | // Check the player is connected to a turtle 47 | if (turtleId === undefined) { 48 | world.sendMessage("[No Turtle Connected]"); 49 | return; 50 | } 51 | //Help command 52 | else if (command == "help"){ 53 | world.sendMessage(`Command list: 54 | -help 55 | -tree 56 | -cd 57 | -mkdir 58 | -rmdir 59 | -new 60 | -del 61 | -edit 62 | -run 63 | -inventory`) 64 | } 65 | // Tree command 66 | else if (command == "tree") { 67 | const resolved = FileSystem.resolveDirectory(turtleFiles, currentPath) 68 | if (resolved.type == "FileError") { 69 | world.sendMessage(resolved.error); 70 | return; 71 | } 72 | world.sendMessage(FileSystem.directoryTree(resolved)); 73 | } 74 | 75 | // Changing directories with relative paths 76 | else if (command == "cd") { 77 | const relative = rest[0].split("/") 78 | const newPath = currentPath 79 | 80 | for (var i = 0; i < relative.length; i++) { 81 | if (relative[i] == "..") newPath.pop(); 82 | else newPath.push(relative[i]) 83 | } 84 | 85 | const dir = FileSystem.resolveDirectory(turtleFiles, newPath); 86 | if (dir.type == "FileError") { 87 | world.sendMessage(`Error: ${dir.error}`) 88 | return; 89 | } 90 | 91 | currentPath = newPath; 92 | world.sendMessage(`§7/${newPath.join("/")}>§r`) 93 | } 94 | 95 | // Make directories 96 | else if (command == "mkdir") { 97 | const name = rest[0]; 98 | const newFiles = FileSystem.makeDirectory(turtleFiles, currentPath, name); 99 | if (newFiles.type == "FileError") { 100 | world.sendMessage(`Error: ${newFiles.error}`); 101 | return; 102 | } 103 | turtle.setDynamicProperty(turtleFilesProp, JSON.stringify(turtleFiles)) 104 | world.sendMessage(`§7/${currentPath.join("/")}>`); 105 | return; 106 | } 107 | 108 | else if (command == "rmdir") { 109 | const name = rest[0]; 110 | const newFiles = FileSystem.deleteDirectory(turtleFiles, currentPath, name); 111 | if (newFiles.type == "FileError") { 112 | world.sendMessage(`Error: ${newFiles.error}`) 113 | return; 114 | } 115 | turtle.setDynamicProperty(turtleFilesProp, JSON.stringify(turtleFiles)) 116 | world.sendMessage(`§7/${currentPath.join("/")}>`); 117 | return; 118 | } 119 | 120 | // Make files 121 | else if (command == "new") { 122 | const name = rest[0]; 123 | const newFiles = FileSystem.makeFile(turtleFiles, currentPath, name); 124 | if (newFiles.type == "FileError") { 125 | world.sendMessage(`Error: ${newFiles.error}`) 126 | return; 127 | } 128 | turtle.setDynamicProperty(turtleFilesProp, JSON.stringify(turtleFiles)) 129 | world.sendMessage(`§7${currentPath.join("/")}/${name}`); 130 | return; 131 | } 132 | 133 | else if (command == "del") { 134 | const name = rest[0]; 135 | const newFiles = FileSystem.deleteFile(turtleFiles, currentPath, name); 136 | if (newFiles.type == "FileError") { 137 | world.sendMessage(`Error: ${newFiles.error}`) 138 | return; 139 | } 140 | turtle.setDynamicProperty(turtleFilesProp, JSON.stringify(turtleFiles)) 141 | world.sendMessage(`§7${currentPath.join("/")}/${name}`); 142 | return; 143 | } 144 | 145 | // Write files 146 | else if (command == "edit") { 147 | const name = rest[0]; 148 | const file = FileSystem.readFile(turtleFiles, currentPath, name) as File | FileError; 149 | if (file.type == "FileError") return world.sendMessage(file.error); 150 | const newContent = await FileSystem.openFile(e.sender, name, file.content); 151 | FileSystem.writeFile(turtleFiles, currentPath, name, newContent); 152 | turtle.setDynamicProperty(turtleFilesProp, JSON.stringify(turtleFiles)) 153 | } 154 | 155 | else if (command == "run") { 156 | const name = rest[0]; 157 | const file = FileSystem.readFile(turtleFiles, currentPath, name) as File | FileError; 158 | if (file.type == "FileError") return world.sendMessage(file.error); 159 | 160 | // Execute the file 161 | const turtleInterpreter = new TurtleInterpreter(turtle); 162 | await turtleInterpreter.runScript(file.content) 163 | } 164 | 165 | else if (command == "inventory") { 166 | const inventory = turtle.getComponent("minecraft:inventory") as EntityInventoryComponent 167 | 168 | for (var i = 0; i < 16; i++) { 169 | const item = inventory.container!.getItem(i) 170 | if (item == undefined) continue; 171 | world.sendMessage(`§7${i}.§r ${item.typeId} - ${item.amount}`) 172 | } 173 | 174 | e.cancel = true 175 | } 176 | 177 | else { 178 | world.sendMessage(`${command} is not a recognised command, use help for a list of commands`) 179 | } 180 | } catch (e) { console.warn(e); throw e } 181 | }) -------------------------------------------------------------------------------- /docs/.vitepress/cache/deps_temp_c3414293/vitepress___@vue_devtools-api.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "sources": ["../../../../node_modules/@vue/devtools-api/lib/esm/env.js", "../../../../node_modules/@vue/devtools-api/lib/esm/const.js", "../../../../node_modules/@vue/devtools-api/lib/esm/time.js", "../../../../node_modules/@vue/devtools-api/lib/esm/proxy.js", "../../../../node_modules/@vue/devtools-api/lib/esm/index.js"], 4 | "sourcesContent": ["export function getDevtoolsGlobalHook() {\n return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;\n}\nexport function getTarget() {\n // @ts-ignore\n return (typeof navigator !== 'undefined' && typeof window !== 'undefined')\n ? window\n : typeof global !== 'undefined'\n ? global\n : {};\n}\nexport const isProxyAvailable = typeof Proxy === 'function';\n", "export const HOOK_SETUP = 'devtools-plugin:setup';\nexport const HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set';\n", "let supported;\nlet perf;\nexport function isPerformanceSupported() {\n var _a;\n if (supported !== undefined) {\n return supported;\n }\n if (typeof window !== 'undefined' && window.performance) {\n supported = true;\n perf = window.performance;\n }\n else if (typeof global !== 'undefined' && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {\n supported = true;\n perf = global.perf_hooks.performance;\n }\n else {\n supported = false;\n }\n return supported;\n}\nexport function now() {\n return isPerformanceSupported() ? perf.now() : Date.now();\n}\n", "import { HOOK_PLUGIN_SETTINGS_SET } from './const.js';\nimport { now } from './time.js';\nexport class ApiProxy {\n constructor(plugin, hook) {\n this.target = null;\n this.targetQueue = [];\n this.onQueue = [];\n this.plugin = plugin;\n this.hook = hook;\n const defaultSettings = {};\n if (plugin.settings) {\n for (const id in plugin.settings) {\n const item = plugin.settings[id];\n defaultSettings[id] = item.defaultValue;\n }\n }\n const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;\n let currentSettings = Object.assign({}, defaultSettings);\n try {\n const raw = localStorage.getItem(localSettingsSaveId);\n const data = JSON.parse(raw);\n Object.assign(currentSettings, data);\n }\n catch (e) {\n // noop\n }\n this.fallbacks = {\n getSettings() {\n return currentSettings;\n },\n setSettings(value) {\n try {\n localStorage.setItem(localSettingsSaveId, JSON.stringify(value));\n }\n catch (e) {\n // noop\n }\n currentSettings = value;\n },\n now() {\n return now();\n },\n };\n if (hook) {\n hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {\n if (pluginId === this.plugin.id) {\n this.fallbacks.setSettings(value);\n }\n });\n }\n this.proxiedOn = new Proxy({}, {\n get: (_target, prop) => {\n if (this.target) {\n return this.target.on[prop];\n }\n else {\n return (...args) => {\n this.onQueue.push({\n method: prop,\n args,\n });\n };\n }\n },\n });\n this.proxiedTarget = new Proxy({}, {\n get: (_target, prop) => {\n if (this.target) {\n return this.target[prop];\n }\n else if (prop === 'on') {\n return this.proxiedOn;\n }\n else if (Object.keys(this.fallbacks).includes(prop)) {\n return (...args) => {\n this.targetQueue.push({\n method: prop,\n args,\n resolve: () => { },\n });\n return this.fallbacks[prop](...args);\n };\n }\n else {\n return (...args) => {\n return new Promise(resolve => {\n this.targetQueue.push({\n method: prop,\n args,\n resolve,\n });\n });\n };\n }\n },\n });\n }\n async setRealTarget(target) {\n this.target = target;\n for (const item of this.onQueue) {\n this.target.on[item.method](...item.args);\n }\n for (const item of this.targetQueue) {\n item.resolve(await this.target[item.method](...item.args));\n }\n }\n}\n", "import { getTarget, getDevtoolsGlobalHook, isProxyAvailable } from './env.js';\nimport { HOOK_SETUP } from './const.js';\nimport { ApiProxy } from './proxy.js';\nexport * from './api/index.js';\nexport * from './plugin.js';\nexport * from './time.js';\nexport function setupDevtoolsPlugin(pluginDescriptor, setupFn) {\n const descriptor = pluginDescriptor;\n const target = getTarget();\n const hook = getDevtoolsGlobalHook();\n const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy;\n if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {\n hook.emit(HOOK_SETUP, pluginDescriptor, setupFn);\n }\n else {\n const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null;\n const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];\n list.push({\n pluginDescriptor: descriptor,\n setupFn,\n proxy,\n });\n if (proxy)\n setupFn(proxy.proxiedTarget);\n }\n}\n"], 5 | "mappings": ";AAAO,SAAS,wBAAwB;AACpC,SAAO,UAAU,EAAE;AACvB;AACO,SAAS,YAAY;AAExB,SAAQ,OAAO,cAAc,eAAe,OAAO,WAAW,cACxD,SACA,OAAO,WAAW,cACd,SACA,CAAC;AACf;AACO,IAAM,mBAAmB,OAAO,UAAU;;;ACX1C,IAAM,aAAa;AACnB,IAAM,2BAA2B;;;ACDxC,IAAI;AACJ,IAAI;AACG,SAAS,yBAAyB;AACrC,MAAI;AACJ,MAAI,cAAc,QAAW;AACzB,WAAO;AAAA,EACX;AACA,MAAI,OAAO,WAAW,eAAe,OAAO,aAAa;AACrD,gBAAY;AACZ,WAAO,OAAO;AAAA,EAClB,WACS,OAAO,WAAW,iBAAiB,KAAK,OAAO,gBAAgB,QAAQ,OAAO,SAAS,SAAS,GAAG,cAAc;AACtH,gBAAY;AACZ,WAAO,OAAO,WAAW;AAAA,EAC7B,OACK;AACD,gBAAY;AAAA,EAChB;AACA,SAAO;AACX;AACO,SAAS,MAAM;AAClB,SAAO,uBAAuB,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI;AAC5D;;;ACpBO,IAAM,WAAN,MAAe;AAAA,EAClB,YAAY,QAAQ,MAAM;AACtB,SAAK,SAAS;AACd,SAAK,cAAc,CAAC;AACpB,SAAK,UAAU,CAAC;AAChB,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,UAAM,kBAAkB,CAAC;AACzB,QAAI,OAAO,UAAU;AACjB,iBAAW,MAAM,OAAO,UAAU;AAC9B,cAAM,OAAO,OAAO,SAAS,EAAE;AAC/B,wBAAgB,EAAE,IAAI,KAAK;AAAA,MAC/B;AAAA,IACJ;AACA,UAAM,sBAAsB,mCAAmC,OAAO,EAAE;AACxE,QAAI,kBAAkB,OAAO,OAAO,CAAC,GAAG,eAAe;AACvD,QAAI;AACA,YAAM,MAAM,aAAa,QAAQ,mBAAmB;AACpD,YAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,aAAO,OAAO,iBAAiB,IAAI;AAAA,IACvC,SACO,GAAG;AAAA,IAEV;AACA,SAAK,YAAY;AAAA,MACb,cAAc;AACV,eAAO;AAAA,MACX;AAAA,MACA,YAAY,OAAO;AACf,YAAI;AACA,uBAAa,QAAQ,qBAAqB,KAAK,UAAU,KAAK,CAAC;AAAA,QACnE,SACO,GAAG;AAAA,QAEV;AACA,0BAAkB;AAAA,MACtB;AAAA,MACA,MAAM;AACF,eAAO,IAAI;AAAA,MACf;AAAA,IACJ;AACA,QAAI,MAAM;AACN,WAAK,GAAG,0BAA0B,CAAC,UAAU,UAAU;AACnD,YAAI,aAAa,KAAK,OAAO,IAAI;AAC7B,eAAK,UAAU,YAAY,KAAK;AAAA,QACpC;AAAA,MACJ,CAAC;AAAA,IACL;AACA,SAAK,YAAY,IAAI,MAAM,CAAC,GAAG;AAAA,MAC3B,KAAK,CAAC,SAAS,SAAS;AACpB,YAAI,KAAK,QAAQ;AACb,iBAAO,KAAK,OAAO,GAAG,IAAI;AAAA,QAC9B,OACK;AACD,iBAAO,IAAI,SAAS;AAChB,iBAAK,QAAQ,KAAK;AAAA,cACd,QAAQ;AAAA,cACR;AAAA,YACJ,CAAC;AAAA,UACL;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,CAAC;AACD,SAAK,gBAAgB,IAAI,MAAM,CAAC,GAAG;AAAA,MAC/B,KAAK,CAAC,SAAS,SAAS;AACpB,YAAI,KAAK,QAAQ;AACb,iBAAO,KAAK,OAAO,IAAI;AAAA,QAC3B,WACS,SAAS,MAAM;AACpB,iBAAO,KAAK;AAAA,QAChB,WACS,OAAO,KAAK,KAAK,SAAS,EAAE,SAAS,IAAI,GAAG;AACjD,iBAAO,IAAI,SAAS;AAChB,iBAAK,YAAY,KAAK;AAAA,cAClB,QAAQ;AAAA,cACR;AAAA,cACA,SAAS,MAAM;AAAA,cAAE;AAAA,YACrB,CAAC;AACD,mBAAO,KAAK,UAAU,IAAI,EAAE,GAAG,IAAI;AAAA,UACvC;AAAA,QACJ,OACK;AACD,iBAAO,IAAI,SAAS;AAChB,mBAAO,IAAI,QAAQ,aAAW;AAC1B,mBAAK,YAAY,KAAK;AAAA,gBAClB,QAAQ;AAAA,gBACR;AAAA,gBACA;AAAA,cACJ,CAAC;AAAA,YACL,CAAC;AAAA,UACL;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EACA,MAAM,cAAc,QAAQ;AACxB,SAAK,SAAS;AACd,eAAW,QAAQ,KAAK,SAAS;AAC7B,WAAK,OAAO,GAAG,KAAK,MAAM,EAAE,GAAG,KAAK,IAAI;AAAA,IAC5C;AACA,eAAW,QAAQ,KAAK,aAAa;AACjC,WAAK,QAAQ,MAAM,KAAK,OAAO,KAAK,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;AAAA,IAC7D;AAAA,EACJ;AACJ;;;ACpGO,SAAS,oBAAoB,kBAAkB,SAAS;AAC3D,QAAM,aAAa;AACnB,QAAM,SAAS,UAAU;AACzB,QAAM,OAAO,sBAAsB;AACnC,QAAM,cAAc,oBAAoB,WAAW;AACnD,MAAI,SAAS,OAAO,yCAAyC,CAAC,cAAc;AACxE,SAAK,KAAK,YAAY,kBAAkB,OAAO;AAAA,EACnD,OACK;AACD,UAAM,QAAQ,cAAc,IAAI,SAAS,YAAY,IAAI,IAAI;AAC7D,UAAM,OAAO,OAAO,2BAA2B,OAAO,4BAA4B,CAAC;AACnF,SAAK,KAAK;AAAA,MACN,kBAAkB;AAAA,MAClB;AAAA,MACA;AAAA,IACJ,CAAC;AACD,QAAI;AACA,cAAQ,MAAM,aAAa;AAAA,EACnC;AACJ;", 6 | "names": [] 7 | } 8 | -------------------------------------------------------------------------------- /BP/scripts/structs/Turtle.ts: -------------------------------------------------------------------------------- 1 | import { BlockType, system, world, MinecraftBlockTypes, BlockPermutation, Block, Entity, Vector, EntityItemComponent, EntityInventoryComponent, ItemStack, MinecraftItemTypes, ItemType, ItemTypes } from "@minecraft/server" 2 | import { NativeFunction } from "../cosmic/src/Struct/NativeFunction"; 3 | import { StructType } from "../cosmic/src/Struct/StructType"; 4 | 5 | const movementDelayInTicks = 10; 6 | console.log = console.warn 7 | 8 | // export function drawTurtle(oldPosition, position, rotation, ctx) { 9 | // // Move the entity controller 10 | // const entity = ctx.getProtectedData("entity") as Entity 11 | // entity.teleport(new Vector(position[0] + 0.5, position[1], position[2] + 0.5), entity.dimension, 0, 0, false) 12 | 13 | // // Erase old 14 | // const oldBlockLocation = new BlockLocation(oldPosition[0], oldPosition[1], oldPosition[2]); 15 | // world.getDimension("overworld").getBlock(oldBlockLocation).setType(MinecraftBlockTypes.get("minecraft:air")) 16 | 17 | // // Draw new 18 | // const blockLocation = new BlockLocation(position[0], position[1], position[2]); 19 | // const block = world.getDimension("overworld").getBlock(blockLocation) 20 | // block.setType(MinecraftBlockTypes.get("coslang:turtle")); 21 | 22 | // // Rotation 23 | // const permutation = block.permutation; 24 | // // @ts-ignore Missing Field on type IBlockProperty 25 | // permutation.getProperty("coslang:rotation").value = rotation; 26 | // block.setPermutation(permutation); 27 | // } 28 | 29 | // const overworld = world.getDimension("overworld") 30 | 31 | // const pickUpBlock = (blockPos: BlockLocation, inventory: EntityInventoryComponent) => { 32 | // overworld.getEntitiesAtBlockLocation(blockPos).forEach(entity => { 33 | // if (entity.typeId == "minecraft:item") { 34 | // const itemComponent = entity.getComponent("minecraft:item") as EntityItemComponent 35 | 36 | // // The item will always fit 37 | // if (inventory.container.emptySlotsCount > 0) { 38 | // inventory.container.addItem(itemComponent.itemStack) 39 | // entity.kill() 40 | // } 41 | // else { 42 | // var remainingItems = itemComponent.itemStack.amount; 43 | 44 | // for (var i = 0; i < 16; i++) { 45 | // const slot = inventory.container.getItem(i); 46 | // if (slot.typeId != itemComponent.itemStack.typeId) continue; 47 | 48 | // const startAmount = slot.amount; 49 | // const itemType = ItemTypes.get(slot.typeId) 50 | // const newItemStack = new ItemStack(itemType, Math.min(slot.amount + remainingItems, 64)); 51 | 52 | // const itemsAdded = newItemStack.amount - startAmount; 53 | // if (itemsAdded > 0) inventory.container.setItem(i, newItemStack); 54 | // remainingItems -= itemsAdded; 55 | 56 | // if (remainingItems == 0) break; 57 | // } 58 | 59 | // if (remainingItems > 0) { 60 | // const type = ItemTypes.get(itemComponent.itemStack.typeId) 61 | // const blockLoc = new BlockLocation( 62 | // Math.floor(entity.location.x), 63 | // Math.floor(entity.location.y), 64 | // Math.floor(entity.location.z) 65 | // ) 66 | // overworld.spawnItem(new ItemStack(type, remainingItems, itemComponent.itemStack.data), blockLoc) 67 | // } 68 | // entity.kill(); 69 | // } 70 | // } 71 | // }) 72 | // } 73 | 74 | export const Turtle = new StructType("Turtle", [], [ 75 | // new NativeFunction("Forward", async (interpreter, ctx, args) => { 76 | // await delay() 77 | // const oldPosition: [number, number, number] = ctx.getProtectedData("position"); 78 | // const rotation = ctx.getProtectedData("rotation"); 79 | // const position = [...oldPosition] 80 | // if (rotation % 4 == 0) position[0] += 1; 81 | // else if (rotation % 4 == 1) position[2] -= 1; 82 | // else if (rotation % 4 == 2) position[0] -= 1; 83 | // else if (rotation % 4 == 3) position[2] += 1; 84 | // const blockPos = new BlockLocation(position[0], position[1], position[2]) 85 | 86 | // if (!overworld.getBlock(blockPos).canPlace(MinecraftBlockTypes.stone)) return [null, ctx] 87 | 88 | // drawTurtle(oldPosition, position, rotation % 4, ctx); 89 | // ctx.setProtectedData("position", position); 90 | 91 | // return [null, ctx]; 92 | // }), 93 | 94 | // new NativeFunction("TurnRight", async (interpreter, ctx, args) => { 95 | // await delay() 96 | // const position: [number, number, number] = ctx.getProtectedData("position"); 97 | // var rotation: number = ctx.getProtectedData("rotation") - 1; 98 | // if (rotation > 3) rotation = 0; 99 | // if (rotation < 0) rotation = 3; 100 | 101 | // drawTurtle(position, position, rotation % 4, ctx); 102 | // ctx.setProtectedData("rotation", rotation); 103 | 104 | 105 | // return [null, ctx]; 106 | // }), 107 | 108 | // new NativeFunction("TurnLeft", async (interpreter, ctx, args) => { 109 | // await delay() 110 | // const position: [number, number, number] = ctx.getProtectedData("position"); 111 | // var rotation: number = ctx.getProtectedData("rotation") + 1; 112 | // if (rotation > 3) rotation = 0; 113 | // if (rotation < 0) rotation = 3; 114 | 115 | // drawTurtle(position, position, rotation % 4, ctx); 116 | // ctx.setProtectedData("rotation", rotation); 117 | 118 | // return [null, ctx]; 119 | // }), 120 | 121 | // new NativeFunction("Inspect", async (interpreter, ctx, args) => { 122 | // const [...position] = ctx.getProtectedData("position"); 123 | // const rotation = ctx.getProtectedData("rotation"); 124 | 125 | // if (rotation % 4 == 0) position[0] += 1; 126 | // else if (rotation % 4 == 1) position[2] -= 1; 127 | // else if (rotation % 4 == 2) position[0] -= 1; 128 | // else if (rotation % 4 == 3) position[2] += 1; 129 | // const blockPos = new BlockLocation(position[0], position[1], position[2]) 130 | 131 | // const blockId = overworld.getBlock(blockPos).typeId; 132 | // return interpreter.primitiveString({ value: `${blockId}` }, ctx) 133 | // }), 134 | 135 | // new NativeFunction("InspectDown", async (interpreter, ctx, args) => { 136 | // const position: [number, number, number] = ctx.getProtectedData("position"); 137 | // const blockLocation = new BlockLocation(position[0], position[1] - 1, position[2]); 138 | 139 | // const blockId = overworld.getBlock(blockLocation).typeId; 140 | // return interpreter.primitiveString({ value: `${blockId}` }, ctx) 141 | // }), 142 | 143 | // new NativeFunction("InspectUp", async (interpreter, ctx, args) => { 144 | // const position: [number, number, number] = ctx.getProtectedData("position"); 145 | // const blockLocation = new BlockLocation(position[0], position[1] + 1, position[2]); 146 | 147 | // const blockId = overworld.getBlock(blockLocation).typeId; 148 | // return interpreter.primitiveString({ value: `${blockId}` }, ctx) 149 | // }), 150 | 151 | // new NativeFunction("Dig", async (interpreter, ctx, args) => { 152 | // const [...position] = ctx.getProtectedData("position"); 153 | // const rotation = ctx.getProtectedData("rotation"); 154 | 155 | // if (rotation % 4 == 0) position[0] += 1; 156 | // else if (rotation % 4 == 1) position[2] -= 1; 157 | // else if (rotation % 4 == 2) position[0] -= 1; 158 | // else if (rotation % 4 == 3) position[2] += 1; 159 | // const blockPos = new BlockLocation(position[0], position[1], position[2]) 160 | 161 | // await delay() 162 | // await overworld.runCommandAsync(`setblock ${position[0]} ${position[1]} ${position[2]} air 0 destroy`) 163 | // const inventory = (ctx.getProtectedData("entity") as Entity).getComponent("minecraft:inventory") as EntityInventoryComponent; 164 | // pickUpBlock(blockPos, inventory) 165 | 166 | // return [null, ctx] 167 | // }), 168 | 169 | // new NativeFunction("DigUp", async (interpreter, ctx, args) => { 170 | // const [...position] = ctx.getProtectedData("position"); 171 | // const blockPos = new BlockLocation(position[0], position[1] + 1, position[2]) 172 | 173 | // await delay() 174 | // await overworld.runCommandAsync(`setblock ${position[0]} ${position[1] + 1} ${position[2]} air 0 destroy`) 175 | // const inventory = (ctx.getProtectedData("entity") as Entity).getComponent("minecraft:inventory") as EntityInventoryComponent; 176 | // pickUpBlock(blockPos, inventory) 177 | 178 | // return [null, ctx] 179 | // }), 180 | 181 | // new NativeFunction("DigDown", async (interpreter, ctx, args) => { 182 | // const [...position] = ctx.getProtectedData("position"); 183 | // const blockPos = new BlockLocation(position[0], position[1] - 1, position[2]) 184 | 185 | // await delay() 186 | // await overworld.runCommandAsync(`setblock ${position[0]} ${position[1] - 1} ${position[2]} air 0 destroy`) 187 | // const inventory = (ctx.getProtectedData("entity") as Entity).getComponent("minecraft:inventory") as EntityInventoryComponent; 188 | // pickUpBlock(blockPos, inventory) 189 | 190 | // return [null, ctx] 191 | // }), 192 | ]) -------------------------------------------------------------------------------- /BP/scripts/structs/PixelBuffer.ts: -------------------------------------------------------------------------------- 1 | import { Interpreter } from "../cosmic/src/Interpreter"; 2 | import { getBooleanLiteral } from "../cosmic/src/Primitives/Boolean"; 3 | import { getNumberLiteral } from "../cosmic/src/Primitives/Number"; 4 | import { getStringLiteral } from "../cosmic/src/Primitives/String"; 5 | import { NativeFunction } from "../cosmic/src/Struct/NativeFunction"; 6 | import { NativeFunctionHelper } from "../cosmic/src/Struct/NativeFunctionHelper"; 7 | import { StructInstance } from "../cosmic/src/Struct/StructInstance"; 8 | import { StructType } from "../cosmic/src/Struct/StructType"; 9 | console.log = console.warn 10 | 11 | const validatePointOnScreen = (x: number, y: number, width: number, height: number, interpreter: Interpreter, start: number, end: number) => { 12 | // if (x < 0 || x >= width || y < 0 || y >= width) { 13 | // throw interpreter.runtimeErrorCode( 14 | // `Pixel (${x}, ${y}) is outside of the pixel display!`, 15 | // start, 16 | // end 17 | // ) 18 | // } 19 | 20 | return [x, y]; 21 | } 22 | 23 | const isPointOnScreen = (x: number, y: number, width: number, height: number) => { 24 | return !(x < 0 || x >= width || y < 0 || y >= width) 25 | } 26 | 27 | const fontPoints = { 28 | "none": [[0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [1, 0], [2, 0], [3, 0], [4, 0], [1, 6], [2, 6], [3, 6], [4, 6]], 29 | "a": [[0,1],[1,4],[1,2],[1,0],[2,4],[2,2],[2,0],[3,4],[3,2],[3,0],[4,3],[4,2],[4,1],[4,0]], 30 | "b": [[0,6],[0,5],[0,4],[0,3],[0,2],[0,1],[0,0],[1,3],[1,0],[2,4],[2,0],[3,4],[3,0],[4,3],[4,2],[4,1]], 31 | "c": [[0,3],[0,2],[0,1],[1,4],[1,0],[2,4],[2,0],[3,4],[3,0],[4,3],[4,1]], 32 | "d": [[0,3],[0,2],[0,1],[1,4],[1,0],[2,4],[2,0],[3,3],[3,0],[4,6],[4,5],[4,4],[4,3],[4,2],[4,1],[4,0]], 33 | "e": [[0,3],[0,2],[0,1],[1,4],[1,2],[1,0],[2,4],[2,2],[2,0],[3,4],[3,2],[3,0],[4,3],[4,2],[4,0]], 34 | "f": [[0,4],[1,5],[1,4],[1,3],[1,2],[1,1],[1,0],[2,6],[2,4],[3,6],[3,4]], 35 | "g": [[0,4],[0,3],[0,0],[1,5],[1,2],[1,0],[2,5],[2,2],[2,0],[3,5],[3,2],[3,0],[4,5],[4,4],[4,3],[4,2],[4,1]], 36 | "h": [[0,6],[0,5],[0,4],[0,3],[0,2],[0,1],[0,0],[1,3],[2,4],[3,4],[4,3],[4,2],[4,1],[4,0]], 37 | "i": [[2,6],[2,4],[2,3],[2,2],[2,1],[2,0]], 38 | "j": [[0,2],[0,1],[1,0],[2,0],[3,0],[4,6],[4,4],[4,3],[4,2],[4,1]], 39 | "k": [[0,6],[0,5],[0,4],[0,3],[0,2],[0,1],[0,0],[1,2],[2,3],[2,1],[3,4],[3,0]], 40 | "l": [[2,6],[2,5],[2,4],[2,3],[2,2],[2,1],[3,0]], 41 | "m": [[0,4],[0,3],[0,2],[0,1],[0,0],[1,4],[2,3],[2,2],[3,4],[4,3],[4,2],[4,1],[4,0]], 42 | "n": [[0,4],[0,3],[0,2],[0,1],[0,0],[1,4],[2,4],[3,4],[4,3],[4,2],[4,1],[4,0]], 43 | "o": [[0,3],[0,2],[0,1],[1,4],[1,0],[2,4],[2,0],[3,4],[3,0],[4,3],[4,2],[4,1]], 44 | "p": [[0,5],[0,4],[0,3],[0,2],[0,1],[0,0],[1,4],[1,2],[2,5],[2,2],[3,5],[3,2],[4,4],[4,3]], 45 | "q": [[0,4],[0,3],[1,5],[1,2],[2,5],[2,2],[3,4],[3,2],[4,5],[4,4],[4,3],[4,2],[4,1],[4,0]], 46 | "r": [[0,4],[0,3],[0,2],[0,1],[0,0],[1,3],[2,4],[3,4],[4,3]], 47 | "s": [[0,3],[0,0],[1,4],[1,2],[1,0],[2,4],[2,2],[2,0],[3,4],[3,2],[3,0],[4,4],[4,1]], 48 | "t": [[1,5],[2,6],[2,5],[2,4],[2,3],[2,2],[2,1],[3,5],[3,0]], 49 | "u": [[0,4],[0,3],[0,2],[0,1],[1,0],[2,0],[3,0],[4,4],[4,3],[4,2],[4,1],[4,0]], 50 | "v": [[0,4],[0,3],[0,2],[1,1],[2,0],[3,1],[4,4],[4,3],[4,2]], 51 | "w": [[0,4],[0,3],[0,2],[0,1],[1,0],[2,2],[2,1],[2,0],[3,0],[4,4],[4,3],[4,2],[4,1],[4,0]], 52 | "x": [[0,4],[0,0],[1,3],[1,1],[2,2],[3,3],[3,1],[4,4],[4,0]], 53 | "y": [[0,5],[0,4],[0,3],[0,0],[1,2],[1,0],[2,2],[2,0],[3,2],[3,0],[4,5],[4,4],[4,3],[4,2],[4,1]], 54 | "z": [[0,4],[0,0],[1,4],[1,1],[1,0],[2,4],[2,2],[2,0],[3,4],[3,3],[3,0],[4,4],[4,0]], 55 | "0": [[0,5],[0,4],[0,3],[0,2],[0,1],[1,6],[1,2],[1,0],[2,6],[2,3],[2,0],[3,6],[3,4],[3,0],[4,5],[4,4],[4,3],[4,2],[4,1]], 56 | "1": [[0,0],[1,5],[1,0],[2,6],[2,5],[2,4],[2,3],[2,2],[2,1],[2,0],[3,0],[4,0]], 57 | "2": [[0,5],[0,1],[0,0],[1,6],[1,2],[1,0],[2,6],[2,3],[2,0],[3,6],[3,3],[3,0],[4,5],[4,4],[4,0]], 58 | "3": [[0,5],[0,1],[1,6],[1,0],[2,6],[2,3],[2,0],[3,6],[3,3],[3,0],[4,5],[4,4],[4,2],[4,1]], 59 | "4": [[0,3],[0,2],[1,4],[1,2],[2,5],[2,2],[3,6],[3,2],[4,6],[4,5],[4,4],[4,3],[4,2],[4,1],[4,0]], 60 | "5": [[0,6],[0,5],[0,4],[0,1],[1,6],[1,4],[1,0],[2,6],[2,4],[2,0],[3,6],[3,4],[3,0],[4,6],[4,3],[4,2],[4,1]], 61 | "6": [[0,4],[0,3],[0,2],[0,1],[1,5],[1,3],[1,0],[2,6],[2,3],[2,0],[3,6],[3,3],[3,0],[4,2],[4,1]], 62 | "7": [[0,6],[0,5],[1,6],[2,6],[2,2],[2,1],[2,0],[3,6],[3,3],[4,6],[4,5],[4,4]], 63 | "8": [[0,5],[0,4],[0,2],[0,1],[1,6],[1,3],[1,0],[2,6],[2,3],[2,0],[3,6],[3,3],[3,0],[4,5],[4,4],[4,2],[4,1]], 64 | "9": [[0,5],[0,4],[1,6],[1,3],[1,0],[2,6],[2,3],[2,0],[3,6],[3,3],[3,1],[4,5],[4,4],[4,3],[4,2]], 65 | " ": [], 66 | ":": [[2,6],[2,5],[2,2],[2,1]], 67 | "!": [[2,6],[2,5],[2,4],[2,3],[2,2],[2,0]], 68 | ",": [[2,2],[2,1],[2,0]] 69 | } 70 | 71 | export const PixelBuffer = new StructType("PixelBuffer", [], [ 72 | new NativeFunction("New", async (interpreter, ctx, start, end, args) => { 73 | const helper = new NativeFunctionHelper(interpreter, args, 2, start, end); 74 | const instance = new StructInstance(PixelBuffer); 75 | const width = getNumberLiteral(helper.expectType(0, "Number")); 76 | const height = getNumberLiteral(helper.expectType(1, "Number")); 77 | 78 | if (width <= 0 || height <= 0) throw interpreter.runtimeErrorCode( 79 | `PixelBuffer cannot have a width or height below 0, got width: ${width}, height: ${height}`, 80 | start, end 81 | ) 82 | 83 | if (width % 16 != 0 || height % 16 != 0) throw interpreter.runtimeErrorCode( 84 | `Width (${width}) and Height (${height}) must both be divisible by 16`, 85 | start, end 86 | ) 87 | 88 | instance.selfCtx.setProtected("bufferWidth", width) 89 | instance.selfCtx.setProtected("bufferHeight", height) 90 | instance.selfCtx.setProtected("pixelBuffer", new Array(width * height).fill(-1)) 91 | return [instance, ctx]; 92 | }), 93 | 94 | new NativeFunction("DrawPixel", async (interpreter, ctx, start, end, args) => { 95 | const helper = new NativeFunctionHelper(interpreter, args, 3, start, end); 96 | var selfRef = ctx.stack.pop().node as StructInstance; 97 | var screenBuffer = selfRef.selfCtx.getProtected("pixelBuffer"); 98 | var bufferWidth = selfRef.selfCtx.getProtected("bufferWidth") 99 | 100 | 101 | const [x, y] = validatePointOnScreen( 102 | getNumberLiteral(helper.expectType(0, "Number")), 103 | getNumberLiteral(helper.expectType(1, "Number")), 104 | bufferWidth, 105 | selfRef.selfCtx.getProtected("bufferHeight"), 106 | interpreter, start, end 107 | ); 108 | const color = getNumberLiteral(helper.expectType(2, "Number")); 109 | 110 | screenBuffer[y * bufferWidth + x] = color; 111 | selfRef.selfCtx.setProtected("pixelBuffer", screenBuffer) 112 | return [null, ctx] 113 | }), 114 | 115 | new NativeFunction("DrawLine", async (interpreter, ctx, start, end, args) => { 116 | const helper = new NativeFunctionHelper(interpreter, args, 5, start, end); 117 | var selfRef = ctx.stack.pop().node as StructInstance; 118 | var screenBuffer = selfRef.selfCtx.getProtected("pixelBuffer"); 119 | var width = selfRef.selfCtx.getProtected("bufferWidth"); 120 | var height = selfRef.selfCtx.getProtected("bufferHeight"); 121 | 122 | var [x1, y1] = validatePointOnScreen( 123 | getNumberLiteral(helper.expectType(0, "Number")), 124 | getNumberLiteral(helper.expectType(1, "Number")), 125 | width, height, interpreter, start, end 126 | ); 127 | 128 | var [x2, y2] = validatePointOnScreen( 129 | getNumberLiteral(helper.expectType(2, "Number")), 130 | getNumberLiteral(helper.expectType(3, "Number")), 131 | width, height, interpreter, start, end 132 | ); 133 | 134 | const color = getNumberLiteral(helper.expectType(4, "Number")); 135 | 136 | // Get gradient of the line 137 | var [dx, dy] = [Math.abs(x2 - x1), Math.abs(y2 - y1)]; 138 | var [sx, sy] = [Math.sign(x2 - x1), Math.sign(y2 - y1)]; 139 | var [x, y] = [x1, y1]; 140 | var err = dx - dy; 141 | 142 | while (x != x2 || y != y2) { 143 | screenBuffer[y * width + x] = color; 144 | var e2 = 2 * err; 145 | if (e2 > -dy) { 146 | err -= dy; 147 | x += sx; 148 | } 149 | if (e2 < dx) { 150 | err += dx; 151 | y += sy; 152 | } 153 | } 154 | 155 | screenBuffer[y * width + x] = color; 156 | selfRef.selfCtx.setProtected("pixelBuffer", screenBuffer) 157 | return [null, ctx] 158 | }), 159 | 160 | new NativeFunction("DrawCircle", async (interpreter, ctx, start, end, args) => { 161 | const helper = new NativeFunctionHelper(interpreter, args, 5, start, end); 162 | var selfRef = ctx.stack.pop().node as StructInstance; 163 | var screenBuffer = selfRef.selfCtx.getProtected("pixelBuffer"); 164 | var bufferWidth = selfRef.selfCtx.getProtected("bufferWidth"); 165 | var bufferHeight = selfRef.selfCtx.getProtected("bufferHeight"); 166 | 167 | const centerX = getNumberLiteral(helper.expectType(0, "Number")) 168 | const centerY = getNumberLiteral(helper.expectType(1, "Number")) 169 | const radius = getNumberLiteral(helper.expectType(2, "Number")) 170 | const shouldFill = !getBooleanLiteral(helper.expectType(3, "Boolean")) 171 | const color = getNumberLiteral(helper.expectType(4, "Number")) 172 | 173 | for (var xOff = -radius; xOff <= radius; xOff++) { 174 | for (var yOff = -radius; yOff <= radius; yOff++) { 175 | var x = centerX + xOff; 176 | var y = centerY + yOff; 177 | if (!isPointOnScreen(x, y, bufferWidth, bufferHeight)) continue; 178 | const c = Math.sqrt(xOff * xOff + yOff * yOff) 179 | if (c > radius || (c < radius - 1 && shouldFill)) continue; 180 | 181 | screenBuffer[y * bufferWidth + x] = color; 182 | } 183 | } 184 | 185 | return [null, ctx]; 186 | }), 187 | 188 | new NativeFunction("DrawText", async (interpreter, ctx, start, end, args) => { 189 | const helper = new NativeFunctionHelper(interpreter, args, 1, start, end); 190 | var selfRef = ctx.stack.pop().node as StructInstance; 191 | var screenBuffer = selfRef.selfCtx.getProtected("pixelBuffer"); 192 | var bufferWidth = selfRef.selfCtx.getProtected("bufferWidth"); 193 | var bufferHeight = selfRef.selfCtx.getProtected("bufferHeight"); 194 | const text = getStringLiteral(helper.expectType(0, "String")) 195 | const characters = text.split(""); 196 | 197 | var charHeight = 7; 198 | var charWidth = 5; 199 | var x = 0; 200 | var y = bufferHeight - charHeight; 201 | 202 | for (var i = 0; i < characters.length; i++) { 203 | var points = fontPoints[characters[i]] ?? fontPoints.none; 204 | 205 | points.forEach(point => { 206 | var pointX = x + point[0]; 207 | var pointY = y + point[1]; 208 | screenBuffer[pointY * bufferWidth + pointX] = 0; 209 | }) 210 | 211 | if (x + charWidth + 1 < bufferWidth - 2) x += charWidth + 1; 212 | else { 213 | x = 0; 214 | y -= charHeight + 1; 215 | } 216 | } 217 | 218 | selfRef.selfCtx.setProtected("pixelBuffer", screenBuffer) 219 | return [null, ctx]; 220 | }) 221 | ]); 222 | -------------------------------------------------------------------------------- /BP/entities/pixel.json: -------------------------------------------------------------------------------- 1 | {"format_version":"1.19.50","minecraft:entity":{"description":{"identifier":"coslang:pixel","is_spawnable":true,"is_summonable":true,"is_experimental":false,"properties":{"coslang:x":{"range":[0,15],"client_sync":true,"default":0,"type":"int"},"coslang:x_size":{"range":[1,16],"client_sync":true,"default":1,"type":"int"},"coslang:y":{"range":[0,15],"client_sync":true,"default":0,"type":"int"},"coslang:y_size":{"range":[1,16],"client_sync":true,"default":1,"type":"int"},"coslang:color":{"type":"int","range":[0,6],"default":0,"client_sync":true}}},"component_groups":{"coslang:despawn":{"minecraft:instant_despawn":{}}},"components":{"minecraft:collision_box":{"height":0,"width":0}},"events":{"coslang:despawn":{"add":{"component_groups":["coslang:despawn"]}},"coslang:set_0_0":{"set_property":{"coslang:x":0,"coslang:y":0}},"coslang:set_0_1":{"set_property":{"coslang:x":0,"coslang:y":1}},"coslang:set_0_2":{"set_property":{"coslang:x":0,"coslang:y":2}},"coslang:set_0_3":{"set_property":{"coslang:x":0,"coslang:y":3}},"coslang:set_0_4":{"set_property":{"coslang:x":0,"coslang:y":4}},"coslang:set_0_5":{"set_property":{"coslang:x":0,"coslang:y":5}},"coslang:set_0_6":{"set_property":{"coslang:x":0,"coslang:y":6}},"coslang:set_0_7":{"set_property":{"coslang:x":0,"coslang:y":7}},"coslang:set_0_8":{"set_property":{"coslang:x":0,"coslang:y":8}},"coslang:set_0_9":{"set_property":{"coslang:x":0,"coslang:y":9}},"coslang:set_0_10":{"set_property":{"coslang:x":0,"coslang:y":10}},"coslang:set_0_11":{"set_property":{"coslang:x":0,"coslang:y":11}},"coslang:set_0_12":{"set_property":{"coslang:x":0,"coslang:y":12}},"coslang:set_0_13":{"set_property":{"coslang:x":0,"coslang:y":13}},"coslang:set_0_14":{"set_property":{"coslang:x":0,"coslang:y":14}},"coslang:set_0_15":{"set_property":{"coslang:x":0,"coslang:y":15}},"coslang:set_1_0":{"set_property":{"coslang:x":1,"coslang:y":0}},"coslang:set_1_1":{"set_property":{"coslang:x":1,"coslang:y":1}},"coslang:set_1_2":{"set_property":{"coslang:x":1,"coslang:y":2}},"coslang:set_1_3":{"set_property":{"coslang:x":1,"coslang:y":3}},"coslang:set_1_4":{"set_property":{"coslang:x":1,"coslang:y":4}},"coslang:set_1_5":{"set_property":{"coslang:x":1,"coslang:y":5}},"coslang:set_1_6":{"set_property":{"coslang:x":1,"coslang:y":6}},"coslang:set_1_7":{"set_property":{"coslang:x":1,"coslang:y":7}},"coslang:set_1_8":{"set_property":{"coslang:x":1,"coslang:y":8}},"coslang:set_1_9":{"set_property":{"coslang:x":1,"coslang:y":9}},"coslang:set_1_10":{"set_property":{"coslang:x":1,"coslang:y":10}},"coslang:set_1_11":{"set_property":{"coslang:x":1,"coslang:y":11}},"coslang:set_1_12":{"set_property":{"coslang:x":1,"coslang:y":12}},"coslang:set_1_13":{"set_property":{"coslang:x":1,"coslang:y":13}},"coslang:set_1_14":{"set_property":{"coslang:x":1,"coslang:y":14}},"coslang:set_1_15":{"set_property":{"coslang:x":1,"coslang:y":15}},"coslang:set_2_0":{"set_property":{"coslang:x":2,"coslang:y":0}},"coslang:set_2_1":{"set_property":{"coslang:x":2,"coslang:y":1}},"coslang:set_2_2":{"set_property":{"coslang:x":2,"coslang:y":2}},"coslang:set_2_3":{"set_property":{"coslang:x":2,"coslang:y":3}},"coslang:set_2_4":{"set_property":{"coslang:x":2,"coslang:y":4}},"coslang:set_2_5":{"set_property":{"coslang:x":2,"coslang:y":5}},"coslang:set_2_6":{"set_property":{"coslang:x":2,"coslang:y":6}},"coslang:set_2_7":{"set_property":{"coslang:x":2,"coslang:y":7}},"coslang:set_2_8":{"set_property":{"coslang:x":2,"coslang:y":8}},"coslang:set_2_9":{"set_property":{"coslang:x":2,"coslang:y":9}},"coslang:set_2_10":{"set_property":{"coslang:x":2,"coslang:y":10}},"coslang:set_2_11":{"set_property":{"coslang:x":2,"coslang:y":11}},"coslang:set_2_12":{"set_property":{"coslang:x":2,"coslang:y":12}},"coslang:set_2_13":{"set_property":{"coslang:x":2,"coslang:y":13}},"coslang:set_2_14":{"set_property":{"coslang:x":2,"coslang:y":14}},"coslang:set_2_15":{"set_property":{"coslang:x":2,"coslang:y":15}},"coslang:set_3_0":{"set_property":{"coslang:x":3,"coslang:y":0}},"coslang:set_3_1":{"set_property":{"coslang:x":3,"coslang:y":1}},"coslang:set_3_2":{"set_property":{"coslang:x":3,"coslang:y":2}},"coslang:set_3_3":{"set_property":{"coslang:x":3,"coslang:y":3}},"coslang:set_3_4":{"set_property":{"coslang:x":3,"coslang:y":4}},"coslang:set_3_5":{"set_property":{"coslang:x":3,"coslang:y":5}},"coslang:set_3_6":{"set_property":{"coslang:x":3,"coslang:y":6}},"coslang:set_3_7":{"set_property":{"coslang:x":3,"coslang:y":7}},"coslang:set_3_8":{"set_property":{"coslang:x":3,"coslang:y":8}},"coslang:set_3_9":{"set_property":{"coslang:x":3,"coslang:y":9}},"coslang:set_3_10":{"set_property":{"coslang:x":3,"coslang:y":10}},"coslang:set_3_11":{"set_property":{"coslang:x":3,"coslang:y":11}},"coslang:set_3_12":{"set_property":{"coslang:x":3,"coslang:y":12}},"coslang:set_3_13":{"set_property":{"coslang:x":3,"coslang:y":13}},"coslang:set_3_14":{"set_property":{"coslang:x":3,"coslang:y":14}},"coslang:set_3_15":{"set_property":{"coslang:x":3,"coslang:y":15}},"coslang:set_4_0":{"set_property":{"coslang:x":4,"coslang:y":0}},"coslang:set_4_1":{"set_property":{"coslang:x":4,"coslang:y":1}},"coslang:set_4_2":{"set_property":{"coslang:x":4,"coslang:y":2}},"coslang:set_4_3":{"set_property":{"coslang:x":4,"coslang:y":3}},"coslang:set_4_4":{"set_property":{"coslang:x":4,"coslang:y":4}},"coslang:set_4_5":{"set_property":{"coslang:x":4,"coslang:y":5}},"coslang:set_4_6":{"set_property":{"coslang:x":4,"coslang:y":6}},"coslang:set_4_7":{"set_property":{"coslang:x":4,"coslang:y":7}},"coslang:set_4_8":{"set_property":{"coslang:x":4,"coslang:y":8}},"coslang:set_4_9":{"set_property":{"coslang:x":4,"coslang:y":9}},"coslang:set_4_10":{"set_property":{"coslang:x":4,"coslang:y":10}},"coslang:set_4_11":{"set_property":{"coslang:x":4,"coslang:y":11}},"coslang:set_4_12":{"set_property":{"coslang:x":4,"coslang:y":12}},"coslang:set_4_13":{"set_property":{"coslang:x":4,"coslang:y":13}},"coslang:set_4_14":{"set_property":{"coslang:x":4,"coslang:y":14}},"coslang:set_4_15":{"set_property":{"coslang:x":4,"coslang:y":15}},"coslang:set_5_0":{"set_property":{"coslang:x":5,"coslang:y":0}},"coslang:set_5_1":{"set_property":{"coslang:x":5,"coslang:y":1}},"coslang:set_5_2":{"set_property":{"coslang:x":5,"coslang:y":2}},"coslang:set_5_3":{"set_property":{"coslang:x":5,"coslang:y":3}},"coslang:set_5_4":{"set_property":{"coslang:x":5,"coslang:y":4}},"coslang:set_5_5":{"set_property":{"coslang:x":5,"coslang:y":5}},"coslang:set_5_6":{"set_property":{"coslang:x":5,"coslang:y":6}},"coslang:set_5_7":{"set_property":{"coslang:x":5,"coslang:y":7}},"coslang:set_5_8":{"set_property":{"coslang:x":5,"coslang:y":8}},"coslang:set_5_9":{"set_property":{"coslang:x":5,"coslang:y":9}},"coslang:set_5_10":{"set_property":{"coslang:x":5,"coslang:y":10}},"coslang:set_5_11":{"set_property":{"coslang:x":5,"coslang:y":11}},"coslang:set_5_12":{"set_property":{"coslang:x":5,"coslang:y":12}},"coslang:set_5_13":{"set_property":{"coslang:x":5,"coslang:y":13}},"coslang:set_5_14":{"set_property":{"coslang:x":5,"coslang:y":14}},"coslang:set_5_15":{"set_property":{"coslang:x":5,"coslang:y":15}},"coslang:set_6_0":{"set_property":{"coslang:x":6,"coslang:y":0}},"coslang:set_6_1":{"set_property":{"coslang:x":6,"coslang:y":1}},"coslang:set_6_2":{"set_property":{"coslang:x":6,"coslang:y":2}},"coslang:set_6_3":{"set_property":{"coslang:x":6,"coslang:y":3}},"coslang:set_6_4":{"set_property":{"coslang:x":6,"coslang:y":4}},"coslang:set_6_5":{"set_property":{"coslang:x":6,"coslang:y":5}},"coslang:set_6_6":{"set_property":{"coslang:x":6,"coslang:y":6}},"coslang:set_6_7":{"set_property":{"coslang:x":6,"coslang:y":7}},"coslang:set_6_8":{"set_property":{"coslang:x":6,"coslang:y":8}},"coslang:set_6_9":{"set_property":{"coslang:x":6,"coslang:y":9}},"coslang:set_6_10":{"set_property":{"coslang:x":6,"coslang:y":10}},"coslang:set_6_11":{"set_property":{"coslang:x":6,"coslang:y":11}},"coslang:set_6_12":{"set_property":{"coslang:x":6,"coslang:y":12}},"coslang:set_6_13":{"set_property":{"coslang:x":6,"coslang:y":13}},"coslang:set_6_14":{"set_property":{"coslang:x":6,"coslang:y":14}},"coslang:set_6_15":{"set_property":{"coslang:x":6,"coslang:y":15}},"coslang:set_7_0":{"set_property":{"coslang:x":7,"coslang:y":0}},"coslang:set_7_1":{"set_property":{"coslang:x":7,"coslang:y":1}},"coslang:set_7_2":{"set_property":{"coslang:x":7,"coslang:y":2}},"coslang:set_7_3":{"set_property":{"coslang:x":7,"coslang:y":3}},"coslang:set_7_4":{"set_property":{"coslang:x":7,"coslang:y":4}},"coslang:set_7_5":{"set_property":{"coslang:x":7,"coslang:y":5}},"coslang:set_7_6":{"set_property":{"coslang:x":7,"coslang:y":6}},"coslang:set_7_7":{"set_property":{"coslang:x":7,"coslang:y":7}},"coslang:set_7_8":{"set_property":{"coslang:x":7,"coslang:y":8}},"coslang:set_7_9":{"set_property":{"coslang:x":7,"coslang:y":9}},"coslang:set_7_10":{"set_property":{"coslang:x":7,"coslang:y":10}},"coslang:set_7_11":{"set_property":{"coslang:x":7,"coslang:y":11}},"coslang:set_7_12":{"set_property":{"coslang:x":7,"coslang:y":12}},"coslang:set_7_13":{"set_property":{"coslang:x":7,"coslang:y":13}},"coslang:set_7_14":{"set_property":{"coslang:x":7,"coslang:y":14}},"coslang:set_7_15":{"set_property":{"coslang:x":7,"coslang:y":15}},"coslang:set_8_0":{"set_property":{"coslang:x":8,"coslang:y":0}},"coslang:set_8_1":{"set_property":{"coslang:x":8,"coslang:y":1}},"coslang:set_8_2":{"set_property":{"coslang:x":8,"coslang:y":2}},"coslang:set_8_3":{"set_property":{"coslang:x":8,"coslang:y":3}},"coslang:set_8_4":{"set_property":{"coslang:x":8,"coslang:y":4}},"coslang:set_8_5":{"set_property":{"coslang:x":8,"coslang:y":5}},"coslang:set_8_6":{"set_property":{"coslang:x":8,"coslang:y":6}},"coslang:set_8_7":{"set_property":{"coslang:x":8,"coslang:y":7}},"coslang:set_8_8":{"set_property":{"coslang:x":8,"coslang:y":8}},"coslang:set_8_9":{"set_property":{"coslang:x":8,"coslang:y":9}},"coslang:set_8_10":{"set_property":{"coslang:x":8,"coslang:y":10}},"coslang:set_8_11":{"set_property":{"coslang:x":8,"coslang:y":11}},"coslang:set_8_12":{"set_property":{"coslang:x":8,"coslang:y":12}},"coslang:set_8_13":{"set_property":{"coslang:x":8,"coslang:y":13}},"coslang:set_8_14":{"set_property":{"coslang:x":8,"coslang:y":14}},"coslang:set_8_15":{"set_property":{"coslang:x":8,"coslang:y":15}},"coslang:set_9_0":{"set_property":{"coslang:x":9,"coslang:y":0}},"coslang:set_9_1":{"set_property":{"coslang:x":9,"coslang:y":1}},"coslang:set_9_2":{"set_property":{"coslang:x":9,"coslang:y":2}},"coslang:set_9_3":{"set_property":{"coslang:x":9,"coslang:y":3}},"coslang:set_9_4":{"set_property":{"coslang:x":9,"coslang:y":4}},"coslang:set_9_5":{"set_property":{"coslang:x":9,"coslang:y":5}},"coslang:set_9_6":{"set_property":{"coslang:x":9,"coslang:y":6}},"coslang:set_9_7":{"set_property":{"coslang:x":9,"coslang:y":7}},"coslang:set_9_8":{"set_property":{"coslang:x":9,"coslang:y":8}},"coslang:set_9_9":{"set_property":{"coslang:x":9,"coslang:y":9}},"coslang:set_9_10":{"set_property":{"coslang:x":9,"coslang:y":10}},"coslang:set_9_11":{"set_property":{"coslang:x":9,"coslang:y":11}},"coslang:set_9_12":{"set_property":{"coslang:x":9,"coslang:y":12}},"coslang:set_9_13":{"set_property":{"coslang:x":9,"coslang:y":13}},"coslang:set_9_14":{"set_property":{"coslang:x":9,"coslang:y":14}},"coslang:set_9_15":{"set_property":{"coslang:x":9,"coslang:y":15}},"coslang:set_10_0":{"set_property":{"coslang:x":10,"coslang:y":0}},"coslang:set_10_1":{"set_property":{"coslang:x":10,"coslang:y":1}},"coslang:set_10_2":{"set_property":{"coslang:x":10,"coslang:y":2}},"coslang:set_10_3":{"set_property":{"coslang:x":10,"coslang:y":3}},"coslang:set_10_4":{"set_property":{"coslang:x":10,"coslang:y":4}},"coslang:set_10_5":{"set_property":{"coslang:x":10,"coslang:y":5}},"coslang:set_10_6":{"set_property":{"coslang:x":10,"coslang:y":6}},"coslang:set_10_7":{"set_property":{"coslang:x":10,"coslang:y":7}},"coslang:set_10_8":{"set_property":{"coslang:x":10,"coslang:y":8}},"coslang:set_10_9":{"set_property":{"coslang:x":10,"coslang:y":9}},"coslang:set_10_10":{"set_property":{"coslang:x":10,"coslang:y":10}},"coslang:set_10_11":{"set_property":{"coslang:x":10,"coslang:y":11}},"coslang:set_10_12":{"set_property":{"coslang:x":10,"coslang:y":12}},"coslang:set_10_13":{"set_property":{"coslang:x":10,"coslang:y":13}},"coslang:set_10_14":{"set_property":{"coslang:x":10,"coslang:y":14}},"coslang:set_10_15":{"set_property":{"coslang:x":10,"coslang:y":15}},"coslang:set_11_0":{"set_property":{"coslang:x":11,"coslang:y":0}},"coslang:set_11_1":{"set_property":{"coslang:x":11,"coslang:y":1}},"coslang:set_11_2":{"set_property":{"coslang:x":11,"coslang:y":2}},"coslang:set_11_3":{"set_property":{"coslang:x":11,"coslang:y":3}},"coslang:set_11_4":{"set_property":{"coslang:x":11,"coslang:y":4}},"coslang:set_11_5":{"set_property":{"coslang:x":11,"coslang:y":5}},"coslang:set_11_6":{"set_property":{"coslang:x":11,"coslang:y":6}},"coslang:set_11_7":{"set_property":{"coslang:x":11,"coslang:y":7}},"coslang:set_11_8":{"set_property":{"coslang:x":11,"coslang:y":8}},"coslang:set_11_9":{"set_property":{"coslang:x":11,"coslang:y":9}},"coslang:set_11_10":{"set_property":{"coslang:x":11,"coslang:y":10}},"coslang:set_11_11":{"set_property":{"coslang:x":11,"coslang:y":11}},"coslang:set_11_12":{"set_property":{"coslang:x":11,"coslang:y":12}},"coslang:set_11_13":{"set_property":{"coslang:x":11,"coslang:y":13}},"coslang:set_11_14":{"set_property":{"coslang:x":11,"coslang:y":14}},"coslang:set_11_15":{"set_property":{"coslang:x":11,"coslang:y":15}},"coslang:set_12_0":{"set_property":{"coslang:x":12,"coslang:y":0}},"coslang:set_12_1":{"set_property":{"coslang:x":12,"coslang:y":1}},"coslang:set_12_2":{"set_property":{"coslang:x":12,"coslang:y":2}},"coslang:set_12_3":{"set_property":{"coslang:x":12,"coslang:y":3}},"coslang:set_12_4":{"set_property":{"coslang:x":12,"coslang:y":4}},"coslang:set_12_5":{"set_property":{"coslang:x":12,"coslang:y":5}},"coslang:set_12_6":{"set_property":{"coslang:x":12,"coslang:y":6}},"coslang:set_12_7":{"set_property":{"coslang:x":12,"coslang:y":7}},"coslang:set_12_8":{"set_property":{"coslang:x":12,"coslang:y":8}},"coslang:set_12_9":{"set_property":{"coslang:x":12,"coslang:y":9}},"coslang:set_12_10":{"set_property":{"coslang:x":12,"coslang:y":10}},"coslang:set_12_11":{"set_property":{"coslang:x":12,"coslang:y":11}},"coslang:set_12_12":{"set_property":{"coslang:x":12,"coslang:y":12}},"coslang:set_12_13":{"set_property":{"coslang:x":12,"coslang:y":13}},"coslang:set_12_14":{"set_property":{"coslang:x":12,"coslang:y":14}},"coslang:set_12_15":{"set_property":{"coslang:x":12,"coslang:y":15}},"coslang:set_13_0":{"set_property":{"coslang:x":13,"coslang:y":0}},"coslang:set_13_1":{"set_property":{"coslang:x":13,"coslang:y":1}},"coslang:set_13_2":{"set_property":{"coslang:x":13,"coslang:y":2}},"coslang:set_13_3":{"set_property":{"coslang:x":13,"coslang:y":3}},"coslang:set_13_4":{"set_property":{"coslang:x":13,"coslang:y":4}},"coslang:set_13_5":{"set_property":{"coslang:x":13,"coslang:y":5}},"coslang:set_13_6":{"set_property":{"coslang:x":13,"coslang:y":6}},"coslang:set_13_7":{"set_property":{"coslang:x":13,"coslang:y":7}},"coslang:set_13_8":{"set_property":{"coslang:x":13,"coslang:y":8}},"coslang:set_13_9":{"set_property":{"coslang:x":13,"coslang:y":9}},"coslang:set_13_10":{"set_property":{"coslang:x":13,"coslang:y":10}},"coslang:set_13_11":{"set_property":{"coslang:x":13,"coslang:y":11}},"coslang:set_13_12":{"set_property":{"coslang:x":13,"coslang:y":12}},"coslang:set_13_13":{"set_property":{"coslang:x":13,"coslang:y":13}},"coslang:set_13_14":{"set_property":{"coslang:x":13,"coslang:y":14}},"coslang:set_13_15":{"set_property":{"coslang:x":13,"coslang:y":15}},"coslang:set_14_0":{"set_property":{"coslang:x":14,"coslang:y":0}},"coslang:set_14_1":{"set_property":{"coslang:x":14,"coslang:y":1}},"coslang:set_14_2":{"set_property":{"coslang:x":14,"coslang:y":2}},"coslang:set_14_3":{"set_property":{"coslang:x":14,"coslang:y":3}},"coslang:set_14_4":{"set_property":{"coslang:x":14,"coslang:y":4}},"coslang:set_14_5":{"set_property":{"coslang:x":14,"coslang:y":5}},"coslang:set_14_6":{"set_property":{"coslang:x":14,"coslang:y":6}},"coslang:set_14_7":{"set_property":{"coslang:x":14,"coslang:y":7}},"coslang:set_14_8":{"set_property":{"coslang:x":14,"coslang:y":8}},"coslang:set_14_9":{"set_property":{"coslang:x":14,"coslang:y":9}},"coslang:set_14_10":{"set_property":{"coslang:x":14,"coslang:y":10}},"coslang:set_14_11":{"set_property":{"coslang:x":14,"coslang:y":11}},"coslang:set_14_12":{"set_property":{"coslang:x":14,"coslang:y":12}},"coslang:set_14_13":{"set_property":{"coslang:x":14,"coslang:y":13}},"coslang:set_14_14":{"set_property":{"coslang:x":14,"coslang:y":14}},"coslang:set_14_15":{"set_property":{"coslang:x":14,"coslang:y":15}},"coslang:set_15_0":{"set_property":{"coslang:x":15,"coslang:y":0}},"coslang:set_15_1":{"set_property":{"coslang:x":15,"coslang:y":1}},"coslang:set_15_2":{"set_property":{"coslang:x":15,"coslang:y":2}},"coslang:set_15_3":{"set_property":{"coslang:x":15,"coslang:y":3}},"coslang:set_15_4":{"set_property":{"coslang:x":15,"coslang:y":4}},"coslang:set_15_5":{"set_property":{"coslang:x":15,"coslang:y":5}},"coslang:set_15_6":{"set_property":{"coslang:x":15,"coslang:y":6}},"coslang:set_15_7":{"set_property":{"coslang:x":15,"coslang:y":7}},"coslang:set_15_8":{"set_property":{"coslang:x":15,"coslang:y":8}},"coslang:set_15_9":{"set_property":{"coslang:x":15,"coslang:y":9}},"coslang:set_15_10":{"set_property":{"coslang:x":15,"coslang:y":10}},"coslang:set_15_11":{"set_property":{"coslang:x":15,"coslang:y":11}},"coslang:set_15_12":{"set_property":{"coslang:x":15,"coslang:y":12}},"coslang:set_15_13":{"set_property":{"coslang:x":15,"coslang:y":13}},"coslang:set_15_14":{"set_property":{"coslang:x":15,"coslang:y":14}},"coslang:set_15_15":{"set_property":{"coslang:x":15,"coslang:y":15}},"coslang:size_1_1":{"set_property":{"coslang:x_size":1,"coslang:y_size":1}},"coslang:size_1_2":{"set_property":{"coslang:x_size":1,"coslang:y_size":2}},"coslang:size_1_3":{"set_property":{"coslang:x_size":1,"coslang:y_size":3}},"coslang:size_1_4":{"set_property":{"coslang:x_size":1,"coslang:y_size":4}},"coslang:size_1_5":{"set_property":{"coslang:x_size":1,"coslang:y_size":5}},"coslang:size_1_6":{"set_property":{"coslang:x_size":1,"coslang:y_size":6}},"coslang:size_1_7":{"set_property":{"coslang:x_size":1,"coslang:y_size":7}},"coslang:size_1_8":{"set_property":{"coslang:x_size":1,"coslang:y_size":8}},"coslang:size_1_9":{"set_property":{"coslang:x_size":1,"coslang:y_size":9}},"coslang:size_1_10":{"set_property":{"coslang:x_size":1,"coslang:y_size":10}},"coslang:size_1_11":{"set_property":{"coslang:x_size":1,"coslang:y_size":11}},"coslang:size_1_12":{"set_property":{"coslang:x_size":1,"coslang:y_size":12}},"coslang:size_1_13":{"set_property":{"coslang:x_size":1,"coslang:y_size":13}},"coslang:size_1_14":{"set_property":{"coslang:x_size":1,"coslang:y_size":14}},"coslang:size_1_15":{"set_property":{"coslang:x_size":1,"coslang:y_size":15}},"coslang:size_1_16":{"set_property":{"coslang:x_size":1,"coslang:y_size":16}},"coslang:size_2_1":{"set_property":{"coslang:x_size":2,"coslang:y_size":1}},"coslang:size_2_2":{"set_property":{"coslang:x_size":2,"coslang:y_size":2}},"coslang:size_2_3":{"set_property":{"coslang:x_size":2,"coslang:y_size":3}},"coslang:size_2_4":{"set_property":{"coslang:x_size":2,"coslang:y_size":4}},"coslang:size_2_5":{"set_property":{"coslang:x_size":2,"coslang:y_size":5}},"coslang:size_2_6":{"set_property":{"coslang:x_size":2,"coslang:y_size":6}},"coslang:size_2_7":{"set_property":{"coslang:x_size":2,"coslang:y_size":7}},"coslang:size_2_8":{"set_property":{"coslang:x_size":2,"coslang:y_size":8}},"coslang:size_2_9":{"set_property":{"coslang:x_size":2,"coslang:y_size":9}},"coslang:size_2_10":{"set_property":{"coslang:x_size":2,"coslang:y_size":10}},"coslang:size_2_11":{"set_property":{"coslang:x_size":2,"coslang:y_size":11}},"coslang:size_2_12":{"set_property":{"coslang:x_size":2,"coslang:y_size":12}},"coslang:size_2_13":{"set_property":{"coslang:x_size":2,"coslang:y_size":13}},"coslang:size_2_14":{"set_property":{"coslang:x_size":2,"coslang:y_size":14}},"coslang:size_2_15":{"set_property":{"coslang:x_size":2,"coslang:y_size":15}},"coslang:size_2_16":{"set_property":{"coslang:x_size":2,"coslang:y_size":16}},"coslang:size_3_1":{"set_property":{"coslang:x_size":3,"coslang:y_size":1}},"coslang:size_3_2":{"set_property":{"coslang:x_size":3,"coslang:y_size":2}},"coslang:size_3_3":{"set_property":{"coslang:x_size":3,"coslang:y_size":3}},"coslang:size_3_4":{"set_property":{"coslang:x_size":3,"coslang:y_size":4}},"coslang:size_3_5":{"set_property":{"coslang:x_size":3,"coslang:y_size":5}},"coslang:size_3_6":{"set_property":{"coslang:x_size":3,"coslang:y_size":6}},"coslang:size_3_7":{"set_property":{"coslang:x_size":3,"coslang:y_size":7}},"coslang:size_3_8":{"set_property":{"coslang:x_size":3,"coslang:y_size":8}},"coslang:size_3_9":{"set_property":{"coslang:x_size":3,"coslang:y_size":9}},"coslang:size_3_10":{"set_property":{"coslang:x_size":3,"coslang:y_size":10}},"coslang:size_3_11":{"set_property":{"coslang:x_size":3,"coslang:y_size":11}},"coslang:size_3_12":{"set_property":{"coslang:x_size":3,"coslang:y_size":12}},"coslang:size_3_13":{"set_property":{"coslang:x_size":3,"coslang:y_size":13}},"coslang:size_3_14":{"set_property":{"coslang:x_size":3,"coslang:y_size":14}},"coslang:size_3_15":{"set_property":{"coslang:x_size":3,"coslang:y_size":15}},"coslang:size_3_16":{"set_property":{"coslang:x_size":3,"coslang:y_size":16}},"coslang:size_4_1":{"set_property":{"coslang:x_size":4,"coslang:y_size":1}},"coslang:size_4_2":{"set_property":{"coslang:x_size":4,"coslang:y_size":2}},"coslang:size_4_3":{"set_property":{"coslang:x_size":4,"coslang:y_size":3}},"coslang:size_4_4":{"set_property":{"coslang:x_size":4,"coslang:y_size":4}},"coslang:size_4_5":{"set_property":{"coslang:x_size":4,"coslang:y_size":5}},"coslang:size_4_6":{"set_property":{"coslang:x_size":4,"coslang:y_size":6}},"coslang:size_4_7":{"set_property":{"coslang:x_size":4,"coslang:y_size":7}},"coslang:size_4_8":{"set_property":{"coslang:x_size":4,"coslang:y_size":8}},"coslang:size_4_9":{"set_property":{"coslang:x_size":4,"coslang:y_size":9}},"coslang:size_4_10":{"set_property":{"coslang:x_size":4,"coslang:y_size":10}},"coslang:size_4_11":{"set_property":{"coslang:x_size":4,"coslang:y_size":11}},"coslang:size_4_12":{"set_property":{"coslang:x_size":4,"coslang:y_size":12}},"coslang:size_4_13":{"set_property":{"coslang:x_size":4,"coslang:y_size":13}},"coslang:size_4_14":{"set_property":{"coslang:x_size":4,"coslang:y_size":14}},"coslang:size_4_15":{"set_property":{"coslang:x_size":4,"coslang:y_size":15}},"coslang:size_4_16":{"set_property":{"coslang:x_size":4,"coslang:y_size":16}},"coslang:size_5_1":{"set_property":{"coslang:x_size":5,"coslang:y_size":1}},"coslang:size_5_2":{"set_property":{"coslang:x_size":5,"coslang:y_size":2}},"coslang:size_5_3":{"set_property":{"coslang:x_size":5,"coslang:y_size":3}},"coslang:size_5_4":{"set_property":{"coslang:x_size":5,"coslang:y_size":4}},"coslang:size_5_5":{"set_property":{"coslang:x_size":5,"coslang:y_size":5}},"coslang:size_5_6":{"set_property":{"coslang:x_size":5,"coslang:y_size":6}},"coslang:size_5_7":{"set_property":{"coslang:x_size":5,"coslang:y_size":7}},"coslang:size_5_8":{"set_property":{"coslang:x_size":5,"coslang:y_size":8}},"coslang:size_5_9":{"set_property":{"coslang:x_size":5,"coslang:y_size":9}},"coslang:size_5_10":{"set_property":{"coslang:x_size":5,"coslang:y_size":10}},"coslang:size_5_11":{"set_property":{"coslang:x_size":5,"coslang:y_size":11}},"coslang:size_5_12":{"set_property":{"coslang:x_size":5,"coslang:y_size":12}},"coslang:size_5_13":{"set_property":{"coslang:x_size":5,"coslang:y_size":13}},"coslang:size_5_14":{"set_property":{"coslang:x_size":5,"coslang:y_size":14}},"coslang:size_5_15":{"set_property":{"coslang:x_size":5,"coslang:y_size":15}},"coslang:size_5_16":{"set_property":{"coslang:x_size":5,"coslang:y_size":16}},"coslang:size_6_1":{"set_property":{"coslang:x_size":6,"coslang:y_size":1}},"coslang:size_6_2":{"set_property":{"coslang:x_size":6,"coslang:y_size":2}},"coslang:size_6_3":{"set_property":{"coslang:x_size":6,"coslang:y_size":3}},"coslang:size_6_4":{"set_property":{"coslang:x_size":6,"coslang:y_size":4}},"coslang:size_6_5":{"set_property":{"coslang:x_size":6,"coslang:y_size":5}},"coslang:size_6_6":{"set_property":{"coslang:x_size":6,"coslang:y_size":6}},"coslang:size_6_7":{"set_property":{"coslang:x_size":6,"coslang:y_size":7}},"coslang:size_6_8":{"set_property":{"coslang:x_size":6,"coslang:y_size":8}},"coslang:size_6_9":{"set_property":{"coslang:x_size":6,"coslang:y_size":9}},"coslang:size_6_10":{"set_property":{"coslang:x_size":6,"coslang:y_size":10}},"coslang:size_6_11":{"set_property":{"coslang:x_size":6,"coslang:y_size":11}},"coslang:size_6_12":{"set_property":{"coslang:x_size":6,"coslang:y_size":12}},"coslang:size_6_13":{"set_property":{"coslang:x_size":6,"coslang:y_size":13}},"coslang:size_6_14":{"set_property":{"coslang:x_size":6,"coslang:y_size":14}},"coslang:size_6_15":{"set_property":{"coslang:x_size":6,"coslang:y_size":15}},"coslang:size_6_16":{"set_property":{"coslang:x_size":6,"coslang:y_size":16}},"coslang:size_7_1":{"set_property":{"coslang:x_size":7,"coslang:y_size":1}},"coslang:size_7_2":{"set_property":{"coslang:x_size":7,"coslang:y_size":2}},"coslang:size_7_3":{"set_property":{"coslang:x_size":7,"coslang:y_size":3}},"coslang:size_7_4":{"set_property":{"coslang:x_size":7,"coslang:y_size":4}},"coslang:size_7_5":{"set_property":{"coslang:x_size":7,"coslang:y_size":5}},"coslang:size_7_6":{"set_property":{"coslang:x_size":7,"coslang:y_size":6}},"coslang:size_7_7":{"set_property":{"coslang:x_size":7,"coslang:y_size":7}},"coslang:size_7_8":{"set_property":{"coslang:x_size":7,"coslang:y_size":8}},"coslang:size_7_9":{"set_property":{"coslang:x_size":7,"coslang:y_size":9}},"coslang:size_7_10":{"set_property":{"coslang:x_size":7,"coslang:y_size":10}},"coslang:size_7_11":{"set_property":{"coslang:x_size":7,"coslang:y_size":11}},"coslang:size_7_12":{"set_property":{"coslang:x_size":7,"coslang:y_size":12}},"coslang:size_7_13":{"set_property":{"coslang:x_size":7,"coslang:y_size":13}},"coslang:size_7_14":{"set_property":{"coslang:x_size":7,"coslang:y_size":14}},"coslang:size_7_15":{"set_property":{"coslang:x_size":7,"coslang:y_size":15}},"coslang:size_7_16":{"set_property":{"coslang:x_size":7,"coslang:y_size":16}},"coslang:size_8_1":{"set_property":{"coslang:x_size":8,"coslang:y_size":1}},"coslang:size_8_2":{"set_property":{"coslang:x_size":8,"coslang:y_size":2}},"coslang:size_8_3":{"set_property":{"coslang:x_size":8,"coslang:y_size":3}},"coslang:size_8_4":{"set_property":{"coslang:x_size":8,"coslang:y_size":4}},"coslang:size_8_5":{"set_property":{"coslang:x_size":8,"coslang:y_size":5}},"coslang:size_8_6":{"set_property":{"coslang:x_size":8,"coslang:y_size":6}},"coslang:size_8_7":{"set_property":{"coslang:x_size":8,"coslang:y_size":7}},"coslang:size_8_8":{"set_property":{"coslang:x_size":8,"coslang:y_size":8}},"coslang:size_8_9":{"set_property":{"coslang:x_size":8,"coslang:y_size":9}},"coslang:size_8_10":{"set_property":{"coslang:x_size":8,"coslang:y_size":10}},"coslang:size_8_11":{"set_property":{"coslang:x_size":8,"coslang:y_size":11}},"coslang:size_8_12":{"set_property":{"coslang:x_size":8,"coslang:y_size":12}},"coslang:size_8_13":{"set_property":{"coslang:x_size":8,"coslang:y_size":13}},"coslang:size_8_14":{"set_property":{"coslang:x_size":8,"coslang:y_size":14}},"coslang:size_8_15":{"set_property":{"coslang:x_size":8,"coslang:y_size":15}},"coslang:size_8_16":{"set_property":{"coslang:x_size":8,"coslang:y_size":16}},"coslang:size_9_1":{"set_property":{"coslang:x_size":9,"coslang:y_size":1}},"coslang:size_9_2":{"set_property":{"coslang:x_size":9,"coslang:y_size":2}},"coslang:size_9_3":{"set_property":{"coslang:x_size":9,"coslang:y_size":3}},"coslang:size_9_4":{"set_property":{"coslang:x_size":9,"coslang:y_size":4}},"coslang:size_9_5":{"set_property":{"coslang:x_size":9,"coslang:y_size":5}},"coslang:size_9_6":{"set_property":{"coslang:x_size":9,"coslang:y_size":6}},"coslang:size_9_7":{"set_property":{"coslang:x_size":9,"coslang:y_size":7}},"coslang:size_9_8":{"set_property":{"coslang:x_size":9,"coslang:y_size":8}},"coslang:size_9_9":{"set_property":{"coslang:x_size":9,"coslang:y_size":9}},"coslang:size_9_10":{"set_property":{"coslang:x_size":9,"coslang:y_size":10}},"coslang:size_9_11":{"set_property":{"coslang:x_size":9,"coslang:y_size":11}},"coslang:size_9_12":{"set_property":{"coslang:x_size":9,"coslang:y_size":12}},"coslang:size_9_13":{"set_property":{"coslang:x_size":9,"coslang:y_size":13}},"coslang:size_9_14":{"set_property":{"coslang:x_size":9,"coslang:y_size":14}},"coslang:size_9_15":{"set_property":{"coslang:x_size":9,"coslang:y_size":15}},"coslang:size_9_16":{"set_property":{"coslang:x_size":9,"coslang:y_size":16}},"coslang:size_10_1":{"set_property":{"coslang:x_size":10,"coslang:y_size":1}},"coslang:size_10_2":{"set_property":{"coslang:x_size":10,"coslang:y_size":2}},"coslang:size_10_3":{"set_property":{"coslang:x_size":10,"coslang:y_size":3}},"coslang:size_10_4":{"set_property":{"coslang:x_size":10,"coslang:y_size":4}},"coslang:size_10_5":{"set_property":{"coslang:x_size":10,"coslang:y_size":5}},"coslang:size_10_6":{"set_property":{"coslang:x_size":10,"coslang:y_size":6}},"coslang:size_10_7":{"set_property":{"coslang:x_size":10,"coslang:y_size":7}},"coslang:size_10_8":{"set_property":{"coslang:x_size":10,"coslang:y_size":8}},"coslang:size_10_9":{"set_property":{"coslang:x_size":10,"coslang:y_size":9}},"coslang:size_10_10":{"set_property":{"coslang:x_size":10,"coslang:y_size":10}},"coslang:size_10_11":{"set_property":{"coslang:x_size":10,"coslang:y_size":11}},"coslang:size_10_12":{"set_property":{"coslang:x_size":10,"coslang:y_size":12}},"coslang:size_10_13":{"set_property":{"coslang:x_size":10,"coslang:y_size":13}},"coslang:size_10_14":{"set_property":{"coslang:x_size":10,"coslang:y_size":14}},"coslang:size_10_15":{"set_property":{"coslang:x_size":10,"coslang:y_size":15}},"coslang:size_10_16":{"set_property":{"coslang:x_size":10,"coslang:y_size":16}},"coslang:size_11_1":{"set_property":{"coslang:x_size":11,"coslang:y_size":1}},"coslang:size_11_2":{"set_property":{"coslang:x_size":11,"coslang:y_size":2}},"coslang:size_11_3":{"set_property":{"coslang:x_size":11,"coslang:y_size":3}},"coslang:size_11_4":{"set_property":{"coslang:x_size":11,"coslang:y_size":4}},"coslang:size_11_5":{"set_property":{"coslang:x_size":11,"coslang:y_size":5}},"coslang:size_11_6":{"set_property":{"coslang:x_size":11,"coslang:y_size":6}},"coslang:size_11_7":{"set_property":{"coslang:x_size":11,"coslang:y_size":7}},"coslang:size_11_8":{"set_property":{"coslang:x_size":11,"coslang:y_size":8}},"coslang:size_11_9":{"set_property":{"coslang:x_size":11,"coslang:y_size":9}},"coslang:size_11_10":{"set_property":{"coslang:x_size":11,"coslang:y_size":10}},"coslang:size_11_11":{"set_property":{"coslang:x_size":11,"coslang:y_size":11}},"coslang:size_11_12":{"set_property":{"coslang:x_size":11,"coslang:y_size":12}},"coslang:size_11_13":{"set_property":{"coslang:x_size":11,"coslang:y_size":13}},"coslang:size_11_14":{"set_property":{"coslang:x_size":11,"coslang:y_size":14}},"coslang:size_11_15":{"set_property":{"coslang:x_size":11,"coslang:y_size":15}},"coslang:size_11_16":{"set_property":{"coslang:x_size":11,"coslang:y_size":16}},"coslang:size_12_1":{"set_property":{"coslang:x_size":12,"coslang:y_size":1}},"coslang:size_12_2":{"set_property":{"coslang:x_size":12,"coslang:y_size":2}},"coslang:size_12_3":{"set_property":{"coslang:x_size":12,"coslang:y_size":3}},"coslang:size_12_4":{"set_property":{"coslang:x_size":12,"coslang:y_size":4}},"coslang:size_12_5":{"set_property":{"coslang:x_size":12,"coslang:y_size":5}},"coslang:size_12_6":{"set_property":{"coslang:x_size":12,"coslang:y_size":6}},"coslang:size_12_7":{"set_property":{"coslang:x_size":12,"coslang:y_size":7}},"coslang:size_12_8":{"set_property":{"coslang:x_size":12,"coslang:y_size":8}},"coslang:size_12_9":{"set_property":{"coslang:x_size":12,"coslang:y_size":9}},"coslang:size_12_10":{"set_property":{"coslang:x_size":12,"coslang:y_size":10}},"coslang:size_12_11":{"set_property":{"coslang:x_size":12,"coslang:y_size":11}},"coslang:size_12_12":{"set_property":{"coslang:x_size":12,"coslang:y_size":12}},"coslang:size_12_13":{"set_property":{"coslang:x_size":12,"coslang:y_size":13}},"coslang:size_12_14":{"set_property":{"coslang:x_size":12,"coslang:y_size":14}},"coslang:size_12_15":{"set_property":{"coslang:x_size":12,"coslang:y_size":15}},"coslang:size_12_16":{"set_property":{"coslang:x_size":12,"coslang:y_size":16}},"coslang:size_13_1":{"set_property":{"coslang:x_size":13,"coslang:y_size":1}},"coslang:size_13_2":{"set_property":{"coslang:x_size":13,"coslang:y_size":2}},"coslang:size_13_3":{"set_property":{"coslang:x_size":13,"coslang:y_size":3}},"coslang:size_13_4":{"set_property":{"coslang:x_size":13,"coslang:y_size":4}},"coslang:size_13_5":{"set_property":{"coslang:x_size":13,"coslang:y_size":5}},"coslang:size_13_6":{"set_property":{"coslang:x_size":13,"coslang:y_size":6}},"coslang:size_13_7":{"set_property":{"coslang:x_size":13,"coslang:y_size":7}},"coslang:size_13_8":{"set_property":{"coslang:x_size":13,"coslang:y_size":8}},"coslang:size_13_9":{"set_property":{"coslang:x_size":13,"coslang:y_size":9}},"coslang:size_13_10":{"set_property":{"coslang:x_size":13,"coslang:y_size":10}},"coslang:size_13_11":{"set_property":{"coslang:x_size":13,"coslang:y_size":11}},"coslang:size_13_12":{"set_property":{"coslang:x_size":13,"coslang:y_size":12}},"coslang:size_13_13":{"set_property":{"coslang:x_size":13,"coslang:y_size":13}},"coslang:size_13_14":{"set_property":{"coslang:x_size":13,"coslang:y_size":14}},"coslang:size_13_15":{"set_property":{"coslang:x_size":13,"coslang:y_size":15}},"coslang:size_13_16":{"set_property":{"coslang:x_size":13,"coslang:y_size":16}},"coslang:size_14_1":{"set_property":{"coslang:x_size":14,"coslang:y_size":1}},"coslang:size_14_2":{"set_property":{"coslang:x_size":14,"coslang:y_size":2}},"coslang:size_14_3":{"set_property":{"coslang:x_size":14,"coslang:y_size":3}},"coslang:size_14_4":{"set_property":{"coslang:x_size":14,"coslang:y_size":4}},"coslang:size_14_5":{"set_property":{"coslang:x_size":14,"coslang:y_size":5}},"coslang:size_14_6":{"set_property":{"coslang:x_size":14,"coslang:y_size":6}},"coslang:size_14_7":{"set_property":{"coslang:x_size":14,"coslang:y_size":7}},"coslang:size_14_8":{"set_property":{"coslang:x_size":14,"coslang:y_size":8}},"coslang:size_14_9":{"set_property":{"coslang:x_size":14,"coslang:y_size":9}},"coslang:size_14_10":{"set_property":{"coslang:x_size":14,"coslang:y_size":10}},"coslang:size_14_11":{"set_property":{"coslang:x_size":14,"coslang:y_size":11}},"coslang:size_14_12":{"set_property":{"coslang:x_size":14,"coslang:y_size":12}},"coslang:size_14_13":{"set_property":{"coslang:x_size":14,"coslang:y_size":13}},"coslang:size_14_14":{"set_property":{"coslang:x_size":14,"coslang:y_size":14}},"coslang:size_14_15":{"set_property":{"coslang:x_size":14,"coslang:y_size":15}},"coslang:size_14_16":{"set_property":{"coslang:x_size":14,"coslang:y_size":16}},"coslang:size_15_1":{"set_property":{"coslang:x_size":15,"coslang:y_size":1}},"coslang:size_15_2":{"set_property":{"coslang:x_size":15,"coslang:y_size":2}},"coslang:size_15_3":{"set_property":{"coslang:x_size":15,"coslang:y_size":3}},"coslang:size_15_4":{"set_property":{"coslang:x_size":15,"coslang:y_size":4}},"coslang:size_15_5":{"set_property":{"coslang:x_size":15,"coslang:y_size":5}},"coslang:size_15_6":{"set_property":{"coslang:x_size":15,"coslang:y_size":6}},"coslang:size_15_7":{"set_property":{"coslang:x_size":15,"coslang:y_size":7}},"coslang:size_15_8":{"set_property":{"coslang:x_size":15,"coslang:y_size":8}},"coslang:size_15_9":{"set_property":{"coslang:x_size":15,"coslang:y_size":9}},"coslang:size_15_10":{"set_property":{"coslang:x_size":15,"coslang:y_size":10}},"coslang:size_15_11":{"set_property":{"coslang:x_size":15,"coslang:y_size":11}},"coslang:size_15_12":{"set_property":{"coslang:x_size":15,"coslang:y_size":12}},"coslang:size_15_13":{"set_property":{"coslang:x_size":15,"coslang:y_size":13}},"coslang:size_15_14":{"set_property":{"coslang:x_size":15,"coslang:y_size":14}},"coslang:size_15_15":{"set_property":{"coslang:x_size":15,"coslang:y_size":15}},"coslang:size_15_16":{"set_property":{"coslang:x_size":15,"coslang:y_size":16}},"coslang:size_16_1":{"set_property":{"coslang:x_size":16,"coslang:y_size":1}},"coslang:size_16_2":{"set_property":{"coslang:x_size":16,"coslang:y_size":2}},"coslang:size_16_3":{"set_property":{"coslang:x_size":16,"coslang:y_size":3}},"coslang:size_16_4":{"set_property":{"coslang:x_size":16,"coslang:y_size":4}},"coslang:size_16_5":{"set_property":{"coslang:x_size":16,"coslang:y_size":5}},"coslang:size_16_6":{"set_property":{"coslang:x_size":16,"coslang:y_size":6}},"coslang:size_16_7":{"set_property":{"coslang:x_size":16,"coslang:y_size":7}},"coslang:size_16_8":{"set_property":{"coslang:x_size":16,"coslang:y_size":8}},"coslang:size_16_9":{"set_property":{"coslang:x_size":16,"coslang:y_size":9}},"coslang:size_16_10":{"set_property":{"coslang:x_size":16,"coslang:y_size":10}},"coslang:size_16_11":{"set_property":{"coslang:x_size":16,"coslang:y_size":11}},"coslang:size_16_12":{"set_property":{"coslang:x_size":16,"coslang:y_size":12}},"coslang:size_16_13":{"set_property":{"coslang:x_size":16,"coslang:y_size":13}},"coslang:size_16_14":{"set_property":{"coslang:x_size":16,"coslang:y_size":14}},"coslang:size_16_15":{"set_property":{"coslang:x_size":16,"coslang:y_size":15}},"coslang:size_16_16":{"set_property":{"coslang:x_size":16,"coslang:y_size":16}},"coslang:set_color_0":{"set_property":{"coslang:color":0}},"coslang:set_color_1":{"set_property":{"coslang:color":1}},"coslang:set_color_2":{"set_property":{"coslang:color":2}},"coslang:set_color_3":{"set_property":{"coslang:color":3}},"coslang:set_color_4":{"set_property":{"coslang:color":4}},"coslang:set_color_5":{"set_property":{"coslang:color":5}},"coslang:set_color_6":{"set_property":{"coslang:color":6}}}}} --------------------------------------------------------------------------------